service

package
v0.1.7 Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Service

type Service struct {
	// contains filtered or unexported fields
}

func New

func New(cfg config.Config, logger *slog.Logger, db *store.Store, runtimeDriver runtime.Runtime, eventsClient *docker.Client, caddyClient *caddy.Client, cipher *secrets.Cipher, mountManager *mounts.Manager, admitter *capacity.Admitter) *Service

func (*Service) Capacity

func (s *Service) Capacity() capacity.Snapshot

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 (s *Service) ClaimIdempotentRequest(ctx context.Context, scope, fingerprint string, now time.Time, pendingTTL time.Duration) (*models.IdempotentRequestRecord, bool, error)

func (*Service) CompleteIdempotentRequest added in v0.1.7

func (s *Service) CompleteIdempotentRequest(ctx context.Context, scope, fingerprint, targetID string, now time.Time, replayTTL time.Duration) error

func (*Service) CreateSandbox

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

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

func (*Service) DeleteSnapshot added in v0.1.7

func (s *Service) DeleteSnapshot(ctx context.Context, idOrName string) error

func (*Service) DeleteSnapshotAlias added in v0.1.7

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

func (*Service) DestroySandbox

func (s *Service) DestroySandbox(ctx context.Context, id string) error

func (*Service) EnsureLayer4Ready added in v0.1.4

func (s *Service) EnsureLayer4Ready(ctx context.Context) error

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

func (s *Service) EnsureNetstatsReady(ctx context.Context) error

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 (s *Service) GetCompatState(ctx context.Context, sandboxID, facade string) (*models.SandboxCompatState, error)

func (*Service) GetIdempotentRequest added in v0.1.7

func (s *Service) GetIdempotentRequest(ctx context.Context, scope, fingerprint string) (*models.IdempotentRequestRecord, error)

func (*Service) GetNetworkUsage added in v0.1.7

func (s *Service) GetNetworkUsage(ctx context.Context, id string) (*models.NetworkUsage, error)

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 (s *Service) GetSandbox(ctx context.Context, id string) (*models.Sandbox, error)

func (*Service) GetSnapshot added in v0.1.7

func (s *Service) GetSnapshot(ctx context.Context, idOrName string) (*models.SandboxSnapshot, error)

func (*Service) GetSnapshotAlias added in v0.1.7

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

func (*Service) Health

func (s *Service) Health(ctx context.Context) (models.HealthStatus, error)

func (*Service) ListCompatState added in v0.1.7

func (s *Service) ListCompatState(ctx context.Context, facade string) (map[string]models.SandboxCompatState, error)

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) ([]*models.Sandbox, error)

func (*Service) ListSnapshotAliases added in v0.1.7

func (s *Service) ListSnapshotAliases(ctx context.Context, facade string) (map[string]models.SnapshotAlias, error)

func (*Service) ListSnapshots added in v0.1.7

func (s *Service) ListSnapshots(ctx context.Context) ([]*models.SandboxSnapshot, error)

func (*Service) Reconcile

func (s *Service) Reconcile(ctx context.Context) error

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

func (s *Service) ReplayReservations(ctx context.Context)

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 (s *Service) ResizeSandbox(ctx context.Context, id string, req models.ResizeSandboxRequest) (*models.Sandbox, error)

func (*Service) ResolveSandboxIDByName added in v0.1.7

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

ResolveSandboxIDByName looks up the sandbox owning the given unique name. Empty name returns ErrNotFound (handled inside the store).

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

func (s *Service) StartBuiltImageGC(ctx context.Context)

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

func (s *Service) StartEventMonitor(ctx context.Context)

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

func (s *Service) StartLifecycleSweep(ctx context.Context)

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 (s *Service) StartReconcileLoop(ctx context.Context)

func (*Service) StartSandbox

func (s *Service) StartSandbox(ctx context.Context, id string) (*models.Sandbox, error)

func (*Service) StopSandbox

func (s *Service) StopSandbox(ctx context.Context, id string) (*models.Sandbox, error)

func (*Service) ToolboxTarget

func (s *Service) ToolboxTarget(ctx context.Context, id string) (ToolboxEndpoint, error)

func (*Service) TouchSandbox

func (s *Service) TouchSandbox(ctx context.Context, id string) error

func (*Service) UnexposePort

func (s *Service) UnexposePort(ctx context.Context, id string, port int) error

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

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

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

func (*Service) UpsertCompatState added in v0.1.7

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

func (*Service) UpsertSnapshotAlias added in v0.1.7

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

type ToolboxEndpoint

type ToolboxEndpoint struct {
	URL   string
	Token string
}

Jump to

Keyboard shortcuts

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