github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/upgradedatabase/shim.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package upgradedatabase 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/version/v2" 11 12 "github.com/juju/juju/core/status" 13 "github.com/juju/juju/mongo" 14 "github.com/juju/juju/state" 15 ) 16 17 // Logger represents the methods required to emit log messages. 18 type Logger interface { 19 Debugf(message string, args ...interface{}) 20 Infof(message string, args ...interface{}) 21 Errorf(message string, args ...interface{}) 22 } 23 24 // Clock provides an interface for dealing with clocks. 25 type Clock interface { 26 // Now returns the current clock time. 27 Now() time.Time 28 29 // After waits for the duration to elapse and then sends the 30 // current time on the returned channel. 31 After(time.Duration) <-chan time.Time 32 } 33 34 // UpgradeInfo describes methods for working with the state representation of 35 // an upgrade-in-progress. 36 type UpgradeInfo interface { 37 // Status returns the current status of the upgrade. 38 Status() state.UpgradeStatus 39 40 // SetStatus sets the current status of the upgrade. 41 SetStatus(status state.UpgradeStatus) error 42 43 // Watch returns a watcher that notifies of changes to the UpgradeInfo. 44 Watch() state.NotifyWatcher 45 46 // Refresh refreshes the UpgradeInfo from state. 47 Refresh() error 48 } 49 50 // Pool describes methods required by the upgradeDB worker, 51 // supplied by a state pool. 52 type Pool interface { 53 // IsPrimary returns true if the Mongo primary is 54 // running on the machine with the input ID. 55 IsPrimary(string) (bool, error) 56 57 // SetStatus updates the status of the machine with the input ID. 58 SetStatus(string, status.Status, string) error 59 60 // EnsureUpgradeInfo ensures that a document exists in the "upgradeInfo" 61 // collection for coordinating the current upgrade. 62 EnsureUpgradeInfo(string, version.Number, version.Number) (UpgradeInfo, error) 63 64 // Close closes the state pool. 65 Close() error 66 } 67 68 type pool struct { 69 *state.StatePool 70 } 71 72 // IsPrimary (Pool) returns true if the Mongo primary is 73 // running on the controller with the input ID. 74 func (p *pool) IsPrimary(controllerId string) (bool, error) { 75 st, err := p.SystemState() 76 if err != nil { 77 return false, errors.Trace(err) 78 } 79 80 // For IAAS models, controllers are machines. 81 // For CAAS models, until we support HA, there is only one Mongo 82 // and it is the primary. 83 hasMachine, err := p.hasMachine() 84 if err != nil { 85 return false, errors.Trace(err) 86 } 87 // TODO(CAAS) - bug 1849030 support HA 88 if !hasMachine { 89 return true, nil 90 } 91 92 machine, err := st.Machine(controllerId) 93 if err != nil { 94 return false, errors.Trace(err) 95 } 96 isPrimary, err := mongo.IsMaster(st.MongoSession(), machine) 97 return isPrimary, errors.Trace(err) 98 } 99 100 func (p *pool) hasMachine() (bool, error) { 101 systemState, err := p.SystemState() 102 if err != nil { 103 return false, errors.Trace(err) 104 } 105 model, err := systemState.Model() 106 if err != nil { 107 return false, errors.Trace(err) 108 } 109 return model.Type() == state.ModelTypeIAAS, nil 110 } 111 112 // SetStatus (Pool) updates the status of the machine with the input ID. 113 func (p *pool) SetStatus(controllerId string, sts status.Status, msg string) error { 114 hasMachine, err := p.hasMachine() 115 if err != nil { 116 return errors.Trace(err) 117 } 118 if !hasMachine { 119 // TODO(CAAS) - bug 1849030 support HA 120 // Nothing we can do for now because we do not have any machine for CAAS controller. 121 return nil 122 } 123 systemState, err := p.SystemState() 124 if err != nil { 125 return errors.Trace(err) 126 } 127 machine, err := systemState.Machine(controllerId) 128 if err != nil { 129 return errors.Trace(err) 130 } 131 132 now := time.Now() 133 return errors.Trace(machine.SetStatus(status.StatusInfo{ 134 Status: sts, 135 Message: msg, 136 Since: &now, 137 })) 138 } 139 140 // EnsureUpgradeInfo (Pool) ensures that a document exists in the "upgradeInfo" 141 // collection for coordinating the current upgrade. 142 func (p *pool) EnsureUpgradeInfo(controllerId string, fromVersion, toVersion version.Number) (UpgradeInfo, error) { 143 systemState, err := p.SystemState() 144 if err != nil { 145 return nil, errors.Trace(err) 146 } 147 info, err := systemState.EnsureUpgradeInfo(controllerId, fromVersion, toVersion) 148 return info, errors.Trace(err) 149 }