// upstartService returns an upstart.Service corresponding to the specified // unit. func (ctx *SimpleContext) upstartService(unitName string) *upstart.Service { tag := state.UnitTag(unitName) svcName := "jujud-" + tag svc := upstart.NewService(svcName) svc.InitDir = ctx.initDir return svc }
func (ctx *SimpleContext) RecallUnit(unitName string) error { svc := ctx.findUpstartJob(unitName) if svc == nil || !svc.Installed() { return fmt.Errorf("unit %q is not deployed", unitName) } if err := svc.Remove(); err != nil { return err } tag := state.UnitTag(unitName) agentDir := agent.Dir(ctx.dataDir, tag) if err := os.RemoveAll(agentDir); err != nil { return err } if err := os.Remove(ctx.syslogConfigPath); err != nil && !os.IsNotExist(err) { logger.Warningf("installer: cannot remove %q: %v", ctx.syslogConfigPath, err) } // Defer this so a failure here does not impede the cleanup (as in tests). defer func() { if err := syslog.Restart(); err != nil { logger.Warningf("installer: cannot restart syslog daemon: %v", err) } }() toolsDir := agent.ToolsDir(ctx.dataDir, tag) return os.Remove(toolsDir) }
func (fix *SimpleToolsFixture) checkUnitInstalled(c *C, name, password string) { tag := state.UnitTag(name) uconfPath, _, toolsDir, syslogConfPath := fix.paths(tag) uconfData, err := ioutil.ReadFile(uconfPath) c.Assert(err, IsNil) uconf := string(uconfData) var execLine string for _, line := range strings.Split(uconf, "\n") { if strings.HasPrefix(line, "exec ") { execLine = line break } } if execLine == "" { c.Fatalf("no command found in %s:\n%s", uconfPath, uconf) } logPath := filepath.Join(fix.logDir, tag+".log") jujudPath := filepath.Join(toolsDir, "jujud") for _, pat := range []string{ "^exec " + jujudPath + " unit ", " --unit-name " + name + " ", " >> " + logPath + " 2>&1$", } { match, err := regexp.MatchString(pat, execLine) c.Assert(err, IsNil) if !match { c.Fatalf("failed to match:\n%s\nin:\n%s", pat, execLine) } } conf, err := agent.ReadConf(fix.dataDir, tag) c.Assert(err, IsNil) c.Assert(conf, DeepEquals, &agent.Conf{ DataDir: fix.dataDir, OldPassword: password, StateInfo: &state.Info{ Addrs: []string{"s1:123", "s2:123"}, CACert: []byte("test-cert"), Tag: tag, }, APIInfo: &api.Info{ Addrs: []string{"a1:123", "a2:123"}, CACert: []byte("test-cert"), Tag: tag, }, }) jujudData, err := ioutil.ReadFile(jujudPath) c.Assert(err, IsNil) c.Assert(string(jujudData), Equals, fakeJujud) syslogConfData, err := ioutil.ReadFile(syslogConfPath) c.Assert(err, IsNil) parts := strings.SplitN(name, "/", 2) unitTag := fmt.Sprintf("unit-%s-%s", parts[0], parts[1]) expectedSyslogConfReplaced := fmt.Sprintf(expectedSyslogConf, unitTag, unitTag, unitTag, unitTag) c.Assert(string(syslogConfData), Equals, expectedSyslogConfReplaced) }
func (fix *SimpleToolsFixture) checkUnitRemoved(c *C, name string) { tag := state.UnitTag(name) confPath, agentDir, toolsDir, syslogConfPath := fix.paths(tag) for _, path := range []string{confPath, agentDir, toolsDir, syslogConfPath} { _, err := ioutil.ReadFile(path) if err == nil { c.Log("Warning: %q not removed as expected", path) } else { c.Assert(err, checkers.Satisfies, os.IsNotExist) } } }
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 := state.UnitTag(unitName) _, err = agent.ChangeAgentTools(ctx.dataDir, tag, version.Current) toolsDir := agent.ToolsDir(ctx.dataDir, tag) defer removeOnErr(&err, toolsDir) // Retrieve addresses from state. stateAddrs, err := ctx.addresser.Addresses() 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, } apiInfo := api.Info{ Addrs: apiAddrs, Tag: tag, CACert: ctx.caCert, } // 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{ "JUJU_PROVIDER_TYPE": os.Getenv("JUJU_PROVIDER_TYPE"), }, } return uconf.Install() }
func (a *UnitAgent) Tag() string { return state.UnitTag(a.UnitName) }
func (s *UnitSuite) TestUnitTag(c *C) { c.Assert(state.UnitTag("wordpress/2"), Equals, "unit-wordpress-2") }