archsetup
Automated Arch Linux installation, dotfile management, and machine maintenance for a personal workstation, driven by a single Bash script, GNU Stow, and a handful of helper utilities.
Overview | Features | Requirements | Installation | Configuration | Dotfile Management | Desktop Environments | Testing | Contributing | License
Note: This is one person's personal Arch setup. It works as-is on that machine; if you fork it, change the hardcoded repositories and account details first (see Configuration).
Overview
archsetup turns a freshly installed Arch Linux box into a working desktop. It does three things:
- Provisions the system. The
archsetupscript installs packages, creates the primary user, builds suckless tools and an Emacs config from source, enables systemd services, sets up an AUR helper, configures the firewall, and installs a desktop environment (DWM on Xorg, or Hyprland on Wayland). - Manages dotfiles. Configuration lives in a separate dotfiles repo (
git.cjennings.net/dotfiles.git), cloned to~/.dotfilesand symlinked into$HOMEby GNU Stow. That repo carries its ownMakefilewrapping the common Stow operations plus anfzf-driven importer for new app configs. The installer clones and stows it for you. - Provides maintenance scripts. Small utilities under
scripts/here, and under~/.dotfiles/*/.local/bin/, for VPN setup, post-install repo cloning, disk wiping, ZFS replication, and similar chores.
The provisioning step is resumable: it records progress as marker files, so an interrupted run picks up where it left off. archsetup --status shows what's done; archsetup --fresh starts over.
Features
- One-script system provisioning with per-step state tracking and resume
- Pre-flight checks (root, disk space, network) before anything is touched
- Interactive or fully unattended install (via a config file)
- Choice of desktop environment:
dwm(Xorg + DWM),hyprland(Wayland + Hyprland), ornone(headless/server) - GPU driver auto-detection (skippable)
- Optional automatic console login for encrypted-root systems
- Builds suckless tools (dwm, dmenu, st, slock) and an Emacs config from configurable Git repos, compiled on a tmpfs RAM disk
- Stow-managed dotfiles in a separate repo, split into
common/,dwm/,hyprland/, andminimal/trees - That repo's
Makefilecarries the stow / restow / reset / unstow / import targets; the installer clones and stows it automatically - Two-theme system (
dupre,hudson) switchable with theset-themescript - VM-based integration test harness (QEMU/KVM) that installs into a throwaway VM and validates the result
- Logs everything to
/var/log/archsetup-*.log
Requirements
- A booted Arch Linux live ISO (for the initial OS install), or an already-installed Arch system (to run
archsetup) - UEFI firmware (the test harness and typical installs assume UEFI)
- A network connection
git,make,stow, andfzffor the dotfile workflow (make depsinstalls these)- For the test harness:
qemu-full,sshpass, OVMF firmware,socat, and KVM support (make depsorscripts/testing/setup-testing-env.sh)
Installation
1. Install Arch (live ISO bootstrap)
Boot any Arch Linux ISO from a USB stick and run the bootstrap script:
curl -s https://<your-domain>/archsetup/init | shinit installs git and tmux, sets a temporary root password, and starts sshd so you can finish the install remotely. Then it launches archinstall to partition the disk and install the base system. (You can also do the base install by hand; init is just a convenience.)
2. Run archsetup on the installed system
Boot into the new install, clone this repo, and run the provisioning script as root:
git clone https://github.com/yourusername/archsetup.git
cd archsetup
sudo ./archsetupThe script prompts for the username, password, locale, and (on encrypted systems) autologin, unless you supply them via a config file.
archsetup options
Usage: ./archsetup [OPTIONS]
--config-file PATH Use a config file for unattended installation
--fresh Start fresh, ignore previous progress
--status Show installation progress and exit
--no-gpu-drivers Skip GPU driver detection/installation
--autologin Enable automatic console login
--no-autologin Disable automatic console login
--help, -h Show this help message
3. Dotfiles (handled automatically)
archsetup clones the dotfiles repo to ~/.dotfiles and stows the right trees for your DESKTOP_ENV, so there's nothing to do by hand. To re-link later (after a git pull in ~/.dotfiles), use that repo's Makefile:
cd ~/.dotfiles && make stow hyprland # or: make restow hyprlandConfiguration
For an unattended install, copy the template and edit it:
cp archsetup.conf.example archsetup.conf
./archsetup --config-file archsetup.confEvery field has a default. Set only what you want to change. The config covers:
USERNAME/PASSWORD: primary user account (prompted if unset)AUTOLOGIN:yes/no, automatic console login (only relevant with encrypted root)NO_GPU_DRIVERS:yesto skip GPU driver auto-detectionLOCALE: e.g.en_US.UTF-8DESKTOP_ENV:dwm,hyprland, ornoneDWM_REPO,DMENU_REPO,ST_REPO,SLOCK_REPO,DOTEMACS_REPO,ARCHSETUP_REPO: Git URLs for the suckless tools, the Emacs config, and this repo
Forking note: The upstream defaults point at the original author's personal Git server and assume a particular username. If you're adapting this for yourself, override the
*_REPOvariables inarchsetup.confto point at your own forks. Also reviewscripts/post-install.sh— it clones personal repositories you won't want. Thearchsetupheader,init's temporary root password, and a handful of dotfiles (.gitconfig,.ssh/config, etc.) also carry author-specific values.
Dotfile Management
Dotfiles live in their own repo (git.cjennings.net/dotfiles.git), cloned to ~/.dotfiles and stowed into $HOME with GNU Stow. The tree splits four ways:
common/— shared by every setup (shell config,~/.local/binscripts, app configs that don't depend on the display server)dwm/— Xorg/DWM-specific configs and scriptshyprland/— Wayland/Hyprland-specific configs and scriptsminimal/— a standalone headless tree (stowed alone forDESKTOP_ENV=none, not layered oncommon/)
The installer clones and stows the right trees for you. The dotfiles repo carries its own Makefile for managing them afterwards — run these from ~/.dotfiles:
make stow hyprland # Link common + hyprland (or: dwm)
make restow hyprland # Refresh links after a git pull (prompts on conflicts)
make reset hyprland # Resolve conflicts by keeping the repo version
make unstow hyprland # Remove all symlinks
make import common # fzf-pick app configs and import them into common/
make test # Run the dotfile-script unit suites
make help # Full target list
make import scans ~, ~/.config, and ~/.local for config directories not yet in the repo, lets you multi-select with fzf, moves them into the chosen tree, and re-stows so the originals become symlinks. It reminds you to commit afterwards.
This archsetup repo no longer carries the dotfiles itself — the in-repo dotfiles/ tree was extracted to the standalone repo so it can be developed, tested, and published on its own.
Theme system
Two themes ship in the dotfiles repo, dupre (default) and hudson. Switch with the set-theme script (installed via the common dotfiles). Theme files live under ~/.dotfiles/hyprland/.config/themes/<theme>/ and cover foot, fuzzel, waybar, dunst, hyprlock, and Xresources.
Desktop Environments
- DWM (Xorg). The
dwmdesktop env builds dwm, dmenu, st, and slock from the configured Git repos and links thedwmdotfile tree. DWM keybindings live in that fork'sconfig.def.h. - Hyprland (Wayland). The
hyprlanddesktop env installs Hyprland and links thehyprlanddotfile tree, including a waybar/foot/fuzzel/dunst/hyprlock stack themed to match.
Pick the desktop env at install time with DESKTOP_ENV in the config file (or accept the prompt/default); the installer links the matching dotfiles for you. To re-link later, run make stow dwm or make stow hyprland from ~/.dotfiles.
Testing
archsetup has two test layers: fast unit tests for the standalone helper scripts, and a full VM-based integration test for the installer itself.
Unit tests
Installer helpers (such as the safe_rm_rf guard) have Python unittest suites under tests/, one directory per helper, sourcing the real function out of the archsetup script and exercising it with fakes on PATH. No VM, root, or network needed; they run in under a second.
make test-unit # Run every installer-helper suite(unittest discover skips these because the per-helper directory names are hyphenated, so make test-unit runs each suite explicitly.)
The standalone dotfile scripts (the ones that shell out to tmux, hyprctl, iw, and friends) have their own suites in the dotfiles repo, run with make test from ~/.dotfiles. They moved there to live alongside the scripts they exercise.
Integration tests (VM harness)
archsetup ships a VM-based integration test harness under scripts/testing/. It uses QEMU/KVM directly (no libvirt) to install Arch into a throwaway VM, run archsetup inside it, and validate the result: user creation, stowed dotfiles, AUR helper, desktop environment, services, firewall, and package set.
make deps # Install qemu-full, sshpass, OVMF, socat (one-time)
make test # Create the base VM if needed, then run the full test
make test-keep # Same, but leave the VM running for manual inspection
make test-vm-base # (Re)create the base VM onlyResults land in test-results/<timestamp>/ (logs, a summary report, and package lists). See scripts/testing/README.org for the full workflow, the cleanup and debug helpers, and the validation checks.
Contributing
This is a personal setup, but bug reports and pull requests are welcome, especially fixes that make it easier to fork. If you're sending a change, keep the common / dwm / hyprland dotfile split intact. Run make test-unit for any script change (it's fast and needs no VM), and make test for installer changes (or at least bash -n archsetup) before opening a PR.
