예제 #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)
}
예제 #2
0
func (s *agentSuite) uploadTools(c *C, vers version.Binary) *state.Tools {
	tgz := coretesting.TarGz(
		coretesting.NewTarFile("juju", 0777, "juju contents "+vers.String()),
		coretesting.NewTarFile("jujuc", 0777, "jujuc contents "+vers.String()),
		coretesting.NewTarFile("jujud", 0777, "jujud contents "+vers.String()),
	)
	storage := s.Conn.Environ.Storage()
	err := storage.Put(environs.ToolsStoragePath(vers), bytes.NewReader(tgz), int64(len(tgz)))
	c.Assert(err, IsNil)
	url, err := s.Conn.Environ.Storage().URL(environs.ToolsStoragePath(vers))
	c.Assert(err, IsNil)
	return &state.Tools{URL: url, Binary: vers}
}
예제 #3
0
// putFakeTools sets up a bucket containing something
// that looks like a tools archive so test methods
// that start an instance can succeed even though they
// do not upload tools.
func putFakeTools(c *C, s environs.StorageWriter) {
	path := environs.ToolsStoragePath(version.Current)
	c.Logf("putting fake tools at %v", path)
	toolsContents := "tools archive, honest guv"
	err := s.Put(path, strings.NewReader(toolsContents), int64(len(toolsContents)))
	c.Assert(err, IsNil)
}
예제 #4
0
// Check that we can't start an instance running tools
// that correspond with no available platform.
func (t *LiveTests) TestStartInstanceOnUnknownPlatform(c *C) {
	vers := version.Current
	// Note that we want this test to function correctly in the
	// dummy environment, so to avoid enumerating all possible
	// platforms in the dummy provider, it treats only series and/or
	// architectures with the "unknown" prefix as invalid.
	vers.Series = "unknownseries"
	vers.Arch = "unknownarch"
	name := environs.ToolsStoragePath(vers)
	storage := t.Env.Storage()
	checkPutFile(c, storage, name, []byte("fake tools on invalid series"))
	defer storage.Remove(name)

	url, err := storage.URL(name)
	c.Assert(err, IsNil)
	tools := &state.Tools{
		Binary: vers,
		URL:    url,
	}

	inst, err := t.Env.StartInstance("4", testing.InvalidStateInfo("4"), tools)
	if inst != nil {
		err := t.Env.StopInstances([]environs.Instance{inst})
		c.Check(err, IsNil)
	}
	c.Assert(inst, IsNil)
	c.Assert(err, ErrorMatches, "cannot find image.*")
}
예제 #5
0
func toolsStoragePath(vers string) string {
	return environs.ToolsStoragePath(version.Binary{
		Number: version.MustParse(vers),
		Series: version.Current.Series,
		Arch:   version.Current.Arch,
	})
}
예제 #6
0
func upload(s environs.Storage, v string) {
	vers := version.MustParseBinary(v)
	p := environs.ToolsStoragePath(vers)
	err := s.Put(p, strings.NewReader(v), int64(len(v)))
	if err != nil {
		panic(err)
	}
}
예제 #7
0
// putFakeTools writes something
// that looks like a tools archive so Bootstrap can
// find some tools and initialise the state correctly.
func putFakeTools(s environs.StorageWriter) {
	log.Printf("environs/dummy: putting fake tools")
	path := environs.ToolsStoragePath(version.Current)
	toolsContents := "tools archive, honest guv"
	err := s.Put(path, strings.NewReader(toolsContents), int64(len(toolsContents)))
	if err != nil {
		panic(err)
	}
}
예제 #8
0
func (t *ToolsSuite) TestListTools(c *C) {
	testList := []string{
		"foo",
		"tools/.tgz",
		"tools/juju-1.2.3-precise-i386.tgz",
		"tools/juju-2.2.3-precise-amd64.tgz",
		"tools/juju-2.2.3-precise-i386.tgz",
		"tools/juju-2.2.4-precise-i386.tgz",
		"tools/juju-2.2-precise-amd64.tgz",
		"tools/juju-3.2.1-quantal-amd64.tgz",
		"xtools/juju-2.2.3-precise-amd64.tgz",
	}

	// dummy always populates the tools set with version.Current.
	// Remove any tools in the public storage to ensure they don't
	// conflict with the list of tools we expect.
	ps := t.env.PublicStorage().(environs.Storage)
	tools, err := ps.List("")
	c.Assert(err, IsNil)
	for _, tool := range tools {
		ps.Remove(tool)
	}

	putNames(c, t.env, testList, testList)

	for i, test := range listToolsTests {
		c.Logf("test %d", i)
		toolsList, err := environs.ListTools(t.env, test.major)
		c.Assert(err, IsNil)
		c.Assert(toolsList.Private, HasLen, len(test.expect))
		c.Assert(toolsList.Public, HasLen, len(test.expect))
		for i, t := range toolsList.Private {
			vers := binaryVersion(test.expect[i])
			c.Assert(t.Binary, Equals, vers)
			assertURLContents(c, t.URL, environs.ToolsStoragePath(vers))
		}
		for i, t := range toolsList.Public {
			vers := binaryVersion(test.expect[i])
			c.Assert(t.Binary, Equals, vers)
			assertURLContents(c, t.URL, "public-"+environs.ToolsStoragePath(vers))
		}
	}
}
예제 #9
0
func (s *UpgradeJujuSuite) TestUpgradeJujuWithRealPutTools(c *C) {
	s.Reset(c)
	com := &UpgradeJujuCommand{}
	err := com.Init(newFlagSet(), []string{"--upload-tools", "--dev"})
	c.Assert(err, IsNil)
	err = com.Run(&cmd.Context{c.MkDir(), nil, ioutil.Discard, ioutil.Discard})
	c.Assert(err, IsNil)
	p := environs.ToolsStoragePath(version.Current)
	r, err := s.Conn.Environ.Storage().Get(p)
	c.Assert(err, IsNil)
	r.Close()
}
예제 #10
0
func (s *UpgradeJujuSuite) TestUpgradeJuju(c *C) {
	oldVersion := version.Current
	putTools = testPutTools
	defer func() {
		version.Current = oldVersion
		putTools = environs.PutTools
	}()

	for i, test := range upgradeJujuTests {
		c.Logf("%d. %s", i, test.about)
		// Set up the test preconditions.
		s.Reset(c)
		for _, v := range test.private {
			upload(s.Conn.Environ.Storage(), v)
		}
		for _, v := range test.public {
			storage := s.Conn.Environ.PublicStorage().(environs.Storage)
			upload(storage, v)
		}
		version.Current = version.MustParseBinary(test.currentVersion)
		err := SetAgentVersion(s.State, version.MustParse(test.agentVersion), false)
		c.Assert(err, IsNil)

		// Run the command
		com := &UpgradeJujuCommand{}
		err = com.Init(newFlagSet(), test.args)
		if test.expectInitErr != "" {
			c.Check(err, ErrorMatches, test.expectInitErr)
			continue
		}
		err = com.Run(&cmd.Context{c.MkDir(), nil, ioutil.Discard, ioutil.Discard})
		if test.expectErr != "" {
			c.Check(err, ErrorMatches, test.expectErr)
			continue
		}
		c.Assert(err, IsNil)
		cfg, err := s.State.EnvironConfig()
		c.Check(err, IsNil)
		c.Check(cfg.AgentVersion(), Equals, version.MustParse(test.expectVersion))
		c.Check(cfg.Development(), Equals, test.expectDevelopment)

		if test.expectUploaded != "" {
			p := environs.ToolsStoragePath(version.MustParseBinary(test.expectUploaded))
			r, err := s.Conn.Environ.Storage().Get(p)
			c.Assert(err, IsNil)
			data, err := ioutil.ReadAll(r)
			c.Check(err, IsNil)
			c.Check(string(data), Equals, test.expectUploaded)
			r.Close()
		}
	}
}
예제 #11
0
func (s *UpgraderSuite) removeVersion(c *C, vers version.Binary) {
	path := environs.ToolsStoragePath(vers)
	err := s.Conn.Environ.Storage().Remove(path)
	c.Assert(err, IsNil)
}
예제 #12
0
func (s *UpgraderSuite) poisonVersion(vers version.Binary) {
	path := environs.ToolsStoragePath(vers)
	dummy.Poison(s.Conn.Environ.Storage(), path, fmt.Errorf("poisoned file"))
}
예제 #13
0
func (t *ToolsSuite) TestToolsStoragePath(c *C) {
	c.Assert(environs.ToolsStoragePath(binaryVersion("1.2.3-precise-amd64")),
		Equals, "tools/juju-1.2.3-precise-amd64.tgz")
}
예제 #14
0
	os      string
	arch    string
}

var findToolsTests = []struct {
	version        version.Number // version to assume is current for the test.
	flags          environs.ToolsSearchFlags
	contents       []string // names in private storage.
	publicContents []string // names in public storage.
	expect         string   // the name we expect to find (if no error).
	err            string   // the error we expect to find (if not blank).
}{{
	// current version should be satisfied by current tools path.
	version:  version.Current.Number,
	flags:    environs.CompatVersion,
	contents: []string{environs.ToolsStoragePath(version.Current)},
	expect:   environs.ToolsStoragePath(version.Current),
}, {
	// highest version of tools is chosen.
	version: version.MustParse("0.0.0"),
	flags:   environs.HighestVersion | environs.DevVersion | environs.CompatVersion,
	contents: []string{
		toolsStoragePath("0.0.9"),
		toolsStoragePath("0.1.9"),
	},
	expect: toolsStoragePath("0.1.9"),
}, {
	// fall back to public storage when nothing found in private.
	version: version.MustParse("1.0.2"),
	flags:   environs.DevVersion | environs.CompatVersion,
	contents: []string{