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: &params.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  }