85 lines
3.2 KiB
Nix
85 lines
3.2 KiB
Nix
{...}: {
|
|||
|
|
# `nix run .#sync-hardware`
|
||
|
|
#
|
||
|
|
# Refreshes the calling host's generated hardware module in-repo, replacing the
|
||
|
|
# old habit of importing /etc/nixos/hardware-configuration.nix by absolute path.
|
||
|
|
#
|
||
|
|
# Why bother: that absolute import left the flake impure (every eval needed
|
||
|
|
# --impure, since the file lives outside the store) and — worse — meant *both*
|
||
|
|
# hosts resolved to whichever machine's hardware file was on disk at build
|
||
|
|
# time. Building t480 from shadow silently baked in shadow's disk UUIDs.
|
||
|
|
#
|
||
|
|
# Run this on a host after changing its hardware, then commit the result.
|
||
|
|
perSystem = {pkgs, ...}: let
|
||
|
|
script = pkgs.writeShellApplication {
|
||
|
|
name = "sync-hardware";
|
||
|
|
runtimeInputs = [pkgs.nixos-install-tools pkgs.git pkgs.coreutils pkgs.nettools];
|
||
|
|
text = ''
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
host="''${1:-$(hostname)}"
|
||
|
|
|
||
|
|
root=$(git rev-parse --show-toplevel 2>/dev/null || true)
|
||
|
|
if [ -z "$root" ]; then
|
||
|
|
echo "sync-hardware: run this from inside the config repo." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
dir="$root/modules/hosts/$host"
|
||
|
|
if [ ! -d "$dir" ]; then
|
||
|
|
echo "sync-hardware: no host directory at $dir" >&2
|
||
|
|
echo " known hosts: $(cd "$root/modules/hosts" && echo *)" >&2
|
||
|
|
echo " pass an explicit name with: nix run .#sync-hardware -- <host>" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
out="$dir/_hardware.nix"
|
||
|
|
|
||
|
|
# --no-filesystems is load-bearing: fileSystems/swapDevices are declared
|
||
|
|
# by hand in the host's disks.nix. Without the flag this would emit
|
||
|
|
# entries for whatever is mounted right now, duplicating (and conflicting
|
||
|
|
# with) those definitions.
|
||
|
|
header=$(cat <<'EOF'
|
||
|
|
# GENERATED FILE — do not edit by hand.
|
||
|
|
#
|
||
|
|
# Regenerate on the host itself with: nix run .#sync-hardware
|
||
|
|
#
|
||
|
|
# Produced by `nixos-generate-config --show-hardware-config --no-filesystems`.
|
||
|
|
# The --no-filesystems flag is deliberate: fileSystems and swapDevices are
|
||
|
|
# declared by hand in ./disks.nix, so regenerating this file can never clobber
|
||
|
|
# them or emit duplicates for whatever happened to be mounted at the time.
|
||
|
|
#
|
||
|
|
# Leading underscore keeps import-tree from auto-importing this as a
|
||
|
|
# flake-parts module (its filter drops any path containing "/_"); it is
|
||
|
|
# imported explicitly from ./default.nix instead.
|
||
|
|
EOF
|
||
|
|
)
|
||
|
|
|
||
|
|
tmp=$(mktemp)
|
||
|
|
trap 'rm -f "$tmp"' EXIT
|
||
|
|
|
||
|
|
# Strip the upstream 3-line "Do not modify" banner; ours replaces it.
|
||
|
|
{
|
||
|
|
printf '%s\n' "$header" | sed 's/^ //'
|
||
|
|
nixos-generate-config --show-hardware-config --no-filesystems | tail -n +4
|
||
|
|
} > "$tmp"
|
||
|
|
|
||
|
|
if [ -f "$out" ] && cmp -s "$tmp" "$out"; then
|
||
|
|
echo "sync-hardware: $out already up to date."
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
cp "$tmp" "$out"
|
||
|
|
echo "sync-hardware: wrote $out"
|
||
|
|
echo " review with: git diff -- $out"
|
||
|
|
'';
|
||
|
|
};
|
||
|
|
in {
|
||
|
|
apps.sync-hardware = {
|
||
|
|
type = "app";
|
||
|
|
program = "${script}/bin/sync-hardware";
|
||
|
|
meta.description = "Regenerate modules/hosts/<host>/_hardware.nix from the running machine";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|