feat: snapshot/restore checkpoints (SAND-WP-0007)
Add workspace checkpoint API with SnapshotStore, extension hooks on compose-ssh and saas-stub, manager orchestration, CLI/HTTP surface, profile.compose-checkpoint, and docs/tests.
This commit is contained in:
parent
2760ef2373
commit
952cebf2e9
21 changed files with 966 additions and 34 deletions
|
|
@ -5,7 +5,12 @@ from __future__ import annotations
|
|||
from fastapi import FastAPI, HTTPException
|
||||
|
||||
from sandboxer.core.manager import SandboxManager
|
||||
from sandboxer.models import SandboxCreateRequest, SandboxStatus
|
||||
from sandboxer.models import (
|
||||
SandboxCreateRequest,
|
||||
SandboxStatus,
|
||||
SnapshotRecord,
|
||||
SnapshotRestoreRequest,
|
||||
)
|
||||
|
||||
app = FastAPI(title="sand-boxer", version="0.0.0")
|
||||
_manager = SandboxManager()
|
||||
|
|
@ -37,4 +42,44 @@ def destroy_sandbox(sandbox_id: str) -> SandboxStatus:
|
|||
try:
|
||||
return _manager.destroy(sandbox_id)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/v1/sandboxes/{sandbox_id}/snapshot", response_model=SnapshotRecord)
|
||||
def snapshot_sandbox(
|
||||
sandbox_id: str,
|
||||
name: str | None = None,
|
||||
) -> SnapshotRecord:
|
||||
try:
|
||||
return _manager.snapshot(sandbox_id, name=name)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except RuntimeError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/v1/snapshots/{snapshot_id}/restore", response_model=SandboxStatus)
|
||||
def restore_snapshot(
|
||||
snapshot_id: str,
|
||||
request: SnapshotRestoreRequest | None = None,
|
||||
) -> SandboxStatus:
|
||||
req = request or SnapshotRestoreRequest()
|
||||
try:
|
||||
return _manager.restore(snapshot_id, host=req.host, consumer=req.consumer)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except (ValueError, Exception) as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.get("/v1/snapshots", response_model=list[SnapshotRecord])
|
||||
def list_snapshots(sandbox_id: str | None = None) -> list[SnapshotRecord]:
|
||||
return _manager.list_snapshots(sandbox_id=sandbox_id)
|
||||
|
||||
|
||||
@app.get("/v1/snapshots/{snapshot_id}", response_model=SnapshotRecord)
|
||||
def get_snapshot(snapshot_id: str) -> SnapshotRecord:
|
||||
record = _manager.get_snapshot(snapshot_id)
|
||||
if not record:
|
||||
raise HTTPException(status_code=404, detail="snapshot not found")
|
||||
return record
|
||||
Loading…
Add table
Add a link
Reference in a new issue