Esempio n. 1
0
func (s *provisionerSuite) TestProvisioningScript(c *gc.C) {
	const series = "precise"
	const arch = "amd64"
	defer fakeSSH{
		Series:         series,
		Arch:           arch,
		InitUbuntuUser: true,
	}.install(c).Restore()
	machineId, err := manual.ProvisionMachine(s.getArgs(c))
	c.Assert(err, gc.IsNil)

	mcfg, err := client.MachineConfig(s.State, machineId, state.BootstrapNonce, "/var/lib/juju")
	c.Assert(err, gc.IsNil)
	script, err := manual.ProvisioningScript(mcfg)
	c.Assert(err, gc.IsNil)

	cloudcfg := coreCloudinit.New()
	err = cloudinit.ConfigureJuju(mcfg, cloudcfg)
	c.Assert(err, gc.IsNil)
	cloudcfg.SetAptUpgrade(false)
	sshinitScript, err := sshinit.ConfigureScript(cloudcfg)
	c.Assert(err, gc.IsNil)

	removeLogFile := "rm -f '/var/log/cloud-init-output.log'\n"
	expectedScript := removeLogFile + shell.DumpFileOnErrorScript("/var/log/cloud-init-output.log") + sshinitScript
	c.Assert(script, gc.Equals, expectedScript)
}
Esempio n. 2
0
func (*scriptSuite) TestDumpFileOnErrorScript(c *gc.C) {
	tempdir := c.MkDir()
	filename := filepath.Join(tempdir, "log.txt")
	err := ioutil.WriteFile(filename, []byte("abc"), 0644)
	c.Assert(err, gc.IsNil)

	dumpScript := shell.DumpFileOnErrorScript(filename)
	c.Logf("%s", dumpScript)
	run := func(command string) (stdout, stderr string) {
		var stdoutBuf, stderrBuf bytes.Buffer
		cmd := exec.Command("/bin/bash", "-s")
		cmd.Stdin = strings.NewReader(dumpScript + command)
		cmd.Stdout = &stdoutBuf
		cmd.Stderr = &stderrBuf
		cmd.Run()
		return stdoutBuf.String(), stderrBuf.String()
	}

	stdout, stderr := run("exit 0")
	c.Assert(stdout, gc.Equals, "")
	c.Assert(stderr, gc.Equals, "")

	stdout, stderr = run("exit 1")
	c.Assert(stdout, gc.Equals, "")
	c.Assert(stderr, gc.Equals, "abc")

	err = os.Remove(filename)
	c.Assert(err, gc.IsNil)
	stdout, stderr = run("exit 1")
	c.Assert(stdout, gc.Equals, "")
	c.Assert(stderr, gc.Equals, "")
}
Esempio n. 3
0
func (*scriptSuite) TestDumpFileOnErrorScriptOutput(c *gc.C) {
	script := shell.DumpFileOnErrorScript("a b c")
	c.Assert(script, gc.Equals, `
dump_file() {
    code=$?
    if [ $code -ne 0 -a -e 'a b c' ]; then
        cat 'a b c' >&2
    fi
    exit $code
}
trap dump_file EXIT
`[1:])
}
Esempio n. 4
0
// ProvisioningScript generates a bash script that can be
// executed on a remote host to carry out the cloud-init
// configuration.
func ProvisioningScript(mcfg *cloudinit.MachineConfig) (string, error) {
	cloudcfg := coreCloudinit.New()
	if err := cloudinit.ConfigureJuju(mcfg, cloudcfg); err != nil {
		return "", err
	}
	// Explicitly disabling apt_upgrade so as not to trample
	// the target machine's existing configuration.
	cloudcfg.SetAptUpgrade(false)
	configScript, err := sshinit.ConfigureScript(cloudcfg)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	// Always remove the cloud-init-output.log file first, if it exists.
	fmt.Fprintf(&buf, "rm -f %s\n", utils.ShQuote(mcfg.CloudInitOutputLog))
	// If something goes wrong, dump cloud-init-output.log to stderr.
	buf.WriteString(shell.DumpFileOnErrorScript(mcfg.CloudInitOutputLog))
	buf.WriteString(configScript)
	return buf.String(), nil
}
Esempio n. 5
0
	}
	// Bootstrap is synchronous, and will spawn a subprocess
	// to complete the procedure. If the user hits Ctrl-C,
	// SIGINT is sent to the foreground process attached to
	// the terminal, which will be the ssh subprocess at this
	// point. For that reason, we do not call StopInterruptNotify
	// until this function completes.
	cloudcfg := coreCloudinit.New()
	if err := cloudinit.ConfigureJuju(machineConfig, cloudcfg); err != nil {
		return err
	}
	configScript, err := sshinit.ConfigureScript(cloudcfg)
	if err != nil {
		return err
	}
	script := shell.DumpFileOnErrorScript(machineConfig.CloudInitOutputLog) + configScript
	return sshinit.RunConfigureScript(script, sshinit.ConfigureParams{
		Host:           "ubuntu@" + addr,
		Client:         client,
		Config:         cloudcfg,
		ProgressWriter: ctx.GetStderr(),
	})
}

type addresser interface {
	// Refresh refreshes the addresses for the instance.
	Refresh() error

	// Addresses returns the addresses for the instance.
	// To ensure that the results are up to date, call
	// Refresh first.