1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
# 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](#overview) | [Features](#features) | [Requirements](#requirements) | [Installation](#installation) | [Configuration](#configuration) | [Dotfile Management](#dotfile-management) | [Desktop Environments](#desktop-environments) | [Testing](#testing) | [Contributing](#contributing) | [License](#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](#configuration)).
## Overview
archsetup turns a freshly installed Arch Linux box into a working desktop. It does three things:
1. **Provisions the system.** The `archsetup` script 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).
2. **Manages dotfiles.** Configuration lives in a separate dotfiles repo (`git.cjennings.net/dotfiles.git`), cloned to `~/.dotfiles` and symlinked into `$HOME` by GNU Stow. That repo carries its own `Makefile` wrapping the common Stow operations plus an `fzf`-driven importer for new app configs. The installer clones and stows it for you.
3. **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), or `none` (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/`, and `minimal/` trees
- That repo's `Makefile` carries the stow / restow / reset / unstow / import targets; the installer clones and stows it automatically
- Two-theme system (`dupre`, `hudson`) switchable with the `set-theme` script
- 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`, and `fzf` for the dotfile workflow (`make deps` installs these)
- For the test harness: `qemu-full`, `sshpass`, OVMF firmware, `socat`, and KVM support (`make deps` or `scripts/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:
```sh
curl -s https://<your-domain>/archsetup/init | sh
```
`init` 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:
```sh
git clone https://github.com/yourusername/archsetup.git
cd archsetup
sudo ./archsetup
```
The 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:
```sh
cd ~/.dotfiles && make stow hyprland # or: make restow hyprland
```
## Configuration
For an unattended install, copy the template and edit it:
```sh
cp archsetup.conf.example archsetup.conf
./archsetup --config-file archsetup.conf
```
Every 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`: `yes` to skip GPU driver auto-detection
- `LOCALE`: e.g. `en_US.UTF-8`
- `DESKTOP_ENV`: `dwm`, `hyprland`, or `none`
- `DWM_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 `*_REPO` variables in `archsetup.conf` to point at your own forks. Also review `scripts/post-install.sh` — it clones personal repositories you won't want. The `archsetup` header, `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/bin` scripts, app configs that don't depend on the display server)
- `dwm/` — Xorg/DWM-specific configs and scripts
- `hyprland/` — Wayland/Hyprland-specific configs and scripts
- `minimal/` — a standalone headless tree (stowed alone for `DESKTOP_ENV=none`, not layered on `common/`)
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 `dwm` desktop env builds dwm, dmenu, st, and slock from the configured Git repos and links the `dwm` dotfile tree. DWM keybindings live in that fork's `config.def.h`.
- **Hyprland (Wayland).** The `hyprland` desktop env installs Hyprland and links the `hyprland` dotfile 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.
```sh
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.
```sh
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 only
```
Results 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.
## License
[GPL-3.0](LICENSE)
|