David Heinemeier HanssonandClaude f32247afc3 Confirm the Start Omarchy Now prompt after provisioning setup (#100)
* Confirm the Start Omarchy Now prompt after provisioning setup

First-boot account setup now ends on a celebration screen whose Start
Omarchy Now button gates the SDDM handoff, so the provisioning test
must press it — same as the installer's Reboot Now prompt — once the
pending flag clears.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add a centered greeter before the installer keyboard step

Open the ISO configurator with the same greeter the deferred-provisioning
first boot uses — vertically centered logo, the Omarchy tagline, and a
single button — so install and first boot bookend setup identically. The
installer's button reads "Start install"; first boot's reads "Start setup".

Co-Authored-By: Claude <noreply@anthropic.com>

* Animate the installer greeter logo with a skippable ColorShift

Match the first-boot greeter: a looping tte ColorShift over the centered
logo with a "Press Return to Start Install" hint instead of a button.
Return begins the install at any time.

Co-Authored-By: Claude <noreply@anthropic.com>

* Theme the installer greeter ColorShift to the Omarchy palette

Match the first-boot greeter: sweep the logo ColorShift through the
Tokyo Night accent colors instead of tte's default rainbow.

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix installer greeter ColorShift: green base, no flash, clean handoff

Mirror the first-boot greeter fixes: indexed ANSI colors (green base with
a cyan accent) because the framebuffer console can't render tte truecolor;
one long tte invocation so the loop never flashes; stty sane + clear after
Return so the keyboard step starts clean.

Co-Authored-By: Claude <noreply@anthropic.com>

* Dismiss the greeter in the QEMU test drivers

The installer and first-boot flows now open with a greeter (animated logo
+ tagline). Wait for the tagline and press Return before the keyboard
step, in both drive paths, so the harness gets past the greeter.

Co-Authored-By: Claude <noreply@anthropic.com>

* Kill the installer greeter animation cleanly

Run tte directly instead of inside a backgrounded `while` subshell, so
killing the tracked PID actually stops the effect. Killing the subshell
orphaned tte, which kept painting the logo over the keyboard step.

Co-Authored-By: Claude <noreply@anthropic.com>

* Guard the greeter wait against set -e in the configurator too

Harmless today (no set -e), but keeps the greeter's animation teardown
robust if that changes.

Co-Authored-By: Claude <noreply@anthropic.com>

* Also settle the terminal in emulators, not just real VTs

wait_for_stable_terminal skipped terminal emulators on the assumption
they're already at final size, but a fresh terminal (or sudo's pty)
reports a stale 24x80 for a moment at startup too. Drop the VT-only gate
so the greeter centers there as well.

Co-Authored-By: Claude <noreply@anthropic.com>

* Test harness: drive the first-boot timezone step and direct SDDM handoff

Match the deferred-provisioning first-boot flow changes: the owner now picks
a timezone after the email step, and setup hands straight off to SDDM instead
of pausing on a celebration screen with a Start Omarchy Now button. Drive the
new Timezone screen (accept the geo-guessed default) and drop the button
confirmation.

Co-Authored-By: Claude <noreply@anthropic.com>

* Don't bake hostname/timezone into deferred installs; set them at first boot

Deferred provisioning defers the user step to first boot, so the machine's
owner should name the machine and pick the timezone there — not inherit values
chosen at install time. Stop setting hostname/timezone in the configurator's
deferred branch: the orchestrator already skips an empty timezone (the system
stays UTC until first boot), and it now falls back to a neutral "archlinux"
hostname for the install so archinstall still succeeds. The first-boot
omarchy-provision-owner form collects and applies both.

Harness: drive the new Hostname screen and assert both hostname and timezone
actually landed on the running system after first boot.

Co-Authored-By: Claude <noreply@anthropic.com>

* Match the installer greeter: solid green logo, no color animation

Same fix as the first-boot greeter — tte's ColorShift judders on the 16-color
framebuffer console (truecolor crush). Show the logo in solid green and drop
the animation so both greeters look identical and flash-free.

Co-Authored-By: Claude <noreply@anthropic.com>

* Harden the provision harness: SSH-blip wait, timezone timeout, hostname assert

- The pending-flag wait treated an SSH connection failure (rc 255) the same as
  "flag absent" (rc 1), so a transient blip during finalization would exit early
  and snapshot the base mid-finalization. Only break on a clean rc 1; keep
  waiting on 0 or 255.
- Bump the first-boot Timezone screen wait 60s -> 180s (tzupdate geo-guess over
  first-boot networking can lag; matches the installer's headroom).
- Make the applied-hostname check a hard failure (it's deterministic — we typed
  it), so a first-boot apply regression can't pass green; timezone stays a
  report since it's geo-guessed.

Co-Authored-By: Claude <noreply@anthropic.com>

* Seed hostname=omarchy/timezone=UTC in deferred install instead of empties

Write neutral valid defaults in the configurator's deferred branch rather than
empty strings, and drop the orchestrator's `config.hostname or "archlinux"`
fallback (hostname is always non-empty now). The first-boot wizard overwrites
both. This keeps the "owner sets them at first boot" behavior without depending
on archinstall tolerating empty hostname/timezone at config-load time.

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix set -e regression in the provision pending-wait loop

The previous hardening moved `ssh_guest "test -f pending"` out of the `while`
condition into a standalone command, but the harness runs `set -euo pipefail` —
so the moment the flag cleared (ssh returns 1, the intended "done" signal) it
tripped errexit and aborted the whole run right after provisioning, before the
session/acceptance phase. Capture the result with `|| rc=$?` so the non-zero is
the signal, not a fatal error. Also guard the follow-on hostname/timezone
substitutions with `|| got=""` so a transient SSH failure there can't abort
either (an empty value then correctly fails the hostname assertion).

Co-Authored-By: Claude <noreply@anthropic.com>

* Bring back the installer greeter ColorShift animation

Match the first-boot greeter: restore the static green logo + looping tte
ColorShift overlay. The framebuffer truecolor crush gives it a quick flash,
which is acceptable — both greeters keep the animation.

Co-Authored-By: Claude <noreply@anthropic.com>

* Skip the install celebration on deferred installs; reboot directly

A deferred-provisioning install has nothing to celebrate yet — the owner
finishes setup (and gets the send-off) at first boot. So the installer's
"Installed Omarchy in ..." screen and the Reboot Now prompt now belong to a
direct install only: for a deferred install the dashboard clears and reboots on
its own. .automated_script.sh detects deferred mode (the config's
defer_provisioning flag, or the cidata defer-provisioning marker) and passes
OMARCHY_UI_DEFER_PROVISIONING to the dashboard.

Harness: a deferred install no longer shows Reboot Now, so wait_for_install
recognizes the auto-reboot by the first-boot greeter tagline appearing.

Co-Authored-By: Claude <noreply@anthropic.com>

* Detect deferred mode with jq, not a line regex

The dashboard's deferred detection grepped user_configuration.json for the
defer_provisioning boolean on one line; a reformatted config would read as a
direct install and wrongly show the celebration. Parse it with jq using the
same path the orchestrator reads (.omarchy_install.defer_provisioning).

Co-Authored-By: Claude <noreply@anthropic.com>

* Drop Bosnian and Khmer from the installer keyboard picker

Match the first-boot picker: neither has a console keymap, so both silently
fell back to US. Remove them rather than offer a layout that can't apply.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 21:56:01 +02:00
2025-11-26 01:29:16 -05:00
2025-08-15 09:38:30 +02:00
2026-07-28 08:43:43 -07:00

Omarchy ISO

The Omarchy ISO is the only supported way to install Omarchy. It ships the Omarchy Configurator, installs Arch Linux, installs the Omarchy packages from the bundled mirror, runs target system setup in the chroot, creates the user, and runs omarchy-setup-user for that user.

Downloading the latest ISO

See the ISO link on omarchy.org.

Creating the ISO

Run ./bin/omarchy-iso-make; output goes into ./release. By default the ISO uses the Omarchy packages and tracks the quattro branch, from the stable mirror. Pass --edge to use omarchy-dev and omarchy-settings-dev from the edge mirror.

For local development, build the ISO from sibling checkouts:

./bin/omarchy-iso-make --local-source ../omarchy-installer ../omarchy-pkgs

Despite the local folder name, the first argument is the Omarchy source checkout (runtime commands, configs, setup scripts, themes, shell, migrations). The installer itself lives in this ISO repo.

Use --dev or --rc to build against those package channels. Both --dev and --edge select the dev packages from the edge mirror.

Autoinstall

The shipped ISO installs itself with no keyboard when it finds its configuration on a second drive. Attach a drive labeled cidata alongside the ISO and the installer copies the config off it and skips the configurator; with no such drive, nothing changes and the wizard runs as usual. No rebuild, no extra boot entry.

cidata is the cloud-init NoCloud label, so Proxmox, libvirt, and Packer already know how to attach one.

Configuration files

These are the configurator's own output files, so the way to get a starting set is to run one interactive install and copy what it wrote into /root.

File Required Purpose
user_configuration.json Yes archinstall config: disk, hostname, timezone, keyboard
user_credentials.json Yes Username and password hash
user_full_name.txt No Git full name
user_email_address.txt No Git email
user_encrypt_installation.txt No true when user_configuration.json carries a disk_encryption block; defaults to false
authorized_keys No SSH public keys in sshd's own format, one per line
tailscale_authkey No Tailscale auth key; the machine joins your tailnet on first boot

Both required files must be present or the installer falls back to the configurator. Generate the password hash for user_credentials.json with openssl passwd -6 "yourpassword".

Encryption itself is configured by the disk_encryption block inside user_configuration.json — which carries the passphrase in plaintext, so treat a drive built from an encrypted install accordingly. The flag file must match it: it drives the encrypted install's SDDM autologin and the final boot validation, not the encryption.

authorized_keys is the same file sshd reads — copy your own or write one key per line:

ssh-ed25519 AAAA... you@host

When authorized_keys is present, autoinstall installs it as the user's ~/.ssh/authorized_keys, enables sshd, and adds a ufw allow ssh rule — a stock Omarchy install ships openssh with the service disabled and its firewall opens neither port 22 nor anything else beyond LocalSend. Networking needs nothing extra; NetworkManager is already enabled with DHCP. Password SSH authentication is left at the distro default. An authorized_keys with no usable keys fails the install rather than producing a machine nobody can reach.

When tailscale_authkey is present (one key, blank lines and # comments ignored), the install adds the tailscale package from the ISO's bundled mirror — nothing is fetched from the network at install or boot — and stages the join for first boot: the key lands at /etc/tailscale/authkey (root-only), tailscaled is enabled, ufw allows traffic in on tailscale0, and a background unit runs tailscale up once the network is actually up, retrying until it succeeds without holding up the boot. After a successful join the key is deleted and the unit disables itself; until then both survive reboots, so a machine installed offline joins whenever it first gets connectivity. The node appears on the tailnet under the configured hostname. Use a reusable, pre-authorized (tagged) key so one drive image serves many machines — or an ephemeral key for disposable VMs.

Building the drive

mkdir cidata
cp user_configuration.json user_credentials.json authorized_keys cidata/
genisoimage -output cidata.iso -volid cidata -joliet -rock cidata/

Proxmox example

qm create 101 --name my-omarchy \
  --bios ovmf --machine q35 --cpu host --cores 4 --memory 8192 \
  --ostype l26 --scsihw virtio-scsi-single \
  --efidisk0 local-lvm:0,efitype=4m,pre-enrolled-keys=0 \
  --scsi0 local-lvm:40,discard=on,iothread=1 \
  --net0 virtio,bridge=vmbr0 --vga virtio --serial0 socket \
  --ide2 local:iso/omarchy.iso,media=cdrom \
  --ide3 local:iso/cidata.iso,media=cdrom \
  --boot order='scsi0;ide2'

qm start 101

Boot order is disk first: the empty disk falls through to the ISO on the first boot, and the installed system boots from disk afterwards. The machine reboots into Omarchy on its own when the install finishes.

Encrypted autoinstalls are not fully unattended — the LUKS passphrase prompt still needs someone at the first boot.

Testing the ISO

Run ./bin/omarchy-iso-boot [release/omarchy.iso].

Run ./test/all for the unit tests, which cover cidata autoinstall loading and the orchestrator's SSH access phase without needing a built ISO.

To exercise installation alongside existing Windows-style partitions, run ./bin/omarchy-iso-test-windows-disk [release/omarchy.iso]. It creates a synthetic disk in /tmp with an existing ESP and data partition plus ample unallocated space, then offers to start an interactive installation on it. The fixture exercises Windows partition preservation but does not contain Windows.

Acceptance testing the ISO

Run ./bin/omarchy-iso-test [release/omarchy.iso] to install the ISO into a headless VM by driving the real interactive install flow — the harness reads each screen via QMP screendumps + OCR and answers with virtual keystrokes, so the configurator wizard, install dashboard, reboot prompt, and SDDM login are all exercised exactly as a user would. It then boots the installed system, sends real VM keyboard shortcuts for the primary shell and window-management actions, and runs the in-guest acceptance suite (test/acceptance in the omarchy repo). The suite checks session and service health, the complete core-package manifest, user defaults, representative applications, menus, panels, live weather, launchers, visual selectors, notifications, clipboard, and other interactive shell behavior.

Visual checkpoints are saved as success-<step>.png or failure-<step>.png alongside the serial and install logs in test-runs/<iso>/runs/<timestamp>/. Independent test files and applications continue after a failure so one broken surface does not hide the rest of the report. The harness then stops the VM and opens the ordered screenshots in imv for quick visual review.

The harness syncs the acceptance suite from $OMARCHY_PATH when it is available. The install phase produces a reusable base image, so iterating against another checkout is fast:

./bin/omarchy-iso-test release/omarchy.iso --install-only        # once per ISO
./bin/omarchy-iso-test release/omarchy.iso --reuse-base \
  --sync-omarchy ../omarchy                                      # fast loop against local tests

Pass --encrypt to drive the encrypted install flow (including typing the LUKS passphrase at boot) instead of the unencrypted one. Pass --no-preview to collect the same visual artifacts without opening them in imv when the run finishes.

Signing the ISO

Run ./bin/omarchy-iso-sign [release/omarchy.iso]. The signing key is retrieved from the shared Omarchy vault with the 1Password CLI.

Uploading the ISO

Run ./bin/omarchy-iso-upload [release/omarchy.iso]. This requires rclone configuration (rclone config).

Full release of the ISO

Run ./bin/omarchy-iso-release VERSION to create, test, sign, and upload the ISO in one flow. Add --rc to release an RC build instead.

S
Description
Omarchy ISO with the Chinese installer. Fork of omacom/omarchy-iso.
Readme MIT
2 MiB
0 Stars 1 Watchers 0 Forks
Languages
Shell 61%
Python 39%