diff --git a/cmd/influxd/run/command.go b/cmd/influxd/run/command.go index 5ef967e389..00c7b0413f 100644 --- a/cmd/influxd/run/command.go +++ b/cmd/influxd/run/command.go @@ -98,7 +98,7 @@ func (cmd *Command) Run(args ...string) error { // If we have a node ID, ignore the join argument // We are not using the reference to this node var, just checking // to see if we have a node ID on disk - if node, _ := influxdb.LoadNode(config.Meta.Dir, config.Meta.HTTPBindAddress); node == nil || node.ID == 0 { + if node, _ := influxdb.LoadNode(config.Meta.Dir, []string{config.Meta.HTTPBindAddress}); node == nil || node.ID == 0 { if options.Join != "" { config.Meta.JoinPeers = strings.Split(options.Join, ",") } diff --git a/cmd/influxd/run/config.go b/cmd/influxd/run/config.go index 44ca9f678d..2221192e5d 100644 --- a/cmd/influxd/run/config.go +++ b/cmd/influxd/run/config.go @@ -60,8 +60,6 @@ type Config struct { // Server reporting ReportingDisabled bool `toml:"reporting-disabled"` - Dir string `toml:"dir"` - // BindAddress is the address that all TCP services use (Raft, Snapshot, Cluster, etc.) BindAddress string `toml:"bind-address"` } diff --git a/cmd/influxd/run/server.go b/cmd/influxd/run/server.go index f595b6ebbb..4d8a1481db 100644 --- a/cmd/influxd/run/server.go +++ b/cmd/influxd/run/server.go @@ -5,6 +5,7 @@ import ( "log" "net" "os" + "path/filepath" "reflect" "runtime" "runtime/pprof" @@ -103,20 +104,37 @@ type Server struct { // NewServer returns a new instance of Server built from a config. func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) { - // load the node information. Before 0.10 this was in the meta directory, - // so use that if the top level directory isn't specified - dir := c.Dir - if dir == "" { - dir = c.Meta.Dir + // We need to ensure that a meta directory always exists even if + // we don't start the meta store. node.json is always stored under + // the meta directory. + if err := os.MkdirAll(c.Meta.Dir, 0777); err != nil { + return nil, fmt.Errorf("mkdir all: %s", err) + } + + // 0.10-rc1 and prior would sometimes put the node.json at the root + // dir which breaks backup/restore and restarting nodes. This moves + // the file from the root so it's always under the meta dir. + oldPath := filepath.Join(filepath.Dir(c.Meta.Dir), "node.json") + newPath := filepath.Join(c.Meta.Dir, "node.json") + + if _, err := os.Stat(oldPath); err == nil { + if err := os.Rename(oldPath, newPath); err != nil { + return nil, err + } } // load the node information - node, err := influxdb.LoadNode(dir, c.Meta.HTTPBindAddress) + metaAddresses := []string{c.Meta.HTTPBindAddress} + if !c.Meta.Enabled { + metaAddresses = c.Meta.JoinPeers + } + + node, err := influxdb.LoadNode(c.Meta.Dir, metaAddresses) if err != nil { if !os.IsNotExist(err) { return nil, err } else { - node = influxdb.NewNode(dir, c.Meta.HTTPBindAddress) + node = influxdb.NewNode(c.Meta.Dir, metaAddresses) } } @@ -642,8 +660,9 @@ func (s *Server) initializeMetaClient() error { return err } for _, n := range metaNodes { - s.Node.MetaServers = append(s.Node.MetaServers, n.Host) + s.Node.AddMetaServers([]string{n.Host}) } + if err := s.Node.Save(); err != nil { return err } diff --git a/etc/config.sample.toml b/etc/config.sample.toml index 8ffcc14ed6..cc57761251 100644 --- a/etc/config.sample.toml +++ b/etc/config.sample.toml @@ -8,9 +8,6 @@ # Change this option to true to disable reporting. reporting-disabled = false -# directory where server ID and cluster metaservers information will be kept -dir = "/var/lib/influxdb" - # we'll try to get the hostname automatically, but if it the os returns something # that isn't resolvable by other servers in the cluster, use this option to # manually set the hostname diff --git a/node.go b/node.go index b4674e622f..40cc31ae08 100644 --- a/node.go +++ b/node.go @@ -22,9 +22,9 @@ type Node struct { } // LoadNode will load the node information from disk if present -func LoadNode(path, addr string) (*Node, error) { +func LoadNode(path string, addrs []string) (*Node, error) { // Always check to see if we are upgrading first - if err := upgradeNodeFile(path, addr); err != nil { + if err := upgradeNodeFile(path, addrs); err != nil { return nil, err } @@ -46,10 +46,10 @@ func LoadNode(path, addr string) (*Node, error) { } // NewNode will return a new node -func NewNode(path, addr string) *Node { +func NewNode(path string, addrs []string) *Node { return &Node{ path: path, - MetaServers: []string{addr}, + MetaServers: addrs, } } @@ -71,7 +71,26 @@ func (n *Node) Save() error { return os.Rename(tmpFile, file) } -func upgradeNodeFile(path, addr string) error { +// AddMetaServers adds the addrs to the set of MetaServers known to this node. +// If an addr already exists, it will not be re-added. +func (n *Node) AddMetaServers(addrs []string) { + unique := map[string]struct{}{} + for _, addr := range n.MetaServers { + unique[addr] = struct{}{} + } + + for _, addr := range addrs { + unique[addr] = struct{}{} + } + + metaServers := []string{} + for addr := range unique { + metaServers = append(metaServers, addr) + } + n.MetaServers = metaServers +} + +func upgradeNodeFile(path string, addrs []string) error { oldFile := filepath.Join(path, oldNodeFile) b, err := ioutil.ReadFile(oldFile) if err != nil { @@ -100,7 +119,7 @@ func upgradeNodeFile(path, addr string) error { n := &Node{ path: path, - MetaServers: []string{addr}, + MetaServers: addrs, } if n.ID, err = strconv.ParseUint(string(b), 10, 64); err != nil { return err diff --git a/services/meta/config.go b/services/meta/config.go index 4a5202cd5d..70cad91832 100644 --- a/services/meta/config.go +++ b/services/meta/config.go @@ -89,7 +89,7 @@ func NewConfig() *Config { } func (c *Config) Validate() error { - if c.Enabled && c.Dir == "" { + if c.Dir == "" { return errors.New("Meta.Dir must be specified") } return nil