podman

package
v1.0.26 Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2026 License: MIT Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const MinPodmanVersion = "5.6.0"

MinPodmanVersion is the floor for managed hosts. Cold-copy migrate streams volumes through libpod's GET /volumes/{name}/export and volumes.Import, which first shipped in podman 5.6.0 — on older hosts the export 404s mid-migration. The preflight turns that into a clear setup error (#85).

Variables

View Source
var ErrHostVersionUnsupported = errors.New("host podman version unsupported")

ErrHostVersionUnsupported marks a host whose podman is below MinPodmanVersion (or whose version cannot be parsed, which fails closed).

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

ErrNotFound is returned when a pod, container, secret, or volume isn't present.

Functions

This section is empty.

Types

type Client

type Client interface {
	// Pods
	PlayKube(ctx context.Context, hostID, yaml string, replace bool, networks ...string) error
	PodInspect(ctx context.Context, hostID, name string) (Pod, error)
	PodList(ctx context.Context, hostID string, labelFilters map[string]string) ([]Pod, error)
	PodStart(ctx context.Context, hostID, name string) error
	PodStop(ctx context.Context, hostID, name string) error
	PodRestart(ctx context.Context, hostID, name string) error
	PodRemove(ctx context.Context, hostID, name string, force bool) error

	// Secrets
	SecretCreate(ctx context.Context, hostID, name string, value []byte) error
	SecretList(ctx context.Context, hostID string) ([]Secret, error)
	SecretInspect(ctx context.Context, hostID, name string) (Secret, error)
	SecretRemove(ctx context.Context, hostID, name string) error

	// Volumes
	VolumeInspect(ctx context.Context, hostID, name string) (Volume, error)
	VolumeRemove(ctx context.Context, hostID, name string, force bool) error
	// VolumeExport streams the named volume's contents from host as an
	// uncompressed tar. The caller must Close the returned reader.
	VolumeExport(ctx context.Context, hostID, name string) (io.ReadCloser, error)
	// VolumeImport unpacks an uncompressed tar (as produced by VolumeExport)
	// into the named volume on host. The volume must already exist.
	VolumeImport(ctx context.Context, hostID, name string, r io.Reader) error
	// VolumeCreate creates an empty named volume on host. Creating a volume that
	// already exists is a no-op (no error).
	VolumeCreate(ctx context.Context, hostID, name string) error

	// Networks
	// NetworkEnsure creates the named network if absent; creating one that
	// already exists is a no-op (no error).
	NetworkEnsure(ctx context.Context, hostID, name string) error

	// Exec
	// ContainerExec runs cmd in the named running container and returns its
	// exit code and combined stdout+stderr. A non-zero exit code is NOT an
	// error; only a transport/podman failure returns a non-nil error.
	ContainerExec(ctx context.Context, hostID, container string, cmd []string) (ExecResult, error)
	// CopyToContainer writes content as a single file `name` into directory
	// `destDir` inside the running container (e.g. destDir="/etc/caddy",
	// name="Caddyfile"). destDir must already exist in the container.
	CopyToContainer(ctx context.Context, hostID, container, destDir, name string, content []byte) error

	// Logs
	ContainerLogs(ctx context.Context, hostID, container string, opts LogOptions) (<-chan LogLine, error)

	// Images
	ImagePull(ctx context.Context, hostID, ref string) error

	// Prune
	// ImagePrune removes unused images. all=false removes only dangling layers;
	// all=true also removes tagged images not used by any container.
	ImagePrune(ctx context.Context, hostID string, all bool) (PruneReport, error)
	// ContainerPrune removes stopped (exited) containers.
	ContainerPrune(ctx context.Context, hostID string) (PruneReport, error)
	// BuildCachePrune removes dangling build cache.
	BuildCachePrune(ctx context.Context, hostID string) (PruneReport, error)
	// VolumePrune removes unused (unattached) volumes. filters are libpod volume
	// prune filters (e.g. {"label!": {"podman-api.protect=true"}}) so callers can
	// protect volumes; never removes in-use volumes.
	VolumePrune(ctx context.Context, hostID string, filters map[string][]string) (PruneReport, error)

	// Health
	Ping(ctx context.Context, hostID string) error
	Version(ctx context.Context, hostID string) (string, error)
	UsedHostPorts(ctx context.Context, hostID string) ([]PortMapping, error)

	// Host
	HostInfo(ctx context.Context, hostID string) (HostInfo, error)
	// Knows reports whether hostID is a registered host this client can reach.
	// The host set is updated at construction and whenever SetHosts is called
	// (e.g. after a SIGHUP host-config reload).
	Knows(hostID string) bool
	// SetHosts replaces the client's host map at runtime. New hosts become
	// connectable; removed hosts are dropped (and their cached connections
	// cleaned up); changed connection params (addr/socket/ssh_key) invalidate
	// the cached context so the next call reopens the connection.
	SetHosts(hosts []config.Host)
}

Client is the contract every consumer of podman speaks. The real implementation calls libpod via SSH-tunnelled or unix-socket connections; tests use the in-memory fake under ./fake.

type Container

type Container struct {
	ID       string
	Name     string
	Image    string // resolved digest, e.g. "docker.io/library/postgres@sha256:..."
	ImageTag string // human-readable tag, e.g. "docker.io/library/postgres:16"
	Status   string
	// Health is the container's healthcheck status: "" when the container
	// declares no healthcheck, otherwise "healthy" / "unhealthy" / "starting".
	Health string
	// HealthStartPeriod and HealthInterval are the container's *declared*
	// healthcheck timings, both zero when it declares no healthcheck. They are
	// the grace the container was promised, so readiness waits can bound
	// themselves by the spec they are verifying rather than by a fixed constant
	// that may be shorter than the first check can possibly run (#196).
	HealthStartPeriod time.Duration
	HealthInterval    time.Duration
	StartedAt         time.Time
	RestartCount      int
	Ports             []PortMapping
	Env               map[string]string
}

type DiskUsage

type DiskUsage struct {
	Total       int64 // bytes (graphroot partition size)
	Used        int64 // bytes
	Free        int64 // bytes (Total-Used)
	Reclaimable int64 // bytes reclaimable from dangling volumes (system df)
}

DiskUsage describes the host's container-storage partition (graphroot).

type ExecResult

type ExecResult struct {
	ExitCode int
	Output   string // combined stdout+stderr
}

ExecResult is the outcome of ContainerExec.

type HostInfo

type HostInfo struct {
	CPUs       int         // logical CPUs
	MemTotal   int64       // bytes
	MemFree    int64       // bytes
	MemUsedPct float64     // derived: (MemTotal-MemFree)/MemTotal*100, 0 if MemTotal==0
	CPUPct     *float64    // average CPU utilization since boot (user+system %); nil when libpod omits CPUUtilization
	LoadAvg    *[3]float64 // 1/5/15-min; nil when unavailable
	Disk       DiskUsage
}

HostInfo is a point-in-time resource snapshot for a host, sourced from libpod `info` + `system df` plus a best-effort read of /proc/loadavg. Pointer fields are nil when the underlying source does not report them, so an absent metric serializes as null rather than a misleading zero.

type LogLine

type LogLine struct {
	Container string
	Stream    string // stdout / stderr
	Time      time.Time
	Line      string
}

type LogOptions

type LogOptions struct {
	Tail   int    // 0 = all
	Since  string // RFC3339 or duration like "5m"; "" = beginning
	Follow bool
}

LogOptions are the knobs for ContainerLogs.

type Pod

type Pod struct {
	ID         string
	Name       string
	Status     string // "Running", "Created", "Exited", etc.
	Created    time.Time
	Containers []Container
	Labels     map[string]string
}

Pod is the libpod-shaped pod summary the rest of the API consumes.

type PortMapping

type PortMapping struct {
	HostIP        string
	HostPort      int
	ContainerPort int
	Protocol      string // tcp/udp
	Pod           string // pod name owning this port (empty if not derivable)
	Container     string // container name owning this port (empty if not derivable)
}

type PruneReport

type PruneReport struct {
	Items     []string
	Reclaimed int64
}

PruneReport summarizes one prune operation: the ids/names removed and the bytes reclaimed (sum of per-item sizes).

type Real

type Real struct {
	// contains filtered or unexported fields
}

Real is the production podman.Client implementation backed by libpod over SSH (production) or a local unix socket (dev).

Per-host context.Contexts are created lazily and cached. The bindings library stores the underlying connection on the context, so callers must pass the cached context (returned by ctxFor) to every libpod call.

Uses github.com/containers/podman/v5 v5.8.2. bindings.NewConnection signature: func(ctx context.Context, uri string) (context.Context, error)

func NewReal

func NewReal(hosts []config.Host) (*Real, error)

NewReal validates host configs and registers them. Connections are not opened here; first use opens them.

func (*Real) BuildCachePrune

func (r *Real) BuildCachePrune(ctx context.Context, id string) (PruneReport, error)

func (*Real) ContainerExec

func (r *Real) ContainerExec(ctx context.Context, id, container string, cmd []string) (ExecResult, error)

func (*Real) ContainerLogs

func (r *Real) ContainerLogs(ctx context.Context, id, container string, opts LogOptions) (<-chan LogLine, error)

ContainerLogs streams log lines from a container. Cancellation propagates bidirectionally: if the caller's ctx is cancelled the underlying containers.Logs call is cancelled (via mergedCtx), and if the producer finishes naturally the bridge goroutine exits cleanly.

The connection context (c) is long-lived and must not be cancelled per request; mergedCtx derives from c but can be independently cancelled so the streaming call is torn down without killing the cached connection.

func (*Real) ContainerPrune

func (r *Real) ContainerPrune(ctx context.Context, id string) (PruneReport, error)

func (*Real) CopyToContainer

func (r *Real) CopyToContainer(ctx context.Context, id, container, destDir, name string, content []byte) error

func (*Real) HostInfo

func (r *Real) HostInfo(ctx context.Context, id string) (HostInfo, error)

HostInfo returns a point-in-time resource snapshot for a host. CPU/mem/disk come from libpod `info`; reclaimable from `system df`; loadavg is a best-effort read of /proc/loadavg (the one metric libpod does not expose). Any sub-metric that cannot be obtained is left at its zero/nil value rather than failing the whole call; only a failed `info` call (host unreachable) returns an error.

func (*Real) ImagePrune

func (r *Real) ImagePrune(ctx context.Context, id string, all bool) (PruneReport, error)

func (*Real) ImagePull

func (r *Real) ImagePull(ctx context.Context, id, ref string) error

func (*Real) Knows

func (r *Real) Knows(id string) bool

Knows reports whether the host is registered.

func (*Real) NetworkEnsure

func (r *Real) NetworkEnsure(ctx context.Context, id, name string) error

NetworkEnsure creates the named network if absent, with aardvark DNS enabled.

DNS must be on: the `podman network create` CLI defaults it true, but the REST API does not, and ingress backend routing resolves pods by name on this network — without DNS the proxy can't reach the backend (502).

An existing network is only accepted if its DNS is already on. A network left by a pre-DNS build has it off, and DNS can't be flipped on an existing network via the API, so we fail with the one-time fix instead of silently keeping it disabled (which IgnoreIfExists would do).

func (*Real) Ping

func (r *Real) Ping(ctx context.Context, id string) error

func (*Real) PlayKube

func (r *Real) PlayKube(ctx context.Context, id, raw string, replace bool, networks ...string) error

func (*Real) PodInspect

func (r *Real) PodInspect(ctx context.Context, id, name string) (Pod, error)

func (*Real) PodList

func (r *Real) PodList(ctx context.Context, id string, filters map[string]string) ([]Pod, error)

func (*Real) PodRemove

func (r *Real) PodRemove(ctx context.Context, id, name string, force bool) error

func (*Real) PodRestart

func (r *Real) PodRestart(ctx context.Context, id, name string) error

func (*Real) PodStart

func (r *Real) PodStart(ctx context.Context, id, name string) error

func (*Real) PodStop

func (r *Real) PodStop(ctx context.Context, id, name string) error

func (*Real) Preflight

func (r *Real) Preflight(ctx context.Context) error

Preflight enforces MinPodmanVersion at boot. ALL reachable hosts are checked and any below the floor are collected; the returned error aggregates every offender via errors.Join so operators see every problem in a single boot attempt (main treats it as fatal — the daemon refuses to start). An unreachable or slow host is logged and left unverified; the check re-runs on its first successful connect (opCtxFor), so a down-at-boot old host still cannot sneak in. See #85.

func (*Real) SecretCreate

func (r *Real) SecretCreate(ctx context.Context, id, name string, value []byte) error

func (*Real) SecretInspect

func (r *Real) SecretInspect(ctx context.Context, id, name string) (Secret, error)

func (*Real) SecretList

func (r *Real) SecretList(ctx context.Context, id string) ([]Secret, error)

func (*Real) SecretRemove

func (r *Real) SecretRemove(ctx context.Context, id, name string) error

func (*Real) SetHosts

func (r *Real) SetHosts(hosts []config.Host)

SetHosts replaces the client's host map at runtime, diff-invalidating cached connections so that:

  • newly added hosts become connectable on first use (lazy ctxFor);
  • removed hosts are dropped (cached context garbage-collected);
  • hosts whose addr/socket/ssh_key changed get their cached connection and verified flag cleared so the next call reopens with the new params;
  • unchanged hosts keep their live cached connection.

func (*Real) URIFor

func (r *Real) URIFor(id string) (string, error)

URIFor returns the libpod URI for hostID. unix-only when addr=="unix".

func (*Real) UsedHostPorts

func (r *Real) UsedHostPorts(ctx context.Context, id string) ([]PortMapping, error)

func (*Real) Version

func (r *Real) Version(ctx context.Context, id string) (string, error)

func (*Real) VolumeCreate

func (r *Real) VolumeCreate(ctx context.Context, id, name string) error

VolumeCreate creates an empty named volume. An already-existing name is treated as success so migrate's create-then-copy step is idempotent on retry.

func (*Real) VolumeExport

func (r *Real) VolumeExport(ctx context.Context, id, name string) (io.ReadCloser, error)

VolumeExport streams a volume's contents as an uncompressed tar. The returned reader is the live HTTP response body; the caller must Close it. We issue the REST request directly rather than using the high-level volumes.Export binding because that binding copies into an io.Writer, whereas our contract must hand back a live io.ReadCloser for pipe streaming.

func (*Real) VolumeImport

func (r *Real) VolumeImport(ctx context.Context, id, name string, src io.Reader) error

VolumeImport unpacks an uncompressed tar into an existing volume on the host.

func (*Real) VolumeInspect

func (r *Real) VolumeInspect(ctx context.Context, id, name string) (Volume, error)

func (*Real) VolumePrune

func (r *Real) VolumePrune(ctx context.Context, id string, filters map[string][]string) (PruneReport, error)

func (*Real) VolumeRemove

func (r *Real) VolumeRemove(ctx context.Context, id, name string, force bool) error

type Secret

type Secret struct {
	Name      string
	CreatedAt time.Time
}

type Volume

type Volume struct {
	Name      string
	SizeBytes int64
}

Directories

Path Synopsis
Package fake is an in-memory implementation of podman.Client used by tests.
Package fake is an in-memory implementation of podman.Client used by tests.

Jump to

Keyboard shortcuts

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