From 34af77e0d8f5c52f1a78bcb0ffe0d35b98116d04 Mon Sep 17 00:00:00 2001 From: pptx704 Date: Sat, 28 Mar 2026 14:30:18 +0600 Subject: [PATCH] Fix snapshot race, delete auth, sparse dd, default disk to 5GB Snapshot race fix: - Pre-mark sandbox as "paused" in DB before issuing CreateSnapshot and PauseSandbox RPCs, preventing the reconciler from marking it "stopped" during the flatten window when the sandbox is gone from the host agent's in-memory map but DB still says "running" - Revert status to "running" on RPC failure - Check ctx.Err() before writing response to avoid writing to dead connections when client disconnects during long snapshot operations Delete auth fix: - Block non-admin deletion of platform templates (team_id = all-zeros) at DELETE /v1/snapshots/{name} with 403, preventing file deletion before the team ownership check fails Sparse dd: - Add conv=sparse to dd in FlattenSnapshot so flattened images preserve sparseness (~200MB actual vs 5GB logical) Default disk size: - Change default disk_size_mb from 20GB to 5GB across migration, manager, service, build, and EnsureImageSizes - Disable split-button dropdown arrow for platform templates in dashboard snapshots page (teams cannot delete platform templates) --- db/migrations/20260310094104_initial.sql | 2 +- frontend/src/lib/api/capsules.ts | 1 + .../routes/dashboard/snapshots/+page.svelte | 35 ++++++------ internal/api/handlers_snapshots.go | 56 ++++++++++++++----- internal/devicemapper/devicemapper.go | 1 + internal/sandbox/images.go | 2 +- internal/sandbox/manager.go | 2 +- internal/service/build.go | 2 +- internal/service/sandbox.go | 22 ++++++-- proto/hostagent/gen/hostagent.pb.go | 4 +- proto/hostagent/hostagent.proto | 4 +- 11 files changed, 89 insertions(+), 42 deletions(-) diff --git a/db/migrations/20260310094104_initial.sql b/db/migrations/20260310094104_initial.sql index da6607f..6c8afc4 100644 --- a/db/migrations/20260310094104_initial.sql +++ b/db/migrations/20260310094104_initial.sql @@ -144,7 +144,7 @@ CREATE TABLE sandboxes ( vcpus INTEGER NOT NULL DEFAULT 1, memory_mb INTEGER NOT NULL DEFAULT 512, timeout_sec INTEGER NOT NULL DEFAULT 300, - disk_size_mb INTEGER NOT NULL DEFAULT 20480, + disk_size_mb INTEGER NOT NULL DEFAULT 5120, guest_ip TEXT NOT NULL DEFAULT '', host_ip TEXT NOT NULL DEFAULT '', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), diff --git a/frontend/src/lib/api/capsules.ts b/frontend/src/lib/api/capsules.ts index cc4ad79..565f14f 100644 --- a/frontend/src/lib/api/capsules.ts +++ b/frontend/src/lib/api/capsules.ts @@ -54,6 +54,7 @@ export type Snapshot = { memory_mb?: number; size_bytes: number; created_at: string; + platform: boolean; }; export async function createSnapshot(sandboxId: string, name?: string): Promise> { diff --git a/frontend/src/routes/dashboard/snapshots/+page.svelte b/frontend/src/routes/dashboard/snapshots/+page.svelte index 6f86d4c..2ae201a 100644 --- a/frontend/src/routes/dashboard/snapshots/+page.svelte +++ b/frontend/src/routes/dashboard/snapshots/+page.svelte @@ -423,6 +423,7 @@