Beispiel #1
0
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")
}
Beispiel #2
0
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}
}
Beispiel #3
0
// 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)
	}
}
Beispiel #4
0
// 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}
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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)
}
Beispiel #7
0
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()
}
Beispiel #8
0
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
}
Beispiel #9
0
// 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
}
Beispiel #10
0
// 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)
}
Beispiel #11
0
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")
	}
}
Beispiel #12
0
// 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
}
Beispiel #13
0
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"))
}
Beispiel #15
0
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)
}
Beispiel #17
0
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, &current.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)
}