dockerruntime

package
v0.0.0-...-79934c9 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package dockerruntime is the single Docker runtime adapter (PRD §18.1, ADR-004, ADR-051): every Docker Engine API call AkerDock makes — from the control plane's jobs and handlers or from the server agent — goes through the Runtime interface. Business logic never talks to a transport, a shell or the SDK client directly, so where an operation executes (the agent's local socket today, the typed command channel of ADR-052 tomorrow) is decided entirely by which implementation a caller is handed (ADR-001).

The method set is the strict subset of the Engine API the codebase uses. Deliberately absent: ImageBuild — build contexts live on the target server (git clone on the host), so builds are driven server-side (BuildKit via the agent, ADR-051 §scope) and never through this interface.

Index

Constants

View Source
const DefaultSocket = "/var/run/docker.sock"

DefaultSocket is the local Docker Engine API socket (ADR-004: standalone Docker is the only runtime).

Variables

This section is empty.

Functions

func CPUPercent

func CPUPercent(s container.StatsResponse) *float64

CPUPercent computes the CPU column from the sample and its precpu predecessor. It needs a stream=false snapshot: one-shot stats leave precpu_stats empty and the delta is incomputable.

func Demux

func Demux(r io.Reader, tty bool, onOutput func(string)) error

Demux copies a Docker log/attach stream to onOutput until EOF. The Engine multiplexes stdout and stderr with an 8-byte frame header unless the container has a TTY; tty says which framing r carries. Chunks are forwarded in arrival order, merged into one stream — the contract sshexec.RunStream gives job code today, so migrated call sites keep their onOutput callbacks unchanged.

func IsConflict

func IsConflict(err error) bool

IsConflict reports a state conflict — name already taken, container not stopped before removal, network still in use.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports the daemon's "no such object" answer — the API equivalent of the CLI's "No such container/volume/network". Removal and inspection paths treat it as "nothing to do", the way `|| true` did.

func IsNotModified

func IsNotModified(err error) bool

IsNotModified reports the daemon's 304 — start of an already-running or stop of an already-stopped container. The SDK swallows most of these as success; the predicate exists for the paths where it surfaces.

func IsUnavailable

func IsUnavailable(err error) bool

IsUnavailable reports the mandatory-agent failure mode (ADR-051): the server's command channel is not there. The remedy is the agent's reconciliation, never a fallback.

func MemoryUsage

func MemoryUsage(s container.StatsResponse) (used, limit *int64, percent *float64)

MemoryUsage computes used/limit/percent. Used excludes the reclaimable page cache, like the CLI: inactive_file on cgroup v2, total_inactive_file on v1.

Types

type AttachStream

type AttachStream interface {
	io.ReadWriteCloser
	CloseWrite() error
}

AttachStream is the bidirectional stream of an attached exec: reads carry its output, writes its stdin, CloseWrite ends the stdin without ending the output.

type CommandSender

type CommandSender interface {
	Command(ctx context.Context, method string, params any) (json.RawMessage, error)
	Stream(ctx context.Context, method string, params any) (io.ReadCloser, error)
	Attach(ctx context.Context, method string, params any) (AttachStream, error)
}

CommandSender is the control-plane handle on one server's agent channel (ADR-052): it carries a typed command and returns its result, opens the command's output stream, or attaches to the one bidirectional command. internal/handlers implements it on the live WebSocket; this package never sees the transport.

type Hijacker

type Hijacker interface {
	DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error)
}

Hijacker is the raw connection upgrade the SDK client exposes — the rail the agent's BuildKit session rides (ADR-055 phase 2: /grpc for the build gRPC, /session for the attachables). Only the LOCAL implementation has it; a remote runtime deliberately does not — builds execute where the context lives, never across the channel.

type Local

type Local struct {
	*client.Client
}

Local is the Runtime served by the official SDK client over a local unix socket — the implementation the agent (and the waker) runs against /var/run/docker.sock. Remote execution reaches this same implementation through the typed command channel (ADR-052).

func NewLocal

func NewLocal(socket, apiVersion string) (*Local, error)

NewLocal builds a Runtime over the unix socket (DefaultSocket when empty). apiVersion optionally pins the Engine API version (e.g. "1.45"); empty — the default — negotiates with the daemon, so a client newer than the daemon still works. Pinning a version newer than the daemon supports makes every call fail ("client version too new"), so we do not pin by default.

type Runtime

type Runtime interface {
	// Containers.
	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
	ContainerStart(ctx context.Context, container string, options container.StartOptions) error
	ContainerStop(ctx context.Context, container string, options container.StopOptions) error
	ContainerRestart(ctx context.Context, container string, options container.StopOptions) error
	ContainerRename(ctx context.Context, container, newContainerName string) error
	ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error
	ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
	ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
	ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error)
	ContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error)
	// ContainerStats with stream=false is the metrics snapshot: unlike the
	// one-shot variant, it fills precpu_stats, without which CPU% cannot be
	// computed (ADR-034). stream=true is not carried by the agent channel.
	ContainerStats(ctx context.Context, container string, stream bool) (container.StatsResponseReader, error)
	ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)

	// Exec — one-shot (ContainerExecStart) and attached/interactive
	// (ContainerExecAttach returns the hijacked bidirectional stream; resize
	// serves the container terminal's PTY).
	ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (container.ExecCreateResponse, error)
	ContainerExecStart(ctx context.Context, execID string, options container.ExecStartOptions) error
	ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (types.HijackedResponse, error)
	ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error)
	ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error

	// Images. Pull/push authenticate per request (options.RegistryAuth) —
	// nothing is persisted in the host's docker config for API-path
	// operations, unlike the CLI login/logout dance.
	ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
	ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error)
	ImageTag(ctx context.Context, image, ref string) error
	ImageInspect(ctx context.Context, image string, options ...client.ImageInspectOption) (image.InspectResponse, error)
	ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
	ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
	ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)

	// Volumes.
	VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error)
	VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error)
	VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error)
	VolumeRemove(ctx context.Context, volumeID string, force bool) error
	VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error)

	// Networks.
	NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error)
	NetworkConnect(ctx context.Context, network, container string, config *network.EndpointSettings) error
	NetworkDisconnect(ctx context.Context, network, container string, force bool) error
	NetworkInspect(ctx context.Context, network string, options network.InspectOptions) (network.Inspect, error)
	NetworkList(ctx context.Context, options network.ListOptions) ([]network.Summary, error)
	NetworkRemove(ctx context.Context, network string) error
	NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error)

	// System.
	Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error)
	Info(ctx context.Context) (system.Info, error)
	ServerVersion(ctx context.Context) (types.Version, error)
	DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
	RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
	Ping(ctx context.Context) (types.Ping, error)

	Close() error
}

Runtime is the Engine API surface AkerDock relies on. Signatures mirror the official SDK client verbatim so the local implementation is the SDK itself and a typed command frame (ADR-052) maps 1:1 onto a method — the SDK types ARE the Engine API wire types.

Error discipline: implementations surface the SDK's typed errors; callers branch with IsNotFound/IsConflict/IsNotModified from this package, never by matching message text. Streaming returns (io.ReadCloser, hijacked connections, channels) are bounded by the caller's ctx — implementations must not impose a global timeout, which would kill a follow stream mid-flight.

func NewAgentRuntime

func NewAgentRuntime(s CommandSender) Runtime

NewAgentRuntime returns the Runtime that executes every call as a typed command on the server's agent channel. The agent is mandatory (ADR-051): there is no fallback below this — a dead channel surfaces as an IsUnavailable error and the caller's remedy is repairing the agent.

type Source

type Source interface {
	Runtime(ctx context.Context, serverID int64) (Runtime, error)
}

Source resolves the Runtime executing on a given server — the seam job and handler code depends on. The api process serves it from its live channel registry; a worker or scheduler serves it through the api relay (ADR-052 §8). An unreachable agent answers an IsUnavailable error.

Directories

Path Synopsis
Package fake is the test double for dockerruntime.Runtime: a typed recorder.
Package fake is the test double for dockerruntime.Runtime: a typed recorder.

Jump to

Keyboard shortcuts

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