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 }