handleSignalProcess sends a signal to a running process.
(rw http.ResponseWriter, r *http.Request)
| 218 | |
| 219 | // handleSignalProcess sends a signal to a running process. |
| 220 | func (api *API) handleSignalProcess(rw http.ResponseWriter, r *http.Request) { |
| 221 | ctx := r.Context() |
| 222 | |
| 223 | id := chi.URLParam(r, "id") |
| 224 | |
| 225 | // Enforce chat ID isolation. |
| 226 | if chatContext, ok := agentchat.FromContext(ctx); ok { |
| 227 | proc, procOK := api.manager.get(id) |
| 228 | if procOK && proc.chatID != "" && proc.chatID != chatContext.ID.String() { |
| 229 | httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{ |
| 230 | Message: fmt.Sprintf("Process %q not found.", id), |
| 231 | }) |
| 232 | return |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | var req workspacesdk.SignalProcessRequest |
| 237 | if err := json.NewDecoder(r.Body).Decode(&req); err != nil { |
| 238 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 239 | Message: "Request body must be valid JSON.", |
| 240 | Detail: err.Error(), |
| 241 | }) |
| 242 | return |
| 243 | } |
| 244 | |
| 245 | if req.Signal == "" { |
| 246 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 247 | Message: "Signal is required.", |
| 248 | }) |
| 249 | return |
| 250 | } |
| 251 | |
| 252 | if req.Signal != "kill" && req.Signal != "terminate" { |
| 253 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 254 | Message: fmt.Sprintf( |
| 255 | "Unsupported signal %q. Use \"kill\" or \"terminate\".", |
| 256 | req.Signal, |
| 257 | ), |
| 258 | }) |
| 259 | return |
| 260 | } |
| 261 | |
| 262 | if err := api.manager.signal(id, req.Signal); err != nil { |
| 263 | switch { |
| 264 | case errors.Is(err, errProcessNotFound): |
| 265 | httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{ |
| 266 | Message: fmt.Sprintf("Process %q not found.", id), |
| 267 | }) |
| 268 | case errors.Is(err, errProcessNotRunning): |
| 269 | httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{ |
| 270 | Message: fmt.Sprintf( |
| 271 | "Process %q is not running.", id, |
| 272 | ), |
| 273 | }) |
| 274 | default: |
| 275 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 276 | Message: "Failed to signal process.", |
| 277 | Detail: err.Error(), |