From ccecdbde56a0174a7962ccffaabe412f96d0c4cd Mon Sep 17 00:00:00 2001 From: Jim Martin Date: Wed, 9 Sep 2026 22:36:53 -0500 Subject: [PATCH 1/6] omarchy-settings: keep the Limine and mkinitcpio drop-ins on aarch64 The aarch64 packages removed etc/mkinitcpio.conf.d and etc/limine-entry-tool.d wholesale. On an encrypted aarch64 install that boots with Limine (DGX Spark, Snapdragon X), installing the published package therefore drops omarchy_hooks.conf, HOOKS falls back to /etc/mkinitcpio.conf, and the next kernel update builds an initramfs with no encrypt hook: the machine hangs waiting for /dev/mapper/root with no prompt. Ship both drop-in directories on aarch64 and remove only thunderbolt_module.conf, whose module ARM kernels do not have. Keep the Limine template and the snapper notifier autostart for the same reason. The memory-stack removals (zram, oomd, zswap, USB autosuspend) are unchanged. --- pkgbuilds/omarchy-settings-dev/PKGBUILD | 42 ++++++++++------------- pkgbuilds/omarchy-settings/PKGBUILD | 44 ++++++++++--------------- 2 files changed, 35 insertions(+), 51 deletions(-) diff --git a/pkgbuilds/omarchy-settings-dev/PKGBUILD b/pkgbuilds/omarchy-settings-dev/PKGBUILD index 6c7f8d9..61dd516 100644 --- a/pkgbuilds/omarchy-settings-dev/PKGBUILD +++ b/pkgbuilds/omarchy-settings-dev/PKGBUILD @@ -6,10 +6,11 @@ _pkgver_base=4.0.0 _pkgver_base_tag=v3.8.2 pkgdesc='Omarchy user defaults, /etc/skel content, fonts, plymouth theme, and support helpers (quattro branch tip)' # Arch-specific because the shipped /etc tree is not the same on every -# architecture: the Limine, mkinitcpio, zram and oomd drop-ins belong to the -# x86_64 boot and memory stack and are left out of the aarch64 package (see -# package()). makepkg only honours the arch-suffixed arrays below on -# arch-specific packages. +# architecture: the zram and oomd drop-ins belong to the x86_64 memory stack +# and are left out of the aarch64 package (see package()). The Limine and +# mkinitcpio drop-ins ship on both: UEFI aarch64 installs (DGX Spark, +# Snapdragon X) boot with Limine and an encrypted root exactly like x86_64. +# makepkg only honours the arch-suffixed arrays below on arch-specific packages. arch=('x86_64' 'aarch64') url='https://github.com/basecamp/omarchy' license=('MIT') @@ -68,14 +69,17 @@ backup=( 'etc/udev/rules.d/99-omarchy-power-profile.rules' 'etc/udev/rules.d/99-omarchy-wifi-powersave.rules' ) +# Boot configuration is backed up on both architectures. +backup+=( + 'etc/mkinitcpio.conf.d/omarchy_hooks.conf' + 'etc/limine-entry-tool.d/omarchy-defaults.conf' + 'etc/limine-entry-tool.d/omarchy-uki.conf' +) # backup has no arch-suffixed form, so the x86_64-only drop-ins join it here. # Each of these paths is removed from the aarch64 package in package(). if [[ $CARCH == x86_64 ]]; then backup+=( - 'etc/mkinitcpio.conf.d/omarchy_hooks.conf' 'etc/mkinitcpio.conf.d/thunderbolt_module.conf' - 'etc/limine-entry-tool.d/omarchy-defaults.conf' - 'etc/limine-entry-tool.d/omarchy-uki.conf' 'etc/modprobe.d/omarchy-usb-autosuspend.conf' 'etc/systemd/oomd.conf.d/10-omarchy.conf' 'etc/systemd/zram-generator.conf' @@ -160,14 +164,6 @@ package() { install -d "$pkgdir/usr/share/omarchy/config" cp -a config/. "$pkgdir/usr/share/omarchy/config/" - # The Limine/Snapper notifier has nothing to notify about without the x86_64 - # boot stack; drop it from both seeds so aarch64 users don't autostart a - # helper whose backing tool is not installed. - if [[ $CARCH == aarch64 ]]; then - rm -f "$pkgdir/etc/skel/.config/autostart/limine-snapper-notify.desktop" \ - "$pkgdir/usr/share/omarchy/config/autostart/limine-snapper-notify.desktop" - fi - # Package-owned defaults with real system/XDG locations. User config remains # higher priority: ~/.config/uwsm/default, ~/.config/uwsm/env.d, # ~/.config/environment.d, ~/.config/fontconfig, ~/.config/xdg-terminals.list, @@ -217,11 +213,12 @@ package() { install -d "$pkgdir/etc" cp -a etc/. "$pkgdir/etc/" if [[ $CARCH == aarch64 ]]; then - # The x86_64 boot stack's drop-ins must not ship on aarch64: mkinitcpio - # reads every file under /etc/mkinitcpio.conf.d/, so omarchy_hooks.conf - # would inject the Limine hooks into the Asahi kernel's initramfs, and the - # Limine entry-tool config has no consumer without Limine. - rm -rf "$pkgdir/etc/limine-entry-tool.d" "$pkgdir/etc/mkinitcpio.conf.d" + # Keep omarchy_hooks.conf and the Limine entry-tool config: without them a + # kernel update on an encrypted aarch64 install rebuilds an initramfs with + # no encrypt hook and the machine cannot unlock its root. Only the + # Thunderbolt module request is x86-specific; ARM kernels lack the module + # and mkinitcpio treats a missing explicit module as an error. + rm -f "$pkgdir/etc/mkinitcpio.conf.d/thunderbolt_module.conf" # Memory stack: no zram device or zswap on the aarch64 install, and # systemd-oomd is not enabled there, so the vm.* reclaim tuning written # for zram would be wrong for it. Keep only the network tuning. @@ -325,11 +322,6 @@ EOF # live root config. install -d "$pkgdir/usr/share/omarchy/default" cp -a default/. "$pkgdir/usr/share/omarchy/default/" - # The Limine template is read by the x86_64 ISO orchestrator only. - if [[ $CARCH == aarch64 ]]; then - rm -rf "$pkgdir/usr/share/omarchy/default/limine" - fi - # Snapper config template used by the install-time `snapper create-config`. install -Dm644 default/snapper/root \ "$pkgdir/etc/snapper/config-templates/omarchy" diff --git a/pkgbuilds/omarchy-settings/PKGBUILD b/pkgbuilds/omarchy-settings/PKGBUILD index 0d063f3..346dbe2 100644 --- a/pkgbuilds/omarchy-settings/PKGBUILD +++ b/pkgbuilds/omarchy-settings/PKGBUILD @@ -13,13 +13,14 @@ pkgname='omarchy-settings' _tag='v4.0.3' _commit='0534987009061cbe2dacdde4ad564092ab698d12' pkgver=4.0.3 -pkgrel=1 +pkgrel=2 pkgdesc='Omarchy user defaults, /etc/skel content, fonts, plymouth theme, and support helpers' # Arch-specific because the shipped /etc tree is not the same on every -# architecture: the Limine, mkinitcpio, zram and oomd drop-ins belong to the -# x86_64 boot and memory stack and are left out of the aarch64 package (see -# package()). makepkg only honours the arch-suffixed arrays below on -# arch-specific packages. +# architecture: the zram and oomd drop-ins belong to the x86_64 memory stack +# and are left out of the aarch64 package (see package()). The Limine and +# mkinitcpio drop-ins ship on both: UEFI aarch64 installs (DGX Spark, +# Snapdragon X) boot with Limine and an encrypted root exactly like x86_64. +# makepkg only honours the arch-suffixed arrays below on arch-specific packages. arch=('x86_64' 'aarch64') url='https://github.com/basecamp/omarchy' license=('MIT') @@ -77,14 +78,17 @@ backup=( 'etc/udev/rules.d/99-omarchy-power-profile.rules' 'etc/udev/rules.d/99-omarchy-wifi-powersave.rules' ) +# Boot configuration is backed up on both architectures. +backup+=( + 'etc/mkinitcpio.conf.d/omarchy_hooks.conf' + 'etc/limine-entry-tool.d/omarchy-defaults.conf' + 'etc/limine-entry-tool.d/omarchy-uki.conf' +) # backup has no arch-suffixed form, so the x86_64-only drop-ins join it here. # Each of these paths is removed from the aarch64 package in package(). if [[ $CARCH == x86_64 ]]; then backup+=( - 'etc/mkinitcpio.conf.d/omarchy_hooks.conf' 'etc/mkinitcpio.conf.d/thunderbolt_module.conf' - 'etc/limine-entry-tool.d/omarchy-defaults.conf' - 'etc/limine-entry-tool.d/omarchy-uki.conf' 'etc/modprobe.d/omarchy-usb-autosuspend.conf' 'etc/systemd/oomd.conf.d/10-omarchy.conf' 'etc/systemd/zram-generator.conf' @@ -155,14 +159,6 @@ package() { install -d "$pkgdir/usr/share/omarchy/config" cp -a config/. "$pkgdir/usr/share/omarchy/config/" - # The Limine/Snapper notifier has nothing to notify about without the x86_64 - # boot stack; drop it from both seeds so aarch64 users don't autostart a - # helper whose backing tool is not installed. - if [[ $CARCH == aarch64 ]]; then - rm -f "$pkgdir/etc/skel/.config/autostart/limine-snapper-notify.desktop" \ - "$pkgdir/usr/share/omarchy/config/autostart/limine-snapper-notify.desktop" - fi - # Package-owned defaults with real system/XDG locations. User config remains # higher priority: ~/.config/uwsm/default, ~/.config/uwsm/env.d, # ~/.config/environment.d, ~/.config/fontconfig, ~/.config/xdg-terminals.list, @@ -215,11 +211,12 @@ package() { install -d "$pkgdir/etc" cp -a etc/. "$pkgdir/etc/" if [[ $CARCH == aarch64 ]]; then - # The x86_64 boot stack's drop-ins must not ship on aarch64: mkinitcpio - # reads every file under /etc/mkinitcpio.conf.d/, so omarchy_hooks.conf - # would inject the Limine hooks into the Asahi kernel's initramfs, and the - # Limine entry-tool config has no consumer without Limine. - rm -rf "$pkgdir/etc/limine-entry-tool.d" "$pkgdir/etc/mkinitcpio.conf.d" + # Keep omarchy_hooks.conf and the Limine entry-tool config: without them a + # kernel update on an encrypted aarch64 install rebuilds an initramfs with + # no encrypt hook and the machine cannot unlock its root. Only the + # Thunderbolt module request is x86-specific; ARM kernels lack the module + # and mkinitcpio treats a missing explicit module as an error. + rm -f "$pkgdir/etc/mkinitcpio.conf.d/thunderbolt_module.conf" # Memory stack: no zram device or zswap on the aarch64 install, and # systemd-oomd is not enabled there, so the vm.* reclaim tuning written # for zram would be wrong for it. Keep only the network tuning. @@ -323,11 +320,6 @@ EOF # live root config. install -d "$pkgdir/usr/share/omarchy/default" cp -a default/. "$pkgdir/usr/share/omarchy/default/" - # The Limine template is read by the x86_64 ISO orchestrator only. - if [[ $CARCH == aarch64 ]]; then - rm -rf "$pkgdir/usr/share/omarchy/default/limine" - fi - # Snapper config template used by the install-time `snapper create-config`. install -Dm644 default/snapper/root \ "$pkgdir/etc/snapper/config-templates/omarchy" From 39722554db638febabe1cceb6f787e8a25619c19 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Wed, 16 Sep 2026 20:37:43 +0200 Subject: [PATCH 2/6] Refresh dev settings version and package revision Record the current quattro-derived version before bumping pkgrel, so makepkg does not discard the revision bump when updating a stale pkgver. --- pkgbuilds/omarchy-settings-dev/PKGBUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgbuilds/omarchy-settings-dev/PKGBUILD b/pkgbuilds/omarchy-settings-dev/PKGBUILD index 46ee0bf..273e387 100644 --- a/pkgbuilds/omarchy-settings-dev/PKGBUILD +++ b/pkgbuilds/omarchy-settings-dev/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Ryan Hughes pkgname='omarchy-settings-dev' -pkgver=4.0.0.r847.g4de185b -pkgrel=1 +pkgver=4.0.0.r2153.g9c5482c +pkgrel=2 _pkgver_base=4.0.0 _pkgver_base_tag=v3.8.2 pkgdesc='Omarchy user defaults, /etc/skel content, fonts, plymouth theme, and support helpers (quattro branch tip)' From 203b7340ab227407da1f4f3cb51b9dce87a16b5b Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Wed, 16 Sep 2026 20:37:43 +0200 Subject: [PATCH 3/6] Test packaged boot settings on ARM and x86_64 Exercise both settings recipes with synthetic runtime files. Check the exact Limine templates, boot drop-ins and backup metadata, installer-owned configuration, notifier copies and architecture-specific Thunderbolt handling. Run package regressions in the existing self-test job. --- .github/workflows/test.yml | 4 ++ pkgbuilds/omarchy-settings/test.sh | 110 +++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 pkgbuilds/omarchy-settings/test.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6e48346..4910361 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,4 +47,8 @@ jobs: ./bin/omarchy-release self-test ./tests/partial-release.sh ./tests/published-build-plan.sh + shopt -s nullglob + for test in pkgbuilds/*/test.sh; do + bash "$test" + done ' diff --git a/pkgbuilds/omarchy-settings/test.sh b/pkgbuilds/omarchy-settings/test.sh new file mode 100644 index 0000000..5cb8c62 --- /dev/null +++ b/pkgbuilds/omarchy-settings/test.sh @@ -0,0 +1,110 @@ +#!/bin/bash +# Exercise the real package functions with a minimal, synthetic runtime tree. +set -euo pipefail + +BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/../..") +scratch=$(mktemp -d) +trap 'rm -rf "$scratch"' EXIT +fixture=$scratch/src/omarchy + +files=( + config/autostart/limine-snapper-notify.desktop + etc/fastfetch/config.jsonc + etc/mkinitcpio.conf.d/omarchy_hooks.conf + etc/mkinitcpio.conf.d/thunderbolt_module.conf + etc/limine-entry-tool.d/omarchy-defaults.conf + etc/limine-entry-tool.d/omarchy-uki.conf + etc/security/faillock.conf + etc/nsswitch.conf + etc/cups/cups-browsed.conf + etc/cups/cups-files.conf + etc/plymouth/plymouthd.conf + etc/sysctl.d/99-omarchy-sysctl.conf + default/uwsm/env.d/10-omarchy + default/environment.d/10-omarchy-fcitx.conf + default/fontconfig/conf.avail/50-omarchy.conf + default/xdg-terminal-exec/hyprland-xdg-terminals.list + default/applications/mimeapps.list + default/systemd/user/bt-agent.service + default/systemd/user/omarchy-sleep-lock.service + default/systemd/user/omarchy-recover-internal-monitor.service + default/systemd/user/omarchy-migrate-notify.service + default/systemd/user/omarchy-tailscale-receive.service + default/systemd/user/omarchy-fcitx5.service + default/systemd/user/omarchy-crash-watch.service + default/systemd/user/app.slice.d/10-oomd.conf + default/systemd/zram-generator.conf.d/90-omarchy.conf + default/systemd/system/plocate-updatedb.service.d/10-omarchy.conf + default/systemd/system-sleep/unmount-fuse + default/bashrc + default/limine/default.conf + default/limine/limine.conf + default/snapper/root + default/sddm/omarchy/Main.qml + default/sddm/hyprland.lua + default/wayland-sessions/omarchy.desktop + default/plymouth/omarchy.plymouth + default/fonts/omarchy/omarchy.ttf + default/hypr/toggles/flags.lua + default/nautilus-python/extensions/localsend.py + default/nautilus-python/extensions/transcode.py + default/tensaku/state.toml + applications/example.desktop + bin/omarchy-upload-log + bin/omarchy-debug + bin/omarchy-debug-idle + logo.txt + logo.svg + icon.txt + icon.png +) +for path in "${files[@]}"; do + mkdir -p "$(dirname "$fixture/$path")" + printf 'fixture for %s\n' "$path" > "$fixture/$path" +done + +for recipe in omarchy-settings omarchy-settings-dev; do + for target_arch in aarch64 x86_64; do + ( + export CARCH=$target_arch OMARCHY_SRC=$fixture + export srcdir=$scratch/src pkgdir=$scratch/$recipe-$target_arch + backup=() + # shellcheck disable=SC1090 # Exercise each recipe's actual package function. + source "$BUILD_ROOT/pkgbuilds/$recipe/PKGBUILD" + package + + for path in etc/mkinitcpio.conf.d/omarchy_hooks.conf \ + etc/limine-entry-tool.d/omarchy-defaults.conf \ + etc/limine-entry-tool.d/omarchy-uki.conf; do + cmp "$fixture/$path" "$pkgdir/$path" + printf '%s\n' "${backup[@]}" | grep -Fxq "$path" + done + for template in default.conf limine.conf; do + cmp "$fixture/default/limine/$template" "$pkgdir/usr/share/omarchy/default/limine/$template" + done + # The installer owns the machine-specific live configuration. + [[ ! -e $pkgdir/etc/default/limine ]] + if printf '%s\n' "${backup[@]}" | grep -Fxq 'etc/default/limine'; then + echo 'FAIL: installer-owned Limine configuration is in backup metadata' >&2 + exit 1 + fi + cmp "$fixture/config/autostart/limine-snapper-notify.desktop" \ + "$pkgdir/etc/skel/.config/autostart/limine-snapper-notify.desktop" + cmp "$fixture/config/autostart/limine-snapper-notify.desktop" \ + "$pkgdir/usr/share/omarchy/config/autostart/limine-snapper-notify.desktop" + + thunderbolt=etc/mkinitcpio.conf.d/thunderbolt_module.conf + if [[ $CARCH == aarch64 ]]; then + [[ ! -e $pkgdir/$thunderbolt ]] + if printf '%s\n' "${backup[@]}" | grep -Fxq "$thunderbolt"; then + echo 'FAIL: removed ARM Thunderbolt config remains in backup metadata' >&2 + exit 1 + fi + else + cmp "$fixture/$thunderbolt" "$pkgdir/$thunderbolt" + printf '%s\n' "${backup[@]}" | grep -Fxq "$thunderbolt" + fi + echo "PASS: $recipe $CARCH retains boot configuration and matching backup metadata" + ) + done +done From 16b1a730f6627786f442ebccb7fbeaeeb68df5e5 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Wed, 16 Sep 2026 20:54:59 +0200 Subject: [PATCH 4/6] Run boot settings regression explicitly from tests --- .github/workflows/test.yml | 5 +---- .../test.sh => tests/settings-boot-config.sh | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) rename pkgbuilds/omarchy-settings/test.sh => tests/settings-boot-config.sh (98%) mode change 100644 => 100755 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4910361..f50f8f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,8 +47,5 @@ jobs: ./bin/omarchy-release self-test ./tests/partial-release.sh ./tests/published-build-plan.sh - shopt -s nullglob - for test in pkgbuilds/*/test.sh; do - bash "$test" - done + ./tests/settings-boot-config.sh ' diff --git a/pkgbuilds/omarchy-settings/test.sh b/tests/settings-boot-config.sh old mode 100644 new mode 100755 similarity index 98% rename from pkgbuilds/omarchy-settings/test.sh rename to tests/settings-boot-config.sh index 5cb8c62..b9dcff7 --- a/pkgbuilds/omarchy-settings/test.sh +++ b/tests/settings-boot-config.sh @@ -2,7 +2,7 @@ # Exercise the real package functions with a minimal, synthetic runtime tree. set -euo pipefail -BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/../..") +BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..") scratch=$(mktemp -d) trap 'rm -rf "$scratch"' EXIT fixture=$scratch/src/omarchy From 21f3c4a8c4bc5fdae36dca47974fc96ffc890906 Mon Sep 17 00:00:00 2001 From: Jim Martin Date: Sun, 27 Sep 2026 09:03:08 -0500 Subject: [PATCH 5/6] omarchy-settings: keep the Mac initramfs hooks on aarch64 Apple Silicon Macs install the aarch64 package too, and an unconditional HOOKS= line would replace their asahi hooks. Apply Omarchy's HOOKS line only when the incoming hooks lack asahi, in whichever drop-in carries it, and rebuild omarchy-settings (4.0.4-3) so existing installs get the fix. --- pkgbuilds/omarchy-settings-dev/PKGBUILD | 16 +++ pkgbuilds/omarchy-settings/PKGBUILD | 18 ++- tests/settings-boot-config.sh | 165 +++++++++++++++++++++++- 3 files changed, 197 insertions(+), 2 deletions(-) diff --git a/pkgbuilds/omarchy-settings-dev/PKGBUILD b/pkgbuilds/omarchy-settings-dev/PKGBUILD index ce5ebbe..714fc61 100644 --- a/pkgbuilds/omarchy-settings-dev/PKGBUILD +++ b/pkgbuilds/omarchy-settings-dev/PKGBUILD @@ -220,6 +220,22 @@ package() { # Thunderbolt module request is x86-specific; ARM kernels lack the module # and mkinitcpio treats a missing explicit module as an error. rm -f "$pkgdir/etc/mkinitcpio.conf.d/thunderbolt_module.conf" + # Apple Silicon Macs install this package too. Their initramfs needs the + # asahi hook, which omarchy-mac-boot's 90-94 fragments (Aurora) or + # mkinitcpio.conf (legacy GRUB Macs) set, and an unconditional HOOKS= here + # would replace it. Omarchy's line applies only when the hooks loaded so far + # lack asahi. The check reads configuration, not the running machine, so it + # also holds when the image is built in a chroot. + local hooks_conf guarded=0 + for hooks_conf in "$pkgdir"/etc/mkinitcpio.conf.d/{00-omarchy-hooks,omarchy_hooks}.conf; do + [[ -f $hooks_conf ]] && grep -q '^HOOKS=(' "$hooks_conf" || continue + sed -i 's/^\(HOOKS=(.*)\)$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf" + guarded=1 + done + if (( ! guarded )); then + echo "No HOOKS= line to guard for Apple Silicon in etc/mkinitcpio.conf.d" >&2 + return 1 + fi # Memory stack: no zram device or zswap on the aarch64 install, and # systemd-oomd is not enabled there, so the vm.* reclaim tuning written # for zram would be wrong for it. Keep only the network tuning. diff --git a/pkgbuilds/omarchy-settings/PKGBUILD b/pkgbuilds/omarchy-settings/PKGBUILD index 7ad64a3..655189c 100644 --- a/pkgbuilds/omarchy-settings/PKGBUILD +++ b/pkgbuilds/omarchy-settings/PKGBUILD @@ -13,7 +13,7 @@ pkgname='omarchy-settings' _tag='v4.0.4' _commit='c668141e9c42b13c80c9ca4ea108e11708c5e8a5' pkgver=4.0.4 -pkgrel=2 +pkgrel=3 pkgdesc='Omarchy user defaults, /etc/skel content, fonts, plymouth theme, and support helpers' # Arch-specific because the shipped /etc tree is not the same on every # architecture: the zram and oomd drop-ins belong to the x86_64 memory stack @@ -218,6 +218,22 @@ package() { # Thunderbolt module request is x86-specific; ARM kernels lack the module # and mkinitcpio treats a missing explicit module as an error. rm -f "$pkgdir/etc/mkinitcpio.conf.d/thunderbolt_module.conf" + # Apple Silicon Macs install this package too. Their initramfs needs the + # asahi hook, which omarchy-mac-boot's 90-94 fragments (Aurora) or + # mkinitcpio.conf (legacy GRUB Macs) set, and an unconditional HOOKS= here + # would replace it. Omarchy's line applies only when the hooks loaded so far + # lack asahi. The check reads configuration, not the running machine, so it + # also holds when the image is built in a chroot. + local hooks_conf guarded=0 + for hooks_conf in "$pkgdir"/etc/mkinitcpio.conf.d/{00-omarchy-hooks,omarchy_hooks}.conf; do + [[ -f $hooks_conf ]] && grep -q '^HOOKS=(' "$hooks_conf" || continue + sed -i 's/^\(HOOKS=(.*)\)$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf" + guarded=1 + done + if (( ! guarded )); then + echo "No HOOKS= line to guard for Apple Silicon in etc/mkinitcpio.conf.d" >&2 + return 1 + fi # Memory stack: no zram device or zswap on the aarch64 install, and # systemd-oomd is not enabled there, so the vm.* reclaim tuning written # for zram would be wrong for it. Keep only the network tuning. diff --git a/tests/settings-boot-config.sh b/tests/settings-boot-config.sh index b9dcff7..dfbe742 100755 --- a/tests/settings-boot-config.sh +++ b/tests/settings-boot-config.sh @@ -63,6 +63,10 @@ for path in "${files[@]}"; do printf 'fixture for %s\n' "$path" > "$fixture/$path" done +# Omarchy's HOOKS line, as its sources ship it. +omarchy_hooks='base udev plymouth keyboard autodetect microcode modconf kms keymap consolefont block encrypt filesystems fsck btrfs-overlayfs' +printf 'HOOKS=(%s)\n' "$omarchy_hooks" > "$fixture/etc/mkinitcpio.conf.d/omarchy_hooks.conf" + for recipe in omarchy-settings omarchy-settings-dev; do for target_arch in aarch64 x86_64; do ( @@ -76,9 +80,18 @@ for recipe in omarchy-settings omarchy-settings-dev; do for path in etc/mkinitcpio.conf.d/omarchy_hooks.conf \ etc/limine-entry-tool.d/omarchy-defaults.conf \ etc/limine-entry-tool.d/omarchy-uki.conf; do - cmp "$fixture/$path" "$pkgdir/$path" printf '%s\n' "${backup[@]}" | grep -Fxq "$path" done + for path in etc/limine-entry-tool.d/omarchy-defaults.conf etc/limine-entry-tool.d/omarchy-uki.conf; do + cmp "$fixture/$path" "$pkgdir/$path" + done + hooks_conf=etc/mkinitcpio.conf.d/omarchy_hooks.conf + if [[ $CARCH == aarch64 ]]; then + grep -Fxq 'if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then' "$pkgdir/$hooks_conf" + bash -n "$pkgdir/$hooks_conf" + else + cmp "$fixture/$hooks_conf" "$pkgdir/$hooks_conf" + fi for template in default.conf limine.conf; do cmp "$fixture/default/limine/$template" "$pkgdir/usr/share/omarchy/default/limine/$template" done @@ -108,3 +121,153 @@ for recipe in omarchy-settings omarchy-settings-dev; do ) done done + +# The aarch64 packages also reach Apple Silicon Macs, whose initramfs needs the +# asahi hook. Source mkinitcpio.conf and the drop-ins in mkinitcpio's order and +# compare the resulting HOOKS for each kind of aarch64 install. +package_aarch64() { + local recipe=$1 source_tree=$2 out=$3 + ( + # package() builds from $srcdir/omarchy. + export CARCH=aarch64 OMARCHY_SRC=$source_tree srcdir=${source_tree%/omarchy} pkgdir=$out + backup=() + # shellcheck disable=SC1090 # Exercise the recipe's actual package function. + source "$BUILD_ROOT/pkgbuilds/$recipe/PKGBUILD" + package + ) +} + +effective_hooks() { + local root=$1 + ( + LC_ALL=C + HOOKS=() + # shellcheck disable=SC1091 + source "$root/mkinitcpio.conf" + shopt -s nullglob + for conf in "$root"/mkinitcpio.conf.d/*.conf; do + # shellcheck disable=SC1090 + source "$conf" + done + echo "${HOOKS[*]}" + ) +} + +# machine NAME MKINITCPIO_HOOKS PACKAGED_ETC [FRAGMENT FRAGMENT_HOOKS] +machine() { + local root=$scratch/machines/$1 + mkdir -p "$root/mkinitcpio.conf.d" + printf 'HOOKS=(%s)\n' "$2" > "$root/mkinitcpio.conf" + cp "$3"/*.conf "$root/mkinitcpio.conf.d/" + if (($# == 5)); then + printf 'HOOKS=(%s)\n' "$5" > "$root/mkinitcpio.conf.d/$4" + fi + printf '%s\n' "$root" +} + +arch_default='base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck' +snapdragon='base systemd autodetect microcode modconf kms keyboard sd-vconsole block filesystems fsck' +legacy_mac='base udev autodetect modconf kms keyboard keymap consolefont block asahi encrypt filesystems fsck' +aurora_mac='base udev autodetect modconf kms keyboard keymap consolefont block asahi omarchy-vendorfw omarchy-mac-encrypt sd-encrypt filesystems fsck' + +check_machines() { + local layout=$1 packaged=$2/etc/mkinitcpio.conf.d root + rm -rf "$scratch/machines" + root=$(machine snapdragon "$snapdragon" "$packaged") + [[ $(effective_hooks "$root") == "$omarchy_hooks" ]] || + { echo "FAIL: $layout: Snapdragon gets $(effective_hooks "$root")" >&2; exit 1; } + root=$(machine spark "$arch_default" "$packaged") + [[ $(effective_hooks "$root") == "$omarchy_hooks" ]] || + { echo "FAIL: $layout: DGX Spark gets $(effective_hooks "$root")" >&2; exit 1; } + root=$(machine legacy-mac "$legacy_mac" "$packaged") + [[ $(effective_hooks "$root") == "$legacy_mac" ]] || + { echo "FAIL: $layout: a legacy GRUB Mac loses asahi: $(effective_hooks "$root")" >&2; exit 1; } + root=$(machine aurora-mac "$arch_default" "$packaged" 92-omarchy-mac-boot.conf "$aurora_mac") + [[ $(effective_hooks "$root") == "$aurora_mac" ]] || + { echo "FAIL: $layout: an Aurora Mac loses its hooks: $(effective_hooks "$root")" >&2; exit 1; } + echo "PASS: $layout: Snapdragon and the Spark get Omarchy's hooks; Macs keep asahi" +} + +check_machines "HOOKS in omarchy_hooks.conf" "$scratch/omarchy-settings-aarch64" + +# omacom/omarchy#13362 moves the HOOKS line into 00-omarchy-hooks.conf. +split=$scratch/split/omarchy +mkdir -p "$scratch/split" +cp -a "$fixture" "$split" +printf 'HOOKS=(%s)\n' "$omarchy_hooks" > "$split/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" +sed -i '/^HOOKS=/d' "$split/etc/mkinitcpio.conf.d/omarchy_hooks.conf" +package_aarch64 omarchy-settings "$split" "$scratch/split-package" >/dev/null +grep -Fxq 'if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then' \ + "$scratch/split-package/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" +check_machines "HOOKS in 00-omarchy-hooks.conf" "$scratch/split-package" + +sed -i '/^HOOKS=/d' "$split/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" +if package_aarch64 omarchy-settings "$split" "$scratch/unguarded-package" 2>/dev/null; then + echo 'FAIL: the aarch64 package builds without a HOOKS line to guard' >&2 + exit 1 +fi +echo "PASS: the aarch64 package fails to build without a HOOKS line to guard" + +# Upgrades: pacman replaces an unmodified hooks file, keeps a modified one and +# leaves the guarded version as .pacnew, and installs it where it was absent. +if ((EUID != 0)) || ! command -v pacman >/dev/null; then + echo "SKIP: pacman upgrade checks need root" + exit 0 +fi + +unguarded=$fixture/etc/mkinitcpio.conf.d/omarchy_hooks.conf +guarded=$scratch/omarchy-settings-aarch64/etc/mkinitcpio.conf.d/omarchy_hooks.conf +printf '[options]\nArchitecture = auto\nSigLevel = Never\nLocalFileSigLevel = Never\n' > "$scratch/pacman.conf" + +make_pkg() { + local ver=$1 hooks=${2:-} dir=$scratch/pkg-$1 + mkdir -p "$dir/etc/mkinitcpio.conf.d" + [[ -z $hooks ]] || cp "$hooks" "$dir/etc/mkinitcpio.conf.d/omarchy_hooks.conf" + cat > "$dir/.PKGINFO" </dev/null +} + +stripped=$(make_pkg 1-1) +old=$(make_pkg 2-1 "$unguarded") +new=$(make_pkg 3-1 "$guarded") +installed=etc/mkinitcpio.conf.d/omarchy_hooks.conf + +pacman_in "$scratch/unchanged" -U "$old" +pacman_in "$scratch/unchanged" -U "$new" +cmp "$guarded" "$scratch/unchanged/$installed" +[[ ! -e $scratch/unchanged/$installed.pacnew ]] + +pacman_in "$scratch/modified" -U "$old" +echo '# local change' >> "$scratch/modified/$installed" +pacman_in "$scratch/modified" -U "$new" +grep -Fxq '# local change' "$scratch/modified/$installed" +cmp "$guarded" "$scratch/modified/$installed.pacnew" + +pacman_in "$scratch/absent" -U "$stripped" +pacman_in "$scratch/absent" -U "$new" +cmp "$guarded" "$scratch/absent/$installed" + +# Source what the upgrades installed. +for upgrade in unchanged absent; do + etc=$scratch/$upgrade/etc/mkinitcpio.conf.d + [[ $(effective_hooks "$(machine "$upgrade-snapdragon" "$snapdragon" "$etc")") == "$omarchy_hooks" ]] + [[ $(effective_hooks "$(machine "$upgrade-legacy-mac" "$legacy_mac" "$etc")") == "$legacy_mac" ]] +done +echo "PASS: pacman upgrades install the guarded hooks file and keep local changes" From caac8448bef01d973225115ffcb87e29034abb4e Mon Sep 17 00:00:00 2001 From: Marcelo Alcantara Date: Mon, 28 Sep 2026 07:53:14 +1000 Subject: [PATCH 6/6] omarchy-settings: pass #13362's platform-aware hooks through on aarch64 omacom/omarchy#13362 sets HOOKS per platform inside 00-omarchy-hooks.conf, with no column-0 HOOKS= line, so the aarch64 build failed on it; settings-dev tracks quattro automatically and would break as soon as it lands. Wrap only a single-line HOOKS=(...), refuse any other column-0 HOOKS=, then source the shipped files onto a Mac line and a stock line: the Mac line must come through unchanged and the stock one must not. Back up 00-omarchy-hooks.conf when it ships, and refuse it without the omarchy-hw-platform copy it asks. The test now uses the real v4.0.4 hooks file, #13362's two files and omarchy-mac-boot's 90-94 fragments, and covers upgrades over a hand-restored file. --- pkgbuilds/omarchy-settings-dev/PKGBUILD | 57 +++++- pkgbuilds/omarchy-settings/PKGBUILD | 57 +++++- .../omarchy-13362/00-omarchy-hooks.conf | 37 ++++ .../omarchy-13362/omarchy_hooks.conf | 53 ++++++ .../omarchy-mac-boot/90-omarchy-mac.conf | 18 ++ .../91-omarchy-mac-encrypt.conf | 90 ++++++++++ .../omarchy-mac-boot/92-omarchy-mac-hid.conf | 31 ++++ .../93-omarchy-mac-plymouth.conf | 18 ++ .../94-omarchy-mac-vconsole.conf | 46 +++++ .../settings-boot/omarchy_hooks-v4.0.4.conf | 52 ++++++ tests/settings-boot-config.sh | 167 +++++++++++++----- 11 files changed, 564 insertions(+), 62 deletions(-) create mode 100644 tests/fixtures/settings-boot/omarchy-13362/00-omarchy-hooks.conf create mode 100644 tests/fixtures/settings-boot/omarchy-13362/omarchy_hooks.conf create mode 100644 tests/fixtures/settings-boot/omarchy-mac-boot/90-omarchy-mac.conf create mode 100644 tests/fixtures/settings-boot/omarchy-mac-boot/91-omarchy-mac-encrypt.conf create mode 100644 tests/fixtures/settings-boot/omarchy-mac-boot/92-omarchy-mac-hid.conf create mode 100644 tests/fixtures/settings-boot/omarchy-mac-boot/93-omarchy-mac-plymouth.conf create mode 100644 tests/fixtures/settings-boot/omarchy-mac-boot/94-omarchy-mac-vconsole.conf create mode 100644 tests/fixtures/settings-boot/omarchy_hooks-v4.0.4.conf diff --git a/pkgbuilds/omarchy-settings-dev/PKGBUILD b/pkgbuilds/omarchy-settings-dev/PKGBUILD index 2f22ec8..928ee44 100644 --- a/pkgbuilds/omarchy-settings-dev/PKGBUILD +++ b/pkgbuilds/omarchy-settings-dev/PKGBUILD @@ -135,6 +135,23 @@ prepare() { fi } +# Print the HOOKS that result from sourcing mkinitcpio drop-ins onto a line. +_omarchy_settings_hooks_after() { + local start=$1 + shift + ( + # Keep the build host's own tools, such as a platform detector, out of it. + PATH=/nonexistent + read -ra HOOKS <<<"$start" + MODULES=() FILES=() + for conf in "$@"; do + # shellcheck disable=SC1090 + source "$conf" || exit 1 + done + echo "${HOOKS[*]}" + ) +} + package() { cd "$srcdir/omarchy" @@ -203,6 +220,9 @@ package() { # stage separately below). install -d "$pkgdir/etc" cp -a etc/. "$pkgdir/etc/" + # omacom/omarchy#13362 moves the HOOKS baseline into its own drop-in. + [[ ! -f $pkgdir/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf ]] || + backup+=('etc/mkinitcpio.conf.d/00-omarchy-hooks.conf') if [[ $CARCH == aarch64 ]]; then # Keep omarchy_hooks.conf and the Limine entry-tool config: without them a # kernel update on an encrypted aarch64 install rebuilds an initramfs with @@ -213,17 +233,29 @@ package() { # Apple Silicon Macs install this package too. Their initramfs needs the # asahi hook, which omarchy-mac-boot's 90-94 fragments (Aurora) or # mkinitcpio.conf (legacy GRUB Macs) set, and an unconditional HOOKS= here - # would replace it. Omarchy's line applies only when the hooks loaded so far - # lack asahi. The check reads configuration, not the running machine, so it - # also holds when the image is built in a chroot. - local hooks_conf guarded=0 + # would replace it. A source that sets HOOKS outright (v4.0.4) gets its line + # wrapped so it applies only when the hooks loaded so far lack asahi; one that + # already decides per platform (omacom/omarchy#13362) ships as it is. The + # wrapper reads configuration, not the running machine, so it also holds + # when the image is built in a chroot. + local hooks_conf hooks_confs=() for hooks_conf in "$pkgdir"/etc/mkinitcpio.conf.d/{00-omarchy-hooks,omarchy_hooks}.conf; do - [[ -f $hooks_conf ]] && grep -q '^HOOKS=(' "$hooks_conf" || continue - sed -i 's/^\(HOOKS=(.*)\)$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf" - guarded=1 + [[ -f $hooks_conf ]] || continue + hooks_confs+=("$hooks_conf") + sed -i 's/^\(HOOKS=([^#]*)\)[[:space:]]*$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf" + if grep -q '^HOOKS=' "$hooks_conf"; then + echo "${hooks_conf#"$pkgdir"/}: cannot guard this HOOKS= line for Apple Silicon" >&2 + return 1 + fi done - if (( ! guarded )); then - echo "No HOOKS= line to guard for Apple Silicon in etc/mkinitcpio.conf.d" >&2 + # Whatever the layout, a Mac's asahi line must come through the shipped + # files, and a stock line must not: that is where Omarchy's hooks come from. + local mac_line='base udev block asahi encrypt filesystems fsck' stock_line='base udev block filesystems fsck' + local mac_hooks stock_hooks + if ! mac_hooks=$(_omarchy_settings_hooks_after "$mac_line" "${hooks_confs[@]}") || + ! stock_hooks=$(_omarchy_settings_hooks_after "$stock_line" "${hooks_confs[@]}") || + [[ $mac_hooks != "$mac_line" || $stock_hooks == "$stock_line" ]]; then + echo "etc/mkinitcpio.conf.d: the aarch64 hooks must keep a Mac's asahi line and set everyone else's" >&2 return 1 fi # Memory stack: no zram device or zswap on the aarch64 install, and @@ -376,6 +408,13 @@ EOF install -Dm755 bin/omarchy-hw-platform \ "$pkgdir/usr/share/libalpm/scripts/omarchy-hw-platform" fi + # 00-omarchy-hooks.conf places a Mac through this detector copy; without it + # an Aurora Mac gets the busybox line and its initramfs cannot unlock root. + if grep -qs omarchy-hw-platform "$pkgdir/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" && + [[ ! -x $pkgdir/usr/share/libalpm/scripts/omarchy-hw-platform ]]; then + echo "etc/mkinitcpio.conf.d/00-omarchy-hooks.conf needs the omarchy-hw-platform copy the source does not ship" >&2 + return 1 + fi # Branding assets (logos, icons). install -Dm644 logo.txt "$pkgdir/usr/share/omarchy/logo.txt" diff --git a/pkgbuilds/omarchy-settings/PKGBUILD b/pkgbuilds/omarchy-settings/PKGBUILD index 655189c..2043463 100644 --- a/pkgbuilds/omarchy-settings/PKGBUILD +++ b/pkgbuilds/omarchy-settings/PKGBUILD @@ -140,6 +140,23 @@ prepare() { fi } +# Print the HOOKS that result from sourcing mkinitcpio drop-ins onto a line. +_omarchy_settings_hooks_after() { + local start=$1 + shift + ( + # Keep the build host's own tools, such as a platform detector, out of it. + PATH=/nonexistent + read -ra HOOKS <<<"$start" + MODULES=() FILES=() + for conf in "$@"; do + # shellcheck disable=SC1090 + source "$conf" || exit 1 + done + echo "${HOOKS[*]}" + ) +} + package() { cd "$srcdir/omarchy" @@ -211,6 +228,9 @@ package() { # stage separately below). install -d "$pkgdir/etc" cp -a etc/. "$pkgdir/etc/" + # omacom/omarchy#13362 moves the HOOKS baseline into its own drop-in. + [[ ! -f $pkgdir/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf ]] || + backup+=('etc/mkinitcpio.conf.d/00-omarchy-hooks.conf') if [[ $CARCH == aarch64 ]]; then # Keep omarchy_hooks.conf and the Limine entry-tool config: without them a # kernel update on an encrypted aarch64 install rebuilds an initramfs with @@ -221,17 +241,29 @@ package() { # Apple Silicon Macs install this package too. Their initramfs needs the # asahi hook, which omarchy-mac-boot's 90-94 fragments (Aurora) or # mkinitcpio.conf (legacy GRUB Macs) set, and an unconditional HOOKS= here - # would replace it. Omarchy's line applies only when the hooks loaded so far - # lack asahi. The check reads configuration, not the running machine, so it - # also holds when the image is built in a chroot. - local hooks_conf guarded=0 + # would replace it. A source that sets HOOKS outright (v4.0.4) gets its line + # wrapped so it applies only when the hooks loaded so far lack asahi; one that + # already decides per platform (omacom/omarchy#13362) ships as it is. The + # wrapper reads configuration, not the running machine, so it also holds + # when the image is built in a chroot. + local hooks_conf hooks_confs=() for hooks_conf in "$pkgdir"/etc/mkinitcpio.conf.d/{00-omarchy-hooks,omarchy_hooks}.conf; do - [[ -f $hooks_conf ]] && grep -q '^HOOKS=(' "$hooks_conf" || continue - sed -i 's/^\(HOOKS=(.*)\)$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf" - guarded=1 + [[ -f $hooks_conf ]] || continue + hooks_confs+=("$hooks_conf") + sed -i 's/^\(HOOKS=([^#]*)\)[[:space:]]*$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf" + if grep -q '^HOOKS=' "$hooks_conf"; then + echo "${hooks_conf#"$pkgdir"/}: cannot guard this HOOKS= line for Apple Silicon" >&2 + return 1 + fi done - if (( ! guarded )); then - echo "No HOOKS= line to guard for Apple Silicon in etc/mkinitcpio.conf.d" >&2 + # Whatever the layout, a Mac's asahi line must come through the shipped + # files, and a stock line must not: that is where Omarchy's hooks come from. + local mac_line='base udev block asahi encrypt filesystems fsck' stock_line='base udev block filesystems fsck' + local mac_hooks stock_hooks + if ! mac_hooks=$(_omarchy_settings_hooks_after "$mac_line" "${hooks_confs[@]}") || + ! stock_hooks=$(_omarchy_settings_hooks_after "$stock_line" "${hooks_confs[@]}") || + [[ $mac_hooks != "$mac_line" || $stock_hooks == "$stock_line" ]]; then + echo "etc/mkinitcpio.conf.d: the aarch64 hooks must keep a Mac's asahi line and set everyone else's" >&2 return 1 fi # Memory stack: no zram device or zswap on the aarch64 install, and @@ -384,6 +416,13 @@ EOF install -Dm755 bin/omarchy-hw-platform \ "$pkgdir/usr/share/libalpm/scripts/omarchy-hw-platform" fi + # 00-omarchy-hooks.conf places a Mac through this detector copy; without it + # an Aurora Mac gets the busybox line and its initramfs cannot unlock root. + if grep -qs omarchy-hw-platform "$pkgdir/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" && + [[ ! -x $pkgdir/usr/share/libalpm/scripts/omarchy-hw-platform ]]; then + echo "etc/mkinitcpio.conf.d/00-omarchy-hooks.conf needs the omarchy-hw-platform copy the source does not ship" >&2 + return 1 + fi # Branding assets (logos, icons). install -Dm644 logo.txt "$pkgdir/usr/share/omarchy/logo.txt" diff --git a/tests/fixtures/settings-boot/omarchy-13362/00-omarchy-hooks.conf b/tests/fixtures/settings-boot/omarchy-13362/00-omarchy-hooks.conf new file mode 100644 index 0000000..8789786 --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-13362/00-omarchy-hooks.conf @@ -0,0 +1,37 @@ +# The platform's HOOKS baseline. mkinitcpio sources mkinitcpio.conf and then +# every drop-in here in name order, so the baseline sorts first and the drop-ins +# after it add their hooks to it instead of being overwritten by it. +# +# Apple Silicon boots a systemd initramfs, and its platform package adds the +# firmware and encryption hooks. Every other machine keeps the busybox line. The +# runtime's detector answers, or else the copy omarchy-settings ships for its +# platform guard, so a settings package newer than the runtime still places a +# Mac. Without either, the busybox line stays. A detector that cannot place the +# machine stops the build rather than let it produce an image for the wrong +# platform. +_omarchy_platform="" +_omarchy_detector=$(command -v omarchy-hw-platform) || _omarchy_detector=/usr/share/libalpm/scripts/omarchy-hw-platform +if [[ -x $_omarchy_detector ]]; then + _omarchy_platform=$("$_omarchy_detector") || return 1 +fi + +# A Mac whose mkinitcpio.conf carries the asahi hook, or the busybox encrypt +# hook that unlocks it through cryptdevice= (sd-encrypt cannot parse that), boots +# the initramfs its platform set up without the Apple boot package, as a legacy +# install does. Its line stays as it is. The asahi hook also marks such a root +# off a Mac, as in a chroot or a VM. +if [[ " ${HOOKS[*]:-} " == *" asahi "* ]] || + [[ $_omarchy_platform == "apple-silicon" && " ${HOOKS[*]:-} " == *" encrypt "* ]]; then + _omarchy_platform=platform-owned +fi + +case $_omarchy_platform in + platform-owned) ;; + apple-silicon) + HOOKS=(base systemd plymouth autodetect microcode modconf kms keyboard sd-vconsole block filesystems fsck) + ;; + *) + HOOKS=(base udev plymouth keyboard autodetect microcode modconf kms keymap consolefont block encrypt filesystems fsck btrfs-overlayfs) + ;; +esac +unset _omarchy_platform _omarchy_detector diff --git a/tests/fixtures/settings-boot/omarchy-13362/omarchy_hooks.conf b/tests/fixtures/settings-boot/omarchy-13362/omarchy_hooks.conf new file mode 100644 index 0000000..0dfcb8e --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-13362/omarchy_hooks.conf @@ -0,0 +1,53 @@ +# Adjusts the baseline HOOKS from 00-omarchy-hooks.conf. It stays apart from +# the baseline because it reads what the hardware drop-ins sorting before it set. + +# The proprietary NVIDIA driver does early KMS itself: nvidia.conf (written by +# install/hardware/nvidia.sh, sourced before this file) early-loads nvidia_drm +# with modeset=1. Keeping the kms hook on such a system makes autodetect pull +# in nouveau — and ~100 MB of its GSP firmware — for a driver that never runs. +# Drop kms only when nvidia_drm is early-loaded and NVIDIA owns every display +# controller. Hybrid systems keep kms: their iGPU still needs it for early +# KMS at the LUKS prompt. So does anything unexpected, like a PCI tree that +# cannot be read. +# +# This reads MODULES midway through mkinitcpio's drop-in sourcing, so a +# later-sorting drop-in that resets MODULES outright — surface_device_modules.conf +# does — would strip nvidia_drm after kms was already dropped. Every machine +# Omarchy writes such a file for carries an Intel iGPU, which keeps kms here +# through the scan below; keep it that way. +if [[ " ${MODULES[*]:-} " == *" nvidia_drm "* ]]; then + _omarchy_nvidia_gpu=0 + _omarchy_other_gpu=0 + for _omarchy_pci in "${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}"/*; do + if [[ ! -r $_omarchy_pci/class || ! -r $_omarchy_pci/vendor ]]; then + # An unreadable device could be another GPU. Inconclusive keeps kms. + _omarchy_other_gpu=1 + continue + fi + [[ $(<"$_omarchy_pci/class") == "0x03"* ]] || continue + if [[ $(<"$_omarchy_pci/vendor") == "0x10de" ]]; then + _omarchy_nvidia_gpu=1 + else + _omarchy_other_gpu=1 + fi + done + if ((_omarchy_nvidia_gpu && !_omarchy_other_gpu)); then + _omarchy_hooks=() + for _omarchy_hook in "${HOOKS[@]}"; do + [[ $_omarchy_hook == "kms" ]] || _omarchy_hooks+=("$_omarchy_hook") + done + HOOKS=("${_omarchy_hooks[@]}") + fi + unset _omarchy_nvidia_gpu _omarchy_other_gpu _omarchy_pci _omarchy_hooks _omarchy_hook +fi + +# Bundle vconsole.conf so Plymouth uses the configured keyboard layout at the +# LUKS prompt, but only when that layout types Latin letters. Passphrases are +# Latin characters, so bundling a Hebrew/Greek/Cyrillic/Arabic layout would +# make the correct passphrase untypeable and lock the user out. +if [[ -f /etc/vconsole.conf ]]; then + case $(. /etc/vconsole.conf && echo "${XKBLAYOUT%%,*}") in + af | am | ara | bd | bg | by | et | ge | gr | il | in | iq | ir | kg | kh | kz | la | lk | mk | mm | mn | mv | np | rs | ru | sy | th | tj | ua) ;; + *) FILES+=(/etc/vconsole.conf) ;; + esac +fi diff --git a/tests/fixtures/settings-boot/omarchy-mac-boot/90-omarchy-mac.conf b/tests/fixtures/settings-boot/omarchy-mac-boot/90-omarchy-mac.conf new file mode 100644 index 0000000..0457b32 --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-mac-boot/90-omarchy-mac.conf @@ -0,0 +1,18 @@ +# Generated by the Omarchy Apple Silicon image builder. +_omarchy_asahi_hooks=() +_omarchy_asahi_added=false +for _omarchy_asahi_hook in "${HOOKS[@]}"; do + if [[ $_omarchy_asahi_hook == asahi ]]; then + _omarchy_asahi_added=true + fi + if [[ $_omarchy_asahi_hook == filesystems && $_omarchy_asahi_added == false ]]; then + _omarchy_asahi_hooks+=(asahi omarchy-vendorfw) + _omarchy_asahi_added=true + fi + _omarchy_asahi_hooks+=("$_omarchy_asahi_hook") +done +if [[ $_omarchy_asahi_added == false ]]; then + _omarchy_asahi_hooks+=(asahi omarchy-vendorfw) +fi +HOOKS=("${_omarchy_asahi_hooks[@]}") +unset _omarchy_asahi_hooks _omarchy_asahi_hook _omarchy_asahi_added diff --git a/tests/fixtures/settings-boot/omarchy-mac-boot/91-omarchy-mac-encrypt.conf b/tests/fixtures/settings-boot/omarchy-mac-boot/91-omarchy-mac-encrypt.conf new file mode 100644 index 0000000..306582f --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-mac-boot/91-omarchy-mac-encrypt.conf @@ -0,0 +1,90 @@ +# Insert omarchy-mac-encrypt after vendorfw/block and sd-encrypt immediately +# before filesystems, each only if that hook is absent. 90-omarchy-mac.conf +# already put asahi and omarchy-vendorfw before filesystems; this drop-in is +# sourced after it. +# +# Both are systemd initrd units: the systemd hook replaces udev (mkinitcpio's +# stock HOOKS line) and keymap/consolefont become sd-vconsole. A HOOKS line +# carrying the busybox encrypt hook belongs to a Mac unlocked by cryptdevice=, +# which sd-encrypt cannot parse: that line is left exactly as it is. +_omarchy_mac_encrypt_hooks=() +_omarchy_mac_encrypt_have_systemd=false +_omarchy_mac_encrypt_have_vconsole=false +_omarchy_mac_encrypt_have_encrypt=false +for _omarchy_mac_encrypt_hook in "${HOOKS[@]}"; do + case $_omarchy_mac_encrypt_hook in + systemd) _omarchy_mac_encrypt_have_systemd=true ;; + sd-vconsole) _omarchy_mac_encrypt_have_vconsole=true ;; + encrypt) _omarchy_mac_encrypt_have_encrypt=true ;; + esac +done +if [[ $_omarchy_mac_encrypt_have_encrypt == false ]]; then +for _omarchy_mac_encrypt_hook in "${HOOKS[@]}"; do + case $_omarchy_mac_encrypt_hook in + udev) + if [[ $_omarchy_mac_encrypt_have_systemd == false ]]; then + _omarchy_mac_encrypt_hooks+=(systemd) + _omarchy_mac_encrypt_have_systemd=true + fi + ;; + keymap|consolefont) + if [[ $_omarchy_mac_encrypt_have_vconsole == false ]]; then + _omarchy_mac_encrypt_hooks+=(sd-vconsole) + _omarchy_mac_encrypt_have_vconsole=true + fi + ;; + *) _omarchy_mac_encrypt_hooks+=("$_omarchy_mac_encrypt_hook") ;; + esac +done +if [[ $_omarchy_mac_encrypt_have_systemd == false ]]; then + if [[ ${_omarchy_mac_encrypt_hooks[0]:-} == base ]]; then + _omarchy_mac_encrypt_hooks=(base systemd "${_omarchy_mac_encrypt_hooks[@]:1}") + else + _omarchy_mac_encrypt_hooks=(systemd "${_omarchy_mac_encrypt_hooks[@]}") + fi +fi +HOOKS=("${_omarchy_mac_encrypt_hooks[@]}") +_omarchy_mac_encrypt_hooks=() +_omarchy_mac_encrypt_have_ours=false +_omarchy_mac_encrypt_have_sd=false +_omarchy_mac_encrypt_added_ours=false +_omarchy_mac_encrypt_added_sd=false +for _omarchy_mac_encrypt_hook in "${HOOKS[@]}"; do + if [[ $_omarchy_mac_encrypt_hook == omarchy-mac-encrypt ]]; then + _omarchy_mac_encrypt_have_ours=true + fi + if [[ $_omarchy_mac_encrypt_hook == sd-encrypt ]]; then + _omarchy_mac_encrypt_have_sd=true + fi +done +for _omarchy_mac_encrypt_hook in "${HOOKS[@]}"; do + if [[ $_omarchy_mac_encrypt_hook == sd-encrypt && $_omarchy_mac_encrypt_have_ours == false && + $_omarchy_mac_encrypt_added_ours == false ]]; then + _omarchy_mac_encrypt_hooks+=(omarchy-mac-encrypt) + _omarchy_mac_encrypt_added_ours=true + fi + if [[ $_omarchy_mac_encrypt_hook == filesystems ]]; then + if [[ $_omarchy_mac_encrypt_have_ours == false && $_omarchy_mac_encrypt_added_ours == false ]]; then + _omarchy_mac_encrypt_hooks+=(omarchy-mac-encrypt) + _omarchy_mac_encrypt_added_ours=true + fi + if [[ $_omarchy_mac_encrypt_have_sd == false && $_omarchy_mac_encrypt_added_sd == false ]]; then + _omarchy_mac_encrypt_hooks+=(sd-encrypt) + _omarchy_mac_encrypt_added_sd=true + fi + fi + _omarchy_mac_encrypt_hooks+=("$_omarchy_mac_encrypt_hook") +done +if [[ $_omarchy_mac_encrypt_have_ours == false && $_omarchy_mac_encrypt_added_ours == false ]]; then + _omarchy_mac_encrypt_hooks+=(omarchy-mac-encrypt) +fi +if [[ $_omarchy_mac_encrypt_have_sd == false && $_omarchy_mac_encrypt_added_sd == false ]]; then + _omarchy_mac_encrypt_hooks+=(sd-encrypt) +fi +HOOKS=("${_omarchy_mac_encrypt_hooks[@]}") +fi +unset _omarchy_mac_encrypt_hooks _omarchy_mac_encrypt_hook \ + _omarchy_mac_encrypt_have_ours _omarchy_mac_encrypt_have_sd \ + _omarchy_mac_encrypt_added_ours _omarchy_mac_encrypt_added_sd \ + _omarchy_mac_encrypt_have_systemd _omarchy_mac_encrypt_have_vconsole \ + _omarchy_mac_encrypt_have_encrypt diff --git a/tests/fixtures/settings-boot/omarchy-mac-boot/92-omarchy-mac-hid.conf b/tests/fixtures/settings-boot/omarchy-mac-boot/92-omarchy-mac-hid.conf new file mode 100644 index 0000000..b75e8a5 --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-mac-boot/92-omarchy-mac-hid.conf @@ -0,0 +1,31 @@ +# Origin: omarchy-mx-mac install/hardware/apple/fix-asahi-hid-race.sh +# Apple Silicon internal keyboard and trackpad at the sd-encrypt passphrase +# prompt. dockchannel-hid creates the HID devices; hid_apple binds the +# keyboard and hid_magicmouse the SPI trackpad. MTP machines (M2 Air, M2 Max +# j416c) use dockchannel-hid — linux-aurora has no apple-mtp module. SPI HID +# (M1 Air, M1 Pro j314s) is spi-hid-apple-of, built-in on aurora. usbhid is +# an external USB keyboard at the prompt. thunderbolt (CONFIG_USB4=m) and +# thunderbolt_apple, the Apple Silicon USB4 host router (CONFIG_USB4_APPLE_SOC=m +# on linux-aurora), bring up the USB4/Thunderbolt tunnels, so a keyboard behind +# a USB-C or Thunderbolt dock types at the prompt too (omarchy-mx-mac#86). +# +# mkinitcpio fails the whole image over a MODULES entry it cannot find, or a +# built-in it reports as "(builtin)". Each name is added only when modinfo +# returns a real path. Ending on unset keeps the exit status zero. + +for _omarchy_mac_hid_module in \ + hid_apple hid_magicmouse dockchannel-hid usbhid \ + spi-apple spi-hid-apple spi-hid-apple-of \ + apple-dockchannel apple-rtkit-helper thunderbolt thunderbolt_apple; do + _omarchy_mac_hid_path=$(modinfo -k "${KERNELVERSION:-$(uname -r)}" -F filename \ + "$_omarchy_mac_hid_module" 2>/dev/null) || continue + [[ $_omarchy_mac_hid_path == /* ]] || continue + MODULES+=("$_omarchy_mac_hid_module") +done +unset _omarchy_mac_hid_module _omarchy_mac_hid_path + +# MTP trackpad firmware (apple/tpmtfw-.bin) is not a MODULES entry. +# omarchy-vendorfw-initrd.service unpacks ESP vendorfw/firmware.cpio onto +# /lib/firmware/vendor (symlink to /vendorfw) before cryptsetup-pre.target. +# Do not FILES+= under /lib/firmware/vendor, and do not pre-create +# /vendorfw/apple in the image: that skipped ESP extraction. diff --git a/tests/fixtures/settings-boot/omarchy-mac-boot/93-omarchy-mac-plymouth.conf b/tests/fixtures/settings-boot/omarchy-mac-boot/93-omarchy-mac-plymouth.conf new file mode 100644 index 0000000..75cbbb5 --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-mac-boot/93-omarchy-mac-plymouth.conf @@ -0,0 +1,18 @@ +# Plymouth draws the disk password prompt and the boot splash, as on x86 +# Omarchy. It goes right after systemd so its initrd units order correctly, +# only when the hook is installed, and never twice. +if [[ -f /usr/lib/initcpio/install/plymouth && " ${HOOKS[*]} " != *" plymouth "* ]]; then + _omarchy_mac_plymouth_hooks=() + _omarchy_mac_plymouth_added=false + for _omarchy_mac_plymouth_hook in "${HOOKS[@]}"; do + _omarchy_mac_plymouth_hooks+=("$_omarchy_mac_plymouth_hook") + if [[ $_omarchy_mac_plymouth_hook == systemd && $_omarchy_mac_plymouth_added == false ]]; then + _omarchy_mac_plymouth_hooks+=(plymouth) + _omarchy_mac_plymouth_added=true + fi + done + if [[ $_omarchy_mac_plymouth_added == true ]]; then + HOOKS=("${_omarchy_mac_plymouth_hooks[@]}") + fi + unset _omarchy_mac_plymouth_hooks _omarchy_mac_plymouth_added _omarchy_mac_plymouth_hook +fi diff --git a/tests/fixtures/settings-boot/omarchy-mac-boot/94-omarchy-mac-vconsole.conf b/tests/fixtures/settings-boot/omarchy-mac-boot/94-omarchy-mac-vconsole.conf new file mode 100644 index 0000000..9547df7 --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy-mac-boot/94-omarchy-mac-vconsole.conf @@ -0,0 +1,46 @@ +# The disk passphrase prompt types with the owner's keyboard layout, as on +# x86 Omarchy: sd-vconsole loads KEYMAP on the console (systemd-ask-password) +# and /etc/vconsole.conf gives Plymouth its XKBLAYOUT. The aarch64 +# omarchy-settings drops upstream's omarchy_hooks.conf, so this drop-in +# carries its guard: a layout that does not type Latin letters stays out of +# the initramfs, because a Latin passphrase would be untypeable in it +# (upstream #6229). The prompt then uses the kernel's US map, which is what +# such a passphrase was typed with. +# +# A systemd HOOKS line gets sd-vconsole exactly once, after keyboard (or +# after systemd without one); keymap and consolefont are its busybox +# counterparts and never belong on such a line. A busybox line (a Mac +# unlocked by cryptdevice=, which 91 leaves alone) keeps its hooks; it only +# gets the file for Plymouth, as upstream does. +# No vconsole.conf is the kernel's US map: sd-vconsole stays, nothing to bundle. +_omarchy_mac_vconsole_latin=true +if [[ -f /etc/vconsole.conf ]]; then + _omarchy_mac_vconsole_layout=$(unset XKBLAYOUT; . /etc/vconsole.conf 2>/dev/null; printf '%s' "${XKBLAYOUT:-}") + case ${_omarchy_mac_vconsole_layout%%,*} in + af | am | ara | bd | bg | by | et | ge | gr | il | in | iq | ir | kg | kh | kz | la | lk | mk | mm | mn | mv | np | rs | ru | sy | th | tj | ua) + _omarchy_mac_vconsole_latin=false ;; + esac +fi + +if [[ " ${HOOKS[*]} " == *" systemd "* ]]; then + _omarchy_mac_vconsole_hooks=() + _omarchy_mac_vconsole_anchor=systemd + [[ " ${HOOKS[*]} " != *" keyboard "* ]] || _omarchy_mac_vconsole_anchor=keyboard + for _omarchy_mac_vconsole_hook in "${HOOKS[@]}"; do + case $_omarchy_mac_vconsole_hook in + sd-vconsole | keymap | consolefont) continue ;; + esac + _omarchy_mac_vconsole_hooks+=("$_omarchy_mac_vconsole_hook") + if [[ $_omarchy_mac_vconsole_hook == "$_omarchy_mac_vconsole_anchor" && $_omarchy_mac_vconsole_latin == true ]]; then + _omarchy_mac_vconsole_hooks+=(sd-vconsole) + _omarchy_mac_vconsole_anchor= + fi + done + HOOKS=("${_omarchy_mac_vconsole_hooks[@]}") +fi + +if [[ $_omarchy_mac_vconsole_latin == true && -f /etc/vconsole.conf ]]; then + FILES+=(/etc/vconsole.conf) +fi +unset _omarchy_mac_vconsole_latin _omarchy_mac_vconsole_layout _omarchy_mac_vconsole_hooks \ + _omarchy_mac_vconsole_anchor _omarchy_mac_vconsole_hook diff --git a/tests/fixtures/settings-boot/omarchy_hooks-v4.0.4.conf b/tests/fixtures/settings-boot/omarchy_hooks-v4.0.4.conf new file mode 100644 index 0000000..68408b0 --- /dev/null +++ b/tests/fixtures/settings-boot/omarchy_hooks-v4.0.4.conf @@ -0,0 +1,52 @@ +HOOKS=(base udev plymouth keyboard autodetect microcode modconf kms keymap consolefont block encrypt filesystems fsck btrfs-overlayfs) + +# The proprietary NVIDIA driver does early KMS itself: nvidia.conf (written by +# install/hardware/nvidia.sh, sourced before this file) early-loads nvidia_drm +# with modeset=1. Keeping the kms hook on such a system makes autodetect pull +# in nouveau — and ~100 MB of its GSP firmware — for a driver that never runs. +# Drop kms only when nvidia_drm is early-loaded and NVIDIA owns every display +# controller. Hybrid systems keep kms: their iGPU still needs it for early +# KMS at the LUKS prompt. So does anything unexpected, like a PCI tree that +# cannot be read. +# +# This reads MODULES midway through mkinitcpio's drop-in sourcing, so a +# later-sorting drop-in that resets MODULES outright — surface_device_modules.conf +# does — would strip nvidia_drm after kms was already dropped. Every machine +# Omarchy writes such a file for carries an Intel iGPU, which keeps kms here +# through the scan below; keep it that way. +if [[ " ${MODULES[*]:-} " == *" nvidia_drm "* ]]; then + _omarchy_nvidia_gpu=0 + _omarchy_other_gpu=0 + for _omarchy_pci in "${OMARCHY_PCI_DEVICES_PATH:-/sys/bus/pci/devices}"/*; do + if [[ ! -r $_omarchy_pci/class || ! -r $_omarchy_pci/vendor ]]; then + # An unreadable device could be another GPU. Inconclusive keeps kms. + _omarchy_other_gpu=1 + continue + fi + [[ $(<"$_omarchy_pci/class") == "0x03"* ]] || continue + if [[ $(<"$_omarchy_pci/vendor") == "0x10de" ]]; then + _omarchy_nvidia_gpu=1 + else + _omarchy_other_gpu=1 + fi + done + if ((_omarchy_nvidia_gpu && !_omarchy_other_gpu)); then + _omarchy_hooks=() + for _omarchy_hook in "${HOOKS[@]}"; do + [[ $_omarchy_hook == "kms" ]] || _omarchy_hooks+=("$_omarchy_hook") + done + HOOKS=("${_omarchy_hooks[@]}") + fi + unset _omarchy_nvidia_gpu _omarchy_other_gpu _omarchy_pci _omarchy_hooks _omarchy_hook +fi + +# Bundle vconsole.conf so Plymouth uses the configured keyboard layout at the +# LUKS prompt, but only when that layout types Latin letters. Passphrases are +# Latin characters, so bundling a Hebrew/Greek/Cyrillic/Arabic layout would +# make the correct passphrase untypeable and lock the user out. +if [[ -f /etc/vconsole.conf ]]; then + case $(. /etc/vconsole.conf && echo "${XKBLAYOUT%%,*}") in + af | am | ara | bd | bg | by | et | ge | gr | il | in | iq | ir | kg | kh | kz | la | lk | mk | mm | mn | mv | np | rs | ru | sy | th | tj | ua) ;; + *) FILES+=(/etc/vconsole.conf) ;; + esac +fi diff --git a/tests/settings-boot-config.sh b/tests/settings-boot-config.sh index dfbe742..5528925 100755 --- a/tests/settings-boot-config.sh +++ b/tests/settings-boot-config.sh @@ -63,9 +63,10 @@ for path in "${files[@]}"; do printf 'fixture for %s\n' "$path" > "$fixture/$path" done -# Omarchy's HOOKS line, as its sources ship it. +fixtures=$BUILD_ROOT/tests/fixtures/settings-boot +# Omarchy's HOOKS line, as v4.0.4 ships it (omarchy_hooks-v4.0.4.conf). omarchy_hooks='base udev plymouth keyboard autodetect microcode modconf kms keymap consolefont block encrypt filesystems fsck btrfs-overlayfs' -printf 'HOOKS=(%s)\n' "$omarchy_hooks" > "$fixture/etc/mkinitcpio.conf.d/omarchy_hooks.conf" +cp "$fixtures/omarchy_hooks-v4.0.4.conf" "$fixture/etc/mkinitcpio.conf.d/omarchy_hooks.conf" for recipe in omarchy-settings omarchy-settings-dev; do for target_arch in aarch64 x86_64; do @@ -95,6 +96,10 @@ for recipe in omarchy-settings omarchy-settings-dev; do for template in default.conf limine.conf; do cmp "$fixture/default/limine/$template" "$pkgdir/usr/share/omarchy/default/limine/$template" done + if printf '%s\n' "${backup[@]}" | grep -Fxq etc/mkinitcpio.conf.d/00-omarchy-hooks.conf; then + echo 'FAIL: backup names a 00-omarchy-hooks.conf the source does not ship' >&2 + exit 1 + fi # The installer owns the machine-specific live configuration. [[ ! -e $pkgdir/etc/default/limine ]] if printf '%s\n' "${backup[@]}" | grep -Fxq 'etc/default/limine'; then @@ -124,7 +129,8 @@ done # The aarch64 packages also reach Apple Silicon Macs, whose initramfs needs the # asahi hook. Source mkinitcpio.conf and the drop-ins in mkinitcpio's order and -# compare the resulting HOOKS for each kind of aarch64 install. +# compare the resulting HOOKS for each kind of aarch64 install. Aurora Macs use +# omarchy-mac-boot's real 90-94 fragments (omacom/omarchy-mac ff7ce0d4d). package_aarch64() { local recipe=$1 source_tree=$2 out=$3 ( @@ -133,15 +139,25 @@ package_aarch64() { backup=() # shellcheck disable=SC1090 # Exercise the recipe's actual package function. source "$BUILD_ROOT/pkgbuilds/$recipe/PKGBUILD" - package + package || exit 1 + printf '%s\n' "${backup[@]}" > "$out.backup" ) } +# omacom/omarchy#13362 asks omarchy-hw-platform which machine it is on. +for platform in apple-silicon qualcomm generic-aarch64; do + mkdir -p "$scratch/detector-$platform" + printf '#!/bin/sh\necho %s\n' "$platform" > "$scratch/detector-$platform/omarchy-hw-platform" + chmod +x "$scratch/detector-$platform/omarchy-hw-platform" +done + +# effective_hooks ROOT [PLATFORM] effective_hooks() { - local root=$1 + local root=$1 platform=${2:-} ( LC_ALL=C - HOOKS=() + [[ -z $platform ]] || PATH=$scratch/detector-$platform:$PATH + HOOKS=() MODULES=() FILES=() # shellcheck disable=SC1091 source "$root/mkinitcpio.conf" shopt -s nullglob @@ -153,63 +169,119 @@ effective_hooks() { ) } -# machine NAME MKINITCPIO_HOOKS PACKAGED_ETC [FRAGMENT FRAGMENT_HOOKS] +# machine NAME MKINITCPIO_HOOKS PACKAGED_ETC [mac-boot] machine() { local root=$scratch/machines/$1 + rm -rf "$root" mkdir -p "$root/mkinitcpio.conf.d" printf 'HOOKS=(%s)\n' "$2" > "$root/mkinitcpio.conf" - cp "$3"/*.conf "$root/mkinitcpio.conf.d/" - if (($# == 5)); then - printf 'HOOKS=(%s)\n' "$5" > "$root/mkinitcpio.conf.d/$4" - fi + [[ -z $3 ]] || cp "$3"/*.conf "$root/mkinitcpio.conf.d/" + [[ ${4:-} != mac-boot ]] || cp "$fixtures"/omarchy-mac-boot/*.conf "$root/mkinitcpio.conf.d/" printf '%s\n' "$root" } +expect() { + local layout=$1 what=$2 got=$3 want=$4 + [[ $got == "$want" ]] || { echo "FAIL: $layout: $what gets '$got', want '$want'" >&2; exit 1; } +} + arch_default='base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck' snapdragon='base systemd autodetect microcode modconf kms keyboard sd-vconsole block filesystems fsck' legacy_mac='base udev autodetect modconf kms keyboard keymap consolefont block asahi encrypt filesystems fsck' -aurora_mac='base udev autodetect modconf kms keyboard keymap consolefont block asahi omarchy-vendorfw omarchy-mac-encrypt sd-encrypt filesystems fsck' -check_machines() { - local layout=$1 packaged=$2/etc/mkinitcpio.conf.d root - rm -rf "$scratch/machines" - root=$(machine snapdragon "$snapdragon" "$packaged") - [[ $(effective_hooks "$root") == "$omarchy_hooks" ]] || - { echo "FAIL: $layout: Snapdragon gets $(effective_hooks "$root")" >&2; exit 1; } - root=$(machine spark "$arch_default" "$packaged") - [[ $(effective_hooks "$root") == "$omarchy_hooks" ]] || - { echo "FAIL: $layout: DGX Spark gets $(effective_hooks "$root")" >&2; exit 1; } - root=$(machine legacy-mac "$legacy_mac" "$packaged") - [[ $(effective_hooks "$root") == "$legacy_mac" ]] || - { echo "FAIL: $layout: a legacy GRUB Mac loses asahi: $(effective_hooks "$root")" >&2; exit 1; } - root=$(machine aurora-mac "$arch_default" "$packaged" 92-omarchy-mac-boot.conf "$aurora_mac") - [[ $(effective_hooks "$root") == "$aurora_mac" ]] || - { echo "FAIL: $layout: an Aurora Mac loses its hooks: $(effective_hooks "$root")" >&2; exit 1; } - echo "PASS: $layout: Snapdragon and the Spark get Omarchy's hooks; Macs keep asahi" +# Macs must come out exactly as they would without omarchy-settings' drop-ins. +check_macs() { + local layout=$1 packaged=$2 base + for base in "$arch_default" "$snapdragon"; do + expect "$layout" "an Aurora Mac" \ + "$(effective_hooks "$(machine aurora "$base" "$packaged" mac-boot)")" \ + "$(effective_hooks "$(machine aurora-bare "$base" "" mac-boot)")" + done + expect "$layout" "a legacy GRUB Mac" \ + "$(effective_hooks "$(machine legacy "$legacy_mac" "$packaged")")" "$legacy_mac" + expect "$layout" "a legacy GRUB Mac with the Apple fragments" \ + "$(effective_hooks "$(machine legacy-boot "$legacy_mac" "$packaged" mac-boot)")" \ + "$(effective_hooks "$(machine legacy-boot-bare "$legacy_mac" "" mac-boot)")" } -check_machines "HOOKS in omarchy_hooks.conf" "$scratch/omarchy-settings-aarch64" +layout="HOOKS in omarchy_hooks.conf (v4.0.4)" +packaged=$scratch/omarchy-settings-aarch64/etc/mkinitcpio.conf.d +expect "$layout" Snapdragon "$(effective_hooks "$(machine snapdragon "$snapdragon" "$packaged")")" "$omarchy_hooks" +expect "$layout" "the DGX Spark" "$(effective_hooks "$(machine spark "$arch_default" "$packaged")")" "$omarchy_hooks" +check_macs "$layout" "$packaged" +echo "PASS: $layout: Snapdragon and the Spark get Omarchy's hooks; Macs keep theirs" -# omacom/omarchy#13362 moves the HOOKS line into 00-omarchy-hooks.conf. +# omacom/omarchy#13362 decides per platform in 00-omarchy-hooks.conf; the +# package ships both of its files unchanged. split=$scratch/split/omarchy mkdir -p "$scratch/split" cp -a "$fixture" "$split" -printf 'HOOKS=(%s)\n' "$omarchy_hooks" > "$split/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" -sed -i '/^HOOKS=/d' "$split/etc/mkinitcpio.conf.d/omarchy_hooks.conf" -package_aarch64 omarchy-settings "$split" "$scratch/split-package" >/dev/null -grep -Fxq 'if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then' \ - "$scratch/split-package/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" -check_machines "HOOKS in 00-omarchy-hooks.conf" "$scratch/split-package" +cp "$fixtures"/omarchy-13362/*.conf "$split/etc/mkinitcpio.conf.d/" +# Its 00-omarchy-hooks.conf asks the detector copy the platform guard ships. +for path in default/libalpm/hooks/00-omarchy-platform-guard.hook \ + default/libalpm/scripts/omarchy-platform-guard bin/omarchy-hw-platform; do + mkdir -p "$(dirname "$split/$path")" + printf 'fixture for %s\n' "$path" > "$split/$path" +done +for recipe in omarchy-settings omarchy-settings-dev; do + package_aarch64 "$recipe" "$split" "$scratch/split-$recipe" >/dev/null + for conf in 00-omarchy-hooks.conf omarchy_hooks.conf; do + cmp "$fixtures/omarchy-13362/$conf" "$scratch/split-$recipe/etc/mkinitcpio.conf.d/$conf" + done + grep -Fxq etc/mkinitcpio.conf.d/00-omarchy-hooks.conf "$scratch/split-$recipe.backup" + [[ -x $scratch/split-$recipe/usr/share/libalpm/scripts/omarchy-hw-platform ]] +done +layout="omacom/omarchy#13362 (00-omarchy-hooks.conf)" +packaged=$scratch/split-omarchy-settings/etc/mkinitcpio.conf.d +for platform in "" qualcomm generic-aarch64; do + expect "$layout" "Snapdragon (${platform:-no detector})" \ + "$(effective_hooks "$(machine snapdragon "$snapdragon" "$packaged")" "$platform")" "$omarchy_hooks" + expect "$layout" "the DGX Spark (${platform:-no detector})" \ + "$(effective_hooks "$(machine spark "$arch_default" "$packaged")" "$platform")" "$omarchy_hooks" +done +expect "$layout" "a legacy GRUB Mac" \ + "$(effective_hooks "$(machine legacy "$legacy_mac" "$packaged")" apple-silicon)" "$legacy_mac" +# An Aurora Mac builds on the systemd baseline and unlocks with sd-encrypt. +hooks=" $(effective_hooks "$(machine aurora "$arch_default" "$packaged" mac-boot)" apple-silicon) " +for hook in systemd asahi omarchy-vendorfw omarchy-mac-encrypt sd-encrypt; do + [[ $hooks == *" $hook "* ]] || { echo "FAIL: $layout: an Aurora Mac lacks $hook:$hooks" >&2; exit 1; } +done +for hook in udev encrypt; do + [[ $hooks != *" $hook "* ]] || { echo "FAIL: $layout: an Aurora Mac keeps $hook:$hooks" >&2; exit 1; } +done +echo "PASS: $layout: shipped unchanged and backed up; Snapdragon and the Spark get Omarchy's hooks; Macs keep theirs" -sed -i '/^HOOKS=/d' "$split/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf" -if package_aarch64 omarchy-settings "$split" "$scratch/unguarded-package" 2>/dev/null; then - echo 'FAIL: the aarch64 package builds without a HOOKS line to guard' >&2 - exit 1 -fi -echo "PASS: the aarch64 package fails to build without a HOOKS line to guard" +# Sources the recipe cannot make safe for Macs stop the aarch64 build, each +# with its own reason. +refuse() { + local what=$1 reason=$2 conf=$3 body=$4 bad=$scratch/bad/omarchy + rm -rf "$scratch/bad" "$scratch/bad-package" + mkdir -p "$scratch/bad" + cp -a "$fixture" "$bad" + rm -f "$bad"/etc/mkinitcpio.conf.d/{00-omarchy-hooks,omarchy_hooks}.conf + [[ -z $conf ]] || printf '%s\n' "$body" > "$bad/etc/mkinitcpio.conf.d/$conf" + if package_aarch64 omarchy-settings "$bad" "$scratch/bad-package" 2>"$scratch/bad.err"; then + echo "FAIL: the aarch64 package builds with $what" >&2 + exit 1 + fi + grep -Fq "$reason" "$scratch/bad.err" || + { echo "FAIL: $what stops the build for another reason: $(cat "$scratch/bad.err")" >&2; exit 1; } + echo "PASS: the aarch64 package refuses $what" +} +unsafe="must keep a Mac's asahi line" +unguardable="cannot guard this HOOKS= line" +refuse "no hooks file" "$unsafe" "" "" +refuse "a hooks file that sets no HOOKS" "$unsafe" omarchy_hooks.conf 'FILES+=(/etc/vconsole.conf)' +refuse "a HOOKS line with a trailing comment" "$unguardable" omarchy_hooks.conf "HOOKS=($omarchy_hooks) # local" +refuse "a HOOKS line split over lines" "$unguardable" omarchy_hooks.conf "HOOKS=(base udev"$'\n'" block encrypt filesystems)" +refuse "an indented HOOKS that ignores asahi" "$unsafe" 00-omarchy-hooks.conf "if true; then"$'\n'" HOOKS=($omarchy_hooks)"$'\n'"fi" +refuse "#13362's hooks without the platform detector" "needs the omarchy-hw-platform copy" \ + 00-omarchy-hooks.conf "$(cat "$fixtures/omarchy-13362/00-omarchy-hooks.conf")" # Upgrades: pacman replaces an unmodified hooks file, keeps a modified one and # leaves the guarded version as .pacnew, and installs it where it was absent. +# A file restored by hand after the stripped package (as the Spark and Surface +# owners did) is adopted: it stays in place and the guarded one is .pacnew. if ((EUID != 0)) || ! command -v pacman >/dev/null; then echo "SKIP: pacman upgrade checks need root" exit 0 @@ -264,10 +336,17 @@ pacman_in "$scratch/absent" -U "$stripped" pacman_in "$scratch/absent" -U "$new" cmp "$guarded" "$scratch/absent/$installed" +pacman_in "$scratch/restored" -U "$stripped" +mkdir -p "$scratch/restored/etc/mkinitcpio.conf.d" +cp "$unguarded" "$scratch/restored/$installed" +pacman_in "$scratch/restored" -U "$new" +cmp "$unguarded" "$scratch/restored/$installed" +cmp "$guarded" "$scratch/restored/$installed.pacnew" + # Source what the upgrades installed. for upgrade in unchanged absent; do etc=$scratch/$upgrade/etc/mkinitcpio.conf.d - [[ $(effective_hooks "$(machine "$upgrade-snapdragon" "$snapdragon" "$etc")") == "$omarchy_hooks" ]] - [[ $(effective_hooks "$(machine "$upgrade-legacy-mac" "$legacy_mac" "$etc")") == "$legacy_mac" ]] + expect "$upgrade upgrade" Snapdragon "$(effective_hooks "$(machine "$upgrade-snapdragon" "$snapdragon" "$etc")")" "$omarchy_hooks" + check_macs "$upgrade upgrade" "$etc" done echo "PASS: pacman upgrades install the guarded hooks file and keep local changes"