// makeCustomData produces custom data for Azure. This is a base64-encoded // zipfile of cloudinit userdata. func makeCustomData(cfg *cloudinit.MachineConfig) (string, error) { zipData, err := environs.ComposeUserData(cfg, nil) if err != nil { return "", fmt.Errorf("failure while generating custom data: %v", err) } logger.Debugf("user data; %d bytes", len(zipData)) encodedData := base64.StdEncoding.EncodeToString(zipData) logger.Debugf("base64-encoded custom data: %d bytes", len(encodedData)) return encodedData, nil }
func (*customDataSuite) TestMakeCustomDataEncodesUserData(c *gc.C) { cfg := makeMachineConfig(c) encodedData, err := makeCustomData(cfg) c.Assert(err, gc.IsNil) data, err := base64.StdEncoding.DecodeString(encodedData) c.Assert(err, gc.IsNil) reference, err := environs.ComposeUserData(cfg, nil) c.Assert(err, gc.IsNil) c.Check(data, gc.DeepEquals, reference) }
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{ Info: mongo.Info{ Addrs: []string{"127.0.0.1:1234"}, CACert: "CA CERT\n" + testing.CACert, }, Password: "******", 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) } }