func (s *UnitSuite) TestUpgrade(c *gc.C) { machine, unit, _, currentTools := s.primeAgent(c) agent := s.newAgent(c, unit) newVers := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } newVers.Patch++ envtesting.AssertUploadFakeToolsVersions( c, s.DefaultToolsStorage, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), newVers) // The machine agent downloads the tools; fake this by // creating downloaded-tools.txt in data-dir/tools/<version>. toolsDir := agenttools.SharedToolsDir(s.DataDir(), newVers) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) toolsPath := filepath.Join(toolsDir, "downloaded-tools.txt") testTools := tools.Tools{Version: newVers, URL: "http://testing.invalid/tools"} data, err := json.Marshal(testTools) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(toolsPath, data, 0644) c.Assert(err, jc.ErrorIsNil) // Set the machine agent version to trigger an upgrade. err = machine.SetAgentVersion(newVers) c.Assert(err, jc.ErrorIsNil) err = runWithTimeout(agent) envtesting.CheckUpgraderReadyError(c, err, &upgrader.UpgradeReadyError{ AgentName: unit.Tag().String(), OldTools: currentTools.Version, NewTools: newVers, DataDir: s.DataDir(), }) }
func (fix *SimpleToolsFixture) SetUp(c *gc.C, dataDir string) { fix.BaseSuite.SetUpTest(c) fix.dataDir = dataDir fix.initDir = c.MkDir() fix.logDir = c.MkDir() toolsDir := tools.SharedToolsDir(fix.dataDir, version.Current) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, gc.IsNil) jujudPath := filepath.Join(toolsDir, "jujud") err = ioutil.WriteFile(jujudPath, []byte(fakeJujud), 0755) c.Assert(err, gc.IsNil) toolsPath := filepath.Join(toolsDir, "downloaded-tools.txt") testTools := coretools.Tools{Version: version.Current, URL: "http://testing.invalid/tools"} data, err := json.Marshal(testTools) c.Assert(err, gc.IsNil) err = ioutil.WriteFile(toolsPath, data, 0644) c.Assert(err, gc.IsNil) fix.binDir = c.MkDir() fix.origPath = os.Getenv("PATH") os.Setenv("PATH", fix.binDir+":"+fix.origPath) fix.makeBin(c, "status", `echo "blah stop/waiting"`) fix.makeBin(c, "stopped-status", `echo "blah stop/waiting"`) fix.makeBin(c, "started-status", `echo "blah start/running, process 666"`) fix.makeBin(c, "start", "cp $(which started-status) $(which status)") fix.makeBin(c, "stop", "cp $(which stopped-status) $(which status)") }
func (fix *SimpleToolsFixture) SetUp(c *gc.C, dataDir string) { fix.dataDir = dataDir fix.logDir = c.MkDir() current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } toolsDir := tools.SharedToolsDir(fix.dataDir, current) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) jujudPath := filepath.Join(toolsDir, "jujud") err = ioutil.WriteFile(jujudPath, []byte(fakeJujud), 0755) c.Assert(err, jc.ErrorIsNil) toolsPath := filepath.Join(toolsDir, "downloaded-tools.txt") testTools := coretools.Tools{Version: current, URL: "http://testing.invalid/tools"} data, err := json.Marshal(testTools) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(toolsPath, data, 0644) c.Assert(err, jc.ErrorIsNil) fix.binDir = c.MkDir() fix.origPath = os.Getenv("PATH") os.Setenv("PATH", fix.binDir+":"+fix.origPath) fix.makeBin(c, "status", `echo "blah stop/waiting"`) fix.makeBin(c, "stopped-status", `echo "blah stop/waiting"`) fix.makeBin(c, "started-status", `echo "blah start/running, process 666"`) fix.makeBin(c, "start", "cp $(which started-status) $(which status)") fix.makeBin(c, "stop", "cp $(which stopped-status) $(which status)") fix.data = svctesting.NewFakeServiceData() }
func (s *BootstrapSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.PatchValue(&sshGenerateKey, func(name string) (string, string, error) { return "private-key", "public-key", nil }) s.MgoSuite.SetUpTest(c) s.dataDir = c.MkDir() s.logDir = c.MkDir() s.mongoOplogSize = "1234" s.fakeEnsureMongo = agenttesting.InstallFakeEnsureMongo(s) s.PatchValue(&maybeInitiateMongoServer, s.fakeEnsureMongo.InitiateMongo) // Create fake tools.tar.gz and downloaded-tools.txt. current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } toolsDir := filepath.FromSlash(agenttools.SharedToolsDir(s.dataDir, current)) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(filepath.Join(toolsDir, "tools.tar.gz"), nil, 0644) c.Assert(err, jc.ErrorIsNil) s.writeDownloadedTools(c, &tools.Tools{Version: current}) }
// populateTools stores uploaded tools in provider storage // and updates the tools metadata. func (c *BootstrapCommand) populateTools(st *state.State, env environs.Environ) error { agentConfig := c.CurrentConfig() dataDir := agentConfig.DataDir() current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } tools, err := agenttools.ReadTools(dataDir, current) if err != nil { return errors.Trace(err) } data, err := ioutil.ReadFile(filepath.Join( agenttools.SharedToolsDir(dataDir, current), "tools.tar.gz", )) if err != nil { return errors.Trace(err) } toolstorage, err := st.ToolsStorage() if err != nil { return errors.Trace(err) } defer toolstorage.Close() var toolsVersions []version.Binary if strings.HasPrefix(tools.URL, "file://") { // Tools were uploaded: clone for each series of the same OS. os, err := series.GetOSFromSeries(tools.Version.Series) if err != nil { return errors.Trace(err) } osSeries := series.OSSupportedSeries(os) for _, series := range osSeries { toolsVersion := tools.Version toolsVersion.Series = series toolsVersions = append(toolsVersions, toolsVersion) } } else { // Tools were downloaded from an external source: don't clone. toolsVersions = []version.Binary{tools.Version} } for _, toolsVersion := range toolsVersions { metadata := binarystorage.Metadata{ Version: toolsVersion.String(), Size: tools.Size, SHA256: tools.SHA256, } logger.Debugf("Adding tools: %v", toolsVersion) if err := toolstorage.Add(bytes.NewReader(data), metadata); err != nil { return errors.Trace(err) } } return nil }
func (s *ToolsSuite) SetUpTest(c *gc.C) { s.dataDir = c.MkDir() s.toolsDir = tools.SharedToolsDir(s.dataDir, version.Current) err := os.MkdirAll(s.toolsDir, 0755) c.Assert(err, gc.IsNil) err = symlink.New(s.toolsDir, tools.ToolsDir(s.dataDir, "unit-u-123")) c.Assert(err, gc.IsNil) }
func (s *BootstrapSuite) writeDownloadedTools(c *gc.C, tools *tools.Tools) { toolsDir := filepath.FromSlash(agenttools.SharedToolsDir(s.dataDir, tools.Version)) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) data, err := json.Marshal(tools) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(filepath.Join(toolsDir, "downloaded-tools.txt"), data, 0644) c.Assert(err, jc.ErrorIsNil) }
// populateTools stores uploaded tools in provider storage // and updates the tools metadata. // // TODO(axw) store tools in gridfs, catalogue in state. func (c *BootstrapCommand) populateTools(env environs.Environ) error { agentConfig := c.CurrentConfig() dataDir := agentConfig.DataDir() tools, err := agenttools.ReadTools(dataDir, version.Current) if err != nil { return err } if !strings.HasPrefix(tools.URL, "file://") { // Nothing to do since the tools were not uploaded. return nil } // This is a hack: providers using localstorage (local, manual) // can't use storage during bootstrap as the localstorage worker // isn't running. Use filestorage instead. var stor storage.Storage storageDir := agentConfig.Value(agent.StorageDir) if storageDir != "" { stor, err = filestorage.NewFileStorageWriter(storageDir) if err != nil { return err } } else { stor = env.Storage() } // Create a temporary directory to contain source and cloned tools. tempDir, err := ioutil.TempDir("", "juju-sync-tools") if err != nil { return err } defer os.RemoveAll(tempDir) destTools := filepath.Join(tempDir, filepath.FromSlash(envtools.StorageName(tools.Version))) if err := os.MkdirAll(filepath.Dir(destTools), 0700); err != nil { return err } srcTools := filepath.Join( agenttools.SharedToolsDir(dataDir, version.Current), "tools.tar.gz", ) if err := utils.CopyFile(destTools, srcTools); err != nil { return err } // Until we catalogue tools in state, we clone the tools // for each of the supported series of the same OS. otherSeries := version.OSSupportedSeries(version.Current.OS) _, err = sync.SyncBuiltTools(stor, &sync.BuiltTools{ Version: tools.Version, Dir: tempDir, StorageName: envtools.StorageName(tools.Version), Sha256Hash: tools.SHA256, Size: tools.Size, }, otherSeries...) return err }
func (s *ToolsSuite) SetUpTest(c *gc.C) { s.dataDir = c.MkDir() s.toolsDir = tools.SharedToolsDir(s.dataDir, version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), }) err := os.MkdirAll(s.toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) err = symlink.New(s.toolsDir, tools.ToolsDir(s.dataDir, "unit-u-123")) c.Assert(err, jc.ErrorIsNil) }
func (t *ToolsSuite) TestReadToolsErrors(c *gc.C) { vers := version.MustParseBinary("1.2.3-precise-amd64") testTools, err := agenttools.ReadTools(t.dataDir, vers) c.Assert(testTools, gc.IsNil) c.Assert(err, gc.ErrorMatches, "cannot read tools metadata in tools directory: .*") dir := agenttools.SharedToolsDir(t.dataDir, vers) err = os.MkdirAll(dir, agenttools.DirPerm) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(filepath.Join(dir, agenttools.ToolsFile), []byte(" \t\n"), 0644) c.Assert(err, jc.ErrorIsNil) testTools, err = agenttools.ReadTools(t.dataDir, vers) c.Assert(testTools, gc.IsNil) c.Assert(err, gc.ErrorMatches, "invalid tools metadata in tools directory .*") }
// assertToolsContents asserts that the directory for the tools // has the given contents. func (t *ToolsSuite) assertToolsContents(c *gc.C, testTools *coretest.Tools, files []*testing.TarFile) { var wantNames []string for _, f := range files { wantNames = append(wantNames, f.Header.Name) } wantNames = append(wantNames, agenttools.ToolsFile) dir := agenttools.SharedToolsDir(t.dataDir, testTools.Version) assertDirNames(c, dir, wantNames) expectedURLFileContents, err := json.Marshal(testTools) c.Assert(err, jc.ErrorIsNil) assertFileContents(c, dir, agenttools.ToolsFile, string(expectedURLFileContents), 0200) for _, f := range files { assertFileContents(c, dir, f.Header.Name, f.Contents, 0400) } gotTools, err := agenttools.ReadTools(t.dataDir, testTools.Version) c.Assert(err, jc.ErrorIsNil) c.Assert(*gotTools, gc.Equals, *testTools) }
func (s *BootstrapSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.PatchValue(&version.Current.Series, "trusty") // for predictable tools s.PatchValue(&sshGenerateKey, func(name string) (string, string, error) { return "private-key", "public-key", nil }) s.MgoSuite.SetUpTest(c) s.dataDir = c.MkDir() s.logDir = c.MkDir() s.mongoOplogSize = "1234" s.fakeEnsureMongo = fakeEnsure{} // Create fake tools.tar.gz and downloaded-tools.txt. toolsDir := filepath.FromSlash(agenttools.SharedToolsDir(s.dataDir, version.Current)) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, gc.IsNil) err = ioutil.WriteFile(filepath.Join(toolsDir, "tools.tar.gz"), nil, 0644) c.Assert(err, gc.IsNil) s.writeDownloadedTools(c, &tools.Tools{Version: version.Current}) }
// JujuTools returns the directory where Juju tools are stored. func (cfg *InstanceConfig) JujuTools() string { return agenttools.SharedToolsDir(cfg.DataDir, cfg.AgentVersion()) }
func (cfg *MachineConfig) jujuTools() string { return agenttools.SharedToolsDir(cfg.DataDir, cfg.Tools.Version) }
func (t *ToolsSuite) TestSharedToolsDir(c *gc.C) { dir := agenttools.SharedToolsDir("/var/lib/juju", version.MustParseBinary("1.2.3-precise-amd64")) c.Assert(dir, gc.Equals, "/var/lib/juju/tools/1.2.3-precise-amd64") }