コード例 #1
0
ファイル: app.go プロジェクト: justenwalker/containerpilot
// Terminate kills the application
func (a *App) Terminate() {
	a.signalLock.Lock()
	defer a.signalLock.Unlock()
	a.stopPolling()
	a.forAllServices(deregisterService)

	// Run and wait for preStop command to exit
	utils.RunWithFields(a.PreStopCmd, log.Fields{"process": "PreStop"})

	cmd := a.Command
	if cmd == nil || cmd.Process == nil {
		// Not managing the process, so don't do anything
		return
	}
	if a.StopTimeout > 0 {
		if err := cmd.Process.Signal(syscall.SIGTERM); err != nil {
			log.Warnf("Error sending SIGTERM to application: %s", err)
		} else {
			time.AfterFunc(time.Duration(a.StopTimeout)*time.Second, func() {
				log.Infof("Killing Process %#v", cmd.Process)
				cmd.Process.Kill()
			})
			return
		}
	}
	log.Infof("Killing Process %#v", a.Command.Process)
	cmd.Process.Kill()
}
コード例 #2
0
// OnChange runs the backend's onChange command, returning the results
func (b *Backend) OnChange() (int, error) {
	defer func() {
		// reset command object because it can't be reused
		b.onChangeCmd = utils.ArgsToCmd(b.onChangeCmd.Args)
	}()

	exitCode, err := utils.RunWithFields(b.onChangeCmd, log.Fields{"process": "OnChange", "backend": b.Name})
	return exitCode, err
}
コード例 #3
0
ファイル: app.go プロジェクト: justenwalker/containerpilot
// Run starts the application and blocks until finished
func (a *App) Run() {
	// Set up handlers for polling and to accept signal interrupts
	if 1 == os.Getpid() {
		reapChildren()
	}
	args := getArgs(flag.Args())
	command, err := utils.ParseCommandArgs(args)
	if err != nil {
		log.Errorf("Unable to parse command arguments: %v", err)
	}
	a.handleSignals()
	// Run the preStart handler, if any, and exit if it returns an error
	if preStartCode, err := utils.RunWithFields(a.PreStartCmd, log.Fields{"process": "PreStart"}); err != nil {
		os.Exit(preStartCode)
	}
	a.handleCoprocesses()
	a.handlePolling()

	if len(args) != 0 {
		// Run our main application and capture its stdout/stderr.
		// This will block until the main application exits and then os.Exit
		// with the exit code of that application.
		a.Command = command
		command.Stderr = os.Stderr
		command.Stdout = os.Stdout
		code, err := utils.ExecuteAndWait(command)
		if err != nil {
			log.Println(err)
		}
		// Run the PostStop handler, if any, and exit if it returns an error
		if postStopCode, err := utils.RunWithFields(a.PostStopCmd, log.Fields{"process": "PostStop"}); err != nil {
			os.Exit(postStopCode)
		}
		os.Exit(code)
	}

	// block forever, as we're polling in the two polling functions and
	// did not os.Exit by waiting on an external application.
	select {}
}
コード例 #4
0
// CheckHealth runs the service's health command, returning the results
func (s *Service) CheckHealth() (int, error) {

	defer func() {
		// reset command object because it can't be reused
		if s.healthCheckCmd != nil {
			s.healthCheckCmd = utils.ArgsToCmd(s.healthCheckCmd.Args)
		}
	}()

	// if we have a valid Service but there's no health check
	// set, assume it always passes (ex. telemetry service).
	if s.healthCheckCmd == nil {
		return 0, nil
	}
	exitCode, err := utils.RunWithFields(s.healthCheckCmd, log.Fields{"process": "health", "serviceName": s.Name, "serviceID": s.ID})
	return exitCode, err
}