Container handle

api object

lab.container(name) returns the same Machine handle a VM does — this page is the container-flavoured tour of it, plus the one capability containers do not report.

lab.container(name) (or lab.containers()) returns a Machine — the same handle lab.vm(name) returns, with the same methods. The kind check is there so naming a VM gives you "that's a vm" rather than "no such machine". The screen and input methods exist on it like everything else. Calling one on a container fails at call time with *"machine web has no display"*: no container reports a display today, but that is a fact about the machine, not a rule about the kind — a container running a display server would report one, and the same script would then work unchanged.

MethodMeaning
name()The container's lab name
start() / stop() / stop_force() / restart()Lifecycle (stop is the graceful ladder: stop signal → guest shutdown → kill)
state()stopped / starting / running / stopping
is_ready() / wait_ready(secs)Process started + healthcheck passing (when declared)
is_healthy()Latest healthcheck verdict (a container without one counts healthy once ready)
wait_shutdown(secs)Wait until stopped
ip() / ip_nic(i)The DHCP lease (errors cleanly on an air-gapped container)
snapshot(name) / snapshots() / delete_snapshot(name)Snapshots, same semantics as VMs (offline + online full-parity)
exec(cmd, args) / exec_timeout(cmd, args, secs)Run a command inside the container; returns an ExecResult
copy_to(local, path) / copy_from(path, local)File copy in/out of the container filesystem
logs(lines)Tail of the container's stdout/stderr (the serial console log)
terminal()Interactive send/expect shell inside the container's PID namespace (the workload is PID 1) — a Term handle
stats()Live GuestStats (cpu/mem/disks) — see Guest agent
wscript
use vmlab

fn main(lab: Lab) {
    let web = lab.container("web").unwrap()
    web.wait_ready(120).unwrap()
    let r = web.exec("nginx", ["-t"]).unwrap()
    lab.log("config check: " + r.stderr)
}