feat(cubesandbox): lifecycle + ephemeral + snapshot capability (Phase 2, stacked on #137) - #138
Open
JackWeiw wants to merge 2 commits into
Open
Conversation
…hase 2) Phase 2 lifts the cubesandbox provider from exec-only to the full replay capability surface, mirroring aenv's lifecycle shape over the native CubeSandbox SDK. CubesandboxProvider (__init__.py): - pause: native state.cube_sandbox.pause(wait=True) -- synchronous (the Cloud Hypervisor fork writes a memory snapshot the resume restores from; wait=True keeps it stable before the runner accounts the pause). - resume: state.cube_sandbox = Sandbox.connect(inst.id) -- connect auto-resumes a paused sandbox (the deprecated standalone resume() is replaced by connect) and returns a fresh handle, swapped in like the manager's _attach. - snapshot_sizes: returns None for now. The cube SDK's SnapshotInfo exposes only snapshot_id + names (no size fields), so per-pause size collection can't be satisfied from the control plane yet. None keeps the provider SnapshotSizeCapable (probed right after pause) while signalling "no data" -- the snapshot_size series event is skipped, not crashed. A follow-on can stat the cube snapshot dir on the host like aenv's scan_snapshot_sizes. - create_one / kill_one: trajectory-mode ephemeral lifecycle. Mirrors aenv verbatim -- the path is provider-agnostic, routing through the base manager seams (_new_state / _create_single / _ready_checker / _apply_ready / _handle_of / _kill_one / _slot_templates) the cube manager already supplies. create_one forwards metadata + template; stamps _slot_templates so _to_instance stamps the resolved template. kill_one is finally-safe (missing state returns, present state kill + is_alive=False). - default_replay_mode flipped exec_only -> lifecycle (cube has native pause/resume WITH a memory snapshot -- the same memory-reuse oversubscription shape as aenv). - Added a try/except Sandbox import (resume uses Sandbox.connect); mock mirrors aenv's, keeping the module importable without the SDK. bench.py: the lifecycle/trajectory validation error messages now guide users to "--provider aenv or --provider cubesandbox" (cube is now LifecycleCapable + EphemeralCapable, so the aenv-only guidance was stale). Tests: the 3 Phase 1 identity assertions (exec_only / not-Lifecycle / not-Ephemeral) are replaced with Phase 2 versions (lifecycle / IS-Lifecycle / IS-Ephemeral / IS-Snapshot) plus 11 behavioral tests: pause forwards wait=True + missing-handle raises; resume swaps the handle via connect + missing-state raises; snapshot_sizes returns None; create_one runs the full manager seams (metadata/template forwarding, ready probe, _slot_templates stamping, sdk-failure raises); kill_one calls kill + marks dead + missing state noop. All 47 cube tests + the full kernel/provider suite pass. vm_monitor integration (cube-hypervisor vs cloud-hypervisor VMM name) and real snapshot-size host-stat collection stay deferred.
… + usage §8
Records the now-merged Phase 1 + Phase 2 surface (lifecycle + ephemeral +
snapshot) in the project guide and the CN replay mode guide:
CLAUDE.md:
- Scenarios: add CubeSandbox (Cloud Hypervisor KVM microVM, lifecycle-capable).
- Architecture diagram + provider-leaves: list aenv + cubesandbox (the CLI
choices line and leaf row were stale, missing aenv).
- Provider impls: describe aenv (subclasses E2BProvider, lifecycle/ephemeral/
snapshot) and cubesandbox (native pause/connect-resume, snapshot_sizes=None).
- Key Packages table: src/env_provider/ now lists e2b/aenv/docker/cubesandbox/
fake + the Protocols.
- monitor: cubesandbox -> skipped (vmm_type None, cube-hypervisor vs
cloud-hypervisor unresolved).
- Replay modes: lifecycle/trajectory note aenv + cubesandbox as capable;
exec_only stays e2b/docker/fake; cubesandbox snapshot_sizes=None skips the
snapshot_size event.
- Entry points + phase ladder: --provider adds cubesandbox; Tier 2 lists
e2b/aenv/cubesandbox.
- Install note: cubesandbox is an optional-dependency extra (like e2b/docker).
- Adding-a-provider: cubesandbox is the worked example for a full lifecycle
backend; notes the structural Protocols + the optional-dependency step.
docs/bench-core-usage-zh.md §8:
- Intro + mode table: aenv/cubesandbox interchangeable for lifecycle &
trajectory; cubesandbox snapshot_sizes=None note.
- Example command: --provider cubesandbox as a drop-in for lifecycle.
- CLI provider list: {fake,e2b,docker,aenv,cubesandbox}.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Phase 2 of the cubesandbox provider, stacked on #137 (Phase 1 exec-only). This lifts the provider from exec-only to the full replay capability surface, mirroring aenv's lifecycle shape over the native CubeSandbox pause/resume (the Cloud Hypervisor fork writes a memory snapshot the resume restores from -- the same memory-reuse oversubscription shape as aenv).
Scope (Phase 2 — full capability)
CubesandboxProvidergains the three replay Protocols:LifecycleCapable—pause= nativestate.cube_sandbox.pause(wait=True)(synchronous: the snapshot must be stable before the runner accounts the pause);resume=state.cube_sandbox = Sandbox.connect(inst.id)(cube'sconnectauto-resumes a paused sandbox -- the deprecated standaloneresume()is replaced byconnect-- and returns a fresh handle, swapped in like the manager's_attach).EphemeralCapable—create_one/kill_one(trajectory mode). Mirrors aenv verbatim: the path is provider-agnostic, routing through the base manager seams (_new_state/_create_single/_ready_checker/_apply_ready/_handle_of/_kill_one/_slot_templates) the cube manager already supplies.create_oneforwardsmetadata+template; stamps_slot_templatesso_to_instancestamps the resolved template.kill_oneis finally-safe (missing state returns).SnapshotSizeCapable—snapshot_sizesreturnsNonefor now. The cube SDK'sSnapshotInfoexposes onlysnapshot_id+names(no size fields), so per-pause size collection can't be satisfied from the control plane yet.Nonekeeps the providerSnapshotSizeCapable(probed right afterpause) while signalling "no data" -- thesnapshot_sizeseries event is skipped, not crashed. A follow-on can stat the cube snapshot dir on the host like aenv'sscan_snapshot_sizes.default_replay_modeflipsexec_only→lifecycle(cube has native pause/resume WITH a memory snapshot).vmm_typestaysNone(vm_monitor deferred).A try/except
Sandboximport is added to the provider module (resume usesSandbox.connect); the mock mirrors aenv's, keeping it importable without the SDK.bench.py
The lifecycle/trajectory validation error messages now guide users to
--provider aenv or --provider cubesandbox(cube is nowLifecycleCapable+EphemeralCapable, so the aenv-only guidance was stale).Tests
The 3 Phase 1 identity assertions (
exec_only/ not-Lifecycle / not-Ephemeral) are replaced with Phase 2 versions (lifecycle/ IS-Lifecycle / IS-Ephemeral / IS-Snapshot) plus 11 behavioral tests:pauseforwardswait=True+ missing-handle raisesresumeswaps the handle viaconnect+ missing-state raisessnapshot_sizesreturnsNonecreate_oneruns the full manager seams (metadata/template forwarding, ready probe,_slot_templatesstamping, sdk-failure raises)kill_onecallskill+ marks dead + missing-state noopAll 47 cube tests + the full kernel/provider suite pass.
Verification
Stacking
feat/cubesandbox-provider-exec) — this PR targets that branch.feat/cubesandbox-provider-rfc) — base of feat(cubesandbox): exec-only provider (Phase 1, stacked on RFC #136) #137.When #137 merges, this PR retargets to the next base up.