4 Commits

Author SHA1 Message Date
82c11dd2f8 feat: add web terminal UI with WebSocket console and clone management API
Introduces a browser-based terminal interface backed by xterm.js, served
directly from the binary via an embedded HTML asset.

New HTTP server (`serve [addr]`, default :8080):
  GET  /              — xterm.js terminal UI; ?id=N selects a clone
  GET  /clones        — JSON list of running clone IDs
  POST /clones        — spawn a new clone; returns {"id": N}
  DELETE /clones/{id} — destroy a clone by ID
  GET  /ws/{id}       — WebSocket console for clone {id}
                        binary frames = raw PTY I/O
                        text frames   = JSON resize {"rows":N,"cols":M}

Supporting changes:
- orchestrator: add SpawnSingle() and KillClone(id) for per-clone lifecycle
  management from the HTTP layer
- console: add a resize sideband Unix socket (console-resize.sock) that
  accepts newline-delimited JSON {"rows","cols"} messages and applies them
  to the PTY master via pty.Setsize; the WebSocket handler writes to this
  socket on text frames so browser window resizes propagate into the VM
- deps: add gorilla/websocket v1.5.3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 10:53:41 +00:00
9089cbdbe9 feat: add serial console access via PTY + Unix socket proxy
Each spawned clone now runs under a _console-proxy daemon that connects
firecracker's ttyS0 (stdin/stdout) to a PTY and serves it on a Unix
socket at clones/<id>/console.sock for the VM's lifetime.

  sudo ./fc-orch spawn 1
  sudo ./fc-orch console 1   # Ctrl+] to detach

spawnOne delegates VM startup to the proxy process (Setsid, detached)
and waits for console.sock to appear before returning. Kill continues
to work via PID files — proxy and firecracker PIDs are both recorded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 10:24:09 +00:00
b46d510cb7 docs: add full command reference; fix module path and KernelURL config
- Add docs/commands.md with per-command purpose, step-by-step shell/SDK
  call sequences, config tables, outputs, and error conditions
- Rename module from github.com/you/fc-orchestrator to github.com/kacerr/fc-orchestrator
- Add KernelURL field to Config so the download URL is configurable via
  FC_KERNEL_URL instead of being hardcoded in Init()
- Expose FC_KERNEL_URL in the usage string
- Add verbose logging of dd/mkfs.ext4/mount/tar calls in buildRootfs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 21:47:48 +00:00
640bf5065a feat: initial Firecracker snapshot orchestrator (fc-orch)
A "poor man's" Firecracker VM orchestrator that boots a single golden VM,
snapshots it, then restores N clone VMs from that snapshot with minimal
per-clone overhead.

How it works:
- `init`   — downloads a Linux 6.1 kernel and builds a minimal Alpine 3.20
             rootfs (512 MiB ext4) with a basic init script
- `golden` — boots the golden VM, lets it settle, then pauses and snapshots
             it (vmstate + memory file); the golden VMM is then terminated
             since only the artifacts are needed
- `spawn N` — restores N clone VMs concurrently from the golden snapshot:
               * rootfs: filesystem-level COW copy via `cp --reflink` (falls
                 back to a plain copy if reflinks are not supported)
               * memory: shared golden `mem` file; Firecracker's MAP_PRIVATE
                 lets the kernel handle COW page-by-page at no up-front cost
               * vmstate: small file, cheap regular copy per clone
               * networking: per-clone TAP device (fctapN) bridged to fcbr0
                 with iptables MASQUERADE NAT on the default route interface
- `status`  — reads PID files and checks /proc to report alive/dead clones
- `kill`    — stops in-memory clones, kills any stragglers via PID files,
              and tears down all fctap* devices
- `cleanup` — kill + remove all state dirs and the bridge

All tunables (binary path, base dir, kernel/rootfs paths, vCPUs, memory,
bridge name/CIDR) are configurable via environment variables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 09:53:16 +02:00