fix: include modifications missed by 528447c

Previous commit only picked up the new files (branding.nix, hardware-db.sh).
This adds the matching wires:

- core/system/default.nix: import branding.nix
- flake.nix: expose overlays.default = nomarchyOverlay for downstream flakes
- installer/disko-golden.nix: 1 GiB /boot, @snapshots subvolume, LUKS key
  via /dev/shm
- installer/install.sh: hardware auto-detect, hostname prompt, pinned
  nomarchy commit, shared pkgs in generated flake, flake.lock generation,
  post-install home-manager switch via nixos-enter

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-04-25 10:07:17 +01:00
parent 528447cc19
commit 04512eabcd
4 changed files with 299 additions and 106 deletions

View File

@@ -8,6 +8,13 @@ set -e
# For a customized installation, manually set up your disk and use the generated
# flake configuration as a starting point.
# Load the hardware-detection database — resolved relative to this script so it
# works whether we're invoked from /etc/install.sh on the live ISO or straight
# from a checkout.
_NOMARCHY_INSTALL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=hardware-db.sh
source "$_NOMARCHY_INSTALL_DIR/hardware-db.sh"
# Colors and styling
RED='\033[0;31m'
GREEN='\033[0;32m'
@@ -19,6 +26,8 @@ BOLD='\033[1m'
# Installer state
NOMARCHY_REPO=""
NOMARCHY_REV=""
HOSTNAME=""
TARGET_DRIVE=""
USERNAME=""
LUKS_PASSWORD=""
@@ -93,6 +102,18 @@ check_environment() {
fi
success "Found Nomarchy at $NOMARCHY_REPO"
# Capture the exact commit we're installing from. The generated flake
# pins `nomarchy.url` to this revision so the installed system can't
# silently drift onto a newer (possibly breaking) main.
if command -v git >/dev/null 2>&1 && [[ -d "$NOMARCHY_REPO/.git" ]]; then
NOMARCHY_REV=$(git -C "$NOMARCHY_REPO" rev-parse HEAD 2>/dev/null || echo "")
fi
if [[ -n "$NOMARCHY_REV" ]]; then
success "Pinning Nomarchy to $NOMARCHY_REV"
else
info "Could not determine Nomarchy revision; downstream flake will track main."
fi
# Check internet
gum spin --spinner dot --title "Checking internet connection..." -- sleep 1
while ! ping -c 1 -W 2 1.1.1.1 &>/dev/null; do
@@ -184,6 +205,13 @@ configure_user() {
success "Username: $USERNAME"
HOSTNAME=$(nrun gum input --value "nomarchy" --placeholder "Hostname for this machine")
if [[ -z "$HOSTNAME" ]] || [[ ! "$HOSTNAME" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
error "Invalid hostname (use lowercase letters, digits, and hyphens only)"
exit 1
fi
success "Hostname: $HOSTNAME"
# User password (can be same as LUKS or different)
info "Set a password for your user account"
local pass1 pass2
@@ -226,66 +254,147 @@ select_timezone() {
select_hardware() {
section "Hardware Configuration"
local product_name cpu_vendor
product_name=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "Unknown")
cpu_vendor=$(lscpu 2>/dev/null | grep "Vendor ID" | awk '{print $3}' || echo "Unknown")
info "Detected: $product_name"
info "CPU: $cpu_vendor"
local dmi_vendor dmi_product detect_output
dmi_vendor=$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || echo "Unknown")
dmi_product=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "Unknown")
info "DMI: $dmi_vendor / $dmi_product"
echo ""
# Set CPU-specific module
if [[ "$cpu_vendor" == "AuthenticAMD" ]]; then
HARDWARE_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-amd"
elif [[ "$cpu_vendor" == "GenuineIntel" ]]; then
HARDWARE_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-intel"
fi
# Auto-detect CPU, GPU, chassis, and known model from hardware-db.sh.
detect_output=$(nomarchy_detect_hw || true)
local vendor
vendor=$(gum choose --header "Select hardware vendor" \
"Generic (Auto-detect)" \
"Framework" \
"Dell" \
"Lenovo" \
"Apple (T2 Mac)" \
"Microsoft Surface" \
"Other...")
echo "Auto-detected:"
nomarchy_hw_summary <<< "$detect_output"
echo ""
case "$vendor" in
*Framework*)
local model
model=$(gum choose "16-7040-amd" "13-7040-amd" "13-intel-13th-gen" "13-intel-12th-gen")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.framework-$model"
NOMARCHY_HW_OPTS="nomarchy.hardware.isFramework = true;"
# Collect modules + nomarchy options from the detector output.
local modules=() hw_opts=()
while IFS= read -r line; do
case "$line" in
"MODULE "*) modules+=("${line#MODULE }") ;;
"OPT "*) hw_opts+=("${line#OPT }") ;;
esac
done <<< "$detect_output"
# Let the user accept, extend, or replace the detection.
local choice
choice=$(nrun gum choose --header "Hardware configuration" \
"Accept detected modules" \
"Add an extra nixos-hardware module" \
"Pick from the manual list (override)")
case "$choice" in
"Add an extra nixos-hardware module")
local extra
extra=$(nrun gum input --placeholder "e.g. asus-zephyrus-ga401 (no 'nixos-hardware.' prefix)")
[[ -n "$extra" ]] && modules+=("$extra")
;;
*Dell*)
local model
model=$(gum choose "xps-15-9500" "xps-15-9510" "xps-13-9310" "xps-13-9380" "precision-5530")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.dell-$model"
[[ "$model" == *"xps"* ]] && NOMARCHY_HW_OPTS="nomarchy.hardware.isXPS = true;"
;;
*Lenovo*)
local model
model=$(gum choose "thinkpad-x1-carbon-gen10" "thinkpad-t14-amd" "thinkpad-t480" "thinkpad-x1-extreme")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.lenovo-$model"
;;
*Apple*)
NOMARCHY_HW_OPTS="nomarchy.hardware.isT2Mac = true;"
;;
*Surface*)
local model
model=$(gum choose "surface-pro-9" "surface-pro-8" "surface-laptop-4")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.microsoft-$model"
;;
*Other*)
info "Enter nixos-hardware module path (or leave empty):"
local custom_mod
custom_mod=$(gum input --placeholder "e.g., inputs.nixos-hardware.nixosModules.asus-zephyrus-ga401")
[[ -n "$custom_mod" ]] && HARDWARE_MODULES="$HARDWARE_MODULES\n $custom_mod"
"Pick from the manual list (override)")
modules=()
hw_opts=()
_select_hardware_manual modules hw_opts
;;
esac
success "Hardware configuration set"
# De-duplicate while preserving order.
local seen="" uniq_mods=() m
for m in "${modules[@]}"; do
if [[ ":$seen:" != *":$m:"* ]]; then
uniq_mods+=("$m")
seen="$seen:$m"
fi
done
# Emit a list the heredoc in generate_flake_config splats into
# hardware-selection.nix's imports. The heredoc already indents the first
# line by 4 spaces — we add real newlines + 4 spaces (via $'\n ') for
# subsequent lines so every entry lines up.
HARDWARE_MODULES=""
for m in "${uniq_mods[@]}"; do
[[ -z "$HARDWARE_MODULES" ]] || HARDWARE_MODULES+=$'\n '
HARDWARE_MODULES+="inputs.nixos-hardware.nixosModules.${m}"
done
# Same treatment for nomarchy.hardware.* toggles.
NOMARCHY_HW_OPTS=""
local o
for o in "${hw_opts[@]}"; do
# opt is e.g. `isFramework=true` → `nomarchy.hardware.isFramework = true;`
local key="${o%%=*}" val="${o#*=}"
NOMARCHY_HW_OPTS+="nomarchy.hardware.${key} = ${val};"$'\n '
done
success "Hardware configuration set (${#uniq_mods[@]} module$([[ ${#uniq_mods[@]} -eq 1 ]] || echo s))"
}
# Manual fallback menu, kept for odd hardware the DB doesn't recognise yet.
# Writes into the two arrays named by its arguments (bash 4.3+ nameref).
_select_hardware_manual() {
local -n _mods_ref="$1"
local -n _opts_ref="$2"
local vendor
vendor=$(nrun gum choose --header "Pick vendor" \
"Framework" "Dell" "Lenovo" "Apple (T2 Mac)" "Microsoft Surface" "ASUS" "System76" "Other...")
case "$vendor" in
Framework)
local model
model=$(nrun gum choose \
"framework-16-7040-amd" \
"framework-13-amd-ai-300-series" \
"framework-13-7040-amd" \
"framework-13-13th-gen-intel" \
"framework-13-12th-gen-intel" \
"framework-13-11th-gen-intel")
_mods_ref+=("$model")
_opts_ref+=("isFramework=true")
;;
Dell)
local model
model=$(nrun gum choose \
"dell-xps-15-9500" "dell-xps-15-9510" "dell-xps-15-9520" \
"dell-xps-13-9310" "dell-xps-13-9370" "dell-xps-13-9380" \
"dell-precision-5530" "dell-latitude-7480")
_mods_ref+=("$model")
[[ "$model" == *xps* ]] && _opts_ref+=("isXPS=true")
;;
Lenovo)
local model
model=$(nrun gum choose \
"lenovo-thinkpad-x1-carbon-gen11" "lenovo-thinkpad-x1-carbon-gen10" \
"lenovo-thinkpad-x1-carbon-gen9" "lenovo-thinkpad-x1-extreme" \
"lenovo-thinkpad-t14-amd-gen3" "lenovo-thinkpad-t14-amd-gen2" \
"lenovo-thinkpad-t480" "lenovo-thinkpad-l13")
_mods_ref+=("$model")
;;
"Apple (T2 Mac)")
_mods_ref+=("apple-t2")
_opts_ref+=("isT2Mac=true")
;;
"Microsoft Surface")
local model
model=$(nrun gum choose \
"microsoft-surface-pro-9" "microsoft-surface-pro-8" "microsoft-surface-pro-7" \
"microsoft-surface-laptop-5" "microsoft-surface-laptop-4" "microsoft-surface-laptop-3")
_mods_ref+=("$model")
;;
ASUS)
local model
model=$(nrun gum choose \
"asus-zephyrus-ga403" "asus-zephyrus-ga402" "asus-zephyrus-ga401" \
"asus-zephyrus-ga503" "asus-rog-strix-g513" "asus-zenbook-ux")
_mods_ref+=("$model")
;;
System76)
_mods_ref+=("system76")
;;
"Other...")
local custom
custom=$(nrun gum input --placeholder "e.g. asus-zephyrus-ga401 (no 'nixos-hardware.' prefix)")
[[ -n "$custom" ]] && _mods_ref+=("$custom")
;;
esac
}
# ============================================================================
@@ -316,9 +425,11 @@ review_configuration() {
section "Review Configuration"
echo " Drive: $TARGET_DRIVE (BTRFS + LUKS2)"
echo " Hostname: $HOSTNAME"
echo " Username: $USERNAME"
echo " Timezone: $TIMEZONE"
echo " Impermanence: $ENABLE_IMPERMANENCE"
echo " Nomarchy rev: ${NOMARCHY_REV:-main (unpinned)}"
echo ""
nrun gum style --foreground 9 "This will DESTROY all data on $TARGET_DRIVE"
@@ -345,10 +456,16 @@ execute_installation() {
sed "s|@TARGET_DRIVE@|${TARGET_DRIVE}|g" "$disko_file" > "$tmp_disko"
# Provide the LUKS passphrase via a temporary file for disk encryption
echo -n "$LUKS_PASSWORD" > /tmp/secret.key
# Provide the LUKS passphrase via tmpfs so the secret never touches a
# spinning disk. /dev/shm is tmpfs on the live ISO. We restrict perms
# to root and shred the file (overwrite) on the way out, even though
# it's already in RAM — defense in depth.
local luks_key="/dev/shm/nomarchy-luks.key"
install -m 600 /dev/null "$luks_key"
printf '%s' "$LUKS_PASSWORD" > "$luks_key"
disko --mode disko "$tmp_disko"
rm /tmp/secret.key
shred -u "$luks_key" 2>/dev/null || rm -f "$luks_key"
unset LUKS_PASSWORD
success "Disk partitioned"
# 9.2 Generate hardware config
@@ -362,7 +479,16 @@ execute_installation() {
generate_flake_config
success "Configuration generated"
# 9.4 Initialize git repo
# 9.4 Resolve inputs once, here, and lock them. First boot then consumes
# the same flake.lock and doesn't re-resolve a newer upstream.
info "Resolving flake inputs (this pins nomarchy, nixpkgs, etc.)..."
(
cd /mnt/etc/nixos
nix --extra-experimental-features "nix-command flakes" flake lock >/dev/null
)
success "flake.lock written"
# 9.5 Initialize git repo so `nix` treats /etc/nixos as a flake worktree.
info "Initializing git repository..."
(
cd /mnt/etc/nixos
@@ -374,7 +500,7 @@ execute_installation() {
)
success "Git repository initialized"
# 9.5 Handle impermanence
# 9.6 Handle impermanence
if [[ "$ENABLE_IMPERMANENCE" == "true" ]]; then
info "Setting up impermanence..."
mkdir -p /mnt/persist/etc
@@ -384,9 +510,30 @@ execute_installation() {
success "Impermanence configured"
fi
# 9.6 Install
# 9.7 Install the NixOS system from the freshly-generated flake.
info "Running nixos-install (this will take a while)..."
nixos-install --flake /mnt/etc/nixos#default --no-root-passwd
nixos-install --flake "/mnt/etc/nixos#$HOSTNAME" --no-root-passwd
success "NixOS installed"
# 9.8 Activate Home Manager for $USERNAME inside the new system so the
# user's first login already has Nomarchy's dotfiles. `home-manager
# switch` must run as the target user with a real $HOME, so we use
# `runuser` (sudo -u keeps the caller's HOME → files land in /root).
info "Activating Home Manager for $USERNAME..."
if nixos-enter --root /mnt -- bash -c "
set -e
install -d -o '$USERNAME' -g users -m 0755 '/home/$USERNAME'
runuser -u '$USERNAME' -- env HOME='/home/$USERNAME' \
nix --extra-experimental-features 'nix-command flakes' \
run 'home-manager/release-25.11' -- switch \
--flake '/etc/nixos#$USERNAME' --impure
"; then
success "Home Manager activated"
else
error "Home Manager activation failed (non-fatal)."
info "Run \`nomarchy-env-update\` after the first login to retry."
fi
success "Installation complete!"
}
@@ -398,14 +545,25 @@ generate_flake_config() {
local impermanence_opt=""
[[ "$ENABLE_IMPERMANENCE" == "true" ]] && impermanence_opt="nomarchy.system.impermanence.enable = true;"
# flake.nix
cat > /mnt/etc/nixos/flake.nix << 'FLAKE_EOF'
# Pin the upstream Nomarchy flake to the exact commit we're installing
# from so the first post-reboot `nixos-rebuild` doesn't silently pull a
# newer main. Fall back to tracking main if we couldn't resolve a SHA.
local nomarchy_url
if [[ -n "$NOMARCHY_REV" ]]; then
nomarchy_url="github:bemagri/nomarchy/$NOMARCHY_REV"
else
nomarchy_url="github:bemagri/nomarchy"
fi
# flake.nix — the generator uses a non-quoted heredoc so $HOSTNAME,
# $USERNAME, and $nomarchy_url expand inline.
cat > /mnt/etc/nixos/flake.nix <<FLAKE_EOF
{
description = "My Nomarchy Configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nomarchy.url = "github:bemagri/nomarchy";
nomarchy.url = "$nomarchy_url";
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
home-manager = {
url = "github:nix-community/home-manager/release-25.11";
@@ -413,35 +571,52 @@ generate_flake_config() {
};
};
outputs = { self, nixpkgs, nomarchy, home-manager, nixos-hardware, ... }@inputs: {
nixosConfigurations.default = nixpkgs.lib.nixosSystem {
specialArgs = { inputs = nomarchy.inputs // inputs; };
modules = [
{ nixpkgs.hostPlatform = "x86_64-linux"; }
./hardware-configuration.nix
./hardware-selection.nix
nomarchy.nixosModules.system
./system.nix
];
};
# Two-track Nomarchy workflow:
# * System changes → sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME
# * Dotfiles/themes nomarchy-env-update (home-manager switch, no rebuild)
#
# Both consume the same \`pkgs\` below so overlays and allowUnfree stay in
# sync across the two paths.
outputs = { self, nixpkgs, nomarchy, home-manager, nixos-hardware, ... }@inputs:
let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
overlays = [ nomarchy.overlays.default ];
config.allowUnfree = true;
};
in
{
nixosConfigurations.$HOSTNAME = nixpkgs.lib.nixosSystem {
inherit pkgs;
specialArgs = { inputs = nomarchy.inputs // inputs; };
modules = [
./hardware-configuration.nix
./hardware-selection.nix
nomarchy.nixosModules.system
./system.nix
];
};
homeConfigurations.@USERNAME@ = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
extraSpecialArgs = { inputs = nomarchy.inputs // inputs; };
modules = [
nomarchy.nixosModules.home
./home.nix
{
home.username = "@USERNAME@";
home.homeDirectory = "/home/@USERNAME@";
home.stateVersion = "25.11";
}
];
# Standalone Home Manager — \`home-manager switch --flake /etc/nixos#$USERNAME\`
# (which is what \`nomarchy-env-update\` runs). Kept separate from the
# NixOS config so dotfile/theme iterations don't rebuild the system.
homeConfigurations.$USERNAME = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
extraSpecialArgs = { inputs = nomarchy.inputs // inputs; };
modules = [
nomarchy.nixosModules.home
./home.nix
{
home.username = "$USERNAME";
home.homeDirectory = "/home/$USERNAME";
home.stateVersion = "25.11";
}
];
};
};
};
}
FLAKE_EOF
sed -i "s/@USERNAME@/$USERNAME/g" /mnt/etc/nixos/flake.nix
# hardware-selection.nix
cat > /mnt/etc/nixos/hardware-selection.nix << EOF
@@ -455,10 +630,11 @@ FLAKE_EOF
EOF
# system.nix — curated system-level options. Uncomment what you want and
# run \`sudo nixos-rebuild switch --flake /etc/nixos#default\` to apply.
# run \`sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME\` to apply.
cat > /mnt/etc/nixos/system.nix << EOF
{ pkgs, ... }:
{
networking.hostName = "$HOSTNAME";
time.timeZone = "$TIMEZONE";
$impermanence_opt
@@ -609,8 +785,12 @@ finish() {
echo "Next steps:"
echo " 1. Remove the installation media"
echo " 2. Reboot your computer"
echo " 3. Log in with username: $USERNAME"
echo " 4. Your configuration is at /etc/nixos/"
echo " 3. Log in as: $USERNAME (host: $HOSTNAME)"
echo " 4. Your configuration lives at /etc/nixos/"
echo ""
echo "Rebuild commands:"
echo " • System: sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME"
echo " • Dotfiles: nomarchy-env-update (runs home-manager switch)"
echo ""
echo "Tip: run 'nomarchy-themes-prebuild' once to pre-cache every theme"
echo " variant. Theme switches after that are instant (no rebuild)."
@@ -641,7 +821,3 @@ main() {
}
main "$@"
finish
}
main "$@"