Documentation
¶
Overview ¶
Package agentwire defines the wire protocol of the agent channel: the ADR-041 observation frames (v1) and the ADR-052 typed command frames (v2). Both sides — the agent (internal/waker) and the control plane (internal/handlers, internal/dockerruntime) — share these types, so the vocabulary is defined exactly once and every command on the wire is one of the enumerated methods below, never an opaque byte stream to the daemon.
Index ¶
- Constants
- func IsStreamMethod(method string) bool
- func PumpReader(ctx context.Context, id int64, r io.Reader, write func(Frame) error)
- func Unavailable(why string) error
- type Attached
- type Command
- type Conn
- func (c *Conn) Attach(ctx context.Context, method string, params any) (*Attached, error)
- func (c *Conn) CancelRemote(id int64)
- func (c *Conn) Command(ctx context.Context, method string, params any) (json.RawMessage, error)
- func (c *Conn) DeliverChunk(chunk *StreamChunk)
- func (c *Conn) DeliverResult(res *Result)
- func (c *Conn) Done() <-chan struct{}
- func (c *Conn) Stream(ctx context.Context, method string, params any) (io.ReadCloser, error)
- func (c *Conn) WriteFrame(f Frame) error
- type ContainerCreateParams
- type ContainerExecAttachParams
- type ContainerExecCreateParams
- type ContainerExecResizeParams
- type ContainerExecStartParams
- type ContainerListParams
- type ContainerLogsParams
- type ContainerRemoveParams
- type ContainerRenameParams
- type ContainerStartParams
- type ContainerStopParams
- type ContainerWaitParams
- type DirEnsureParams
- type DiskUsageParams
- type Error
- type EventsParams
- type ExecToFileParams
- type ExecToFileResult
- type FileChownParams
- type FileCopyParams
- type FileHashParams
- type FileHashResult
- type FileReadParams
- type FileReadResult
- type FileRemoveParams
- type FileStatParams
- type FileStatResult
- type FileToExecParams
- type FileToExecResult
- type FileToURLParams
- type FileWriteParams
- type Frame
- type ImageBuildParams
- type ImageListParams
- type ImagePullParams
- type ImagePushParams
- type ImageRemoveParams
- type ImageTagParams
- type NameParams
- type NetworkConnectParams
- type NetworkCreateParams
- type NetworkDisconnectParams
- type NetworkInspectParams
- type NetworkListParams
- type Observation
- type PruneParams
- type RawFilters
- type RegistryLoginParams
- type Result
- type StatsResult
- type StreamChunk
- type URLToFileParams
- type VolumeCreateParams
- type VolumeListParams
- type VolumeRemoveParams
Constants ¶
const ( MethodContainerCreate = "ContainerCreate" MethodContainerStart = "ContainerStart" MethodContainerStop = "ContainerStop" MethodContainerRestart = "ContainerRestart" MethodContainerRename = "ContainerRename" MethodContainerRemove = "ContainerRemove" MethodContainerInspect = "ContainerInspect" MethodContainerWait = "ContainerWait" MethodContainerList = "ContainerList" MethodContainerLogs = "ContainerLogs" // stream MethodContainerStats = "ContainerStats" MethodContainersPrune = "ContainersPrune" MethodContainerExecCreate = "ContainerExecCreate" MethodContainerExecStart = "ContainerExecStart" MethodContainerExecInspect = "ContainerExecInspect" MethodContainerExecResize = "ContainerExecResize" MethodImagePull = "ImagePull" // stream MethodImagePush = "ImagePush" // stream MethodImageTag = "ImageTag" MethodImageInspect = "ImageInspect" MethodImageList = "ImageList" MethodImageRemove = "ImageRemove" MethodImagesPrune = "ImagesPrune" MethodVolumeCreate = "VolumeCreate" MethodVolumeInspect = "VolumeInspect" MethodVolumeList = "VolumeList" MethodVolumeRemove = "VolumeRemove" MethodVolumesPrune = "VolumesPrune" MethodNetworkCreate = "NetworkCreate" MethodNetworkConnect = "NetworkConnect" MethodNetworkDisconnect = "NetworkDisconnect" MethodNetworkInspect = "NetworkInspect" MethodNetworkList = "NetworkList" MethodNetworkRemove = "NetworkRemove" MethodNetworksPrune = "NetworksPrune" MethodEvents = "Events" // stream MethodInfo = "Info" MethodServerVersion = "ServerVersion" MethodDiskUsage = "DiskUsage" MethodRegistryLogin = "RegistryLogin" MethodPing = "Ping" )
const ( MethodFileWrite = "FileWrite" MethodFileRead = "FileRead" MethodFileRemove = "FileRemove" MethodFileStat = "FileStat" MethodFileChown = "FileChown" MethodFileCopy = "FileCopy" MethodDirEnsure = "DirEnsure" )
Host-ops vocabulary (ADR-054): file primitives the agent executes in pure Go against the bind-mounted /var/lib/akerdock tree — the helper image is distroless, so there is no shell to fall back on, and every path is validated against that root before it is touched.
const ( MethodExecToFile = "ExecToFile" MethodFileToExec = "FileToExec" MethodFileToURL = "FileToURL" MethodURLToFile = "URLToFile" MethodFileHash = "FileHash" )
Pipe vocabulary (ADR-054 tranche C): bulk transfers the agent executes LOCALLY — container exec ↔ host file with compression, host file ↔ presigned URL — so a multi-gigabyte dump never crosses the control plane. Each is a single long-running unary command; only the typed verdict (exit code, size, digest, output tail) travels back.
const ( SubprotocolV1 = "akerdock-agent-v1" SubprotocolV2 = "akerdock-agent-v2" // SubprotocolRelay is the worker→api bridge (ADR-052 §8): a process that // does not terminate agent WebSockets sends its typed commands here, and // the api forwards them onto the target server's live channel. SubprotocolRelay = "akerdock-relay-v1" )
Channel subprotocols. The agent offers both; the control plane picks v2 when it speaks commands, and an older side falls back to v1 (observations only) — the rail upgrades without a flag day.
const ( // FrameObservations carries an acked observation batch (agent → CP). FrameObservations = "observations" // FrameAck acknowledges an observation batch by sequence (CP → agent). FrameAck = "ack" // FrameCommand carries one typed command (CP → agent, v2). FrameCommand = "cmd" // FrameResult answers a command by id (agent → CP, v2). FrameResult = "res" // FrameStream carries one chunk of a command's output stream — logs // follow, pull/push progress, daemon events (agent → CP, v2). FrameStream = "stream" // FrameCancel aborts a command in flight and closes its stream // (CP → agent, v2). Identified by the command id. FrameCancel = "cancel" )
Frame types.
const ( CodeNotFound = "not_found" CodeConflict = "conflict" CodeNotModified = "not_modified" CodeInvalid = "invalid" CodeCanceled = "canceled" CodeUnimplemented = "unimplemented" CodeInternal = "internal" )
Error codes: the daemon's typed answers (errdefs), flattened for the wire so the control plane can re-wrap them and keep IsNotFound/IsConflict working across the channel.
const ChunkSize = 32 << 10
ChunkSize bounds one stream chunk; small enough to interleave fairly with other traffic on a shared channel, large enough to keep log following cheap.
const ( // MethodContainerExecAttach is the one BIDIRECTIONAL stream: after the // acknowledging result, output flows as chunks one way and input chunks // travel the other way under the same command id — an input chunk with // EOF closes the exec's stdin without ending the output. MethodContainerExecAttach = "ContainerExecAttach" )
The command vocabulary: one name per dockerruntime.Runtime method carried over the channel. The executor refuses anything outside this list, and each name is what audit and telemetry record.
const MethodImageBuild = "ImageBuild"
MethodImageBuild (ADR-055 phase 2) runs a BuildKit build agent-side: the context is a host path local to the agent, the image lands in the local daemon's store, and only the progress stream crosses the channel. Streamed.
const StreamBuffer = 512
StreamBuffer bounds one stream's undelivered chunks. A channel is shared by every command to a server: rather than stall it behind one slow consumer, an overflowing stream is killed with an explicit error.
Variables ¶
This section is empty.
Functions ¶
func IsStreamMethod ¶
IsStreamMethod reports whether the method answers with a chunk stream after its acknowledging result — what a relay must know to bridge it.
func PumpReader ¶
PumpReader forwards a reader as stream chunks for command id until EOF or error, then sends the terminal chunk. brokeCleanly is decided by ctx: a canceled pump reports EOF-less silence, not a daemon error.
func Unavailable ¶
Unavailable is the mandatory-agent failure mode (ADR-051): the channel is not there, the operation cannot run, and the remedy is the agent's reconciliation — never a silent fallback.
Types ¶
type Attached ¶
type Attached struct {
// contains filtered or unexported fields
}
Attached is a bidirectional attach stream (ContainerExecAttach): reads carry the peer's output, writes its input.
func (*Attached) CloseWrite ¶
CloseWrite closes the peer-side stdin; output keeps flowing.
type Command ¶
type Command struct {
ID int64 `json:"id"`
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
}
Command is one typed method call. Method is a name from the enumerated vocabulary (method.go); Params is the JSON of that method's params struct — the Docker SDK types, which are the Engine API's own wire types.
type Conn ¶
type Conn struct {
// Record, when set, feeds the docker-ops counter: one increment per
// command or stream open, by method and outcome.
Record func(method, outcome string)
// contains filtered or unexported fields
}
Conn routes typed commands over one live channel and matches results and stream chunks back by id. It is side-agnostic: the api process runs one per agent WebSocket, the relay client (ADR-052 §8) one per bridged server. The OWNER runs the read loop and feeds received frames in through DeliverResult/DeliverChunk; writes are serialized here.
func (*Conn) Attach ¶
Attach sends one bidirectional command: the result acknowledges the open, output arrives through Read, writes travel as input chunks under the same id, and CloseWrite marks the peer-side stdin closed without ending reads.
func (*Conn) CancelRemote ¶
CancelRemote tells the peer to abort the command; best-effort — a broken socket is its own cancellation.
func (*Conn) DeliverChunk ¶
func (c *Conn) DeliverChunk(chunk *StreamChunk)
DeliverChunk routes a stream frame. A consumer that cannot keep up loses its stream — with an explicit error, and with the peer told to stop — so one slow log follower never stalls the whole channel.
func (*Conn) DeliverResult ¶
DeliverResult routes a result frame to its waiting call.
func (*Conn) Done ¶
func (c *Conn) Done() <-chan struct{}
Done reports the connection's end — the owner's ctx.
func (*Conn) Stream ¶
Stream sends one streaming command: the result acknowledges the open, then chunks flow until EOF, error or Close.
func (*Conn) WriteFrame ¶
WriteFrame serializes one frame onto the socket; 10 s bounds a stalled peer, not the command it carries.
type ContainerCreateParams ¶
type ContainerCreateParams struct {
Config *container.Config `json:"config"`
HostConfig *container.HostConfig `json:"host_config,omitempty"`
NetworkingConfig *network.NetworkingConfig `json:"networking_config,omitempty"`
Platform *ocispec.Platform `json:"platform,omitempty"`
Name string `json:"name"`
}
type ContainerExecAttachParams ¶
type ContainerExecAttachParams struct {
ExecID string `json:"exec_id"`
Options container.ExecAttachOptions `json:"options"`
}
type ContainerExecCreateParams ¶
type ContainerExecCreateParams struct {
Name string `json:"name"`
Options container.ExecOptions `json:"options"`
}
type ContainerExecResizeParams ¶
type ContainerExecResizeParams struct {
ExecID string `json:"exec_id"`
Options container.ResizeOptions `json:"options"`
}
type ContainerExecStartParams ¶
type ContainerExecStartParams struct {
ExecID string `json:"exec_id"`
Options container.ExecStartOptions `json:"options"`
}
type ContainerListParams ¶
type ContainerListParams struct {
Options container.ListOptions `json:"options"`
Filters RawFilters `json:"filters,omitempty"`
}
type ContainerLogsParams ¶
type ContainerLogsParams struct {
Name string `json:"name"`
Options container.LogsOptions `json:"options"`
}
type ContainerRemoveParams ¶
type ContainerRemoveParams struct {
Name string `json:"name"`
Options container.RemoveOptions `json:"options"`
}
type ContainerRenameParams ¶
type ContainerStartParams ¶
type ContainerStartParams struct {
Name string `json:"name"`
Options container.StartOptions `json:"options"`
}
type ContainerStopParams ¶
type ContainerStopParams struct {
Name string `json:"name"`
Options container.StopOptions `json:"options"`
}
type ContainerWaitParams ¶
type ContainerWaitParams struct {
Name string `json:"name"`
Condition container.WaitCondition `json:"condition"`
}
type DirEnsureParams ¶
type DiskUsageParams ¶
type DiskUsageParams struct {
Options types.DiskUsageOptions `json:"options"`
}
type Error ¶
Error is a command failure on the wire.
type EventsParams ¶
type EventsParams struct {
Options events.ListOptions `json:"options"`
Filters RawFilters `json:"filters,omitempty"`
}
type ExecToFileParams ¶
type ExecToFileParams struct {
Container string `json:"container"`
Cmd []string `json:"cmd"`
Path string `json:"path"`
Mode uint32 `json:"mode"`
MakeDirs bool `json:"make_dirs,omitempty"`
DirMode uint32 `json:"dir_mode,omitempty"`
Gzip bool `json:"gzip,omitempty"`
}
ExecToFileParams runs Cmd in Container and streams its stdout to Path — gzipped when Gzip is set. The digest and size describe the file as written (compressed), so a later FileHash comparison is byte-exact.
type ExecToFileResult ¶
type FileChownParams ¶
type FileCopyParams ¶
type FileHashParams ¶
type FileHashParams struct {
Path string `json:"path"`
}
type FileHashResult ¶
type FileReadParams ¶
type FileReadResult ¶
type FileRemoveParams ¶
type FileStatParams ¶
type FileStatParams struct {
Path string `json:"path"`
}
type FileStatResult ¶
type FileToExecParams ¶
type FileToExecParams struct {
Path string `json:"path"`
Gunzip bool `json:"gunzip,omitempty"`
Container string `json:"container"`
Cmd []string `json:"cmd"`
}
FileToExecParams streams Path — gunzipped when Gunzip is set — into the stdin of Cmd run in Container.
type FileToExecResult ¶
type FileToURLParams ¶
type FileToURLParams struct {
Path string `json:"path"`
URL string `json:"url"`
Headers map[string]string `json:"headers,omitempty"`
}
FileToURLParams uploads Path to URL with a plain PUT. The URL is presigned by the control plane and travels in this body over the encrypted channel — never argv, never a process list (INV-003).
type FileWriteParams ¶
type FileWriteParams struct {
Path string `json:"path"`
Content []byte `json:"content"`
// Mode is applied explicitly after the write — the agent's umask never
// decides what a key file ends up world-readable as.
Mode uint32 `json:"mode"`
// MakeDirs creates the missing parents with DirMode first.
MakeDirs bool `json:"make_dirs,omitempty"`
DirMode uint32 `json:"dir_mode,omitempty"`
// Atomic stages the content next to Path and renames it into place, so a
// concurrent reader (the proxy, the waker) never sees a partial file.
Atomic bool `json:"atomic,omitempty"`
}
type Frame ¶
type Frame struct {
Type string `json:"type"`
// Observation batching (v1 semantics, unchanged in v2).
Seq int64 `json:"seq,omitempty"`
Observations []Observation `json:"observations,omitempty"`
Denied bool `json:"denied,omitempty"`
// Command traffic (v2).
Cmd *Command `json:"cmd,omitempty"`
Res *Result `json:"res,omitempty"`
Chunk *StreamChunk `json:"chunk,omitempty"`
Cancel int64 `json:"cancel,omitempty"`
}
Frame is one message on the channel, both directions. Exactly one of the role-specific fields is set, per Type.
type ImageBuildParams ¶
type ImageBuildParams struct {
// ContextDir is the build context, a host path under the mounted tree.
ContextDir string `json:"context_dir"`
// Dockerfile is the dockerfile path RELATIVE to ContextDir.
Dockerfile string `json:"dockerfile"`
Tags []string `json:"tags"`
BuildArgs map[string]string `json:"build_args,omitempty"`
Secrets map[string][]byte `json:"secrets,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Target string `json:"target,omitempty"`
NoCache bool `json:"no_cache,omitempty"`
}
ImageBuildParams describes one agent-side BuildKit build (ADR-055). The values that must never become image layers — the secrets — travel in this body over the encrypted channel and are mounted as BuildKit secrets, never exported as ARGs (INV-003, §5.2).
type ImageListParams ¶
type ImageListParams struct {
Options image.ListOptions `json:"options"`
Filters RawFilters `json:"filters,omitempty"`
}
type ImagePullParams ¶
type ImagePullParams struct {
Ref string `json:"ref"`
All bool `json:"all,omitempty"`
RegistryAuth string `json:"registry_auth,omitempty"`
Platform string `json:"platform,omitempty"`
}
ImagePullParams carries the pull WITHOUT the SDK options struct: its PrivilegeFunc field is a func, which encoding/json refuses outright — the same "SDK type unfit for the wire" trap as filters.Args, caught the same day. The executor rebuilds image.PullOptions from these fields.
type ImagePushParams ¶
type ImagePushParams struct {
Ref string `json:"ref"`
All bool `json:"all,omitempty"`
RegistryAuth string `json:"registry_auth,omitempty"`
Platform *ocispec.Platform `json:"platform,omitempty"`
}
ImagePushParams mirrors ImagePullParams for the same reason.
type ImageRemoveParams ¶
type ImageRemoveParams struct {
Image string `json:"image"`
Options image.RemoveOptions `json:"options"`
}
type ImageTagParams ¶
type NameParams ¶
type NameParams struct {
Name string `json:"name"`
}
NameParams serves every method whose only parameter is the object's name or id: ContainerInspect, ContainerStatsOneShot, VolumeInspect, ImageInspect, NetworkRemove, …
type NetworkConnectParams ¶
type NetworkConnectParams struct {
Network string `json:"network"`
Container string `json:"container"`
Config *network.EndpointSettings `json:"config,omitempty"`
}
type NetworkCreateParams ¶
type NetworkCreateParams struct {
Name string `json:"name"`
Options network.CreateOptions `json:"options"`
}
type NetworkDisconnectParams ¶
type NetworkInspectParams ¶
type NetworkInspectParams struct {
Network string `json:"network"`
Options network.InspectOptions `json:"options"`
}
type NetworkListParams ¶
type NetworkListParams struct {
Options network.ListOptions `json:"options"`
Filters RawFilters `json:"filters,omitempty"`
}
type Observation ¶
type Observation struct {
Type string `json:"type"`
At time.Time `json:"at"`
Container string `json:"container,omitempty"`
State string `json:"state,omitempty"`
ResourceUUID string `json:"resource_uuid,omitempty"`
}
Observation is one pushed fact (ADR-040). Types: "container_state" (a managed container changed state), "stz_woken" (a wake started containers), "heartbeat" (the agent is alive).
type PruneParams ¶
type PruneParams struct {
Filters RawFilters `json:"filters"`
}
PruneParams serves every *sPrune method.
type RawFilters ¶
type RawFilters string
RawFilters is filters.Args in the SDK's canonical wire string (filters.ToJSON) — the ONLY form that survives a JSON round-trip; see the params comment above for why the SDK type itself does not.
func EncodeFilters ¶
func EncodeFilters(f filters.Args) RawFilters
EncodeFilters renders args for the wire; an empty set encodes empty.
type RegistryLoginParams ¶
type RegistryLoginParams struct {
Auth registry.AuthConfig `json:"auth"`
}
type Result ¶
type Result struct {
ID int64 `json:"id"`
Body json.RawMessage `json:"body,omitempty"`
Err *Error `json:"error,omitempty"`
}
Result answers the command with the same ID: a body (the method's return value as JSON) or an error, never both. A streaming method's Result only acknowledges the open; its output arrives as StreamChunks and its end as a chunk with EOF or Err set.
type StatsResult ¶
StatsResult carries the one-shot stats snapshot: the daemon's OS type and the raw JSON body, re-wrapped into a StatsResponseReader on the caller side.
type StreamChunk ¶
type StreamChunk struct {
ID int64 `json:"id"`
Data []byte `json:"data,omitempty"`
EOF bool `json:"eof,omitempty"`
Err *Error `json:"error,omitempty"`
}
StreamChunk is one piece of a command's output stream. Data is raw bytes (base64 on the wire); EOF marks a clean end, Err a broken one.
type URLToFileParams ¶
type URLToFileParams struct {
URL string `json:"url"`
Path string `json:"path"`
Mode uint32 `json:"mode"`
MakeDirs bool `json:"make_dirs,omitempty"`
DirMode uint32 `json:"dir_mode,omitempty"`
}
URLToFileParams downloads URL into Path.
type VolumeCreateParams ¶
type VolumeCreateParams struct {
Options volume.CreateOptions `json:"options"`
}
type VolumeListParams ¶
type VolumeListParams struct {
Options volume.ListOptions `json:"options"`
Filters RawFilters `json:"filters,omitempty"`
}