40
40
func Main(args []string) {
41
ctx, err := cmd.DefaultContext()
43
fmt.Fprintf(os.Stderr, "error: %v\n", err)
41
46
if err := juju.InitJujuHome(); err != nil {
42
47
fmt.Fprintf(os.Stderr, "error: %s\n", err)
45
os.Exit(cmd.Main(&restoreCommand{}, cmd.DefaultContext(), args[1:]))
50
os.Exit(cmd.Main(&restoreCommand{}, ctx, args[1:]))
48
53
var logger = loggo.GetLogger("juju.plugins.restore")
266
271
newInstId = instance.Id(info.InstanceId)
268
273
progress("copying backup file to bootstrap host")
269
if err := scp(backupFile, addr, "~/juju-backup.tgz"); err != nil {
274
if err := sendViaScp(backupFile, addr, "~/juju-backup.tgz"); err != nil {
270
275
return "", "", fmt.Errorf("cannot copy backup file to bootstrap instance: %v", err)
272
277
progress("updating bootstrap machine")
273
if err := ssh(addr, updateBootstrapMachineScript(newInstId, creds)); err != nil {
278
if err := runViaSsh(addr, updateBootstrapMachineScript(newInstId, creds)); err != nil {
274
279
return "", "", fmt.Errorf("update script failed: %v", err)
276
281
return newInstId, addr, nil
346
351
s/- .*(:[0-9]+)/- {{.Address}}\1/
347
352
}" $agent/agent.conf
354
# If we're processing a unit agent's directly
355
# and it has some relations, reset
356
# the stored version of all of them to
357
# ensure that any relation hooks will
348
359
if [[ $agent = unit-* ]]
350
sed -i -r 's/change-version: [0-9]+$/change-version: 0/' $agent/state/relations/*/* || true
361
find $agent/state/relations -type f -exec sed -i -r 's/change-version: [0-9]+$/change-version: 0/' {} \;
352
363
initctl start jujud-$agent
354
sed -i -r 's/^(:syslogtag, startswith, "juju-" @)(.*)(:[0-9]+.*)$/\1{{.Address}}\3/' /etc/rsyslog.d/*-juju*.conf
357
367
// setAgentAddressScript generates an ssh script argument to update state addresses
405
415
return fmt.Errorf("no appropriate public address found")
407
return ssh(addr, sshArg)
410
func ssh(addr string, script string) error {
414
"-o", "StrictHostKeyChecking no",
415
"-o", "PasswordAuthentication no",
417
"sudo -n bash -c " + utils.ShQuote(script),
419
cmd := exec.Command("ssh", args...)
420
logger.Debugf("ssh command: %s %q", cmd.Path, cmd.Args)
421
data, err := cmd.CombinedOutput()
423
return fmt.Errorf("ssh command failed: %v (%q)", err, data)
425
progress("ssh command succeeded: %q", data)
429
func scp(file, host, destFile string) error {
434
"-o", "StrictHostKeyChecking no",
435
"-o", "PasswordAuthentication no",
437
"ubuntu@"+host+":"+destFile)
438
logger.Debugf("scp command: %s %q", cmd.Path, cmd.Args)
439
out, err := cmd.CombinedOutput()
443
if _, ok := err.(*exec.ExitError); ok {
444
return fmt.Errorf("scp failed: %s", out)
417
return runViaSsh(addr, sshArg)
420
func runViaSsh(addr string, script string) error {
421
// This is taken from cmd/juju/ssh.go there is no other clear way to set user
422
userAddr := "ubuntu@" + addr
423
cmd := ssh.Command(userAddr, []string{"sudo", "-n", "bash", "-c " + utils.ShQuote(script)}, nil)
424
var stderrBuf bytes.Buffer
425
var stdoutBuf bytes.Buffer
426
cmd.Stderr = &stderrBuf
427
cmd.Stdout = &stdoutBuf
430
return fmt.Errorf("ssh command failed: %v (%q)", err, stderrBuf.String())
432
progress("ssh command succedded: %q", stdoutBuf.String())
436
func sendViaScp(file, host, destFile string) error {
437
err := ssh.Copy([]string{file, "ubuntu@" + host + ":" + destFile}, nil, nil)
439
return fmt.Errorf("scp command failed: %v", err)
449
444
func mustParseTemplate(templ string) *template.Template {