Commit graph

13 commits

Author SHA1 Message Date
Till Wegmueller
33383e37e9
Fix forger version check to use absolute path
The freshly installed binary may not be in PATH yet during
provisioning, so use the full path to /usr/local/bin/forger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:46:12 +01:00
Till Wegmueller
2265fca023
Remove docs build output and gitignore docs/book/
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:38:05 +01:00
Till Wegmueller
b37beea0f5
Add mdbook documentation for vmctl and vm-manager
Comprehensive docs covering CLI reference, VMFile.kdl format,
architecture, library API, tutorials, and advanced topics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:37:22 +01:00
Till Wegmueller
7f65305fb8
Fix exec_streaming blocking: run channel.exec() before switching to non-blocking mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:18:02 +01:00
Till Wegmueller
9274f7c47e
Clean up tracing output and infer VM name for ssh command
- Remove timestamps and module targets from tracing output for
  a cleaner CLI experience.
- vmctl ssh now infers the VM name from VMFile.kdl when only one
  VM is defined, so `vmctl ssh` works without arguments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:10:55 +01:00
Till Wegmueller
7cf207a9ec
Stream provision output live and fix generated key permissions
- Add ssh::exec_streaming() that prints stdout/stderr as data arrives
  instead of buffering until command completion. Provision scripts now
  show output in real time without tracing annotation.
- Set 0600 permissions on generated SSH private keys so OpenSSH
  accepts them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:06:06 +01:00
Till Wegmueller
acdf43ae5a
Add console and provision logging, vmctl log command, fix ssh user
- QEMU serial console now logs to console.log in the VM's work
  directory via chardev logfile, so boot and cloud-init output can
  be reviewed after the fact.
- Provision steps stream stdout/stderr through tracing and append
  to provision.log in the work directory.
- vmctl ssh now reads the VMFile ssh block to resolve the user
  (e.g. "smithy") instead of always defaulting to "vm".
- New vmctl log command shows console and/or provision logs with
  optional --tail support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:01:25 +01:00
Till Wegmueller
4cf35c99d0
Generate per-VM Ed25519 SSH keypairs instead of requiring user keys
libssh2 cannot handle all OpenSSH private key formats (e.g. passphrase-
protected or newer ed25519 keys), causing auth failures. Instead of
referencing the user's ~/.ssh keys, generate a fresh Ed25519 keypair at
resolve time when the VMFile omits ssh-key and private-key. The public
key is injected into cloud-init and the private PEM is persisted to the
VM's work directory so that provision, reload, and ssh commands can
reuse it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:05:28 +01:00
Till Wegmueller
d9a4206447
Add OmniOS builder VM definition and provisioning scripts
VMFile.kdl defines the omnios-builder VM with cloud-init, SSH config,
and a 3-stage provision pipeline (bootstrap packages + Rust, upload
forger source tarball, build and install forger). Makefile provides
convenience targets wrapping vmctl commands. pack-forger.sh creates a
minimal tarball of just the forger + spec-parser crates and image specs
from refraction-forger for upload to the VM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 22:03:08 +01:00
Till Wegmueller
eb78c24a8b
Add OmniOS builder VM definition and provisioning scripts
VMFile.kdl defines the omnios-builder VM with cloud-init, SSH config,
and a 3-stage provision pipeline (bootstrap packages + Rust, upload
forger source tarball, build and install forger). Makefile provides
convenience targets wrapping vmctl commands. pack-forger.sh creates a
minimal tarball of just the forger + spec-parser crates and image specs
from refraction-forger for upload to the VM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:56:43 +01:00
Till Wegmueller
38bc2fa6fb
Add VMFile.kdl declarative VM definitions with up/down/reload/provision commands
Introduce a Vagrantfile-like declarative config format using KDL for defining
multi-VM environments. Includes KDL parsing with validation, a provisioning
engine (shell inline/script + file upload over SSH), and four new CLI commands
for managing VM lifecycles from VMFile.kdl definitions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:48:12 +01:00
Till Wegmueller
407baab42f
Make QEMU backend fully functional end-to-end
The scaffolding compiled but couldn't actually run VMs because QEMU
was missing vCPU/memory/networking args, VmHandle didn't persist enough
state for restart, and CLI commands discarded updated handles after
operations.

Key changes:
- Add vcpus, memory_mb, disk_gb, network, ssh_host_port, mac_addr to
  VmHandle with serde(default) for backward compat
- Make NetworkConfig serializable with serde(tag = "type")
- Change Hypervisor trait: start/stop/suspend/resume return Result<VmHandle>
  so backends can return updated PID, VNC addr, etc.
- Complete QEMU start() with -smp, -m, tap/user-mode networking, stale
  socket cleanup, PID reading, and VNC querying via QMP
- Fix guest_ip() to return 127.0.0.1 for user-mode networking and
  filter ARP entries by bridge for tap mode
- Add QMP query_vnc() and fix unwrap() panics in send_command()
- All CLI commands now persist the updated VmHandle after operations
- Add input validation in create with miette diagnostics
- Atomic state persistence (write-to-tmp + rename)
- SSH: port-aware connections, try ed25519/ecdsa/rsa key types
- Enhanced status/list output with vCPUs, memory, network, SSH port
- New tests: NetworkConfig roundtrip, VmHandle roundtrip, backward compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 18:58:02 +01:00
Till Wegmueller
9dc492f90f
Add vm-manager library and vmctl CLI
Unified VM management consolidating QEMU-KVM (Linux) and Propolis/bhyve
(illumos) backends behind an async Hypervisor trait, with a vmctl CLI for
direct use and a library API for orchestrators.

- Core library: types, async Hypervisor trait, miette diagnostic errors
- QEMU backend: direct process management, raw QMP client, QCOW2 overlays
- Propolis backend: zone-based VMM with REST API control
- Shared infra: cloud-init NoCloud ISO generation, image download/cache,
  SSH helpers with retry
- vmctl CLI: create, start, stop, destroy, list, status, console, ssh,
  suspend, resume, image pull/list/inspect
- nebula-vm zone brand: lifecycle scripts and platform/config XML for
  illumos zone integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 18:25:17 +01:00