Documentation
¶
Index ¶
- Constants
- Variables
- type Client
- type Container
- type DiskUsage
- type ExecResult
- type HostInfo
- type LogLine
- type LogOptions
- type Pod
- type PortMapping
- type PruneReport
- type Real
- func (r *Real) BuildCachePrune(ctx context.Context, id string) (PruneReport, error)
- func (r *Real) ContainerExec(ctx context.Context, id, container string, cmd []string) (ExecResult, error)
- func (r *Real) ContainerLogs(ctx context.Context, id, container string, opts LogOptions) (<-chan LogLine, error)
- func (r *Real) ContainerPrune(ctx context.Context, id string) (PruneReport, error)
- func (r *Real) CopyToContainer(ctx context.Context, id, container, destDir, name string, content []byte) error
- func (r *Real) HostInfo(ctx context.Context, id string) (HostInfo, error)
- func (r *Real) ImagePrune(ctx context.Context, id string, all bool) (PruneReport, error)
- func (r *Real) ImagePull(ctx context.Context, id, ref string) error
- func (r *Real) Knows(id string) bool
- func (r *Real) NetworkEnsure(ctx context.Context, id, name string) error
- func (r *Real) Ping(ctx context.Context, id string) error
- func (r *Real) PlayKube(ctx context.Context, id, raw string, replace bool, networks ...string) error
- func (r *Real) PodInspect(ctx context.Context, id, name string) (Pod, error)
- func (r *Real) PodList(ctx context.Context, id string, filters map[string]string) ([]Pod, error)
- func (r *Real) PodRemove(ctx context.Context, id, name string, force bool) error
- func (r *Real) PodRestart(ctx context.Context, id, name string) error
- func (r *Real) PodStart(ctx context.Context, id, name string) error
- func (r *Real) PodStop(ctx context.Context, id, name string) error
- func (r *Real) Preflight(ctx context.Context) error
- func (r *Real) SecretCreate(ctx context.Context, id, name string, value []byte) error
- func (r *Real) SecretInspect(ctx context.Context, id, name string) (Secret, error)
- func (r *Real) SecretList(ctx context.Context, id string) ([]Secret, error)
- func (r *Real) SecretRemove(ctx context.Context, id, name string) error
- func (r *Real) SetHosts(hosts []config.Host)
- func (r *Real) URIFor(id string) (string, error)
- func (r *Real) UsedHostPorts(ctx context.Context, id string) ([]PortMapping, error)
- func (r *Real) Version(ctx context.Context, id string) (string, error)
- func (r *Real) VolumeCreate(ctx context.Context, id, name string) error
- func (r *Real) VolumeExport(ctx context.Context, id, name string) (io.ReadCloser, error)
- func (r *Real) VolumeImport(ctx context.Context, id, name string, src io.Reader) error
- func (r *Real) VolumeInspect(ctx context.Context, id, name string) (Volume, error)
- func (r *Real) VolumePrune(ctx context.Context, id string, filters map[string][]string) (PruneReport, error)
- func (r *Real) VolumeRemove(ctx context.Context, id, name string, force bool) error
- type Secret
- type Volume
Constants ¶
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 ¶
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).
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
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 ¶
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 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 PruneReport ¶
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 ¶
NewReal validates host configs and registers them. Connections are not opened here; first use opens them.
func (*Real) BuildCachePrune ¶
func (*Real) ContainerExec ¶
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 (*Real) CopyToContainer ¶
func (*Real) HostInfo ¶
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 (*Real) NetworkEnsure ¶
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) PodInspect ¶
func (*Real) Preflight ¶
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 (*Real) SecretInspect ¶
func (*Real) SecretList ¶
func (*Real) SetHosts ¶
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) UsedHostPorts ¶
func (*Real) VolumeCreate ¶
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 ¶
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 ¶
VolumeImport unpacks an uncompressed tar into an existing volume on the host.