Skip to content

feat(cli): expose --live-fork on forkd fork / from-image / run for spawn-time opt-in #209

Description

@WaylandYang

Gap

Phase 7.1 (REST live_fork: true on POST /v1/sandboxes) and Phase 7.3 (Controller.spawn_sandboxes(live_fork=True) in Python/TS/MCP SDKs) shipped the spawn-time live-fork opt-in. The CLI did not get a matching flag.

This means:

  • The doc comment on forkd snapshot --live (added in Phase 7.2) tells users "the source must have been created with `--live-fork`," but that flag doesn't exist.
  • A CLI-only workflow can't currently spawn a live-fork-capable source — you have to drop into the SDK or curl REST to set live_fork: true.

Scope

Add --live-fork (bool flag) to:

  • forkd fork (spawns N children from a registered snapshot)
  • forkd from-image (Docker → rootfs → boot → register, then optionally spawn one)
  • forkd run (one-shot spawn)

For each, plumb the flag through to POST /v1/sandboxes body's live_fork: true (the daemon already accepts it).

Acceptance

  • forkd fork --tag X -n 1 --live-fork spawns a live-fork-capable child; forkd snapshot --from-sandbox <id> --live then succeeds against it
  • clap docstring explains the kernel/FC prereqs (link to docs/VENDORED-FIRECRACKER.md)
  • forkd snapshot --live doc comment can drop the "source must have been created with --live-fork" caveat into being literally true on the CLI
  • README's bash snippet (currently calls out the gap explicitly) can be tightened to remove that note

Why follow-up not blocking

mode: \"live\" itself works today via SDK or REST — this is purely CLI ergonomics. Filed honestly in the v0.4 CHANGELOG entry rather than papered over.

Activity

  1. WaylandYang commented on May 31, 2026

    @WaylandYang
    ContributorAuthor

    PR #211 closed half of this — forkd fork --live-fork now exists and plumbs MemoryBackend::MemfdShared through the local-boot path.

    What's still open: there's no CLI verb that spawns via the daemon. The two existing pieces don't compose:

    • forkd fork --live-fork boots Firecracker locally; the daemon doesn't track those processes.
    • forkd snapshot --from-sandbox <id> --live hits the daemon's POST /v1/sandboxes/<id>/branch, which only knows about daemon-spawned sandboxes.

    For a pure-CLI live-BRANCH workflow we'd need something like forkd sandbox spawn --tag X --live-fork (or extending forkd fork with a --via-daemon flag) that POSTs to /v1/sandboxes with live_fork: true. Existing daemon-aware verbs (ls, kill, rmi) confirm that pattern fits the CLI.

    Also dropping the original "add to from-image / run" parts of the scope:

    • from-image builds a snapshot TAG, but live_fork is per-spawn, not per-tag — no place to apply it.
    • run is a one-shot that kills the child after the exec, so a live-BRANCH target wouldn't exist long enough to use.

    Re-titling mentally to "Add daemon-side forkd sandbox spawn --live-fork CLI verb" for the remaining work.

  2. WaylandYang commented on Jun 11, 2026

    @WaylandYang
    ContributorAuthor

    Scoping note for anyone picking this up (labeled good-first-issue):

    forkd fork --live-fork already landed (and #230 built --hugepages on top of it), so the remaining work is just from-image and run:

    1. Add #[arg(long)] live_fork: bool to the FromImage and Run variants in crates/forkd-cli/src/main.rs (copy the doc comment + pattern from the Fork variant around line 206)
    2. Thread it into from_image_cmd / run_cmd → set memory_backend: MemoryBackend::MemfdShared { use_hugepages: false } when true (see fork_cmd around line 2668 for the exact pattern)
    3. Bonus points: also thread --hugepages with requires = "live_fork" the same way feat(live-fork, memfd): Back Mem Snapshot with Hugepages #230 did for fork

    No daemon or VMM changes needed — this is pure CLI plumbing with an existing template. cargo run -p forkd-cli -- from-image --help to verify the flag shows up.

    Happy to review quickly — recent first-PR turnaround here has been < 24h (#230, #236).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions