store

package
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("sandbox not found")
View Source
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.

View Source
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 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 Open

func Open(path string) (*Store, error)

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:

  1. INSERTed a fresh pending row → acquired=true, caller owns the work.
  2. Found a Ready row whose ReplayUntil has not expired → acquired=false, caller replays the TargetID instead of running the work again.
  3. 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

func (s *Store) ClearNetworkQuotaExceeded(ctx context.Context, id string) error

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) Close

func (s *Store) Close() error

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) Create

func (s *Store) Create(ctx context.Context, sandbox *models.Sandbox) error

func (*Store) CreateSnapshot added in v0.1.7

func (s *Store) CreateSnapshot(ctx context.Context, snapshot *models.SandboxSnapshot) error

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, id string) error

func (*Store) DeleteClusterSecretsForSandbox added in v0.2.1

func (s *Store) DeleteClusterSecretsForSandbox(ctx context.Context, sandboxID string) error

func (*Store) DeleteIdempotentRequest added in v0.1.7

func (s *Store) DeleteIdempotentRequest(ctx context.Context, scope, fingerprint string) error

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

func (s *Store) DeleteMounts(ctx context.Context, sandboxID string) error

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) DeletePort

func (s *Store) DeletePort(ctx context.Context, sandboxID string, port int) error

func (*Store) DeleteSnapshot added in v0.1.7

func (s *Store) DeleteSnapshot(ctx context.Context, name string) error

func (*Store) DeleteSnapshotAlias added in v0.1.7

func (s *Store) DeleteSnapshotAlias(ctx context.Context, alias string) error

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) Get

func (s *Store) Get(ctx context.Context, id string) (*models.Sandbox, error)

func (*Store) GetClusterSecret added in v0.2.1

func (s *Store) GetClusterSecret(ctx context.Context, ref string) (*ClusterSecretRecord, error)

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

func (s *Store) GetMounts(ctx context.Context, sandboxID string) ([]byte, error)

GetMounts returns the encrypted mount blob, or ErrNotFound if no row exists.

func (*Store) GetPortByHostPort added in v0.2.4

func (s *Store) GetPortByHostPort(ctx context.Context, hostPort int) (*models.ExposedPort, error)

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 (s *Store) GetSnapshot(ctx context.Context, name string) (*models.SandboxSnapshot, error)

func (*Store) GetSnapshotAlias added in v0.1.7

func (s *Store) GetSnapshotAlias(ctx context.Context, alias string) (*models.SnapshotAlias, error)

GetSnapshotAlias returns the alias row, or ErrNotFound if the alias does not exist.

func (*Store) HasActiveImageRef

func (s *Store) HasActiveImageRef(ctx context.Context, image string) (bool, error)

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) List

func (s *Store) List(ctx context.Context) ([]*models.Sandbox, error)

func (*Store) ListAllExposedPorts added in v0.1.4

func (s *Store) ListAllExposedPorts(ctx context.Context) ([]models.ExposedPort, error)

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

func (s *Store) ListAutoImportPendingIDs(ctx context.Context) ([]string, error)

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) 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 (s *Store) ListSnapshots(ctx context.Context) ([]*models.SandboxSnapshot, error)

func (*Store) ListSnapshotsPendingPush added in v0.2.4

func (s *Store) ListSnapshotsPendingPush(ctx context.Context) ([]*models.SandboxSnapshot, error)

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

func (s *Store) PutMounts(ctx context.Context, sandboxID string, sealed []byte) error

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) ResolveSandboxIDByName added in v0.1.7

func (s *Store) ResolveSandboxIDByName(ctx context.Context, name string) (string, error)

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) SetAutoImportPending added in v0.2.3

func (s *Store) SetAutoImportPending(ctx context.Context, id string, pending bool) error

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) 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

func (s *Store) SetSnapshotPushState(ctx context.Context, name, state, errMsg string) error

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

func (s *Store) SetWakeArmed(ctx context.Context, id string, armed bool) error

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) Touch

func (s *Store) Touch(ctx context.Context, id string, at time.Time) error

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

func (s *Store) UpdateLifecycle(ctx context.Context, id string, l models.Lifecycle) error

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 (s *Store) UpdateRuntime(ctx context.Context, id, containerID, containerIP, publicURL string) error

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 (s *Store) UpdateStatus(ctx context.Context, id string, status models.SandboxStatus, lastError string) error

func (*Store) UpdateTags added in v0.1.7

func (s *Store) UpdateTags(ctx context.Context, id string, tags map[string]string) error

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) Upsert

func (s *Store) Upsert(ctx context.Context, sandbox *models.Sandbox) error

func (*Store) UpsertCompatState added in v0.1.7

func (s *Store) UpsertCompatState(ctx context.Context, sandboxID, facade, stateJSON string) error

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 (s *Store) UpsertPort(ctx context.Context, exposure models.ExposedPort) error

func (*Store) UpsertSnapshotAlias added in v0.1.7

func (s *Store) UpsertSnapshotAlias(ctx context.Context, alias models.SnapshotAlias) error

UpsertSnapshotAlias maps a facade-shaped alternate identifier onto a native sandbox_snapshots row. created_at is preserved on update.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL