feat: initial commit — void-installer multi-profile (stable-cinnamon + mainline-niri)

This commit is contained in:
mozempk
2026-04-22 23:53:16 +02:00
commit a16ac37d20
35 changed files with 3902 additions and 0 deletions

195
README.md Normal file
View File

@@ -0,0 +1,195 @@
# void-installer — XPS 17 (xps9700)
Auto-installing Void Linux ISO targeted at a Dell XPS 17 9700 dual-booting Windows.
Final installed system ships with: **Cinnamon**, **Docker**, **VS Code**, your
SSH config, NVIDIA PRIME render-offload, and Nix for Spotify/Discord/LocalSend.
> ⚠️ **Destructive.** This installer wipes one partition. Read the
> [Safety](#safety) section before running on real hardware.
---
## Layout produced
| What | Where |
|------------------------------|--------------------------------------|
| Void root (btrfs `@`) | `/dev/nvme0n1p5` (replaces Mint) |
| `/home`, `/.snapshots`, etc. | btrfs subvolumes on the same device |
| EFI System Partition | `/dev/nvme0n1p1` *(shared, untouched)* |
| GRUB target | `\EFI\Void\` (Windows entry preserved) |
| Windows | `/dev/nvme0n1p3` *(left alone)* |
---
## Repo layout
```
config/install.conf # all knobs (hostname, locale, kbd, GPU, etc.)
config/packages.target.list # xbps packages installed into target
config/packages.live.list # extra packages added to the LIVE iso
secrets.env # USER_PASSWORD / ROOT_PASSWORD (gitignored)
installer/
install.sh # main entrypoint, runs in the live env
lib/ # tui, partition, bootstrap, grub, postinstall
iso/
build-iso.sh # host-side: stages overlay, then runs mklive in docker
_inner-build.sh # invoked inside the docker container as root
Dockerfile # debian:stable-slim + mtools/xorriso/squashfs-tools
patches/ # patches applied to upstream void-mklive
tests/
make-test-disk.sh # builds a qcow2 mimicking the XPS 17 partition table
run-qemu-test.sh # automated headless install + smoke tests
interactive-qemu.sh # GUI QEMU for manual exploration
lib/make-test-overlay.sh
Makefile # build / test entrypoints
```
---
## Quick start
### Build dependencies (host)
Any Linux with **bash, git, curl, docker** (and `qemu` + `ovmf` if you want to run
`make test` / `make qemu`). The mklive build runs inside a Debian container, so
you don't need `mtools`, `xorriso`, `squashfs-tools`, etc. on the host.
- **Void**: `xbps-install -S git curl docker qemu ovmf`
- **Debian/Ubuntu/Mint**: `apt install git curl docker.io qemu-system-x86 qemu-utils ovmf`
- **Arch**: `pacman -S git curl docker qemu-full edk2-ovmf`
Make sure your user is in the `docker` group (`sudo usermod -aG docker $USER`,
then log out / back in) so the build runs without `sudo`.
### 1. Provide secrets
`secrets.env` is gitignored and pre-populated for you with the values from the
chat. Edit if you want different passwords.
### 2. Build the ISO
```sh
make iso
# -> out/void-install-xps9700-YYYYMMDD.iso
```
### 3. Test in QEMU (recommended before flashing!)
```sh
make test # full headless install + smoke tests (~15-30 min)
# or
make qemu # interactive QEMU window with the ISO booted
```
### 4. Flash to USB and boot the XPS 17
```sh
sudo dd if=out/void-install-xps9700-*.iso of=/dev/sdX bs=4M status=progress conv=fsync
```
Boot the XPS from the USB (F12 boot menu). The TUI shows detected partitions
with `[WINDOWS]` and `[EFI]` markers. Pick `/dev/nvme0n1p5`, type the device
path verbatim to confirm, and let it run.
---
## Safety
- The installer **refuses** to wipe any NTFS partition.
- A TUI confirmation step requires you to **type the full device path** before
any destructive action.
- The shared EFI partition is **mounted read-write but never reformatted**;
Windows boot files under `EFI/Microsoft/` are preserved.
- All passwords come from `/etc/installer-secrets.env` baked into the ISO at
build time (mode `0600`). They are not on the network and not in `argv`.
If you want to be paranoid, run `make test` first — the smoke test asserts
that `EFI/Microsoft/Boot/bootmgfw.efi` survives the install on a simulated
disk with the same layout as the XPS.
---
## Configuration
Everything tunable lives in [config/install.conf](config/install.conf):
- locale `en_US.UTF-8`, keymap `ch-fr_nodeadkeys`, timezone `Europe/Zurich`
- hostname `xps9700`, user `moze` in `wheel,docker,video,audio,...`
- btrfs subvolumes `@`, `@home`, `@snapshots`, `@var_log`, `@var_cache`
- GPU mode `prime-offload` (Intel UHD primary, NVIDIA GTX 1650 Ti via `prime-run`)
- zram swap at 50% RAM (zramen)
- nonfree + multilib + multilib-nonfree repos enabled
---
## What's installed
**xbps:** base-system, linux, intel-ucode, NetworkManager, cinnamon, lightdm,
docker, docker-compose, vscode (Microsoft), firefox, vlc, obs, flameshot,
nvidia + nvidia-libs-32bit, pipewire, sudo, git, curl, vim, tlp, nix, …
(full list in [config/packages.target.list](config/packages.target.list))
**nix profile (first boot, as moze):** spotify, discord, localsend.
The first-boot service runs once after `nix-daemon` is up, then exits.
---
## Post-install
After first reboot:
1. Log in as `moze` (password: `void`).
2. The Cinnamon greeter appears (LightDM).
3. The first-boot Nix service installs Spotify/Discord/LocalSend in the
background (~515 min depending on connection). Watch with
`journalctl -fu first-boot-nix` is replaced by `tail -f /var/log/socklog/everything/current` on Void's runit; or just check `nix profile list` later.
4. Run NVIDIA-accelerated apps with `prime-run <app>`.
---
## Test harness
`tests/run-qemu-test.sh` runs end-to-end:
1. Builds a TEST ISO variant (overlay forces `UNATTENDED=1 TEST_MODE=1` and
bakes a one-off ssh keypair for the harness).
2. Builds a fresh `out/test-disk.qcow2` with the **same partition layout**
as the XPS (EFI + MSR + NTFS "Windows" placeholder + btrfs "Mint").
3. Boots the ISO under QEMU/OVMF; installer runs unattended; VM powers off.
4. Boots the installed disk; ssh's in as `moze`; runs ~20 smoke assertions.
```sh
make test # default
TIMEOUT_INSTALL=5400 make test # slower hosts
ACCEL=tcg make test # no KVM (e.g., nested virt without)
```
---
## Files of interest while debugging
| File on installed system | Purpose |
|------------------------------------|------------------------------------------|
| `/var/log/void-installer.log` | full installer log |
| `/etc/sv/first-boot-nix/run` | one-shot nix profile installer |
| `/usr/local/bin/prime-run` | NVIDIA PRIME offload wrapper |
| `/etc/X11/xorg.conf.d/20-nvidia.conf` | NVIDIA display config |
| `/etc/runit/runsvdir/default/` | enabled services |
| File on the live ISO | Purpose |
|------------------------------------|------------------------------------------|
| `/usr/local/share/installer/` | installer scripts + config + packages |
| `/etc/installer-secrets.env` | passwords (mode 0600) |
| `/etc/installer-ssh/` | snapshot of build-host `~/.ssh/` |
---
## Caveats
- 150 MB shared EFI is tight (was 91 % full before install). Void puts only
`\EFI\Void\grubx64.efi` (~150 KB) there; kernels live on btrfs `/boot`.
- Secure Boot is **off** (per the input). NVIDIA proprietary modules won't
load with SB on without manual MOK enrollment.
- The installer assumes `/dev/nvme0n1p5` is currently Linux Mint (btrfs).
If that ever changes, the TUI default will be wrong but the listing is
always live, and the confirmation step prevents accidents.