diff --git a/pkg/integration_test/join_test.go b/pkg/integration_test/join_test.go index c66b45409c4..1c5ee1c2e0a 100644 --- a/pkg/integration_test/join_test.go +++ b/pkg/integration_test/join_test.go @@ -15,6 +15,7 @@ package integration import ( "context" + "os" "time" . "github.com/pingcap/check" @@ -44,6 +45,8 @@ func (s *integrationTestSuite) TestSimpleJoin(c *C) { c.Assert(err, IsNil) err = pd2.Run(context.TODO()) c.Assert(err, IsNil) + _, err = os.Stat(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 +60,8 @@ func (s *integrationTestSuite) TestSimpleJoin(c *C) { c.Assert(err, IsNil) err = pd3.Run(context.TODO()) c.Assert(err, IsNil) + _, err = os.Stat(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..60849786c0a 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,15 @@ 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 + + retryTimes = 100 +) + // PrepareJoinCluster sends MemberAdd command to PD cluster, // and returns the initial configuration of the PD cluster. // @@ -73,8 +83,20 @@ func PrepareJoinCluster(cfg *Config) error { return errors.New("join self is forbidden") } - // Cases with data directory. + filePath := 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 @@ -138,7 +160,20 @@ func PrepareJoinCluster(cfg *Config) error { initialCluster = strings.Join(pds, ",") cfg.InitialCluster = initialCluster cfg.InitialClusterState = embed.ClusterStateFlagExisting - return nil + err = os.Mkdir(cfg.DataDir, privateDirMode) + if err != nil && !os.IsExist(err) { + return err + } + + for i := 0; i < retryTimes; i++ { + err = ioutil.WriteFile(filePath, []byte(cfg.InitialCluster), privateFileMode) + if err != nil { + log.Errorf("persist join config failed: %s", err) + continue + } + break + } + return err } func isDataExist(d string) bool {