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