containers

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: BSD-3-Clause Imports: 12 Imported by: 0

Documentation

Overview

Package containers is the VM side of the dynamic container set. loom-server (or weft-agent reconciler) publishes a pod.ContainerSet on the per-VM subject `weft.containers.<vmID>` — the subscriber here diffs it against the running set + drives crun to converge : pull missing images via ncl, start newly-listed containers, stop containers that vanished.

State is pushed whole and applied idempotently (replace-by-name) — same model pkg/mounts uses for shares. A missed message self-heals on the next publish.

Same Subscriber+ApplyFunc shape as pkg/mounts so any test that drove mounts can be cargo-culted to drive containers ; the real crun apply lives in Runtime below behind an interface so the reconciler is testable without root + cgroups.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HandleMessage

func HandleMessage(ctx context.Context, data []byte, r *Reconciler) error

HandleMessage decodes a published ContainerSet + applies it. Pure aside from the injected runtime — same testable shape as pkg/mounts.

func Subject

func Subject(vmID string) string

Subject is the per-VM event-bus subject container set updates arrive on. Mirror of mounts.Subject ; class / fleet fan-out lives in the control plane the way teacher → student broadcast does.

Types

type CrunRuntime

type CrunRuntime struct {
	BundleRoot   string // e.g. "/run/weft/containers"
	NCLImagePath string // e.g. "/run/weft/images"
	Logger       *log.Logger
}

CrunRuntime drives crun. BundleRoot is where per-container bundle dirs land (<bundleRoot>/<name>/{config.json,rootfs}) ; NCLImagePath is the ncl cache the pre-baked rootfs lives under when an image has already been pre-staged at build time (the dev path).

func (*CrunRuntime) Pull

func (r *CrunRuntime) Pull(ctx context.Context, image string) error

Pull defers to ncl to fetch+unpack the image. When ncl isn't on PATH (dev rootfs without ncl pre-baked) the pull is treated as a no-op : Start will look for a pre-staged rootfs at NCLImagePath keyed by image ref and use that. Lets the dev path work today without the full V0.6 ncl pipeline in place.

func (*CrunRuntime) Running

func (r *CrunRuntime) Running(ctx context.Context) ([]string, error)

Running asks crun for the list of containers it knows about.

func (*CrunRuntime) Start

Start materialises an OCI bundle from the pulled image + asks crun to run it. The bundle lives at <BundleRoot>/<name>/ with config.json rendered from c (Command/Args/Env/Mounts/WorkingDir/Net) and rootfs symlinked / bind-mounted from the ncl image cache.

Restart="always" is honoured by the agent's reconciler layer (it re-invokes Start on exit) ; this method is fire-and-forget once crun start returns.

func (*CrunRuntime) Stop

func (r *CrunRuntime) Stop(ctx context.Context, name string) error

Stop terminates the container + reaps the bundle dir.

type Reconciler

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

Reconciler holds the last-applied set so diffs are quick + the crun runtime stays the source of truth for "is it actually running". Concurrent Apply-safe (one in flight at a time ; later publishes during an apply wait).

func NewReconciler

func NewReconciler(runtime Runtime, logger *log.Logger) *Reconciler

NewReconciler builds a Reconciler over runtime. logger may be nil.

func (*Reconciler) Apply

func (r *Reconciler) Apply(ctx context.Context, s pod.ContainerSet) error

Apply converges the runtime to s. Steps :

  1. validate the payload (rejection on schema bugs)
  2. compute add / update / drop relative to the previously-applied set (replace-by-name)
  3. for each add : pull + start for each update: stop + start (the simplest semantics that covers env / image / command changes) for each drop : stop

Returns the first error from a step ; subsequent ones still run so a single broken container doesn't gate the rest of the set.

type Runtime

type Runtime interface {
	// Pull ensures the image's bundle exists locally. Idempotent on
	// the digest — pulling the same ref twice is a no-op.
	Pull(ctx context.Context, image string) error
	// Start launches the container. Name is the stable handle the
	// diff uses to find this container later.
	Start(ctx context.Context, c pod.WorkloadContainer) error
	// Stop terminates + cleans up the container's bundle.
	Stop(ctx context.Context, name string) error
	// Running returns the names of every container the runtime
	// currently considers alive ; used to seed the diff after a
	// JetStream replay.
	Running(ctx context.Context) ([]string, error)
}

Runtime is the crun-driving side the reconciler talks to. Stubbed in tests + in dev mode (where containers are simulated as plain processes), real impl lives next to the agent's crun bundle path.

type Subscriber

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

Subscriber listens for this VM's container-set updates + drives the reconciler. Direct mirror of mounts.Subscriber down to the JetStream last-per-subject replay trick — that's what makes boot-time replay of the previously-desired set work, even if loom-server published it before the VM was alive.

func NewSubscriber

func NewSubscriber(nc *nats.Conn, vmID string, runtime Runtime, logger *log.Logger) *Subscriber

NewSubscriber wires a Subscriber for vmID against runtime + logger.

func (*Subscriber) Start

func (s *Subscriber) Start(ctx context.Context) (*nats.Subscription, error)

Start subscribes to the VM's container-set subject. The returned subscription is live until unsubscribed or the connection drops. JetStream replay : a stream named `weft-containers` with subjects `weft.containers.*` + LastPerSubject retention is the boot-time guarantee that the agent picks up the most recent desired set even if it was published before the VM existed.

Jump to

Keyboard shortcuts

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