github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/peergrouper/initiate.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package peergrouper 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/replicaset" 11 "github.com/juju/utils" 12 "gopkg.in/mgo.v2" 13 14 "github.com/juju/juju/agent" 15 "github.com/juju/juju/mongo" 16 ) 17 18 // TODO(katco): 2016-08-09: lp:1611427 19 var initiateAttemptStrategy = utils.AttemptStrategy{ 20 Total: 60 * time.Second, 21 Delay: 5 * time.Second, 22 } 23 24 // InitiateMongoParams holds parameters for the MaybeInitiateMongo call. 25 type InitiateMongoParams struct { 26 // DialInfo specifies how to connect to the mongo server. 27 DialInfo *mgo.DialInfo 28 29 // MemberHostPort provides the address to use for 30 // the first replica set member. 31 MemberHostPort string 32 33 // User holds the user to log as in to the mongo server. 34 // If it is empty, no login will take place. 35 User string 36 Password string 37 } 38 39 // InitiateMongoServer checks for an existing mongo configuration. 40 // If no existing configuration is found one is created using Initiate. 41 func InitiateMongoServer(p InitiateMongoParams) error { 42 logger.Debugf("Initiating mongo replicaset; dialInfo %#v; memberHostport %q; user %q; password %q", p.DialInfo, p.MemberHostPort, p.User, p.Password) 43 defer logger.Infof("finished InitiateMongoServer") 44 45 if len(p.DialInfo.Addrs) > 1 { 46 logger.Infof("more than one member; replica set must be already initiated") 47 return nil 48 } 49 p.DialInfo.Direct = true 50 51 // Initiate may fail while mongo is initialising, so we retry until 52 // we successfully populate the replicaset config. 53 var err error 54 for attempt := initiateAttemptStrategy.Start(); attempt.Next(); { 55 err = attemptInitiateMongoServer(p.DialInfo, p.MemberHostPort) 56 if err == nil { 57 logger.Infof("replica set initiated") 58 return err 59 } 60 if attempt.HasNext() { 61 logger.Debugf("replica set initiation failed, will retry: %v", err) 62 } 63 } 64 return errors.Annotatef(err, "cannot initiate replica set") 65 } 66 67 // attemptInitiateMongoServer attempts to initiate the replica set. 68 func attemptInitiateMongoServer(dialInfo *mgo.DialInfo, memberHostPort string) error { 69 session, err := mgo.DialWithInfo(dialInfo) 70 if err != nil { 71 return errors.Annotatef(err, "cannot dial mongo to initiate replicaset") 72 } 73 defer session.Close() 74 session.SetSocketTimeout(mongo.SocketTimeout) 75 76 return replicaset.Initiate( 77 session, 78 memberHostPort, 79 mongo.ReplicaSetName, 80 map[string]string{ 81 jujuMachineKey: agent.BootstrapMachineId, 82 }, 83 ) 84 }