github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/cmd/juju/bootstrap_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "bytes" 8 "fmt" 9 "strings" 10 11 "github.com/juju/loggo" 12 gc "launchpad.net/gocheck" 13 14 "launchpad.net/juju-core/cmd" 15 "launchpad.net/juju-core/constraints" 16 "launchpad.net/juju-core/environs" 17 "launchpad.net/juju-core/environs/configstore" 18 "launchpad.net/juju-core/environs/filestorage" 19 "launchpad.net/juju-core/environs/imagemetadata" 20 imtesting "launchpad.net/juju-core/environs/imagemetadata/testing" 21 "launchpad.net/juju-core/environs/simplestreams" 22 "launchpad.net/juju-core/environs/storage" 23 "launchpad.net/juju-core/environs/sync" 24 envtesting "launchpad.net/juju-core/environs/testing" 25 envtools "launchpad.net/juju-core/environs/tools" 26 ttesting "launchpad.net/juju-core/environs/tools/testing" 27 "launchpad.net/juju-core/errors" 28 "launchpad.net/juju-core/provider/dummy" 29 coretesting "launchpad.net/juju-core/testing" 30 jc "launchpad.net/juju-core/testing/checkers" 31 "launchpad.net/juju-core/testing/testbase" 32 coretools "launchpad.net/juju-core/tools" 33 "launchpad.net/juju-core/version" 34 ) 35 36 type BootstrapSuite struct { 37 testbase.LoggingSuite 38 coretesting.MgoSuite 39 envtesting.ToolsFixture 40 } 41 42 var _ = gc.Suite(&BootstrapSuite{}) 43 44 func (s *BootstrapSuite) SetUpSuite(c *gc.C) { 45 s.LoggingSuite.SetUpSuite(c) 46 s.MgoSuite.SetUpSuite(c) 47 } 48 49 func (s *BootstrapSuite) SetUpTest(c *gc.C) { 50 s.LoggingSuite.SetUpTest(c) 51 s.MgoSuite.SetUpTest(c) 52 s.ToolsFixture.SetUpTest(c) 53 54 // Set up a local source with tools. 55 sourceDir := createToolsSource(c, vAll) 56 s.PatchValue(&envtools.DefaultBaseURL, sourceDir) 57 } 58 59 func (s *BootstrapSuite) TearDownSuite(c *gc.C) { 60 s.MgoSuite.TearDownSuite(c) 61 s.LoggingSuite.TearDownSuite(c) 62 } 63 64 func (s *BootstrapSuite) TearDownTest(c *gc.C) { 65 s.ToolsFixture.TearDownTest(c) 66 s.MgoSuite.TearDownTest(c) 67 s.LoggingSuite.TearDownTest(c) 68 dummy.Reset() 69 } 70 71 type bootstrapRetryTest struct { 72 info string 73 args []string 74 expectedAllowRetry []bool 75 err string 76 // If version != "", version.Current will be 77 // set to it for the duration of the test. 78 version string 79 // If addVersionToSource is true, then "version" 80 // above will be populated in the tools source. 81 addVersionToSource bool 82 } 83 84 var bootstrapRetryTests = []bootstrapRetryTest{{ 85 info: "no tools uploaded, first check has no retries; no matching binary in source; sync fails with no second attempt", 86 expectedAllowRetry: []bool{false}, 87 err: "cannot find bootstrap tools: no matching tools available", 88 version: "1.16.0-precise-amd64", 89 }, { 90 info: "no tools uploaded, first check has no retries; matching binary in source; check after sync has retries", 91 expectedAllowRetry: []bool{false, true}, 92 err: "cannot find bootstrap tools: tools not found", 93 version: "1.16.0-precise-amd64", 94 addVersionToSource: true, 95 }, { 96 info: "no tools uploaded, first check has no retries; no matching binary in source; check after upload has retries", 97 expectedAllowRetry: []bool{false, true}, 98 err: "cannot find bootstrap tools: tools not found", 99 version: "1.15.1-precise-amd64", // dev version to force upload 100 }, { 101 info: "new tools uploaded, so we want to allow retries to give them a chance at showing up", 102 args: []string{"--upload-tools"}, 103 expectedAllowRetry: []bool{true}, 104 err: "cannot find bootstrap tools: no matching tools available", 105 }} 106 107 // Test test checks that bootstrap calls FindTools with the expected allowRetry flag. 108 func (s *BootstrapSuite) TestAllowRetries(c *gc.C) { 109 for i, test := range bootstrapRetryTests { 110 c.Logf("test %d: %s\n", i, test.info) 111 s.runAllowRetriesTest(c, test) 112 } 113 } 114 115 func (s *BootstrapSuite) runAllowRetriesTest(c *gc.C, test bootstrapRetryTest) { 116 toolsVersions := envtesting.VAll 117 if test.version != "" { 118 testVersion := version.MustParseBinary(test.version) 119 restore := testbase.PatchValue(&version.Current, testVersion) 120 defer restore() 121 if test.addVersionToSource { 122 toolsVersions = append([]version.Binary{}, toolsVersions...) 123 toolsVersions = append(toolsVersions, testVersion) 124 } 125 } 126 _, fake := makeEmptyFakeHome(c) 127 defer fake.Restore() 128 sourceDir := createToolsSource(c, toolsVersions) 129 s.PatchValue(&envtools.DefaultBaseURL, sourceDir) 130 131 var findToolsRetryValues []bool 132 mockFindTools := func(cloudInst environs.ConfigGetter, majorVersion, minorVersion int, 133 filter coretools.Filter, allowRetry bool) (list coretools.List, err error) { 134 findToolsRetryValues = append(findToolsRetryValues, allowRetry) 135 return nil, errors.NotFoundf("tools") 136 } 137 138 restore := envtools.TestingPatchBootstrapFindTools(mockFindTools) 139 defer restore() 140 141 _, errc := runCommand(nullContext(), new(BootstrapCommand), test.args...) 142 err := <-errc 143 c.Check(findToolsRetryValues, gc.DeepEquals, test.expectedAllowRetry) 144 c.Check(err, gc.ErrorMatches, test.err) 145 } 146 147 func (s *BootstrapSuite) TestTest(c *gc.C) { 148 s.PatchValue(&sync.Upload, mockUploadTools) 149 for i, test := range bootstrapTests { 150 c.Logf("\ntest %d: %s", i, test.info) 151 test.run(c) 152 } 153 } 154 155 type bootstrapTest struct { 156 info string 157 // binary version string used to set version.Current 158 version string 159 sync bool 160 args []string 161 err string 162 // binary version strings for expected tools; if set, no default tools 163 // will be uploaded before running the test. 164 uploads []string 165 constraints constraints.Value 166 } 167 168 func (test bootstrapTest) run(c *gc.C) { 169 // Create home with dummy provider and remove all 170 // of its envtools. 171 env, fake := makeEmptyFakeHome(c) 172 defer fake.Restore() 173 174 if test.version != "" { 175 origVersion := version.Current 176 version.Current = version.MustParseBinary(test.version) 177 defer func() { version.Current = origVersion }() 178 } 179 180 uploadCount := len(test.uploads) 181 if uploadCount == 0 { 182 usefulVersion := version.Current 183 usefulVersion.Series = env.Config().DefaultSeries() 184 envtesting.AssertUploadFakeToolsVersions(c, env.Storage(), usefulVersion) 185 } 186 187 // Run command and check for uploads. 188 opc, errc := runCommand(nullContext(), new(BootstrapCommand), test.args...) 189 if uploadCount > 0 { 190 for i := 0; i < uploadCount; i++ { 191 c.Check((<-opc).(dummy.OpPutFile).Env, gc.Equals, "peckham") 192 } 193 list, err := envtools.FindTools( 194 env, version.Current.Major, version.Current.Minor, coretools.Filter{}, envtools.DoNotAllowRetry) 195 c.Check(err, gc.IsNil) 196 c.Logf("found: " + list.String()) 197 urls := list.URLs() 198 c.Check(urls, gc.HasLen, len(test.uploads)) 199 for _, v := range test.uploads { 200 c.Logf("seeking: " + v) 201 vers := version.MustParseBinary(v) 202 _, found := urls[vers] 203 c.Check(found, gc.Equals, true) 204 } 205 } 206 207 // Check for remaining operations/errors. 208 if test.err != "" { 209 c.Check(<-errc, gc.ErrorMatches, test.err) 210 return 211 } 212 if !c.Check(<-errc, gc.IsNil) { 213 return 214 } 215 if len(test.uploads) > 0 { 216 indexFile := (<-opc).(dummy.OpPutFile) 217 c.Check(indexFile.FileName, gc.Equals, "tools/streams/v1/index.json") 218 productFile := (<-opc).(dummy.OpPutFile) 219 c.Check(productFile.FileName, gc.Equals, "tools/streams/v1/com.ubuntu.juju:released:tools.json") 220 } 221 opPutBootstrapVerifyFile := (<-opc).(dummy.OpPutFile) 222 c.Check(opPutBootstrapVerifyFile.Env, gc.Equals, "peckham") 223 c.Check(opPutBootstrapVerifyFile.FileName, gc.Equals, environs.VerificationFilename) 224 225 opPutBootstrapInitFile := (<-opc).(dummy.OpPutFile) 226 c.Check(opPutBootstrapInitFile.Env, gc.Equals, "peckham") 227 c.Check(opPutBootstrapInitFile.FileName, gc.Equals, "provider-state") 228 229 opBootstrap := (<-opc).(dummy.OpBootstrap) 230 c.Check(opBootstrap.Env, gc.Equals, "peckham") 231 c.Check(opBootstrap.Constraints, gc.DeepEquals, test.constraints) 232 233 store, err := configstore.Default() 234 c.Assert(err, gc.IsNil) 235 // Check a CA cert/key was generated by reloading the environment. 236 env, err = environs.NewFromName("peckham", store) 237 c.Assert(err, gc.IsNil) 238 _, hasCert := env.Config().CACert() 239 c.Check(hasCert, gc.Equals, true) 240 _, hasKey := env.Config().CAPrivateKey() 241 c.Check(hasKey, gc.Equals, true) 242 } 243 244 var bootstrapTests = []bootstrapTest{{ 245 info: "no args, no error, no uploads, no constraints", 246 }, { 247 info: "bad arg", 248 args: []string{"twiddle"}, 249 err: `unrecognized args: \["twiddle"\]`, 250 }, { 251 info: "bad --constraints", 252 args: []string{"--constraints", "bad=wrong"}, 253 err: `invalid value "bad=wrong" for flag --constraints: unknown constraint "bad"`, 254 }, { 255 info: "bad --series", 256 args: []string{"--series", "bad1"}, 257 err: `invalid value "bad1" for flag --series: invalid series name "bad1"`, 258 }, { 259 info: "lonely --series", 260 args: []string{"--series", "fine"}, 261 err: `--series requires --upload-tools`, 262 }, { 263 info: "bad environment", 264 version: "1.2.3-precise-amd64", 265 args: []string{"-e", "brokenenv"}, 266 err: `dummy.Bootstrap is broken`, 267 }, { 268 info: "constraints", 269 args: []string{"--constraints", "mem=4G cpu-cores=4"}, 270 constraints: constraints.MustParse("mem=4G cpu-cores=4"), 271 }, { 272 info: "--upload-tools picks all reasonable series", 273 version: "1.2.3-saucy-amd64", 274 args: []string{"--upload-tools"}, 275 uploads: []string{ 276 "1.2.3.1-saucy-amd64", // from version.Current 277 "1.2.3.1-raring-amd64", // from env.Config().DefaultSeries() 278 "1.2.3.1-precise-amd64", // from environs/config.DefaultSeries 279 }, 280 }, { 281 info: "--upload-tools only uploads each file once", 282 version: "1.2.3-precise-amd64", 283 args: []string{"--upload-tools"}, 284 uploads: []string{ 285 "1.2.3.1-raring-amd64", 286 "1.2.3.1-precise-amd64", 287 }, 288 }, { 289 info: "--upload-tools rejects invalid series", 290 version: "1.2.3-saucy-amd64", 291 args: []string{"--upload-tools", "--series", "ping,ping,pong"}, 292 err: `invalid series "ping"`, 293 }, { 294 info: "--upload-tools always bumps build number", 295 version: "1.2.3.4-raring-amd64", 296 args: []string{"--upload-tools"}, 297 uploads: []string{ 298 "1.2.3.5-raring-amd64", 299 "1.2.3.5-precise-amd64", 300 }, 301 }} 302 303 func (s *BootstrapSuite) TestBootstrapTwice(c *gc.C) { 304 env, fake := makeEmptyFakeHome(c) 305 defer fake.Restore() 306 defaultSeriesVersion := version.Current 307 defaultSeriesVersion.Series = env.Config().DefaultSeries() 308 309 ctx := coretesting.Context(c) 310 code := cmd.Main(&BootstrapCommand{}, ctx, nil) 311 c.Check(code, gc.Equals, 0) 312 313 ctx2 := coretesting.Context(c) 314 code2 := cmd.Main(&BootstrapCommand{}, ctx2, nil) 315 c.Check(code2, gc.Equals, 1) 316 c.Check(coretesting.Stderr(ctx2), gc.Equals, "error: environment is already bootstrapped\n") 317 c.Check(coretesting.Stdout(ctx2), gc.Equals, "") 318 } 319 320 func (s *BootstrapSuite) TestBootstrapJenvWarning(c *gc.C) { 321 env, fake := makeEmptyFakeHome(c) 322 defer fake.Restore() 323 defaultSeriesVersion := version.Current 324 defaultSeriesVersion.Series = env.Config().DefaultSeries() 325 326 store, err := configstore.Default() 327 c.Assert(err, gc.IsNil) 328 ctx := coretesting.Context(c) 329 environs.PrepareFromName("peckham", ctx, store) 330 331 logger := "jenv.warning.test" 332 testWriter := &loggo.TestWriter{} 333 loggo.RegisterWriter(logger, testWriter, loggo.WARNING) 334 defer loggo.RemoveWriter(logger) 335 336 _, errc := runCommand(ctx, new(BootstrapCommand), "-e", "peckham") 337 c.Assert(<-errc, gc.IsNil) 338 c.Assert(testWriter.Log, jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"}) 339 } 340 341 func (s *BootstrapSuite) TestInvalidLocalSource(c *gc.C) { 342 s.PatchValue(&version.Current.Number, version.MustParse("1.2.0")) 343 env, fake := makeEmptyFakeHome(c) 344 defer fake.Restore() 345 346 // Bootstrap the environment with an invalid source. 347 // The command returns with an error. 348 ctx := coretesting.Context(c) 349 code := cmd.Main(&BootstrapCommand{}, ctx, []string{"--metadata-source", c.MkDir()}) 350 c.Check(code, gc.Equals, 1) 351 352 // Now check that there are no tools available. 353 _, err := envtools.FindTools( 354 env, version.Current.Major, version.Current.Minor, coretools.Filter{}, envtools.DoNotAllowRetry) 355 c.Assert(err, gc.FitsTypeOf, errors.NotFoundf("")) 356 } 357 358 // createImageMetadata creates some image metadata in a local directory. 359 func createImageMetadata(c *gc.C) (string, []*imagemetadata.ImageMetadata) { 360 // Generate some image metadata. 361 im := []*imagemetadata.ImageMetadata{ 362 { 363 Id: "1234", 364 Arch: "amd64", 365 Version: "13.04", 366 RegionName: "region", 367 Endpoint: "endpoint", 368 }, 369 } 370 cloudSpec := &simplestreams.CloudSpec{ 371 Region: "region", 372 Endpoint: "endpoint", 373 } 374 sourceDir := c.MkDir() 375 sourceStor, err := filestorage.NewFileStorageWriter(sourceDir) 376 c.Assert(err, gc.IsNil) 377 err = imagemetadata.MergeAndWriteMetadata("raring", im, cloudSpec, sourceStor) 378 c.Assert(err, gc.IsNil) 379 return sourceDir, im 380 } 381 382 // checkImageMetadata checks that the environment contains the expected image metadata. 383 func checkImageMetadata(c *gc.C, stor storage.StorageReader, expected []*imagemetadata.ImageMetadata) { 384 metadata := imtesting.ParseMetadataFromStorage(c, stor) 385 c.Assert(metadata, gc.HasLen, 1) 386 c.Assert(expected[0], gc.DeepEquals, metadata[0]) 387 } 388 389 func (s *BootstrapSuite) TestUploadLocalImageMetadata(c *gc.C) { 390 sourceDir, expected := createImageMetadata(c) 391 env, fake := makeEmptyFakeHome(c) 392 defer fake.Restore() 393 394 // Bootstrap the environment with the valid source. 395 ctx := coretesting.Context(c) 396 code := cmd.Main(&BootstrapCommand{}, ctx, []string{"--metadata-source", sourceDir}) 397 c.Check(code, gc.Equals, 0) 398 c.Assert(imagemetadata.DefaultBaseURL, gc.Equals, imagemetadata.UbuntuCloudImagesURL) 399 400 // Now check the image metadata has been uploaded. 401 checkImageMetadata(c, env.Storage(), expected) 402 } 403 404 func (s *BootstrapSuite) TestAutoSyncLocalSource(c *gc.C) { 405 sourceDir := createToolsSource(c, vAll) 406 s.PatchValue(&version.Current.Number, version.MustParse("1.2.0")) 407 env, fake := makeEmptyFakeHome(c) 408 defer fake.Restore() 409 410 // Bootstrap the environment with the valid source. 411 // The bootstrapping has to show no error, because the tools 412 // are automatically synchronized. 413 ctx := coretesting.Context(c) 414 code := cmd.Main(&BootstrapCommand{}, ctx, []string{"--metadata-source", sourceDir}) 415 c.Check(code, gc.Equals, 0) 416 417 // Now check the available tools which are the 1.2.0 envtools. 418 checkTools(c, env, v120All) 419 } 420 421 func (s *BootstrapSuite) setupAutoUploadTest(c *gc.C, vers, series string) environs.Environ { 422 s.PatchValue(&sync.Upload, mockUploadTools) 423 sourceDir := createToolsSource(c, vAll) 424 s.PatchValue(&envtools.DefaultBaseURL, sourceDir) 425 426 // Change the tools location to be the test location and also 427 // the version and ensure their later restoring. 428 // Set the current version to be something for which there are no tools 429 // so we can test that an upload is forced. 430 origVersion := version.Current 431 version.Current.Number = version.MustParse(vers) 432 version.Current.Series = series 433 s.AddCleanup(func(*gc.C) { version.Current = origVersion }) 434 435 // Create home with dummy provider and remove all 436 // of its envtools. 437 env, fake := makeEmptyFakeHome(c) 438 s.AddCleanup(func(*gc.C) { fake.Restore() }) 439 return env 440 } 441 442 func (s *BootstrapSuite) TestAutoUploadAfterFailedSync(c *gc.C) { 443 otherSeries := "precise" 444 if otherSeries == version.Current.Series { 445 otherSeries = "raring" 446 } 447 env := s.setupAutoUploadTest(c, "1.7.3", otherSeries) 448 // Run command and check for that upload has been run for tools matching the current juju version. 449 opc, errc := runCommand(nullContext(), new(BootstrapCommand)) 450 c.Assert(<-errc, gc.IsNil) 451 c.Assert((<-opc).(dummy.OpPutFile).Env, gc.Equals, "peckham") 452 list, err := envtools.FindTools(env, version.Current.Major, version.Current.Minor, coretools.Filter{}, false) 453 c.Assert(err, gc.IsNil) 454 c.Logf("found: " + list.String()) 455 urls := list.URLs() 456 c.Assert(urls, gc.HasLen, 2) 457 expectedVers := []version.Binary{ 458 version.MustParseBinary(fmt.Sprintf("1.7.3.1-%s-%s", otherSeries, version.Current.Arch)), 459 version.MustParseBinary(fmt.Sprintf("1.7.3.1-%s-%s", version.Current.Series, version.Current.Arch)), 460 } 461 for _, vers := range expectedVers { 462 c.Logf("seeking: " + vers.String()) 463 _, found := urls[vers] 464 c.Check(found, gc.Equals, true) 465 } 466 } 467 468 func (s *BootstrapSuite) TestAutoUploadOnlyForDev(c *gc.C) { 469 s.setupAutoUploadTest(c, "1.8.3", "precise") 470 _, errc := runCommand(nullContext(), new(BootstrapCommand)) 471 err := <-errc 472 c.Assert(err, gc.ErrorMatches, "cannot find bootstrap tools: no matching tools available") 473 } 474 475 func (s *BootstrapSuite) TestMissingToolsError(c *gc.C) { 476 s.setupAutoUploadTest(c, "1.8.3", "precise") 477 context := coretesting.Context(c) 478 code := cmd.Main(&BootstrapCommand{}, context, nil) 479 c.Assert(code, gc.Equals, 1) 480 errText := context.Stderr.(*bytes.Buffer).String() 481 errText = strings.Replace(errText, "\n", "", -1) 482 expectedErrText := "error: cannot find bootstrap tools: no matching tools available" 483 c.Assert(errText, gc.Matches, expectedErrText) 484 } 485 486 func uploadToolsAlwaysFails(stor storage.Storage, forceVersion *version.Number, series ...string) (*coretools.Tools, error) { 487 return nil, fmt.Errorf("an error") 488 } 489 490 func (s *BootstrapSuite) TestMissingToolsUploadFailedError(c *gc.C) { 491 s.setupAutoUploadTest(c, "1.7.3", "precise") 492 s.PatchValue(&sync.Upload, uploadToolsAlwaysFails) 493 context := coretesting.Context(c) 494 code := cmd.Main(&BootstrapCommand{}, context, nil) 495 c.Assert(code, gc.Equals, 1) 496 errText := context.Stderr.(*bytes.Buffer).String() 497 errText = strings.Replace(errText, "\n", "", -1) 498 expectedErrText := "error: cannot find bootstrap tools: an error" 499 c.Assert(errText, gc.Matches, expectedErrText) 500 } 501 502 func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) { 503 _, fake := makeEmptyFakeHome(c) 504 defer fake.Restore() 505 opc, errc := runCommand(nullContext(), new(BootstrapCommand), "-e", "brokenenv") 506 err := <-errc 507 c.Assert(err, gc.ErrorMatches, "dummy.Bootstrap is broken") 508 var opDestroy *dummy.OpDestroy 509 for opDestroy == nil { 510 select { 511 case op := <-opc: 512 switch op := op.(type) { 513 case dummy.OpDestroy: 514 opDestroy = &op 515 } 516 default: 517 c.Error("expected call to env.Destroy") 518 return 519 } 520 } 521 c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken") 522 } 523 524 // createToolsSource writes the mock tools and metadata into a temporary 525 // directory and returns it. 526 func createToolsSource(c *gc.C, versions []version.Binary) string { 527 versionStrings := make([]string, len(versions)) 528 for i, vers := range versions { 529 versionStrings[i] = vers.String() 530 } 531 source := c.MkDir() 532 ttesting.MakeTools(c, source, "releases", versionStrings) 533 return source 534 } 535 536 // makeEmptyFakeHome creates a faked home without envtools. 537 func makeEmptyFakeHome(c *gc.C) (environs.Environ, *coretesting.FakeHome) { 538 fake := coretesting.MakeFakeHome(c, envConfig) 539 dummy.Reset() 540 store, err := configstore.Default() 541 c.Assert(err, gc.IsNil) 542 env, err := environs.PrepareFromName("peckham", nullContext(), store) 543 c.Assert(err, gc.IsNil) 544 envtesting.RemoveAllTools(c, env) 545 return env, fake 546 } 547 548 // checkTools check if the environment contains the passed envtools. 549 func checkTools(c *gc.C, env environs.Environ, expected []version.Binary) { 550 list, err := envtools.FindTools( 551 env, version.Current.Major, version.Current.Minor, coretools.Filter{}, envtools.DoNotAllowRetry) 552 c.Check(err, gc.IsNil) 553 c.Logf("found: " + list.String()) 554 urls := list.URLs() 555 c.Check(urls, gc.HasLen, len(expected)) 556 } 557 558 var ( 559 v100d64 = version.MustParseBinary("1.0.0-raring-amd64") 560 v100p64 = version.MustParseBinary("1.0.0-precise-amd64") 561 v100q32 = version.MustParseBinary("1.0.0-quantal-i386") 562 v100q64 = version.MustParseBinary("1.0.0-quantal-amd64") 563 v120d64 = version.MustParseBinary("1.2.0-raring-amd64") 564 v120p64 = version.MustParseBinary("1.2.0-precise-amd64") 565 v120q32 = version.MustParseBinary("1.2.0-quantal-i386") 566 v120q64 = version.MustParseBinary("1.2.0-quantal-amd64") 567 v190p32 = version.MustParseBinary("1.9.0-precise-i386") 568 v190q64 = version.MustParseBinary("1.9.0-quantal-amd64") 569 v200p64 = version.MustParseBinary("2.0.0-precise-amd64") 570 v100All = []version.Binary{ 571 v100d64, v100p64, v100q64, v100q32, 572 } 573 v120All = []version.Binary{ 574 v120d64, v120p64, v120q64, v120q32, 575 } 576 vAll = []version.Binary{ 577 v100d64, v100p64, v100q32, v100q64, 578 v120d64, v120p64, v120q32, v120q64, 579 v190p32, v190q64, 580 v200p64, 581 } 582 )