Documentation
¶
Index ¶
- Variables
- func GenerateSandboxID() (string, error)
- func ImageRequiresLocalPlacement(req models.CreateSandboxRequest) bool
- func IngressInstalledVersion() uint64
- func NormalizeCreateFailover(req *models.CreateSandboxRequest) error
- func RecordCreateReservationState(state string)
- func RecordExpiredReservations(count int)
- func RecordFacadeIdempotencyConflict(scope string)
- func RecordFacadeIdempotencyReplay(scope string)
- func RecordRouteMiss(reasons ...string)
- func RedactClusterSecrets(req models.CreateSandboxRequest) models.CreateSandboxRequest
- func SetIngressRouteLag(fsmVersion uint64)
- type ImageDistributionProvider
- type Service
- func (s *Service) AttachCluster(c cluster.Client)
- func (s *Service) Capacity() capacity.Snapshot
- func (s *Service) ClaimIdempotentRequest(ctx context.Context, scope, fingerprint string, now time.Time, ...) (*models.IdempotentRequestRecord, bool, error)
- func (s *Service) Cluster() cluster.Client
- func (s *Service) ClusterTopologyError() error
- func (s *Service) CompleteIdempotentRequest(ctx context.Context, scope, fingerprint, targetID string, now time.Time, ...) error
- func (s *Service) CreateSandbox(ctx context.Context, req models.CreateSandboxRequest) (*models.CreateSandboxResponse, error)
- func (s *Service) CreateSandboxWithID(ctx context.Context, req models.CreateSandboxRequest, id string) (*models.CreateSandboxResponse, error)
- func (s *Service) CreateSnapshot(ctx context.Context, sandboxID string, req models.CreateSandboxSnapshotRequest) (*models.SandboxSnapshot, error)
- func (s *Service) CreateSnapshotWithOwnership(ctx context.Context, sandboxID string, req models.CreateSandboxSnapshotRequest) (*models.SandboxSnapshot, bool, error)
- func (s *Service) DeleteClusterSecrets(ctx context.Context, sandboxID string) error
- func (s *Service) DeleteIdempotentRequest(ctx context.Context, scope, fingerprint string) error
- func (s *Service) DeleteSnapshot(ctx context.Context, idOrName string) error
- func (s *Service) DeleteSnapshotAlias(ctx context.Context, alias string) error
- func (s *Service) DestroySandbox(ctx context.Context, id string) error
- func (s *Service) EnsureClusterReady(ctx context.Context) error
- func (s *Service) EnsureLayer4Ready(ctx context.Context) error
- func (s *Service) EnsureNetstatsReady(ctx context.Context) error
- func (s *Service) ExposePort(ctx context.Context, id string, port int, protocol string) (models.ExposePortResponse, error)
- func (s *Service) GetCompatState(ctx context.Context, sandboxID, facade string) (*models.SandboxCompatState, error)
- func (s *Service) GetIdempotentRequest(ctx context.Context, scope, fingerprint string) (*models.IdempotentRequestRecord, error)
- func (s *Service) GetNetworkUsage(ctx context.Context, id string) (*models.NetworkUsage, error)
- func (s *Service) GetSandbox(ctx context.Context, id string) (*models.Sandbox, error)
- func (s *Service) GetSnapshot(ctx context.Context, idOrName string) (*models.SandboxSnapshot, error)
- func (s *Service) GetSnapshotAlias(ctx context.Context, alias string) (*models.SnapshotAlias, error)
- func (s *Service) Health(ctx context.Context) (models.HealthStatus, error)
- func (s *Service) ListCompatState(ctx context.Context, facade string) (map[string]models.SandboxCompatState, error)
- func (s *Service) ListMounts(ctx context.Context, sandboxID string) ([]models.MountSpecRedacted, error)
- func (s *Service) ListSandboxes(ctx context.Context, tagFilter map[string]string) ([]*models.Sandbox, error)
- func (s *Service) ListSnapshotAliases(ctx context.Context, facade string) (map[string]models.SnapshotAlias, error)
- func (s *Service) ListSnapshots(ctx context.Context) ([]*models.SandboxSnapshot, error)
- func (s *Service) NormalizeCreateImageDistribution(ctx context.Context, req *models.CreateSandboxRequest) error
- func (s *Service) OpenClusterSecrets(ctx context.Context, redacted models.CreateSandboxRequest, ...) (models.CreateSandboxRequest, error)
- func (s *Service) OpenClusterSecretsForNode(ctx context.Context, redacted models.CreateSandboxRequest, ...) (out models.CreateSandboxRequest, err error)
- func (s *Service) PutClusterSecretsForRecipient(ctx context.Context, sandboxID string, req models.CreateSandboxRequest, ...) (cluster.PlacementSecrets, error)
- func (s *Service) Reconcile(ctx context.Context) error
- func (s *Service) ReconcileClusterIngress(ctx context.Context) error
- func (s *Service) RecreateSandbox(ctx context.Context, id string, spec models.CreateSandboxRequest, ...) error
- func (s *Service) RegisterSnapshot(ctx context.Context, snapshot *models.SandboxSnapshot) (*models.SandboxSnapshot, error)
- func (s *Service) ReplayReservations(ctx context.Context)
- func (s *Service) ResizeSandbox(ctx context.Context, id string, req models.ResizeSandboxRequest) (*models.Sandbox, error)
- func (s *Service) ResolveSandboxIDByName(ctx context.Context, name string) (string, error)
- func (s *Service) SealClusterSecrets(req models.CreateSandboxRequest) ([]byte, error)
- func (s *Service) SealClusterSecretsForRecipient(req models.CreateSandboxRequest, recipient string) ([]byte, error)
- func (s *Service) SetNetworkLimits(ctx context.Context, id string, bytesInLimit, bytesOutLimit int64) (*models.NetworkUsage, error)
- func (s *Service) StartBuiltImageGC(ctx context.Context)
- func (s *Service) StartClusterIngressReconcile(ctx context.Context)
- func (s *Service) StartEventMonitor(ctx context.Context)
- func (s *Service) StartLifecycleSweep(ctx context.Context)
- func (s *Service) StartReconcileLoop(ctx context.Context)
- func (s *Service) StartSandbox(ctx context.Context, id string) (*models.Sandbox, error)
- func (s *Service) StopSandbox(ctx context.Context, id string) (*models.Sandbox, error)
- func (s *Service) ToolboxTarget(ctx context.Context, id string) (ToolboxEndpoint, error)
- func (s *Service) TouchSandbox(ctx context.Context, id string) error
- func (s *Service) UnexposePort(ctx context.Context, id string, port int) error
- func (s *Service) UnsealClusterSecrets(redacted models.CreateSandboxRequest, sealed []byte) (models.CreateSandboxRequest, error)
- func (s *Service) UnsealClusterSecretsForNode(redacted models.CreateSandboxRequest, sealed []byte, nodeID string) (models.CreateSandboxRequest, error)
- func (s *Service) UnsealRegistry(sealed []byte) (*models.RegistryAuth, error)
- func (s *Service) UpdateLifecycle(ctx context.Context, id string, l models.Lifecycle) (*models.Sandbox, error)
- func (s *Service) UpdateTags(ctx context.Context, sandboxID string, tags map[string]string) error
- func (s *Service) UpsertCompatState(ctx context.Context, sandboxID, facade, stateJSON string) error
- func (s *Service) UpsertSnapshotAlias(ctx context.Context, alias models.SnapshotAlias) error
- type ToolboxEndpoint
Constants ¶
This section is empty.
Variables ¶
ErrPreferredHostPortUnavailable is returned by exposePort when a TCP replay supplied a specific preferredHostPort that's already reserved (cluster-wide or on this node) and so cannot be re-bound. The allocator deliberately does NOT silently fall through to a fresh random port: cluster-stable TCP endpoints are the entire point of B6 — clients addressing host:40123 must not be invisibly rerouted to host:55555 after a failover-recreate. Park is the policy; the FSM record (with the original HostPort) stays intact and the watcher / operator surfaces the parked state instead of mutating the contract behind the client's back.
Functions ¶
func GenerateSandboxID ¶ added in v0.2.1
GenerateSandboxID is the exported entry point for the cluster handler's reservation-first create path: the router (Node A) needs to mint a sandbox ID before opReserve so the chosen target (Node T) can accept the forward with X-Cluster-Create-ID and run CreateSandboxWithID against the same reservation. Routes through the package-private generateSandboxID so the format stays in lockstep with the local create path.
func ImageRequiresLocalPlacement ¶ added in v0.2.1
func ImageRequiresLocalPlacement(req models.CreateSandboxRequest) bool
func IngressInstalledVersion ¶ added in v0.2.1
func IngressInstalledVersion() uint64
IngressInstalledVersion returns the highest placement.Version this node's ingress reconciler has finished installing routes for. The /v1/cluster/ placements/{id} convergence-status read compares this against the per- placement Version to answer "has this node bound the cluster-stable TCP route yet?" without reaching into Caddy state. Zero means the reconciler has not yet run a successful pass (fresh boot) — treat as "not converged" for any non-zero placement.Version.
func NormalizeCreateFailover ¶ added in v0.2.2
func NormalizeCreateFailover(req *models.CreateSandboxRequest) error
func RecordCreateReservationState ¶ added in v0.2.1
func RecordCreateReservationState(state string)
func RecordExpiredReservations ¶ added in v0.2.1
func RecordExpiredReservations(count int)
func RecordFacadeIdempotencyConflict ¶ added in v0.2.1
func RecordFacadeIdempotencyConflict(scope string)
func RecordFacadeIdempotencyReplay ¶ added in v0.2.1
func RecordFacadeIdempotencyReplay(scope string)
func RecordRouteMiss ¶ added in v0.2.1
func RecordRouteMiss(reasons ...string)
RecordRouteMiss bumps the route-miss counter from the API layer. Exported so pkg/api/v1 can wire it in without exposing the expvar directly (keeps the metric name owned by this package). Service has no logical role here — this is a package-level counter the v1 wrap layer pokes when it observes the no-usable-URL case.
func RedactClusterSecrets ¶ added in v0.2.1
func RedactClusterSecrets(req models.CreateSandboxRequest) models.CreateSandboxRequest
RedactClusterSecrets returns a copy of req with credentials stripped — safe to replicate via raft. The Registry field's Server/Username are preserved (not secret) but Password is cleared; mount Credentials maps are dropped per-entry. Maps and slices that the caller might mutate are deep-copied so the original req is left untouched.
Lives next to SealClusterSecrets because the two are always called as a pair: seal returns the encrypted bag, redact returns the safe-to-replicate spec, and writing one without the other would either leak secrets (no redact) or lose them on failover (no seal).
func SetIngressRouteLag ¶ added in v0.2.1
func SetIngressRouteLag(fsmVersion uint64)
SetIngressRouteLag is the post-tick hook the reconciler calls with the FSM's current PlacementVersion. Lag is computed as max(0, fsmVersion - ingressPlacementVersionMax). Computed here (not at recordIngressReconcile) so callers that only have the FSM version can still publish the lag without needing the reconciler's maxVersion.
Types ¶
type ImageDistributionProvider ¶ added in v0.2.1
type ImageDistributionProvider interface {
ClassifyImage(ctx context.Context, image string) (models.ImageDistributionMetadata, error)
}
ImageDistributionProvider is the control-plane contract for image availability. Providers may verify digests or talk to an external registry cache, but the core daemon only needs the resulting placement metadata.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) AttachCluster ¶ added in v0.2.1
AttachCluster swaps in a cluster.Client. Called from cmd/sandboxd/main after service.New when SB_ENABLE_CLUSTER=true. Idempotent.
func (*Service) Capacity ¶
Capacity returns the admitter's current snapshot. Returns the zero value when no admitter is configured (e.g. in tests).
func (*Service) ClaimIdempotentRequest ¶ added in v0.1.7
func (*Service) Cluster ¶ added in v0.2.1
Cluster returns the attached cluster.Client. Always non-nil.
func (*Service) ClusterTopologyError ¶ added in v0.2.2
ClusterTopologyError returns a production-topology violation for the current live member set. It is intentionally a runtime check so rolling membership, old nodes that still gossip empty roles, and explicit hybrid roles are all evaluated from the same source of truth the scheduler uses.
func (*Service) CompleteIdempotentRequest ¶ added in v0.1.7
func (*Service) CreateSandbox ¶
func (s *Service) CreateSandbox(ctx context.Context, req models.CreateSandboxRequest) (*models.CreateSandboxResponse, error)
func (*Service) CreateSandboxWithID ¶ added in v0.2.1
func (s *Service) CreateSandboxWithID(ctx context.Context, req models.CreateSandboxRequest, id string) (*models.CreateSandboxResponse, error)
CreateSandboxWithID is the failover-recreate entry point: it behaves like CreateSandbox but uses the supplied ID instead of generating a fresh one. Idempotent at the cluster boundary — if a sandbox with this ID already exists locally we return the existing record without touching docker. Used by the cluster owner watcher to re-materialize a sandbox after its previous owner died.
func (*Service) CreateSnapshot ¶ added in v0.1.7
func (s *Service) CreateSnapshot(ctx context.Context, sandboxID string, req models.CreateSandboxSnapshotRequest) (*models.SandboxSnapshot, error)
CreateSnapshot commits the sandbox container into a reusable local image. Idempotency is by snapshot name: repeated requests for the same sandbox + name return the stored snapshot metadata, while a different sandbox trying to claim the same name is rejected with a conflict.
func (*Service) CreateSnapshotWithOwnership ¶ added in v0.1.7
func (s *Service) CreateSnapshotWithOwnership(ctx context.Context, sandboxID string, req models.CreateSandboxSnapshotRequest) (*models.SandboxSnapshot, bool, error)
CreateSnapshotWithOwnership commits a sandbox image and reports whether this call created the native snapshot row. Callers that add companion metadata can use the flag to avoid rolling back a snapshot that already existed.
func (*Service) DeleteClusterSecrets ¶ added in v0.2.1
func (*Service) DeleteIdempotentRequest ¶ added in v0.1.7
func (*Service) DeleteSnapshot ¶ added in v0.1.7
func (*Service) DeleteSnapshotAlias ¶ added in v0.1.7
func (*Service) DestroySandbox ¶
func (*Service) EnsureClusterReady ¶ added in v0.2.1
EnsureClusterReady blocks until the cluster has elected a leader, mirroring the EnsureLayer4Ready single-flight latch shape. Single-node mode latches immediately. The API wrapper calls this before any RecordPlacement so a just-booted node doesn't 503 a CreateSandbox while raft is still catching up.
func (*Service) EnsureLayer4Ready ¶ added in v0.1.4
EnsureLayer4Ready bootstraps the caddy-l4 app under a single-flight mutex and latches success. Safe to call from boot AND from each L4 exposure path: the atomic fast-path turns it into a single load on the steady state, and a failed boot is recovered by the very next TCP/TLS expose call instead of surfacing as a confusing "layer4 app missing" error from caddy.
func (*Service) EnsureNetstatsReady ¶ added in v0.1.7
EnsureNetstatsReady boots the per-sandbox network byte-counter poller under a single-flight latch. Same lazy-bootstrap shape as EnsureLayer4Ready: caller pays the bootstrap cost only once across the daemon's lifetime, and the poller goroutine survives until ctx — typically the daemon's signal context — is cancelled.
Failure here is non-fatal: callers log and continue. Without the poller, network counters stay at zero and quotas never trigger; both Create and reads of /network/usage still work.
func (*Service) ExposePort ¶
func (s *Service) ExposePort(ctx context.Context, id string, port int, protocol string) (models.ExposePortResponse, error)
ExposePort publishes a sandbox container port through one of three caddy surfaces, selected by protocol:
- "" / "http": existing Caddy HTTP reverse-proxy route, returns https://<id>-<port>.<domain> (or the path-mode equivalent).
- "tcp": allocates a parent-host TCP port from the [SB_L4_PORT_RANGE_START, SB_L4_PORT_RANGE_END] pool, points caddy-l4 at it, and returns tcp://<public-host>:<host-port>. This is what unblocks native Postgres / Redis / MySQL DSNs in the spawn-postgres docs.
- "tls": adds a TLS-SNI route to the shared layer4 server. Requires --domain (so the SNI hostname has a place to resolve) and a non-empty SB_L4_TLS_LISTEN. Returns tls://<id>-<port>.<domain>:<l4-port>.
func (*Service) GetCompatState ¶ added in v0.1.7
func (*Service) GetIdempotentRequest ¶ added in v0.1.7
func (*Service) GetNetworkUsage ¶ added in v0.1.7
GetNetworkUsage returns the current cumulative byte counters and configured limits for a sandbox. Callers handle ErrNotFound translation.
Best-effort lazy bootstrap of the netstats poller: if boot's EnsureNetstatsReady failed (cold-start race against the docker daemon, etc.) this call retries it under the same single-flight latch. Failure is logged and swallowed — the caller still gets back whatever counters the store has, and the next call will retry again.
func (*Service) GetSandbox ¶
func (*Service) GetSnapshot ¶ added in v0.1.7
func (*Service) GetSnapshotAlias ¶ added in v0.1.7
func (*Service) ListCompatState ¶ added in v0.1.7
func (*Service) ListMounts ¶
func (s *Service) ListMounts(ctx context.Context, sandboxID string) ([]models.MountSpecRedacted, error)
ListMounts returns the redacted mount config for a sandbox. Credentials are never included in the response — they are write-only via CreateSandbox.
func (*Service) ListSandboxes ¶
func (s *Service) ListSandboxes(ctx context.Context, tagFilter map[string]string) ([]*models.Sandbox, error)
ListSandboxes returns sandboxes whose Tags match every entry in tagFilter. A nil or empty filter returns every sandbox on this node. Filtering happens in-memory after the store read because Tags is JSON-encoded; pushing the filter into SQL via json_extract is a follow-up once row counts make the extra hop worth it. The filter exists so an external control plane can ask "give me the sandboxes belonging to user X" without round-tripping every sandbox in the cluster (see plans/multi-tenancy-via-control-plane.md).
func (*Service) ListSnapshotAliases ¶ added in v0.1.7
func (*Service) ListSnapshots ¶ added in v0.1.7
func (*Service) NormalizeCreateImageDistribution ¶ added in v0.2.1
func (s *Service) NormalizeCreateImageDistribution(ctx context.Context, req *models.CreateSandboxRequest) error
NormalizeCreateImageDistribution resolves snapshot aliases and fills the create request's image-distribution metadata before placement decisions are made. The method is intentionally side-effect free: it does not pull, push, or verify image contents.
func (*Service) OpenClusterSecrets ¶ added in v0.2.1
func (s *Service) OpenClusterSecrets(ctx context.Context, redacted models.CreateSandboxRequest, secrets cluster.PlacementSecrets) (models.CreateSandboxRequest, error)
func (*Service) OpenClusterSecretsForNode ¶ added in v0.2.1
func (s *Service) OpenClusterSecretsForNode(ctx context.Context, redacted models.CreateSandboxRequest, secrets cluster.PlacementSecrets, nodeID string) (out models.CreateSandboxRequest, err error)
OpenClusterSecretsForNode resolves a replicated secret handle and merges the decrypted credentials back into a redacted spec. LegacySealed is still honored for placements written before the ref model.
func (*Service) PutClusterSecretsForRecipient ¶ added in v0.2.1
func (s *Service) PutClusterSecretsForRecipient(ctx context.Context, sandboxID string, req models.CreateSandboxRequest, recipient string) (cluster.PlacementSecrets, error)
PutClusterSecretsForRecipient stores the credential-bearing parts of req behind a provider ref and returns the handle safe to replicate through Raft. The local provider stores an encrypted recipient-bound envelope in SQLite; external KMS/secret-store providers can replace this boundary without changing cluster placement state.
func (*Service) ReconcileClusterIngress ¶ added in v0.2.1
func (*Service) RecreateSandbox ¶ added in v0.2.1
func (s *Service) RecreateSandbox(ctx context.Context, id string, spec models.CreateSandboxRequest, secrets cluster.PlacementSecrets, exposedPorts map[int]cluster.ExposedPortRoute) error
RecreateSandbox satisfies cluster.SandboxRecreator. The cluster owner watcher invokes this for any FSM placement that points to self. If the sandbox already exists locally, we still replay the replicated port intents: a previous recreate attempt may have created the container and then failed while restoring Caddy/L4 ingress.
secrets is the provider handle that can rehydrate the redacted spec; we resolve and re-merge it here via OpenClusterSecretsForNode so the recreated container can pull from the same private registry / mount the same external storage. A decrypt failure is fatal to this attempt but non-fatal globally — the watcher's retry loop (now with reassign-after-K-failures) will eventually move the placement to a node whose key matches.
Port replay tries every port but returns an error when any replay failed so the owner watcher keeps retrying and can eventually reassign the placement. ExposePort is idempotent, so a partial replay is safe to resume.
Only placements whose create spec opted into failover.policy=recreate reach this path; default sandboxes remain non-HA and are orphaned on owner death.
func (*Service) RegisterSnapshot ¶ added in v0.1.7
func (s *Service) RegisterSnapshot(ctx context.Context, snapshot *models.SandboxSnapshot) (*models.SandboxSnapshot, error)
RegisterSnapshot persists a snapshot row whose Image was resolved out-of-band — either a pre-existing registry image the caller supplied by name, or a freshly built local tag produced by the image builder (e.g. the daytona facade's buildInfo path). It does NOT call docker.CreateSnapshot; the image is assumed to already be runnable. Idempotency is by snapshot name; a re-register with matching image is treated as a no-op so SDK retries don't fail. A different image under the same name is a conflict.
func (*Service) ReplayReservations ¶
ReplayReservations re-populates the admitter from persistent state. Without this, after a daemon restart the admitter sees zero reservations and the host can be overcommitted on the first wave of new sandboxes. Destroyed AND stopped sandboxes are skipped — neither holds host CPU/RAM (the stop path releases the slot, and StartSandbox re-Admits on the way back up), so counting them here would re-introduce the overcommit-budget bug we fixed when stop began releasing capacity. Best-effort: a store error is logged, not returned, since admission control degrading to "unaware" is preferable to refusing to boot.
func (*Service) ResizeSandbox ¶
func (*Service) ResolveSandboxIDByName ¶ added in v0.1.7
ResolveSandboxIDByName looks up the sandbox owning the given unique name. Empty name returns ErrNotFound (handled inside the store).
func (*Service) SealClusterSecrets ¶ added in v0.2.1
func (s *Service) SealClusterSecrets(req models.CreateSandboxRequest) ([]byte, error)
SealClusterSecrets extracts the secret-bearing portions of req, marshals them as JSON, and encrypts the result with the service cipher. The output is opaque bytes safe to put in the raft log. Returns nil/nil when there are no secrets to seal so the FSM column stays empty for sandboxes that don't need it.
The legacy method emits a wildcard-recipient v2 envelope for compatibility. New cluster placement paths should prefer SealClusterSecretsForRecipient so the encrypted payload is authenticated to the specific owner node ID.
func (*Service) SealClusterSecretsForRecipient ¶ added in v0.2.1
func (*Service) SetNetworkLimits ¶ added in v0.1.7
func (s *Service) SetNetworkLimits(ctx context.Context, id string, bytesInLimit, bytesOutLimit int64) (*models.NetworkUsage, error)
SetNetworkLimits writes new caps (0 = unlimited) and re-evaluates the quota state. If the new limit moves the sandbox back under-quota, the matching ingress/egress block is cleared. If it leaves the sandbox over, the matching block is (re-)applied.
Egress clears are conditional: NetworkBlockAll uses the same DOCKER-USER row as the quota egress block, so we must not lift it here when the operator's blanket egress block is still on. See pkg/docker/netrules commentary on the shared rule.
func (*Service) StartBuiltImageGC ¶ added in v0.1.7
StartBuiltImageGC launches the periodic janitor that removes locally-built images (BuiltImageNamespace, i.e. "aerolvm-build/*") that are no longer referenced by any active sandbox AND were created more than the configured TTL ago. Without this, two failure modes leak images forever:
- POST /v1/images/build called standalone (no follow-up CreateSandbox).
- Build succeeded, CreateSandbox failed AND the daytona facade's inline rollback couldn't reach the daemon (e.g. server-side panic, dropped connection between build success and rollback call).
The TTL keeps the janitor from racing the dominant build+create flow: an image built moments ago must clear ImageBuildGCTTL before it's eligible, so a transient network hiccup between build and create can't have the janitor yanking an image the client is about to consume.
No-op if ImageBuildGCEnabled is false or ImageBuildGCInterval <= 0.
func (*Service) StartClusterIngressReconcile ¶ added in v0.2.1
func (*Service) StartEventMonitor ¶
StartEventMonitor launches the Docker event consumer goroutine. It is the realtime counterpart to Reconcile() — when a container dies, OOM-kills, or is destroyed out-of-band, this loop updates the DB and tears down routes within ~1s instead of waiting for the next reconcile tick.
func (*Service) StartLifecycleSweep ¶
StartLifecycleSweep launches the per-sandbox lifecycle ticker. Every minute it evaluates each sandbox's Lifecycle timers (StopIfIdleFor / DestroyIfIdleFor / StopAtAge / DestroyAtAge) plus the legacy global SB_IDLE_TIMEOUT_MIN fallback for sandboxes that don't declare any per-sandbox timers. Without either configured, the sweep still runs but is a no-op — kept on so a later UpdateLifecycle call doesn't need to start a goroutine.
func (*Service) StartReconcileLoop ¶
func (*Service) StartSandbox ¶
func (*Service) StopSandbox ¶
func (*Service) ToolboxTarget ¶
func (*Service) UnexposePort ¶
func (*Service) UnsealClusterSecrets ¶ added in v0.2.1
func (s *Service) UnsealClusterSecrets(redacted models.CreateSandboxRequest, sealed []byte) (models.CreateSandboxRequest, error)
UnsealClusterSecrets opens a sealed bag and merges the credentials back into the previously-redacted spec. Returns the merged spec; the input is not mutated. An empty sealed payload returns redacted unchanged so callers don't have to short-circuit themselves.
The merge prefers the redacted spec for non-secret fields (Registry Server/Username, mount Source/Target/Options) and overlays only the secret bits — so a future credential rotation that re-seals doesn't stomp on whatever the latest replicated metadata is.
func (*Service) UnsealClusterSecretsForNode ¶ added in v0.2.1
func (s *Service) UnsealClusterSecretsForNode(redacted models.CreateSandboxRequest, sealed []byte, nodeID string) (models.CreateSandboxRequest, error)
func (*Service) UnsealRegistry ¶ added in v0.2.1
func (s *Service) UnsealRegistry(sealed []byte) (*models.RegistryAuth, error)
UnsealRegistry decrypts a previously sealed RegistryAuth. Returns nil/nil when the input is empty (no credentials persisted). Exported for the boot-time backfill in cmd/sandboxd that rebuilds CreateSandboxRequest from the persisted Sandbox row.
func (*Service) UpdateLifecycle ¶
func (s *Service) UpdateLifecycle(ctx context.Context, id string, l models.Lifecycle) (*models.Sandbox, error)
UpdateLifecycle replaces the lifecycle timers on an existing sandbox. Full-replacement semantics: pass zero in any field to clear that timer. The sweep picks up the new values on its next tick (within ~1 minute), so a tightened deadline can fire as soon as the next sweep runs.
func (*Service) UpdateTags ¶ added in v0.1.7
UpdateTags replaces sandboxes.tags_json for the given sandbox. Tags are the native key/value bag — facades use it for label-style metadata (Daytona labels, E2B metadata).