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