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 ¶
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.
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 ¶
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 ¶
New constructs a Subsystem. It does not touch the store or filesystem until Start is called.
func (*Subsystem) MountTargetFor ¶
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) 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.