Skip to content

v0.8.0

Choose a tag to compare

@clemlesne clemlesne released this 20 Jan 12:12
· 359 commits to main since this release

What's New

Port Forwarding

Expose guest VM ports to the host for health checks, API testing, or service validation:

result = await scheduler.run(
    code="import http.server; http.server.test(port=8080)",
    language=Language.PYTHON,
    expose_ports=[PortMapping(internal=8080, external=3000)],
)
print(result.exposed_ports[0].url)  # http://127.0.0.1:3000

CLI: sbx run --expose 8080:3000 'code'. Works independently of internet access — when allow_network=False, guests cannot initiate outbound but host-to-guest forwarding still works.

Automatic Boot Retry

VMs automatically retry on transient failures (CPU contention, resource pressure) with exponential backoff and jitter. timing.boot_retries reports retry count.

Two-Stage Ctrl+C Handling

  • First Ctrl+C: cancels execution, allows cleanup (__aexit__) to run
  • Second Ctrl+C: force kills all tracked VM process groups immediately

QEMU Stream Reconnect

Version-appropriate reconnect for transient gvproxy disconnections: reconnect-ms=250 (QEMU 9.2+), reconnect=1 (8.0-9.1).

Performance

  • Initramfs zstd — Switch from LZ4 to zstd compression, strip debug symbols, uncompressed module extraction (~34% smaller)

Architecture

  • VM Manager split — Monolithic vm_manager.py (2400+ lines) refactored into qemu_cmd.py, qemu_vm.py, system_probes.py, gvproxy.py, plus process_registry.py and validation.py
  • Exception hierarchy — New TransientError/PermanentError classification for intelligent retry (e.g. VmBootTimeoutError is transient, VmConfigError is permanent)
  • System probes_async_cached_probe decorator for stampede-safe capability caching, QEMU version detection for feature gating

Bug Fixes

  • Frozen VM detection via process state instead of socket timeouts
  • Guest agent verifies gvproxy gateway reachability before package install
  • Handle QEMU exit code 0 during snapshot creation
  • Verify guest-agent architecture matches target before qcow2 embedding
  • Prevent orphaned asyncio tasks and event loop cleanup warnings (Python 3.14 compatible)
  • VM concurrency semaphore now lifecycle-bound (released on destroy, not on boot failure)
  • Close parent socket after gvproxy readiness confirmation

Full Changelog: v0.7.0...v0.8.0