3.3 KiB
Rigging
Multi-repo NixOS + Nomad infrastructure management CLI and flake-parts module.
What this is
Three components:
- Flake-parts module (
flake-module.nix) — repos import this to declare what they provide and expose abosun-manifestpackage (JSON derivation) - Nushell CLI (
cli/rigging.nu) — reads~/.config/bosun/config.toml, builds each repo's manifest vianix build, aggregates, dispatches commands - Bash CLI (
cli/default.nix) — repo-local Nomad job operations with runtime variable support
File layout
flake.nix # exports flakeModules.default + lib
flake-module.nix # the flake-parts module (top-level bosun.{meta,hosts} + perSystem bosun.{enable,jobsDir,...})
cli/
default.nix # bash bosun CLI (repo-local Nomad ops)
rigging.nix # nix wrapper for the nushell CLI
rigging.nu # nushell CLI source
lib/
default.nix # bosun library (discoverJobs, evalJob, compileJobs, etc.)
nomad.nix # nomad helpers (traefikTags, pinToHost, resources, etc.)
nushell.nix # writeNushellApplication (bundled, no overlay needed)
How consumers use it
Consumers add this as a flake input and import flakeModules.default. This gives them:
bosun.meta.name/bosun.hosts— top-level options for repo identity + host declarationsperSystem.bosun.{enable,jobsDir,nomadAddress,...}— Nomad job managementpackages.bosun-manifest— always generated JSON manifestpackages.rigging— the multi-repo CLIpackages.bosun— repo-local Nomad CLI (only whenbosun.enable = true)
The manifest is the key integration point: rigging builds each repo's manifest via nix build <repo>#bosun-manifest, reads the JSON, and knows what hosts/jobs each repo provides.
Key design decisions
- No legacyPackages for vars: Runtime job evaluation with variables uses
nix eval --exprinline (same pattern as the bash CLI). ThelegacyPackages.bosun.evalJobWithVarsexists for backward compat but the CLI constructs the eval expression directly. - Rigging delegates Nomad ops: The nushell CLI is a thin orchestration layer. For actual Nomad operations (run, plan, stop, etc.), it delegates to the repo-local bash CLI via
nix run <repo>#bosun -- <cmd>. - writeNushellApplication bundled:
lib/nushell.nixis a self-contained copy so consumers don't need an overlay. - Top-level + perSystem split:
bosun.meta/bosun.hostsare flake-level options (shared across systems). Nomad job config is perSystem (needspkgs). The manifest bridges both by reading top-level config from within perSystem via closure overtopArgs.config.bosun. mkMerge/mkIffor config: The perSystem config usesmkMerge+mkIf(not//+lib.optionalAttrs) to avoid infinite recursion when the module system evaluates packages.
Vision
The end state: rigging is installed globally (via home-manager or devShell) and manages all infrastructure repos. Each repo is self-describing — rigging repo add <path> discovers everything. Commands like rigging host deploy alvin or rigging job run forgejo Just Work regardless of which repo owns the resource.
Phase 4 (pending): wire up dotfiles repo as a second consumer. Phase 5: drop the bash CLI once rigging fully replaces it.