// primeAgent writes the configuration file and tools with version vers // for an agent with the given entity name. It returns the agent's // configuration and the current tools. func (s *agentSuite) primeAgent(c *gc.C, tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) { stor := s.Conn.Environ.Storage() agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), vers) err := envtools.MergeAndWriteMetadata(stor, coretools.List{agentTools}, envtools.DoNotWriteMirrors) c.Assert(err, gc.IsNil) tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag, vers) c.Assert(err, gc.IsNil) c.Assert(tools1, gc.DeepEquals, agentTools) stateInfo := s.StateInfo(c) apiInfo := s.APIInfo(c) conf, err := agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: s.DataDir(), Tag: tag, UpgradedToVersion: vers.Number, Password: password, Nonce: state.BootstrapNonce, StateAddresses: stateInfo.Addrs, APIAddresses: apiInfo.Addrs, CACert: stateInfo.CACert, }) conf.SetPassword(password) c.Assert(conf.Write(), gc.IsNil) s.primeAPIHostPorts(c) return conf, agentTools }
// PrimeAgentVersion writes the configuration file and tools with version // vers for an agent with the given entity name. It returns the agent's // configuration and the current tools. func (s *AgentSuite) PrimeAgentVersion(c *gc.C, tag names.Tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) { c.Logf("priming agent %s", tag.String()) stor, err := filestorage.NewFileStorageWriter(c.MkDir()) c.Assert(err, jc.ErrorIsNil) agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), "released", vers) err = envtools.MergeAndWriteMetadata(stor, "released", "released", coretools.List{agentTools}, envtools.DoNotWriteMirrors) tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag.String(), vers) c.Assert(err, jc.ErrorIsNil) c.Assert(tools1, gc.DeepEquals, agentTools) stateInfo := s.MongoInfo(c) apiInfo := s.APIInfo(c) paths := agent.DefaultPaths paths.DataDir = s.DataDir() conf, err := agent.NewAgentConfig( agent.AgentConfigParams{ Paths: paths, Tag: tag, UpgradedToVersion: vers.Number, Password: password, Nonce: agent.BootstrapNonce, StateAddresses: stateInfo.Addrs, APIAddresses: apiInfo.Addrs, CACert: stateInfo.CACert, Model: apiInfo.ModelTag, }) c.Assert(err, jc.ErrorIsNil) conf.SetPassword(password) c.Assert(conf.Write(), gc.IsNil) s.primeAPIHostPorts(c) return conf, agentTools }
// ChangeAgentTools does the actual agent upgrade. // It should be called just before an agent exits, so that // it will restart running the new tools. func (e *UpgradeReadyError) ChangeAgentTools() error { agentTools, err := tools.ChangeAgentTools(e.DataDir, e.AgentName, e.NewTools) if err != nil { return err } logger.Infof("upgraded from %v to %v (%q)", e.OldTools, agentTools.Version, agentTools.URL) return nil }
func (t *ToolsSuite) TestChangeAgentTools(c *gc.C) { files := []*testing.TarFile{ testing.NewTarFile("jujuc", agenttools.DirPerm, "juju executable"), testing.NewTarFile("jujud", agenttools.DirPerm, "jujuc executable"), } data, checksum := testing.TarGz(files...) testTools := &coretest.Tools{ URL: "http://foo/bar1", Version: version.MustParseBinary("1.2.3-quantal-amd64"), Size: int64(len(data)), SHA256: checksum, } err := agenttools.UnpackTools(t.dataDir, testTools, bytes.NewReader(data)) c.Assert(err, jc.ErrorIsNil) gotTools, err := agenttools.ChangeAgentTools(t.dataDir, "testagent", testTools.Version) c.Assert(err, jc.ErrorIsNil) c.Assert(*gotTools, gc.Equals, *testTools) assertDirNames(c, t.toolsDir(), []string{"1.2.3-quantal-amd64", "testagent"}) assertDirNames(c, agenttools.ToolsDir(t.dataDir, "testagent"), []string{"jujuc", "jujud", agenttools.ToolsFile}) // Upgrade again to check that the link replacement logic works ok. files2 := []*testing.TarFile{ testing.NewTarFile("quantal", agenttools.DirPerm, "foo content"), testing.NewTarFile("amd64", agenttools.DirPerm, "bar content"), } data2, checksum2 := testing.TarGz(files2...) tools2 := &coretest.Tools{ URL: "http://foo/bar2", Version: version.MustParseBinary("1.2.4-quantal-amd64"), Size: int64(len(data2)), SHA256: checksum2, } err = agenttools.UnpackTools(t.dataDir, tools2, bytes.NewReader(data2)) c.Assert(err, jc.ErrorIsNil) gotTools, err = agenttools.ChangeAgentTools(t.dataDir, "testagent", tools2.Version) c.Assert(err, jc.ErrorIsNil) c.Assert(*gotTools, gc.Equals, *tools2) assertDirNames(c, t.toolsDir(), []string{"1.2.3-quantal-amd64", "1.2.4-quantal-amd64", "testagent"}) assertDirNames(c, agenttools.ToolsDir(t.dataDir, "testagent"), []string{"quantal", "amd64", agenttools.ToolsFile}) }
// primeStateAgent writes the configuration file and tools with version vers // for an agent with the given entity name. It returns the agent's configuration // and the current tools. func (s *agentSuite) primeStateAgent( c *gc.C, tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) { agentTools := envtesting.PrimeTools(c, s.Conn.Environ.Storage(), s.DataDir(), vers) tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag, vers) c.Assert(err, gc.IsNil) c.Assert(tools1, gc.DeepEquals, agentTools) stateInfo := s.StateInfo(c) conf := writeStateAgentConfig(c, stateInfo, s.DataDir(), tag, password, vers) s.primeAPIHostPorts(c) return conf, agentTools }
// PrimeStateAgentVersion writes the configuration file and tools with // version vers for a state agent with the given entity name. It // returns the agent's configuration and the current tools. func (s *AgentSuite) PrimeStateAgentVersion(c *gc.C, tag names.Tag, password string, vers version.Binary) ( agent.ConfigSetterWriter, *coretools.Tools, ) { stor, err := filestorage.NewFileStorageWriter(c.MkDir()) c.Assert(err, jc.ErrorIsNil) agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), "released", vers) tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag.String(), vers) c.Assert(err, jc.ErrorIsNil) c.Assert(tools1, gc.DeepEquals, agentTools) conf := s.WriteStateAgentConfig(c, tag, password, vers, s.State.ModelTag()) s.primeAPIHostPorts(c) return conf, agentTools }
func (ctx *SimpleContext) DeployUnit(unitName, initialPassword string) (err error) { // Check sanity. renderer, err := shell.NewRenderer("") if err != nil { return errors.Trace(err) } svc, err := ctx.service(unitName, renderer) if err != nil { return errors.Trace(err) } installed, err := svc.Installed() if err != nil { return errors.Trace(err) } if installed { return fmt.Errorf("unit %q is already deployed", unitName) } // Link the current tools for use by the new agent. tag := names.NewUnitTag(unitName) dataDir := ctx.agentConfig.DataDir() logDir := ctx.agentConfig.LogDir() current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } toolsDir := tools.ToolsDir(dataDir, tag.String()) defer removeOnErr(&err, toolsDir) _, err = tools.ChangeAgentTools(dataDir, tag.String(), current) if err != nil { return errors.Trace(err) } result, err := ctx.api.ConnectionInfo() if err != nil { return errors.Trace(err) } logger.Debugf("state addresses: %q", result.StateAddresses) logger.Debugf("API addresses: %q", result.APIAddresses) containerType := ctx.agentConfig.Value(agent.ContainerType) namespace := ctx.agentConfig.Value(agent.Namespace) conf, err := agent.NewAgentConfig( agent.AgentConfigParams{ Paths: agent.Paths{ DataDir: dataDir, LogDir: logDir, MetricsSpoolDir: agent.DefaultPaths.MetricsSpoolDir, }, UpgradedToVersion: version.Current, Tag: tag, Password: initialPassword, Nonce: "unused", Model: ctx.agentConfig.Model(), // TODO: remove the state addresses here and test when api only. StateAddresses: result.StateAddresses, APIAddresses: result.APIAddresses, CACert: ctx.agentConfig.CACert(), Values: map[string]string{ agent.ContainerType: containerType, agent.Namespace: namespace, }, }) if err != nil { return errors.Trace(err) } if err := conf.Write(); err != nil { return err } defer removeOnErr(&err, conf.Dir()) // Install an init service that runs the unit agent. if err := service.InstallAndStart(svc); err != nil { return errors.Trace(err) } return nil }
func (ctx *SimpleContext) DeployUnit(unitName, initialPassword string) (err error) { // Check sanity. svc := ctx.service(unitName) if svc.Installed() { return fmt.Errorf("unit %q is already deployed", unitName) } // Link the current tools for use by the new agent. tag := names.NewUnitTag(unitName) dataDir := ctx.agentConfig.DataDir() logDir := ctx.agentConfig.LogDir() // TODO(dfc) _, err = tools.ChangeAgentTools(dataDir, tag.String(), version.Current) // TODO(dfc) toolsDir := tools.ToolsDir(dataDir, tag.String()) defer removeOnErr(&err, toolsDir) result, err := ctx.api.ConnectionInfo() if err != nil { return err } logger.Debugf("state addresses: %q", result.StateAddresses) logger.Debugf("API addresses: %q", result.APIAddresses) containerType := ctx.agentConfig.Value(agent.ContainerType) namespace := ctx.agentConfig.Value(agent.Namespace) conf, err := agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: dataDir, LogDir: logDir, UpgradedToVersion: version.Current.Number, Tag: tag, Password: initialPassword, Nonce: "unused", // TODO: remove the state addresses here and test when api only. StateAddresses: result.StateAddresses, APIAddresses: result.APIAddresses, CACert: ctx.agentConfig.CACert(), Values: map[string]string{ agent.ContainerType: containerType, agent.Namespace: namespace, }, }) if err != nil { return err } if err := conf.Write(); err != nil { return err } defer removeOnErr(&err, conf.Dir()) // Install an upstart job that runs the unit agent. logPath := path.Join(logDir, tag.String()+".log") cmd := strings.Join([]string{ filepath.FromSlash(path.Join(toolsDir, jujunames.Jujud)), "unit", "--data-dir", dataDir, "--unit-name", unitName, "--debug", // TODO: propagate debug state sensibly }, " ") // TODO(thumper): 2013-09-02 bug 1219630 // As much as I'd like to remove JujuContainerType now, it is still // needed as MAAS still needs it at this stage, and we can't fix // everything at once. sconf := common.Conf{ Desc: "juju unit agent for " + unitName, Cmd: cmd, Out: logPath, Env: map[string]string{ osenv.JujuContainerTypeEnvKey: containerType, }, InitDir: ctx.initDir, } svc.UpdateConfig(sconf) return svc.Install() }