forked from wrenn/wrenn
fix: resolve bugs and DRY violations in sandbox manager and API handlers
- Fix createFromSnapshot discarding memoryMB param (balloon optimization was dead) - Fix double dm-snapshot removal in Pause() cleanupPauseFailure path - Fix DestroySandbox RPC mapping all errors to CodeNotFound - Fix handleFailed event consumer missing pausing/resuming → error transitions - Fix stream resource leak in StreamUpload on early-return paths - Add envs/cwd fields to ExecRequest proto for foreground exec parity - Extract createResources rollback helper to eliminate 4x duplicated teardown - Remove unused chClient.ping method - Add .mcp.json to gitignore Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -119,6 +119,8 @@ func (h *execHandler) Exec(w http.ResponseWriter, r *http.Request) {
|
||||
Cmd: req.Cmd,
|
||||
Args: req.Args,
|
||||
TimeoutSec: req.TimeoutSec,
|
||||
Envs: req.Envs,
|
||||
Cwd: req.Cwd,
|
||||
}))
|
||||
if err != nil {
|
||||
status, code, msg := agentErrToHTTP(err)
|
||||
|
||||
@ -89,6 +89,12 @@ func (h *filesStreamHandler) StreamUpload(w http.ResponseWriter, r *http.Request
|
||||
|
||||
// Open client-streaming RPC to host agent.
|
||||
stream := agent.WriteFileStream(ctx)
|
||||
var streamClosed bool
|
||||
defer func() {
|
||||
if !streamClosed {
|
||||
stream.CloseAndReceive()
|
||||
}
|
||||
}()
|
||||
|
||||
// Send metadata first.
|
||||
if err := stream.Send(&pb.WriteFileStreamRequest{
|
||||
@ -127,6 +133,7 @@ func (h *filesStreamHandler) StreamUpload(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
// Close and receive response.
|
||||
streamClosed = true
|
||||
if _, err := stream.CloseAndReceive(); err != nil {
|
||||
status, code, msg := agentErrToHTTP(err)
|
||||
writeError(w, status, code, msg)
|
||||
|
||||
@ -210,16 +210,14 @@ func (c *SandboxEventConsumer) handleStopped(ctx context.Context, sandboxID pgty
|
||||
// or the CP's background goroutine publishes a failure. Uses conditional update
|
||||
// to avoid clobbering concurrent operations.
|
||||
func (c *SandboxEventConsumer) handleFailed(ctx context.Context, sandboxID pgtype.UUID) {
|
||||
// Try running → error (VM crash pushed by host agent).
|
||||
if _, err := c.db.UpdateSandboxStatusIf(ctx, db.UpdateSandboxStatusIfParams{
|
||||
ID: sandboxID, Status: "running", Status_2: "error",
|
||||
}); err == nil {
|
||||
return
|
||||
// Try each possible pre-failure state until one matches.
|
||||
for _, fromStatus := range []string{"running", "starting", "pausing", "resuming"} {
|
||||
if _, err := c.db.UpdateSandboxStatusIf(ctx, db.UpdateSandboxStatusIfParams{
|
||||
ID: sandboxID, Status: fromStatus, Status_2: "error",
|
||||
}); err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Try starting → error (create failed).
|
||||
_, _ = c.db.UpdateSandboxStatusIf(ctx, db.UpdateSandboxStatusIfParams{
|
||||
ID: sandboxID, Status: "starting", Status_2: "error",
|
||||
})
|
||||
}
|
||||
|
||||
func (c *SandboxEventConsumer) handleAutoPaused(ctx context.Context, sandboxID pgtype.UUID, _ SandboxEvent) {
|
||||
|
||||
Reference in New Issue
Block a user