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, ¤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, 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) }
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} }
// 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) }
// 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.*") }
func toolsStoragePath(vers string) string { return environs.ToolsStoragePath(version.Binary{ Number: version.MustParse(vers), Series: version.Current.Series, Arch: version.Current.Arch, }) }
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) } }
// 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) } }
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)) } } }
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() }
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() } } }
func (s *UpgraderSuite) removeVersion(c *C, vers version.Binary) { path := environs.ToolsStoragePath(vers) err := s.Conn.Environ.Storage().Remove(path) c.Assert(err, IsNil) }
func (s *UpgraderSuite) poisonVersion(vers version.Binary) { path := environs.ToolsStoragePath(vers) dummy.Poison(s.Conn.Environ.Storage(), path, fmt.Errorf("poisoned file")) }
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") }
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{