Server Installer_

A dialog-driven, text-mode installer for headless and console NextBSD server deployments. This document specifies the screen-by-screen flow, interaction model, and visual treatment.

DESIGN DOC TUI / dialog(1) STYLE VGA + SERIAL CONSOLE KEYBOARD-ONLY NAV

The installer runs in a 80×24 (or larger) text console. Navigation is keyboard-only: to move, Space to toggle, Tab to jump between widgets and buttons, Enter to confirm. The palette is deliberately minimal — amber on black — to remain legible on real serial terminals, VGA text mode, and modern emulators alike, while the highlight bar inverts to draw the eye.

① Mode──▶ ② Target Disk──▶ ③ Account + Hostname──▶ ④ Install Progress──▶ ⑤ Finish

1Install Mode

First screen after boot. The Upgrade option is greyed out and unselectable unless a probe detects an existing NextBSD install on an attached disk.

PHASE 1 · NO EXISTING INSTALL
┌─────────────────────────  NextBSD Installer  ──────────────────────────┐
│                                                                        │
│   Welcome to NextBSD Server                                            │
│   continuous · 2026-06-08 00:19 UTC · 0d5f191                          │
│                                                                        │
│   Choose an action.  Use ↑↓ to move, Enter to select.                  │
│                                                                        │
│     ▸ Install      Fresh install onto a selected disk                  │
│       Upgrade      (no existing NextBSD install detected)              │
│       Shell        Drop to a live rescue shell                         │
│       Reboot       Restart the machine                                 │
│                                                                        │
│   Probe: scanned ada0, ada1 — found no bootable NextBSD root.          │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                         < OK >        < Cancel >                       │
└────────────────────────────────────────────────────────────────────────┘

When the probe does find an install, the row lights up and becomes selectable:

PHASE 1 · EXISTING INSTALL FOUND
┌─────────────────────────  NextBSD Installer  ──────────────────────────┐
│                                                                        │
│   Welcome to NextBSD Server                                            │
│   continuous · 2026-06-08 00:19 UTC · 0d5f191                          │
│                                                                        │
│   Choose an action.  Use ↑↓ to move, Enter to select.                  │
│                                                                        │
│       Install      Fresh install onto a selected disk                  │
│     ▸ Upgrade      Keep data, replace base — ada0 (2026-05-20)         │
│       Shell        Drop to a live rescue shell                         │
│       Reboot       Restart the machine                                 │
│                                                                        │
│   Probe: ada0p2  zroot  NextBSD Server 2026-05-20  (upgradable)        │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                         < OK >        < Cancel >                       │
└────────────────────────────────────────────────────────────────────────┘

2Target Disk Selection

Whole-disk installs only — no partition editor in the server flow. Each disk is shown with its volume label(s), not just the device id, so operators don't wipe the wrong drive. Existing volumes are broken out underneath with their filesystem type.

PHASE 2 · WHOLE-DISK PICKER
┌──────────────────────────  Select Install Disk  ───────────────────────┐
│                                                                        │
│   The selected disk will be ERASED in full.  Pick a target:            │
│                                                                        │
│     ▸ ada0   238 GB   Samsung SSD 860 EVO                              │
│          ├─ "BACKUP"        212 GB   ufs                               │
│          └─ "EFI"           260 MB   fat32  (ESP)                      │
│                                                                        │
│       ada1   931 GB   WDC WD10EZEX-08WN4A0                             │
│          ├─ "vault"         900 GB   zfs    (zpool: tank)              │
│          └─ "swap"           16 GB   freebsd-swap                      │
│                                                                        │
│       da0    15 GB    SanDisk Ultra USB  (install media)               │
│          └─ "NEXTBSD_INST"   15 GB   iso9660                           │
│                                                                        │
│   Space toggles details · Enter selects · da0 is locked (booted from)  │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                     < Select >      < Back >    < Rescan >             │
└────────────────────────────────────────────────────────────────────────┘
ColumnSourcePurpose
ada0 / da0geom disk listKernel device id — the unambiguous handle.
SizediskinfoHuman-readable capacity for quick sanity check.
ModelGEOM ident / CAMPhysical drive identification ("which one is this?").
"Label"glabel status · GPT label · FS volnameThe headline feature — operators recognize volumes by name, not by p2.
FS typefstyp / GPT typeufs · zfs · fat32 (ESP) · freebsd-swap · iso9660 — shows what's at risk.

3Account & Hostname

One screen creates the primary admin account and sets the hostname. The hostname is auto-suggested from the username plus the detected machine model — and stays editable.

PHASE 3 · ACCOUNT
┌────────────────────────  Create Admin Account  ────────────────────────┐
│                                                                        │
│   This user is added to the wheel group and may use sudo.              │
│                                                                        │
│     Username      [ joe________________ ]                              │
│     Password      [ •••••••••__________ ]                              │
│     Confirm       [ •••••••••__________ ]  ✓ match                     │
│                                                                        │
│     Hostname      [ joe-thinkpad-t460_ ]                               │
│                  suggested from username + DMI model — editable        │
│                                                                        │
│   DMI: LENOVO ThinkPad T460 (20FN)  →  slug: thinkpad-t460             │
│                                                                        │
│   Tab moves between fields · Enter on Next to continue.                │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                      < Next >       < Back >                           │
└────────────────────────────────────────────────────────────────────────┘

Validation states surface inline — mismatched confirmation blocks Next:

PHASE 3 · VALIDATION
│     Password      [ •••••••••__________ ]                              │
│     Confirm       [ ••••••____________ ]   ✗ does not match            │
│                                                                        │
│   Passwords must match before you can continue.

Hostname suggestion logic

InputDerivationResult
username = joeslugify(username)joe
DMI product = ThinkPad T460slugify(model), strip vendor noisethinkpad-t460
joined<user>-<model-slug>joe-thinkpad-t460
no DMI / VMfallbackjoe-nextbsd

4Install Progress

A live progress dialog streams each stage. The base system is cloned with cpdup from the running live media to the destination volume — no archive extraction. The gauge fills in amber; the current action and a scrolling log tail keep the operator informed during the copy.

PHASE 4 · INSTALLING
┌──────────────────────────  Installing NextBSD  ────────────────────────┐
│                                                                        │
│   Cloning filesystem to destination volume…                            │
│                                                                        │
│   ████████████████████████████████████░░░░░░░░░░░░░░░░░░░░  64%        │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│                            < Cancel >                                  │
└────────────────────────────────────────────────────────────────────────┘

5Finish

On success, a summary plus the two terminal actions: Reboot or Shutdown. A reminder to remove the install medium is shown.

PHASE 5 · COMPLETE
┌────────────────────────  Installation Complete  ───────────────────────┐
│                                                                        │
│   ✓  NextBSD Server installed successfully.                            │
│                                                                        │
│     Build       continuous · 2026-06-08 00:19 UTC · 0d5f191            │
│     Disk        ada0                                                    │
│     Hostname    joe-thinkpad-t460                                      │
│     Admin user  joe  (wheel, sudo)                                     │
│                                                                        │
│   Remove the install medium (da0) before rebooting.                    │
│                                                                        │
│   What next?                                                           │
│                                                                        │
├────────────────────────────────────────────────────────────────────────┤
│              < Reboot >      < Shut Down >    < Shell >                │
└────────────────────────────────────────────────────────────────────────┘

Visual Language

Notes for whoever implements this against bsddialog(1) / libdialog or a custom ncurses front-end.

TokenRoleTreatment
BackgroundeverythingPure black #000
Body text / frameslabels, box-drawAmber #ff9416, dim frames #a85e0e
Title / emphasisheadings, field valuesBright amber #ffb454 + glow
Selection barcurrent row / default buttonInverted — black text on solid amber
Disabledgated options (Upgrade)Muted brown #4a3517, skipped by cursor
Success / failure✓ match, ✗ mismatchGreen #39d353 / red #ff4f4f — the only non-amber accents