container

package
v0.2026217.301 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package container is the spec fabric slice for container-engine host helpers — resolving which engine binary to invoke, its GPU run-args, and auto-detecting the installed engine. RELOCATED from sdk/kit (#55 fabric-primitive extraction). It carries os/exec (the engine auto-detect shells `LookPath`) in its OWN slice (Rule 2) so a consumer needing only value types never drags os/exec. charly core inlines from here; sdk/kit re-exports the same symbols so existing kit.EngineBinary / kit.GPURunArgs / kit.DetectEngine call sites are untouched.

spec/container/transfer.go — the container-engine image-transfer host primitive, RELOCATED from sdk/kit by #55 coneC (charly/ off sdk/kit): it pipes an image from one engine's local store to another via `save | load` (os/exec), the fabric twin of the LocalImageExists probe that already lives in this slice. sdk/kit re-exports it (var TransferImage = container.TransferImage) so every existing kit.TransferImage call site (candy/plugin-build, candy/plugin-box, candy/plugin-deploy-pod, …) is unchanged; charly core inlines from here. Co-located with EngineBinary (same package) and the LocalImageExists family this transfer path complements.

Index

Constants

This section is empty.

Variables

View Source
var InspectLabels = InspectImageLabels

InspectLabels reads OCI labels from a local image via engine inspect. Package-level var for testability — defaults to the canonical InspectImageLabels (spec/container/image_inspect.go, coneA). Override this var (not kit/deploykit's re-exports) to stub label reads in tests of ExtractMetadata's decode logic.

View Source
var ListLocalImages = defaultListLocalImages

ListLocalImages returns all images in the engine's local storage. Package-level var for testability (same pattern as LocalImageExists, DetectEngine).

View Source
var LocalImageExists = defaultLocalImageExists

LocalImageExists checks whether an image reference exists in the given engine's local store. Package-level var for testability (same pattern as DetectEngine). Co-located with the resolution family because ResolveLocalImageRef reads it; kit re-exports it (kit.LocalImageExists = container.LocalImageExists) so existing direct callers (candy/plugin-build, candy/plugin-box, candy/plugin-deploy-pod, candy/plugin-kube, charly core) are unchanged.

Functions

func ContainerImage

func ContainerImage(engine, containerName string) string

ContainerImage returns the image ref for a running container, best-effort ("" on error). Thin wrapper over ContainerImageRef.

func ContainerImageRef

func ContainerImageRef(engine, containerName string) (string, error)

ContainerImageRef returns the image ref backing a running container (.Config.Image via `<engine> inspect`). THE single container→image-ref inspector — there is exactly one inspect implementation.

func DetectEngine

func DetectEngine() (string, error)

DetectEngine auto-detects the container engine: prefers podman, falls back to docker.

func EngineBinary

func EngineBinary(engine string) string

EngineBinary returns the CLI binary name for a container engine. "auto" resolves via DetectEngine (podman preferred), falling back to "docker".

func ExtractCalVerTag

func ExtractCalVerTag(ref string) string

ExtractCalVerTag returns the CalVer portion of a ref's tag, or "" if the tag is not a recognisable CalVer (`YYYY.DDD.HHMM`). Lets the resolver distinguish CalVer tags from legacy floats like `:latest` (which should never be chosen as the newest candidate).

func ExtractMetadata

func ExtractMetadata(engine, imageRef string) (*spec.BoxMetadata, error)

ExtractMetadata reads OCI labels from a local image and returns parsed spec.BoxMetadata. Returns nil if the image has no ai.opencharly labels. Returns spec.ErrImageNotLocal wrapped with the image ref if the image is not in local storage.

func GPURunArgs

func GPURunArgs(engine string) []string

GPURunArgs returns the engine-specific run flags that expose all host GPUs to a container.

func InspectImageLabels

func InspectImageLabels(engine, imageRef string) (map[string]string, error)

InspectImageLabels reads a local image's OCI labels via engine inspect. Pure container-storage probe: no charly-core coupling.

func IsHostNetworked

func IsHostNetworked(engine, containerName string) bool

IsHostNetworked checks if a running container uses --network host.

func LooksLikeFullRef

func LooksLikeFullRef(ref string) bool

LooksLikeFullRef returns true if the image ref contains a registry segment (a "/" before any ":") — e.g. "ghcr.io/org/name:tag" — so it can be pulled without charly.yml resolution.

func ParsePublishedPort

func ParsePublishedPort(output string, port int) (string, error)

ParsePublishedPort extracts the host "ip:port" from `<engine> port` output for an in-container port, normalizing 0.0.0.0 / [::] to 127.0.0.1.

func ResolveLocalImageRef

func ResolveLocalImageRef(engine, input string) (string, error)

ResolveLocalImageRef resolves a user-supplied image reference against the engine's local storage — never reads charly.yml. Used by test-mode commands (charly check live, charly check box) so they stay within the test-mode input set.

For full refs (registry prefix present) it validates the image exists locally and passes through unchanged. For short names it resolves via CalVer: collect every candidate ref and pick the one with the highest `ai.opencharly.version` label (falling back to the highest tag CalVer). charly is CalVer-only — no `:latest` fallback. See `/charly-build:build` "CalVer-only" for the contract.

A candidate ref must satisfy BOTH halves: its image is identified as the short name (preferred: an `ai.opencharly.image=<short>` label; fallback: no such label) AND the ref ITSELF is named `<short>` in its trailing repo component. The second half is not cosmetic — a label-family image accumulates the deploy-name alias tags of every OTHER deployment built on the same base box, and they inherit its label, so without it an untagged resolve can return a sibling deployment's image (see the invariant comment in the label branch below).

Returns `spec.ErrImageNotLocal` when nothing matches. An ambiguous result across multiple repos with the same highest CalVer tag surfaces as an explicit error asking for a full ref.

func ResolveNewestLocalCalVer

func ResolveNewestLocalCalVer(engine, short string) (string, error)

ResolveNewestLocalCalVer is the canonical "find the newest local image for this short name" helper. Thin wrapper around ResolveLocalImageRef — exposed so callers that start with an explicit short-name + empty-tag can resolve uniformly.

func ResolveShellImageRef

func ResolveShellImageRef(registry, name, tag string) string

ResolveShellImageRef builds the full image reference from registry, name, and tag, for a caller about to run an engine command (podman/docker) against it. When tag is empty, it resolves to the newest local CalVer for the given short name via ResolveNewestLocalCalVer — the CalVer-only contract (`/charly-build:build` "Cache Efficiency"). A caller that wants a specific tag passes it; a caller whose `--tag` flag is empty gets the newest CalVer with no extra work. When registry is set AND tag is empty, there's no way to guess a remote CalVer without a registry-list call, so the caller gets `<registry>/<name>` back with no tag suffix — the engine resolves it locally first (matching any single local tag) or errors. (P14: relocated from charly/shell.go's resolveShellImageRef, which now delegates here — R3, single source for every caller: candy/plugin-box's `merge` command plus charly core's own bundle_add/config_image/ensure_image/remote_image/pod_lifecycle_resolve/update_deploy_dispatch.)

func TransferImage

func TransferImage(srcEngine, dstEngine, imageRef string) error

TransferImage pipes an image from one engine to another via save | load.

Types

type LocalImageInfo

type LocalImageInfo struct {
	ID     string            // image ID (sha256:...) — used by `charly clean` to skip in-use images
	Names  []string          // Full refs: ["ghcr.io/opencharly/jupyter:latest", ...]
	Labels map[string]string // OCI labels from the image config
	Size   int64             // reported storage size in bytes (podman's "Size" field; 0 if absent/unparsed)
}

LocalImageInfo describes an image present in the engine's local storage. Populated by ListLocalImages from `{podman,docker} images --format json`.

func ParseLocalImagesJSON

func ParseLocalImagesJSON(out []byte) ([]LocalImageInfo, error)

ParseLocalImagesJSON parses `{podman,docker} images --format json` output into ONE LocalImageInfo per distinct image ID, with that id's tag refs merged into Names.

This dedup is load-bearing: podman emits ONE ROW PER TAG, and each row's Names array already lists EVERY tag on that id. A naive row-by-row mapping therefore produces N near-identical entries for an id with N tags — which made `charly clean`'s keep-N retention over-count entries and, worse, remove an id's whole Names array per "extra" entry (deleting tags it meant to keep). Collapsing to one-id-with-a-tag-list matches the struct's shape and what every consumer (retention prune, short-name resolver) expects.

Empty-id rows (dangling/untagged) are kept separate via a per-row sentinel key so they never merge into one another.

Jump to

Keyboard shortcuts

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