Split update coordination helpers

This commit is contained in:
David Heinemeier Hansson
2026-07-29 20:04:49 -07:00
parent 695614ce6a
commit 8554801537
7 changed files with 295 additions and 98 deletions
+11 -76
View File
@@ -12,66 +12,19 @@ if [[ -z ${OMARCHY_UPDATE_LOGGED:-} ]]; then
exec env OMARCHY_UPDATE_LOGGED=1 script -qefc "$script_command" "/tmp/omarchy-update.log"
fi
acquire_update_lock() {
local lock_dir="${XDG_RUNTIME_DIR:-/tmp}"
local lock_path="$lock_dir/omarchy-update.lock"
local lock_fd_path=""
if ! omarchy-update-lock held; then
exec omarchy-update-lock run "$0" "$@"
fi
mkdir -p "$lock_dir" 2>/dev/null || true
trap 'echo ""; echo -e "\033[0;31mSomething went wrong during the update!\n\nPlease review the output above carefully, correct the error, and retry the update.\n\nIf you need assistance, get help from the community at https://omarchy.org/discord\033[0m"' ERR
trap 'omarchy-update-stay-awake stop' EXIT
if [[ -n ${OMARCHY_UPDATE_LOCK_FD:-} && -e /proc/$$/fd/$OMARCHY_UPDATE_LOCK_FD ]]; then
lock_fd_path=$(readlink -f "/proc/$$/fd/$OMARCHY_UPDATE_LOCK_FD" 2>/dev/null || true)
if [[ $lock_fd_path == "$(readlink -m "$lock_path")" ]] && flock -n "$OMARCHY_UPDATE_LOCK_FD"; then
return 0
fi
fi
omarchy-update-requires-free-space
exec {OMARCHY_UPDATE_LOCK_FD}>"$lock_path"
if ! flock -n "$OMARCHY_UPDATE_LOCK_FD"; then
echo "An Omarchy update is already running."
exit 1
fi
export OMARCHY_UPDATE_LOCK_FD
}
if [[ ${1:-} == "-y" ]] || omarchy-update-confirm; then
omarchy-snapshot create || (($? == 127))
update_disabled_idle=0
sleep_inhibit_pid=""
disable_sleep_for_update() {
omarchy-cmd-present systemd-inhibit || return 0
systemd-inhibit \
--what=sleep:idle \
--who=omarchy-update \
--why="Omarchy update in progress" \
--mode=block \
sleep infinity >/dev/null 2>&1 {OMARCHY_UPDATE_LOCK_FD}>&- &
sleep_inhibit_pid=$!
}
disable_idle_for_update() {
local stay_awake_state="$HOME/.local/state/omarchy/indicators/stay-awake"
if [[ ! -f $stay_awake_state ]]; then
omarchy-toggle-idle stay-awake >/dev/null 2>&1 || true
update_disabled_idle=1
fi
}
restore_update_inhibitors() {
if (( update_disabled_idle )); then
omarchy-toggle-idle allow-idle >/dev/null 2>&1 || true
fi
if [[ -n $sleep_inhibit_pid ]]; then
kill "$sleep_inhibit_pid" >/dev/null 2>&1 || true
wait "$sleep_inhibit_pid" >/dev/null 2>&1 || true
fi
}
run_update_pipeline() {
disable_sleep_for_update
disable_idle_for_update
omarchy-update-stay-awake start
omarchy-update-dev
omarchy-update-keyring
@@ -83,31 +36,13 @@ run_update_pipeline() {
omarchy-update-orphan-pkgs
omarchy-update-analyze-logs
# Re-check after updates so the status bar reflects any remaining updates.
if omarchy-update-available >/dev/null; then
omarchy-shell -q omarchy.system-update refresh
else
omarchy-shell -q omarchy.system-update clear
fi
omarchy-update-status
# Release update-owned inhibitors before offering a reboot. A confirmed
# reboot can terminate this process before its EXIT trap gets a chance to
# remove the persistent Stay Awake marker.
restore_update_inhibitors
omarchy-update-stay-awake stop
trap - EXIT
omarchy-update-restart
}
acquire_update_lock
omarchy-update-requires-free-space
trap restore_update_inhibitors EXIT
trap 'echo ""; echo -e "\033[0;31mSomething went wrong during the update!\n\nPlease review the output above carefully, correct the error, and retry the update.\n\nIf you need assistance, get help from the community at https://omarchy.org/discord\033[0m"' ERR
if [[ ${1:-} == "-y" ]] || omarchy-update-confirm; then
omarchy-snapshot create || (($? == 127))
run_update_pipeline
fi
+47
View File
@@ -0,0 +1,47 @@
#!/bin/bash
# omarchy:summary=Run a command while holding the Omarchy update lock
# omarchy:args=<held|run> [command] [args...]
# omarchy:hidden=true
set -e
lock_dir="${XDG_RUNTIME_DIR:-/tmp}"
lock_path="$lock_dir/omarchy-update.lock"
lock_is_held() {
local lock_fd_path=""
[[ -n ${OMARCHY_UPDATE_LOCK_FD:-} && -e /proc/$$/fd/$OMARCHY_UPDATE_LOCK_FD ]] || return 1
lock_fd_path=$(readlink -f "/proc/$$/fd/$OMARCHY_UPDATE_LOCK_FD" 2>/dev/null || true)
[[ $lock_fd_path == "$(readlink -m "$lock_path")" ]] &&
flock -n "$OMARCHY_UPDATE_LOCK_FD"
}
case "${1:-}" in
held)
lock_is_held
;;
run)
shift
if (( $# == 0 )); then
echo "Usage: omarchy-update-lock run <command> [args...]" >&2
exit 2
fi
mkdir -p "$lock_dir" 2>/dev/null || true
exec {OMARCHY_UPDATE_LOCK_FD}>"$lock_path"
if ! flock -n "$OMARCHY_UPDATE_LOCK_FD"; then
echo "An Omarchy update is already running."
exit 1
fi
export OMARCHY_UPDATE_LOCK_FD
exec "$@"
;;
*)
echo "Usage: omarchy-update-lock <held|run> [command] [args...]" >&2
exit 2
;;
esac
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
# omarchy:summary=Refresh the shell update status
# omarchy:hidden=true
set -e
if omarchy-update-available >/dev/null; then
omarchy-shell -q omarchy.system-update refresh
else
omarchy-shell -q omarchy.system-update clear
fi
+136
View File
@@ -0,0 +1,136 @@
#!/bin/bash
# omarchy:summary=Manage sleep and idle inhibition during an update
# omarchy:args=<start|stop>
# omarchy:hidden=true
set -e
state_dir="${XDG_RUNTIME_DIR:-/tmp/omarchy-$UID}/omarchy-update-stay-awake"
idle_owner_file="$state_dir/idle-owner"
inhibit_pid_file="$state_dir/inhibit-pid"
stay_awake_state="$HOME/.local/state/omarchy/indicators/stay-awake"
process_start_time() {
local process_pid="$1"
local process_stat=""
local stat_fields=()
[[ -r /proc/$process_pid/stat ]] || return 1
process_stat=$(</proc/"$process_pid"/stat)
process_stat="${process_stat##*) }"
read -r -a stat_fields <<<"$process_stat"
(( ${#stat_fields[@]} > 19 )) || return 1
printf '%s\n' "${stat_fields[19]}"
}
process_state() {
local process_pid="$1"
local process_stat=""
[[ -r /proc/$process_pid/stat ]] || return 1
process_stat=$(</proc/"$process_pid"/stat)
process_stat="${process_stat##*) }"
printf '%s\n' "${process_stat%% *}"
}
stop() {
local inhibit_pid=""
local recorded_start_time=""
local current_start_time=""
local idle_owner=""
local current_idle_owner=""
if [[ -s $idle_owner_file ]]; then
idle_owner=$(<"$idle_owner_file")
if [[ -f $stay_awake_state ]]; then
current_idle_owner=$(<"$stay_awake_state")
fi
if [[ -n $idle_owner && $current_idle_owner == "$idle_owner" ]]; then
omarchy-toggle-idle allow-idle >/dev/null 2>&1 || true
fi
rm -f "$idle_owner_file"
fi
if [[ -s $inhibit_pid_file ]]; then
read -r inhibit_pid recorded_start_time <"$inhibit_pid_file" || true
if [[ $inhibit_pid =~ ^[0-9]+$ ]]; then
current_start_time=$(process_start_time "$inhibit_pid" 2>/dev/null || true)
fi
if [[ -n $recorded_start_time && $current_start_time == "$recorded_start_time" ]]; then
kill "$inhibit_pid" >/dev/null 2>&1 || true
for (( attempt = 0; attempt < 50; attempt++ )); do
current_start_time=$(process_start_time "$inhibit_pid" 2>/dev/null || true)
[[ $current_start_time == "$recorded_start_time" ]] || break
[[ $(process_state "$inhibit_pid" 2>/dev/null || true) != "Z" ]] || break
sleep 0.02
done
current_start_time=$(process_start_time "$inhibit_pid" 2>/dev/null || true)
if [[ $current_start_time == "$recorded_start_time" ]] &&
[[ $(process_state "$inhibit_pid" 2>/dev/null || true) != "Z" ]]; then
echo "Failed to stop the Omarchy update sleep inhibitor." >&2
return 1
fi
fi
rm -f "$inhibit_pid_file"
fi
rmdir "$state_dir" 2>/dev/null || true
}
start() {
local inhibit_pid=""
local inhibit_start_time=""
local idle_owner="$$:$RANDOM:$RANDOM"
stop
mkdir -p "$state_dir"
if omarchy-cmd-present systemd-inhibit; then
if [[ -n ${OMARCHY_UPDATE_LOCK_FD:-} ]]; then
systemd-inhibit \
--what=sleep:idle \
--who=omarchy-update \
--why="Omarchy update in progress" \
--mode=block \
sleep infinity >/dev/null 2>&1 {OMARCHY_UPDATE_LOCK_FD}>&- &
else
systemd-inhibit \
--what=sleep:idle \
--who=omarchy-update \
--why="Omarchy update in progress" \
--mode=block \
sleep infinity >/dev/null 2>&1 &
fi
inhibit_pid=$!
inhibit_start_time=$(process_start_time "$inhibit_pid" 2>/dev/null || true)
if [[ -n $inhibit_start_time ]]; then
printf '%s %s\n' "$inhibit_pid" "$inhibit_start_time" >"$inhibit_pid_file"
fi
fi
if [[ ! -f $stay_awake_state ]]; then
printf '%s\n' "$idle_owner" >"$idle_owner_file"
mkdir -p "$(dirname "$stay_awake_state")"
if omarchy-toggle-idle stay-awake >/dev/null 2>&1; then
printf '%s\n' "$idle_owner" >"$stay_awake_state"
else
rm -f "$idle_owner_file"
fi
fi
}
case "${1:-}" in
start)
start
;;
stop)
stop
;;
*)
echo "Usage: omarchy-update-stay-awake <start|stop>" >&2
exit 2
;;
esac