Audited every entry in `installer/hardware-db.sh` against
`inputs.nixos-hardware.nixosModules` and found **21 of 43 entries (49%)
referenced modules that don't exist** in the upstream attribute set —
those installs would fail at eval time with "attribute not found"
errors on real hardware. Specifically:
- Framework 13 per-gen: nixos-hardware uses `framework-11th-gen-intel`,
not `framework-13-11th-gen-intel`. Fixed all four generations.
- Framework 13 AMD AI 300: `framework-amd-ai-300-series` (no "13-").
- Framework Intel Core Ultra: added `framework-intel-core-ultra-series1`.
- Framework 16 AMD AI 300: added `framework-16-amd-ai-300-series`.
- Framework generic fallback now uses the `framework` umbrella module.
- ThinkPad X1 Carbon: modules are `lenovo-thinkpad-x1-Nth-gen`,
not `-x1-carbon-genN`. Fixed gens 6/7/9/10/11; added X1 Nano.
- ThinkPad P14s: requires arch+gen suffix; switched to the AMD gen3/4/5
modules (the prior `lenovo-thinkpad-p14s` had no attribute).
- Surface Pro 6/7/8/10: all share `microsoft-surface-pro-intel`. Pro 9
keeps its dedicated module. Pro 3 fixed to `-pro-3`. Surface Book
2/3 and Intel-based Surface Laptop 3/4/5: no nixos-hardware module
— rows dropped; generic chassis+cpu+gpu detection still emits
sensible `common-pc-laptop`.
- ASUS ROG Strix G513 → `asus-rog-strix-g513im` (correct attr name).
- ASUS ROG Zephyrus GA403 didn't exist — dropped. Added `ga402x`,
`gu603h`, `g533zw`.
- ASUS Zenbook generic `asus-zenbook-ux` was non-existent — dropped
(too vague; available modules are per-model like `asus-zenbook-ux481`).
- Dell Latitude 5400 / 7480: no modules — replaced with the existing
`dell-latitude-7420`, `7430`, `7490`.
Added:
- ROG Ally / Ally X support (`asus-ally-rc71l` for `RC71L`,
`RC72LA`, and the "ROG Ally" product string). nixos-hardware
currently ships one module for both revisions.
Documented (in a footer comment) the devices nixos-hardware doesn't
cover so they're known-unsupported rather than accidentally missing:
- Valve Steam Deck → Jovian-NixOS as a separate flake input.
- Snapdragon X laptops → aarch64 only; Nomarchy installer is x86_64.
- Raspberry Pi → same as above.
Bug discovered along the way: the DB's pipe-separated row format
collides with bash regex alternation. A row like
`Microsoft|Surface Pro (10|8|7|6)|_|module` parses as 7 fields, with
"7" extracted as the module name. Surface Pro variants are now one
row per version.
CI gate added (`.forgejo/workflows/check.yml`): a new step extracts
every 4th-pipe-field from `HARDWARE_DB` and `comm -23`s it against
`inputs.nixos-hardware.nixosModules`. Any future entry pointing at a
non-existent module fails CI with a clear error. Closes the regression
class entirely.
Verified locally: bash -n + shellcheck --severity=error pass on
hardware-db.sh; the CI step's exact commands pass against the new DB.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
213 lines
9.7 KiB
Bash
213 lines
9.7 KiB
Bash
# Nomarchy Hardware Database
|
|
#
|
|
# Flat table mapping detected DMI fields to `nixos-hardware` flake modules.
|
|
# Sourced by installer/install.sh at runtime.
|
|
#
|
|
# Format (pipe-separated):
|
|
# sys_vendor_regex | product_regex | nomarchy_hw_opt | nixos_hardware_module
|
|
#
|
|
# - Matching is bash `[[ =~ ]]` regex, case-insensitive.
|
|
# - Use "_" for `nomarchy_hw_opt` when there's no Nomarchy toggle to set.
|
|
# - Multiple modules can be joined with "+" if a device needs >1.
|
|
# - First match wins — put more specific entries (e.g. exact model years) above
|
|
# broader fallbacks.
|
|
#
|
|
# To add a new device: grab the string from `/sys/class/dmi/id/product_name`
|
|
# on the target machine and add a line here. See:
|
|
# https://github.com/NixOS/nixos-hardware/tree/master/<vendor>
|
|
# for the list of available module attributes.
|
|
|
|
HARDWARE_DB=(
|
|
# Framework ---------------------------------------------------------------
|
|
# Module names follow nixos-hardware's actual attrs — for Framework 13
|
|
# the per-generation modules dropped the "13-" prefix.
|
|
"Framework|Laptop 16.*AMD|isFramework=true|framework-16-7040-amd"
|
|
"Framework|Laptop 16.*Ryzen AI 300|isFramework=true|framework-16-amd-ai-300-series"
|
|
"Framework|Laptop 13.*Ryzen AI 300|isFramework=true|framework-amd-ai-300-series"
|
|
"Framework|Laptop 13.*Ryzen 7040|isFramework=true|framework-13-7040-amd"
|
|
"Framework|Laptop 13.*Core Ultra|isFramework=true|framework-intel-core-ultra-series1"
|
|
"Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13th-gen-intel"
|
|
"Framework|Laptop 13.*12th Gen Intel|isFramework=true|framework-12th-gen-intel"
|
|
"Framework|Laptop 13.*11th Gen Intel|isFramework=true|framework-11th-gen-intel"
|
|
"Framework|Laptop \(13.*|isFramework=true|framework"
|
|
|
|
# Dell XPS / Precision / Latitude ----------------------------------------
|
|
"Dell|XPS 15 9500|isXPS=true|dell-xps-15-9500"
|
|
"Dell|XPS 15 9510|isXPS=true|dell-xps-15-9510"
|
|
"Dell|XPS 15 9520|isXPS=true|dell-xps-15-9520"
|
|
"Dell|XPS 13 9310|isXPS=true|dell-xps-13-9310"
|
|
"Dell|XPS 13 9370|isXPS=true|dell-xps-13-9370"
|
|
"Dell|XPS 13 9380|isXPS=true|dell-xps-13-9380"
|
|
"Dell|XPS 13 7390|isXPS=true|dell-xps-13-7390"
|
|
"Dell|Precision 5530|_|dell-precision-5530"
|
|
"Dell|Latitude 7490|_|dell-latitude-7490"
|
|
"Dell|Latitude 7430|_|dell-latitude-7430"
|
|
"Dell|Latitude 7420|_|dell-latitude-7420"
|
|
|
|
# Lenovo ThinkPad --------------------------------------------------------
|
|
# X1 Carbon: the per-gen modules are named "x1-Nth-gen", not
|
|
# "x1-carbon-genN" — both naming schemes appeared in nixos-hardware and
|
|
# the old DB references picked the wrong one. Carbon-specific quirks
|
|
# match the X1 modules because the X1 series IS the Carbon line.
|
|
"LENOVO|ThinkPad X1 Carbon Gen 11|_|lenovo-thinkpad-x1-11th-gen"
|
|
"LENOVO|ThinkPad X1 Carbon Gen 10|_|lenovo-thinkpad-x1-10th-gen"
|
|
"LENOVO|ThinkPad X1 Carbon Gen 9|_|lenovo-thinkpad-x1-9th-gen"
|
|
"LENOVO|ThinkPad X1 Carbon Gen 7|_|lenovo-thinkpad-x1-7th-gen"
|
|
"LENOVO|ThinkPad X1 Carbon Gen 6|_|lenovo-thinkpad-x1-6th-gen"
|
|
"LENOVO|ThinkPad X1 Extreme|_|lenovo-thinkpad-x1-extreme"
|
|
"LENOVO|ThinkPad X1 Nano|_|lenovo-thinkpad-x1-nano-gen1"
|
|
"LENOVO|ThinkPad T14 Gen 3|_|lenovo-thinkpad-t14-amd-gen3"
|
|
"LENOVO|ThinkPad T14 Gen 2|_|lenovo-thinkpad-t14-amd-gen2"
|
|
"LENOVO|ThinkPad T14 Gen 1|_|lenovo-thinkpad-t14-amd-gen1"
|
|
"LENOVO|ThinkPad T480|_|lenovo-thinkpad-t480"
|
|
"LENOVO|ThinkPad L13|_|lenovo-thinkpad-l13"
|
|
"LENOVO|ThinkPad P14s.*Gen 5|_|lenovo-thinkpad-p14s-amd-gen5"
|
|
"LENOVO|ThinkPad P14s.*Gen 4|_|lenovo-thinkpad-p14s-amd-gen4"
|
|
"LENOVO|ThinkPad P14s.*Gen 3|_|lenovo-thinkpad-p14s-amd-gen3"
|
|
|
|
# Microsoft Surface ------------------------------------------------------
|
|
# nixos-hardware ships per-chip modules, not per-revision: Intel Surface
|
|
# Pros (6 through 10) all use `microsoft-surface-pro-intel`; AMD Surface
|
|
# Laptops use `microsoft-surface-laptop-amd`. Surface Pro 9 has its own
|
|
# variant for the SQ3 / ARM model — kept separate. Surface Book and
|
|
# Intel-based Surface Laptops have no dedicated module; we fall back to
|
|
# the common detection (chassis + cpu + gpu).
|
|
"Microsoft|Surface Pro 10|_|microsoft-surface-pro-intel"
|
|
"Microsoft|Surface Pro 9|_|microsoft-surface-pro-9"
|
|
"Microsoft|Surface Pro 8|_|microsoft-surface-pro-intel"
|
|
"Microsoft|Surface Pro 7|_|microsoft-surface-pro-intel"
|
|
"Microsoft|Surface Pro 6|_|microsoft-surface-pro-intel"
|
|
"Microsoft|Surface Pro 3|_|microsoft-surface-pro-3"
|
|
"Microsoft|Surface Laptop.*Ryzen|_|microsoft-surface-laptop-amd"
|
|
"Microsoft|Surface Go|_|microsoft-surface-go"
|
|
|
|
# ASUS ROG Ally / Zephyrus / Strix --------------------------------------
|
|
# Ally is the handheld (Z1 Extreme / Z1). RC71L is the original Ally,
|
|
# RC72LA is the Ally X — both share the same nixos-hardware module
|
|
# currently.
|
|
"ASUS.*|RC71L|_|asus-ally-rc71l"
|
|
"ASUS.*|RC72LA|_|asus-ally-rc71l"
|
|
"ASUS.*|ROG Ally|_|asus-ally-rc71l"
|
|
"ASUS.*|ROG Zephyrus G14.*GA402X|_|asus-zephyrus-ga402x"
|
|
"ASUS.*|ROG Zephyrus G14.*GA402|_|asus-zephyrus-ga402"
|
|
"ASUS.*|ROG Zephyrus G14.*GA401|_|asus-zephyrus-ga401"
|
|
"ASUS.*|ROG Zephyrus G15|_|asus-zephyrus-ga503"
|
|
"ASUS.*|ROG Zephyrus.*GU603|_|asus-zephyrus-gu603h"
|
|
"ASUS.*|ROG Strix G513|_|asus-rog-strix-g513im"
|
|
"ASUS.*|ROG Strix G533|_|asus-rog-strix-g533zw"
|
|
|
|
# Apple (T2 Intel; M-series falls back to asahi elsewhere) ---------------
|
|
"Apple.*|MacBookPro15|isT2Mac=true|apple-t2"
|
|
"Apple.*|MacBookPro16|isT2Mac=true|apple-t2"
|
|
"Apple.*|MacBookAir8|isT2Mac=true|apple-t2"
|
|
"Apple.*|MacBookAir9|isT2Mac=true|apple-t2"
|
|
"Apple.*|iMac19|isT2Mac=true|apple-t2"
|
|
"Apple.*|iMacPro1|isT2Mac=true|apple-t2"
|
|
|
|
# System76 ---------------------------------------------------------------
|
|
"System76|Oryx Pro.*|_|system76"
|
|
"System76|Lemur Pro.*|_|system76"
|
|
"System76|Darter Pro.*|_|system76"
|
|
"System76|Galago Pro.*|_|system76"
|
|
"System76|Pangolin.*|_|system76"
|
|
|
|
# Devices nixos-hardware doesn't cover (yet) -----------------------------
|
|
# Listed here so future contributors know they're known-unsupported, not
|
|
# accidentally missing:
|
|
# - Valve Steam Deck (Galileo / Jupiter): try Jovian-NixOS as a flake
|
|
# input instead — separate ecosystem, not in nixos-hardware.
|
|
# - Snapdragon X laptops (Surface Pro 11, Lenovo Yoga Slim 7x, …):
|
|
# aarch64-only and the Nomarchy installer is x86_64 only.
|
|
# - Raspberry Pi (ARM): same — installer is x86_64 only.
|
|
)
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# nomarchy_detect_hw
|
|
#
|
|
# Inspects DMI + lspci + /sys to figure out which nixos-hardware modules fit
|
|
# the running machine. Emits (on stdout) one line per result:
|
|
#
|
|
# MODULE <module-name>
|
|
# OPT <nomarchy_hw_opt> # zero or more, one per line
|
|
# DETAIL <human-readable hit>
|
|
#
|
|
# Return codes: 0 if at least one module was detected, 1 otherwise.
|
|
# ----------------------------------------------------------------------------
|
|
nomarchy_detect_hw() {
|
|
local sys_vendor product_name board_name cpu_vendor
|
|
sys_vendor=$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || echo "")
|
|
product_name=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "")
|
|
board_name=$(cat /sys/class/dmi/id/board_name 2>/dev/null || echo "")
|
|
cpu_vendor=$(lscpu 2>/dev/null | awk -F: '/Vendor ID/{gsub(/ /,"",$2); print $2; exit}')
|
|
|
|
local detected=0
|
|
|
|
# CPU --------------------------------------------------------------------
|
|
case "$cpu_vendor" in
|
|
AuthenticAMD) echo "MODULE common-cpu-amd"; echo "DETAIL cpu: AMD"; detected=1 ;;
|
|
GenuineIntel) echo "MODULE common-cpu-intel"; echo "DETAIL cpu: Intel"; detected=1 ;;
|
|
esac
|
|
|
|
# GPU (lspci may list multiple; handle all) -----------------------------
|
|
if command -v lspci >/dev/null 2>&1; then
|
|
local gpu_line nvidia=0 amdgpu=0 intelgpu=0
|
|
while IFS= read -r gpu_line; do
|
|
case "$gpu_line" in
|
|
*"[10de:"*|*"NVIDIA"*) nvidia=1 ;;
|
|
*"[1002:"*|*"AMD/ATI"*|*"Advanced Micro Devices"*) amdgpu=1 ;;
|
|
*"[8086:"*|*"Intel Corporation"*) intelgpu=1 ;;
|
|
esac
|
|
done < <(lspci -nn 2>/dev/null | grep -iE 'vga|3d|display')
|
|
|
|
(( nvidia )) && { echo "MODULE common-gpu-nvidia"; echo "DETAIL gpu: NVIDIA"; detected=1; }
|
|
(( amdgpu )) && { echo "MODULE common-gpu-amd"; echo "DETAIL gpu: AMD"; detected=1; }
|
|
(( intelgpu )) && { echo "MODULE common-gpu-intel"; echo "DETAIL gpu: Intel"; detected=1; }
|
|
fi
|
|
|
|
# Laptop / SSD ----------------------------------------------------------
|
|
if compgen -G "/sys/class/power_supply/BAT*" >/dev/null; then
|
|
echo "MODULE common-pc-laptop"
|
|
echo "DETAIL chassis: laptop (battery present)"
|
|
detected=1
|
|
else
|
|
echo "MODULE common-pc"
|
|
echo "DETAIL chassis: desktop"
|
|
detected=1
|
|
fi
|
|
|
|
# Model-specific match from the DB --------------------------------------
|
|
local entry v_re p_re opt mod
|
|
for entry in "${HARDWARE_DB[@]}"; do
|
|
IFS='|' read -r v_re p_re opt mod <<< "$entry"
|
|
shopt -s nocasematch
|
|
if [[ "$sys_vendor" =~ $v_re ]] && [[ "$product_name" =~ $p_re ]]; then
|
|
shopt -u nocasematch
|
|
echo "MODULE $mod"
|
|
[[ "$opt" != "_" ]] && echo "OPT $opt"
|
|
echo "DETAIL model: $sys_vendor $product_name → $mod"
|
|
detected=1
|
|
break
|
|
fi
|
|
shopt -u nocasematch
|
|
done
|
|
|
|
return $(( 1 - detected ))
|
|
}
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# nomarchy_hw_summary
|
|
#
|
|
# Pretty-prints the output of `nomarchy_detect_hw` for TUI consumption.
|
|
# Reads from stdin.
|
|
# ----------------------------------------------------------------------------
|
|
nomarchy_hw_summary() {
|
|
local line key val
|
|
while IFS= read -r line; do
|
|
key="${line%% *}"
|
|
val="${line#* }"
|
|
case "$key" in
|
|
DETAIL) echo " → $val" ;;
|
|
esac
|
|
done
|
|
}
|