Documentation
¶
Index ¶
- Constants
- 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 RecordPromoteRetract(result string)
- func RecordRouteMiss(reasons ...string)
- func RedactClusterSecrets(req models.CreateSandboxRequest) models.CreateSandboxRequest
- func SetIngressRouteLag(fsmVersion uint64)
- func SnapshotNeedsPush(snapshot *models.SandboxSnapshot) bool
- func TemplateNeedsPush(tpl *models.Template) bool
- func ValidateSnapshotRefArch(ref, hostArch string) error
- func WithReplicatedJSBundleOwner(ctx context.Context, owner string) context.Context
- type ACMEBudget
- type ACMEBudgetConfig
- type AutoImportConfig
- type AutoImportPendingStore
- type AutoImportReconcileStats
- type AutoImportReconciler
- type AutoImportRequest
- type AutoImportResult
- type AutoImportSpecMutator
- type AutoImportSpecResolver
- type AutoImporter
- type CustomDomainCacheEvicter
- type DNSResolver
- type DefaultDNSResolver
- type ImageDistributionProvider
- type PortEndpoint
- type RouteKind
- type RouteShape
- type Service
- func (s *Service) AddCustomDomain(ctx context.Context, sandboxID, hostname string, targetPort int) error
- func (s *Service) AttachCluster(c cluster.Client)
- func (s *Service) AttachCustomDomainCacheEvicter(e CustomDomainCacheEvicter)
- func (s *Service) AttachSnapshotPusher(pusher *SnapshotPusher, reconciler *SnapshotPushReconciler)
- func (s *Service) AttachTemplateArtifactPuller(p *TemplateArtifactPuller)
- func (s *Service) AttachTemplateArtifactPusher(pusher *TemplateArtifactPusher, reconciler *TemplateArtifactPushReconciler)
- func (s *Service) AttachWasmCheckpointPusher(pusher WasmCheckpointStore)
- 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) ClearClusterForTest()
- 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) CreateJSBundle(ctx context.Context, req models.CreateJSBundleRequest) (*models.JSBundle, error)
- func (s *Service) CreatePlatformVolume(ctx context.Context, name string) (*models.Volume, 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) CreateTemplate(ctx context.Context, req models.CreateTemplateRequest) (*models.Template, error)
- func (s *Service) CreateWasmModule(ctx context.Context, req models.CreateWasmModuleRequest) (*models.WasmModule, error)
- func (s *Service) CustomDomainDNS(ctx context.Context, sandboxID string) (models.CustomDomainDNSRecords, error)
- func (s *Service) DeleteByOwner(ctx context.Context, ownerRef string) 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) DeleteJSBundle(ctx context.Context, digest string) error
- func (s *Service) DeletePlatformVolume(ctx context.Context, id 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) DeleteTemplate(ctx context.Context, id string) error
- func (s *Service) DeleteWasmModule(ctx context.Context, id string) error
- func (s *Service) DestroySandbox(ctx context.Context, id string) error
- func (s *Service) DrainWasmSandboxes(ctx context.Context) 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) EnsureSandboxAwakeForHTTP(ctx context.Context, id string) (*models.Sandbox, error)
- func (s *Service) EnsureTemplateLocal(ctx context.Context, tpl *models.Template) error
- func (s *Service) EvacuateLocalWasmSandboxesForDrain(ctx context.Context) error
- func (s *Service) ExportWasmMigration(ctx context.Context, sandboxID string, w io.Writer) (cloneGen string, err error)
- func (s *Service) ExposePort(ctx context.Context, id string, port int, protocol string) (models.ExposePortResponse, error)
- func (s *Service) FireWebhook(_ context.Context, ownerRef, level string) error
- func (s *Service) ForceReconcileHTTPWakeShape(ctx context.Context) error
- func (s *Service) GCUnreferencedJSBundles(ctx context.Context) (int, 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) GetJSBundle(ctx context.Context, digest string) (*models.JSBundle, error)
- func (s *Service) GetNetworkUsage(ctx context.Context, id string) (*models.NetworkUsage, error)
- func (s *Service) GetPlatformVolume(ctx context.Context, id string) (*models.Volume, error)
- func (s *Service) GetPlatformVolumeByName(ctx context.Context, name string) (*models.Volume, 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) GetTemplate(ctx context.Context, id string) (*models.Template, error)
- func (s *Service) GetWasmModule(ctx context.Context, id string) (*models.WasmModule, error)
- func (s *Service) Health(ctx context.Context) (models.HealthStatus, error)
- func (s *Service) ImportWasmMigration(ctx context.Context, sandboxID, expectedCloneGen string, r io.Reader) (err error)
- func (s *Service) IngressDNSTarget() models.IngressTarget
- func (s *Service) IsSandboxStarted(ctx context.Context, id string) (bool, error)
- func (s *Service) ListCompatState(ctx context.Context, facade string) (map[string]models.SandboxCompatState, error)
- func (s *Service) ListCustomDomains(ctx context.Context, sandboxID string) ([]models.CustomDomain, error)
- func (s *Service) ListJSBundles(ctx context.Context) ([]*models.JSBundle, error)
- func (s *Service) ListMounts(ctx context.Context, sandboxID string) ([]models.MountSpecRedacted, error)
- func (s *Service) ListPlatformVolumes(ctx context.Context) ([]models.Volume, 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) ListTemplates(ctx context.Context) ([]*models.Template, error)
- func (s *Service) ListWasmModules(ctx context.Context) ([]*models.WasmModule, error)
- func (s *Service) LocalReadyTemplateIDs(ctx context.Context) []string
- func (s *Service) LocalReadyTemplateInventory(ctx context.Context) ([]string, bool)
- func (s *Service) LocalReadyWasmModuleInventory(ctx context.Context) ([]string, bool)
- func (s *Service) MarkImported(ctx context.Context, sandboxID string, registryRef string)
- func (s *Service) MarkSnapshotCorrupt(ctx context.Context, templateID, reason string) error
- func (s *Service) MigrateWasmSandbox(ctx context.Context, sandboxID, destDir string) (string, string, error)
- func (s *Service) MigrateWasmSandboxToNode(ctx context.Context, sandboxID, targetNodeID string) (resp *WasmMigrateResponse, err 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) PushWasmModule(ctx context.Context, name, tag, username, token string, data io.Reader) (*models.PushWasmModuleResponse, error)
- func (s *Service) PutClusterSecretsForRecipient(ctx context.Context, sandboxID string, req models.CreateSandboxRequest, ...) (cluster.PlacementSecrets, error)
- func (s *Service) RebuildTemplateSnapshot(ctx context.Context, templateID string) error
- func (s *Service) Reconcile(ctx context.Context) error
- func (s *Service) ReconcileClusterIngress(ctx context.Context) error
- func (s *Service) ReconstructWakeArmedIfNeeded(ctx context.Context, sandbox *models.Sandbox)
- 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) RekickUnhealthyTemplatesAtStart(ctx context.Context)
- func (s *Service) RemoveCustomDomain(ctx context.Context, sandboxID, hostname string) error
- func (s *Service) RepairLayer4Ready(ctx context.Context) error
- func (s *Service) ReplayClusterOwnership(ctx context.Context) (int, error)
- func (s *Service) ReplayReservations(ctx context.Context)
- func (s *Service) RequestTemplateRebuild(ctx context.Context, templateID string) (*models.Template, error)
- func (s *Service) ResizeSandbox(ctx context.Context, id string, req models.ResizeSandboxRequest) (*models.Sandbox, error)
- func (s *Service) ResolvePlatformVolumesForReplication(ctx context.Context, req *models.CreateSandboxRequest) error
- func (s *Service) ResolveSandboxIDByName(ctx context.Context, name string) (string, error)
- func (s *Service) RestoreByOwner(ctx context.Context, ownerRef string) error
- func (s *Service) RoundTripToolbox(ctx context.Context, sandboxID, method, path string, query url.Values, ...) (*http.Response, error)
- func (s *Service) RunJSBundleGCLoop(ctx context.Context, interval time.Duration)
- func (s *Service) SealClusterSecrets(req models.CreateSandboxRequest) ([]byte, error)
- func (s *Service) SealClusterSecretsForRecipient(req models.CreateSandboxRequest, recipient string) ([]byte, error)
- func (s *Service) ServeToolboxReverseProxy(ctx context.Context, sandboxID string, w http.ResponseWriter, r *http.Request, ...) error
- func (s *Service) SetContainerdRuntime(r runtime.Runtime)
- func (s *Service) SetDNSResolver(resolver DNSResolver)
- func (s *Service) SetDockerAuxClient(c *docker.Client)
- func (s *Service) SetEventsSource(src docker.EventsSource)
- func (s *Service) SetFirecrackerRuntime(r runtime.Runtime)
- func (s *Service) SetFleetAdmitter(a controlplane.Admitter)
- func (s *Service) SetIsolateBundleStore(bundleStore *jsbundle.Store)
- func (s *Service) SetIsolateRuntime(r runtime.Runtime)
- func (s *Service) SetJSBundleReplicator(...)
- func (s *Service) SetNetworkLimits(ctx context.Context, id string, bytesInLimit, bytesOutLimit int64) (*models.NetworkUsage, error)
- func (s *Service) SetTemplateBuilder(b TemplateBuilder)
- func (s *Service) SetTemplateCIDAllocator(a TemplateCIDAllocator)
- func (s *Service) SetTemplateSnapshotter(snap TemplateSnapshotter)
- func (s *Service) SetUsageReporter(r controlplane.Reporter)
- func (s *Service) SetVolumeReclaimer(r VolumeReclaimer)
- func (s *Service) SetWasmModuleResolver(r WasmModuleResolver)
- func (s *Service) SetWasmRuntime(r runtime.Runtime)
- func (s *Service) SetWasmWarmPool(p WasmWarmPoolNotifier)
- func (s *Service) SnapshotPushReconciler() *SnapshotPushReconciler
- func (s *Service) StartBuiltImageGC(ctx context.Context)
- func (s *Service) StartCaddyCoalescer(ctx context.Context)
- func (s *Service) StartClusterIngressReconcile(ctx context.Context)
- func (s *Service) StartEventMonitor(ctx context.Context)
- func (s *Service) StartL4WakeProxy(ctx context.Context) error
- func (s *Service) StartLifecycleSweep(ctx context.Context)
- func (s *Service) StartLiveUsageSampler(ctx context.Context)
- func (s *Service) StartPendingImageGC(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) StartTemplateGC(ctx context.Context)
- func (s *Service) StartVolumeReclaim(ctx context.Context)
- func (s *Service) StartWasmDurablePushSweep(ctx context.Context)
- func (s *Service) StartWasmModuleGC(ctx context.Context)
- func (s *Service) StartWasmPeriodicCheckpoint(ctx context.Context)
- func (s *Service) StopByOwner(ctx context.Context, ownerRef string) error
- func (s *Service) StopCaddyCoalescer()
- func (s *Service) StopSandbox(ctx context.Context, id string) (*models.Sandbox, error)
- func (s *Service) TemplateArtifactPushReconciler() *TemplateArtifactPushReconciler
- 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
- func (s *Service) WakeAwareL4PortTarget(ctx context.Context, id string, port int) (string, error)
- func (s *Service) WakeAwarePortTarget(ctx context.Context, id string, port int) (PortEndpoint, error)
- func (s *Service) WakeAwareToolboxTarget(ctx context.Context, id string) (ToolboxEndpoint, error)
- type SnapshotPushConfig
- type SnapshotPushDocker
- type SnapshotPushReconcileStats
- type SnapshotPushReconciler
- type SnapshotPushResult
- type SnapshotPushStore
- type SnapshotPusher
- type TemplateArtifactManifest
- type TemplateArtifactPullDocker
- type TemplateArtifactPuller
- type TemplateArtifactPushDocker
- type TemplateArtifactPushReconciler
- type TemplateArtifactPushResult
- type TemplateArtifactPushStats
- type TemplateArtifactPushStore
- type TemplateArtifactPusher
- type TemplateBuildRequest
- type TemplateBuildResult
- type TemplateBuilder
- type TemplateCIDAllocator
- type TemplateRotationConfig
- type TemplateRotationReconciler
- type TemplateRotationStats
- type TemplateRotationStore
- type TemplateRotationStoreAdapter
- type TemplateSnapshotRequest
- type TemplateSnapshotResult
- type TemplateSnapshotter
- type ToolboxEndpoint
- type VolumeReclaimer
- type WasmCheckpointPushResult
- type WasmCheckpointPusher
- func (p *WasmCheckpointPusher) DeleteRef(ctx context.Context, registryRef string) error
- func (p *WasmCheckpointPusher) DestRefFor(sandboxID string) string
- func (p *WasmCheckpointPusher) DestRefTagged(sandboxID, tag string) string
- func (p *WasmCheckpointPusher) PullOnce(ctx context.Context, registryRef, dstDir string) error
- func (p *WasmCheckpointPusher) PushOnce(ctx context.Context, sandboxID, memSnapDir string) (WasmCheckpointPushResult, error)
- func (p *WasmCheckpointPusher) PushOnceTo(ctx context.Context, sandboxID, memSnapDir, dest string) (WasmCheckpointPushResult, error)
- type WasmCheckpointStore
- type WasmMigrateRequest
- type WasmMigrateResponse
- type WasmModuleResolver
- type WasmWarmPoolNotifier
Constants ¶
const TemplateArtifactSchemaVersion = 1
TemplateArtifactSchemaVersion is the wire/storage schema of the manifest.json that travels inside the OCI image alongside the three artifact files. PR 6-B.2 (consumer side) reads this and refuses unknown versions; bumping it means a coordinated push/pull rollout.
Variables ¶
var AutoImportDisabledError = errors.New("auto-import disabled")
AutoImportDisabledError is returned by callsites that want to distinguish "feature off" from "feature on, but failed". main() can switch on it to suppress alerts.
var ErrCustomDomainNotSupported = models.ErrCustomDomainNotSupported
ErrCustomDomainNotSupported is re-exported from pkg/models so callers that already import internal/service (every handler) don't need a second import just to errors.Is against the sentinel. Same pattern other service-layer sentinels (ErrSandboxManuallyStopped) follow.
var ErrCustomDomainPerSandboxCap = models.ErrCustomDomainPerSandboxCap
ErrCustomDomainPerSandboxCap — see pkg/models comment.
var ErrCustomDomainPortMismatch = store.ErrCustomDomainPortMismatch
ErrCustomDomainPortMismatch surfaces the store-layer port-mismatch sentinel under the service-layer sentinel that the API handler already maps to 409. See store.ErrCustomDomainPortMismatch for the underlying rule.
var ErrCustomDomainProtocolConflict = models.ErrCustomDomainProtocolConflict
ErrCustomDomainProtocolConflict — see pkg/models comment.
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.
var ErrPublicTrafficDisabled = errors.New("public traffic is disabled for this sandbox; pass allow_public_traffic=true at create or expose a port to opt in")
ErrPublicTrafficDisabled is returned when a still-private sandbox (allow_public_traffic=false) is asked for a custom-domain route. It is NOT returned by expose_port — expose is the opt-in lever that flips the sandbox public (enableSandboxPublicTraffic); custom domains alone stay refused so that attaching a domain never silently publishes a sandbox the caller kept private. The sandbox stays reachable through the toolbox proxy and SSH gateway.
var ErrSandboxManuallyStopped = errors.New("sandbox manually stopped (do not wake)")
ErrSandboxManuallyStopped is returned by the wake helper when the sandbox was stopped via the manual StopSandbox path. Surfaces 409 at the control-plane proxy so the caller knows to call StartSandbox explicitly instead of triggering an implicit resume.
var ErrWakeCircuitOpen = errors.New("wake circuit open")
ErrWakeCircuitOpen is returned when the per-sandbox wake breaker is tripped (D3). Surfaces 503 + Retry-After: 60 at the control-plane proxy so a sandbox stuck in a cold-start failure loop does not thrash StartSandbox on every request for the full open window.
var ErrWasmCustomDomainPortNotExposed = errors.New("wasm custom domain target_port is not an exposed http port")
ErrWasmCustomDomainPortNotExposed is returned when a WASM sandbox custom domain targets a guest HTTP port that is not exposed while other HTTP ports already are. Attaching before the first expose_port is allowed.
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 RecordPromoteRetract ¶ added in v0.6.0
func RecordPromoteRetract(result string)
RecordPromoteRetract increments aerolvm_cluster_promote_retract_total after an overlapped create/promote failure path finishes its sync retract. result is typically "ok", "delete_placement_failed", or "delete_secrets_failed".
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.
func SnapshotNeedsPush ¶ added in v0.2.4
func SnapshotNeedsPush(snapshot *models.SandboxSnapshot) bool
SnapshotNeedsPush reports whether a snapshot row is a candidate for background push. Only local_only snapshots benefit — anything already in a remote registry is already distributable, and pushing it would just double-store the image.
func TemplateNeedsPush ¶ added in v0.4.1
TemplateNeedsPush reports whether a template row is a candidate for background AOCR push. Only `ready` rows qualify — `unhealthy` is the Phase 6 PR-A "snapshot was corrupt at load time" terminal state, and pushing a known-corrupt snapshot would just propagate the corruption to every peer. The reconciler enforces this defensively too.
func ValidateSnapshotRefArch ¶ added in v0.5.4
ValidateSnapshotRefArch rejects foreign-arch AOCR refs at resume/pull time. Defense-in-depth for homogeneous per-arch clusters (see plans/arm64-firecracker-hosts.md D5).
func WithReplicatedJSBundleOwner ¶ added in v0.7.18
WithReplicatedJSBundleOwner marks ctx as a cluster-replication write of a js-bundle, carrying the original owner so CreateJSBundle stores it under that owner (not the replicating peer's PAT scope) and skips re-replicating. The v1 handler sets this when a peer POSTs with models.HeaderJSBundleReplicated.
Types ¶
type ACMEBudget ¶ added in v0.3.1
type ACMEBudget struct {
// contains filtered or unexported fields
}
ACMEBudget is the daemon-wide brake on new-cert issuance for custom hostnames (plan §5b / OV5A). Let's Encrypt enforces a per-account `new-orders` limit (300 / 3h rolling). One misconfigured tenant adding 100 custom domains can drain that window for the whole cluster, so every TLSAsk hit that would trigger a new ACME order (status != ready) passes through Reserve; the hot path is the wildcard fast-fail and the negative cache, not this bucket.
Semantics:
- Sliding window over the LE rolling limit (capacity attempts per window). At capacity*fraction (default 0.8 — 240/300) we refuse, returning a Retry-After equal to the time the oldest in-window attempt ages out. The 20% headroom buys the in-flight renewals (cert-magic kicks them off ~30 days before expiry) survival room.
- Per-node bucket, NOT raft-synced. LE limits are per-account, not per-IP, and certmagic-s3's distributed lock already serialises simultaneous issuance for the same hostname across nodes; a node- local bucket is the right granularity for "this node is about to burn the account."
- Observation, not metering: a single Reserve call corresponds to one TLSAsk that COULD trigger issuance. Caddy may rate-limit further before actually opening an order, and certmagic dedupes simultaneous orders for the same host. Treat the bucket as an upper bound on issuance rate, not the exact count.
func NewACMEBudget ¶ added in v0.3.1
func NewACMEBudget(cfg ACMEBudgetConfig) *ACMEBudget
NewACMEBudget builds a budget. A nil result is safe: budget == nil implies "no daemon-wide brake" (Reserve degrades to always-allow), so the TLSAsk hot path stays single-branch when the feature is off.
func (*ACMEBudget) InWindow ¶ added in v0.3.1
func (b *ACMEBudget) InWindow() int
InWindow returns the current in-window attempt count. Test-only — production callers should not gate on this number; use Reserve.
func (*ACMEBudget) Reserve ¶ added in v0.3.1
func (b *ACMEBudget) Reserve(sandboxID, hostname string) (bool, time.Duration)
Reserve records an attempt and returns (true, 0) if the new attempt keeps the bucket below threshold, or (false, retryAfter) if it would cross. sandboxID is logged on denial so the operator can spot the burner. retryAfter is the time until the oldest in-window attempt ages out — the earliest moment another attempt could succeed.
A nil *ACMEBudget always allows: makes the call site one-liner.
func (*ACMEBudget) Threshold ¶ added in v0.3.1
func (b *ACMEBudget) Threshold() int
Threshold returns the denial line. Stable for the life of the budget.
type ACMEBudgetConfig ¶ added in v0.3.1
type ACMEBudgetConfig struct {
Capacity int
Window time.Duration
Fraction float64
Logger *slog.Logger
}
ACMEBudgetConfig captures the operator-facing knobs.
type AutoImportConfig ¶ added in v0.2.3
type AutoImportConfig struct {
// Enabled gates the whole feature. When false the post-pull path
// short-circuits and the auto-importer is never built.
Enabled bool
// HooksBaseURL is the root URL of the AOCR hooks service (no trailing
// slash, e.g. `https://aocr.aerol.ai`). The importer appends
// `/v1/internal/imports`.
HooksBaseURL string
// ClusterID identifies this sandboxd cluster to AOCR. Goes into the
// import request body and constrains the cluster PAT's scope.
ClusterID string
// ClusterPAT is the bearer token presented to the ImportAPI. Treat as
// secret; do not log. Sourced from a file path at startup, not env.
ClusterPAT string
// RetentionSuffix is appended to the target tag in the cluster
// namespace (e.g. `--idle-90d`). Empty means use the ImportAPI's
// server-side default (`--idle-90d`).
RetentionSuffix string
// RequestTimeout caps a single ImportAPI call. The mount-from-repo
// flow is normally sub-second (no byte transfer) but the timeout
// guards against an upstream that hangs on layer enumeration.
RequestTimeout time.Duration
}
AutoImportConfig wires the post-pull auto-import path to a specific AOCR hooks deployment. A zero value disables auto-import; the rest of the service runs exactly as before. main() is expected to validate that the PAT + cluster ID are set when Enabled=true.
See `plans/cluster-mirror-and-snapshot-distribution.md` F21 for the full motivation. Short version: the first time a private upstream image is pulled on a sandbox with `failover.policy: recreate`, sandboxd asks AOCR to re-mount the just-cached bytes under `cluster/<id>/_imported/<host>/<repo>`. Future recreates pull from the cluster namespace with a cluster PAT — surviving an upstream credential rotation that would otherwise break the F17 wrap-creds path.
func (AutoImportConfig) Validate ¶ added in v0.2.3
func (c AutoImportConfig) Validate() error
Validate enforces the consistency rules the rest of the service relies on. Returns nil for a disabled config so callers can validate unconditionally.
type AutoImportPendingStore ¶ added in v0.2.3
type AutoImportPendingStore interface {
ListAutoImportPendingIDs(ctx context.Context) ([]string, error)
Get(ctx context.Context, id string) (*models.Sandbox, error)
SetAutoImportPending(ctx context.Context, id string, pending bool) error
}
AutoImportPendingStore is the narrow store surface the reconciler needs. Pulled out as an interface so the reconciler can be tested without instantiating a full SQLite store — and so future store backends can satisfy it without growing the reconciler's dependency surface.
type AutoImportReconcileStats ¶ added in v0.2.3
AutoImportReconcileStats is what RunOnce reports back. Used by tests and by the metrics-collection wrapper in main.go.
type AutoImportReconciler ¶ added in v0.2.3
type AutoImportReconciler struct {
// contains filtered or unexported fields
}
AutoImportReconciler walks the rows the post-pull path flagged `auto_import_pending = true` and re-tries them. One ticker per node; fan-out inside a single tick is capped to keep a recovery storm from saturating the local Docker daemon or AOCR.
The reconciler does not own a goroutine — `RunOnce` is the unit of work, and a thin wrapper in main.go schedules it on a ticker. That keeps the type fully testable (table-driven, no time.Tick) and lets the operator trigger an immediate retry from a debug endpoint if they want.
func NewAutoImportReconciler ¶ added in v0.2.3
func NewAutoImportReconciler(importer *AutoImporter, store AutoImportPendingStore, specs AutoImportSpecResolver, logger *slog.Logger, maxInFlight int) *AutoImportReconciler
NewAutoImportReconciler builds the reconciler. Returns nil if the importer is nil (auto-import disabled) so callers can `if r == nil { return }` cheaply. maxInFlight clamps fan-out per tick; pass 0 for the safe default (4).
func (*AutoImportReconciler) RunOnce ¶ added in v0.2.3
func (r *AutoImportReconciler) RunOnce(ctx context.Context) (AutoImportReconcileStats, error)
RunOnce processes one sweep of the auto-import pending queue. Blocks until all per-sandbox attempts have returned (success, failure, or context cancel). The bounded semaphore caps in-flight HTTP calls; the AOCR side is happy with the load but the local Docker network stack is not infinitely parallel.
func (*AutoImportReconciler) SetSpecMutator ¶ added in v0.2.3
func (r *AutoImportReconciler) SetSpecMutator(m AutoImportSpecMutator)
SetSpecMutator installs the optional write-back hook. Calling again replaces the previous one; pass nil to disable. Separated from the constructor so existing call sites (and tests) keep working unchanged — the mutator is a strict upgrade, not a required dependency.
type AutoImportRequest ¶ added in v0.2.3
type AutoImportRequest struct {
UpstreamHost string
UpstreamRepo string
UpstreamTag string
UpstreamDigest string
}
AutoImportRequest is the per-sandbox import payload. Fields mirror what AOCR `ImportAPI` (hooks/src/controllers/ImportAPI.ts) expects on the wire; the JSON marshaller below pins the contract.
type AutoImportResult ¶ added in v0.2.3
AutoImportResult is what comes back. RegistryRef is the *cluster-side* pull reference the caller should write onto the sandbox spec (replacing the user's upstream ref for future recreates). AlreadyPresent=true means the destination tag already existed at the right digest — the importer treats that as success but the caller may want to suppress the spec mutation to avoid an unnecessary Raft write.
type AutoImportSpecMutator ¶ added in v0.2.3
type AutoImportSpecMutator interface {
MarkImported(ctx context.Context, sandboxID string, registryRef string)
}
AutoImportSpecMutator is the optional write-back hook. After a successful import, the reconciler calls MarkImported so the replicated spec carries the new cluster registry ref and `aocr_imported` distribution mode. Future failovers then pull from the cluster namespace with the cluster PAT, fully decoupled from the original upstream credential.
Implementations must be safe to call on a non-leader node: the leader- forwarding lives below this surface (cluster.UpsertSpec proposes through the Raft FSM regardless of caller node). Errors are absorbed inside the implementation — the reconciler always treats import success as a clean retryOutcome even if the mutator can't reach the leader, because the imported bytes are already in AOCR.
A nil mutator disables write-through cleanly; the reconciler logs the new ref and moves on. This is the standalone-mode default.
type AutoImportSpecResolver ¶ added in v0.2.3
type AutoImportSpecResolver interface {
GetSandboxSpec(sandboxID string) (*models.CreateSandboxRequest, bool)
}
AutoImportSpecResolver lets the reconciler look up the replicated CreateSandboxRequest that owns a given sandbox. The reconciler needs this because the spec carries the original upstream ref + the failover policy (the gate for whether import should happen at all), but the sandbox row only carries the runtime view. In standalone mode this is backed by an in-memory map; in cluster mode by the Raft FSM.
Returns nil, false when no replicated spec exists — the reconciler treats that as "drop the flag, nothing to retry" rather than as an error, since a sandbox without a spec cannot meaningfully be recreated elsewhere anyway.
type AutoImporter ¶ added in v0.2.3
type AutoImporter struct {
// contains filtered or unexported fields
}
AutoImporter is the leaf dependency that actually talks to AOCR. It holds no per-sandbox state; instantiate once at boot and reuse. Safe for concurrent use (it's just an http.Client wrapper).
func NewAutoImporter ¶ added in v0.2.3
func NewAutoImporter(cfg AutoImportConfig) (*AutoImporter, error)
NewAutoImporter builds an importer. Returns nil if cfg.Enabled is false so callers can do `if importer == nil { return }` on the post-pull path without an extra config check.
func (*AutoImporter) Endpoint ¶ added in v0.2.3
func (a *AutoImporter) Endpoint() string
Endpoint is exposed for log/debug use. Returns "" for a nil importer so callers can log it unconditionally.
func (*AutoImporter) Import ¶ added in v0.2.3
func (a *AutoImporter) Import(ctx context.Context, req AutoImportRequest) (AutoImportResult, error)
Import calls the AOCR ImportAPI once. Idempotent on (upstream_digest, cluster_id, target_tag): re-posting an already-imported sandbox returns AlreadyPresent=true without an error. Network/HTTP failures return a wrapped error so the caller can decide whether to log+flag or surface.
type CustomDomainCacheEvicter ¶ added in v0.3.1
type CustomDomainCacheEvicter interface {
EvictNegativeCache(hostname string)
}
CustomDomainCacheEvicter is the narrow surface the service needs from the ingressproxy TLS-ask handler so that AddCustomDomain can punch a hole in the negative cache immediately when a new hostname is attached. Kept as an interface (rather than importing pkg/api/ingressproxy directly) because ingressproxy already depends on internal/service — pulling the dependency the other way would create an import cycle. cmd/sandboxd wires the real handler in via AttachCustomDomainCacheEvicter once both packages are built.
type DNSResolver ¶ added in v0.4.1
DNSResolver is an interface to allow mocking of net.Resolver in tests.
type DefaultDNSResolver ¶ added in v0.4.1
type DefaultDNSResolver struct{}
DefaultDNSResolver is the default implementation using net.DefaultResolver.
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 PortEndpoint ¶ added in v0.2.4
type PortEndpoint struct {
URL string
// MaskRequestHost is the value the loopback ingress proxy must rewrite the
// upstream Host header to before re-dialing the container. Empty = keep the
// proxy's default (the upstream URL host). This is the serverless wake-path
// enforcement point for E2B network.maskRequestHost; the direct Caddy route
// enforces the same value via caddy.HTTPRouteOptions. Both read the one
// sandbox row, so they can't disagree.
MaskRequestHost string
}
PortEndpoint is the upstream the ingress proxy dials for a wake-aware exposed-port request. URL has the form http://{containerIP}:{port}.
type RouteKind ¶ added in v0.2.4
type RouteKind int
RouteKind is the protocol surface a callsite is choosing a shape for. HTTP and L4 (TCP/TLS) consult different bypass flags so each can be rolled out independently — Phase 1 ships HTTP behind SB_HTTP_WAKE_DIRECT_BYPASS_ENABLED; Phase 2 ships L4 behind SB_L4_WAKE_DIRECT_BYPASS_ENABLED. Within each kind the decision tree is identical (Status + WakeArmed + ContainerIP) — only the "is bypass enabled?" predicate differs.
type RouteShape ¶ added in v0.2.4
type RouteShape int
RouteShape is the published Caddy shape for a (sandbox, exposed-port). One shape is live at a time per exposure; transitions are driven by status changes (Start/Stop/Die/Reconcile), never by per-request work.
See plans/warm-direct-route-bypass.md D7/D8 — this enum + chooseRouteShape are the single source of truth so HTTP, TCP, TLS, reconcile, and event callsites cannot disagree about what shape should be live for a given sandbox row.
const ( // RouteShapeNone means no route should be published. Destroyed // sandboxes and disarmed-stopped serverless sandboxes fall through // to Caddy's fallback (404). RouteShapeNone RouteShape = iota // RouteShapeDirect publishes the upstream as ContainerIP:port. // Used for non-serverless sandboxes always, and for serverless // sandboxes only while warm (HTTPWakeDirectBypassEnabled=true). RouteShapeDirect // RouteShapeWake publishes the upstream as the sandboxd loopback // ingress proxy (or per-exposure unix socket for TLS). Used for // serverless sandboxes while Stopped+armed, and for serverless // sandboxes always when HTTPWakeDirectBypassEnabled=false. RouteShapeWake )
func (RouteShape) String ¶ added in v0.2.4
func (r RouteShape) String() string
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) AddCustomDomain ¶ added in v0.3.1
func (s *Service) AddCustomDomain(ctx context.Context, sandboxID, hostname string, targetPort int) error
AddCustomDomain attaches a new public hostname to an existing sandbox. The caller is responsible for sandbox-scoped authorization (the API layer); this helper validates the hostname against the deployment's base domain, enforces the IRON RULE (no coexistence with protocol=tcp/tls exposures), persists the row, re-PATCHes the Caddy route to include the new hostname, and rolls back the store insert on Caddy failure. On success, the negative cache entry for the hostname is punched so the next ACME ask hits the resolver instead of being refused for the cached 60s.
targetPort selects the in-container port the hostname routes to. Zero is the sentinel meaning "use the toolbox port" (the pre-target-port default, preserving existing behavior). Set once at attach time; changing the port requires detach + re-add so in-flight traffic can't silently redirect.
Returns:
- ErrCustomDomainNotSupported (412) when the deployment doesn't support custom domains.
- ErrCustomDomainInvalid (400) when the hostname fails validation.
- ErrCustomDomainInvalidTargetPort (400) when targetPort is outside [0, 65535].
- ErrCustomDomainProtocolConflict (409) when the sandbox already exposes tcp/tls ports.
- ErrCustomDomainPerSandboxCap (409) when the sandbox already holds the cap.
- ErrCustomDomainPortMismatch (409) when re-adding an existing hostname with a different port.
- store.ErrCustomDomainConflict (409) when the hostname is owned by a different sandbox.
- store.ErrNotFound (404) when the sandbox does not exist.
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) AttachCustomDomainCacheEvicter ¶ added in v0.3.1
func (s *Service) AttachCustomDomainCacheEvicter(e CustomDomainCacheEvicter)
AttachCustomDomainCacheEvicter is the wire-up hook called from cmd/sandboxd once the TLSAskHandler is built. Passing nil is allowed (and the default) — negative-cache eviction is best-effort; the cache entry expires on its own TTL and the worst case is a 60s delay before the first ACME ask sees the freshly-added hostname.
func (*Service) AttachSnapshotPusher ¶ added in v0.2.4
func (s *Service) AttachSnapshotPusher(pusher *SnapshotPusher, reconciler *SnapshotPushReconciler)
AttachSnapshotPusher wires in the optional AOCR snapshot-push pipeline. pusher must be non-nil to activate the feature; a nil pusher is a no-op and leaves the service in legacy local-only snapshot mode. reconciler may be nil — when nil, kick-after-create is disabled (useful in tests that assert on the initial persisted state before any reconcile runs). Called once from main() after cfg.SnapshotPushEnabled validation.
func (*Service) AttachTemplateArtifactPuller ¶ added in v0.4.1
func (s *Service) AttachTemplateArtifactPuller(p *TemplateArtifactPuller)
AttachTemplateArtifactPuller wires in the consumer-side puller. nil puller leaves the feature off and EnsureTemplateLocal becomes a fast no-op — the right behaviour for single-node deployments and for nodes where SnapshotPushEnabled=false (no AOCR configured). Called once from main() after the docker client is up.
func (*Service) AttachTemplateArtifactPusher ¶ added in v0.4.1
func (s *Service) AttachTemplateArtifactPusher(pusher *TemplateArtifactPusher, reconciler *TemplateArtifactPushReconciler)
AttachTemplateArtifactPusher wires in the optional AOCR template push pipeline (Phase 6 PR 6-B.1). pusher must be non-nil to activate the feature; a nil pusher leaves new template rows in push_state='active' forever (the reconciler only picks 'pending'/'error') — backward- compatible with single-node deployments and with cfg.EnableCluster=false. reconciler may be nil for tests that assert on initial persisted state. Called once from main() after cfg.SnapshotPushEnabled validation.
func (*Service) AttachWasmCheckpointPusher ¶ added in v0.5.3
func (s *Service) AttachWasmCheckpointPusher(pusher WasmCheckpointStore)
AttachWasmCheckpointPusher wires AOCR push for durable WASM checkpoints. Called from main when SnapshotPushEnabled is true.
func (*Service) Capacity ¶
Capacity returns the admitter's current snapshot. Returns the zero value when no admitter is configured (e.g. in tests).
Phase 6 PR-D: overlays LocalTemplateIDs from a 5s-TTL cache so peers fetching /v1/capacity see which Firecracker templates this node can already serve without paying a remote AOCR pull. The cache shields SQLite from the gossip cadence (single-writer; MaxOpenConns=1).
func (*Service) ClaimIdempotentRequest ¶ added in v0.1.7
func (*Service) ClearClusterForTest ¶ added in v0.5.2
func (s *Service) ClearClusterForTest()
ClearClusterForTest drops the attached cluster client so API handlers can exercise their "cluster disabled" branches. Production always has at least cluster.Noop from New().
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) CreateJSBundle ¶ added in v0.7.15
func (s *Service) CreateJSBundle(ctx context.Context, req models.CreateJSBundleRequest) (*models.JSBundle, error)
CreateJSBundle stores a bundle under the caller's identity and returns its catalogue view. Idempotent: re-uploading identical bytes yields the same digest with no error; re-using a name repoints it. The digest is the stable reference a create request passes as module_ref ("sha256:<digest>").
func (*Service) CreatePlatformVolume ¶ added in v0.5.4
CreatePlatformVolume creates (or, idempotently, returns) the named volume for the calling tenant. Duplicate creates converge on the existing row rather than erroring, so the operation is safe under retry and concurrent duplicate calls (repo idempotency rule).
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) CreateTemplate ¶ added in v0.4.1
func (s *Service) CreateTemplate(ctx context.Context, req models.CreateTemplateRequest) (*models.Template, error)
CreateTemplate accepts a build request, persists a PENDING row, and kicks off the background build. The handler renders the returned row as 202 — callers poll GET /v1/templates/{id} to observe the READY/FAILED transition. Build errors do NOT bubble back through the API; they land in the row's last_error so the operator sees them on poll. This matches the snapshot-push reconciler's async shape.
func (*Service) CreateWasmModule ¶ added in v0.5.3
func (s *Service) CreateWasmModule(ctx context.Context, req models.CreateWasmModuleRequest) (*models.WasmModule, error)
CreateWasmModule resolves module_ref on this host and upserts the catalogue. Idempotent when the caller supplies an explicit id that already points at the same module_ref; conflicting ids return ErrWasmModuleIDConflict.
func (*Service) CustomDomainDNS ¶ added in v0.3.1
func (s *Service) CustomDomainDNS(ctx context.Context, sandboxID string) (models.CustomDomainDNSRecords, error)
CustomDomainDNS expands a sandbox's attached custom domains into the ready-to-paste DNS record set users must create at their provider. Returns ErrCustomDomainNotSupported (412) when the deployment can't accept custom domains at all — symmetric with ListCustomDomains so callers handle both endpoints the same way. Empty Records is returned (with the resolved Target attached) when the sandbox exists but has no custom domains; that lets the SDK still surface the cluster target without separately calling IngressDNSTarget.
func (*Service) DeleteByOwner ¶ added in v0.5.1
DeleteByOwner destroys every sandbox owned by ownerRef. Terminal and idempotent: a sandbox already gone (ErrNotFound) counts as success, so a re-tick over a partially-deleted set converges. Errors on other sandboxes are collected and returned so the loop retries the remainder.
func (*Service) DeleteClusterSecrets ¶ added in v0.2.1
func (*Service) DeleteIdempotentRequest ¶ added in v0.1.7
func (*Service) DeleteJSBundle ¶ added in v0.7.15
DeleteJSBundle removes a bundle the caller owns, refusing when a live sandbox still pins its digest (mirrors DeleteWasmModule — a referenced artifact is not garbage).
func (*Service) DeletePlatformVolume ¶ added in v0.5.4
DeletePlatformVolume removes a volume, but only when no live sandbox still has it attached — otherwise the backing data would vanish out from under a running workload. Returns models.ErrPlatformVolumeInUse (→ 409) when attachers remain, models.ErrNotFound when the id is unknown.
The store writes a pending cleanup ledger row before removing the metadata row, so backend bytes retain durable reconciliation coordinates even if a request-path cleanup worker or operator lifecycle policy is delayed.
func (*Service) DeleteSnapshot ¶ added in v0.1.7
func (*Service) DeleteSnapshotAlias ¶ added in v0.1.7
func (*Service) DeleteTemplate ¶ added in v0.4.1
DeleteTemplate refuses when an active sandbox still references the template — yanking the rootfs out from under a running Firecracker guest would surface as a delayed I/O error inside the guest, hours after the operator's action. The 409 forces the operator to destroy the sandbox first. Best-effort artifact cleanup runs before the row delete: a half-cleaned dir on disk is fine (GC catches it), a missing row with an orphan dir is the painful case (no one will ever clean it). Pending rows are also rejected — a delete that races the build goroutine would leave the goroutine writing to a directory the operator believed was gone.
func (*Service) DeleteWasmModule ¶ added in v0.5.3
DeleteWasmModule removes a catalogue row when no sandbox references it.
func (*Service) DestroySandbox ¶
func (*Service) DrainWasmSandboxes ¶ added in v0.5.3
DrainWasmSandboxes checkpoints passivatable/durable live WASM sandboxes during graceful shutdown (plans/wasm-runtime.md §4.3).
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) EnsureSandboxAwakeForHTTP ¶ added in v0.2.4
func (s *Service) EnsureSandboxAwakeForHTTP(ctx context.Context, id string) (*models.Sandbox, error)
EnsureSandboxAwakeForHTTP is the single chokepoint the control-plane HTTP proxies (v1 toolbox, daytona toolbox, e2b runtime) call before resolving the toolbox endpoint. It returns the current sandbox row so the caller can route to ContainerIP without re-fetching.
Behavior:
- sandbox started → fast-path return (no lock, no metric latency observation; only a requests_total tick).
- sandbox stopped + (gate off OR Lifecycle.Serverless=false OR WakeArmed=false) → ErrSandboxManuallyStopped. The proxy maps this to 409 so the SDK can explicitly call StartSandbox.
- sandbox stopped + eligible to wake → take the per-sandbox wake lock, recheck under the lock (a concurrent flight may have finished), enforce the circuit breaker, then call StartSandbox with a 15s budget. On admission failure or start error the breaker counter advances; 5 failures inside 60s trip it for 60s. Success resets the counter.
Same single-flight pattern as EnsureLayer4Ready, but per-sandbox: the wave of HTTP requests waking the same sandbox collapses to one StartSandbox; waves to different sandboxes proceed concurrently.
func (*Service) EnsureTemplateLocal ¶ added in v0.4.1
EnsureTemplateLocal guarantees that <templatesDir>/<id>/ exists with rootfs.ext4 + snapshot.{memory,state} on this node, fetching from AOCR via the attached puller when missing. Idempotent: callers that hit the latch fast-path pay one atomic load.
Mirrors EnsureLayer4Ready exactly:
- atomic.Bool per-template latch for the lock-free steady-state path
- sync.Mutex per-template single-flight collapses concurrent first callers into one pull
- failure leaves the latch unset so the next call retries
Returns nil immediately when:
- puller is not attached (single-node mode, or push/pull disabled)
- the template has no registry_ref (never pushed; this node must be the producer and the files are presumed local already)
- the files are already on disk (cold-start on the producer node)
func (*Service) EvacuateLocalWasmSandboxesForDrain ¶ added in v0.5.3
EvacuateLocalWasmSandboxesForDrain checkpoints and migrates passivatable/durable WASM sandboxes off this node during cluster drain (§4.4).
func (*Service) ExportWasmMigration ¶ added in v0.5.3
func (s *Service) ExportWasmMigration(ctx context.Context, sandboxID string, w io.Writer) (cloneGen string, err error)
ExportWasmMigration streams a §4.8.1 mem.snap tarball for sandboxID.
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) FireWebhook ¶ added in v0.5.1
FireWebhook records that an owner crossed a notify-level directive. The webhook URL and secret live entirely in the managed contract (never in the open-source build), so the host's part of the contract is just to surface the crossing in its audit log; the managed control plane owns any outbound notification. Called once per transition by the enforcement loop, so this is already idempotent per crossing.
func (*Service) ForceReconcileHTTPWakeShape ¶ added in v0.2.4
ForceReconcileHTTPWakeShape republishes the HTTP route for every serverless sandbox's HTTP exposures using the current HTTPWakeDirectBypassEnabled value. Called exactly once at daemon startup when the rollback marker shows the previous run had bypass=true and the current run has bypass=false: without this, every serverless sandbox that was last written under bypass=true keeps its direct route pointing straight at the container IP, bypassing the wake-aware ingress proxy entirely — i.e. the rollback knob would not actually roll back. Conversely, on a fresh enable (false→true) routes will be rewritten lazily on the next Start/Stop, so no force-pass is needed in that direction (D5 of plans/warm-direct-route-bypass.md).
Idempotent: chooseRouteShape is a pure function of (cfg, sandbox), so repeated calls converge to the same route set. Best-effort per sandbox — one failed Caddy write logs and the loop continues so a single broken row does not block the rest from being rolled back.
func (*Service) GCUnreferencedJSBundles ¶ added in v0.7.15
GCUnreferencedJSBundles is the single sweep used by the loop, operators, and tests.
func (*Service) GetCompatState ¶ added in v0.1.7
func (*Service) GetIdempotentRequest ¶ added in v0.1.7
func (*Service) GetJSBundle ¶ added in v0.7.15
GetJSBundle returns one bundle by digest, refusing digests the caller does not own (a 404, not a 403, so a user token cannot probe others' digests).
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) GetPlatformVolume ¶ added in v0.5.4
GetPlatformVolume returns the tenant's volume by id, or models.ErrNotFound.
func (*Service) GetPlatformVolumeByName ¶ added in v0.5.4
GetPlatformVolumeByName returns the tenant's volume by name, or models.ErrNotFound. The name is sanitized so lookups match how it was stored.
func (*Service) GetSandbox ¶
func (*Service) GetSnapshot ¶ added in v0.1.7
func (*Service) GetSnapshotAlias ¶ added in v0.1.7
func (*Service) GetTemplate ¶ added in v0.4.1
GetTemplate is the read path behind GET /v1/templates/{id}. Returns the store row unchanged — status is whatever the build goroutine last wrote, so a freshly-created template reads as PENDING until the goroutine flips it.
func (*Service) GetWasmModule ¶ added in v0.5.3
func (*Service) ImportWasmMigration ¶ added in v0.5.3
func (s *Service) ImportWasmMigration(ctx context.Context, sandboxID, expectedCloneGen string, r io.Reader) (err error)
ImportWasmMigration accepts a streamed mem.snap tarball on the receiving node, promotes the sandbox row to passivated, and reassigns cluster ownership to self.
func (*Service) IngressDNSTarget ¶ added in v0.3.1
func (s *Service) IngressDNSTarget() models.IngressTarget
IngressDNSTarget returns the cluster's public ingress address as the SDK would render it to a user (CNAME target hostname, raw A/AAAA IP list, or both). Delegates to cluster.Client so single-node, cluster, and agent deployments all answer through the same aggregator. This call does NOT gate on EnableCustomDomains: knowing the target is useful BEFORE attaching any domain (e.g. an SDK consumer rendering "point your DNS here first"), and the operator information returned (a hostname or IP they already chose to advertise on memberlist) is the same data anyone running `dig <sandbox-url>` could discover.
func (*Service) IsSandboxStarted ¶ added in v0.2.4
IsSandboxStarted is the preflight check the wake-aware ingress proxy uses to skip request-body buffering for warm sandboxes. It returns (true, nil) only when the sandbox row exists and its status is Started; any other status (Stopped, Destroyed, in-flight create) returns (false, nil). store.ErrNotFound is returned unwrapped so the proxy can map it to 404 without a second store hit.
Hot path: a short-TTL cache (warmCache) lets repeated warm requests to the same sandbox skip the SQLite read. The cache holds positives only ("seen Started in the last warmCacheTTL"); a miss always falls through to s.store.Get so cold/stopped/destroyed sandboxes never short-circuit. Lifecycle transitions (StartSandbox success, every stop path, every destroy path) explicitly invalidate the entry.
func (*Service) ListCompatState ¶ added in v0.1.7
func (*Service) ListCustomDomains ¶ added in v0.3.1
func (s *Service) ListCustomDomains(ctx context.Context, sandboxID string) ([]models.CustomDomain, error)
ListCustomDomains returns the canonical rows for one sandbox. Empty slice (nil) when none are attached. Same deployment-capability gate as Add/Remove: disabled-feature or IP-mode returns ErrCustomDomainNotSupported (412) rather than an empty list, so callers can distinguish "this sandbox has no domains" from "this cluster does not do custom domains".
func (*Service) ListJSBundles ¶ added in v0.7.15
ListJSBundles returns the caller's stored bundles.
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) ListPlatformVolumes ¶ added in v0.5.4
ListPlatformVolumes returns all of the tenant's volumes.
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) ListTemplates ¶ added in v0.4.1
ListTemplates is the read path behind GET /v1/templates. Returns rows in newest-first order matching the snapshot list shape.
func (*Service) ListWasmModules ¶ added in v0.5.3
func (*Service) LocalReadyTemplateIDs ¶ added in v0.4.1
LocalReadyTemplateIDs returns only the template IDs from LocalReadyTemplateInventory. Callers that need to distinguish authoritative empty inventory from legacy/unknown should use the richer method.
func (*Service) LocalReadyTemplateInventory ¶ added in v0.4.1
LocalReadyTemplateInventory returns the IDs of Firecracker templates whose artifacts are usable on this host plus whether that inventory is authoritative. Cached for 5s — peers gossip /v1/capacity at this cadence and a per-tick SQLite hit would starve the create path's writes (single-writer DB). On error the cache is left untouched and the previous value is returned, matching the "stale is better than wrong" contract the rest of the heartbeat path uses.
func (*Service) LocalReadyWasmModuleInventory ¶ added in v0.5.3
LocalReadyWasmModuleInventory returns module_ref values present in the local wasm_modules catalogue plus whether that inventory is authoritative.
func (*Service) MarkImported ¶ added in v0.2.3
MarkImported is the spec write-back invoked by the AutoImportReconciler after a successful import. It flips the replicated spec's distribution mode to `aocr_imported` and points ImageRegistryRef at the new cluster- side ref so any future failover/recreate pulls from the cluster namespace (cluster PAT) instead of the original upstream.
Best-effort by contract: a missing spec, a non-leader UpsertSpec rejection, or a Raft commit error all log+return without surfacing the failure. The bytes are already in AOCR; the original ref still resolves through the mirror; the next mutation will refresh the FSM. This is the AutoImportSpecMutator implementation referenced by the reconciler.
func (*Service) MarkSnapshotCorrupt ¶ added in v0.4.1
MarkSnapshotCorrupt transitions a template from ready to unhealthy and, on the first such transition for a given corruption event, kicks an async snapshot rebuild. Subsequent concurrent calls for the same template return nil with no rebuild kicked — the idempotent UPDATE ... WHERE status='ready' is the gating primitive.
reason is logged + persisted to the snapshot_error column so the operator-facing GET /v1/templates/{id} payload carries the human-readable detail.
The method swallows store/rebuild errors after logging — the caller (driver.Create's failure path / warm-spawn notifier) is already returning its own user-facing error. The notification is a best-effort hint to the service layer; failing to honour it leaves the system no worse than today (next corruption observation retries).
func (*Service) MigrateWasmSandbox ¶ added in v0.5.3
func (s *Service) MigrateWasmSandbox(ctx context.Context, sandboxID, destDir string) (string, string, error)
MigrateWasmSandbox packages a boundary checkpoint for handoff to a sibling node.
func (*Service) MigrateWasmSandboxToNode ¶ added in v0.5.3
func (s *Service) MigrateWasmSandboxToNode(ctx context.Context, sandboxID, targetNodeID string) (resp *WasmMigrateResponse, err error)
MigrateWasmSandboxToNode orchestrates export on the current owner and import on targetNodeID (plans/wasm-runtime.md §4.4).
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. The handle (Ref/Version) is the only carrier — placements never embed sealed bytes.
func (*Service) PushWasmModule ¶ added in v0.5.3
func (s *Service) PushWasmModule(ctx context.Context, name, tag, username, token string, data io.Reader) (*models.PushWasmModuleResponse, error)
PushWasmModule is a STATELESS proxy: it validates a BYO .wasm upload (core-wasip1, size) and forwards it to the registry under the caller's own per-tenant credentials, returning the oci:// ref for a later create. The daemon never stores or serves the bytes — AOCR is the registry, this is just orchestration convenience for clients without oras/docker.
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) RebuildTemplateSnapshot ¶ added in v0.4.1
RebuildTemplateSnapshot reruns the snapshot phase against an existing rootfs. Synchronous (the caller — typically kickSnapshotRebuild — provides its own goroutine + timeout). Exported because future phases (snapshot rotation in PR 6-D, operator-triggered repair via an API endpoint) will call it directly.
Precondition: template must exist and be in status=unhealthy. (ready_no_snapshot rebuilds need a different entry point — they failed during build and may not have a valid rootfs path; that's PR 6-D territory.)
State transitions on success: unhealthy → snapshotting → ready. On snapshotter failure: unhealthy → snapshotting → ready_no_snapshot. The intermediate snapshotting state is intentional — it matches the kickTemplateBuild semantics so operators see a uniform state machine on the dashboard.
func (*Service) ReconcileClusterIngress ¶ added in v0.2.1
func (*Service) ReconstructWakeArmedIfNeeded ¶ added in v0.2.4
ReconstructWakeArmedIfNeeded is the D1 reconstruction rule from plans/serverless-sandbox-http-wake.md, extended to also self-heal Caddy state. A serverless sandbox can land in `stopped + wake_armed=false` on a node that does not own the arming history — typically after a cluster owner change (the old owner's SQLite wake_armed bit doesn't migrate) or after a daemon restart that lost the in-memory expected-stop bookkeeping and saw a crash event arrive before the row got an armed value. In those cases the conservative default is the same as the involuntary-stop policy: arm wake so the next HTTP request resurrects the sandbox.
It ALSO re-upserts wake routes when wake_armed=true is already set. Caddy's admin-API routes are dynamic and do not survive a Caddy restart (only certs persist via S3 storage), so the daemon must treat wake_armed=true as a goal state to reassert against Caddy on every reconcile pass, not as a witness that routes still exist. Without this, a Caddy restart between auto-stop and the next wake request leaves the wildcard 404 fallback serving requests forever even though the DB looks correct.
Reconstruction is a no-op unless ALL of:
- cfg.EnableServerless is on
- sandbox is Lifecycle.Serverless
- sandbox is in Stopped status
- the sandbox has at least one exposed port that can receive an inbound wake request or connection
Caddy-first per D5: install wake routes for every exposure before flipping the store bit. If every wake route install fails we leave wake_armed unchanged (false stays false, true stays true) so route state and the bit remain in sync — the next reconcile pass will retry. The store write is skipped when wake_armed is already true so steady-state reconcile passes do not churn the row.
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) RekickUnhealthyTemplatesAtStart ¶ added in v0.4.1
RekickUnhealthyTemplatesAtStart sweeps every firecracker_templates row in status='unhealthy' and re-kicks the snapshot rebuild for each.
Closes the crash-mid-rebuild gap: MarkSnapshotCorrupt flips the row then spawns an async kickSnapshotRebuild goroutine. If sandboxd dies between the row flip and the rebuild completing, the row is stuck unhealthy on restart and no caller re-kicks it — every subsequent create against that template fails with a confusing "template unhealthy" error until an operator intervenes.
Designed to be called once at daemon start, after the snapshotter + CID-allocator wiring has landed (without those, RebuildTemplateSnapshot would refuse with a clear error and the rebuild would never happen). Returns nil and only logs on store errors — a daemon that can't list templates should still start, since the rest of the service may be healthy and the scanner re-runs on the next process restart.
Idempotency: safe under repeated daemon starts. The CAS in MarkTemplateUnhealthy is not re-entered (the row is already unhealthy), and RebuildTemplateSnapshot re-checks the row's state before doing any work, so a row that another caller already recovered between this list and the rebuild kick short-circuits cleanly.
func (*Service) RemoveCustomDomain ¶ added in v0.3.1
RemoveCustomDomain detaches a hostname. Order is store-first then Caddy. If the store delete succeeds but the Caddy patch fails, the hostname is gone from the store while Caddy may still serve it until the next reconcile pass converges routing. Cross-sandbox removal returns store.ErrNotFound (the store layer scopes the DELETE to (sandbox, hostname)), so a tenant cannot rip a domain out of someone else's route by guessing the hostname.
func (*Service) RepairLayer4Ready ¶ added in v0.5.5
func (*Service) ReplayClusterOwnership ¶ added in v0.2.4
ReplayClusterOwnership pushes local sandbox truth into the cluster placement FSM. It is the local-store -> global-index repair path used at boot and by the periodic reconciler after Docker confirms a container still exists.
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) RequestTemplateRebuild ¶ added in v0.4.1
func (s *Service) RequestTemplateRebuild(ctx context.Context, templateID string) (*models.Template, error)
RequestTemplateRebuild is the operator-triggered entry point for re-running the snapshot phase of a template. It is the service-layer half of POST /v1/templates/{id}/rebuild.
State semantics:
- ready: delegate to MarkSnapshotCorrupt(reason="operator-requested"). The store-side CAS (UPDATE...WHERE status='ready') makes the transition idempotent under concurrent operator requests — N parallel callers collapse to one ready→unhealthy transition and one rebuild kick. The N-1 callers that lose the race see the post- transition row on the re-read below and get a successful 202.
- unhealthy: a rebuild is already in flight (or will be re-kicked by RekickUnhealthyTemplatesAtStart on next daemon restart). Returning the row as-is is the simplest UX — operator polls GET /v1/templates/{id} for the transition back to ready.
- anything else: ErrTemplateNotRebuildable. See the sentinel's docstring for the reasoning per state.
The 202-with-current-template response shape mirrors the rest of the async template lifecycle (POST /v1/templates also returns 202 with a PENDING row), so SDK callers can reuse their existing "poll until status=ready" code path.
func (*Service) ResizeSandbox ¶
func (*Service) ResolvePlatformVolumesForReplication ¶ added in v0.5.4
func (s *Service) ResolvePlatformVolumesForReplication(ctx context.Context, req *models.CreateSandboxRequest) error
ResolvePlatformVolumesForReplication rewrites platform-volume references into concrete MountSpecs for the cluster-replicated create spec. That preserves the already-resolved tenant prefix across failover/recreate, where there is no original user auth context to derive the tenant from. It intentionally does no quota or volume-row writes; createSandbox already did those before the sandbox was admitted.
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) RestoreByOwner ¶ added in v0.5.1
RestoreByOwner restarts the owner's fleet-suspended sandboxes and clears the marker. Only sandboxes carrying the marker are touched — a user-initiated stop during suspension is respected. Start happens before the marker is cleared so a failed start retries next tick (marker preserved); an already-running marked sandbox just has its marker cleared. Idempotent.
func (*Service) RoundTripToolbox ¶ added in v0.5.3
func (s *Service) RoundTripToolbox(ctx context.Context, sandboxID, method, path string, query url.Values, body io.Reader, headers http.Header) (*http.Response, error)
RoundTripToolbox performs an HTTP round trip to the sandbox toolbox.
func (*Service) RunJSBundleGCLoop ¶ added in v0.7.15
RunJSBundleGCLoop periodically deletes content-addressed bundles that no live isolate sandbox pins and that no catalogue name points at (plans/isolate-runtime.md Phase 2 leftover). Interval <= 0 disables.
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) ServeToolboxReverseProxy ¶ added in v0.5.3
func (s *Service) ServeToolboxReverseProxy(ctx context.Context, sandboxID string, w http.ResponseWriter, r *http.Request, path string) error
ServeToolboxReverseProxy forwards a toolbox request to the sandbox toolbox. WASM sandboxes are served in-process via the driver's ToolboxHost.
func (*Service) SetContainerdRuntime ¶ added in v0.7.1
SetContainerdRuntime registers the containerd engine driver. Called from pkg/daemon when SB_CONTAINER_ENGINE=containerd.
func (*Service) SetDNSResolver ¶ added in v0.4.1
func (s *Service) SetDNSResolver(resolver DNSResolver)
SetDNSResolver sets the DNS resolver for the service (used for testing from other packages).
func (*Service) SetDockerAuxClient ¶ added in v0.7.1
SetDockerAuxClient wires docker-only auxiliary APIs (built-image GC, live stats) that are not part of the EventsSource seam.
func (*Service) SetEventsSource ¶ added in v0.7.1
func (s *Service) SetEventsSource(src docker.EventsSource)
SetEventsSource wires the daemon event monitor + netstats PID lookup seam.
func (*Service) SetFirecrackerRuntime ¶ added in v0.4.1
SetFirecrackerRuntime registers the second runtime driver. Called by main.go after construction, only when cfg.EnableFirecracker is true. Passing nil clears the registration (used by tests). Once set, the CreateSandbox dispatch routes runtime="firecracker" requests through this driver instead of returning a "not enabled" error.
Why a setter rather than a New() parameter: the existing service.New signature is consumed by ~20 test files, and growing it to carry a nil-able second runtime would force a fan-out edit across every one. A setter keeps the constructor stable and confines the wire-up to main.go where the daemon-config flag actually lives.
func (*Service) SetFleetAdmitter ¶ added in v0.5.1
func (s *Service) SetFleetAdmitter(a controlplane.Admitter)
SetFleetAdmitter installs the managed create-gate. The managed daemon calls this once at boot from the control-plane provider; the open-source build never does, so fleetAdmitter stays nil and createSandbox skips the gate.
func (*Service) SetIsolateBundleStore ¶ added in v0.7.15
SetIsolateBundleStore registers the content-addressed bundle store. Called from pkg/daemon when cfg.EnableIsolate is true (the same store instance the isolate driver's resolver reads).
func (*Service) SetIsolateRuntime ¶ added in v0.7.15
SetIsolateRuntime registers the V8-isolate driver. Called from pkg/daemon when cfg.EnableIsolate is true.
func (*Service) SetJSBundleReplicator ¶ added in v0.7.18
func (s *Service) SetJSBundleReplicator(fn func(ctx context.Context, owner string, req models.CreateJSBundleRequest) error)
SetJSBundleReplicator wires the cluster fan-out for uploaded bundles. Called by pkg/daemon in cluster+isolate mode; nil (the default) means single-node — no replication.
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) SetTemplateBuilder ¶ added in v0.4.1
func (s *Service) SetTemplateBuilder(b TemplateBuilder)
SetTemplateBuilder is the bootstrap-time wiring hook called once from main.go after the daemon has constructed pkg/oci.Builder. Idempotent: passing nil disables template create (the handler returns 503) without tearing down existing template rows.
func (*Service) SetTemplateCIDAllocator ¶ added in v0.4.1
func (s *Service) SetTemplateCIDAllocator(a TemplateCIDAllocator)
SetTemplateCIDAllocator wires the per-template CID reservation seam. Nil disables the snapshot phase (same effect as a nil snapshotter): without a reserved CID the snapshot would clash with the next sandbox slot allocation. The setter is separate so main.go can wire the two independently — handy when one of them is being swapped out.
func (*Service) SetTemplateSnapshotter ¶ added in v0.4.1
func (s *Service) SetTemplateSnapshotter(snap TemplateSnapshotter)
SetTemplateSnapshotter wires the Phase 3 snapshot-capture seam. Nil disables the second build phase — new templates still get a rootfs but land in status=ready_no_snapshot, and CreateSandbox cold-boots from them. Useful for hosts where the snapshotter is misbehaving.
func (*Service) SetUsageReporter ¶ added in v0.5.1
func (s *Service) SetUsageReporter(r controlplane.Reporter)
SetUsageReporter installs the control-plane usage reporter. The managed daemon calls this once at boot; the open-source build never does, so usageReporter stays nil and every emit path is a no-op that allocates nothing.
func (*Service) SetVolumeReclaimer ¶ added in v0.5.4
func (s *Service) SetVolumeReclaimer(r VolumeReclaimer)
SetVolumeReclaimer installs the backend reclaimer. Called once during daemon wiring before the worker starts; nil disables byte reclaim.
func (*Service) SetWasmModuleResolver ¶ added in v0.5.3
func (s *Service) SetWasmModuleResolver(r WasmModuleResolver)
SetWasmModuleResolver wires the pkg/wasmmod.Resolver used by CreateWasmModule and lazy create paths.
func (*Service) SetWasmRuntime ¶ added in v0.5.3
SetWasmRuntime registers the WASM driver. Called from pkg/daemon when cfg.EnableWasm is true.
func (*Service) SetWasmWarmPool ¶ added in v0.5.5
func (s *Service) SetWasmWarmPool(p WasmWarmPoolNotifier)
SetWasmWarmPool wires the warm pool into module registration.
func (*Service) SnapshotPushReconciler ¶ added in v0.2.4
func (s *Service) SnapshotPushReconciler() *SnapshotPushReconciler
SnapshotPushReconciler exposes the reconciler so main.go can drive it from a ticker. Returns nil when snapshot push is disabled — the ticker wrapper should no-op cleanly in that case.
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) StartCaddyCoalescer ¶ added in v0.2.4
StartCaddyCoalescer starts the periodic-drain goroutine. Called once from cmd/sandboxd/main.go after svc.New on worker nodes. Flush-only callers (installHTTPPortRoute today) don't strictly need this — Flush drives its own drain — but the ticker is the safety net for any future Enqueue (fire-and-forget) callsites and for ops that get stranded when a Flush caller's ctx cancels mid-drain.
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) StartL4WakeProxy ¶ added in v0.2.4
StartL4WakeProxy starts the loopback TCP wake listener used by raw-TCP serverless routes. TLS-SNI wake uses per-exposure Unix sockets installed by ensureTLSWakeListener, but those listeners are also closed from this context.
func (*Service) StartLifecycleSweep ¶
func (*Service) StartLiveUsageSampler ¶ added in v0.5.1
StartLiveUsageSampler launches the opt-in live CPU/memory sampler if, and only if, all of these hold: an interval is configured (> 0), a usage reporter is wired (managed build), and a Docker client is available to query. Under the open-source build (no reporter) or the default config (interval 0) it returns immediately and starts no goroutine — so this is genuinely off unless an operator opts in on a managed node.
The sampler is deliberately additive to the reserved axes: reserved gives the provisioned envelope from the row (no I/O), live gives measured consumption from one cheap stats read per running Docker sandbox per tick. Firecracker sandboxes are skipped (the Docker stats endpoint doesn't know them); their reserved axes still flow.
func (*Service) StartPendingImageGC ¶ added in v0.3.1
StartPendingImageGC launches the periodic janitor that removes images scheduled by destroy paths (DestroySandbox, reconcile destroyed-branch, handleDestroyEvent). It piggybacks on ImageBuildGCEnabled / Interval / TTL: same enable switch, same cadence, same TTL — so an operator who wants to disable image GC entirely flips one knob, and tightening the TTL applies to both pulled images (this janitor) and built images (StartBuiltImageGC). No-op when disabled or Interval <= 0.
func (*Service) StartReconcileLoop ¶
func (*Service) StartSandbox ¶
func (*Service) StartTemplateGC ¶ added in v0.4.1
StartTemplateGC launches the periodic janitor that drops unreferenced templates. Shape mirrors StartBuiltImageGC verbatim: ticker + context-cancellation, per-tick bounded sweep context, best-effort log on failures. No-op when SB_ENABLE_FIRECRACKER=false (templates can't exist on those nodes) or when the GC enable knob is off — the latter gives operators a way to pause cleanup during a forensic window without recompiling.
func (*Service) StartVolumeReclaim ¶ added in v0.5.4
StartVolumeReclaim launches the backend-reclaim janitor that drains the pending_volume_deletions ledger. No-op when platform volumes are disabled, no reclaimer was wired, or the interval is non-positive — the metadata delete path is unaffected either way, only byte reclaim pauses.
func (*Service) StartWasmDurablePushSweep ¶ added in v0.5.3
StartWasmDurablePushSweep retries AOCR push for durable checkpoints missing registry metadata.
func (*Service) StartWasmModuleGC ¶ added in v0.5.3
StartWasmModuleGC launches the periodic wasm_modules catalogue janitor.
func (*Service) StartWasmPeriodicCheckpoint ¶ added in v0.5.3
StartWasmPeriodicCheckpoint launches optional boundary checkpoint sweeps.
func (*Service) StopByOwner ¶ added in v0.5.1
StopByOwner stops every currently-running sandbox owned by ownerRef, marking each one fleet-suspended first so RestoreByOwner knows to bring it back. A sandbox already stopped (by its user, or by a prior tick) is left untouched, so repeated calls do not thrash. Errors are collected and returned joined so the enforcement loop retries the whole owner next tick; the marker-then-stop order means a stop that fails still leaves the sandbox marked and running, and the retry re-attempts it.
func (*Service) StopCaddyCoalescer ¶ added in v0.2.4
func (s *Service) StopCaddyCoalescer()
StopCaddyCoalescer drains any pending op and exits the Run goroutine. No-op when StartCaddyCoalescer was never called — caddyCoalescer.Stop blocks on c.done which is only closed by Run, so calling it without a prior Start would hang shutdown.
func (*Service) StopSandbox ¶
StopSandbox is the operator-initiated stop (API surface, manual). It is a thin wrapper over stopSandboxInternal that pins the stop mode to manual: wake_armed is always cleared, so a serverless sandbox stopped via this path stays down until the operator explicitly starts it again. See serverless.go for the full wake-arming policy.
func (*Service) TemplateArtifactPushReconciler ¶ added in v0.4.1
func (s *Service) TemplateArtifactPushReconciler() *TemplateArtifactPushReconciler
TemplateArtifactPushReconciler exposes the reconciler so main.go can drive it from a ticker. Returns nil when template push is disabled.
func (*Service) ToolboxTarget ¶
func (*Service) TouchSandbox ¶
TouchSandbox bumps last_active_at for id with per-sandbox debounce. The wake-aware ingress proxy and the toolbox/session/runtime proxies call this on every request, so it must be cheap under high per-sandbox RPS — see touch_coalescer.go for the rationale and the debounce window. Callers that need a guaranteed immediate flush (lifecycle transitions, tests) should drop to s.store.Touch directly.
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).
func (*Service) UpsertCompatState ¶ added in v0.1.7
func (*Service) UpsertSnapshotAlias ¶ added in v0.1.7
func (*Service) WakeAwareL4PortTarget ¶ added in v0.2.4
WakeAwareL4PortTarget resolves a raw TCP upstream, ensuring the sandbox is awake first. It is shared by raw TCP and TLS-SNI wake proxying.
func (*Service) WakeAwarePortTarget ¶ added in v0.2.4
func (s *Service) WakeAwarePortTarget(ctx context.Context, id string, port int) (PortEndpoint, error)
WakeAwarePortTarget resolves a sandbox's exposed-port upstream URL, ensuring the sandbox is awake first. Used by the loopback ingress proxy when Caddy forwards a wake-aware HTTP port route. The same sentinels EnsureSandboxAwakeForHTTP returns flow through here unchanged.
func (*Service) WakeAwareToolboxTarget ¶ added in v0.2.4
WakeAwareToolboxTarget is the entry point every control-plane HTTP proxy (v1 toolbox/sessions, daytona toolbox, e2b runtime) calls in place of ToolboxTarget. It funnels every request through the wake helper so a stopped serverless sandbox with wake_armed=true is resurrected before the proxy attempts to dial the toolbox.
Behavior is exactly ToolboxTarget for: running sandboxes, stopped non-serverless sandboxes, and any case where cfg.EnableServerless is off (rollout-gate contract). The two new sentinels (ErrSandboxManuallyStopped, ErrWakeCircuitOpen) are surfaced upstream so apihttp can map them to 409 and 503+Retry-After:60 respectively.
type SnapshotPushConfig ¶ added in v0.2.4
type SnapshotPushConfig struct {
// Enabled gates the whole feature. When false the snapshot-create
// path stays byte-identical to today (no push, no state transitions).
Enabled bool
// Host is the AOCR registry vhost the daemon pushes to
// (e.g. `aocr.aerol.ai`). Falls back to ImageDistributionAOCRHost
// at the wiring layer when MirrorPushHost is unset.
Host string
// ClusterID is the AOCR-scoped tenant the snapshot ends up under.
// Used both as the registry-auth username (by convention; AOCR
// validates the PAT, not the username) and as the path namespace
// `cluster/<id>/snapshots/<name>`.
ClusterID string
// PATPath is the file path to the bearer token presented as the
// Docker registry password. File-sourced so rotation is just a
// file write; never logged.
PATPath string
// TagSuffix is an optional AOCR retention suffix appended at the end of the
// pushed tag (`latest<arch><suffix>`), e.g. "--ttl-1h" or "--idle-30d".
// AOCR's reaper parses `--(ttl|idle)-<dur>` off the END of the tag, so
// `latest--arch-arm64--ttl-1h` expires 1h after push. Empty (the default
// and prod behavior) pushes a plain `latest` tag, which the reaper keeps
// latest-only forever. Because "suffixes are real tags" in AOCR, the
// pull side (DestRefFor) must use the same suffix — both go through
// snapshotAOCRRef, so they stay consistent. Used by ephemeral clusters
// (e.g. integration tests) that want their snapshots auto-reaped.
TagSuffix string
}
SnapshotPushConfig wires the optional background AOCR push to a specific registry endpoint. A zero value disables push; the snapshot path runs exactly as before. main() validates that PATPath, ClusterID, and Host are non-empty when Enabled=true.
Auth reuses the auto-import cluster PAT (same secret, same rotation surface). The PAT file is re-read on every call so an operator can rotate it without restarting sandboxd — there's no in-memory cache.
func (SnapshotPushConfig) Validate ¶ added in v0.2.4
func (c SnapshotPushConfig) Validate() error
Validate enforces the consistency rules the snapshot pusher relies on. Returns nil for a disabled config so callers can validate unconditionally.
type SnapshotPushDocker ¶ added in v0.2.4
type SnapshotPushDocker interface {
PushImage(ctx context.Context, req docker.PushImageRequest) (string, error)
}
SnapshotPushDocker is the narrow Docker surface the pusher needs. Pulled out so tests can inject a fake without instantiating a real Docker client, and so the dependency surface of the pusher stays readable at a glance.
type SnapshotPushReconcileStats ¶ added in v0.2.4
SnapshotPushReconcileStats is what RunOnce reports back. Used by tests and by the metrics-collection wrapper in main.go.
type SnapshotPushReconciler ¶ added in v0.2.4
type SnapshotPushReconciler struct {
// contains filtered or unexported fields
}
SnapshotPushReconciler walks rows the snapshot-create path flagged `push_state IN ('pending', 'error')` and re-tries them. One ticker per node; fan-out inside a single tick is capped to keep a recovery storm from saturating the local Docker daemon or AOCR.
Like AutoImportReconciler, the type does not own a goroutine — RunOnce is the unit of work and the ticker lives in main.go. That keeps the type fully testable (table-driven, no time.Tick) and lets an operator trigger an immediate retry from a debug endpoint if they want.
func NewSnapshotPushReconciler ¶ added in v0.2.4
func NewSnapshotPushReconciler(pusher *SnapshotPusher, store SnapshotPushStore, logger *slog.Logger, maxInFlight int) *SnapshotPushReconciler
NewSnapshotPushReconciler builds the reconciler. Returns nil if the pusher is nil (snapshot push disabled) so callers can `if r == nil { return }` cheaply. maxInFlight clamps fan-out per tick; pass 0 for the safe default (2 — pushes are I/O-heavy).
func (*SnapshotPushReconciler) RunOnce ¶ added in v0.2.4
func (r *SnapshotPushReconciler) RunOnce(ctx context.Context) (SnapshotPushReconcileStats, error)
RunOnce processes one sweep of the push-pending queue. Blocks until all per-snapshot attempts have returned (success, failure, or context cancel). The bounded semaphore caps in-flight Docker push streams; the AOCR side is usually fine with the load but the local daemon's network/IO is not infinitely parallel.
type SnapshotPushResult ¶ added in v0.2.4
type SnapshotPushResult struct {
RegistryRef string
// Digest is the manifest digest (`sha256:...`) the registry assigned
// to the pushed tag, as reported by Docker's push stream `aux`
// payload. Empty when the daemon did not surface one — older daemons
// or registries that don't return a manifest digest will leave this
// blank and the reconciler stores "" rather than fabricating a value.
Digest string
}
SnapshotPushResult is what PushOnce returns on success. The destination ref is what the reconciler writes onto the snapshot row's ImageRegistryRef field — and what cluster placement on other nodes will see when they decide where to start a sandbox from this snapshot.
type SnapshotPushStore ¶ added in v0.2.4
type SnapshotPushStore interface {
ListSnapshotsPendingPush(ctx context.Context) ([]*models.SandboxSnapshot, error)
SetSnapshotPushState(ctx context.Context, name, state, errMsg string) error
UpdateSnapshotImageDistribution(ctx context.Context, name, mode, registryRef, digest string) error
}
SnapshotPushStore is the narrow store surface the reconciler needs. Pulled out as an interface so the reconciler is testable without a real SQLite store and so future store backends can satisfy it without growing the reconciler's dependency surface.
type SnapshotPusher ¶ added in v0.2.4
type SnapshotPusher struct {
// contains filtered or unexported fields
}
SnapshotPusher pushes a locally-committed snapshot image to AOCR. It holds no per-snapshot state; instantiate once at boot and reuse. Safe for concurrent use.
func NewSnapshotPusher ¶ added in v0.2.4
func NewSnapshotPusher(cfg SnapshotPushConfig, docker SnapshotPushDocker, logger *slog.Logger) (*SnapshotPusher, error)
NewSnapshotPusher builds a pusher. Returns nil if cfg.Enabled is false so callers can do `if pusher == nil { return }` on the snapshot-create path without an extra config check.
func (*SnapshotPusher) DestRefFor ¶ added in v0.2.4
func (p *SnapshotPusher) DestRefFor(snapshotName string) string
DestRefFor returns the AOCR destination ref this pusher would write for the given snapshot name. Used by callers that need the canonical ref without actually pushing — e.g. cross-node snapshot lookup, where a peer node took the snapshot and we want to pull from AOCR without asking the FSM whether the snapshot exists. Returns "" when the pusher is nil so callers can no-op cleanly when push is disabled.
func (*SnapshotPusher) PushOnce ¶ added in v0.2.4
func (p *SnapshotPusher) PushOnce(ctx context.Context, snapshot *models.SandboxSnapshot) (SnapshotPushResult, error)
PushOnce tags the snapshot's local image as the AOCR destination ref and pushes via the Docker daemon. Returns the destination ref on success — used by the reconciler to fill ImageRegistryRef and flip ImageDistributionMode to "aocr".
Idempotent: re-pushing the same `cluster/<id>/snapshots/<name>:latest` tag is safe; the registry treats the layer set as already-present and the daemon's push completes without error.
The PAT is read fresh from disk on every call so an operator can rotate it without restarting sandboxd. The PAT never appears in the returned error message — only the registry's response body does.
type TemplateArtifactManifest ¶ added in v0.4.1
type TemplateArtifactManifest struct {
SchemaVersion int `json:"schema_version"`
TemplateID string `json:"template_id"`
Image string `json:"image"`
RootfsSizeBytes int64 `json:"rootfs_size_bytes"`
SnapshotSizeBytes int64 `json:"snapshot_size_bytes"`
SnapshotChecksum string `json:"snapshot_checksum"`
SnapshotVsockCID uint32 `json:"snapshot_vsock_cid"`
HasOverlay bool `json:"has_overlay"`
MinSizeMiB int `json:"min_size_mib,omitempty"`
}
TemplateArtifactManifest is the JSON the puller in PR 6-B.2 reads to reconstruct the Template row on a fresh node. SchemaVersion is the forward-compat guard; everything else mirrors what the consumer needs to insert the row in status=ready without a second round-trip to the origin node.
type TemplateArtifactPullDocker ¶ added in v0.4.1
type TemplateArtifactPullDocker interface {
PullImage(ctx context.Context, ref string, auth *models.RegistryAuth) error
ExportImageTar(ctx context.Context, ref string) (io.ReadCloser, error)
RemoveImage(ctx context.Context, ref string) error
}
TemplateArtifactPullDocker is the narrow Docker surface the puller needs. Mirrors TemplateArtifactPushDocker so test fakes look the same; pulled out so unit tests don't need a real *docker.Client.
func NewTemplateArtifactPullDockerAdapter ¶ added in v0.4.1
func NewTemplateArtifactPullDockerAdapter(c *docker.Client) TemplateArtifactPullDocker
NewTemplateArtifactPullDockerAdapter is the constructor used by cmd/sandboxd to satisfy the puller's docker dependency without exposing the full *docker.Client API.
type TemplateArtifactPuller ¶ added in v0.4.1
type TemplateArtifactPuller struct {
// contains filtered or unexported fields
}
TemplateArtifactPuller is the consumer-side counterpart to TemplateArtifactPusher (template_push.go:60). It fetches a template's AOCR-pushed OCI image, walks the docker-save outer tar to find the single layer, walks that layer (which is the producer's original artifact tar) to extract manifest.json + rootfs.ext4 + snapshot.{memory,state}, validates the schema version + checksums, and atomically renames the staging dir into place under templatesDir.
Holds no per-template state; instantiate once at boot and reuse. The per-template single-flight latch lives on Service so the lazy EnsureTemplateLocal pattern (§3 of pr-review.md) can collapse concurrent first-creates against a missing-local template into one pull. Mirrors the EnsureLayer4Ready shape exactly.
func NewTemplateArtifactPuller ¶ added in v0.4.1
func NewTemplateArtifactPuller(d TemplateArtifactPullDocker, templatesDir string, logger *slog.Logger) (*TemplateArtifactPuller, error)
NewTemplateArtifactPuller mirrors NewTemplateArtifactPusher: returns nil when puller is disabled (templatesDir blank). Caller can then do `if puller == nil { return }` to keep the wire-up path tidy.
func (*TemplateArtifactPuller) PullOnce ¶ added in v0.4.1
PullOnce fetches+extracts the template's artifacts. Idempotent: a row whose local files already exist is a fast no-op (no network call). Failure modes — all surface to the caller, none are silently swallowed:
- registry_ref blank: nothing to pull, return descriptive error
- docker pull failure (registry unreachable, auth, manifest unknown)
- docker save failure (image went missing between pull and save)
- tar walk failure / unexpected layout (missing manifest, missing files)
- schema-version mismatch (refuse: a future producer can't roll back)
- filesystem error mid-extract (out of space, permission denied)
On any failure, the .partial directory is removed before return so the next call starts clean. Row state is untouched — the puller is purely "make local files match registry_ref", not a state-machine driver.
type TemplateArtifactPushDocker ¶ added in v0.4.1
type TemplateArtifactPushDocker interface {
ImportImage(ctx context.Context, req docker.ImportImageRequest) error
PushImage(ctx context.Context, req docker.PushImageRequest) (string, error)
RemoveImage(ctx context.Context, ref string) error
}
TemplateArtifactPushDocker is the narrow Docker surface the TemplateArtifactPusher needs. Mirrors SnapshotPushDocker so test fakes look the same; pulled out for the same reason — to avoid instantiating a real *docker.Client inside unit tests.
type TemplateArtifactPushReconciler ¶ added in v0.4.1
type TemplateArtifactPushReconciler struct {
// contains filtered or unexported fields
}
TemplateArtifactPushReconciler walks rows the build success path flagged `push_state IN ('pending', 'error')` and re-tries them. One ticker per node; fan-out inside a single tick is capped so a recovery storm doesn't saturate the local Docker daemon or AOCR.
Like SnapshotPushReconciler, the type does not own a goroutine — RunOnce is the unit of work and the ticker lives in main.go. That keeps the type fully testable (table-driven, no time.Tick) and lets an operator trigger an immediate retry from a debug endpoint.
func NewTemplateArtifactPushReconciler ¶ added in v0.4.1
func NewTemplateArtifactPushReconciler(pusher *TemplateArtifactPusher, store TemplateArtifactPushStore, logger *slog.Logger, maxInFlight int) *TemplateArtifactPushReconciler
NewTemplateArtifactPushReconciler builds the reconciler. Returns nil if the pusher is nil (push disabled) so callers can `if r == nil { return }` cheaply. maxInFlight clamps fan-out per tick; pass 0 for the safe default (2 — template pushes are even heavier than snapshot pushes because the rootfs.ext4 layer can run hundreds of MB).
func (*TemplateArtifactPushReconciler) RunOnce ¶ added in v0.4.1
func (r *TemplateArtifactPushReconciler) RunOnce(ctx context.Context) (TemplateArtifactPushStats, error)
RunOnce processes one sweep of the template push-pending queue. Blocks until all per-template attempts have returned. The bounded semaphore caps in-flight Docker push streams; the AOCR side is usually fine with the load but the local daemon's network/IO is not infinitely parallel — and a template tar is much larger than a snapshot's, so even a small fanout consumes real bandwidth.
type TemplateArtifactPushResult ¶ added in v0.4.1
TemplateArtifactPushResult mirrors SnapshotPushResult. RegistryRef is what the reconciler writes to firecracker_templates.registry_ref; Digest is the OCI manifest digest reported by the daemon's push stream `aux` payload (may be empty for older daemons / registries).
type TemplateArtifactPushStats ¶ added in v0.4.1
TemplateArtifactPushStats is what RunOnce reports back. Used by tests and by the metrics-collection wrapper in main.go (PR 6-E).
type TemplateArtifactPushStore ¶ added in v0.4.1
type TemplateArtifactPushStore interface {
ListTemplatesPendingPush(ctx context.Context) ([]*models.Template, error)
SetTemplatePushState(ctx context.Context, id, state, errMsg string) error
UpdateTemplatePushDistribution(ctx context.Context, id, ref, digest string) error
}
TemplateArtifactPushStore is the narrow store surface the template push reconciler needs. Pulled out as an interface so the reconciler is testable without a real SQLite store. Mirrors SnapshotPushStore.
type TemplateArtifactPusher ¶ added in v0.4.1
type TemplateArtifactPusher struct {
// contains filtered or unexported fields
}
TemplateArtifactPusher pushes the three artifact files (rootfs.ext4 + snapshot.memory + snapshot.state) plus a manifest.json to AOCR by (a) wrapping them in a tar, (b) docker-importing the tar as a local image under BuiltImageNamespace, and (c) pushing that image to `<host>/cluster/<id>/templates/<tid>:latest`. The local intermediate tag is removed on best-effort after the push so the built-image GC doesn't have to sweep it later.
Holds no per-template state; instantiate once at boot and reuse. Safe for concurrent use; the reconciler invokes PushOnce from goroutines under the bounded fanout semaphore.
func NewTemplateArtifactPusher ¶ added in v0.4.1
func NewTemplateArtifactPusher(cfg SnapshotPushConfig, docker TemplateArtifactPushDocker, templatesDir string, logger *slog.Logger) (*TemplateArtifactPusher, error)
NewTemplateArtifactPusher mirrors NewSnapshotPusher: returns nil if cfg.Enabled is false so callers can do `if pusher == nil { return }`. templatesDir is the absolute path that templateDir(id) was computed against in template.go so the pusher can re-derive the artifact paths from a Template row alone (the row's path columns are also checked for safety).
func (*TemplateArtifactPusher) DestRefFor ¶ added in v0.4.1
func (p *TemplateArtifactPusher) DestRefFor(templateID string) string
DestRefFor returns the AOCR destination ref this pusher would write for the given template ID. Used by the future consumer-side pull (PR 6-B.2) to compute the lookup ref without involving the pusher instance directly.
func (*TemplateArtifactPusher) PushOnce ¶ added in v0.4.1
func (p *TemplateArtifactPusher) PushOnce(ctx context.Context, tpl *models.Template) (TemplateArtifactPushResult, error)
PushOnce builds the artifact tar, imports it as a local image, and pushes it to AOCR. Returns the canonical ref + manifest digest on success. The PAT is read fresh on every call so an operator can rotate it without restarting sandboxd — same contract as the snapshot pusher.
Failure modes (caller maps each to push_state=error + push_error):
- missing artifact file (rootfs.ext4 or snapshot.{memory,state})
- read error mid-tar (e.g. disk fault)
- docker import failure (daemon down, malformed tar)
- docker push failure (registry down, auth rejected)
On any failure the local intermediate tag may or may not exist; RemoveImage is benign on 404/409 so the cleanup runs unconditionally.
type TemplateBuildRequest ¶ added in v0.4.1
TemplateBuildRequest is the small struct passed to TemplateBuilder. Mirrors pkg/oci.BuildRequest by name and shape so the production adapter is a one-field cast; declared locally so the service package does not import pkg/oci (which would pull internal/runtime/firecracker concerns into the service-layer dependency graph). Exported so the adapter in cmd/sandboxd can implement the interface.
type TemplateBuildResult ¶ added in v0.4.1
TemplateBuildResult is the subset of pkg/oci.Result the template service actually consumes; carried as a separate struct so the interface stays minimal.
type TemplateBuilder ¶ added in v0.4.1
type TemplateBuilder interface {
Build(ctx context.Context, req TemplateBuildRequest) (*TemplateBuildResult, error)
}
TemplateBuilder is the seam the template service uses to invoke the OCI→ext4 pipeline. Production wires this to pkg/oci.Builder via a thin adapter in cmd/sandboxd/main.go; tests stub it to skip real subprocesses. The interface intentionally mirrors pkg/oci's surface — keeping the shapes identical means the adapter is trivial and the service's mental model matches the real builder.
type TemplateCIDAllocator ¶ added in v0.4.1
type TemplateCIDAllocator interface {
AllocateForTemplate(ctx context.Context, templateID string) (uint32, error)
ReleaseForTemplate(ctx context.Context, templateID string) error
}
TemplateCIDAllocator reserves the per-template host-side AF_VSOCK CID the snapshot is captured with and that every later clone reuses. The production impl wraps *internal/network/tap.Pool's Allocate/Release — the same primitive used for per-sandbox slot allocation — keyed by a synthetic "template:<id>" sandbox id so the pool's per-id PK gives us idempotent reservation. Declared in the service package so template.go does not have to import internal/network/tap.
type TemplateRotationConfig ¶ added in v0.4.1
TemplateRotationConfig pins the operator-tunable knobs the reconciler reads. Cached on the struct rather than re-read off cfg every tick so a config rewrite under a live reconciler doesn't change MaxAge mid-sweep. (Production has no config-rewrite path; this is defensive.)
func (TemplateRotationConfig) IsEnabled ¶ added in v0.4.1
func (c TemplateRotationConfig) IsEnabled() bool
IsEnabled returns true when both knobs are non-zero. Rotation is opt-in (Phase 6 PR-E); a daemon that sets Interval but leaves MaxAge zero would tick forever and find nothing — main.go warns at boot.
type TemplateRotationReconciler ¶ added in v0.4.1
type TemplateRotationReconciler struct {
// contains filtered or unexported fields
}
TemplateRotationReconciler walks `ready` templates whose ready_at is older than MaxAge and re-kicks the snapshot rebuild via MarkSnapshotCorrupt(reason="rotation"). That re-uses the Phase 6 PR-A rebuild pipeline — same CAS, same gauge accounting, same recordTemplateUnhealthyGauge transitions — so rotation does not need its own rebuild plumbing.
Like the other reconcilers in this package, the type does not own a goroutine. RunOnce is the unit of work; the ticker lives in main.go. That keeps the type fully unit-testable and lets an operator trigger an immediate rotation sweep from a debug endpoint (future).
func NewTemplateRotationReconciler ¶ added in v0.4.1
func NewTemplateRotationReconciler(cfg TemplateRotationConfig, store TemplateRotationStore, marker rotationMarker, logger *slog.Logger) (*TemplateRotationReconciler, error)
NewTemplateRotationReconciler builds the reconciler. Returns nil if rotation is disabled so callers can `if r == nil { return }` cheaply. store/marker must both be non-nil when rotation is enabled.
func (*TemplateRotationReconciler) RunOnce ¶ added in v0.4.1
func (r *TemplateRotationReconciler) RunOnce(ctx context.Context) (TemplateRotationStats, error)
RunOnce processes a single rotation sweep. Each stale `ready` row is passed through MarkSnapshotCorrupt, whose CAS gates the transition — rows that another path already flipped to unhealthy are skipped without error. Unbounded fanout would be unsafe (every rebuild ties up a Firecracker VMM slot for the snapshot capture) so this method iterates serially; rotation is opt-in and not latency-sensitive, so "one rebuild kicked per tick" is fine.
Failure modes:
- store.ListTemplatesReadyBefore failure: returned to the caller; the ticker wrapper logs and waits for the next tick.
- MarkSnapshotCorrupt failure on an individual row: logged, stats count it as skipped, the sweep continues with the next row. One bad row should not abort the whole sweep.
type TemplateRotationStats ¶ added in v0.4.1
TemplateRotationStats is what RunOnce reports. Used by tests and by the metrics-aware ticker wrapper in main.go.
type TemplateRotationStore ¶ added in v0.4.1
type TemplateRotationStore interface {
// ListTemplatesReadyBefore returns templates with status='ready'
// and ready_at older than cutoff. The reconciler is the only caller.
ListTemplatesReadyBefore(ctx context.Context, cutoff time.Time) ([]*templateRotationCandidate, error)
}
TemplateRotationStore is the narrow store surface the rotation reconciler needs. Mirrors TemplateArtifactPushStore in shape so the reconciler is testable without a real SQLite store, and so a future refactor that splits store responsibilities along sub-interfaces doesn't have to revisit this file.
type TemplateRotationStoreAdapter ¶ added in v0.4.1
type TemplateRotationStoreAdapter struct {
Store templateReadyBeforeQuerier
}
TemplateRotationStoreAdapter wraps the real *store.Store into the narrow TemplateRotationStore interface the reconciler uses. Lives in this package so the rotation reconciler has zero dependencies on internal/store at the type-level (the adapter is a one-method shim; the rest of the file stays unit-testable with a fake).
func (*TemplateRotationStoreAdapter) ListTemplatesReadyBefore ¶ added in v0.4.1
func (a *TemplateRotationStoreAdapter) ListTemplatesReadyBefore(ctx context.Context, cutoff time.Time) ([]*templateRotationCandidate, error)
ListTemplatesReadyBefore satisfies TemplateRotationStore by mapping the *models.Template rows the store returns into the minimal candidate shape the reconciler consumes.
type TemplateSnapshotRequest ¶ added in v0.4.1
type TemplateSnapshotRequest struct {
TemplateID string
RootfsPath string
OutMemoryPath string
OutStatePath string
GuestCID uint32
MemoryMB int
VCPU int
}
TemplateSnapshotRequest is the input for the Phase 3 snapshot phase. RootfsPath is the absolute on-disk location of the rootfs.ext4 produced by the rootfs phase; the snapshotter mounts it as the boot drive. Out* paths are absolute file paths under the per-template dir where the snapshotter writes snapshot.memory and snapshot.state. GuestCID is the host-side AF_VSOCK CID the snapshotter will configure the transient template VMM with — re-used by every later clone load so the snapshot state's vsock device stays consistent. MemoryMB/VCPU are the transient VMM's resource budget; they also become the resumed clone's effective resources (Firecracker bakes them into the snapshot state).
type TemplateSnapshotResult ¶ added in v0.4.1
TemplateSnapshotResult is what the snapshot phase returns. Checksum is "sha256:<hex>|sha256:<hex>" (memory|state) so a later load can verify integrity in O(read) without re-decoding the format. The two size fields are reported separately for operator-facing metrics; the store persists their sum.
type TemplateSnapshotter ¶ added in v0.4.1
type TemplateSnapshotter interface {
SnapshotTemplate(ctx context.Context, req TemplateSnapshotRequest) (*TemplateSnapshotResult, error)
}
TemplateSnapshotter is the seam the template service uses to capture the Phase 3 snapshot. Production wires this to *firecracker.Driver via an adapter in cmd/sandboxd/main.go; the driver owns the transient VMM lifecycle because it already owns the VMM/network seams. Tests stub it to skip the real Firecracker subprocess.
type ToolboxEndpoint ¶
type VolumeReclaimer ¶ added in v0.5.4
VolumeReclaimer deletes the backend bytes of a deleted platform volume. The concrete implementation (pkg/volumes.Reclaimer) shells out to the AWS CLI / a transient NFS mount; the interface keeps the service offline-testable.
type WasmCheckpointPushResult ¶ added in v0.5.3
WasmCheckpointPushResult is persisted on the sandbox row after a successful AOCR push.
type WasmCheckpointPusher ¶ added in v0.5.3
type WasmCheckpointPusher struct {
// contains filtered or unexported fields
}
WasmCheckpointPusher uploads durable WASM checkpoints to AOCR via ORAS.
func NewWasmCheckpointPusher ¶ added in v0.5.3
func NewWasmCheckpointPusher(cfg SnapshotPushConfig, logger *slog.Logger) (*WasmCheckpointPusher, error)
NewWasmCheckpointPusher builds a pusher. Returns nil when cfg.Enabled is false.
func (*WasmCheckpointPusher) DeleteRef ¶ added in v0.5.3
func (p *WasmCheckpointPusher) DeleteRef(ctx context.Context, registryRef string) error
DeleteRef removes a tagged WASM checkpoint manifest from AOCR.
func (*WasmCheckpointPusher) DestRefFor ¶ added in v0.5.3
func (p *WasmCheckpointPusher) DestRefFor(sandboxID string) string
DestRefFor returns the AOCR :latest ref for sandboxID without pushing.
func (*WasmCheckpointPusher) DestRefTagged ¶ added in v0.5.3
func (p *WasmCheckpointPusher) DestRefTagged(sandboxID, tag string) string
DestRefTagged returns an AOCR ref with an explicit tag.
func (*WasmCheckpointPusher) PullOnce ¶ added in v0.5.3
func (p *WasmCheckpointPusher) PullOnce(ctx context.Context, registryRef, dstDir string) error
PullOnce downloads a durable checkpoint from AOCR into dstDir (§4.8 failover).
func (*WasmCheckpointPusher) PushOnce ¶ added in v0.5.3
func (p *WasmCheckpointPusher) PushOnce(ctx context.Context, sandboxID, memSnapDir string) (WasmCheckpointPushResult, error)
PushOnce uploads memSnapDir to AOCR :latest for sandboxID.
func (*WasmCheckpointPusher) PushOnceTo ¶ added in v0.5.3
func (p *WasmCheckpointPusher) PushOnceTo(ctx context.Context, sandboxID, memSnapDir, dest string) (WasmCheckpointPushResult, error)
PushOnceTo uploads memSnapDir to an explicit AOCR ref.
type WasmCheckpointStore ¶ added in v0.5.3
type WasmCheckpointStore interface {
DestRefFor(sandboxID string) string
DestRefTagged(sandboxID, tag string) string
PushOnceTo(ctx context.Context, sandboxID, memSnapDir, dest string) (WasmCheckpointPushResult, error)
PullOnce(ctx context.Context, registryRef, dstDir string) error
DeleteRef(ctx context.Context, registryRef string) error
}
WasmCheckpointStore abstracts AOCR push/pull for durable WASM checkpoints. Production uses *WasmCheckpointPusher; tests inject fakes.
type WasmMigrateRequest ¶ added in v0.5.3
type WasmMigrateRequest struct {
SandboxID string `json:"sandbox_id"`
TargetNodeID string `json:"target_node_id"`
}
WasmMigrateRequest is the operator body for POST /v1/cluster/wasm-migrate.
type WasmMigrateResponse ¶ added in v0.5.3
type WasmMigrateResponse struct {
SandboxID string `json:"sandbox_id"`
SourceNodeID string `json:"source_node_id"`
TargetNodeID string `json:"target_node_id"`
CloneGeneration string `json:"clone_generation"`
CheckpointPath string `json:"checkpoint_path"`
}
WasmMigrateResponse summarizes a completed cross-node handoff.
type WasmModuleResolver ¶ added in v0.5.3
type WasmModuleResolver interface {
Resolve(ctx context.Context, ref string) (*wasmmod.ResolvedModule, error)
}
WasmModuleResolver resolves a module reference to a local .wasm artifact.
type WasmWarmPoolNotifier ¶ added in v0.5.5
type WasmWarmPoolNotifier interface {
NoteModule(digest, modulePath string)
}
WasmWarmPoolNotifier registers a resolved module as a warm-pool refill target. Production wiring passes *wasmpool.Pool; tests inject a recorder.
Source Files
¶
- acme_budget.go
- arch_tag.go
- auto_import.go
- auto_import_retry.go
- auto_import_writeback.go
- caddy_coalescer.go
- cluster_ownership.go
- cluster_secrets.go
- custom_domains.go
- dns_verify.go
- docker_pool_create.go
- events.go
- facade_state.go
- fleet_control.go
- image_distribution.go
- ingress.go
- ingress_delta.go
- ingress_metrics.go
- isolate.go
- isolate_bundle_gc.go
- isolate_bundles.go
- isolate_ports.go
- l4wake.go
- metrics.go
- netstats.go
- owner_scope.go
- platform_volumes.go
- platform_volumes_crud.go
- platform_volumes_reclaim.go
- public_traffic.go
- route_shape.go
- serverless.go
- service.go
- snapshot_push.go
- snapshot_push_retry.go
- template.go
- template_health.go
- template_metrics.go
- template_pull.go
- template_push.go
- template_push_retry.go
- template_rotation.go
- toolbox_proxy.go
- touch_coalescer.go
- usage.go
- usage_live.go
- volume_meta.go
- wasm.go
- wasm_checkpoint.go
- wasm_checkpoint_periodic.go
- wasm_checkpoint_pull.go
- wasm_checkpoint_push.go
- wasm_checkpoint_store.go
- wasm_cleanup.go
- wasm_custom_domains.go
- wasm_migrate.go
- wasm_migrate_tar.go
- wasm_module.go
- wasm_module_api.go
- wasm_module_health.go
- wasm_network.go
- wasm_ports.go
- wasm_reconcile.go
- wasm_recreate.go