github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cloudconfig/cloudinit/renderscript_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cloudinit_test
     5  
     6  import (
     7  	"regexp"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	"github.com/juju/utils/packaging"
    11  	"github.com/juju/version"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/cloudconfig"
    15  	"github.com/juju/juju/cloudconfig/cloudinit"
    16  	"github.com/juju/juju/cloudconfig/instancecfg"
    17  	"github.com/juju/juju/constraints"
    18  	"github.com/juju/juju/environs"
    19  	"github.com/juju/juju/environs/config"
    20  	"github.com/juju/juju/environs/imagemetadata"
    21  	"github.com/juju/juju/state/multiwatcher"
    22  	coretesting "github.com/juju/juju/testing"
    23  	"github.com/juju/juju/tools"
    24  )
    25  
    26  type configureSuite struct {
    27  	coretesting.BaseSuite
    28  }
    29  
    30  var _ = gc.Suite(&configureSuite{})
    31  
    32  type testProvider struct {
    33  	environs.EnvironProvider
    34  }
    35  
    36  func (p *testProvider) SecretAttrs(cfg *config.Config) (map[string]string, error) {
    37  	return map[string]string{}, nil
    38  }
    39  
    40  func init() {
    41  	environs.RegisterProvider("sshinit_test", &testProvider{})
    42  }
    43  
    44  func testConfig(c *gc.C, controller bool, vers version.Binary) *config.Config {
    45  	testConfig, err := config.New(config.UseDefaults, coretesting.FakeConfig())
    46  	c.Assert(err, jc.ErrorIsNil)
    47  	testConfig, err = testConfig.Apply(map[string]interface{}{
    48  		"type":           "sshinit_test",
    49  		"default-series": vers.Series,
    50  		"agent-version":  vers.Number.String(),
    51  	})
    52  	c.Assert(err, jc.ErrorIsNil)
    53  	return testConfig
    54  }
    55  
    56  func (s *configureSuite) getCloudConfig(c *gc.C, controller bool, vers version.Binary) cloudinit.CloudConfig {
    57  	var icfg *instancecfg.InstanceConfig
    58  	var err error
    59  	if controller {
    60  		icfg, err = instancecfg.NewBootstrapInstanceConfig(
    61  			constraints.Value{}, constraints.Value{},
    62  			vers.Series, "",
    63  		)
    64  		c.Assert(err, jc.ErrorIsNil)
    65  		icfg.InstanceId = "instance-id"
    66  		icfg.HostedModelConfig = map[string]interface{}{
    67  			"name": "hosted-model",
    68  		}
    69  		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobManageModel, multiwatcher.JobHostUnits}
    70  	} else {
    71  		icfg, err = instancecfg.NewInstanceConfig("0", "ya", imagemetadata.ReleasedStream, vers.Series, "", true, nil, nil)
    72  		c.Assert(err, jc.ErrorIsNil)
    73  		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobHostUnits}
    74  	}
    75  	err = icfg.SetTools(tools.List{
    76  		&tools.Tools{
    77  			Version: vers,
    78  			URL:     "http://testing.invalid/tools.tar.gz",
    79  		},
    80  	})
    81  	environConfig := testConfig(c, controller, vers)
    82  	err = instancecfg.FinishInstanceConfig(icfg, environConfig)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  	cloudcfg, err := cloudinit.New(icfg.Series)
    85  	c.Assert(err, jc.ErrorIsNil)
    86  	udata, err := cloudconfig.NewUserdataConfig(icfg, cloudcfg)
    87  	c.Assert(err, jc.ErrorIsNil)
    88  	err = udata.Configure()
    89  	c.Assert(err, jc.ErrorIsNil)
    90  	return cloudcfg
    91  }
    92  
    93  var allSeries = []string{"precise", "quantal", "raring", "saucy"}
    94  
    95  func checkIff(checker gc.Checker, condition bool) gc.Checker {
    96  	if condition {
    97  		return checker
    98  	}
    99  	return gc.Not(checker)
   100  }
   101  
   102  var aptgetRegexp = "(.|\n)*" + regexp.QuoteMeta("apt-get --option=Dpkg::Options::=--force-confold --option=Dpkg::options::=--force-unsafe-io --assume-yes --quiet ")
   103  
   104  func (s *configureSuite) TestAptSources(c *gc.C) {
   105  	for _, series := range allSeries {
   106  		vers := version.MustParseBinary("1.16.0-" + series + "-amd64")
   107  		script, err := s.getCloudConfig(c, true, vers).RenderScript()
   108  		c.Assert(err, jc.ErrorIsNil)
   109  
   110  		// Only Precise requires the cloud-tools pocket.
   111  		//
   112  		// The only source we add that requires an explicitly
   113  		// specified key is cloud-tools.
   114  		needsCloudTools := series == "precise"
   115  		c.Assert(
   116  			script,
   117  			checkIff(gc.Matches, needsCloudTools),
   118  			"(.|\n)*apt-key add.*(.|\n)*",
   119  		)
   120  		c.Assert(
   121  			script,
   122  			checkIff(gc.Matches, needsCloudTools),
   123  			"(.|\n)*add-apt-repository.*cloud-tools(.|\n)*",
   124  		)
   125  		c.Assert(
   126  			script,
   127  			checkIff(gc.Matches, needsCloudTools),
   128  			"(.|\n)*Pin: release n=precise-updates/cloud-tools\nPin-Priority: 400(.|\n)*",
   129  		)
   130  		c.Assert(
   131  			script,
   132  			checkIff(gc.Matches, needsCloudTools),
   133  			"(.|\n)*install -D -m 644 /dev/null '/etc/apt/preferences.d/50-cloud-tools'(.|\n)*",
   134  		)
   135  
   136  		// Only install python-software-properties (add-apt-repository)
   137  		// if we need to.
   138  		c.Assert(
   139  			script,
   140  			checkIff(gc.Matches, needsCloudTools),
   141  			aptgetRegexp+"install.*python-software-properties(.|\n)*",
   142  		)
   143  	}
   144  }
   145  
   146  func assertScriptMatches(c *gc.C, cfg cloudinit.CloudConfig, pattern string, match bool) {
   147  	script, err := cfg.RenderScript()
   148  	c.Assert(err, jc.ErrorIsNil)
   149  	checker := gc.Matches
   150  	if !match {
   151  		checker = gc.Not(checker)
   152  	}
   153  	c.Assert(script, checker, pattern)
   154  }
   155  
   156  func (s *configureSuite) TestAptUpdate(c *gc.C) {
   157  	// apt-get update is run only if AptUpdate is set.
   158  	aptGetUpdatePattern := aptgetRegexp + "update(.|\n)*"
   159  	cfg, err := cloudinit.New("quantal")
   160  	c.Assert(err, jc.ErrorIsNil)
   161  
   162  	c.Assert(cfg.SystemUpdate(), jc.IsFalse)
   163  	c.Assert(cfg.PackageSources(), gc.HasLen, 0)
   164  	assertScriptMatches(c, cfg, aptGetUpdatePattern, false)
   165  
   166  	cfg.SetSystemUpdate(true)
   167  	assertScriptMatches(c, cfg, aptGetUpdatePattern, true)
   168  
   169  	// If we add sources, but disable updates, display an error.
   170  	cfg.SetSystemUpdate(false)
   171  	source := packaging.PackageSource{
   172  		Name: "source",
   173  		URL:  "source",
   174  		Key:  "key",
   175  	}
   176  	cfg.AddPackageSource(source)
   177  	_, err = cfg.RenderScript()
   178  	c.Check(err, gc.ErrorMatches, "update sources were specified, but OS updates have been disabled.")
   179  }
   180  
   181  func (s *configureSuite) TestAptUpgrade(c *gc.C) {
   182  	// apt-get upgrade is only run if AptUpgrade is set.
   183  	aptGetUpgradePattern := aptgetRegexp + "upgrade(.|\n)*"
   184  	cfg, err := cloudinit.New("quantal")
   185  	c.Assert(err, jc.ErrorIsNil)
   186  	cfg.SetSystemUpdate(true)
   187  	source := packaging.PackageSource{
   188  		Name: "source",
   189  		URL:  "source",
   190  		Key:  "key",
   191  	}
   192  	cfg.AddPackageSource(source)
   193  	assertScriptMatches(c, cfg, aptGetUpgradePattern, false)
   194  	cfg.SetSystemUpgrade(true)
   195  	assertScriptMatches(c, cfg, aptGetUpgradePattern, true)
   196  }
   197  
   198  func (s *configureSuite) TestAptMirrorWrapper(c *gc.C) {
   199  	expectedCommands := regexp.QuoteMeta(`
   200  echo 'Changing apt mirror to http://woat.com' >&9
   201  old_mirror=$(awk "/^deb .* $(lsb_release -sc) .*main.*\$/{print \$2;exit}" /etc/apt/sources.list)
   202  new_mirror=http://woat.com
   203  sed -i s,$old_mirror,$new_mirror, /etc/apt/sources.list
   204  old_prefix=/var/lib/apt/lists/$(echo $old_mirror | sed 's,.*://,,' | sed 's,/$,,' | tr / _)
   205  new_prefix=/var/lib/apt/lists/$(echo $new_mirror | sed 's,.*://,,' | sed 's,/$,,' | tr / _)
   206  [ "$old_prefix" != "$new_prefix" ] &&
   207  for old in ${old_prefix}_*; do
   208      new=$(echo $old | sed s,^$old_prefix,$new_prefix,)
   209      mv $old $new
   210  done`)
   211  	aptMirrorRegexp := "(.|\n)*" + expectedCommands + "(.|\n)*"
   212  	cfg, err := cloudinit.New("quantal")
   213  	c.Assert(err, jc.ErrorIsNil)
   214  	cfg.SetPackageMirror("http://woat.com")
   215  	assertScriptMatches(c, cfg, aptMirrorRegexp, true)
   216  }