func (S) TestSetOutput(c *gc.C) { type test struct { kind cloudinit.OutputKind stdout string stderr string } tests := []test{{ cloudinit.OutAll, "a", "", }, { cloudinit.OutAll, "", "b", }, { cloudinit.OutInit, "a", "b", }, { cloudinit.OutAll, "a", "b", }, { cloudinit.OutAll, "", "", }} cfg := cloudinit.New() stdout, stderr := cfg.Output(cloudinit.OutAll) c.Assert(stdout, gc.Equals, "") c.Assert(stderr, gc.Equals, "") for i, t := range tests { c.Logf("test %d: %+v", i, t) cfg.SetOutput(t.kind, t.stdout, t.stderr) stdout, stderr = cfg.Output(t.kind) c.Assert(stdout, gc.Equals, t.stdout) c.Assert(stderr, gc.Equals, t.stderr) } }
func (S) TestRunCmds(c *gc.C) { cfg := cloudinit.New() c.Assert(cfg.RunCmds(), gc.HasLen, 0) cfg.AddScripts("a", "b") cfg.AddRunCmdArgs("c", "d") cfg.AddRunCmd("e") c.Assert(cfg.RunCmds(), gc.DeepEquals, []interface{}{ "a", "b", []string{"c", "d"}, "e", }) }
func (S) TestOutput(c *gc.C) { for _, t := range ctests { cfg := cloudinit.New() t.setOption(cfg) data, err := cfg.Render() c.Assert(err, gc.IsNil) c.Assert(data, gc.NotNil) c.Assert(string(data), gc.Equals, header+t.expect, gc.Commentf("test %q output differs", t.name)) } }
//#cloud-config //packages: //- juju //- ubuntu func ExampleConfig() { cfg := cloudinit.New() cfg.AddPackage("juju") cfg.AddPackage("ubuntu") data, err := cfg.Render() if err != nil { fmt.Printf("render error: %v", err) return } fmt.Printf("%s", data) }
func (S) TestPackages(c *gc.C) { cfg := cloudinit.New() c.Assert(cfg.Packages(), gc.HasLen, 0) cfg.AddPackage("a b c") cfg.AddPackage("d!") expectedPackages := []string{"a b c", "d!"} c.Assert(cfg.Packages(), gc.DeepEquals, expectedPackages) cfg.AddPackageFromTargetRelease("package", "series") expectedPackages = append(expectedPackages, "--target-release 'series' 'package'") c.Assert(cfg.Packages(), gc.DeepEquals, expectedPackages) }
func cloudInitUserData(machineConfig *cloudinit.MachineConfig) ([]byte, error) { cloudConfig := coreCloudinit.New() err := cloudinit.Configure(machineConfig, cloudConfig) if err != nil { return nil, err } // Run ifconfig to get the addresses of the internal container at least // logged in the host. cloudConfig.AddRunCmd("ifconfig") data, err := cloudConfig.Render() if err != nil { return nil, err } return data, nil }
// templateUserData returns a minimal user data necessary for the template. // This should have the authorized keys, base packages, the cloud archive if // necessary, initial apt proxy config, and it should do the apt-get // update/upgrade initially. func templateUserData( series string, authorizedKeys string, aptProxy proxy.Settings, ) ([]byte, error) { config := coreCloudinit.New() config.AddScripts( "set -xe", // ensure we run all the scripts or abort. ) config.AddSSHAuthorizedKeys(authorizedKeys) cloudinit.MaybeAddCloudArchiveCloudTools(config, series) cloudinit.AddAptCommands(aptProxy, config) config.AddScripts( fmt.Sprintf( "printf '%%s\n' %s > %s", utils.ShQuote(templateShutdownUpstartScript), templateShutdownUpstartFilename, )) data, err := config.Render() if err != nil { return nil, err } return data, nil }
func (*CloudInitSuite) testUserData(c *gc.C, bootstrap bool) { testJujuHome := c.MkDir() defer osenv.SetJujuHome(osenv.SetJujuHome(testJujuHome)) tools := &tools.Tools{ URL: "http://foo.com/tools/releases/juju1.2.3-linux-amd64.tgz", Version: version.MustParseBinary("1.2.3-linux-amd64"), } envConfig, err := config.New(config.NoDefaults, dummySampleConfig()) c.Assert(err, gc.IsNil) allJobs := []params.MachineJob{ params.JobManageEnviron, params.JobHostUnits, } cfg := &cloudinit.MachineConfig{ MachineId: "10", MachineNonce: "5432", Tools: tools, StateInfo: &state.Info{ Addrs: []string{"127.0.0.1:1234"}, Password: "******", CACert: "CA CERT\n" + testing.CACert, Tag: "machine-10", }, APIInfo: &api.Info{ Addrs: []string{"127.0.0.1:1234"}, Password: "******", CACert: "CA CERT\n" + testing.CACert, Tag: "machine-10", }, DataDir: environs.DataDir, LogDir: agent.DefaultLogDir, Jobs: allJobs, CloudInitOutputLog: environs.CloudInitOutputLog, Config: envConfig, AgentEnvironment: map[string]string{agent.ProviderType: "dummy"}, AuthorizedKeys: "wheredidileavemykeys", MachineAgentServiceName: "jujud-machine-10", } if bootstrap { cfg.Bootstrap = true cfg.StateServingInfo = ¶ms.StateServingInfo{ StatePort: envConfig.StatePort(), APIPort: envConfig.APIPort(), Cert: testing.ServerCert, PrivateKey: testing.ServerKey, } } script1 := "script1" script2 := "script2" cloudcfg := coreCloudinit.New() cloudcfg.AddRunCmd(script1) cloudcfg.AddRunCmd(script2) result, err := environs.ComposeUserData(cfg, cloudcfg) c.Assert(err, gc.IsNil) unzipped, err := utils.Gunzip(result) c.Assert(err, gc.IsNil) config := make(map[interface{}]interface{}) err = goyaml.Unmarshal(unzipped, &config) c.Assert(err, gc.IsNil) // The scripts given to userData where added as the first // commands to be run. runCmd := config["runcmd"].([]interface{}) c.Check(runCmd[0], gc.Equals, script1) c.Check(runCmd[1], gc.Equals, script2) if bootstrap { // The cloudinit config should have nothing but the basics: // SSH authorized keys, the additional runcmds, and log output. // // Note: the additional runcmds *do* belong here, at least // for MAAS. MAAS needs to configure and then bounce the // network interfaces, which would sever the SSH connection // in the synchronous bootstrap phase. c.Check(config, gc.DeepEquals, map[interface{}]interface{}{ "output": map[interface{}]interface{}{ "all": "| tee -a /var/log/cloud-init-output.log", }, "runcmd": []interface{}{ "script1", "script2", "set -xe", "install -D -m 644 /dev/null '/var/lib/juju/nonce.txt'", "printf '%s\\n' '5432' > '/var/lib/juju/nonce.txt'", }, "ssh_authorized_keys": []interface{}{"wheredidileavemykeys"}, }) } else { // Just check that the cloudinit config looks good, // and that there are more runcmds than the additional // ones we passed into ComposeUserData. c.Check(config["apt_upgrade"], gc.Equals, true) c.Check(len(runCmd) > 2, jc.IsTrue) } }
interrupted, client, checkNonceCommand, inst, 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(), }) }