# 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 (~5–15 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 `. --- ## 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.