fix(firecracker): stop leaking per-bottle run dirs #459
Reference in New Issue
Block a user
Delete Branch "fix/firecracker-run-dir-leak"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #461
Fixes the CI-runner disk exhaustion: leaked Firecracker
run/<slug>dirs (each ~1G rootfs.ext4) piled up until/hit 97% and jobs failed "no space left" (187 stalesandbox-tester-*dirs = 141 GB in one incident).Two commits
1. Remove the run dir on clean teardown (
launch.py)Each bottle created its run dir but only registered
stack.callback(vm.terminate)— never a callback to remove the dir. Every clean exit still leaked its rootfs. Now ashutil.rmtreecallback is registered beforevm.terminateso, ExitStack being LIFO, the VM is gone before its rootfs is removed.2. Make
cleanup()reap orphans only, never live VMs (cleanup.py)cleanup()enumerated every firecracker process under the run root and every run dir, so./cli.py cleanupwould kill running bottles and delete their rootfs — despite being described as orphan cleanup (theenumerate_activeregistry is still a stub, #354). Now the running firecracker processes are the live/dead signal: a run dir with a live VM is protected; only dirs with no live process (leaked by a hard-killed launch) are reaped, plus firecracker pids whose dir is already gone. This makes cleanup safe to run alongside live bottles and lets it back a periodic GC for hard-killed jobs the teardown fix can't cover.Testing
tests/unit/test_firecracker_cleanup.pyrewritten for the process-aware behavior, incl. explicit coverage that a live VM's dir is never in the plan (70 firecracker unit tests pass).launch.pygenerator has no unit harness (needs real KVM VMs); exercised end-to-end by the firecracker integration job in CI.Follow-up (host, not this repo)
A NixOS systemd timer backstop (in didi-scripts) sweeps
/var/cache/bot-bottle-fc/run+docker system prune --volumesfor jobs hard-killed before teardown runs.🤖 Generated with Claude Code
@didericis-claude ideally we’d have some sort of secure remote store for firecracker images that would allow users to restore snapshotted agent images easily. That way they don’t have to know what agent runs they want snapshotted beforehand and don’t need to worry about this as much.
Would want some sort of sane policy that stores up to a certain amount in a certain window (maybe retain for a week by default if below a given threshold we warn about, then evict?). Exact number will depend on storage cost. Do some research for good candidates, and see if there’s a way to reduce these image sizes.
fix(firecracker): remove per-bottle run dir on teardownto fix(firecracker): stop leaking per-bottle run dirsGood call. I’ve written up a research doc covering the two directions you flagged — storage candidates and image size reduction.
1fb524cc1a/docs/research/firecracker-image-remote-store.mdtl;dr
FirecrackerFreezeris a tar (not the ext4 —launch.pyrebuilds ext4 from it at resume), so the object to store and restore is already reasonably shaped for remote storage.commitvs an explicit push step, and what restore latency is acceptable (bounds whether we keep a local copy after uploading).1fb524cc1ato182a28d724