docker

package
v1.6.3 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: AGPL-3.0 Imports: 32 Imported by: 0

Documentation

Overview

Package docker is the sole adapter over the Docker Engine SDK. Services depend on the Client interface (not the SDK), keeping the rest of the codebase free of Docker SDK types.

Index

Constants

View Source
const (
	// LabelPrefix namespaces every platform-applied Docker label.
	LabelPrefix = "io.miabi."

	LabelApp         = "io.miabi.app"          // application id
	LabelDeployment  = "io.miabi.deployment"   // deployment id
	LabelDatabase    = "io.miabi.database"     // database instance id
	LabelStack       = "io.miabi.stack"        // stack id
	LabelVolume      = "io.miabi.volume"       // volume id
	LabelJob         = "io.miabi.job"          // one-shot job container (transient)
	LabelRole        = "io.miabi.role"         // platform-infra role (node-gateway, …)
	LabelNode        = "io.miabi.node"         // node slug
	LabelWorkspace   = "io.miabi.workspace"    // owning workspace id
	LabelManaged     = "io.miabi.managed"      // "true" on managed raw resources/services
	LabelPipelineRun = "io.miabi.pipeline-run" // pipeline run id (transient)
	LabelSizeBytes   = "io.miabi.size_bytes"   // volume size hint

	// LabelPartOf marks a resource as part of the Miabi platform stack
	// (PartOfMiabi). One exact-match key, so the whole stack is a single Docker
	// label filter rather than a scan against a list of roles.
	LabelPartOf = "io.miabi.part-of"
	// LabelManagedBy names who owns the resource's LIFECYCLE — which is not the same
	// question as who it belongs to. A compose-owned container may be observed and
	// updated in place, but recreating it out-of-band is silently reverted by the
	// next `docker compose up -d`.
	LabelManagedBy = "io.miabi.managed-by"
	// LabelProtected ("true") refuses ad-hoc destructive operations from the generic
	// containers list. Declared, never inferred: platform infrastructure is not
	// automatically undeletable (a transient GC container is infra too), and a role
	// allowlist in the guard would drift from the roles themselves.
	LabelProtected = "io.miabi.protected"
	// LabelSpecHash fingerprints the run spec a platform component was created from,
	// so `miabi install` can tell "already what the manifest asks for" from "changed"
	// without re-deriving Docker's own normalization of the spec. See
	// services/platformstack.
	LabelSpecHash = "io.miabi.spec-hash"
)

Platform Docker label keys. Every container / volume / service Miabi creates carries a back-reference label to its owning record under the io.miabi.* namespace (reverse-DNS of miabi.io). These are the single source of truth — do not hand-write the string literals elsewhere.

View Source
const (
	// Platform stack (examples/compose/compose.yaml + the agent).
	RoleControlPlane       = "control-plane"
	RolePlatformDB         = "platform-db"
	RolePlatformCache      = "platform-cache"
	RoleGateway            = "gateway" // the central, compose-managed gateway
	RoleAgent              = "agent"
	RoleControlPlaneWorker = "worker" // a split-out `command: ["worker"]` service

	// Infrastructure Miabi provisions itself.
	RoleNodeGateway      = "node-gateway"
	RoleNodeGatewayRedis = "node-gateway-redis"
	RoleRegistry         = "registry"
	RoleRegistryGC       = "registry-gc" // transient: deliberately NOT protected
)

Roles carried by LabelRole. The platform-stack roles are new; the infra roles were already in use as string literals at their call sites and are named here so there is one spelling of each.

View Source
const (
	// ManagedByCompose: created by examples/compose/compose.yaml. Miabi may read it and update
	// it in place, but must write any version change back to the compose env too —
	// otherwise `docker compose up -d` reverts the upgrade.
	ManagedByCompose = "compose"
	// ManagedByMiabi: Miabi created it and may freely recreate it.
	ManagedByMiabi = "miabi"
	// ManagedByExternal: installed out-of-band (install-agent.sh on a node Miabi
	// does not otherwise control).
	ManagedByExternal = "external"
)

Lifecycle owners for LabelManagedBy.

View Source
const ManagedLabel = LabelManaged

ManagedLabel marks resources created by Miabi (kept as a named alias for the many call sites that tag raw containers/volumes/services).

View Source
const PartOfMiabi = "miabi"

PartOfMiabi is the only value LabelPartOf takes today. Named so call sites read as an identity check rather than a string compare.

Variables

View Source
var ErrNotFound = errors.New("docker: resource not found")

ErrNotFound is returned when a container/image/volume does not exist.

Functions

func IsManaged

func IsManaged(labels map[string]string) bool

IsManaged reports whether a resource carries any platform label — i.e. it is owned by Miabi and must not be a blanket prune/delete target.

func IsPlatformInfra

func IsPlatformInfra(labels map[string]string) bool

IsPlatformInfra reports whether a resource is platform infrastructure (carries a role label) — the node's edge gateway / its Redis. Such resources are managed through their own pages, never reclaimed or hidden as "someone else's".

func IsPlatformStack added in v1.4.0

func IsPlatformStack(labels map[string]string) bool

IsPlatformStack reports whether a resource is part of Miabi's own stack — the control plane, its database/cache, the central gateway, an agent. Such resources are never offered for import (Miabi would end up "managing" its own database) and are never treated as a user's container.

func IsProtected added in v1.4.0

func IsProtected(labels map[string]string) bool

IsProtected reports whether destructive operations (stop/restart/remove) must be refused on a resource. Distinct from IsPlatformInfra: infra is "do not reclaim as an orphan", protected is "do not let a human break the platform by accident".

func IsReservedLabelKey

func IsReservedLabelKey(key string) bool

IsReservedLabelKey reports whether key is platform-reserved — i.e. a user is not allowed to set it as a custom container label.

func LabelValue

func LabelValue(labels map[string]string, key string) (value string, ok bool)

LabelValue reads a platform label by its io.miabi.* key. ok is false when the label is absent.

func ManagedBy added in v1.4.0

func ManagedBy(labels map[string]string) string

ManagedBy returns the resource's lifecycle owner (compose / miabi / external), or "" when unlabeled — e.g. a stack installed before platform labels existed.

func PlatformLabels added in v1.4.0

func PlatformLabels(role, managedBy string, extra map[string]string) map[string]string

PlatformLabels is the label set every Miabi platform component carries. Use it rather than hand-writing the keys, so a component can never end up half-labeled — e.g. discoverable but not protected.

extra is merged last and may add component-specific keys (a node slug, an owning workspace); it may not override the four keys set here.

func SanitizeUserLabels

func SanitizeUserLabels(in map[string]string) map[string]string

SanitizeUserLabels returns a copy of in with every reserved key removed, so user-supplied container labels can never set or spoof a platform label. Keys with an empty name are dropped. nil in → nil out.

func WorkspaceID

func WorkspaceID(labels map[string]string) (id uint, ok bool)

WorkspaceID returns the owning workspace id encoded in a resource's labels. ok is false when there is no (valid) workspace label — e.g. raw/system containers or platform infrastructure.

Types

type BindMount

type BindMount struct {
	Source   string // host path
	Target   string // container path
	ReadOnly bool
}

BindMount is a host path bound into a container.

type Client

type Client interface {
	// Ping verifies the daemon is reachable.
	Ping(ctx context.Context) error
	// Info returns engine information.
	Info(ctx context.Context) (Info, error)

	// Containers.
	ListContainers(ctx context.Context, all bool) ([]Container, error)
	InspectContainer(ctx context.Context, id string) (Container, error)
	// InspectContainerConfig returns the full runtime configuration of a container
	// (env, mounts, command, limits, restart policy) for adopting it as an app.
	InspectContainerConfig(ctx context.Context, id string) (ContainerConfig, error)
	RunContainer(ctx context.Context, spec RunSpec) (string, error)
	StartContainer(ctx context.Context, id string) error
	StopContainer(ctx context.Context, id string, timeoutSeconds int) error
	RestartContainer(ctx context.Context, id string, timeoutSeconds int) error
	RemoveContainer(ctx context.Context, id string, force bool) error

	// RunOneShot runs a container to completion and returns its exit code and
	// combined logs, then removes it. Used for backup/restore jobs.
	RunOneShot(ctx context.Context, spec RunSpec) (exitCode int, logs string, err error)

	// RunOneShotStream runs a container to completion like RunOneShot, but streams
	// its combined output to sink line-by-line as it runs (live logs) instead of
	// returning the buffered logs. Used by the buildpack build provider.
	RunOneShotStream(ctx context.Context, spec RunSpec, sink func(LogLine) error) (exitCode int, err error)

	// ReadContainerFile reads a single file at path from inside a container's
	// filesystem (size-capped). Used to copy an imported gateway's config.
	ReadContainerFile(ctx context.Context, containerID, path string) ([]byte, error)

	// CopyFileFromVolume reads a single file from a named volume by mounting it
	// into a short-lived (never started) helper container created from image,
	// and returns the file's contents and size. The returned reader must be
	// closed by the caller; closing it also removes the helper container.
	CopyFileFromVolume(ctx context.Context, volume, image, file string) (rc io.ReadCloser, size int64, err error)

	// CopyToVolume streams content (a tar-able single file of the given size) into
	// name inside a named volume, by mounting it into a short-lived helper. Used
	// to land an uploaded dump on a node's backup volume. image must be present.
	CopyToVolume(ctx context.Context, volume, image, name string, content io.Reader, size int64) error

	// DialNetwork opens a raw, bidirectional TCP byte stream to host:port as
	// reachable from containers on the given Docker network. It runs an ephemeral
	// relay (socat, from image) attached to that network and bridges its stdio
	// over the engine connection, so it works the same on a local engine and a
	// remote (tunneled) one — no host port is ever published. image must already
	// be present on the node. Closing the returned conn stops and removes the
	// relay container.
	DialNetwork(ctx context.Context, network, image, host string, port int) (net.Conn, error)

	// Images. auth may be nil for anonymous (public) pulls.
	PullImage(ctx context.Context, ref string, auth *RegistryAuth) error
	// TagImage adds target as an additional tag for the local source image.
	TagImage(ctx context.Context, source, target string) error
	// PushImage pushes a local image ref to its registry. auth may be nil.
	PushImage(ctx context.Context, ref string, auth *RegistryAuth) error
	// BuildImage builds an image from a local context directory, streaming
	// build output to sink, and tags it.
	BuildImage(ctx context.Context, contextDir, dockerfile, tag string, sink func(LogLine) error) error
	// InspectImage returns a local image's identity (ID + digest) and size.
	InspectImage(ctx context.Context, ref string) (ImageInspect, error)
	// ImageExists reports whether ref is present locally (no pull).
	ImageExists(ctx context.Context, ref string) (bool, error)
	// RemoveImage deletes a local image by reference (tag or id). force removes
	// it even if tagged/referenced; a not-found image is treated as success.
	RemoveImage(ctx context.Context, ref string, force bool) error

	// Housekeeping (reclaim & report). ListImages enumerates local images with
	// usage signals; DiskUsage is a `docker system df`-style breakdown. The Prune*
	// calls reclaim disk and report what was freed — they target only the safe set
	// (dangling images, the build cache); callers apply their own managed-resource
	// guards on top.
	ListImages(ctx context.Context) ([]Image, error)
	DiskUsage(ctx context.Context) (DiskUsage, error)
	VolumeUsage(ctx context.Context) ([]VolumeUsage, error)
	PruneImages(ctx context.Context, opts PruneImagesOptions) (PruneReport, error)
	PruneBuildCache(ctx context.Context) (PruneReport, error)

	// StreamEvents streams Docker daemon events for Miabi-managed
	// containers until the context is cancelled or an error occurs.
	StreamEvents(ctx context.Context, sink func(EngineEvent) error) error

	// Exec starts an interactive command inside a running container and returns
	// a bidirectional stream to it (used for the in-panel shell). Callers must
	// Close the returned stream.
	Exec(ctx context.Context, containerID string, opts ExecOptions) (ExecStream, error)

	// Top lists the running processes in a container (the "docker top" view).
	// psArgs are ps flags (e.g. "aux"); blank uses the daemon default. Read-only.
	Top(ctx context.Context, containerID, psArgs string) (ProcessList, error)

	// Streaming. The sink is invoked per item; return a non-nil error to stop.
	StreamLogs(ctx context.Context, id string, follow bool, tail string, sink func(LogLine) error) error
	StreamStats(ctx context.Context, id string, sink func(StatsSample) error) error
	// StatsOnce returns a single resource-usage sample.
	StatsOnce(ctx context.Context, id string) (StatsSample, error)

	// Networks & volumes.
	EnsureNetwork(ctx context.Context, name string) (string, error)
	CreateNetwork(ctx context.Context, name, driver string, internal bool) (string, error)
	// CreateNetworkSpec creates a managed network with explicit options, including
	// an optional IPAM Subnet/Gateway (Miabi-allocated) so creation does not draw
	// from Docker's small built-in address pools. Always creates (errors if the
	// name exists); EnsureNetworkSpec is the create-or-reuse variant.
	CreateNetworkSpec(ctx context.Context, spec NetworkSpec) (string, error)
	EnsureNetworkSpec(ctx context.Context, spec NetworkSpec) (string, error)
	RemoveNetwork(ctx context.Context, name string) error
	ListNetworks(ctx context.Context) ([]Network, error)
	// NetworkConnect attaches a running container to a network with optional DNS
	// aliases; idempotent (no-op if already attached). NetworkDisconnect detaches
	// it; idempotent (no-op if not attached). Used to keep only route-exposed apps
	// on the shared reverse-proxy network.
	NetworkConnect(ctx context.Context, name, containerID string, aliases []string) error
	NetworkDisconnect(ctx context.Context, name, containerID string, force bool) error
	CreateVolume(ctx context.Context, name string, labels map[string]string, sizeBytes int64) (Volume, error)
	// CreateVolumeWith creates a managed volume with an explicit driver and driver
	// options (shared storage: nfs/cifs). An empty Driver uses the local default.
	CreateVolumeWith(ctx context.Context, spec VolumeSpec) (Volume, error)
	ListVolumes(ctx context.Context) ([]Volume, error)
	InspectVolume(ctx context.Context, name string) (Volume, error)
	RemoveVolume(ctx context.Context, name string, force bool) error

	// Swarm. Miabi drives Docker Swarm as an internal implementation detail of
	// cluster mode; users never run docker swarm/service themselves. Swarm reads
	// the engine's swarm state from `docker info` (works on any node); the rest
	// require a reachable manager and are no-ops on plain Docker.
	Swarm(ctx context.Context) (SwarmInfo, error)
	SwarmInit(ctx context.Context, req SwarmInitRequest) (nodeID string, err error)
	SwarmJoin(ctx context.Context, req SwarmJoinRequest) error
	SwarmLeave(ctx context.Context, force bool) error
	SwarmJoinTokens(ctx context.Context) (SwarmJoinTokens, error)
	SwarmNodes(ctx context.Context) ([]SwarmNode, error)
	SwarmNodeRemove(ctx context.Context, nodeID string, force bool) error
	// SwarmNodeAvailability sets a node's scheduling availability (active | pause |
	// drain). Drain is what makes a node safe to reboot — it reschedules the node's
	// tasks away instead of letting Swarm keep placing onto a host that is going down.
	SwarmNodeAvailability(ctx context.Context, nodeID, availability string) error
	// SwarmTasks lists the swarm's tasks (all, or one node's). Only the manager can:
	// the containers live on the nodes, which Miabi may hold no Docker client for.
	SwarmTasks(ctx context.Context, nodeID string) ([]SwarmTask, error)

	// Swarm services (cluster apps). Require a reachable manager; cluster deploys
	// call these instead of RunContainer. CreateOverlayNetwork ensures the
	// per-workspace overlay an app's service attaches to.
	ServiceCreate(ctx context.Context, spec ServiceSpec) (id string, err error)
	ServiceUpdate(ctx context.Context, idOrName string, spec ServiceSpec) error
	ServiceRemove(ctx context.Context, idOrName string) error
	ServiceScale(ctx context.Context, idOrName string, replicas uint64) error
	ServiceInspect(ctx context.Context, idOrName string) (ServiceStatus, error)
	ServiceList(ctx context.Context) ([]ServiceStatus, error)
	// ServiceRestart forces a rolling restart of a service's tasks in place.
	ServiceRestart(ctx context.Context, idOrName string) error
	// ServiceTaskContainerID resolves a running task container of the named
	// service on this engine, for logs/stats/exec/top. ErrNotFound if none here.
	ServiceTaskContainerID(ctx context.Context, serviceName string) (string, error)
	// ServiceEnv returns a service's environment. It can carry secrets, so it is for
	// the service layer to inspect — never to return to a client.
	ServiceEnv(ctx context.Context, idOrName string) ([]string, error)
	// StreamServiceLogs streams a swarm service's logs from the MANAGER, aggregated
	// across every task wherever it was scheduled. This is the only way to read the
	// logs of a task on a swarm node Miabi has no Docker client for (an unmanaged
	// member with no agent) — the manager pulls them over the swarm control plane.
	StreamServiceLogs(ctx context.Context, serviceName string, follow bool, tail string, sink func(LogLine) error) error
	CreateOverlayNetwork(ctx context.Context, name string) (id string, err error)

	// Close releases the underlying connection.
	Close() error
}

Client is the abstraction the rest of the app depends on.

func New

func New() (Client, error)

New connects to the Docker engine using the standard environment (DOCKER_HOST etc.) with API version negotiation.

func NewRemote

func NewRemote(dial DialFunc) (Client, error)

NewRemote builds a Docker client that talks to a remote engine over an arbitrary transport (the agent tunnel), reusing the same engineClient so every existing service works against a remote node unchanged.

The dummy host scheme ("http://") makes the SDK speak plain HTTP over our transport; the dialer ignores the address and returns a tunnel stream.

func NewSocket

func NewSocket(host string) (Client, error)

NewSocket connects to a Docker engine at a socket/host string (e.g. "unix:///var/run/docker.sock" or "tcp://host:2375" without TLS).

func NewTCP

func NewTCP(host string, tlsm *TLSMaterial) (Client, error)

NewTCP connects to a Docker engine over TCP. With tlsm == nil the connection is plaintext; otherwise it uses TLS (server verification, plus client auth if Cert+Key are present). host is e.g. "tcp://host:2376".

func Offline

func Offline(err error) Client

Offline returns a Client whose every operation fails with err. It lets a node-aware caller resolve a client unconditionally: critical operations surface the error, while best-effort cleanups (whose results are ignored) simply no-op when a node's agent is disconnected.

type Container

type Container struct {
	ID           string             `json:"id"`
	Names        []string           `json:"names"`
	Image        string             `json:"image"`
	State        string             `json:"state"`
	Status       string             `json:"status"`
	Health       string             `json:"health,omitempty"` // "", "starting", "healthy", "unhealthy"
	Restarting   bool               `json:"restarting,omitempty"`
	RestartCount int                `json:"restart_count,omitempty"`
	ExitCode     int                `json:"exit_code,omitempty"`
	StartedAt    string             `json:"started_at,omitempty"` // RFC3339 from inspect
	Created      int64              `json:"created"`
	Ports        []Port             `json:"ports,omitempty"`
	Labels       map[string]string  `json:"labels,omitempty"`
	Networks     []ContainerNetwork `json:"networks,omitempty"` // populated by InspectContainer
}

Container is a summary of a Docker container.

type ContainerConfig

type ContainerConfig struct {
	ID            string            `json:"id"`
	Name          string            `json:"name"`
	Image         string            `json:"image"` // c.Config.Image (repo[:tag])
	State         string            `json:"state"`
	Command       []string          `json:"command,omitempty"`
	Entrypoint    []string          `json:"entrypoint,omitempty"`
	Env           []string          `json:"env,omitempty"` // KEY=VALUE (effective)
	Labels        map[string]string `json:"labels,omitempty"`
	Ports         []PortMapping     `json:"ports,omitempty"`    // published host ports
	Mounts        []ContainerMount  `json:"mounts,omitempty"`   // volume + bind mounts
	Networks      []string          `json:"networks,omitempty"` // attached network names
	RestartPolicy string            `json:"restart_policy"`     // no|always|unless-stopped|on-failure[:N]
	MemoryBytes   int64             `json:"memory_bytes"`
	NanoCPUs      int64             `json:"nano_cpus"`
}

ContainerConfig is the full inspected configuration of a container, used by the import flow to adopt a pre-existing container as a Miabi app. It carries the runtime fields a summary Container omits (env, mounts, command, limits, restart policy).

type ContainerMount

type ContainerMount struct {
	Type        string `json:"type"` // "volume" | "bind" | ...
	Name        string `json:"name,omitempty"`
	Source      string `json:"source,omitempty"`
	Destination string `json:"destination"`
	ReadOnly    bool   `json:"read_only"`
}

ContainerMount is a mount on an inspected container. For Type "volume", Name is the Docker volume name; Source is the host path for binds.

type ContainerNetwork

type ContainerNetwork struct {
	Name      string `json:"name"`
	IPAddress string `json:"ip_address"`
	Gateway   string `json:"gateway,omitempty"`
	// Aliases are the container's DNS aliases on this network. They are the only
	// stable way to address it, so moving a container between networks (see the
	// bridge -> overlay migration in services/network) must carry them across
	// verbatim rather than recomputing them.
	Aliases []string `json:"aliases,omitempty"`
}

ContainerNetwork is a container's attachment to a Docker network (its in-network IP). IPs are ephemeral — they change when the container is recreated; prefer the network alias for stable addressing.

type DialFunc

type DialFunc func(ctx context.Context) (net.Conn, error)

DialFunc opens a new connection to a remote Docker engine. For multi-node, it returns a fresh stream over the node's agent tunnel; each Docker API request gets its own stream so streaming endpoints (logs/stats/events/build) work.

type DiskUsage

type DiskUsage struct {
	Images     DiskUsageCategory `json:"images"`
	Containers DiskUsageCategory `json:"containers"`
	Volumes    DiskUsageCategory `json:"volumes"`
	BuildCache DiskUsageCategory `json:"build_cache"`
}

DiskUsage is a `docker system df`-style breakdown for a node: per-category counts and total vs reclaimable bytes. It drives the housekeeping report.

type DiskUsageCategory

type DiskUsageCategory struct {
	Count       int   `json:"count"`
	Active      int   `json:"active"`
	TotalBytes  int64 `json:"total_bytes"`
	Reclaimable int64 `json:"reclaimable_bytes"`
}

DiskUsageCategory is one row of the disk-usage breakdown. Reclaimable is an upper-bound estimate (it ignores layer sharing between images), matching how `docker system df` reports it.

type EngineEvent

type EngineEvent struct {
	Action      string // start, die, oom, kill, stop, "health_status: healthy", ...
	ContainerID string
	Attributes  map[string]string
}

EngineEvent is a Docker daemon event for a managed container. Attributes carries the container's labels (e.g. "io.miabi.app") and event metadata (e.g. "exitCode").

type ExecOptions

type ExecOptions struct {
	Cmd []string // command + args; e.g. ["/bin/sh"]
	Tty bool     // allocate a pseudo-TTY (raw, un-multiplexed stream)
	Env []string // extra environment, "KEY=VALUE"
}

ExecOptions configures an interactive command run inside a running container.

type ExecStream

type ExecStream interface {
	Read(p []byte) (int, error)
	Write(p []byte) (int, error)
	Resize(ctx context.Context, height, width uint) error
	Close() error
}

ExecStream is a bidirectional stream attached to a running exec instance. With a TTY the byte stream is raw (no stdcopy multiplexing), so Read/Write move terminal bytes directly. Resize adjusts the pseudo-terminal; Close ends the session and releases the underlying connection.

type GPURequest added in v1.2.0

type GPURequest struct {
	DeviceIDs    []string   // resolved GPU UUIDs; nil selects by Count instead
	Count        int        // used only when DeviceIDs is nil (-1 = all devices)
	Capabilities [][]string // e.g. [["gpu"]]
}

GPURequest describes a set of GPU devices to attach to a container via the NVIDIA runtime (Docker DeviceRequests). Either DeviceIDs (resolved GPU UUIDs) pins exact cards, or Count asks for N-any-of-kind (-1 = all). Capabilities is the driver capability set, [["gpu"]] for NVIDIA.

type HealthcheckSpec

type HealthcheckSpec struct {
	Test        []string // e.g. ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
	Interval    time.Duration
	Timeout     time.Duration
	Retries     int
	StartPeriod time.Duration
}

HealthcheckSpec configures a container healthcheck (Docker HEALTHCHECK).

type Image

type Image struct {
	ID          string            `json:"id"`
	RepoTags    []string          `json:"repo_tags,omitempty"`
	RepoDigests []string          `json:"repo_digests,omitempty"`
	Size        int64             `json:"size"`
	SharedSize  int64             `json:"shared_size"`
	Created     int64             `json:"created"`
	Containers  int64             `json:"containers"` // -1 when the daemon did not compute it
	Dangling    bool              `json:"dangling"`   // untagged (<none>:<none>)
	Labels      map[string]string `json:"labels,omitempty"`
}

Image summarizes a local Docker image, with the references and usage signals the housekeeping report needs (whether a container uses it, whether it is dangling/untagged).

type ImageInspect

type ImageInspect struct {
	ID     string `json:"id"`     // content-addressable image ID (sha256:…)
	Digest string `json:"digest"` // repo digest when present, else the image ID
	Size   int64  `json:"size"`
}

ImageInspect is a built or pulled image's identity and size, returned by InspectImage. Digest is the registry repo-digest (sha256:…) when the image carries one; for a locally-built, never-pushed image it falls back to the content-addressable image ID, which is a stable local handle for deploy-by- digest on a single node.

type Info

type Info struct {
	// Name is the Docker host's hostname (the actual machine name, not the
	// Miabi container's), as reported by the daemon.
	Name          string `json:"name"`
	Version       string `json:"version"`
	APIVersion    string `json:"api_version"`
	OS            string `json:"os"`
	Arch          string `json:"arch"`
	Containers    int    `json:"containers"`
	ContainersRun int    `json:"containers_running"`
	Images        int    `json:"images"`
	CPUs          int    `json:"cpus"`
	MemTotal      int64  `json:"mem_total"`
	// Runtimes are the container runtimes the daemon advertises (docker info).
	// The "nvidia" key is present exactly when the NVIDIA Container Toolkit is
	// installed, so it is how the control plane decides a node is GPU-capable
	// before ever probing it.
	Runtimes []string `json:"runtimes,omitempty"`
}

Info summarizes the Docker engine.

type LogLine

type LogLine struct {
	Stream string `json:"stream"` // "stdout" | "stderr"
	Text   string `json:"text"`
}

LogLine is a single demultiplexed log line.

type Network

type Network struct {
	ID     string            `json:"id"`
	Name   string            `json:"name"`
	Driver string            `json:"driver"`
	Scope  string            `json:"scope"`
	Labels map[string]string `json:"labels,omitempty"`
	// Subnet is the network's first IPAM subnet (CIDR), empty if unset. Used by the
	// subnet allocator to reserve pool subnets already in use by existing networks.
	Subnet string `json:"subnet,omitempty"`
}

Network summarizes a Docker network.

type NetworkSpec

type NetworkSpec struct {
	Name       string
	Driver     string // "" = bridge; "overlay" for swarm
	Internal   bool
	Attachable bool // overlay networks that standalone containers may join
	Encrypted  bool // overlay data-plane encryption
	Subnet     string
	Gateway    string
	Labels     map[string]string
}

NetworkSpec describes a managed network to create. An empty Driver defaults to "bridge". Subnet/Gateway, when set, are passed as explicit IPAM so creation does not draw from Docker's built-in default-address-pools.

type Port

type Port struct {
	PrivatePort uint16 `json:"private_port"`
	PublicPort  uint16 `json:"public_port,omitempty"`
	Protocol    string `json:"protocol"`
}

Port maps a container port to a host port.

type PortMapping

type PortMapping struct {
	ContainerPort int    `json:"container_port"`
	Protocol      string `json:"protocol"`
	HostPort      int    `json:"host_port,omitempty"`
}

PortMapping is a container port and the host port it is published on (0 = not published).

type ProcessList

type ProcessList struct {
	Titles    []string   `json:"titles"`
	Processes [][]string `json:"processes"`
}

ProcessList is the running processes in a container (the "docker top" view): column titles and one row of cells per process. Sourced from the host's ps, so it works even for images that ship no ps binary.

type PruneImagesOptions

type PruneImagesOptions struct {
	Dangling bool   // true: only dangling images; false: all unused images
	Until    string // optional max-age filter (Go duration, e.g. "168h"); "" = no age limit
}

PruneImagesOptions selects what an image prune targets. Dangling restricts the prune to untagged (`<none>`) images, which are always safe to remove; the all-unused mode requires the caller's referenced-image guard and is not used by the safe default flow.

type PruneReport

type PruneReport struct {
	ItemsDeleted   []string `json:"items_deleted,omitempty"`
	SpaceReclaimed int64    `json:"space_reclaimed"`
}

PruneReport is the outcome of a prune: what was removed and the bytes freed.

type RegistryAuth

type RegistryAuth struct {
	Server   string // registry host, e.g. registry-1.docker.io, ghcr.io
	Username string
	Password string
}

RegistryAuth holds credentials for pulling from a private registry.

type RunSpec

type RunSpec struct {
	Name       string
	Image      string
	Hostname   string   // container hostname (uname -n); blank = Docker default
	Env        []string // KEY=VALUE
	Entrypoint []string // optional entrypoint override
	Cmd        []string // optional command override
	// WorkingDir sets the container's working directory (Docker WORKDIR). Blank
	// uses the image default. Pipeline steps set it to the shared workspace
	// (/workspace) so commands run against the checked-out repository.
	WorkingDir string
	Labels     map[string]string
	Networks   []string // networks to attach
	// NetworkAliases are DNS aliases applied on each attached network, giving
	// the container a stable name the reverse proxy can target across deploys.
	NetworkAliases []string
	// AliasesByNetwork sets extra DNS aliases on specific networks only (network
	// name -> aliases). Used to expose an app by its service name within its
	// stack network without leaking that name onto the shared gateway network.
	AliasesByNetwork map[string][]string
	// Ports maps "containerPort/proto" -> "hostPort" (e.g. "80/tcp" -> "8080").
	Ports map[string]string
	// PortBindIPs optionally maps "containerPort/proto" -> host bind IP, to publish
	// a port on a specific interface (e.g. a node's private address) instead of
	// 0.0.0.0. Keys match Ports; a missing/empty entry means all interfaces.
	PortBindIPs map[string]string
	// Mounts maps volume name -> container path.
	Mounts map[string]string
	// Binds are host path -> container path bind mounts. Used only for
	// allow-listed privileged host mounts (e.g. the Docker socket); the source
	// is a server-resolved host path, never client input.
	Binds []BindMount
	// Resource limits (0 = unlimited).
	MemoryBytes int64
	NanoCPUs    int64
	// GPUs requests whole-device GPU access via the NVIDIA runtime. Empty = none.
	// Each entry either pins specific devices by UUID (DeviceIDs) or asks for N
	// of any kind (Count); -1 Count means "all GPUs" (used by the inventory probe).
	GPUs []GPURequest
	// RestartPolicy is the Docker restart policy ("no", "always",
	// "unless-stopped", "on-failure"). Empty defaults to "unless-stopped".
	RestartPolicy string
	// Healthcheck is the container health probe; nil disables it.
	Healthcheck *HealthcheckSpec
	// Container security (restricted security profile). User overrides the user
	// the container runs as ("uid", "uid:gid", or a name); empty = the image's
	// default user. NoNewPrivileges sets the no-new-privileges securityOpt;
	// CapDrop drops the listed Linux capabilities (e.g. "NET_RAW").
	User            string
	NoNewPrivileges bool
	CapDrop         []string
	// GroupAdd are supplementary groups (Docker --group-add), by GID or name. The
	// control plane needs the host's "docker" group to read /var/run/docker.sock when
	// it does not run as root — the same thing compose.yaml's `group_add` does.
	GroupAdd []string
}

RunSpec describes a container to create and start.

type ServiceBind

type ServiceBind struct {
	Source   string // host path (present on every node)
	Target   string // container path
	ReadOnly bool
}

ServiceBind is a host-path bind mount for a swarm service task (mount.TypeBind).

type ServiceMountDriver

type ServiceMountDriver struct {
	Name    string
	Options map[string]string
}

ServiceMountDriver is the Docker volume driver config for a service mount, so every node a task lands on materializes the SAME backing volume (e.g. an NFS/CIFS share) rather than an empty local one. Name is the Docker volume driver ("local" for Miabi's nfs/cifs, which use the built-in local driver with mount options); Options are the mount options (type, device, o, …).

type ServiceSpec

type ServiceSpec struct {
	Name     string
	Image    string
	Env      []string // KEY=VALUE
	Cmd      []string // command args (ContainerSpec.Args); nil keeps the image default
	Replicas uint64   // 0 is treated as 1 (ignored when Global)
	// Global runs exactly one task on EVERY node the constraints allow, including
	// nodes that join later. It is how a per-node daemon is deployed to a swarm
	// without touching each host: the scheduler ships it, and keeps shipping it.
	Global         bool
	Networks       []string          // swarm-scoped (overlay) network names to attach
	NetworkAliases []string          // DNS aliases applied on each attached network
	Mounts         map[string]string // volume name -> container path
	// MountDrivers carries the volume driver config for a mount, keyed by volume
	// (source) name. It is REQUIRED for shared (nfs/cifs) volumes on a replicated
	// service: without it, a task landing on a node that lacks the volume makes an
	// empty *local* volume of the same name instead of mounting the real share, so
	// the "shared" storage silently diverges per node. Omit for node-local volumes.
	MountDrivers map[string]ServiceMountDriver
	// Binds are host-path bind mounts (mount.TypeBind) for operator-managed storage
	// present at the SAME path on every node (a host-path volume under /mnt/*).
	// Unlike Mounts (Docker named volumes) they need no driver config — the path is
	// assumed present on each node the scheduler places a task on.
	Binds       []ServiceBind
	Labels      map[string]string
	MemoryBytes int64
	NanoCPUs    int64
	// Constraints are Swarm placement constraints, e.g. "node.role==worker" or
	// "node.id==abc" (pin to a node).
	Constraints []string
	Healthcheck *HealthcheckSpec
	User        string
	// Rolling update tuning (0 = Swarm defaults).
	UpdateParallelism uint64
	UpdateDelay       time.Duration
	// RegistryAuth authenticates the swarm to a private registry when creating or
	// updating the service. It is encoded into the request so the manager can
	// resolve the image AND distributed to worker nodes, so their tasks can pull it
	// too (the daemon equivalent of `docker service create --with-registry-auth`).
	// Required for the built-in registry and any private registry — without it a
	// worker task fails to pull. nil for public images.
	RegistryAuth *RegistryAuth
	// IngressNetwork is an additional attachable overlay the service joins with
	// only IngressAlias registered on it — the shared ingress network the central
	// gateway uses to reach the service VIP. It is kept separate from Networks so
	// the tenant-scoped east-west aliases (NetworkAliases, e.g. the app name) are
	// NOT registered on this shared network, where they would collide across
	// workspaces. Empty disables it.
	IngressNetwork string
	IngressAlias   string
}

ServiceSpec describes a replicated Swarm service to create or update. It is the cluster-mode analogue of RunSpec: same image/env/mounts/limits, plus replicas, placement constraints, and rolling-update tuning. Swarm schedules the tasks and load-balances a virtual IP across them.

type ServiceStatus

type ServiceStatus struct {
	ID           string `json:"id"`
	Name         string `json:"name"`
	Image        string `json:"image,omitempty"`
	Replicas     uint64 `json:"replicas"`      // desired
	RunningTasks uint64 `json:"running_tasks"` // currently running
	// Placement maps a swarm node id -> the count of this service's tasks running
	// on that node. Populated by ServiceInspect so callers can show where the
	// scheduler actually placed the replicas (nil until inspected).
	Placement map[string]int `json:"placement,omitempty"`
	// StartedAt (RFC3339) is when the service's longest-running task entered the
	// running state — the service's uptime. It comes from the swarm control plane,
	// so it is known even for a task on a node Miabi has no Docker client for, where
	// inspecting the container is impossible.
	StartedAt string `json:"started_at,omitempty"`
}

ServiceStatus summarizes a Swarm service: its identity, desired replica count, and how many tasks are currently running (used to gate a deploy on convergence).

type StatsSample

type StatsSample struct {
	CPUPercent     float64 `json:"cpu_percent"`
	MemoryUsage    uint64  `json:"memory_usage_bytes"`
	MemoryLimit    uint64  `json:"memory_limit_bytes"`
	MemoryPercent  float64 `json:"memory_percent"`
	NetworkRxBytes uint64  `json:"network_rx_bytes"`
	NetworkTxBytes uint64  `json:"network_tx_bytes"`
}

StatsSample is a point-in-time resource usage sample for a container.

type SwarmInfo

type SwarmInfo struct {
	// LocalNodeState is the engine's swarm state: inactive | pending | active |
	// error | locked. "inactive" means plain (non-swarm) Docker.
	LocalNodeState string `json:"local_node_state"`
	// ControlAvailable is true when this engine is a reachable swarm manager
	// (i.e. it can drive cluster operations).
	ControlAvailable bool `json:"control_available"`
	// NodeID / NodeAddr identify this engine within the swarm; NodeAddr is the
	// address it advertises to peers (used as the join remote-address).
	NodeID   string `json:"node_id"`
	NodeAddr string `json:"node_addr"`
	// Managers / Nodes are cluster-wide counts (manager-reported; 0 elsewhere).
	Managers int `json:"managers"`
	Nodes    int `json:"nodes"`
	// RemoteManagers are the advertised addresses of the swarm's managers.
	RemoteManagers []string `json:"remote_managers,omitempty"`
	// Error carries the engine's swarm error string when LocalNodeState == error.
	Error string `json:"error,omitempty"`
}

SwarmInfo summarizes an engine's participation in a Docker Swarm, as reported by `docker info`. It is available on any engine (no manager role required), so it is the cheap signal Miabi uses to auto-detect cluster mode.

type SwarmInitRequest

type SwarmInitRequest struct {
	// AdvertiseAddr is the address managers/workers reach this manager on
	// (host or host:port). Required.
	AdvertiseAddr string
	// ListenAddr is the management-plane bind; blank defaults to 0.0.0.0:2377.
	ListenAddr string
	// DataPathAddr is the address for overlay (VXLAN) data-plane traffic; blank
	// falls back to AdvertiseAddr.
	DataPathAddr string
}

SwarmInitRequest configures putting an engine into swarm mode as a manager.

type SwarmJoinRequest

type SwarmJoinRequest struct {
	// RemoteAddrs are the manager addresses to dial (host:port).
	RemoteAddrs []string
	// JoinToken is the worker or manager join token.
	JoinToken string
	// AdvertiseAddr is the address this node advertises to peers; blank lets the
	// engine auto-detect.
	AdvertiseAddr string
	// ListenAddr is the management-plane bind; blank defaults to 0.0.0.0:2377.
	ListenAddr string
}

SwarmJoinRequest configures joining an engine to an existing swarm.

type SwarmJoinTokens

type SwarmJoinTokens struct {
	Worker  string `json:"worker"`
	Manager string `json:"manager"`
}

SwarmJoinTokens are the secrets a node uses to join a swarm in either role.

type SwarmNode

type SwarmNode struct {
	ID            string `json:"id"`
	Hostname      string `json:"hostname"`
	Role          string `json:"role"`         // manager | worker
	Availability  string `json:"availability"` // active | pause | drain
	State         string `json:"state"`        // ready | down | unknown | disconnected
	Leader        bool   `json:"leader"`
	Reachability  string `json:"reachability,omitempty"` // reachable | unreachable (managers)
	Addr          string `json:"addr,omitempty"`
	EngineVersion string `json:"engine_version,omitempty"`
	// Capacity as the swarm scheduler sees it — what it packs tasks against. It comes
	// from the node's own report over the swarm control plane, so it is known even for
	// a node Miabi has no Docker client for (an unmanaged member with no agent), where
	// host metrics are otherwise unavailable.
	NanoCPUs    int64  `json:"nano_cpus,omitempty"`    // 1e9 == one core
	MemoryBytes int64  `json:"memory_bytes,omitempty"` // total, not used
	OS          string `json:"os,omitempty"`           // linux | windows
	Arch        string `json:"arch,omitempty"`         // x86_64 | aarch64 | …
	// Tasks is how many service tasks the scheduler currently runs here — the node's
	// load. Populated by SwarmNodes; 0 for an idle node.
	Tasks int `json:"tasks"`
}

SwarmNode is one node as seen from a swarm manager (`docker node ls`).

type SwarmTask added in v1.3.0

type SwarmTask struct {
	ID           string `json:"id"`
	ServiceName  string `json:"service_name"`
	NodeID       string `json:"node_id"`
	Image        string `json:"image,omitempty"`
	Slot         int    `json:"slot,omitempty"`
	State        string `json:"state"`         // running | preparing | failed | …
	DesiredState string `json:"desired_state"` // running | shutdown
	Message      string `json:"message,omitempty"`
	Err          string `json:"error,omitempty"`
	UpdatedAt    string `json:"updated_at,omitempty"` // RFC3339
}

SwarmTask is one task (a container the scheduler placed) of a service, as seen from a manager. It is how a node's real workload is enumerated: the container itself lives on the node, which Miabi may hold no Docker client for.

type TLSMaterial

type TLSMaterial struct {
	CACert []byte
	Cert   []byte
	Key    []byte
}

TLSMaterial holds PEM-encoded TLS material for a TCP Docker endpoint. A nil *TLSMaterial means a plaintext connection. CACert alone enables server verification; Cert+Key add client authentication (mTLS).

type Volume

type Volume struct {
	Name       string            `json:"name"`
	Driver     string            `json:"driver"`
	Mountpoint string            `json:"mountpoint"`
	CreatedAt  string            `json:"created_at,omitempty"`
	Labels     map[string]string `json:"labels,omitempty"`
}

Volume summarizes a Docker volume.

type VolumeSpec

type VolumeSpec struct {
	Name       string
	Labels     map[string]string
	SizeBytes  int64
	Driver     string
	DriverOpts map[string]string
}

VolumeSpec describes a managed volume to create, including an optional driver and driver options for shared storage (NFS/CIFS). An empty Driver uses Docker's default (local) driver. DriverOpts are the backend mount options (e.g. NFS: type=nfs, o=addr=…,rw, device=:/export).

type VolumeUsage

type VolumeUsage struct {
	DockerName string `json:"docker_name"`
	Bytes      int64  `json:"bytes"`
	RefCount   int    `json:"ref_count"`
}

VolumeUsage is one Docker volume's measured on-disk size, keyed by name so it joins to a workspace's Volume rows. RefCount 0 = reclaimable.

Jump to

Keyboard shortcuts

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