2026.07.10 Release v0.5.1
CubeSandbox 0.5.1 is a production follow-up to 0.5.0, hardening AutoPause, ARM64, and cluster deployment for real-world scale. Headline items: a standalone cube-lifecycle-manager control-plane service (extracted from the CubeProxy sidecar so CubeProxy can scale horizontally), a three-value timeout semantics refactor with server-side defaults and NEVER_TIMEOUT, and host-mount path allowlisting to close arbitrary host bind-mounts. The release also fixes ARM64 64 KB page snapshot integrity and substantially improves egress policy / TAP recycle reliability. 59 commits from 18 contributors.
🎯 Major Features
cube-lifecycle-manager: Standalone AutoPause Coordinator
Splits the former in-image cube-proxy-sidecar into a standalone control-plane service — cube-lifecycle-manager (CLM) — so CubeProxy can run multiple replicas without a single-instance sidecar bottleneck.
- Standalone deploy: CLM is wired into
cube-sandbox-control.target; one-click and TencentCloud Terraform deployments both include it. - Redis service discovery: each CubeProxy replica registers its admin endpoint in Redis; CLM discovers live replicas and coordinates auto-pause / auto-resume with no static replica list.
- Protocol compatibility: wire protocol, Redis schema, and SDK behavior are unchanged; existing AutoPause / AutoResume semantics are preserved.
- TencentCloud Terraform (#814): control plane gains a
cube-lifecycle-managerDeployment; supportsTENCENTCLOUD_CUBE_PROXY_REPLICASmulti-replica plus CLM replica count / discovery refresh / admin token knobs.
Three-Value Timeout Semantics + Server-Side Default
Unifies sandbox idle-timeout semantics (E2B-aligned) and moves the "not set" vs "explicit default" decision from SDK / CubeAPI down to CubeMaster.
| Value | Meaning |
|---|---|
Omitted (None / nil)
| Cluster default_timeout_insec; if unset or ≤0 → never timeout
|
NEVER_TIMEOUT (-1)
| Never reclaim on idle |
0
| Immediate timeout (reclaimed on the first idle sweep) |
N > 0
| Idle TTL = N seconds |
- SDK: Go / Python
CreateOptions.Timeoutbecome optional pointers; Create / Connect / Resume no longer inject a hard-coded default. ExposeNeverTimeout/NEVER_TIMEOUTsentinels. - CubeAPI / CubeMaster: timeout fields are
Option/*int, preserving "unset";EndAtfollows three-value rules (-1→ no deadline). - RPC deadline decoupled from idle TTL: new
create_timeout_insec(default 300s) bounds only the create/scheduling RPC. - CLM sweeper: skip reclaim when
TimeoutSeconds < 0; immediate reclaim at== 0; legacynilfalls back toDefaultIdleTimeout. - Runtime adjustment: Python / Go SDKs add
set_timeout()/SetTimeout(), includingNEVER_TIMEOUT(#743, #850). Web UI can pass timeout on sandbox create (#798).
Host-Mount Path Allowlist Hardening
Host-mount previously accepted any absolute path, letting sandboxes bind-mount arbitrary host directories. Paths are now restricted to configurable prefixes (default /data/shared/), with filepath.Clean neutralizing .. traversal; / is explicitly forbidden in config (#756).
Persistent-storage docs updated (path restriction, permissions, multi-tenant isolation, multi-node shared storage); examples aligned to the default prefix (#768).
✨ Enhancements
SDK
- Node.js / TypeScript SDK (preview) (#792): adds
@cubesandbox/sdkaligned with the Python / Go surface; still under validation — use with caution in production. - Python / Go
set_timeout(#743, #850): E2B-aligned; CubeAPI / CubeMaster accept-1(NEVER_TIMEOUT) and reject other negatives. - Go SDK allowOut guard alignment (#802):
AllowPublicTraffic=falseis no longer treated as deny-all; matches CubeAPI (deny-all only whenAllowInternetAccess=falseordenyOutcontains0.0.0.0/0).
Networking & Egress
- CubeEgress credential injection on plain HTTP (#726): allows inject against HTTP-only upstreams. The security boundary is that sandbox code never sees the secret, not that egress→upstream must be TLS.
- CubeEgress transparent-proxy IP from sandbox CIDR (#851): no longer hard-codes
192.168.0.1; derives the first usable IP fromCUBE_SANDBOX_NETWORK_CIDRso custom sandbox networks get correct TPROXY / OpenResty listen addresses. - Minimum TTL for DNS-learned egress entries: clamp learned allow entries to ≥300s so short DNS TTLs do not cause reconnect denials.
- Skip policy re-check for established CubeEgress sessions: CubeVS skips egress policy re-evaluation for existing TCP sessions so DNS expiry does not break live connections; policy check folded into
create_nat_sessionwith per-session caching. - Always replay default deny on replace: replace / flush always replays private / link-local default deny entries so create and replace policy shapes stay consistent.
Deployment & Installer
- CubeProxy pre-published multi-arch images (#849): one-click pulls TCR multi-arch images instead of building on-host; supports
MIRROR=cn|intand airgap local-cache fallback. - Component image release pipeline (#795):
release-docker-images.ymlpushes multi-arch component images to GHCR / TCR;bump-image.shis the single source of truth for hard-coded tags. - CubeMaster Dockerfile (#813, #824): unified Docker build args / context and ARG scoping fixes; CubeAPI Dockerfile switched to single-shot build with safety gates (#854).
- One-click dnsmasq fallback (#740): optional script-owned dnsmasq when systemd-resolved is absent and NetworkManager's dnsmasq plugin never spawns, restoring
cube.appresolution. - Anchored cubelet config patching (#776): sed replacements anchored at line start so updating
CUBE_SANDBOX_NETWORK_CIDRcannot rewrite an emptycube_router_cidr.
Web UI / AgentHub / Other
- CubeAPI lifecycle snake_case (#772): accepts Python-style
lifecycle.on_timeout/lifecycle.auto_resume, avoiding silent fallback to kill / no-resume. - AgentHub OpenClaw bind=lan (#769): force gateway bind to
lanso cube-proxy can reach it via tap IP (autocould resolve to loopback). - ARM64 runtime hardening (#807): dirty-bitmap granularity uses host page size (fixes severely incomplete snapshots on 64 KB pages and 200% CPU on restore); aarch64 vCPU falls back to PMU-less init when the host lacks PMUv3.
- Dev-env QEMU 10.x (#713): explicit
-drive if=none+-device virtio-blk-pcifixes empty-drive errors on QEMU 10.2.2+.
🐛 Bug Fixes
Lifecycle & Sandboxes
- Idempotent resume (#817): already-Running sandboxes return an "already in target state" signal (treated as success by CLM), distinct from truly non-resumable states.
- 404 on delete missing sandbox (#759): CubeAPI / CubeMaster map missing-sandbox deletes to NotFound.
- Stable sandbox list order (#762): sort by creation time descending with SandboxID tie-break so WebUI / SDK refreshes no longer reshuffle.
- Preserve template network rules & resource defaults (#581): keep egress rules when creating templates from images; retain the first CPU/memory validation error; request-side overrides win under first-match-wins.
Networking & Data Plane
- Safe TAP recycle (network-agent): do not return TAPs to the pool until cleanup and pool prep succeed; failed cleanup keeps residual policy off the reusable pool; clear policy / DNS allow state before reuse to prevent cross-sandbox leakage.
- Go SDK envd port (#821): envd RPCs (commands / files / filesystem / PTY) route to port 49983 instead of Jupyter 49999; only
RunCode//executestays on Jupyter.
Other
- Example host-mount paths (#768): examples and docs use
/data/shared/...to match the default allowlist.
📚 Documentation
- ARM64 support announcement blog (#866): bilingual InfoQ-style post on the joint Arm multi-arch effort.
- Pi Agent integration guide (#701): bilingual docs + runnable example (pause/resume, network policy, credential injection).
- Lifecycle / quota docs (#739): ARM64 install notes and lifecycle quota documentation.
- Persistent storage guide (#756): host-mount path restriction, permissions, multi-tenant isolation, multi-node shared storage.
- Roadmap (#731): roadmap added to README and docs site.
- v0.5.0 release materials (#770, #781): release blog and feature copy updates; Quickstart notes Multi-Arch image availability (#806).
- Dev skills & doc hygiene (#788, #789): Claude Code
run-devskill; i18n sync checks and change-driven doc audit rules.
⚙️ Engineering Improvements
- Platform-suffixed versions in matrix checks (#747).
- PVM guest build trigger tightened (#819): only on version tags.
- Image tag bumps: one-click / Terraform defaults synced through
v0.5.1-rc*candidates (#826, #867). - Python SDK version bump to 0.5.0 (#818).
- CubeAPI dead-code cleanup (#796) and other small engineering tidy-ups.
Note: Web Example Center (#615) was merged and immediately reverted (#778); it is not part of this release.