Coppice can resize jail-backed sandboxes while they are running.
The gateway exposes PATCH /sandboxes/:id/limits, then
reapplies FreeBSD rctl(8) rules for CPU and memory and
updates the sandbox dataset’s ZFS quota for disk.
API
The request accepts the same limit names used at create/fork time:
{
"cpuCount": 150,
"memoryMB": 768,
"diskSizeMB": 2048
}
Fields are patch-style: omitted values keep their current setting.
Passing 0 clears that cap. The response is the new
configured limit set:
{
"sandboxID": "a1b2c3d4e5f6...",
"cpuCount": 150,
"memoryMB": 768,
"diskSizeMB": 2048
}
The snake_case aliases cpu_count, memory_mb,
disk_size_mb, and writable_layer_mb are also
accepted for shell scripts and internal rigs.
Host operations
For a jail named e2b-<id>, the backend rebuilds the
Coppice-owned rctl rules as a complete set:
rctl -r jail:e2b-<id>
rctl -a jail:e2b-<id>:pcpu:deny=150
rctl -a jail:e2b-<id>:memoryuse:deny=768M
zfs set quota=2048M zroot/jails/e2b-<id>
Rebuilding the whole rule set avoids stale caps when a caller shrinks
or clears one dimension. ZFS quota updates are live by design: new
writes see the new cap immediately. Clearing disk uses
zfs set quota=none.
Caveats
This surface is intentionally jail-only today. bhyve live CPU/RAM hotplug is a different implementation path, and existing bhyve pool templates still express CPU and memory at checkout time.
CPU and memory caps require kern.racct.enable=1 at boot,
the same requirement as create-time limits and per-sandbox metrics.
Without racct, the rctl -a command fails and the API
returns a backend error instead of pretending the cap applied.
Status
This closes the Daytona-style “live resize CPU / RAM / disk” row for
jail-backed sandboxes. The latest sampler reading on
GET /sandboxes/:id and /metrics catches up on
the next metrics tick; the detail response also stores the intended
limit values immediately so the UI does not have to wait for the
sampler.
Receipt: benchmarks/rigs/live-limits-resize.sh, exposed as
mise run limits:live-resize-honor, creates a fresh jail,
starts a CPU burner before the patch, applies
cpuCount=60, memoryMB=192, and
diskSizeMB=128, checks the live rctl(8) rules,
checks the ZFS quota, verifies a 256 MiB write fails under the live
quota, then clears all three limits with a zero patch.