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 }