storagesupervisor

package
v0.1.21 Latest Latest
Warning

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

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

Documentation

Overview

Package storagesupervisor installs and (eventually) supervises the unbounded-storage daemon on a host. The install workflow is a native Go port of hack/scripts/install-unbounded-storage.sh: it acquires a release-layout tarball (from a GitHub release, an explicit URL, or a local file), verifies it, stages it into a versioned prefix, flips a "current" symlink, writes a systemd unit, and enables/starts the service via systemctl.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Install

func Install(ctx context.Context, cfg Config) error

Install runs the full install workflow using the real systemctl runner.

func InstallWithRunner

func InstallWithRunner(ctx context.Context, cfg Config, runner CommandRunner) error

InstallWithRunner runs the install workflow, delegating systemctl calls to runner. It acquires and verifies the release tarball, stages it into a versioned directory under the host prefix, atomically flips the "current" symlink, writes the systemd unit, and reloads/starts the service.

func Preconditions

func Preconditions(cfg Config) error

Preconditions verifies the host-level requirements for an install: the process must run as root (it writes under the host prefix and the systemd unit directory) and the configured systemctl command must be resolvable.

func RenderConfig

func RenderConfig(sourceDir string, state renderState) ([]byte, error)

RenderConfig reads the daemon Config expressed as YAML from the projected ConfigMap (a single sourceConfigFile under sourceDir), unmarshals it into the protobuf Config message, overlays the per-node render state, and returns the daemon's binary protobuf config wire format.

The YAML is the full Config schema (api/unbounded-storage/config.proto) with snake_case field names. Unknown fields are rejected so an operator typo fails loudly rather than silently dropping a setting. Any field left unset keeps its proto3 zero value, which the daemon promotes to the documented default.

The per-node mesh fields (self and discovered peer set) come from state, computed from the Kubernetes node watch. When the ring is active, this node's peer name is injected and discovered peers are merged with any peers declared in the YAML (discovered peers win on name collision). TCP rings also override startup.fabric.tcp.addr with the node's own routable bind. The default disk set is populated from the self node's storage disk annotations, or from a default file-backed disk when no valid annotation disks are present. Loadgen annotations append synthetic frontends for this node.

func Run

func Run(ctx context.Context, cfg Config) error

Run is the runtime-container entrypoint. It renders the projected ConfigMap under cfg.SourceDir plus the per-node peer set (discovered from the Kubernetes node watch) into the daemon's binary protobuf config at cfg.ConfigPath, then watches both the source directory and cluster nodes and re-renders on change. The daemon owns reacting to the rewritten file (it has its own watcher and manages its own restarts), so this loop is render-only. It blocks until ctx is cancelled.

func WriteConfigAtomic

func WriteConfigAtomic(path string, data []byte) error

WriteConfigAtomic writes data to path via a temp file in the same directory followed by a rename, so the daemon's parent-directory config watcher only ever observes a complete file appearing as an atomic swap. The destination directory must already exist (install bootstraps it).

Types

type CommandRunner

type CommandRunner interface {
	Run(ctx context.Context, argv []string) error
}

CommandRunner executes an external command. It is injected so systemctl invocations can be stubbed in tests and wrapped (e.g. with nsenter) in production.

type Config

type Config struct {
	// Repo is the GitHub "owner/name" used to build release download URLs.
	Repo string
	// Version is the release tag to install, or "latest".
	Version string
	// Prefix is the host-absolute install prefix (e.g. /opt/unbounded-storage).
	// Releases are staged under Prefix/releases and Prefix/current is the
	// active symlink. This is always host-absolute; HostRoot is applied
	// separately when writing files.
	Prefix string
	// ServiceName is the systemd service name (without the .service suffix).
	ServiceName string
	// ConfigPath is the host-absolute path to the daemon config file. The
	// daemon selects its decoder by extension: a ".binpb" path (the default)
	// is decoded as binary protobuf, which is what the run supervisor renders;
	// any other extension is parsed as strict TOML.
	ConfigPath string
	// SourceDir is the host/container path where the cluster ConfigMap is
	// projected. It holds a single sourceConfigFile (config.yaml) carrying the
	// daemon Config as YAML. The run supervisor unmarshals it and renders
	// ConfigPath; install does not use it.
	SourceDir string
	// NodeName is the Kubernetes node this supervisor runs on, sourced from
	// the NODE_NAME downward-API env. The run supervisor uses it to find this
	// node in the cluster (its ring label value, its InternalIP) and to
	// exclude itself from its own peer set. Empty disables peer discovery
	// (the run loop renders startup settings only).
	NodeName string
	// StorageRingLabel is the node label key whose value groups nodes into a
	// storage ring. Nodes sharing a value become each other's peers.
	StorageRingLabel string
	// Kubeconfig is an out-of-cluster kubeconfig path for peer discovery. Empty
	// means in-cluster service-account discovery. This is the developer/test
	// path; in production the run container relies on the in-cluster config.
	Kubeconfig string
	// DeviceInventoryURL, when set, is the daemon inventory base URL whose
	// /rdma and /block paths are published onto this Node for discovery.
	DeviceInventoryURL string
	// StorageArgs are extra arguments appended to the daemon ExecStart line.
	StorageArgs string
	// Arch is the normalized target architecture ("amd64" or "arm64").
	Arch string
	// PoolBytes sizes the hugepage reservation in the systemd unit.
	PoolBytes int64
	// Hugepages, when > 0, reserves an explicit number of 2 MiB hugepages
	// instead of deriving the count from PoolBytes.
	Hugepages int64
	// NoHugepages skips the systemd hugepage reservation preflight. Use this
	// when the daemon config sets startup.memory.no_hugepages.
	NoHugepages bool
	// NoEnable, when true, installs the unit but does not enable/start it.
	NoEnable bool

	// Source is the raw source selector: empty (release), an http(s) URL, or a
	// filesystem path.
	Source string
	// SourceMode is the classification of Source.
	SourceMode SourceMode

	// HostRoot is prefixed to every filesystem write so the installer can run
	// against a mounted host filesystem (or a temp dir in tests). It defaults
	// to "/" so writes land at their real host-absolute locations. It never
	// affects path references embedded in the systemd unit or the "current"
	// symlink target, which must remain host-absolute.
	HostRoot string
	// Systemctl is the argv used to invoke systemctl, parsed from the SYSTEMCTL
	// environment variable. In a container this is typically an nsenter wrapper
	// so the calls execute in the host's namespaces.
	Systemctl []string
}

Config holds the resolved configuration for an install run.

func LoadConfig

func LoadConfig() (Config, error)

LoadConfig builds a Config from the process environment, applying the same defaults and validation as the shell installer. It returns an error if any value is malformed.

type SourceMode

type SourceMode int

SourceMode classifies where the release-layout tarball comes from.

const (
	// SourceRelease downloads the tarball from a GitHub release (latest or a
	// pinned tag) when no explicit source is provided.
	SourceRelease SourceMode = iota
	// SourceURL downloads the tarball from an explicit http(s) URL.
	SourceURL
	// SourceFile uses a release-layout tarball already present on disk.
	SourceFile
)

Jump to

Keyboard shortcuts

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