feat: smarter installer + Nomarchy os-release rebrand

Hardware:
- New installer/hardware-db.sh: flat regex table mapping sys_vendor +
  product_name to nixos-hardware modules (Framework, Dell, Lenovo, Surface,
  ASUS, Apple T2, System76).
- install.sh:select_hardware now auto-detects CPU vendor, GPU vendor, chassis
  type, and known model, then offers Accept / Add / Override. Manual menu
  retained as a fallback.
- Fixes a latent bug where HARDWARE_MODULES used literal "\n" inside a
  heredoc, producing invalid Nix.

Downstream flake:
- Capture the running Nomarchy commit and pin `nomarchy.url` to it so the
  installed system can't drift onto a newer breaking main.
- Prompt for a real hostname; nixosConfigurations.<hostname> replaces the
  generic .default. networking.hostName lands in system.nix.
- Generated flake now derives a single `pkgs` from nixpkgs + Nomarchy's
  `overlays.default` and shares it between nixosSystem and the standalone
  homeManagerConfiguration so dotfile-fast-iteration with nomarchy-env-update
  stays separate from `nixos-rebuild` while still seeing Nomarchy packages.
- `nix flake lock` runs in /mnt/etc/nixos before nixos-install so first boot
  consumes the resolved set.
- Post-install, run home-manager switch inside `nixos-enter` via runuser so
  the user's first login already has dotfiles. Failure is non-fatal.

Disk layout:
- /boot bumped to 1 GiB (was 512 MiB; tight with multi-generation kernels).
- New @snapshots subvolume at /.snapshots for snapper/btrbk/rollback.
- LUKS passphrase moved from /tmp/secret.key to /dev/shm/nomarchy-luks.key
  (tmpfs), shredded after disko, LUKS_PASSWORD unset.

Branding:
- New core/system/branding.nix sets system.nixos.distroId = "nomarchy" and
  distroName = "Nomarchy". /etc/os-release now reports Nomarchy, so fastfetch
  and other os-release readers show the right name.

Cleanup:
- flake.nix exposes `overlays.default = nomarchyOverlay` for downstream use.
- Trailing duplicated `main "$@"` + orphan `}` removed from install.sh.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-04-25 10:06:47 +01:00
parent 877da19770
commit 528447cc19
2 changed files with 193 additions and 0 deletions

11
core/system/branding.nix Normal file
View File

@@ -0,0 +1,11 @@
{ ... }:
{
# Identify the distribution as Nomarchy in /etc/os-release.
# Anything that reads os-release picks this up: fastfetch, login banners,
# GUI "About" dialogs, neofetch, etc.
system.nixos = {
distroId = "nomarchy";
distroName = "Nomarchy";
};
}

182
installer/hardware-db.sh Normal file
View File

@@ -0,0 +1,182 @@
# 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 ---------------------------------------------------------------
"Framework|Laptop 16.*AMD|isFramework=true|framework-16-7040-amd"
"Framework|Laptop 13.*AMD Ryzen AI 300|isFramework=true|framework-13-amd-ai-300-series"
"Framework|Laptop 13.*AMD Ryzen 7040|isFramework=true|framework-13-7040-amd"
"Framework|Laptop 13.*13th Gen Intel|isFramework=true|framework-13-13th-gen-intel"
"Framework|Laptop 13.*12th Gen Intel|isFramework=true|framework-13-12th-gen-intel"
"Framework|Laptop 13.*11th Gen Intel|isFramework=true|framework-13-11th-gen-intel"
"Framework|Laptop \(13.*|isFramework=true|framework-13-11th-gen-intel"
# 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 7480|_|dell-latitude-7480"
"Dell|Latitude 5400|_|dell-latitude-5400"
# Lenovo ThinkPad --------------------------------------------------------
"LENOVO|ThinkPad X1 Carbon Gen 11|_|lenovo-thinkpad-x1-carbon-gen11"
"LENOVO|ThinkPad X1 Carbon Gen 10|_|lenovo-thinkpad-x1-carbon-gen10"
"LENOVO|ThinkPad X1 Carbon Gen 9|_|lenovo-thinkpad-x1-carbon-gen9"
"LENOVO|ThinkPad X1 Extreme|_|lenovo-thinkpad-x1-extreme"
"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|_|lenovo-thinkpad-p14s"
# Microsoft Surface ------------------------------------------------------
"Microsoft|Surface Pro 9|_|microsoft-surface-pro-9"
"Microsoft|Surface Pro 8|_|microsoft-surface-pro-8"
"Microsoft|Surface Pro 7|_|microsoft-surface-pro-7"
"Microsoft|Surface Pro 6|_|microsoft-surface-pro-6"
"Microsoft|Surface Laptop 5|_|microsoft-surface-laptop-5"
"Microsoft|Surface Laptop 4|_|microsoft-surface-laptop-4"
"Microsoft|Surface Laptop 3|_|microsoft-surface-laptop-3"
"Microsoft|Surface Go|_|microsoft-surface-go"
"Microsoft|Surface Book 3|_|microsoft-surface-book-3"
"Microsoft|Surface Book 2|_|microsoft-surface-book-2"
# ASUS ROG / Zephyrus ----------------------------------------------------
"ASUS.*|ROG Zephyrus G14.*2024|_|asus-zephyrus-ga403"
"ASUS.*|ROG Zephyrus G14.*2023|_|asus-zephyrus-ga402"
"ASUS.*|ROG Zephyrus G14.*2021|_|asus-zephyrus-ga401"
"ASUS.*|ROG Zephyrus G15|_|asus-zephyrus-ga503"
"ASUS.*|ROG Strix G15|_|asus-rog-strix-g513"
"ASUS.*|Zenbook UX|_|asus-zenbook-ux"
# 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"
# Raspberry Pi (ARM) — listed for completeness; installer is x86_64 only -
# "Raspberry Pi|Raspberry Pi 5|_|raspberry-pi-5"
# "Raspberry Pi|Raspberry Pi 4|_|raspberry-pi-4"
)
# ----------------------------------------------------------------------------
# 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
}