github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/cloudinit/sshinit/configure_test.go (about)

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