nixos/facter: add debug utilities

This adds debugging tools for comparing system configurations with and
without facter-based hardware detection:

Example usage:
  nix-build '<nixpkgs/nixos>' -A config.hardware.facter.debug.nvd
  ./result/bin/facter-diff

Builds on PR #466808 (camera support).
Part of incremental upstreaming from nixos-facter-modules.
This commit is contained in:
Jörg Thalheim
2025-10-21 17:21:48 +02:00
parent 46a47f3891
commit 7c087d58df
4 changed files with 137 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
{
lib,
pkgs,
config,
extendModules,
...
}:
{
options = {
system.build = {
noFacter = lib.mkOption {
type = lib.types.unspecified;
description = "A version of the system closure with facter disabled";
};
};
hardware.facter.debug = {
nvd = lib.mkOption {
type = lib.types.package;
description = ''
A shell application which will produce an nvd diff of the system closure with and without facter enabled.
'';
};
nix-diff = lib.mkOption {
type = lib.types.package;
description = ''
A shell application which will produce a nix-diff of the system closure with and without facter enabled.
'';
};
};
};
config.system.build = {
noFacter = extendModules {
modules = [
{
# we 'disable' facter by overriding the report and setting it to empty with one caveat: hostPlatform
config.hardware.facter.report = lib.mkForce {
system = config.nixpkgs.hostPlatform;
};
}
];
};
};
config.hardware.facter.debug = {
nvd = pkgs.writeShellApplication {
name = "facter-nvd-diff";
runtimeInputs = [
config.nix.package
pkgs.nvd
];
text = ''
nvd diff \
${config.system.build.noFacter.config.system.build.toplevel} \
${config.system.build.toplevel} \
"$@"
'';
};
nix-diff = pkgs.writeShellApplication {
name = "facter-nix-diff";
runtimeInputs = [
config.nix.package
pkgs.nix-diff
];
text = ''
nix-diff \
${config.system.build.noFacter.config.system.build.toplevel} \
${config.system.build.toplevel} \
"$@"
'';
};
};
}
@@ -7,6 +7,7 @@
imports = [
./bluetooth.nix
./camera
./debug.nix
./disk.nix
./fingerprint
./firmware.nix
+3
View File
@@ -1,6 +1,7 @@
{
lib,
buildGoModule,
callPackage,
fetchFromGitHub,
hwinfo,
libusb1,
@@ -64,6 +65,8 @@ buildGoModule rec {
passthru.tests = {
inherit (nixosTests) facter;
debug-nvd = callPackage ./test-debug-nvd.nix { };
debug-nix-diff = nixosTests.facter.nodes.machine.hardware.facter.debug.nix-diff;
};
meta = {
@@ -0,0 +1,52 @@
{
runCommand,
jq,
nix,
nixosTests,
}:
let
facterDebug = nixosTests.facter.nodes.machine.hardware.facter.debug;
withFacter = nixosTests.facter.nodes.machine.system.build.toplevel;
noFacter = nixosTests.facter.nodes.machine.system.build.noFacter.config.system.build.toplevel;
in
runCommand "facter-debug-nvd-test"
{
nativeBuildInputs = [
facterDebug.nvd
jq
nix
];
__structuredAttrs = true;
unsafeDiscardReferences.out = true;
exportReferencesGraph.withFacter = [ withFacter ];
exportReferencesGraph.noFacter = [ noFacter ];
}
''
# Set up nix environment with read-only store but writable state
mkdir -p "$TMPDIR/nix"/{var/nix,var/log/nix,etc}
export NIX_REMOTE=""
export NIX_STATE_DIR="$TMPDIR/nix/var/nix"
export NIX_LOG_DIR="$TMPDIR/nix/var/log/nix"
export NIX_CONF_DIR="$TMPDIR/nix/etc"
cat > "$TMPDIR/nix/etc/nix.conf" <<EOF
substituters =
sandbox = false
EOF
# Initialize store database and register paths from exportReferencesGraph
nix-store --init
# Convert exportReferencesGraph JSON to nix-store --load-db format
jq -r '(.withFacter + .noFacter)[] | "\(.path)\n\(.narHash)\n\(.narSize)\n\n\(.references | length)\(if .references | length > 0 then "\n" + (.references | join("\n")) else "" end)"' \
< "$NIX_ATTRS_JSON_FILE" | nix-store --load-db
# Run nvd and verify it produces output
facter-nvd-diff > nvd-output.txt
if [ ! -s nvd-output.txt ]; then
echo "facter-nvd-diff produced no output"
exit 1
fi
cat nvd-output.txt
echo "nvd debug utility works correctly" > $out
''