diff options
Diffstat (limited to 'internal/api/scripts.go')
| -rw-r--r-- | internal/api/scripts.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/internal/api/scripts.go b/internal/api/scripts.go new file mode 100644 index 0000000..492570b --- /dev/null +++ b/internal/api/scripts.go @@ -0,0 +1,50 @@ +package api + +import ( + "bytes" + "context" + "net/http" + "os/exec" + "path/filepath" + "time" +) + +const scriptTimeout = 30 * time.Second + +func (s *Server) startNextTaskScriptPath() string { + if s.startNextTaskScript != "" { + return s.startNextTaskScript + } + return filepath.Join(s.workDir, "scripts", "start-next-task") +} + +func (s *Server) handleStartNextTask(w http.ResponseWriter, r *http.Request) { + ctx, cancel := context.WithTimeout(r.Context(), scriptTimeout) + defer cancel() + + scriptPath := s.startNextTaskScriptPath() + cmd := exec.CommandContext(ctx, scriptPath) + + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err := cmd.Run() + exitCode := 0 + if err != nil { + if exitErr, ok := err.(*exec.ExitError); ok { + exitCode = exitErr.ExitCode() + } else { + s.logger.Error("start-next-task: script execution failed", "error", err, "path", scriptPath) + writeJSON(w, http.StatusInternalServerError, map[string]string{ + "error": "script execution failed: " + err.Error(), + }) + return + } + } + + writeJSON(w, http.StatusOK, map[string]interface{}{ + "output": stdout.String(), + "exit_code": exitCode, + }) +} |
