Files

85 lines
3.2 KiB
Nix
Raw Permalink Normal View History

{...}: {
# `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";
};
};
}