Files
omarchy-pkgs/pkgbuilds/omarchy-settings-dev/omarchy-settings-dev.install
T
40ea1555f2 Ship the complete passwordless-sudo lifecycle in settings-dev (#645)
* Move the dev sudo grant lifecycle into omarchy-settings-dev

The hardened omarchy-sudo-passwordless publishes a grant only when its revocation hook is installed and no package transaction has left /run/omarchy-sudo-passwordless-package-removing behind. The hook sets that marker before every settings upgrade, and the settings scriptlets are what clear it, so shipping the hook alone let the first grant work and then refused every grant after the next update until a reboot.

omarchy-settings-dev now ships the command, omarchy-security-functions, the boot cleanup rule and the hook together, with the scriptlets from #257 that revoke before the package changes and clear the marker once no grant remains. omarchy-dev stops shipping the two helpers and requires the settings release that does: without it omarchy-update has no library to source.

Co-authored-by: Afonso Oliveira <afonso.oliveira707@gmail.com>

* Check that settings-dev registers the scriptlet the lifecycle test exercises

The lifecycle test reads the .install file directly, so it kept passing with the recipe's install= line gone, which is the one change that would strand the hook's marker again.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Keep omarchy-dev's settings dependency unversioned

The dev pair builds each package on its own against the published edge repository, in the PR build and in publish alike, so omarchy-dev cannot require a settings-dev release that only this change produces: the floor failed both omarchy-dev builds on this PR, and an exact pkgver match would fail the same way on every upstream pin bump. Nothing needs it. The upstream watch moves both pins together, publish stops the run before anything is published when one package fails, and a new settings-dev over an old runtime is refused on the files they would both own.

* Refuse settings-dev releases that predate the grant helper move

With the dependency unversioned, a new omarchy-dev could still install over a settings-dev that is held back or not yet published, removing omarchy-security-functions from both, and omarchy-update cannot start without it. A versioned conflict refuses that pairing at install time without constraining the per-package builds, which resolve only depends.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Require the security library as a capability instead of a version floor

The conflict named the last settings-dev release without the helpers, a version that moves with every upstream pin bump and settings-only pkgrel while this change waits to merge, and a rebase that kept a stale floor still passed the tests while the published release slipped past it. omarchy-settings-dev now provides omarchy-security-functions and omarchy-dev's package() requires it. makepkg checks only the top-level depends before building, so the per-package builds still resolve against the published repository, while pacman refuses a runtime without a settings release that ships the library, and pulls that release in when only the runtime is asked for.

Co-Authored-By: Codex XHigh <noreply@openai.com>

---------

Co-authored-by: Spencer Bull <spencer@omarchy.org>
Co-authored-by: Afonso Oliveira <afonso.oliveira707@gmail.com>
Co-authored-by: Codex XHigh <noreply@openai.com>
2026-10-11 09:56:47 -05:00

145 lines
6.1 KiB
Plaintext

# This lock and removal marker are shared with omarchy-sudo-passwordless.
# Keep the marker through removal so no grant can be published after its boot
# cleanup prerequisite disappears. A completed installation clears it again.
_passwordless_package_transition() (
local action=$1 lock_fd directory rule
# Scriptlets run under ordinary Bash with pacman's environment. The sweep
# below relies on pathname expansion, so it must not inherit glob state.
unset GLOBIGNORE
set +f
shopt -u failglob
[[ -d /run && ! -L /run ]] || return 1
[[ $(/usr/bin/stat -Lc '%u' /run) == "0" ]] || return 1
! (( 8#$(/usr/bin/stat -Lc '%a' /run) & 022 )) || return 1
umask 077
case "$action" in
begin|installed)
# Refuse publication before waiting for the lock: a timeout, a failed
# lock directory, or an interrupted transaction must not leave the
# namespace unguarded. The publisher rechecks this marker after it
# publishes, so it needs no lock to take effect.
: >/run/omarchy-sudo-passwordless-package-removing || return 1
;;
esac
[[ -d /run/lock && ! -L /run/lock ]] || return 1
[[ $(/usr/bin/stat -Lc '%u' /run/lock) == "0" ]] || return 1
! (( 8#$(/usr/bin/stat -Lc '%a' /run/lock) & 022 )) || return 1
exec {lock_fd}>/run/lock/omarchy-sudo-passwordless.lock || return 1
# Grant operations are short; a stalled holder must not hang pacman's
# transaction indefinitely.
/usr/bin/flock -x -w 60 "$lock_fd" || return 1
case "$action" in
begin)
/usr/bin/rm -f -- /etc/sudoers.d/99-omarchy-nopasswd-* || return 1
;;
removed)
/usr/bin/rm -f -- /etc/sudoers.d/99-omarchy-nopasswd-* || return 1
;;
installed)
# pacman does not stop a transaction on a failed scriptlet, so a failed
# or interrupted pre-transaction cleanup can be followed by this step,
# and a fresh install has no earlier step at all. The blocker written
# above holds while sweeping, so a failure here leaves publication
# refused; certify completion only with the reserved namespace empty.
/usr/bin/rm -f -- /etc/sudoers.d/99-omarchy-nopasswd-* || return 1
for rule in /etc/sudoers.d/99-omarchy-nopasswd-*; do
[[ ! -e $rule && ! -L $rule ]] || return 1
done
[[ -f /etc/tmpfiles.d/omarchy-nopasswd-sudo.conf ]] || return 1
/usr/bin/rm -f -- /run/omarchy-sudo-passwordless-package-removing || return 1
;;
*) return 1 ;;
esac
)
pre_remove() {
_passwordless_package_transition begin || {
echo "ERROR: Could not revoke temporary Omarchy sudo grants before removing their boot cleanup. Administrator cleanup is required." >&2
return 1
}
}
pre_upgrade() {
pre_remove
}
_apple_silicon() {
[[ $(uname -m) == aarch64 ]] && grep -aq 'apple,' /proc/device-tree/compatible 2>/dev/null
}
_etc_overrides_apply() {
echo "Applying Omarchy etc-overrides..."
# The hardened CUPS authorization applies on every platform. It waits for the
# file the cups package owns: an ISO bootstrap without cups installed is left
# alone and picks it up once cups lands.
if [[ -f /etc/cups/cups-files.conf && -f /usr/share/omarchy/etc-overrides/cups-cups-files.conf ]]; then
systemd-sysusers /etc/sysusers.d/omarchy-cups-browsed.conf
install -m 0640 -o root -g cups /usr/share/omarchy/etc-overrides/cups-cups-files.conf /etc/cups/cups-files.conf
fi
# Apple Silicon installs run on Arch Linux ARM's base with the Asahi
# packages, and keep that system identity: /etc/os-release stays the
# symlink to the distribution's /usr/lib/os-release, and the PAM, NSS,
# plymouth and skel overrides below are not applied there.
if _apple_silicon; then
echo "Preserving Arch Linux ARM system configuration on Apple Silicon..."
if [[ -f /usr/lib/os-release ]]; then
rm -f /etc/os-release
ln -s ../usr/lib/os-release /etc/os-release
fi
return 0
fi
# Ensure parent dirs exist. cups-browsed may not be installed yet during ISO
# bootstrap; do not create /etc/cups/cups-browsed.conf before the package is
# installed or pacman will preserve its packaged file as a noisy .pacnew.
install -d /etc/plymouth /etc/security /etc/skel
# NOTE: these cp -f's are intentionally destructive on every install/upgrade.
# Users who customize /etc/os-release, /etc/plymouth/plymouthd.conf (theme
# switch), /etc/cups/cups-browsed.conf, /etc/cups/cups-files.conf, /etc/nsswitch.conf,
# /etc/security/faillock.conf, or /etc/skel/.bashrc WILL have their changes
# reset to Omarchy defaults each time omarchy-settings-dev is upgraded. This is
# the trade-off of routing upstream-owned paths through etc-overrides instead
# of pacman backup=().
rm -f /etc/os-release
cp -f /usr/share/omarchy/etc-overrides/os-release /etc/os-release
cp -f /usr/share/omarchy/etc-overrides/security-faillock.conf /etc/security/faillock.conf
cp -f /usr/share/omarchy/etc-overrides/nsswitch.conf /etc/nsswitch.conf
if [[ -f /etc/cups/cups-browsed.conf ]]; then
install -d /etc/cups
cp -f /usr/share/omarchy/etc-overrides/cups-cups-browsed.conf /etc/cups/cups-browsed.conf
fi
cp -f /usr/share/omarchy/etc-overrides/plymouth-plymouthd.conf /etc/plymouth/plymouthd.conf
cp -f /usr/share/omarchy/etc-overrides/dot.bashrc /etc/skel/.bashrc
chmod 0644 /etc/os-release /etc/security/faillock.conf /etc/nsswitch.conf \
/etc/plymouth/plymouthd.conf /etc/skel/.bashrc
if [[ -f /etc/cups/cups-browsed.conf ]]; then
chmod 0644 /etc/cups/cups-browsed.conf
fi
}
post_install() {
local status=0
# Recover the grant lifecycle before optional configuration work, so a
# later override failure cannot strand the machine-wide blocker.
_passwordless_package_transition installed || {
echo "ERROR: Temporary Omarchy sudo grants remain or their boot cleanup is missing; passwordless sudo stays disabled until this package installs cleanly." >&2
status=1
}
_etc_overrides_apply || status=1
return "$status"
}
post_upgrade() {
post_install
}
post_remove() {
_passwordless_package_transition removed || {
echo "ERROR: Temporary Omarchy sudo grants could not be removed. Administrator cleanup is required." >&2
return 1
}
}