Documentation
¶
Index ¶
- Variables
- type ClusterSecretRecord
- type CustomDomainRow
- type PendingImageGCEntry
- type ReserveHostPortResult
- type Store
- func (s *Store) AddCustomDomain(ctx context.Context, sandboxID, hostname string) error
- func (s *Store) ClaimIdempotentRequest(ctx context.Context, scope, fingerprint string, now time.Time, ...) (*models.IdempotentRequestRecord, bool, error)
- func (s *Store) ClearNetworkQuotaExceeded(ctx context.Context, id string) error
- func (s *Store) Close() error
- func (s *Store) CompleteIdempotentRequest(ctx context.Context, scope, fingerprint, targetID string, now time.Time, ...) error
- func (s *Store) Create(ctx context.Context, sandbox *models.Sandbox) error
- func (s *Store) CreateSnapshot(ctx context.Context, snapshot *models.SandboxSnapshot) error
- func (s *Store) Delete(ctx context.Context, id string) error
- func (s *Store) DeleteClusterSecretsForSandbox(ctx context.Context, sandboxID string) error
- func (s *Store) DeleteIdempotentRequest(ctx context.Context, scope, fingerprint string) error
- func (s *Store) DeleteMounts(ctx context.Context, sandboxID string) error
- func (s *Store) DeletePendingImageGC(ctx context.Context, image string) error
- func (s *Store) DeletePendingImageGCIfScheduledAt(ctx context.Context, image string, at time.Time) (bool, error)
- func (s *Store) DeletePort(ctx context.Context, sandboxID string, port int) error
- func (s *Store) DeleteSnapshot(ctx context.Context, name string) error
- func (s *Store) DeleteSnapshotAlias(ctx context.Context, alias string) error
- func (s *Store) Get(ctx context.Context, id string) (*models.Sandbox, error)
- func (s *Store) GetClusterSecret(ctx context.Context, ref string) (*ClusterSecretRecord, error)
- func (s *Store) GetCompatState(ctx context.Context, sandboxID, facade string) (*models.SandboxCompatState, error)
- func (s *Store) GetIdempotentRequest(ctx context.Context, scope, fingerprint string) (*models.IdempotentRequestRecord, error)
- func (s *Store) GetMounts(ctx context.Context, sandboxID string) ([]byte, error)
- func (s *Store) GetPortByHostPort(ctx context.Context, hostPort int) (*models.ExposedPort, error)
- func (s *Store) GetSnapshot(ctx context.Context, name string) (*models.SandboxSnapshot, error)
- func (s *Store) GetSnapshotAlias(ctx context.Context, alias string) (*models.SnapshotAlias, error)
- func (s *Store) HasActiveImageRef(ctx context.Context, image string) (bool, error)
- func (s *Store) List(ctx context.Context) ([]*models.Sandbox, error)
- func (s *Store) ListAllCustomDomains(ctx context.Context) ([]CustomDomainRow, error)
- func (s *Store) ListAllExposedPorts(ctx context.Context) ([]models.ExposedPort, error)
- func (s *Store) ListAutoImportPendingIDs(ctx context.Context) ([]string, error)
- func (s *Store) ListCompatState(ctx context.Context, facade string) (map[string]models.SandboxCompatState, error)
- func (s *Store) ListCustomDomains(ctx context.Context, sandboxID string) ([]models.CustomDomain, error)
- func (s *Store) ListPendingImageGCDue(ctx context.Context, cutoff time.Time, limit int) ([]PendingImageGCEntry, error)
- func (s *Store) ListSnapshotAliases(ctx context.Context, facade string) (map[string]models.SnapshotAlias, error)
- func (s *Store) ListSnapshots(ctx context.Context) ([]*models.SandboxSnapshot, error)
- func (s *Store) ListSnapshotsPendingPush(ctx context.Context) ([]*models.SandboxSnapshot, error)
- func (s *Store) MarkNetworkQuotaExceeded(ctx context.Context, id string, detectedAt time.Time) error
- func (s *Store) PutClusterSecret(ctx context.Context, rec ClusterSecretRecord) error
- func (s *Store) PutMounts(ctx context.Context, sandboxID string, sealed []byte) error
- func (s *Store) RefreshPendingImageGCIfExists(ctx context.Context, image string, at time.Time) (bool, error)
- func (s *Store) RemoveCustomDomain(ctx context.Context, sandboxID, hostname string) error
- func (s *Store) ResolveCustomDomain(ctx context.Context, hostname string) (string, error)
- func (s *Store) ResolveSandboxIDByName(ctx context.Context, name string) (string, error)
- func (s *Store) SchedulePendingImageGC(ctx context.Context, image string, at time.Time) error
- func (s *Store) SetAutoImportPending(ctx context.Context, id string, pending bool) error
- func (s *Store) SetCustomDomainStatus(ctx context.Context, hostname string, status models.CustomDomainStatus, ...) error
- func (s *Store) SetNetworkLimits(ctx context.Context, id string, bytesInLimit, bytesOutLimit int64) error
- func (s *Store) SetSnapshotPushState(ctx context.Context, name, state, errMsg string) error
- func (s *Store) SetWakeArmed(ctx context.Context, id string, armed bool) error
- func (s *Store) Touch(ctx context.Context, id string, at time.Time) error
- func (s *Store) TryReserveHostPort(ctx context.Context, sandboxID string, containerPort, hostPort int, ...) (ReserveHostPortResult, error)
- func (s *Store) UpdateLifecycle(ctx context.Context, id string, l models.Lifecycle) error
- func (s *Store) UpdateRuntime(ctx context.Context, id, containerID, containerIP, publicURL string) error
- func (s *Store) UpdateSandboxNetCounters(ctx context.Context, id string, deltaIn, deltaOut int64) error
- func (s *Store) UpdateSnapshotImageDistribution(ctx context.Context, name, mode, registryRef, digest string) error
- func (s *Store) UpdateStatus(ctx context.Context, id string, status models.SandboxStatus, lastError string) error
- func (s *Store) UpdateTags(ctx context.Context, id string, tags map[string]string) error
- func (s *Store) Upsert(ctx context.Context, sandbox *models.Sandbox) error
- func (s *Store) UpsertCompatState(ctx context.Context, sandboxID, facade, stateJSON string) error
- func (s *Store) UpsertPort(ctx context.Context, exposure models.ExposedPort) error
- func (s *Store) UpsertSnapshotAlias(ctx context.Context, alias models.SnapshotAlias) error
Constants ¶
This section is empty.
Variables ¶
var ErrCustomDomainConflict = errors.New("custom domain hostname already taken")
ErrCustomDomainConflict is returned by AddCustomDomain when the hostname is already owned by a different sandbox. Surfaced through the API as 409. Same hostname for the same sandbox is idempotent (not a conflict) — that lets retries and reconcile re-converge without surfacing spurious errors.
var ErrNotFound = errors.New("sandbox not found")
var ErrSandboxNameConflict = errors.New("sandbox name already in use")
ErrSandboxNameConflict is returned by Create/Upsert when the sandbox's name collides with an existing row's name or id. Names are unique across the sandboxes table; empty names skip the name uniqueness check but ids still cannot collide with existing non-empty names.
var ErrSnapshotNameConflict = errors.New("snapshot name already in use")
Functions ¶
This section is empty.
Types ¶
type ClusterSecretRecord ¶ added in v0.2.1
type ClusterSecretRecord struct {
Ref string
SandboxID string
Version int
Recipients []string
SealedPayload []byte
CreatedAt time.Time
UpdatedAt time.Time
}
ClusterSecretRecord is an opaque cluster-secret payload addressed by ref. The store never decrypts SealedPayload; service owns the envelope format.
type CustomDomainRow ¶ added in v0.3.1
type CustomDomainRow struct {
Hostname string
SandboxID string
Status models.CustomDomainStatus
LastError string
CreatedAt time.Time
UpdatedAt time.Time
}
CustomDomainRow is the per-row representation read out of sandbox_custom_domains. ListAllCustomDomains returns these so the reconcile loop and the cluster FSM hydration can walk the full set.
type PendingImageGCEntry ¶ added in v0.3.1
PendingImageGCEntry is one row from the pending_image_gc ledger. scheduled_at travels with the image so the janitor can pin its remove/delete decision to the exact row it observed — see DeletePendingImageGCIfScheduledAt for the refresh-race rationale.
type ReserveHostPortResult ¶ added in v0.1.4
type ReserveHostPortResult struct {
Reserved bool
Existing *models.ExposedPort
}
ReserveHostPortResult is the three-state outcome of TryReserveHostPort. Exactly one of Reserved/Existing/(neither) is set:
- Reserved: the row was inserted; the candidate host port is now ours.
- Existing != nil: a row for (sandbox_id, port) already exists. The allocator MUST stop walking the pool — no other host_port will satisfy the (sandbox_id, port) primary key. Caller decides whether to reuse the existing exposure or surface an error.
- both zero: the partial unique index on host_port rejected this candidate (some other sandbox owns it). Caller may retry.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) AddCustomDomain ¶ added in v0.3.1
AddCustomDomain inserts a hostname → sandbox mapping. Returns ErrCustomDomainConflict when the hostname is already owned by a different sandbox; returns nil when the same (hostname, sandbox) pair already exists (idempotent — the caller may retry safely). New rows start in CustomDomainPendingDNS; existing rows are left in whatever state they hold.
func (*Store) ClaimIdempotentRequest ¶ added in v0.1.7
func (s *Store) ClaimIdempotentRequest(ctx context.Context, scope, fingerprint string, now time.Time, pendingTTL time.Duration) (*models.IdempotentRequestRecord, bool, error)
ClaimIdempotentRequest is the generic claim/replay primitive for caller-retry dedupe. scope is a facade-defined namespace string ("e2b.create" today; "daytona.create" or "v1.create" later) so the same fingerprint can be reused across facades without colliding.
Three outcomes per call:
- INSERTed a fresh pending row → acquired=true, caller owns the work.
- Found a Ready row whose ReplayUntil has not expired → acquired=false, caller replays the TargetID instead of running the work again.
- Found a Pending row whose LockedUntil has not expired → acquired=false, caller waits.
Stale Pending or Ready rows past their TTLs are reclaimed as a fresh Pending row (acquired=true), so a crashed claimer cannot block future retries indefinitely.
func (*Store) ClearNetworkQuotaExceeded ¶ added in v0.1.7
ClearNetworkQuotaExceeded resets the flag and the detection timestamp. Used when an operator raises the limit (or sets it to unlimited) and the counter is no longer over the new ceiling.
func (*Store) CompleteIdempotentRequest ¶ added in v0.1.7
func (s *Store) CompleteIdempotentRequest(ctx context.Context, scope, fingerprint, targetID string, now time.Time, replayTTL time.Duration) error
CompleteIdempotentRequest moves a Pending row to Ready, recording the target ID the work produced and extending the lock-and-replay window out to replayTTL from now. Returns ErrNotFound if no row matched — indicating either a programming error or a too-aggressive cleanup that removed the row mid-flight.
func (*Store) CreateSnapshot ¶ added in v0.1.7
func (*Store) DeleteClusterSecretsForSandbox ¶ added in v0.2.1
func (*Store) DeleteIdempotentRequest ¶ added in v0.1.7
DeleteIdempotentRequest drops the row outright. Used by failure paths where the in-flight write rolled back and the next retry should run the work again from scratch instead of waiting for LockedUntil.
func (*Store) DeleteMounts ¶
DeleteMounts removes mount config for a sandbox. The cascade on the sandboxes table handles this when a sandbox is destroyed; explicit deletes are useful for replacing mounts.
func (*Store) DeletePendingImageGC ¶ added in v0.3.1
DeletePendingImageGC removes the ledger row for an image unconditionally. Used when the janitor decides the image is back in use (HasActiveImageRef = true) and the row should be dropped regardless of timestamp — the destroy path will re-schedule with a fresh timestamp if the image goes idle again. Missing rows are not an error.
func (*Store) DeletePendingImageGCIfScheduledAt ¶ added in v0.3.1
func (s *Store) DeletePendingImageGCIfScheduledAt(ctx context.Context, image string, at time.Time) (bool, error)
DeletePendingImageGCIfScheduledAt removes the row only if its scheduled_at still matches `at` — i.e. nobody has refreshed the row since the janitor observed it. Returns whether the delete actually happened so the caller can detect the refresh race.
Why this exists: the sweep does (list, [check active, remove image, delete row]). If a destroy of another sandbox sharing the image upserts the row with a fresh timestamp between the list and the delete, an unconditional delete would silently throw away the extended TTL that destroy was supposed to buy. The janitor uses this to keep the "TTL clock restarts from the most recent destroy" contract under churn.
func (*Store) DeletePort ¶
func (*Store) DeleteSnapshot ¶ added in v0.1.7
func (*Store) DeleteSnapshotAlias ¶ added in v0.1.7
DeleteSnapshotAlias removes the alias row. FK cascade also drops the row when its underlying sandbox_snapshots row is deleted, so explicit deletes are only needed when the facade wants to forget an alias without removing the native snapshot.
func (*Store) GetClusterSecret ¶ added in v0.2.1
func (*Store) GetCompatState ¶ added in v0.1.7
func (s *Store) GetCompatState(ctx context.Context, sandboxID, facade string) (*models.SandboxCompatState, error)
GetCompatState returns the state blob for (sandboxID, facade), or ErrNotFound when no row exists. Callers unmarshal state_json themselves.
func (*Store) GetIdempotentRequest ¶ added in v0.1.7
func (s *Store) GetIdempotentRequest(ctx context.Context, scope, fingerprint string) (*models.IdempotentRequestRecord, error)
GetIdempotentRequest returns the row for (scope, fingerprint), or ErrNotFound when no row exists.
func (*Store) GetMounts ¶
GetMounts returns the encrypted mount blob, or ErrNotFound if no row exists.
func (*Store) GetPortByHostPort ¶ added in v0.2.4
GetPortByHostPort returns the raw-TCP exposure bound to hostPort, or nil if no exposure owns it. The L4 wake listener uses this to map Caddy's PROXY protocol destination port back to a sandbox/container port.
func (*Store) GetSnapshot ¶ added in v0.1.7
func (*Store) GetSnapshotAlias ¶ added in v0.1.7
GetSnapshotAlias returns the alias row, or ErrNotFound if the alias does not exist.
func (*Store) HasActiveImageRef ¶
HasActiveImageRef reports whether any sandbox row references image with a status other than destroyed. Used by image GC: when this returns false the caller may safely remove the image from Docker. Single indexed query — constant cost regardless of how many destroyed rows have accumulated, so 10k destroyed historical rows do not slow the destroy hot path. Returns true on empty image as a conservative default (caller treats it as "still in use, do not delete").
func (*Store) ListAllCustomDomains ¶ added in v0.3.1
func (s *Store) ListAllCustomDomains(ctx context.Context) ([]CustomDomainRow, error)
ListAllCustomDomains returns every row in the table. Used by the reconcile loop's matcher-GC pass and by the cluster FSM hydration on cold start. Ordered by hostname so reconcile diffs are stable across calls.
func (*Store) ListAllExposedPorts ¶ added in v0.1.4
ListAllExposedPorts returns every row in exposed_ports across every sandbox. Used by reconcile to GC zombie caddy routes / layer4 servers without N+1 per-sandbox lookups.
func (*Store) ListAutoImportPendingIDs ¶ added in v0.2.3
ListAutoImportPendingIDs returns the IDs of sandboxes whose post-pull auto-import has not yet succeeded. Returns IDs only (not full Sandbox rows) so the reconciler can fetch+retry one at a time and skip rows that have meanwhile been deleted without holding a large in-memory snapshot. Hits the partial index on (auto_import_pending = 1).
func (*Store) ListCompatState ¶ added in v0.1.7
func (s *Store) ListCompatState(ctx context.Context, facade string) (map[string]models.SandboxCompatState, error)
ListCompatState returns every row for the given facade keyed by sandbox_id. Empty result is map of length zero, not nil — callers can always index into it.
func (*Store) ListCustomDomains ¶ added in v0.3.1
func (s *Store) ListCustomDomains(ctx context.Context, sandboxID string) ([]models.CustomDomain, error)
ListCustomDomains returns the canonical-ordered rows for one sandbox. Empty slice (nil) when the sandbox has no custom domains.
func (*Store) ListPendingImageGCDue ¶ added in v0.3.1
func (s *Store) ListPendingImageGCDue(ctx context.Context, cutoff time.Time, limit int) ([]PendingImageGCEntry, error)
ListPendingImageGCDue returns rows whose scheduled_at is at or before cutoff (the janitor passes now - ImageBuildGCTTL). Ordered by scheduled_at so the oldest entries get GC'd first within a sweep. `limit` caps the batch so a backlog (janitor disabled for a while then re-enabled, or just thousands of destroyed sandboxes sharing a few images) doesn't fan out into one huge serial Docker spike per tick — pass 0 for unbounded. scheduled_at is returned so the caller can guard the conditional delete in DeletePendingImageGCIfScheduledAt.
func (*Store) ListSnapshotAliases ¶ added in v0.1.7
func (s *Store) ListSnapshotAliases(ctx context.Context, facade string) (map[string]models.SnapshotAlias, error)
ListSnapshotAliases returns all alias rows for the given facade keyed by alias. Pass empty facade to fetch every alias regardless of facade.
func (*Store) ListSnapshots ¶ added in v0.1.7
func (*Store) ListSnapshotsPendingPush ¶ added in v0.2.4
ListSnapshotsPendingPush returns snapshots the reconciler should retry — 'pending' is the brand-new state set by the snapshot-create path, 'error' is what a failed previous attempt left behind. 'pushing' is intentionally excluded so a row currently being processed by another reconciler tick (or a still-running goroutine kicked off by snapshot-create) is not re-claimed before its terminal state lands.
func (*Store) MarkNetworkQuotaExceeded ¶ added in v0.1.7
func (s *Store) MarkNetworkQuotaExceeded(ctx context.Context, id string, detectedAt time.Time) error
MarkNetworkQuotaExceeded flips the flag on. detectedAt records when the crossover was first observed so the API can surface it to the SDK. Calls when already-exceeded preserve the original detectedAt — the trigger time is the interesting one, not the most recent re-observation.
func (*Store) PutClusterSecret ¶ added in v0.2.1
func (s *Store) PutClusterSecret(ctx context.Context, rec ClusterSecretRecord) error
func (*Store) PutMounts ¶
PutMounts stores an encrypted mount blob for a sandbox. The blob is opaque to the store layer; encryption / decryption happens in the service layer.
func (*Store) RefreshPendingImageGCIfExists ¶ added in v0.3.1
func (s *Store) RefreshPendingImageGCIfExists(ctx context.Context, image string, at time.Time) (bool, error)
RefreshPendingImageGCIfExists pushes the row's scheduled_at forward when (and only when) a row for image is already present. The Create path calls this after store.Create succeeds, so a freshly-used image that previously had a pending GC gets its deadline reset from "now" instead of inheriting the original destroy's old timestamp.
UPDATE-only (not UPSERT) on purpose: a row should only ever exist when a destroy has scheduled an image for cleanup. We do NOT want the create path inserting one — that would turn pending_image_gc into a one-row-per-image-ever-used table. The row-count stays bounded by "images destroyed in the last TTL window". Returns whether a row was touched, so callers can distinguish "deadline pushed forward" from "no pending GC, nothing to push".
func (*Store) RemoveCustomDomain ¶ added in v0.3.1
RemoveCustomDomain deletes the (sandbox, hostname) row. Cross-sandbox removal is rejected — the API gets ErrNotFound rather than silently stealing a hostname from another sandbox.
func (*Store) ResolveCustomDomain ¶ added in v0.3.1
ResolveCustomDomain is the hot path for the TLSAsk handler — single PK lookup, no scan. Returns ErrNotFound for unknown hostnames so the handler can fold it into a 403 without an error log on the success path.
func (*Store) ResolveSandboxIDByName ¶ added in v0.1.7
ResolveSandboxIDByName returns the sandbox ID owning the given name, or ErrNotFound if no row matches. Empty input is rejected so an accidental "" lookup does not match a no-name sandbox via the partial unique index's escape hatch.
func (*Store) SchedulePendingImageGC ¶ added in v0.3.1
SchedulePendingImageGC records (or refreshes) a pending image-deletion row. UPSERT on the image PK means concurrent or repeated destroys collapse to one row and the TTL clock restarts from the most recent destroy — so a busy churn pattern on the same image keeps deferring removal instead of racing the janitor. Empty image is a no-op.
func (*Store) SetAutoImportPending ¶ added in v0.2.3
SetAutoImportPending toggles the AOCR auto-import retry flag. The post-pull auto-import path sets it to true on failure; the reconciler clears it after a successful import. The reconciler must call this rather than Upsert to avoid racing the runtime-state machine on the rest of the sandbox row.
func (*Store) SetCustomDomainStatus ¶ added in v0.3.1
func (s *Store) SetCustomDomainStatus(ctx context.Context, hostname string, status models.CustomDomainStatus, lastError string) error
SetCustomDomainStatus updates the per-domain state machine. Idempotent — repeated calls with the same (status, lastError) are still write-once on updated_at, which the caller may use as a heartbeat for "we saw an ask for this host". Returns ErrNotFound when the hostname is unknown so a caller observing an issuance failure for a since-removed host gets a clean signal.
func (*Store) SetNetworkLimits ¶ added in v0.1.7
func (s *Store) SetNetworkLimits(ctx context.Context, id string, bytesInLimit, bytesOutLimit int64) error
SetNetworkLimits replaces the per-sandbox network byte caps. Zero means unlimited; negative values are rejected. The handler validates first so the store does not re-validate. Returns ErrNotFound if no row matches id.
func (*Store) SetSnapshotPushState ¶ added in v0.2.4
SetSnapshotPushState is a narrow single-column update used by the push reconciler. errMsg is overwritten unconditionally (including to empty on success transitions) so callers don't have to remember to clear it.
func (*Store) SetWakeArmed ¶ added in v0.2.4
SetWakeArmed toggles the wake_armed flag and bumps updated_at. The flag is set when the sandbox stops in a way that should auto-resume on the next inbound HTTP request (lifecycle idle / involuntary exit, both while Lifecycle.Serverless is true). It is cleared on a manual stop and after a successful wake. Returns ErrNotFound if no row matches id.
This is a dedicated setter rather than going through Upsert so the stop-event path and wake completion don't race the rest of the runtime state on the row (status, container_id, container_ip, etc.).
func (*Store) TryReserveHostPort ¶ added in v0.1.4
func (s *Store) TryReserveHostPort(ctx context.Context, sandboxID string, containerPort, hostPort int, protocol, publicURL string, now time.Time) (ReserveHostPortResult, error)
TryReserveHostPort attempts to claim hostPort for (sandboxID, containerPort) in a single INSERT OR IGNORE. The OR IGNORE swallows two distinct UNIQUE failures — the (sandbox_id, port) primary key AND the partial index on host_port — so on a no-op insert we follow up with a SELECT to disambiguate. Without that disambiguation, retrying expose for an already-exposed port looks identical to a host_port collision and walks the whole allocator pool before failing with "exhausted".
func (*Store) UpdateLifecycle ¶
UpdateLifecycle replaces the lifecycle fields on a sandbox row (the four timers plus the serverless opt-in) and bumps updated_at. Other fields are untouched. Returns ErrNotFound if no row matches id. The caller must validate the Lifecycle first; the store does not re-validate (it would couple two layers for no gain). wake_armed is intentionally NOT touched here — it transitions on stop/wake events, not on lifecycle edits.
func (*Store) UpdateRuntime ¶
func (*Store) UpdateSandboxNetCounters ¶ added in v0.1.7
func (s *Store) UpdateSandboxNetCounters(ctx context.Context, id string, deltaIn, deltaOut int64) error
UpdateSandboxNetCounters bumps the cumulative ingress/egress counters by the given deltas. Both values are non-negative byte counts measured since the last sample. Concurrent calls are serialized by SQLite's single writer, and the UPDATE is atomic so a failed sample never partially applies. Returns ErrNotFound if the sandbox row was deleted between the poller's snapshot and this write — the netstats poller treats that as a cleanup signal and drops the in-memory baseline.
func (*Store) UpdateSnapshotImageDistribution ¶ added in v0.2.4
func (s *Store) UpdateSnapshotImageDistribution(ctx context.Context, name, mode, registryRef, digest string) error
UpdateSnapshotImageDistribution flips the distribution metadata on a snapshot row after a successful AOCR push — local_only → aocr. Called from the reconciler success path together with SetSnapshotPushState. VerifiedAt records when the push completed; cluster placement on other nodes uses this together with the new mode to decide the snapshot is fan-outable.
func (*Store) UpdateStatus ¶
func (*Store) UpdateTags ¶ added in v0.1.7
UpdateTags replaces sandboxes.tags_json on the row matching id and bumps updated_at. Used by facades that want to mutate the native tags field without round-tripping the entire sandbox struct through Upsert. Returns ErrNotFound if no row matches.
func (*Store) UpsertCompatState ¶ added in v0.1.7
UpsertCompatState writes the facade-private state blob for (sandboxID, facade). stateJSON is opaque to the store — each facade defines its own schema inside it. created_at is preserved on update so list ordering stays stable.
func (*Store) UpsertPort ¶
func (*Store) UpsertSnapshotAlias ¶ added in v0.1.7
UpsertSnapshotAlias maps a facade-shaped alternate identifier onto a native sandbox_snapshots row. created_at is preserved on update.