github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/cloudconfig"
    14  	"github.com/juju/juju/cloudconfig/cloudinit"
    15  	"github.com/juju/juju/cloudconfig/instancecfg"
    16  	"github.com/juju/juju/constraints"
    17  	"github.com/juju/juju/environs"
    18  	"github.com/juju/juju/environs/config"
    19  	"github.com/juju/juju/environs/imagemetadata"
    20  	"github.com/juju/juju/state/multiwatcher"
    21  	coretesting "github.com/juju/juju/testing"
    22  	"github.com/juju/juju/tools"
    23  	"github.com/juju/juju/version"
    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, stateServer 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, stateServer bool, vers version.Binary) cloudinit.CloudConfig {
    57  	var icfg *instancecfg.InstanceConfig
    58  	var err error
    59  	if stateServer {
    60  		icfg, err = instancecfg.NewBootstrapInstanceConfig(constraints.Value{}, vers.Series)
    61  		c.Assert(err, jc.ErrorIsNil)
    62  		icfg.InstanceId = "instance-id"
    63  		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobManageEnviron, multiwatcher.JobHostUnits}
    64  	} else {
    65  		icfg, err = instancecfg.NewInstanceConfig("0", "ya", imagemetadata.ReleasedStream, vers.Series, true, nil, nil, nil)
    66  		c.Assert(err, jc.ErrorIsNil)
    67  		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobHostUnits}
    68  	}
    69  	icfg.Tools = &tools.Tools{
    70  		Version: vers,
    71  		URL:     "http://testing.invalid/tools.tar.gz",
    72  	}
    73  	environConfig := testConfig(c, stateServer, vers)
    74  	err = instancecfg.FinishInstanceConfig(icfg, environConfig)
    75  	c.Assert(err, jc.ErrorIsNil)
    76  	cloudcfg, err := cloudinit.New(icfg.Series)
    77  	c.Assert(err, jc.ErrorIsNil)
    78  	udata, err := cloudconfig.NewUserdataConfig(icfg, cloudcfg)
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	err = udata.Configure()
    81  	c.Assert(err, jc.ErrorIsNil)
    82  	return cloudcfg
    83  }
    84  
    85  var allSeries = []string{"precise", "quantal", "raring", "saucy"}
    86  
    87  func checkIff(checker gc.Checker, condition bool) gc.Checker {
    88  	if condition {
    89  		return checker
    90  	}
    91  	return gc.Not(checker)
    92  }
    93  
    94  var aptgetRegexp = "(.|\n)*" + regexp.QuoteMeta("apt-get --option=Dpkg::Options::=--force-confold --option=Dpkg::options::=--force-unsafe-io --assume-yes --quiet ")
    95  
    96  func (s *configureSuite) TestAptSources(c *gc.C) {
    97  	for _, series := range allSeries {
    98  		vers := version.MustParseBinary("1.16.0-" + series + "-amd64")
    99  		script, err := s.getCloudConfig(c, true, vers).RenderScript()
   100  		c.Assert(err, jc.ErrorIsNil)
   101  
   102  		// Only Precise requires the cloud-tools pocket.
   103  		//
   104  		// The only source we add that requires an explicitly
   105  		// specified key is cloud-tools.
   106  		needsCloudTools := series == "precise"
   107  		c.Assert(
   108  			script,
   109  			checkIff(gc.Matches, needsCloudTools),
   110  			"(.|\n)*apt-key add.*(.|\n)*",
   111  		)
   112  		c.Assert(
   113  			script,
   114  			checkIff(gc.Matches, needsCloudTools),
   115  			"(.|\n)*add-apt-repository.*cloud-tools(.|\n)*",
   116  		)
   117  		c.Assert(
   118  			script,
   119  			checkIff(gc.Matches, needsCloudTools),
   120  			"(.|\n)*Pin: release n=precise-updates/cloud-tools\nPin-Priority: 400(.|\n)*",
   121  		)
   122  		c.Assert(
   123  			script,
   124  			checkIff(gc.Matches, needsCloudTools),
   125  			"(.|\n)*install -D -m 644 /dev/null '/etc/apt/preferences.d/50-cloud-tools'(.|\n)*",
   126  		)
   127  
   128  		// Only install python-software-properties (add-apt-repository)
   129  		// if we need to.
   130  		c.Assert(
   131  			script,
   132  			checkIff(gc.Matches, needsCloudTools),
   133  			aptgetRegexp+"install.*python-software-properties(.|\n)*",
   134  		)
   135  	}
   136  }
   137  
   138  func assertScriptMatches(c *gc.C, cfg cloudinit.CloudConfig, pattern string, match bool) {
   139  	script, err := cfg.RenderScript()
   140  	c.Assert(err, jc.ErrorIsNil)
   141  	checker := gc.Matches
   142  	if !match {
   143  		checker = gc.Not(checker)
   144  	}
   145  	c.Assert(script, checker, pattern)
   146  }
   147  
   148  func (s *configureSuite) TestAptUpdate(c *gc.C) {
   149  	// apt-get update is run only if AptUpdate is set.
   150  	aptGetUpdatePattern := aptgetRegexp + "update(.|\n)*"
   151  	cfg, err := cloudinit.New("quantal")
   152  	c.Assert(err, jc.ErrorIsNil)
   153  
   154  	c.Assert(cfg.SystemUpdate(), jc.IsFalse)
   155  	c.Assert(cfg.PackageSources(), gc.HasLen, 0)
   156  	assertScriptMatches(c, cfg, aptGetUpdatePattern, false)
   157  
   158  	cfg.SetSystemUpdate(true)
   159  	assertScriptMatches(c, cfg, aptGetUpdatePattern, true)
   160  
   161  	// If we add sources, but disable updates, display an error.
   162  	cfg.SetSystemUpdate(false)
   163  	source := packaging.PackageSource{
   164  		Name: "source",
   165  		URL:  "source",
   166  		Key:  "key",
   167  	}
   168  	cfg.AddPackageSource(source)
   169  	_, err = cfg.RenderScript()
   170  	c.Check(err, gc.ErrorMatches, "update sources were specified, but OS updates have been disabled.")
   171  }
   172  
   173  func (s *configureSuite) TestAptUpgrade(c *gc.C) {
   174  	// apt-get upgrade is only run if AptUpgrade is set.
   175  	aptGetUpgradePattern := aptgetRegexp + "upgrade(.|\n)*"
   176  	cfg, err := cloudinit.New("quantal")
   177  	c.Assert(err, jc.ErrorIsNil)
   178  	cfg.SetSystemUpdate(true)
   179  	source := packaging.PackageSource{
   180  		Name: "source",
   181  		URL:  "source",
   182  		Key:  "key",
   183  	}
   184  	cfg.AddPackageSource(source)
   185  	assertScriptMatches(c, cfg, aptGetUpgradePattern, false)
   186  	cfg.SetSystemUpgrade(true)
   187  	assertScriptMatches(c, cfg, aptGetUpgradePattern, true)
   188  }
   189  
   190  func (s *configureSuite) TestAptMirrorWrapper(c *gc.C) {
   191  	expectedCommands := regexp.QuoteMeta(`
   192  echo 'Changing apt mirror to http://woat.com' >&9
   193  old_mirror=$(awk "/^deb .* $(lsb_release -sc) .*main.*\$/{print \$2;exit}" /etc/apt/sources.list)
   194  new_mirror=http://woat.com
   195  sed -i s,$old_mirror,$new_mirror, /etc/apt/sources.list
   196  old_prefix=/var/lib/apt/lists/$(echo $old_mirror | sed 's,.*://,,' | sed 's,/$,,' | tr / _)
   197  new_prefix=/var/lib/apt/lists/$(echo $new_mirror | sed 's,.*://,,' | sed 's,/$,,' | tr / _)
   198  [ "$old_prefix" != "$new_prefix" ] &&
   199  for old in ${old_prefix}_*; do
   200      new=$(echo $old | sed s,^$old_prefix,$new_prefix,)
   201      mv $old $new
   202  done`)
   203  	aptMirrorRegexp := "(.|\n)*" + expectedCommands + "(.|\n)*"
   204  	cfg, err := cloudinit.New("quantal")
   205  	c.Assert(err, jc.ErrorIsNil)
   206  	cfg.SetPackageMirror("http://woat.com")
   207  	assertScriptMatches(c, cfg, aptMirrorRegexp, true)
   208  }