func main() { p := kexec.CommandString("python flask_main.py") p.Start() time.Sleep(3 * time.Second) err := p.Terminate(syscall.SIGKILL) if err != nil { log.Println(err) } }
// FIXME(ssx): maybe need to return error func (p *Process) buildCommand() *kexec.KCommand { cmd := kexec.CommandString(p.Command) // cmd := kexec.Command(p.Command[0], p.Command[1:]...) logDir := filepath.Join(defaultConfigDir, "log", sanitize.Name(p.Name)) if !IsDir(logDir) { os.MkdirAll(logDir, 0755) } var fout io.Writer var err error p.OutputFile, err = os.OpenFile(filepath.Join(logDir, "output.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Warn("create stdout log failed:", err) fout = ioutil.Discard } else { fout = p.OutputFile } cmd.Stdout = io.MultiWriter(p.Stdout, p.Output, fout) cmd.Stderr = io.MultiWriter(p.Stderr, p.Output, fout) // config environ cmd.Env = os.Environ() // inherit current vars environ := map[string]string{} if p.User != "" { err := cmd.SetUser(p.User) if err != nil { log.Warnf("[%s] chusr to %s failed", p.Name, p.User) } else { var homeDir string switch runtime.GOOS { case "linux": homeDir = "/home/" + p.User // FIXME(ssx): maybe there is a better way case "darwin": homeDir = "/Users/" + p.User } cmd.Env = append(cmd.Env, "HOME="+homeDir, "USER="******"HOME"] = homeDir environ["USER"] = p.User } } cmd.Env = append(cmd.Env, p.Environ...) mapping := func(key string) string { val := os.Getenv(key) if val != "" { return val } return environ[key] } cmd.Dir = os.Expand(p.Dir, mapping) if strings.HasPrefix(cmd.Dir, "~") { cmd.Dir = mapping("HOME") + cmd.Dir[1:] } log.Infof("[%s] use dir: %s\n", p.Name, cmd.Dir) return cmd }
func (s *Supervisor) hWebhook(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) name, category := vars["name"], vars["category"] proc, ok := s.procMap[name] if !ok { http.Error(w, fmt.Sprintf("proc %s not exist", strconv.Quote(name)), http.StatusForbidden) return } hook := proc.Program.WebHook if category == "github" { gh := hook.Github _ = gh.Secret isRunning := proc.IsRunning() s.stopAndWait(name) go func() { cmd := kexec.CommandString(hook.Command) cmd.Dir = proc.Program.Dir cmd.Stdout = proc.Output cmd.Stderr = proc.Output err := GoTimeout(cmd.Run, time.Duration(hook.Timeout)*time.Second) if err == ErrGoTimeout { cmd.Terminate(syscall.SIGTERM) } if err != nil { log.Warnf("webhook command error: %v", err) // Trigger pushover notification } if isRunning { proc.Operate(StartEvent) } }() io.WriteString(w, "success triggered") } else { log.Warnf("unknown webhook category: %v", category) } }