volumes

package
v0.0.1-dev.137 Latest Latest
Warning

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

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

Documentation

Overview

Package volumes is the per-node Subsystem that drives the storage driver Attach/Mount/Unmount/Detach lifecycle for Volumes whose BoundNode equals this node's identity.

It is the agent-side counterpart to pkg/orchestrator/controllers/ volume_controller.go: the controller decides where a volume is bound (and is the only writer of Volume.BoundNode); this subsystem watches those bindings and turns them into real node-local mounts under `<MountRoot>/<volume.ID>/` (default `/var/lib/rune/mounts`).

Scope intentionally narrow for the first agent-side slice of RUNE-069:

  • Watches ResourceTypeVolume across all namespaces.
  • For each volume bound to this node (`BoundNode == nodeID`, status in {Available, Bound}, non-empty Handle), calls Driver.Attach then Driver.Mount and records the resulting MountTarget in an in-memory table.
  • For previously-tracked volumes that no longer match (BoundNode changed, status regressed, deleted), calls Unmount then Detach and drops the entry.
  • Public accessor MountTargetFor(volumeID) lets the runner-side resolver swap the bare Volume.Handle for the agent-driven mount target once the instance controller is updated to consult it.

Out of scope (deferred to follow-ups):

  • VolumeBound writeback: this Subsystem does not flip status to Bound or write BoundNode itself; that remains the controller's job in a later slice.
  • Persistence of the mount table across restarts: today every Stop/Start re-reconciles from scratch by walking the watch.

Index

Constants

View Source
const DefaultMountRoot = "/var/lib/rune/mounts"

DefaultMountRoot is the per-node directory under which the subsystem nests one subdirectory per Volume.ID. It mirrors the layout called out in the RUNE-069 design.

View Source
const DefaultRetryInterval = 30 * time.Second

DefaultRetryInterval is the period at which the subsystem re-walks every Volume and re-attempts bringUp for any that should be mounted but aren't. Picked so a stuck mount recovers within one operator attention span without hammering cloud-provider APIs.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Store is the resource store to watch. Required.
	Store store.Store

	// NodeID is the local node's stable identity. The subsystem only
	// acts on Volumes whose BoundNode matches. Required.
	NodeID string

	// NodeHostname is the OS hostname of the node (os.Hostname()).
	// Threaded into every driver.OpContext so cloud-backed drivers can
	// map the Rune node onto the cloud provider's instance identity —
	// e.g. dovolume looks up the DO droplet by hostname-derived name.
	// Empty disables that mapping; the affected driver surfaces its
	// own error.
	NodeHostname string

	// Lookup resolves a Volume to a concrete Driver instance.
	// Required.
	Lookup DriverLookup

	// SecretLookup resolves `secret:...` references inside the
	// merged driver parameters before Attach / Mount / Unmount /
	// Detach calls. nil disables resolution; secret-ref-shaped
	// values then fail the operation with a clear error. See
	// RUNE-200 PR 3.
	SecretLookup driverparams.SecretLookup

	// MountRoot is the per-node directory under which mount targets
	// live. Defaults to DefaultMountRoot.
	MountRoot string

	// RetryInterval is how often the run loop re-walks every Volume
	// and re-attempts bringUp for any that should be mounted but
	// aren't. Required so transient Attach / Mount failures recover
	// without a runed restart. Defaults to DefaultRetryInterval.
	RetryInterval time.Duration

	// Logger; defaults to the global logger with component
	// "agent.volumes".
	Logger log.Logger
}

Config bundles construction parameters.

type DriverLookup

type DriverLookup func(ctx context.Context, vol *types.Volume) (driver.Driver, error)

DriverLookup resolves the storage Driver responsible for a given Volume. The implementation typically reads the Volume's StorageClass from the store to learn the driver name, then asks the driver registry for an instance. Keeping that two-step dance behind a closure lets this package stay free of any direct store-access for driver resolution and trivial to fake in tests.

type Subsystem

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

Subsystem implements the agent.Subsystem contract:

Name() string
Start(ctx context.Context) error
Ready() <-chan struct{}
Stop(ctx context.Context) error

The interface itself lives in internal/agent; depending on it here would import-cycle, so the contract is honoured structurally.

func New

func New(cfg Config) (*Subsystem, error)

New constructs a Subsystem. It does not touch the store or filesystem until Start is called.

func (*Subsystem) MountTargetFor

func (s *Subsystem) MountTargetFor(volumeID string) (string, bool)

MountTargetFor returns the host path the named volume is currently mounted at on this node (or false if the subsystem has not mounted it). Called by the instance controller's resolveVolumeMount via the MountResolver hook; the controller falls back to Volume.Handle when this returns false.

func (*Subsystem) Name

func (s *Subsystem) Name() string

Name identifies the subsystem in logs / metrics.

func (*Subsystem) Ready

func (s *Subsystem) Ready() <-chan struct{}

Ready returns a channel closed once the subsystem has opened its watch and finished the initial reconcile pass.

func (*Subsystem) Start

func (s *Subsystem) Start(ctx context.Context) error

Start opens the volume watch and begins reconciling bindings. Returns promptly; long-running work runs in a goroutine.

func (*Subsystem) Stop

func (s *Subsystem) Stop(ctx context.Context) error

Stop tears down the watch and unmounts every tracked volume. Safe to call after a failed Start.

Jump to

Keyboard shortcuts

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