Documentation
¶
Overview ¶
internal/runtime/docker/deploy.go
Package docker is the Docker Engine adapter: it speaks the Engine REST API over the socket and returns product types only. No SDK type leaves this package.
Index ¶
- Variables
- func OwnContainerID() string
- type Client
- func (c *Client) ContainerImageDigests(ctx context.Context, container string) ([]string, error)
- func (c *Client) Deploy(parent context.Context, req protocol.DeploymentRequest, started func()) protocol.DeploymentResult
- func (c *Client) Engine(ctx context.Context) (protocol.Engine, error)
- func (c *Client) InspectContainer(parent context.Context, target protocol.InspectionTarget) (*protocol.ContainerInspection, error)
- func (c *Client) Logs(ctx context.Context, req protocol.LogRequest, sink func([]byte) error) error
- func (c *Client) OpenExec(ctx context.Context, spec protocol.ExecSpec) (*ExecSession, error)
- func (c *Client) Operate(ctx context.Context, cmd protocol.Command) (outcome, detail string)
- func (c *Client) Protect(id string)
- func (c *Client) ReadConfiguration(parent context.Context, target protocol.InspectionTarget) (*protocol.ContainerConfiguration, error)
- func (c *Client) Remove(parent context.Context, req protocol.RemovalRequest, started func()) protocol.DeploymentResult
- func (c *Client) Running(ctx context.Context) ([]string, error)
- func (c *Client) Snapshot(ctx context.Context) (*protocol.Snapshot, error)
- func (c *Client) Stats(ctx context.Context, running []string) protocol.Metrics
- type ExecSession
- func (s *ExecSession) Close() error
- func (s *ExecSession) Inspect(ctx context.Context) (protocol.ExecStatus, error)
- func (s *ExecSession) Read(p []byte) (int, error)
- func (s *ExecSession) Resize(ctx context.Context, size protocol.TerminalSize) error
- func (s *ExecSession) Write(p []byte) (int, error)
Constants ¶
This section is empty.
Variables ¶
var ( ErrExecClosed = errors.New("exec stream closed; process exit is not established") ErrExecIdle = errors.New("exec input idle timeout") ErrExecLifetime = errors.New("exec absolute timeout") ErrExecStartUnknown = errors.New("exec start outcome is unknown; do not automatically retry") )
var ( ErrInspectionInvalid = errors.New("runtime inspection response invalid or exceeds bounds") ErrInspectionChanged = errors.New("runtime inspection target or observations changed") ErrInspectionNotFound = errors.New("runtime inspection target not found") )
var ErrSelfProtected = errors.New("self_protected")
ErrSelfProtected refuses an action on the container this agent runs in.
Functions ¶
func OwnContainerID ¶
func OwnContainerID() string
OwnContainerID is the ID of the Docker container this process runs in, read from /proc/self/mountinfo; "" outside one.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func (*Client) ContainerImageDigests ¶
ContainerImageDigests reads the immutable image ID of a container, then that image's pullable repository digests. Tags are never resolved during discovery.
func (*Client) Deploy ¶
func (c *Client) Deploy(parent context.Context, req protocol.DeploymentRequest, started func()) protocol.DeploymentResult
Deploy replaces each service's mapped container with one created from its pinned image. First every service's precondition and image (pull, for a service naming a digest), in plan order, with each frame volume ensured after the precondition of the first service mounting it; then per service recheck, rename, create, stop, start, remove. Renaming and creating while the old container still runs means a name conflict or a refused create costs no downtime. The first step that is not a success ends the run and every later step is recorded as skipped. A recreate puts the host back: a failed create or stop is undone, and a failed start, which includes a new container that stops running or restarts within startWatch when the old one was running, is rolled back (a rollback step); services already replaced stay replaced. An explicit run (no Replaces) is image, create, start. No volume is ever removed. See docs/superpowers/specs/2026-09-22-deployment-runtime-design.md, 2026-09-23-pull-step-design.md and 2026-09-24-volumes-design.md. started is called once, immediately before the first phase-two call (after the first recheck's deadline guard, or an explicit run's create guard); a run that ends in phase one never calls it.
func (*Client) InspectContainer ¶
func (c *Client) InspectContainer(parent context.Context, target protocol.InspectionTarget) (*protocol.ContainerInspection, error)
InspectContainer reads a bounded, redacted observation through Engine v1.41. It performs GETs only, follows the pinned image ID rather than a tag, and rechecks selected container fields after the image read. It also decodes the container into inspectedForDeploy and reports, as codes only, what a recreate from the definition would drop. Callers own scope, authorization/admission through the agent inspection transport.
func (*Client) Logs ¶
Logs streams one container's log to sink. The caller decides when enough is enough -- a sink that returns an error ends the stream -- so the byte and line bounds live with the reader who is counting them, not here.
The container is addressed by ID, escaped like every other identifier that becomes part of a URL on the host's root-equivalent socket.
func (*Client) OpenExec ¶
OpenExec creates and starts one PTY against an immutable, running container and image identity. Callers must authorize/admit the session before calling this; this method is not exposed by any HTTP or agent frame handler yet. See protocol §7.
func (*Client) Operate ¶
Operate runs one lifecycle action against one container, after checking that the container is still what the operator was looking at. Docker has no universal resource version, so the precondition is operation-specific identity read immediately before acting: the same image digest, the same state. A precondition that no longer holds is a refusal, not a failure, because nothing was attempted.
func (*Client) Protect ¶
Protect makes the client refuse exec, configuration reads, lifecycle actions, replacement and removal of container id (a full ID; "" protects none). Call it before use.
func (*Client) ReadConfiguration ¶
func (c *Client) ReadConfiguration(parent context.Context, target protocol.InspectionTarget) (*protocol.ContainerConfiguration, error)
ReadConfiguration reads one container's editable configuration through Engine v1.41, like InspectContainer: GETs only, the pinned image, and a second container read that must match the first. Errors are fixed values; daemon text never leaves.
func (*Client) Remove ¶
func (c *Client) Remove(parent context.Context, req protocol.RemovalRequest, started func()) protocol.DeploymentResult
Remove stops and deletes each target container in order: precondition, stop, remove. A container already gone counts as removed. Volumes (no v=1) and networks are never touched. The first step that is not a success ends the run and every later step is skipped.
func (*Client) Running ¶
Running lists the IDs of running containers for Stats; it is cheaper than a full snapshot.
type ExecSession ¶
type ExecSession struct {
// contains filtered or unexported fields
}
ExecSession is one raw PTY stream (stdout/stderr combined). One reader and one writer may run concurrently; Close unblocks both. No output or command is logged. Closing an attachment is NOT a promise to terminate the container process.
func (*ExecSession) Close ¶
func (s *ExecSession) Close() error
func (*ExecSession) Inspect ¶
func (s *ExecSession) Inspect(ctx context.Context) (protocol.ExecStatus, error)
Inspect can run after Close with a fresh context. EOF alone is not an exit code.
func (*ExecSession) Resize ¶
func (s *ExecSession) Resize(ctx context.Context, size protocol.TerminalSize) error
Resize counts as operator activity. Runtime output alone does not reset idle time.