Move install-time plumbing out of the setup namespace

setup is where a user goes to configure something: direct boot, security
keys, hibernation. These three are not that. omarchy-apply-system is the
ISO's entry point in the target chroot, omarchy-apply-hardware is what it
calls for device quirks, and omarchy-apply-lock is called by
install/config/lockscreen-pam.sh.

apply is the verb they already used to describe themselves, and it carries
the contract: declared state under install/ converged onto the machine,
idempotent, safe to repeat.

The group gets no GROUP_DESCRIPTIONS entry on purpose. That table drives the
top-level group list on its own, so an entry would put apply back in front of
users even with every command in it hidden, the way provision already stays
out. A test covers it.

The ISO installs the runtime from the mirror it ships with, so it moves to
the new names in lockstep and no compatibility route is needed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-10 14:14:57 -07:00
co-authored by Claude Opus 5
parent 477284f002
commit 536fcd5c6c
11 changed files with 40 additions and 34 deletions
+2 -2
View File
@@ -5,8 +5,8 @@ Read this before working under `install/` or on the system/user setup commands.
The ISO owns installation orchestration. This repo ships target-side setup The ISO owns installation orchestration. This repo ships target-side setup
commands and reusable setup leaves: commands and reusable setup leaves:
- `bin/omarchy-setup-system` runs root-owned system setup during ISO finalization. - `bin/omarchy-apply-system` runs root-owned system setup during ISO finalization.
- `bin/omarchy-setup-hardware` runs idempotent hardware-specific setup and is called by `omarchy-setup-system`. - `bin/omarchy-apply-hardware` runs idempotent hardware-specific setup and is called by `omarchy-apply-system`.
- `bin/omarchy-finalize-user` runs the per-user runtime finalization (skill symlinks, xdg-user-dirs, mime defaults, `install/user/all.sh`). Shipped user defaults are seeded by `/etc/skel` from `omarchy-settings`, not by this command. `bin/omarchy-reinstall-configs` is the explicit destructive resync of those defaults into an existing user's `$HOME`. - `bin/omarchy-finalize-user` runs the per-user runtime finalization (skill symlinks, xdg-user-dirs, mime defaults, `install/user/all.sh`). Shipped user defaults are seeded by `/etc/skel` from `omarchy-settings`, not by this command. `bin/omarchy-reinstall-configs` is the explicit destructive resync of those defaults into an existing user's `$HOME`.
- leaf scripts under `install/` are sourced by `run_logged $OMARCHY_INSTALL/path/to/script.sh` and intentionally do not have shebangs. - leaf scripts under `install/` are sourced by `run_logged $OMARCHY_INSTALL/path/to/script.sh` and intentionally do not have shebangs.
- avoid `exit` in sourced setup scripts unless intentionally aborting setup. - avoid `exit` in sourced setup scripts unless intentionally aborting setup.
@@ -1,20 +1,20 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Apply Omarchy hardware-specific packages and system configuration # omarchy:summary=Apply Omarchy hardware-specific packages and system configuration
# omarchy:group=setup # omarchy:group=apply
# omarchy:requires-sudo=true # omarchy:requires-sudo=true
# omarchy:examples=omarchy setup hardware --install-user dhh # omarchy:examples=omarchy apply hardware --install-user dhh
# omarchy:hidden=true # omarchy:hidden=true
set -euo pipefail set -euo pipefail
usage() { usage() {
cat <<USAGE cat <<USAGE
Usage: omarchy setup hardware --install-user USER Usage: omarchy apply hardware --install-user USER
omarchy setup hardware --defer-provisioning omarchy apply hardware --defer-provisioning
Runs idempotent hardware detection/setup for the installed machine. This is Runs idempotent hardware detection/setup for the installed machine. This is
called by omarchy-setup-system during ISO finalization and can be rerun later called by omarchy-apply-system during ISO finalization and can be rerun later
for diagnostics or after hardware/package updates. for diagnostics or after hardware/package updates.
--defer-provisioning runs without an install user (deferred-provisioning installs create the user at --defer-provisioning runs without an install user (deferred-provisioning installs create the user at
@@ -47,7 +47,7 @@ while (($#)); do
done done
if (( EUID != 0 )); then if (( EUID != 0 )); then
echo "Error: omarchy-setup-hardware must run as root" >&2 echo "Error: omarchy-apply-hardware must run as root" >&2
exit 1 exit 1
fi fi
@@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Configure Quickshell lock screen authentication # omarchy:summary=Configure Quickshell lock screen authentication
# omarchy:group=setup
# omarchy:name=lock
# omarchy:requires-sudo=true # omarchy:requires-sudo=true
# omarchy:hidden=true # omarchy:hidden=true
@@ -1,21 +1,21 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Apply Omarchy system setup in the installed target # omarchy:summary=Apply Omarchy system setup in the installed target
# omarchy:group=setup # omarchy:group=apply
# omarchy:requires-sudo=true # omarchy:requires-sudo=true
# omarchy:examples=omarchy setup system --install-user dhh --first-install # omarchy:examples=omarchy apply system --install-user dhh --first-install
# omarchy:hidden=true # omarchy:hidden=true
set -euo pipefail set -euo pipefail
usage() { usage() {
cat <<USAGE cat <<USAGE
Usage: omarchy setup system --install-user USER [--first-install|--upgrade] Usage: omarchy apply system --install-user USER [--first-install|--upgrade]
omarchy setup system --defer-provisioning --first-install omarchy apply system --defer-provisioning --first-install
Runs root-owned Omarchy system setup. The ISO calls this in the target chroot Runs root-owned Omarchy system setup. The ISO calls this in the target chroot
after packages are installed and the target user exists. It also calls after packages are installed and the target user exists. It also calls
omarchy-setup-hardware, so hardware setup cannot be accidentally skipped. omarchy-apply-hardware, so hardware setup cannot be accidentally skipped.
--defer-provisioning runs without an install user: deferred-provisioning installs create the user at --defer-provisioning runs without an install user: deferred-provisioning installs create the user at
first boot, so scripts that grant group memberships record them in first boot, so scripts that grant group memberships record them in
@@ -59,7 +59,7 @@ while (($#)); do
done done
if (( EUID != 0 )); then if (( EUID != 0 )); then
echo "Error: omarchy-setup-system must run as root" >&2 echo "Error: omarchy-apply-system must run as root" >&2
exit 1 exit 1
fi fi
@@ -91,9 +91,9 @@ start_install_log
source "$OMARCHY_INSTALL/config/all.sh" source "$OMARCHY_INSTALL/config/all.sh"
if (( defer_provisioning )); then if (( defer_provisioning )); then
omarchy-setup-hardware --defer-provisioning omarchy-apply-hardware --defer-provisioning
else else
omarchy-setup-hardware --install-user "$install_user" omarchy-apply-hardware --install-user "$install_user"
fi fi
source "$OMARCHY_INSTALL/login/all.sh" source "$OMARCHY_INSTALL/login/all.sh"
+1 -1
View File
@@ -669,7 +669,7 @@ Timezone,${timezone:-UTC}" |
gum confirm --negative "No, change it" "Does this look right?" gum confirm --negative "No, change it" "Does this look right?"
} }
# Groups recorded by omarchy-setup-system's scripts at install time # Groups recorded by omarchy-apply-system's scripts at install time
# (/var/lib/omarchy/provisioning/groups), filtered to groups that exist on this system. # (/var/lib/omarchy/provisioning/groups), filtered to groups that exist on this system.
user_groups() { user_groups() {
local groups="wheel" group local groups="wheel" group
+3 -3
View File
@@ -612,16 +612,16 @@ configure_snapper_policy() {
} }
configure_lock_authentication() { configure_lock_authentication() {
local setup_lock=/usr/share/omarchy/bin/omarchy-setup-lock local apply_lock=/usr/share/omarchy/bin/omarchy-apply-lock
[[ -x $setup_lock ]] || fail "$setup_lock is unavailable; lock screen authentication could not be configured." [[ -x $apply_lock ]] || fail "$apply_lock is unavailable; lock screen authentication could not be configured."
log "Configuring lock screen authentication" log "Configuring lock screen authentication"
as_root env \ as_root env \
OMARCHY_INSTALL_USER="$target_user" \ OMARCHY_INSTALL_USER="$target_user" \
OMARCHY_PATH=/usr/share/omarchy \ OMARCHY_PATH=/usr/share/omarchy \
PATH="$package_path" \ PATH="$package_path" \
"$setup_lock" "$apply_lock"
} }
create_pre_upgrade_snapshot() { create_pre_upgrade_snapshot() {
+3 -3
View File
@@ -183,7 +183,7 @@ Idempotency marker: `~/.local/state/omarchy/done/finalize-user`, managed
by `omarchy-done`. by `omarchy-done`.
The ISO calls it as `omarchy-finalize-user --force --first-install` in the The ISO calls it as `omarchy-finalize-user --force --first-install` in the
target chroot as the install user, after `omarchy-setup-system` has finished target chroot as the install user, after `omarchy-apply-system` has finished
the root-side work. the root-side work.
## Migrations (`omarchy-migrate`) ## Migrations (`omarchy-migrate`)
@@ -255,13 +255,13 @@ the legacy finalization marker from `~/.local/state/omarchy/` into `done/`.
## Root-side install orchestration ## Root-side install orchestration
`omarchy-setup-system` (root, in chroot) runs target-side setup at ISO `omarchy-apply-system` (root, in chroot) runs target-side setup at ISO
finalization. It sources: finalization. It sources:
- `install/config/all.sh` — theme links, lockout limits, lockscreen PAM, - `install/config/all.sh` — theme links, lockout limits, lockscreen PAM,
powerprofilesctl shebang fix, docker setup, Snapper retention, locate powerprofilesctl shebang fix, docker setup, Snapper retention, locate
index tuning, service enablement, firewall. index tuning, service enablement, firewall.
- `install/hardware/all.sh` via `omarchy-setup-hardware` — vendor- and - `install/hardware/all.sh` via `omarchy-apply-hardware` — vendor- and
device-specific kernel modules, udev rules, microcode, wireless regdom, device-specific kernel modules, udev rules, microcode, wireless regdom,
ASUS / Framework / Intel / Apple / Lenovo quirks. ASUS / Framework / Intel / Apple / Lenovo quirks.
- `install/login/all.sh` — SDDM theme/session config. - `install/login/all.sh` — SDDM theme/session config.
+1 -1
View File
@@ -1 +1 @@
omarchy-setup-lock omarchy-apply-lock
+14 -6
View File
@@ -182,10 +182,18 @@ if [[ $output == *"omarchy update perform"* ]]; then
fi fi
pass "hidden update perform compatibility wrapper is not shown" pass "hidden update perform compatibility wrapper is not shown"
# The setup group is for interactive wizards. These three are install-time # These three are install-time plumbing the ISO and install leaves call, so
# plumbing the ISO and install leaves call, so they stay out of the listing a # they stay out of the listing a user browses -- while still routing, because
# user browses -- while still routing, because those callers use the CLI. # those callers use the CLI. A GROUP_DESCRIPTIONS entry would put the group
for internal in omarchy-setup-system omarchy-setup-hardware omarchy-setup-lock; do # back in the top-level listing even with every command in it hidden, which is
# why apply has none.
output=$(timeout 5 "$CLI")
if [[ $output == *"apply"* ]]; then
fail "a group whose commands are all hidden stays out of the top-level listing"
fi
pass "a group whose commands are all hidden stays out of the top-level listing"
for internal in omarchy-apply-system omarchy-apply-hardware omarchy-apply-lock; do
if "$CLI" commands --json | jq -e --arg binary "$internal" \ if "$CLI" commands --json | jq -e --arg binary "$internal" \
'.commands[] | select(.binary == $binary)' >/dev/null; then '.commands[] | select(.binary == $binary)' >/dev/null; then
fail "$internal stays out of the default command listing" fail "$internal stays out of the default command listing"
@@ -197,8 +205,8 @@ for internal in omarchy-setup-system omarchy-setup-hardware omarchy-setup-lock;
done done
pass "install-time setup plumbing is hidden from the setup wizards" pass "install-time setup plumbing is hidden from the setup wizards"
output=$(timeout 5 "$CLI" setup hardware --help) output=$(timeout 5 "$CLI" apply hardware --help)
assert_output_contains "hidden setup plumbing still routes" "$output" "omarchy-setup-hardware" assert_output_contains "hidden setup plumbing still routes" "$output" "omarchy-apply-hardware"
output=$("$CLI" screenshot --help) output=$("$CLI" screenshot --help)
assert_output_contains "root alias resolves to command help" "$output" "omarchy-capture-screenshot" assert_output_contains "root alias resolves to command help" "$output" "omarchy-capture-screenshot"
+1 -1
View File
@@ -71,7 +71,7 @@ grep -Fx 'systemctl disable --now snapper-timeline.timer' "$test_tmp/calls.log"
grep -Fx 'systemctl enable --now snapper-cleanup.timer limine-snapper-sync.service' "$test_tmp/calls.log" >/dev/null || fail "snapshot configure enables cleanup and Limine snapshot sync" grep -Fx 'systemctl enable --now snapper-cleanup.timer limine-snapper-sync.service' "$test_tmp/calls.log" >/dev/null || fail "snapshot configure enables cleanup and Limine snapshot sync"
pass "snapshot configure normalizes Snapper policy and services" pass "snapshot configure normalizes Snapper policy and services"
setup_system="$ROOT/bin/omarchy-setup-system" setup_system="$ROOT/bin/omarchy-apply-system"
grep -F 'config/all.sh' "$setup_system" >/dev/null || grep -F 'config/all.sh' "$setup_system" >/dev/null ||
fail "system setup runs the config phase" fail "system setup runs the config phase"
grep -F 'config/snapper.sh' "$ROOT/install/config/all.sh" >/dev/null || grep -F 'config/snapper.sh' "$ROOT/install/config/all.sh" >/dev/null ||
+1 -1
View File
@@ -64,7 +64,7 @@ pass "Omarchy 4 upgrade normalizes Snapper retention"
grep -F 'configure_lock_authentication' "$upgrade_to_quattro" >/dev/null grep -F 'configure_lock_authentication' "$upgrade_to_quattro" >/dev/null
grep -F 'OMARCHY_INSTALL_USER="$target_user"' "$upgrade_to_quattro" >/dev/null grep -F 'OMARCHY_INSTALL_USER="$target_user"' "$upgrade_to_quattro" >/dev/null
grep -F '"$setup_lock"' "$upgrade_to_quattro" >/dev/null grep -F '"$apply_lock"' "$upgrade_to_quattro" >/dev/null
pass "Omarchy 4 upgrade configures lock screen authentication for the target user" pass "Omarchy 4 upgrade configures lock screen authentication for the target user"
grep -F 'OMARCHY_UPGRADE_TO_QUATTRO_LIVE=1' "$upgrade_to_quattro" >/dev/null grep -F 'OMARCHY_UPGRADE_TO_QUATTRO_LIVE=1' "$upgrade_to_quattro" >/dev/null