github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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/series" 12 "github.com/juju/utils/shell" 13 "github.com/juju/version" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/agent" 17 "github.com/juju/juju/apiserver/client" 18 "github.com/juju/juju/apiserver/params" 19 "github.com/juju/juju/cloudconfig" 20 "github.com/juju/juju/cloudconfig/cloudinit" 21 "github.com/juju/juju/environs/manual" 22 envtesting "github.com/juju/juju/environs/testing" 23 envtools "github.com/juju/juju/environs/tools" 24 "github.com/juju/juju/instance" 25 "github.com/juju/juju/juju/testing" 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 var series = series.LatestLts() 48 const arch = "amd64" 49 50 args := s.getArgs(c) 51 hostname := args.Host 52 args.Host = "ubuntu@" + args.Host 53 54 defaultToolsURL := envtools.DefaultBaseURL 55 envtools.DefaultBaseURL = "" 56 57 defer fakeSSH{ 58 Series: series, 59 Arch: arch, 60 InitUbuntuUser: true, 61 SkipProvisionAgent: true, 62 }.install(c).Restore() 63 // Attempt to provision a machine with no tools available, expect it to fail. 64 machineId, err := manual.ProvisionMachine(args) 65 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 66 c.Assert(machineId, gc.Equals, "") 67 68 cfg := s.Environ.Config() 69 number, ok := cfg.AgentVersion() 70 c.Assert(ok, jc.IsTrue) 71 binVersion := version.Binary{ 72 Number: number, 73 Series: series, 74 Arch: arch, 75 } 76 envtesting.AssertUploadFakeToolsVersions(c, s.DefaultToolsStorage, "released", "released", binVersion) 77 envtools.DefaultBaseURL = defaultToolsURL 78 79 for i, errorCode := range []int{255, 0} { 80 c.Logf("test %d: code %d", i, errorCode) 81 defer fakeSSH{ 82 Series: series, 83 Arch: arch, 84 InitUbuntuUser: true, 85 ProvisionAgentExitCode: errorCode, 86 }.install(c).Restore() 87 machineId, err = manual.ProvisionMachine(args) 88 if errorCode != 0 { 89 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("subprocess encountered error code %d", errorCode)) 90 c.Assert(machineId, gc.Equals, "") 91 } else { 92 c.Assert(err, jc.ErrorIsNil) 93 c.Assert(machineId, gc.Not(gc.Equals), "") 94 // machine ID will be incremented. Even though we failed and the 95 // machine is removed, the ID is not reused. 96 c.Assert(machineId, gc.Equals, fmt.Sprint(i+1)) 97 m, err := s.State.Machine(machineId) 98 c.Assert(err, jc.ErrorIsNil) 99 instanceId, err := m.InstanceId() 100 c.Assert(err, jc.ErrorIsNil) 101 c.Assert(instanceId, gc.Equals, instance.Id("manual:"+hostname)) 102 } 103 } 104 105 // Attempting to provision a machine twice should fail. We effect 106 // this by checking for existing juju upstart configurations. 107 defer fakeSSH{ 108 Provisioned: true, 109 InitUbuntuUser: true, 110 SkipDetection: true, 111 SkipProvisionAgent: true, 112 }.install(c).Restore() 113 _, err = manual.ProvisionMachine(args) 114 c.Assert(err, gc.Equals, manual.ErrProvisioned) 115 defer fakeSSH{ 116 Provisioned: true, 117 CheckProvisionedExitCode: 255, 118 InitUbuntuUser: true, 119 SkipDetection: true, 120 SkipProvisionAgent: true, 121 }.install(c).Restore() 122 _, err = manual.ProvisionMachine(args) 123 c.Assert(err, gc.ErrorMatches, "error checking if provisioned: subprocess encountered error code 255") 124 } 125 126 func (s *provisionerSuite) TestFinishInstancConfig(c *gc.C) { 127 var series = series.LatestLts() 128 const arch = "amd64" 129 defer fakeSSH{ 130 Series: series, 131 Arch: arch, 132 InitUbuntuUser: true, 133 }.install(c).Restore() 134 machineId, err := manual.ProvisionMachine(s.getArgs(c)) 135 c.Assert(err, jc.ErrorIsNil) 136 137 // Now check what we would've configured it with. 138 icfg, err := client.InstanceConfig(s.State, machineId, agent.BootstrapNonce, "/var/lib/juju") 139 c.Assert(err, jc.ErrorIsNil) 140 c.Check(icfg, gc.NotNil) 141 c.Check(icfg.APIInfo, gc.NotNil) 142 143 apiInfo := s.APIInfo(c) 144 c.Check(icfg.APIInfo.Addrs, gc.DeepEquals, apiInfo.Addrs) 145 } 146 147 func (s *provisionerSuite) TestProvisioningScript(c *gc.C) { 148 var series = series.LatestLts() 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.UpdateModelConfig( 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 }