Beispiel #1
0
// UploadTools uploads tools for the specified series and any other relevant series to
// the environment storage, after which it sets the agent-version. If forceVersion is true,
// we allow uploading even when the agent-version is already set in the environment.
func UploadTools(ctx environs.BootstrapContext, env environs.Environ, toolsArch *string, forceVersion bool, bootstrapSeries ...string) error {
	logger.Infof("checking that upload is possible")
	// Check the series are valid.
	for _, series := range bootstrapSeries {
		if _, err := ubuntu.SeriesVersion(series); err != nil {
			return err
		}
	}
	// See that we are allowed to upload the tools.
	if err := validateUploadAllowed(env, toolsArch, forceVersion); err != nil {
		return err
	}

	// Make storage interruptible.
	interrupted := make(chan os.Signal, 1)
	interruptStorage := make(chan struct{})
	ctx.InterruptNotify(interrupted)
	defer ctx.StopInterruptNotify(interrupted)
	defer close(interrupted)
	go func() {
		defer close(interruptStorage) // closing interrupts all uploads
		if _, ok := <-interrupted; ok {
			ctx.Infof("cancelling tools upload")
		}
	}()
	stor := newInterruptibleStorage(env.Storage(), interruptStorage)

	cfg := env.Config()
	explicitVersion := uploadVersion(version.Current.Number, nil)
	uploadSeries := SeriesToUpload(cfg, bootstrapSeries)
	ctx.Infof("uploading tools for series %s", uploadSeries)
	tools, err := sync.Upload(stor, &explicitVersion, uploadSeries...)
	if err != nil {
		return err
	}
	cfg, err = cfg.Apply(map[string]interface{}{
		"agent-version": tools.Version.Number.String(),
	})
	if err == nil {
		err = env.SetConfig(cfg)
	}
	if err != nil {
		return fmt.Errorf("failed to update environment configuration: %v", err)
	}
	return nil
}
Beispiel #2
0
func (t *LiveTests) BootstrapOnce(c *gc.C) {
	if t.bootstrapped {
		return
	}
	t.PrepareOnce(c)
	// We only build and upload tools if there will be a state agent that
	// we could connect to (actual live tests, rather than local-only)
	cons := constraints.MustParse("mem=2G")
	if t.CanOpenState {
		_, err := sync.Upload(t.Env.Storage(), nil, coretesting.FakeDefaultSeries)
		c.Assert(err, gc.IsNil)
	}
	t.UploadFakeTools(c, t.Env.Storage())
	err := bootstrap.EnsureNotBootstrapped(t.Env)
	c.Assert(err, gc.IsNil)
	err = bootstrap.Bootstrap(coretesting.Context(c), t.Env, environs.BootstrapParams{Constraints: cons})
	c.Assert(err, gc.IsNil)
	t.bootstrapped = true
}
Beispiel #3
0
// checkUpgrade sets the environment agent version and checks that
// all the provided watchers upgrade to the requested version.
func (t *LiveTests) checkUpgrade(c *gc.C, conn *juju.Conn, newVersion version.Binary, waiters ...*toolsWaiter) {
	c.Logf("putting testing version of juju tools")
	upgradeTools, err := sync.Upload(t.Env.Storage(), &newVersion.Number, newVersion.Series)
	c.Assert(err, gc.IsNil)
	// sync.Upload always returns tools for the series on which the tests are running.
	// We are only interested in checking the version.Number below so need to fake the
	// upgraded tools series to match that of newVersion.
	upgradeTools.Version.Series = newVersion.Series

	// Check that the put version really is the version we expect.
	c.Assert(upgradeTools.Version, gc.Equals, newVersion)
	err = statetesting.SetAgentVersion(conn.State, newVersion.Number)
	c.Assert(err, gc.IsNil)

	for i, w := range waiters {
		c.Logf("waiting for upgrade of %d: %v", i, w.tooler.String())

		waitAgentTools(c, w, newVersion)
		c.Logf("upgrade %d successful", i)
	}
}
Beispiel #4
0
func (t *LiveTests) TestBootstrapWithDefaultSeries(c *gc.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"
	}

	dummyCfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge(coretesting.Attrs{
		"state-server": false,
		"name":         "dummy storage",
	}))
	dummyenv, err := environs.Prepare(dummyCfg, coretesting.Context(c), configstore.NewMem())
	c.Assert(err, gc.IsNil)
	defer dummyenv.Destroy()

	t.Destroy(c)

	attrs := t.TestConfig.Merge(coretesting.Attrs{"default-series": other.Series})
	cfg, err := config.New(config.NoDefaults, attrs)
	c.Assert(err, gc.IsNil)
	env, err := environs.Prepare(cfg, coretesting.Context(c), t.ConfigStore)
	c.Assert(err, gc.IsNil)
	defer environs.Destroy(env, t.ConfigStore)

	currentName := envtools.StorageName(current)
	otherName := envtools.StorageName(other)
	envStorage := env.Storage()
	dummyStorage := dummyenv.Storage()

	defer envStorage.Remove(otherName)

	_, err = sync.Upload(dummyStorage, &current.Number)
	c.Assert(err, gc.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, gc.IsNil)

	err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
	c.Assert(err, gc.IsNil)

	conn, err := juju.NewConn(env)
	c.Assert(err, gc.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, gc.IsNil)
	mw0 := newMachineToolWaiter(m0)
	defer mw0.Stop()

	waitAgentTools(c, mw0, other)
}