~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/state/backups/restore.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
166
166
        return st, errors.Annotate(err, "cannot open state")
167
167
}
168
168
 
 
169
type machineModel struct {
 
170
        machine *state.Machine
 
171
        model   *state.Model
 
172
}
 
173
 
169
174
// updateAllMachines finds all machines and resets the stored state address
170
175
// in each of them. The address does not include the port.
171
176
// It is too late to go back and errors in a couple of agents have
172
177
// better chance of being fixed by the user, if we were to fail
173
178
// we risk an inconsistent controller because of one unresponsive
174
179
// agent, we should nevertheless return the err info to the user.
175
 
func updateAllMachines(privateAddress string, machines []*state.Machine) error {
 
180
func updateAllMachines(privateAddress, publicAddress string, machines []machineModel) error {
176
181
        var machineUpdating sync.WaitGroup
177
 
        for key := range machines {
178
 
                // key is used to have machine be scope bound to the loop iteration.
179
 
                machine := machines[key]
 
182
        for _, item := range machines {
 
183
                machine := item.machine
180
184
                // A newly resumed controller requires no updating, and more
181
185
                // than one controller is not yet supported by this code.
182
186
                if machine.IsManager() || machine.Life() == state.Dead {
183
187
                        continue
184
188
                }
185
189
                machineUpdating.Add(1)
186
 
                go func() {
 
190
                go func(machine *state.Machine, model *state.Model) {
187
191
                        defer machineUpdating.Done()
188
 
                        err := runMachineUpdate(machine, setAgentAddressScript(privateAddress))
189
 
                        logger.Errorf("failed updating machine: %v", err)
190
 
                }()
 
192
                        logger.Debugf("updating addresses for machine %s in model %s/%s", machine.Tag().Id(), model.Owner().Canonical(), model.Name())
 
193
                        // TODO: thumper 2016-09-20
 
194
                        // runMachineUpdate only handles linux machines, what about windows?
 
195
                        err := runMachineUpdate(machine, setAgentAddressScript(privateAddress, publicAddress))
 
196
                        if err != nil {
 
197
                                logger.Errorf("failed updating machine: %v", err)
 
198
                        }
 
199
                }(machine, item.model)
191
200
        }
192
201
        machineUpdating.Wait()
193
202
 
203
212
cd /var/lib/juju/agents
204
213
for agent in *
205
214
do
206
 
        status  jujud-$agent| grep -q "^jujud-$agent start" > /dev/null
207
 
        if [ $? -eq 0 ]; then
208
 
                initctl stop jujud-$agent
209
 
        fi
 
215
        service jujud-$agent stop > /dev/null
 
216
 
 
217
        # The below statement will work in cases where there
 
218
        # is a private address for the api server only
 
219
        # or where there are a private and a public, which are
 
220
        # the two common cases.
210
221
        sed -i.old -r "/^(stateaddresses|apiaddresses):/{
211
222
                n
212
223
                s/- .*(:[0-9]+)/- {{.Address}}\1/
 
224
                n
 
225
                s/- .*(:[0-9]+)/- {{.PubAddress}}\1/
213
226
        }" $agent/agent.conf
214
227
 
215
228
        # If we're processing a unit agent's directly
221
234
        then
222
235
                find $agent/state/relations -type f -exec sed -i -r 's/change-version: [0-9]+$/change-version: 0/' {} \;
223
236
        fi
224
 
        # Just in case is a stale unit
225
 
        status  jujud-$agent| grep -q "^jujud-$agent stop" > /dev/null
226
 
        if [ $? -eq 0 ]; then
227
 
                initctl start jujud-$agent
228
 
                systemctl stop jujud-$agent
229
 
                systemctl start jujud-$agent
230
 
        fi
 
237
        service jujud-$agent start > /dev/null
231
238
done
232
239
`))
233
240
 
234
241
// setAgentAddressScript generates an ssh script argument to update state addresses.
235
 
func setAgentAddressScript(stateAddr string) string {
 
242
func setAgentAddressScript(stateAddr, statePubAddr string) string {
236
243
        var buf bytes.Buffer
237
244
        err := agentAddressAndRelationsTemplate.Execute(&buf, struct {
238
 
                Address string
239
 
        }{stateAddr})
 
245
                Address    string
 
246
                PubAddress string
 
247
        }{stateAddr, statePubAddr})
240
248
        if err != nil {
241
249
                panic(errors.Annotate(err, "template error"))
242
250
        }
265
273
        sshOptions := ssh.Options{}
266
274
        sshOptions.SetIdentities("/var/lib/juju/system-identity")
267
275
        userCmd := sshCommand(userAddr, []string{"sudo", "-n", "bash", "-c " + utils.ShQuote(script)}, &sshOptions)
 
276
        var stdoutBuf bytes.Buffer
268
277
        var stderrBuf bytes.Buffer
 
278
        userCmd.Stdout = &stdoutBuf
269
279
        userCmd.Stderr = &stderrBuf
 
280
        logger.Debugf("updating %s, script:\n%s", addr, script)
270
281
        if err := userCmd.Run(); err != nil {
271
282
                return errors.Annotatef(err, "ssh command failed: %q", stderrBuf.String())
272
283
        }
 
284
        logger.Debugf("result %s\nstdout: \n%s\nstderr: %s", addr, stdoutBuf.String(), stderrBuf.String())
273
285
        return nil
274
286
}