From bf30cd07d890e2a9c24e9d1bb9b4b5b4c4cdb34e Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sat, 25 Apr 2026 21:49:36 +0100 Subject: [PATCH] feat(installer): richer disk picker (vendor, model, serial, type) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the bare `NAME SIZE` lsblk listing in select_disk with a six-column table — NAME, SIZE, TYPE, VENDOR, MODEL, SERIAL — aligned via column -t. TYPE is derived from ROTA + TRAN (NVMe / USB / SSD / HDD). Empty vendor/model/serial fields render as `--` instead of collapsing the alignment. Filters loop, ram, zram, sr devices. Roadmap row moves to Shipped. Co-Authored-By: Claude Opus 4.7 --- docs/ROADMAP.md | 4 +-- installer/install.sh | 62 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 9ef4cbe..9acfd4a 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -20,7 +20,6 @@ Guardrails (apply when adding anything): ### Now (ready to pick up) - **Software-profile multi-select in the installer.** Carryover from the old TODO. Add a `gum choose --no-limit` step in `installer/install.sh` (between hardware and impermanence) for opt-in profiles (Dev, Gaming, Office, Media, …). Each profile maps to a list of `home.packages` and optional `nomarchy.system.*` toggles emitted into the generated `home.nix`/`system.nix`. -- **Richer disk metadata.** Carryover from the old TODO. Replace the bare `lsblk` line in `select_disk` with `lsblk -O -J` parsed via `jq`, surfacing vendor, model, serial, and size in the picker. - **Menu cleanup of orphaned references.** Walk `features/scripts/utils/nomarchy-menu` (379 lines, 23 submenus) and either wire each menu item to a real script or replace the `case` arm with a stubbed `notify-send` until the script is ported. See Pillar 3 below. - **Form-factor → laptop preset auto-enable.** When the installer writes `nomarchy.system.formFactor = "laptop"`, also flip on a yet-to-be-built laptop preset (TLP, brightness keys, lid handling). The option exists; the preset module doesn't. @@ -82,7 +81,7 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes, ## 4. Pillar: Installer - Software-profile multi-select (Now). -- Richer disk metadata (Now). +- Richer disk metadata (Shipped). - Form-factor → laptop preset (Now, depends on Pillar 5). - `disko-golden.nix` variants for software-RAID and BTRFS-pool-as-root. - Pre-flight resume polish (Next). @@ -130,5 +129,6 @@ Each PR description should reference the row(s) in `docs/SCRIPTS.md` it closes, (Move items here when they land — keep them brief, link the commit/PR.) - _2026-04-25_ — `docs/KEYBINDINGS.md` auto-generator. New repo-tooling script `bin/utils/nomarchy-docs-keybindings` parses every `bindd =` / `bindeld =` line into a Markdown doc; README's keybinding table slimmed to highlights + link. +- _2026-04-25_ — Installer disk picker shows NAME / SIZE / TYPE / VENDOR / MODEL / SERIAL columns instead of bare `lsblk`. Type derived from `ROTA` + `TRAN` (NVMe / USB / SSD / HDD). Filters loop, ram, zram, sr. - _2026-04-25_ — Installer prompts for keyboard layout + locale, applies live; new `nomarchy.{system,}.formFactor` option; waybar drops battery widget on desktop; nm-applet visibility fix in default theme; live-ISO baseline keymap/locale (`a7e7fa9`). - _2026-04-25_ — `docs/OPTIONS.md` reference; `docs/MIGRATION.md` linked from `README.md` (`3cb012b`, `6ef28f0`). diff --git a/installer/install.sh b/installer/install.sh index da24ccd..990e6bc 100755 --- a/installer/install.sh +++ b/installer/install.sh @@ -220,14 +220,68 @@ select_disk() { return fi + # Build a richer drive table than the bare `NAME SIZE` lsblk default. + # Columns: NAME, SIZE, TYPE (NVMe/USB/SSD/HDD), VENDOR, MODEL, SERIAL. + # Empty fields render as "--" so column -t can still align them. + local raw rows="" + raw=$(lsblk -d -n -p -o NAME,SIZE,ROTA,TRAN,VENDOR,MODEL,SERIAL 2>/dev/null \ + | grep -vE '^(/dev/(loop|ram|zram|sr))') + + while IFS= read -r line; do + [[ -z "$line" ]] && continue + # NAME and SIZE are reliably whitespace-free; ROTA/TRAN are short + # tokens; VENDOR/MODEL/SERIAL can carry internal spaces. Pull the + # first four fields off the front, treat the rest as the + # vendor/model/serial trio split via the original lsblk column + # widths — easier to just re-query each device for clean values. + local dev size rota tran + read -r dev size rota tran _ <<<"$line" + + local type vendor model serial + case "$tran" in + nvme) type="NVMe" ;; + usb) type="USB" ;; + sata|scsi) + if [[ "$rota" == "1" ]]; then type="HDD"; else type="SSD"; fi + ;; + *) + if [[ "$rota" == "1" ]]; then type="HDD"; else type="SSD"; fi + ;; + esac + + vendor=$(lsblk -d -n -o VENDOR "$dev" 2>/dev/null | sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//') + model=$(lsblk -d -n -o MODEL "$dev" 2>/dev/null | sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//') + serial=$(lsblk -d -n -o SERIAL "$dev" 2>/dev/null | sed -E 's/^[[:space:]]+//;s/[[:space:]]+$//') + [[ -z "$vendor" ]] && vendor="--" + [[ -z "$model" ]] && model="--" + [[ -z "$serial" ]] && serial="--" + + # Tab-separated for column -t -s, then collapse internal whitespace + # in MODEL so multi-space brand strings don't break alignment. + rows+=$(printf '%s\t%s\t%s\t%s\t%s\t%s\n' \ + "$dev" "$size" "$type" "$vendor" "${model//$'\t'/ }" "$serial") + rows+=$'\n' + done <<<"$raw" + + if [[ -z "$rows" ]]; then + error "No installable drives found." + exit 1 + fi + info "Available drives:" echo "" - lsblk -d -n -p -o NAME,SIZE,MODEL | grep -v loop + { + printf 'NAME\tSIZE\tTYPE\tVENDOR\tMODEL\tSERIAL\n' + printf '%s' "$rows" + } | column -t -s $'\t' echo "" - local drives - drives=$(lsblk -d -n -p -o NAME,SIZE | grep -v loop) - TARGET_DRIVE=$(echo "$drives" | gum choose --header "Select target drive" | awk '{print $1}') + # gum choose gets the same aligned rows so the picker reads like the table. + local picker + picker=$(printf '%s' "$rows" | column -t -s $'\t') + local choice + choice=$(printf '%s\n' "$picker" | gum choose --header "Select target drive") + TARGET_DRIVE=$(awk '{print $1}' <<<"$choice") if [[ -z "$TARGET_DRIVE" ]]; then error "No drive selected"