diff --git a/pkg/integration_test/join_test.go b/pkg/integration_test/join_test.go index c66b45409c4..f140a1c0184 100644 --- a/pkg/integration_test/join_test.go +++ b/pkg/integration_test/join_test.go @@ -15,6 +15,8 @@ package integration import ( "context" + "os" + "path" "time" . "github.com/pingcap/check" @@ -44,6 +46,8 @@ func (s *integrationTestSuite) TestSimpleJoin(c *C) { c.Assert(err, IsNil) err = pd2.Run(context.TODO()) c.Assert(err, IsNil) + _, err = os.Stat(path.Join(pd2.GetConfig().DataDir, "join")) + c.Assert(os.IsNotExist(err), IsFalse) members, err = etcdutil.ListEtcdMembers(client) c.Assert(err, IsNil) c.Assert(members.Members, HasLen, 2) @@ -57,6 +61,8 @@ func (s *integrationTestSuite) TestSimpleJoin(c *C) { c.Assert(err, IsNil) err = pd3.Run(context.TODO()) c.Assert(err, IsNil) + _, err = os.Stat(path.Join(pd3.GetConfig().DataDir, "join")) + c.Assert(os.IsNotExist(err), IsFalse) members, err = etcdutil.ListEtcdMembers(client) c.Assert(err, IsNil) c.Assert(members.Members, HasLen, 3) diff --git a/server/join.go b/server/join.go index 70624bb2c2d..3de0d21c94d 100644 --- a/server/join.go +++ b/server/join.go @@ -15,6 +15,7 @@ package server import ( "fmt" + "io/ioutil" "os" "path" "strings" @@ -26,6 +27,13 @@ import ( log "github.com/sirupsen/logrus" ) +const ( + // privateFileMode grants owner to read/write a file. + privateFileMode = 0600 + // privateDirMode grants owner to make/remove files inside the directory. + privateDirMode = 0700 +) + // PrepareJoinCluster sends MemberAdd command to PD cluster, // and returns the initial configuration of the PD cluster. // @@ -73,8 +81,20 @@ func PrepareJoinCluster(cfg *Config) error { return errors.New("join self is forbidden") } - // Cases with data directory. + filePath := path.Join(cfg.DataDir, "join") + // Read the persist join config + if _, err := os.Stat(filePath); !os.IsNotExist(err) { + s, err := ioutil.ReadFile(filePath) + if err != nil { + log.Fatal("read the join config meet error: ", err) + } + cfg.InitialCluster = strings.TrimSpace(string(s)) + cfg.InitialClusterState = embed.ClusterStateFlagExisting + return nil + } + initialCluster := "" + // Cases with data directory. if isDataExist(path.Join(cfg.DataDir, "member")) { cfg.InitialCluster = initialCluster cfg.InitialClusterState = embed.ClusterStateFlagExisting @@ -103,6 +123,9 @@ func PrepareJoinCluster(cfg *Config) error { existed := false for _, m := range listResp.Members { + if len(m.Name) == 0 { + return errors.New("there is a member that has not joined successfully") + } if m.Name == cfg.Name { existed = true } @@ -131,6 +154,9 @@ func PrepareJoinCluster(cfg *Config) error { if memb.ID == addResp.Member.ID { n = cfg.Name } + if len(n) == 0 { + return errors.New("there is a member that has not joined successfully") + } for _, m := range memb.PeerURLs { pds = append(pds, fmt.Sprintf("%s=%s", n, m)) } @@ -138,7 +164,13 @@ func PrepareJoinCluster(cfg *Config) error { initialCluster = strings.Join(pds, ",") cfg.InitialCluster = initialCluster cfg.InitialClusterState = embed.ClusterStateFlagExisting - return nil + err = os.MkdirAll(cfg.DataDir, privateDirMode) + if err != nil && !os.IsExist(err) { + return errors.WithStack(err) + } + + err = ioutil.WriteFile(filePath, []byte(cfg.InitialCluster), privateFileMode) + return errors.WithStack(err) } func isDataExist(d string) bool {