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) }
func assertScriptMatches(c *gc.C, cfg *cloudinit.Config, pattern string, match bool) { script, err := sshinit.ConfigureScript(cfg) c.Assert(err, gc.IsNil) checker := gc.Matches if !match { checker = gc.Not(checker) } c.Assert(script, checker, pattern) }
func (s *configureSuite) TestAptSources(c *gc.C) { for _, series := range allSeries { vers := version.MustParseBinary("1.16.0-" + series + "-amd64") script, err := sshinit.ConfigureScript(s.getCloudConfig(c, true, vers)) c.Assert(err, gc.IsNil) // Only Precise requires the cloud-tools pocket. // // The only source we add that requires an explicitly // specified key is cloud-tools. needsCloudTools := series == "precise" c.Assert( script, checkIff(gc.Matches, needsCloudTools), "(.|\n)*apt-key add.*(.|\n)*", ) c.Assert( script, checkIff(gc.Matches, needsCloudTools), "(.|\n)*add-apt-repository.*cloud-tools(.|\n)*", ) c.Assert( script, checkIff(gc.Matches, needsCloudTools), "(.|\n)*Pin: release n=precise-updates/cloud-tools\nPin-Priority: 400(.|\n)*", ) c.Assert( script, checkIff(gc.Matches, needsCloudTools), "(.|\n)*install -D -m 644 /dev/null '/etc/apt/preferences.d/50-cloud-tools'(.|\n)*", ) // Only install python-software-properties (add-apt-repository) // if we need to. c.Assert( script, checkIff(gc.Matches, needsCloudTools), aptgetRegexp+"install.*python-software-properties(.|\n)*", ) } }
// 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 }
machineConfig.Config.BootstrapSSHOpts(), ) if err != nil { return err } // 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