Example #1
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 = "precise"
	if current == other {
		other.Series = "quantal"
	}

	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,
	})
	c.Assert(err, IsNil)
	defer dummyenv.Destroy(nil)

	currentPath := environs.ToolsStoragePath(current)
	otherPath := environs.ToolsStoragePath(other)
	envStorage := env.Storage()
	dummyStorage := dummyenv.Storage()

	defer envStorage.Remove(otherPath)

	_, err = environs.PutTools(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, currentPath, envStorage, otherPath)
	c.Assert(err, IsNil)

	err = environs.Bootstrap(env, false, panicWrite)
	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)
}
Example #2
0
func (t *ToolsSuite) TestPutGetTools(c *C) {
	tools, err := environs.PutTools(t.env.Storage(), nil)
	c.Assert(err, IsNil)
	c.Assert(tools.Binary, Equals, version.Current)
	c.Assert(tools.URL, Not(Equals), "")

	for i, get := range []func(dataDir string, t *state.Tools) error{
		getTools,
		getToolsWithTar,
	} {
		c.Logf("test %d", i)
		// Unarchive the tool executables into a temp directory.
		dataDir := c.MkDir()
		err = get(dataDir, tools)
		c.Assert(err, IsNil)

		dir := environs.ToolsDir(dataDir, version.Current)
		// Verify that each tool executes and produces some
		// characteristic output.
		for i, test := range commandTests {
			c.Logf("command test %d", i)
			out, err := exec.Command(filepath.Join(dir, test.cmd[0]), test.cmd[1:]...).CombinedOutput()
			if err != nil {
				c.Assert(err, FitsTypeOf, (*exec.ExitError)(nil))
			}
			c.Check(string(out), Matches, test.output)
		}
		data, err := ioutil.ReadFile(filepath.Join(dir, urlFile))
		c.Assert(err, IsNil)
		c.Assert(string(data), Equals, tools.URL)
	}
}
Example #3
0
func (t *ToolsSuite) TestPutToolsAndForceVersion(c *C) {
	// This test actually tests three things:
	//   the writing of the FORCE-VERSION file;
	//   the reading of the FORCE-VERSION file by the version package;
	//   and the reading of the version from jujud.
	vers := version.Current
	vers.Patch++
	tools, err := environs.PutTools(t.env.Storage(), &vers.Number)
	c.Assert(err, IsNil)
	c.Assert(tools.Binary, Equals, vers)
}
Example #4
0
func (e *environ) Bootstrap(uploadTools bool, cert, key []byte) error {
	defer delay()
	if err := e.checkBroken("Bootstrap"); err != nil {
		return err
	}
	password := e.Config().AdminSecret()
	if password == "" {
		return fmt.Errorf("admin-secret is required for bootstrap")
	}
	if _, ok := e.Config().CACert(); !ok {
		return fmt.Errorf("no CA certificate in environment configuration")
	}
	var tools *state.Tools
	var err error
	if uploadTools {
		tools, err = environs.PutTools(e.Storage(), nil)
		if err != nil {
			return err
		}
	} else {
		flags := environs.HighestVersion | environs.CompatVersion
		tools, err = environs.FindTools(e, version.Current, flags)
		if err != nil {
			return err
		}
	}
	e.state.mu.Lock()
	defer e.state.mu.Unlock()
	e.state.ops <- OpBootstrap{Env: e.state.name}
	if e.state.bootstrapped {
		return fmt.Errorf("environment is already bootstrapped")
	}
	if e.ecfg().stateServer() {
		info := stateInfo()
		cfg, err := environs.BootstrapConfig(&providerInstance, e.ecfg().Config, tools)
		if err != nil {
			return fmt.Errorf("cannot make bootstrap config: %v", err)
		}
		st, err := state.Initialize(info, cfg)
		if err != nil {
			panic(err)
		}
		if err := st.SetAdminMongoPassword(trivial.PasswordHash(password)); err != nil {
			return err
		}
		if err := st.Close(); err != nil {
			panic(err)
		}
	}
	e.state.bootstrapped = true
	return nil
}
Example #5
0
// checkUpgrade sets the environment agent version and checks that
// all the provided watchers upgrade to the requested version.
func (t *LiveTests) checkUpgrade(c *C, conn *juju.Conn, newVersion version.Binary, waiters ...*toolsWaiter) {
	c.Logf("putting testing version of juju tools")
	upgradeTools, err := environs.PutTools(t.Env.Storage(), &newVersion.Number)
	c.Assert(err, IsNil)

	// Check that the put version really is the version we expect.
	c.Assert(upgradeTools.Binary, Equals, newVersion)
	err = setAgentVersion(conn.State, newVersion.Number)
	c.Assert(err, 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)
	}
}
Example #6
0
// Test that the upload procedure fails correctly
// when the build process fails (because of a bad Go source
// file in this case).
func (t *ToolsSuite) TestUploadBadBuild(c *C) {
	gopath := c.MkDir()
	join := append([]string{gopath, "src"}, strings.Split("launchpad.net/juju-core/cmd/broken", "/")...)
	pkgdir := filepath.Join(join...)
	err := os.MkdirAll(pkgdir, 0777)
	c.Assert(err, IsNil)

	err = ioutil.WriteFile(filepath.Join(pkgdir, "broken.go"), []byte("nope"), 0666)
	c.Assert(err, IsNil)

	defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
	os.Setenv("GOPATH", gopath)

	tools, err := environs.PutTools(t.env.Storage(), nil)
	c.Assert(tools, IsNil)
	c.Assert(err, ErrorMatches, `build command "go" failed: exit status 1; can't load package:(.|\n)*`)
}
Example #7
0
func (e *environ) Bootstrap(uploadTools bool, cert, key []byte) error {
	password := e.Config().AdminSecret()
	if password == "" {
		return fmt.Errorf("admin-secret is required for bootstrap")
	}
	log.Printf("environs/ec2: bootstrapping environment %q", e.name)
	// If the state file exists, it might actually have just been
	// removed by Destroy, and eventual consistency has not caught
	// up yet, so we retry to verify if that is happening.
	var err error
	for a := shortAttempt.Start(); a.Next(); {
		_, err = e.loadState()
		if err != nil {
			break
		}
	}
	if err == nil {
		return fmt.Errorf("environment is already bootstrapped")
	}
	if _, notFound := err.(*environs.NotFoundError); !notFound {
		return fmt.Errorf("cannot query old bootstrap state: %v", err)
	}
	var tools *state.Tools
	if uploadTools {
		tools, err = environs.PutTools(e.Storage(), nil)
		if err != nil {
			return fmt.Errorf("cannot upload tools: %v", err)
		}
	} else {
		flags := environs.HighestVersion | environs.CompatVersion
		v := version.Current
		v.Series = e.Config().DefaultSeries()
		tools, err = environs.FindTools(e, v, flags)
		if err != nil {
			return fmt.Errorf("cannot find tools: %v", err)
		}
	}
	config, err := environs.BootstrapConfig(providerInstance, e.Config(), tools)
	if err != nil {
		return fmt.Errorf("unable to determine inital configuration: %v", err)
	}
	caCert, hasCert := e.Config().CACert()
	if !hasCert {
		return fmt.Errorf("no CA certificate in environment configuration")
	}
	info := &state.Info{
		Password: trivial.PasswordHash(password),
		CACert:   caCert,
	}
	inst, err := e.startInstance(&startInstanceParams{
		machineId:       "0",
		info:            info,
		tools:           tools,
		stateServer:     true,
		config:          config,
		stateServerCert: cert,
		stateServerKey:  key,
	})
	if err != nil {
		return fmt.Errorf("cannot start bootstrap instance: %v", err)
	}
	err = e.saveState(&bootstrapState{
		StateInstances: []state.InstanceId{inst.Id()},
	})
	if err != nil {
		// ignore error on StopInstance because the previous error is
		// more important.
		e.StopInstances([]environs.Instance{inst})
		return fmt.Errorf("cannot save state: %v", err)
	}
	// TODO make safe in the case of racing Bootstraps
	// If two Bootstraps are called concurrently, there's
	// no way to use S3 to make sure that only one succeeds.
	// Perhaps consider using SimpleDB for state storage
	// which would enable that possibility.

	return nil
}