func (s *StorageSuite) TestSetToolPrefix(c *gc.C) { vers := version.MustParseBinary("1.2.3-precise-amd64") tools.SetToolPrefix("test_prefix/juju-") path := tools.StorageName(vers) c.Assert(path, gc.Equals, "test_prefix/juju-1.2.3-precise-amd64.tgz") tools.SetToolPrefix(tools.DefaultToolPrefix) path = tools.StorageName(vers) c.Assert(path, gc.Equals, "tools/juju-1.2.3-precise-amd64.tgz") }
func (s *agentSuite) uploadTools(c *C, vers version.Binary) *tools.Tools { tgz := coretesting.TarGz( coretesting.NewTarFile("jujud", 0777, "jujud contents "+vers.String()), ) storage := s.Conn.Environ.Storage() err := storage.Put(tools.StorageName(vers), bytes.NewReader(tgz), int64(len(tgz))) c.Assert(err, IsNil) url, err := s.Conn.Environ.Storage().URL(tools.StorageName(vers)) c.Assert(err, IsNil) return &tools.Tools{URL: url, Binary: vers} }
// RemoveFakeTools deletes the fake tools from the supplied storage. func RemoveFakeTools(c *C, storage environs.Storage) { toolsVersion := version.Current name := tools.StorageName(toolsVersion) err := storage.Remove(name) c.Check(err, IsNil) if version.Current.Series != config.DefaultSeries { toolsVersion.Series = config.DefaultSeries name := tools.StorageName(toolsVersion) err := storage.Remove(name) c.Check(err, IsNil) } }
// uploadTools uploads fake tools with the given version number // to the dummy environment's storage and returns a tools // value describing them. func (s *UpgraderSuite) uploadTools(c *gc.C, vers version.Binary) *tools.Tools { // TODO(rog) make UploadFakeToolsVersion in environs/testing // sufficient for this use case. tgz := coretesting.TarGz( coretesting.NewTarFile("jujud", 0777, "jujud contents "+vers.String()), ) storage := s.Conn.Environ.Storage() err := storage.Put(tools.StorageName(vers), bytes.NewReader(tgz), int64(len(tgz))) c.Assert(err, gc.IsNil) url, err := s.Conn.Environ.Storage().URL(tools.StorageName(vers)) c.Assert(err, gc.IsNil) return &tools.Tools{URL: url, Version: vers} }
func copyOne( tool *tools.Tools, source environs.StorageReader, target environs.Storage, ctx *cmd.Context, ) error { toolsName := tools.StorageName(tool.Binary) fmt.Fprintf(ctx.Stderr, "copying %v", toolsName) srcFile, err := source.Get(toolsName) if err != nil { return err } defer srcFile.Close() // We have to buffer the content, because Put requires the content // length, but Get only returns us a ReadCloser buf := &bytes.Buffer{} nBytes, err := io.Copy(buf, srcFile) if err != nil { return err } log.Infof("downloaded %v (%dkB), uploading", toolsName, (nBytes+512)/1024) fmt.Fprintf(ctx.Stderr, ", download %dkB, uploading\n", (nBytes+512)/1024) if err := target.Put(toolsName, buf, nBytes); err != nil { return err } return nil }
// putBinary stores a faked binary in the test directory. func putBinary(c *gc.C, storagePath string, v version.Binary) { data := v.String() name := tools.StorageName(v) filename := filepath.Join(storagePath, name) dir := filepath.Dir(filename) err := os.MkdirAll(dir, 0755) c.Assert(err, gc.IsNil) err = ioutil.WriteFile(filename, []byte(data), 0666) c.Assert(err, gc.IsNil) }
func (s *UpgradeJujuSuite) TestUpgradeJujuWithRealUpload(c *C) { s.Reset(c) _, err := coretesting.RunCommand(c, &UpgradeJujuCommand{}, []string{"--upload-tools"}) c.Assert(err, IsNil) vers := version.Current vers.Build = 1 name := tools.StorageName(vers) r, err := s.Conn.Environ.Storage().Get(name) c.Assert(err, IsNil) r.Close() }
func uploadFakeToolsVersion(storage environs.Storage, vers version.Binary) (*tools.Tools, error) { data := vers.String() name := tools.StorageName(vers) log.Noticef("environs/testing: uploading FAKE tools %s", vers) if err := storage.Put(name, strings.NewReader(data), int64(len(data))); err != nil { return nil, err } url, err := storage.URL(name) if err != nil { return nil, err } return &tools.Tools{Binary: vers, URL: url}, nil }
// createToolsSource writes the mock tools into a temporary // derectory and returns it. func createToolsSource(c *gc.C) string { source := c.MkDir() for _, vers := range vAll { data := vers.String() name := tools.StorageName(vers) filename := filepath.Join(source, name) dir := filepath.Dir(filename) err := os.MkdirAll(dir, 0755) c.Assert(err, gc.IsNil) err = ioutil.WriteFile(filename, []byte(data), 0666) c.Assert(err, gc.IsNil) } return source }
// PutBinary stores a faked binary in the HTTP test storage. func (s *EC2HTTPTestStorage) PutBinary(v version.Binary) { data := v.String() name := tools.StorageName(v) parts := strings.Split(name, "/") if len(parts) > 1 { // Also create paths as entries. Needed for // the correct contents of the list bucket result. path := "" for i := 0; i < len(parts)-1; i++ { path = path + parts[i] + "/" s.files[path] = []byte{} } } s.files[name] = []byte(data) }
func (s *UpgraderSuite) TestUpgraderRetryAndChanged(c *gc.C) { oldTools := s.primeTools(c, version.MustParseBinary("5.4.3-foo-bar")) newTools := s.uploadTools(c, version.MustParseBinary("5.4.5-foo-bar")) err := statetesting.SetAgentVersion(s.State, newTools.Version.Number) c.Assert(err, gc.IsNil) retryc := make(chan time.Time) *upgrader.RetryAfter = func() <-chan time.Time { c.Logf("replacement retry after") return retryc } dummy.Poison(s.Conn.Environ.Storage(), tools.StorageName(newTools.Version), fmt.Errorf("a non-fatal dose")) u := upgrader.New(s.state.Upgrader(), s.machine.Tag(), s.DataDir()) defer u.Stop() for i := 0; i < 3; i++ { select { case retryc <- time.Now(): case <-time.After(coretesting.LongWait): c.Fatalf("upgrader did not retry (attempt %d)", i) } } // Make it upgrade to some newer tools that can be // downloaded ok; it should stop retrying, download // the newer tools and exit. newerTools := s.uploadTools(c, version.MustParseBinary("5.4.6-foo-bar")) err = statetesting.SetAgentVersion(s.State, newerTools.Version.Number) c.Assert(err, gc.IsNil) s.BackingState.Sync() done := make(chan error) go func() { done <- u.Wait() }() select { case err := <-done: c.Assert(err, gc.DeepEquals, &upgrader.UpgradeReadyError{ AgentName: s.machine.Tag(), OldTools: oldTools, NewTools: newerTools, DataDir: s.DataDir(), }) case <-time.After(coretesting.LongWait): c.Fatalf("upgrader did not quit after upgrading") } }
// copyOneToolsPackage copies one tool from the source to the target. func copyOneToolsPackage(tool *tools.Tools, ctx *SyncContext) error { toolsName := tools.StorageName(tool.Version) logger.Infof("copying %v", toolsName) srcFile, err := ctx.sourceStorage.Get(toolsName) if err != nil { return err } defer srcFile.Close() // We have to buffer the content, because Put requires the content // length, but Get only returns us a ReadCloser buf := &bytes.Buffer{} nBytes, err := io.Copy(buf, srcFile) if err != nil { return err } logger.Infof("downloaded %v (%dkB), uploading", toolsName, (nBytes+512)/1024) logger.Infof("download %dkB, uploading", (nBytes+512)/1024) if err := ctx.targetStorage.Put(toolsName, buf, nBytes); err != nil { return err } return nil }
func (s *StorageSuite) TestStorageName(c *gc.C) { vers := version.MustParseBinary("1.2.3-precise-amd64") path := tools.StorageName(vers) c.Assert(path, gc.Equals, "tools/juju-1.2.3-precise-amd64.tgz") }
func (s *UpgraderSuite) poisonVersion(vers version.Binary) { name := tools.StorageName(vers) dummy.Poison(s.Conn.Environ.Storage(), name, fmt.Errorf("poisoned file")) }
func (s *UpgradeJujuSuite) TestUpgradeJuju(c *C) { oldVersion := version.Current uploadTools = mockUploadTools defer func() { version.Current = oldVersion uploadTools = tools.Upload }() for i, test := range upgradeJujuTests { c.Logf("\ntest %d: %s", i, test.about) s.Reset(c) // Set up apparent CLI version and initialize the command. version.Current = version.MustParseBinary(test.currentVersion) com := &UpgradeJujuCommand{} if err := coretesting.InitCommand(com, test.args); err != nil { if test.expectInitErr != "" { c.Check(err, ErrorMatches, test.expectInitErr) } else { c.Check(err, IsNil) } continue } // Set up state and environ, and run the command. cfg, err := s.State.EnvironConfig() c.Assert(err, IsNil) cfg, err = cfg.Apply(map[string]interface{}{ "agent-version": test.agentVersion, "development": test.development, }) c.Assert(err, IsNil) err = s.State.SetEnvironConfig(cfg) c.Assert(err, IsNil) for _, v := range test.private { vers := version.MustParseBinary(v) envtesting.MustUploadFakeToolsVersion(s.Conn.Environ.Storage(), vers) } for _, v := range test.public { vers := version.MustParseBinary(v) storage := s.Conn.Environ.PublicStorage().(environs.Storage) envtesting.MustUploadFakeToolsVersion(storage, vers) } err = com.Run(coretesting.Context(c)) if test.expectErr != "" { c.Check(err, ErrorMatches, test.expectErr) continue } else if !c.Check(err, IsNil) { continue } // Check expected changes to environ/state. cfg, err = s.State.EnvironConfig() c.Check(err, IsNil) agentVersion, ok := cfg.AgentVersion() c.Check(ok, Equals, true) c.Check(agentVersion, Equals, version.MustParse(test.expectVersion)) c.Check(cfg.Development(), Equals, test.development) for _, uploaded := range test.expectUploaded { vers := version.MustParseBinary(uploaded) r, err := s.Conn.Environ.Storage().Get(tools.StorageName(vers)) if !c.Check(err, IsNil) { continue } data, err := ioutil.ReadAll(r) r.Close() c.Check(err, IsNil) c.Check(string(data), Equals, uploaded) } } }
func (s *UpgraderSuite) removeVersion(c *C, vers version.Binary) { name := tools.StorageName(vers) err := s.Conn.Environ.Storage().Remove(name) c.Assert(err, IsNil) }
func (t *LiveTests) TestBootstrapWithDefaultSeries(c *C) { if !t.HasProvisioner { c.Skip("HasProvisioner is false; cannot test deployment") } current := version.Current other := current other.Series = "quantal" if current == other { other.Series = "precise" } cfg := t.Env.Config() cfg, err := cfg.Apply(map[string]interface{}{"default-series": other.Series}) c.Assert(err, IsNil) env, err := environs.New(cfg) c.Assert(err, IsNil) dummyenv, err := environs.NewFromAttrs(map[string]interface{}{ "type": "dummy", "name": "dummy storage", "secret": "pizza", "state-server": false, "ca-cert": coretesting.CACert, "ca-private-key": coretesting.CAKey, }) c.Assert(err, IsNil) defer dummyenv.Destroy(nil) // BUG: We destroy the environment, then write to its storage. // This is bogus, strictly speaking, but it works on // existing providers for the time being and means // this test does not fail when the environment is // already bootstrapped. t.Destroy(c) currentName := tools.StorageName(current) otherName := tools.StorageName(other) envStorage := env.Storage() dummyStorage := dummyenv.Storage() defer envStorage.Remove(otherName) _, err = tools.Upload(dummyStorage, ¤t.Number) c.Assert(err, IsNil) // This will only work while cross-compiling across releases is safe, // which depends on external elements. Tends to be safe for the last // few releases, but we may have to refactor some day. err = storageCopy(dummyStorage, currentName, envStorage, otherName) c.Assert(err, IsNil) err = environs.Bootstrap(env, constraints.Value{}) c.Assert(err, IsNil) defer env.Destroy(nil) conn, err := juju.NewConn(env) c.Assert(err, IsNil) defer conn.Close() // Wait for machine agent to come up on the bootstrap // machine and ensure it deployed the proper series. m0, err := conn.State.Machine("0") c.Assert(err, IsNil) mw0 := newMachineToolWaiter(m0) defer mw0.Stop() waitAgentTools(c, mw0, other) }