Documentation
¶
Overview ¶
Package docker is the v1 sandbox backend: one disposable container per session, driven over the Docker Engine API. The image must carry /bin/bash at that exact path (the plan's image contract) and a POSIX userland. A `stat` accepting `-c` (GNU or BusyBox) is wanted rather than required: the write path reads the target's mode with it, and an image without one still writes — it lands the file 0644, as every write did before #204. The k8s backend asks for more, and asks harder (internal/sandbox/k8s/client.go).
Index ¶
- type Config
- type Provider
- func (p *Provider) Export(ctx context.Context, sessionID domain.ID, root string) (io.ReadCloser, error)
- func (p *Provider) Owned(ctx context.Context) ([]domain.ID, error)
- func (p *Provider) Provision(ctx context.Context, spec sandbox.Spec) (sb sandbox.Sandbox, err error)
- func (p *Provider) Reap(ctx context.Context, sessionID domain.ID) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
Host string
// GateNetwork is the Docker network a session's egress-gate container joins
// — the deploy network that carries real egress and reaches the control
// plane. The sandbox does not join it; it shares the gate's netns and reaches
// the world only through the gate's proxy. Empty defaults to "bridge". Unused
// for sessions with no Spec.Gate (unrestricted, no vault credentials).
GateNetwork string
// GateTokenRevoker, when non-nil, is called by Reap before it removes a
// session's containers, so a gate token never outlives its gate (#197). It
// lives on the provider — not on a Spec — because Reap has no Spec: the
// reaper works from a session id alone. The executor supplies the same
// pool-backed implementation it puts on every Spec; the BYOC worker, which
// has no database, leaves it nil and Reap skips revocation.
GateTokenRevoker sandbox.GateTokenRevoker
}
Config configures the backend. Host is a Docker daemon address (unix:///... or tcp://host:port); empty falls back to DOCKER_HOST and then to the well-known socket.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider provisions per-session containers.
func (*Provider) Export ¶ added in v0.2.0
func (p *Provider) Export(ctx context.Context, sessionID domain.ID, root string) (io.ReadCloser, error)
Export streams one root out of the session's container as the daemon's archive tar — members under one top-level directory named after the root's base name, the endpoint's native shape. GET /archive works on a stopped container, which is exactly the checkpoint path's case: the TTL reap reads a sandbox it is about to destroy (plan 24). The label is verified before the read (`ours`) so a name collision from another deployment never leaks its filesystem into this session's checkpoint.
func (*Provider) Owned ¶ added in v0.2.0
Owned lists the distinct session ids of every container — running or stopped, sandboxes and gates alike — carrying this daemon's ownership label.
func (*Provider) Provision ¶
func (p *Provider) Provision(ctx context.Context, spec sandbox.Spec) (sb sandbox.Sandbox, err error)
Provision returns the session's container, creating and starting it only if none exists. Two executors racing on the same session converge: the loser of the create race adopts the winner's container.
When spec.Gate is set the sandbox is one half of a pair: the gate container is ensured first (it owns the network namespace the sandbox joins and enforces its egress), and only once it is healthy is the sandbox created inside its netns. If a fresh gate was created here and the sandbox half then fails, the gate is torn down rather than leaked.
func (*Provider) Reap ¶ added in v0.2.0
Reap destroys everything this daemon owns for the session: the sandbox container, its gate when the session is gated, and their anonymous volumes (removeContainer passes v=1). The gate token is revoked first when the provider has a revoker (#197 — and revoke-before-teardown keeps a partial failure retryable: a re-run re-revokes a no-op and finishes the removals). The sandbox goes before the gate, as Destroy orders it — the sandbox lives in the gate's network namespace — and every removal is attempted even when an earlier one fails, so one stuck container never strands the rest. A session owning nothing is a no-op.