func (s *localJujuTestSuite) makeFakeUpstartScripts(c *gc.C, env environs.Environ, ) (mongoService *upstart.Service, machineAgent *upstart.Service) { upstartDir := c.MkDir() s.PatchValue(&upstart.InitDir, upstartDir) s.MakeTool(c, "start", `echo "some-service start/running, process 123"`) namespace := env.Config().AllAttrs()["namespace"].(string) mongoConf := common.Conf{ Desc: "fake mongo", Cmd: "echo FAKE", } mongoService = upstart.NewService(mongo.ServiceName(namespace), mongoConf) err := mongoService.Install() c.Assert(err, gc.IsNil) c.Assert(mongoService.Installed(), jc.IsTrue) agentConf := common.Conf{ Desc: "fake agent", Cmd: "echo FAKE", } machineAgent = upstart.NewService(fmt.Sprintf("juju-agent-%s", namespace), agentConf) err = machineAgent.Install() c.Assert(err, gc.IsNil) c.Assert(machineAgent.Installed(), jc.IsTrue) return mongoService, machineAgent }
func newService(name string, conf common.Conf, initSystem, series string) (Service, error) { switch initSystem { case InitSystemWindows: svc, err := windows.NewService(name, conf) if err != nil { return nil, errors.Annotatef(err, "failed to wrap service %q", name) } return svc, nil case InitSystemUpstart: return upstart.NewService(name, conf), nil case InitSystemSystemd: dataDir, err := paths.DataDir(series) if err != nil { return nil, errors.Annotatef(err, "failed to find juju data dir for service %q", name) } svc, err := systemd.NewService(name, conf, dataDir) if err != nil { return nil, errors.Annotatef(err, "failed to wrap service %q", name) } return svc, nil default: return nil, errors.NotFoundf("init system %q", initSystem) } }
// upstartService returns the upstart config for the mongo state service. // It also returns the path to the mongod executable that the upstart config // will be using. func upstartService(namespace, dataDir, dbDir, mongoPath string, port, oplogSizeMB int) (*upstart.Service, error) { mongoCmd := mongoPath + " --auth" + " --dbpath=" + utils.ShQuote(dbDir) + " --sslOnNormalPorts" + " --sslPEMKeyFile " + utils.ShQuote(sslKeyPath(dataDir)) + " --sslPEMKeyPassword ignored" + " --port " + fmt.Sprint(port) + " --noprealloc" + " --syslog" + " --smallfiles" + " --journal" + " --keyFile " + utils.ShQuote(sharedSecretPath(dataDir)) + " --replSet " + ReplicaSetName + " --ipv6 " + " --oplogSize " + strconv.Itoa(oplogSizeMB) conf := common.Conf{ Desc: "juju state database", Limit: map[string]string{ "nofile": fmt.Sprintf("%d %d", maxFiles, maxFiles), "nproc": fmt.Sprintf("%d %d", maxProcs, maxProcs), }, Cmd: mongoCmd, } svc := upstart.NewService(ServiceName(namespace), conf) return svc, nil }
// NewService returns an interface to a service apropriate // for the current system func NewService(name string, conf common.Conf) Service { switch version.Current.OS { case version.Windows: svc := windows.NewService(name, conf) return svc default: return upstart.NewService(name, conf) } }
func (s *UpstartSuite) SetUpTest(c *gc.C) { s.testPath = c.MkDir() s.initDir = c.MkDir() s.PatchEnvPathPrepend(s.testPath) s.PatchValue(&upstart.InitDir, s.initDir) s.service = upstart.NewService( "some-application", common.Conf{ Desc: "some service", ExecStart: "/path/to/some-command", }, ) }
func (s *UpstartSuite) SetUpTest(c *gc.C) { s.testPath = c.MkDir() s.initDir = c.MkDir() s.PatchEnvPathPrepend(s.testPath) s.PatchValue(&upstart.InstallStartRetryAttempts, utils.AttemptStrategy{}) s.PatchValue(&upstart.InitDir, s.initDir) s.service = upstart.NewService( "some-service", common.Conf{ Desc: "some service", Cmd: "some command", }, ) }
func (s *UpstartSuite) TestInstallAlreadyRunning(c *gc.C) { pathTo := func(name string) string { return filepath.Join(s.testPath, name) } s.MakeTool(c, "status-stopped", `echo "some-application stop/waiting"`) s.MakeTool(c, "status-started", `echo "some-application start/running, process 123"`) s.MakeTool(c, "stop", fmt.Sprintf( "rm %s; ln -s %s %s", pathTo("status"), pathTo("status-stopped"), pathTo("status"), )) s.MakeTool(c, "start", fmt.Sprintf( "rm %s; ln -s %s %s", pathTo("status"), pathTo("status-started"), pathTo("status"), )) err := symlink.New(pathTo("status-started"), pathTo("status")) c.Assert(err, jc.ErrorIsNil) svc := upstart.NewService("some-application", s.dummyConf(c)) err = svc.Install() c.Assert(err, jc.ErrorIsNil) installed, err := svc.Running() c.Assert(err, jc.ErrorIsNil) c.Check(installed, jc.IsTrue) }
func (s *UpstartSuite) TestInitDir(c *gc.C) { svc := upstart.NewService("blah", common.Conf{}) c.Assert(svc.Conf.InitDir, gc.Equals, s.initDir) }
// RemoveService removes the mongoDB upstart service from this machine. func RemoveService(namespace string) error { svc := upstart.NewService(ServiceName(namespace), common.Conf{}) return upstartServiceStopAndRemove(svc) }
// EnsureAdminUser ensures that the specified user and password // are added to the admin database. // // This function will stop the Mongo service if it needs to add // the admin user, as it must restart Mongo in --noauth mode. func EnsureAdminUser(p EnsureAdminUserParams) (added bool, err error) { portStr := strconv.Itoa(p.Port) localIPv4Addr := net.JoinHostPort("127.0.0.1", portStr) localIPv6Addr := net.JoinHostPort("::1", portStr) if len(p.DialInfo.Addrs) > 1 { // Verify the addresses are for different servers. for _, addr := range p.DialInfo.Addrs { switch addr { case localIPv4Addr, localIPv6Addr: continue default: logger.Infof("more than one state server; admin user must exist") return false, nil } } } p.DialInfo.Addrs = []string{localIPv4Addr, localIPv6Addr} p.DialInfo.Direct = true // Attempt to login to the admin database first. session, err := mgo.DialWithInfo(p.DialInfo) if err != nil { return false, fmt.Errorf("can't dial mongo to ensure admin user: %v", err) } session.SetSocketTimeout(SocketTimeout) err = session.DB("admin").Login(p.User, p.Password) session.Close() if err == nil { return false, nil } logger.Debugf("admin login failed: %v", err) // Login failed, so we need to add the user. // Stop mongo, so we can start it in --noauth mode. mongoServiceName := ServiceName(p.Namespace) mongoService := upstart.NewService(mongoServiceName, common.Conf{}) if err := upstartServiceStop(mongoService); err != nil { return false, fmt.Errorf("failed to stop %v: %v", mongoServiceName, err) } // Start mongod in --noauth mode. logger.Debugf("starting mongo with --noauth") cmd, err := noauthCommand(p.DataDir, p.Port) if err != nil { return false, fmt.Errorf("failed to prepare mongod command: %v", err) } if err := cmd.Start(); err != nil { return false, fmt.Errorf("failed to start mongod: %v", err) } defer cmd.Process.Kill() // Add the user to the admin database. logger.Debugf("setting admin password") if session, err = mgo.DialWithInfo(p.DialInfo); err != nil { return false, fmt.Errorf("can't dial mongo to ensure admin user: %v", err) } err = SetAdminMongoPassword(session, p.User, p.Password) session.Close() if err != nil { return false, fmt.Errorf("failed to add %q to admin database: %v", p.User, err) } logger.Infof("added %q to admin database", p.User) // Restart mongo using upstart. if err := processSignal(cmd.Process, syscall.SIGTERM); err != nil { return false, fmt.Errorf("cannot kill mongod: %v", err) } if err := cmd.Wait(); err != nil { if _, ok := err.(*exec.ExitError); !ok { return false, fmt.Errorf("mongod did not cleanly terminate: %v", err) } } if err := upstartServiceStart(mongoService); err != nil { return false, err } return true, nil }