Install and deploy kits
The install lane puts a machine’s disk layout and hardware report into an install command, and gives a deploy command.
The flake sink carries apps like any other output: an out value that gives apps.<system>.<name> merges with the rest.
The two kits are modules: you put them in imports of the top module. See Kits batteries for kits and assemblies.
# Machines, the sinks that install and deploy read, and the kits of the install lane.# The kits are modules: in your flake they go in `imports` of the top module (`inputs.yen.lib.kits.disko`).{ yen, lib, inputs, ...}:let b = yen.lib.batteries; inherit (yen.lib) maybe; pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;in{ imports = [ # (1) inputs.yen.lib.kits.disko inputs.yen.lib.kits.facter ];
yen.kinds.fleet = { spawns.host = _: yen.host; sinks.out.reduce = yen.lib.reduce.merge; }; yen.kinds.host = { fields = { addr = yen.lib.str; buildHost = maybe yen.lib.str; }; spawns.member = yen.lib.batteries.kits.members { assemblies = lib.attrValues yen.assembly; inherit (yen.lib) holds; }; sinks = { # what the machine's own modules say; the facter and disko batteries write here nixos = { reduce = yen.lib.reduce.merge; out = { scope, sinks, ... }: { config.${scope.name} = sinks.nixos; }; }; # the disk layout: disko reads it; install makes the app `install-<machine>` of it disks = { reduce = yen.lib.reduce.merge; out = b.install.apps { # (2) from = yen.kinds.host.sinks.disks; inherit pkgs; report = h: "./hardware/${h.name}.json"; target = h: "root@${h.addr}"; }; }; # the deploy target (one per machine); rebuild makes the app `rebuild-<machine>` of it deploy = { reduce = yen.lib.reduce.one; out = b.deploy.rebuild { # (3) from = yen.kinds.host.sinks.deploy; inherit pkgs; }; }; }; };
yen.fleet.main = { }; yen.host = { lb = { addr = "10.0.0.1"; }; web = { addr = "10.0.0.2"; buildHost = "10.0.0.1"; }; nas.addr = "10.0.0.3"; }; yen.flake = { out, ... }: out;
yen.aspects = { nixos-disko = { at = yen.kinds.host; nixos = b.disko { from = yen.kinds.host.sinks.disks; }; # (4) }; deploy-target = { at = yen.host.web; deploy = { host, ... }: { inherit (host) buildHost; address = host.addr; user = "deploy"; }; }; };}(1)imports the kitsdiskoandfacter.(2)is theoutof the disks sink. It gives the appinstall-<machine>: nixos-anywhere with the disko layout. It writes the facter report to the pathreportgives for the machine. The app name comes from the scope name.(3)is theoutof the deploy sink. It gives the apprebuild-<machine>:nixos-rebuild switch --target-host user@address. It adds--build-hostwhen the deploy target has abuildHost.(4)is the NixOS key of the disks sink:disko.devicesis the merge of what the machine gave there.
No disks element, no install app; no deploy target, no rebuild app.
Arguments after -- go to the tool: a deploy user that is not root runs nix run .#rebuild-<machine> -- --sudo.
The assemblies of the two kits:
# Assemblies of the library kits. `layout` is a ref to a layout, never a string; `dir` holds one facter report per machine.{ yen, lib, ... }:{ yen.kinds.member = { }; yen.kinds.kit.fields = { roles = yen.lib.opt yen.lib.attrs { }; constraints = yen.lib.opt yen.lib.attrs { }; }; yen.kinds.assembly.fields = { kit = yen.kinds.kit; roles = yen.lib.opt yen.lib.attrs { }; }; yen.aspects.settings-typed = { at = yen.kinds.member; errors = yen.lib.batteries.kits.settings-typed; # (1) };
yen.assembly = { disk-lb = { kit = yen.kit.disko; roles.default = { at = yen.host.lb; settings = { device = "/dev/sda"; layout = yen.kit.disko.layouts.single-ext4; # (2) }; }; }; disk-web = { kit = yen.kit.disko; roles.default = { at = yen.host.web; settings = { device = "/dev/nvme0n1"; layout = yen.kit.disko.layouts.btrfs-luks; }; }; }; disk-nas = { kit = yen.kit.disko; roles.default = { at = yen.host.nas; settings = { device = "/dev/sda /dev/sdb"; layout = yen.kit.disko.layouts.zfs-mirror; }; }; }; hardware = { kit = yen.kit.facter; roles.default = { at = yen.host.lb; settings.dir = ../hardware; # (3) }; }; };}(1) checks the types of the settings. At (2), layout is a ref to a layout of the kit disko: yen.kit.disko.layouts.<name>.
A layout is a value of the kit, not a kind, so the kit adds no name outside itself. Each layout has a devices function
of the device string: single-ext4, btrfs-luks and zfs-mirror (two devices, separated by a space).
At (3), dir is the directory with one facter report per machine. Kit facter reads <dir>/<machine>.json.
The report of the install app is a function from the machine to a path, such as ./facter/<machine>.json. Point it into that directory.
Commit the report after the install, and the next build uses it. A machine with no report gets no facter config.
The result
Section titled “The result”The disk layouts reach each machine’s disko.devices, and the facter report its hardware.facter.reportPath:
{ lb = [ "main" ]; nas = [ "d0" "d1" ]; web = [ "main" ];}The apps, one per machine that has the input:
[ "install-lb" "install-nas" "install-web" "rebuild-web"]A layout is a value of the kit
Section titled “A layout is a value of the kit”A string where the layout goes is an error record, not a silent default:
# a name where a ref goes: the layout is a string{ yen, ... }:{ yen.assembly.disk-bad = { kit = yen.kit.disko; roles.default = { at = yen.host.web; settings = { device = "/dev/sda"; layout = "single-ext4"; }; }; };}[ "kits: disk-bad.default: setting layout is not a layout of kit disko (yen.kit.disko.layouts.<name>)"]The batteries and kits
Section titled “The batteries and kits”| Battery | Value of | Gives |
|---|---|---|
disko { from; } |
a NixOS key | disko.devices: the merge of what the machine gave to sink from |
install.apps { from; pkgs; report; target; flake; } |
out of the machine’s disks sink |
apps.<system>.install-<machine>: nixos-anywhere with the disko layout, writing the facter report to the path report gives for the machine |
deploy.rebuild { from; pkgs; flake; } |
out of the machine’s deploy sink |
apps.<system>.rebuild-<machine>: nixos-rebuild switch --target-host user@address, with --build-host when the deploy target has a buildHost |
| Kit | Role | Interface | Does |
|---|---|---|---|
lib.kits.disko |
default |
device (str), layout (one of yen.kit.disko.layouts) |
gives the layout’s disko devices to sink disks; owns its layouts, yen.kit.disko.layouts |
lib.kits.facter |
default |
dir (path) |
imports <dir>/<machine>.json with nixos.facter |