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