github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/mongo.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names" 9 "github.com/juju/replicaset" 10 jujutxn "github.com/juju/txn" 11 12 "github.com/juju/juju/mongo" 13 "github.com/juju/juju/network" 14 ) 15 16 // environMongo implements state/lease.Mongo to expose environ-filtered mongo 17 // capabilities to the sub-packages (e.g. lease, macaroonstorage). 18 type environMongo struct { 19 state *State 20 } 21 22 // GetCollection is part of the lease.Mongo interface. 23 func (m *environMongo) GetCollection(name string) (mongo.Collection, func()) { 24 return m.state.getCollection(name) 25 } 26 27 // RunTransaction is part of the lease.Mongo interface. 28 func (m *environMongo) RunTransaction(buildTxn jujutxn.TransactionSource) error { 29 return m.state.run(buildTxn) 30 } 31 32 // Mongo Upgrade 33 34 // HAMember holds information that identifies one member 35 // of HA. 36 type HAMember struct { 37 Tag string 38 PublicAddress network.Address 39 Series string 40 } 41 42 // UpgradeMongoParams holds information that identifies 43 // the machines part of HA. 44 type UpgradeMongoParams struct { 45 RsMembers []replicaset.Member 46 47 Master HAMember 48 Members []HAMember 49 } 50 51 // SetUpgradeMongoMode writes a value in the state server to be picked up 52 // by api servers to know that there is an upgrade ready to happen. 53 func (st *State) SetUpgradeMongoMode(v mongo.Version) (UpgradeMongoParams, error) { 54 currentInfo, err := st.ControllerInfo() 55 if err != nil { 56 return UpgradeMongoParams{}, errors.Annotate(err, "could not obtain current controller information") 57 } 58 result := UpgradeMongoParams{} 59 machines := []*Machine{} 60 for _, mID := range currentInfo.VotingMachineIds { 61 m, err := st.Machine(mID) 62 if err != nil { 63 return UpgradeMongoParams{}, errors.Annotate(err, "cannot change all the replicas") 64 } 65 isMaster, err := mongo.IsMaster(st.session, m) 66 if err != nil { 67 return UpgradeMongoParams{}, errors.Annotatef(err, "cannot determine if machine %q is master", mID) 68 } 69 paddr, err := m.PublicAddress() 70 if err != nil { 71 return UpgradeMongoParams{}, errors.Annotatef(err, "cannot obtain public address for machine: %v", m) 72 } 73 tag := m.Tag() 74 mtag := tag.(names.MachineTag) 75 member := HAMember{ 76 Tag: mtag.Id(), 77 PublicAddress: paddr, 78 Series: m.Series(), 79 } 80 if isMaster { 81 result.Master = member 82 } else { 83 result.Members = append(result.Members, member) 84 } 85 machines = append(machines, m) 86 } 87 rsMembers, err := replicaset.CurrentMembers(st.session) 88 if err != nil { 89 return UpgradeMongoParams{}, errors.Annotate(err, "cannot obtain current replicaset members") 90 } 91 masterRs, err := replicaset.MasterHostPort(st.session) 92 if err != nil { 93 return UpgradeMongoParams{}, errors.Annotate(err, "cannot determine master on replicaset members") 94 } 95 for _, m := range rsMembers { 96 if m.Address != masterRs { 97 result.RsMembers = append(result.RsMembers, m) 98 } 99 } 100 for _, m := range machines { 101 if err := m.SetStopMongoUntilVersion(v); err != nil { 102 return UpgradeMongoParams{}, errors.Annotate(err, "cannot trigger replica shutdown") 103 } 104 } 105 return result, nil 106 } 107 108 // ResumeReplication will add all passed members to replicaset. 109 func (st *State) ResumeReplication(members []replicaset.Member) error { 110 return replicaset.Add(st.session, members...) 111 }