// 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 { tools, err := tools.ChangeAgentTools(e.DataDir, e.AgentName, e.NewTools.Version) if err != nil { return err } logger.Infof("upgraded from %v to %v (%q)", e.OldTools.Version, tools.Version, tools.URL) return nil }
func (t *ToolsSuite) TestChangeAgentTools(c *gc.C) { files := []*testing.TarFile{ testing.NewTarFile("jujuc", 0755, "juju executable"), testing.NewTarFile("jujud", 0755, "jujuc executable"), } testTools := &tools.Tools{ URL: "http://foo/bar1", Version: version.MustParseBinary("1.2.3-foo-bar"), } err := tools.UnpackTools(t.dataDir, testTools, bytes.NewReader(testing.TarGz(files...))) c.Assert(err, gc.IsNil) gotTools, err := tools.ChangeAgentTools(t.dataDir, "testagent", testTools.Version) c.Assert(err, gc.IsNil) c.Assert(*gotTools, gc.Equals, *testTools) assertDirNames(c, t.toolsDir(), []string{"1.2.3-foo-bar", "testagent"}) assertDirNames(c, tools.ToolsDir(t.dataDir, "testagent"), []string{"jujuc", "jujud", urlFile}) // Upgrade again to check that the link replacement logic works ok. files2 := []*testing.TarFile{ testing.NewTarFile("foo", 0755, "foo content"), testing.NewTarFile("bar", 0755, "bar content"), } tools2 := &tools.Tools{ URL: "http://foo/bar2", Version: version.MustParseBinary("1.2.4-foo-bar"), } err = tools.UnpackTools(t.dataDir, tools2, bytes.NewReader(testing.TarGz(files2...))) c.Assert(err, gc.IsNil) gotTools, err = tools.ChangeAgentTools(t.dataDir, "testagent", tools2.Version) c.Assert(err, gc.IsNil) c.Assert(*gotTools, gc.Equals, *tools2) assertDirNames(c, t.toolsDir(), []string{"1.2.3-foo-bar", "1.2.4-foo-bar", "testagent"}) assertDirNames(c, tools.ToolsDir(t.dataDir, "testagent"), []string{"foo", "bar", urlFile}) }
// primeAgent writes the configuration file and tools // for an agent with the given entity name. // It returns the agent's configuration and the current tools. func (s *agentSuite) primeAgent(c *C, tag, password string) (*agent.Conf, *tools.Tools) { agentTools := s.primeTools(c, version.Current) tools1, err := tools.ChangeAgentTools(s.DataDir(), tag, version.Current) c.Assert(err, IsNil) c.Assert(tools1, DeepEquals, agentTools) conf := &agent.Conf{ DataDir: s.DataDir(), StateInfo: s.StateInfo(c), APIInfo: s.APIInfo(c), } conf.StateInfo.Tag = tag conf.StateInfo.Password = password conf.APIInfo.Tag = tag conf.APIInfo.Password = password err = conf.Write() c.Assert(err, IsNil) return conf, agentTools }
func (ctx *SimpleContext) DeployUnit(unitName, initialPassword string) (err error) { // Check sanity. svc := ctx.upstartService(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.UnitTag(unitName) _, err = tools.ChangeAgentTools(ctx.dataDir, tag, version.Current) toolsDir := tools.ToolsDir(ctx.dataDir, tag) defer removeOnErr(&err, toolsDir) // Retrieve the state addresses. stateAddrs, err := ctx.addresser.StateAddresses() if err != nil { return err } apiAddrs, err := ctx.addresser.APIAddresses() if err != nil { return err } stateInfo := state.Info{ Addrs: stateAddrs, Tag: tag, CACert: ctx.caCert, } logger.Debugf("state addresses: %q", stateAddrs) apiInfo := api.Info{ Addrs: apiAddrs, Tag: tag, CACert: ctx.caCert, } logger.Debugf("API addresses: %q", apiAddrs) // Prepare the agent's configuration data. conf := &agent.Conf{ DataDir: ctx.dataDir, OldPassword: initialPassword, StateInfo: &stateInfo, APIInfo: &apiInfo, } 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(ctx.logDir, tag+".log") syslogConfigRenderer := syslog.NewForwardConfig(tag, stateAddrs) syslogConfigRenderer.ConfigDir = ctx.syslogConfigDir syslogConfigRenderer.ConfigFileName = fmt.Sprintf("26-juju-%s.conf", tag) if err := syslogConfigRenderer.Write(); err != nil { return err } ctx.syslogConfigPath = syslogConfigRenderer.ConfigFilePath() if err := syslog.Restart(); err != nil { logger.Warningf("installer: cannot restart syslog daemon: %v", err) } defer removeOnErr(&err, ctx.syslogConfigPath) cmd := strings.Join([]string{ path.Join(toolsDir, "jujud"), "unit", "--data-dir", conf.DataDir, "--unit-name", unitName, "--debug", // TODO: propagate debug state sensibly }, " ") uconf := &upstart.Conf{ Service: *svc, Desc: "juju unit agent for " + unitName, Cmd: cmd, Out: logPath, // Propagate the provider type enviroment variable. Env: map[string]string{ osenv.JujuProviderType: os.Getenv(osenv.JujuProviderType), }, } return uconf.Install() }