github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/environs/manual/provisioner_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package manual_test 5 6 import ( 7 "fmt" 8 "os" 9 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils/shell" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/agent" 15 "github.com/juju/juju/apiserver/client" 16 "github.com/juju/juju/apiserver/params" 17 "github.com/juju/juju/cloudconfig" 18 "github.com/juju/juju/cloudconfig/cloudinit" 19 "github.com/juju/juju/environs/manual" 20 envtesting "github.com/juju/juju/environs/testing" 21 envtools "github.com/juju/juju/environs/tools" 22 "github.com/juju/juju/instance" 23 "github.com/juju/juju/juju/testing" 24 coretesting "github.com/juju/juju/testing" 25 "github.com/juju/juju/version" 26 ) 27 28 type provisionerSuite struct { 29 testing.JujuConnSuite 30 } 31 32 var _ = gc.Suite(&provisionerSuite{}) 33 34 func (s *provisionerSuite) getArgs(c *gc.C) manual.ProvisionMachineArgs { 35 hostname, err := os.Hostname() 36 c.Assert(err, jc.ErrorIsNil) 37 client := s.APIState.Client() 38 s.AddCleanup(func(*gc.C) { client.Close() }) 39 return manual.ProvisionMachineArgs{ 40 Host: hostname, 41 Client: client, 42 UpdateBehavior: ¶ms.UpdateBehavior{true, true}, 43 } 44 } 45 46 func (s *provisionerSuite) TestProvisionMachine(c *gc.C) { 47 const series = coretesting.FakeDefaultSeries 48 const arch = "amd64" 49 const operatingSystem = version.Ubuntu 50 51 args := s.getArgs(c) 52 hostname := args.Host 53 args.Host = "ubuntu@" + args.Host 54 55 defaultToolsURL := envtools.DefaultBaseURL 56 envtools.DefaultBaseURL = "" 57 58 defer fakeSSH{ 59 Series: series, 60 Arch: arch, 61 InitUbuntuUser: true, 62 SkipProvisionAgent: true, 63 }.install(c).Restore() 64 // Attempt to provision a machine with no tools available, expect it to fail. 65 machineId, err := manual.ProvisionMachine(args) 66 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 67 c.Assert(machineId, gc.Equals, "") 68 69 cfg := s.Environ.Config() 70 number, ok := cfg.AgentVersion() 71 c.Assert(ok, jc.IsTrue) 72 binVersion := version.Binary{number, series, arch, operatingSystem} 73 envtesting.AssertUploadFakeToolsVersions(c, s.DefaultToolsStorage, "released", "released", binVersion) 74 envtools.DefaultBaseURL = defaultToolsURL 75 76 for i, errorCode := range []int{255, 0} { 77 c.Logf("test %d: code %d", i, errorCode) 78 defer fakeSSH{ 79 Series: series, 80 Arch: arch, 81 InitUbuntuUser: true, 82 ProvisionAgentExitCode: errorCode, 83 }.install(c).Restore() 84 machineId, err = manual.ProvisionMachine(args) 85 if errorCode != 0 { 86 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("subprocess encountered error code %d", errorCode)) 87 c.Assert(machineId, gc.Equals, "") 88 } else { 89 c.Assert(err, jc.ErrorIsNil) 90 c.Assert(machineId, gc.Not(gc.Equals), "") 91 // machine ID will be incremented. Even though we failed and the 92 // machine is removed, the ID is not reused. 93 c.Assert(machineId, gc.Equals, fmt.Sprint(i+1)) 94 m, err := s.State.Machine(machineId) 95 c.Assert(err, jc.ErrorIsNil) 96 instanceId, err := m.InstanceId() 97 c.Assert(err, jc.ErrorIsNil) 98 c.Assert(instanceId, gc.Equals, instance.Id("manual:"+hostname)) 99 } 100 } 101 102 // Attempting to provision a machine twice should fail. We effect 103 // this by checking for existing juju upstart configurations. 104 defer fakeSSH{ 105 Provisioned: true, 106 InitUbuntuUser: true, 107 SkipDetection: true, 108 SkipProvisionAgent: true, 109 }.install(c).Restore() 110 _, err = manual.ProvisionMachine(args) 111 c.Assert(err, gc.Equals, manual.ErrProvisioned) 112 defer fakeSSH{ 113 Provisioned: true, 114 CheckProvisionedExitCode: 255, 115 InitUbuntuUser: true, 116 SkipDetection: true, 117 SkipProvisionAgent: true, 118 }.install(c).Restore() 119 _, err = manual.ProvisionMachine(args) 120 c.Assert(err, gc.ErrorMatches, "error checking if provisioned: subprocess encountered error code 255") 121 } 122 123 func (s *provisionerSuite) TestFinishInstancConfig(c *gc.C) { 124 const series = coretesting.FakeDefaultSeries 125 const arch = "amd64" 126 defer fakeSSH{ 127 Series: series, 128 Arch: arch, 129 InitUbuntuUser: true, 130 }.install(c).Restore() 131 machineId, err := manual.ProvisionMachine(s.getArgs(c)) 132 c.Assert(err, jc.ErrorIsNil) 133 134 // Now check what we would've configured it with. 135 icfg, err := client.InstanceConfig(s.State, machineId, agent.BootstrapNonce, "/var/lib/juju") 136 c.Assert(err, jc.ErrorIsNil) 137 c.Check(icfg, gc.NotNil) 138 c.Check(icfg.APIInfo, gc.NotNil) 139 c.Check(icfg.MongoInfo, gc.NotNil) 140 141 stateInfo := s.MongoInfo(c) 142 apiInfo := s.APIInfo(c) 143 c.Check(icfg.APIInfo.Addrs, gc.DeepEquals, apiInfo.Addrs) 144 c.Check(icfg.MongoInfo.Addrs, gc.DeepEquals, stateInfo.Addrs) 145 } 146 147 func (s *provisionerSuite) TestProvisioningScript(c *gc.C) { 148 const series = coretesting.FakeDefaultSeries 149 const arch = "amd64" 150 defer fakeSSH{ 151 Series: series, 152 Arch: arch, 153 InitUbuntuUser: true, 154 }.install(c).Restore() 155 156 machineId, err := manual.ProvisionMachine(s.getArgs(c)) 157 c.Assert(err, jc.ErrorIsNil) 158 159 err = s.State.UpdateEnvironConfig( 160 map[string]interface{}{ 161 "enable-os-upgrade": false, 162 }, nil, nil) 163 c.Assert(err, jc.ErrorIsNil) 164 165 icfg, err := client.InstanceConfig(s.State, machineId, agent.BootstrapNonce, "/var/lib/juju") 166 167 c.Assert(err, jc.ErrorIsNil) 168 script, err := manual.ProvisioningScript(icfg) 169 c.Assert(err, jc.ErrorIsNil) 170 171 cloudcfg, err := cloudinit.New(series) 172 c.Assert(err, jc.ErrorIsNil) 173 udata, err := cloudconfig.NewUserdataConfig(icfg, cloudcfg) 174 c.Assert(err, jc.ErrorIsNil) 175 err = udata.ConfigureJuju() 176 c.Assert(err, jc.ErrorIsNil) 177 cloudcfg.SetSystemUpgrade(false) 178 provisioningScript, err := cloudcfg.RenderScript() 179 c.Assert(err, jc.ErrorIsNil) 180 181 removeLogFile := "rm -f '/var/log/cloud-init-output.log'\n" 182 expectedScript := removeLogFile + shell.DumpFileOnErrorScript("/var/log/cloud-init-output.log") + provisioningScript 183 c.Assert(script, gc.Equals, expectedScript) 184 }