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  }