Put a blocked package upgrade back to whoever is updating (#6830)
Pacman answers its own conflict question with No under --noconfirm, so one retired package can stop every update after it. Which package to drop is a decision rather than a cleanup, so run the upgrade again with pacman asking when there is a terminal to answer on, and report instead when -y promised not to ask. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
625c66301d
commit
5ca3030c5a
@@ -21,6 +21,10 @@ trap 'omarchy-update-stay-awake stop' EXIT
|
||||
|
||||
omarchy-update-requires-free-space
|
||||
|
||||
# -y is a promise not to ask anything. Steps that would need an answer report
|
||||
# and move on instead of waiting on a prompt nobody is here to give.
|
||||
[[ ${1:-} != "-y" ]] || export OMARCHY_UPDATE_UNATTENDED=1
|
||||
|
||||
if [[ ${1:-} == "-y" ]] || omarchy-update-confirm; then
|
||||
# Before the snapshot: the cache is on the snapshotted subvolume, so pruning
|
||||
# after it frees nothing until that snapshot ages out.
|
||||
@@ -36,6 +40,10 @@ if [[ ${1:-} == "-y" ]] || omarchy-update-confirm; then
|
||||
|
||||
omarchy-update-dev
|
||||
omarchy-update-keyring
|
||||
|
||||
# Migrations ship with the packages installed here and are written against
|
||||
# them, so everything below waits on this finishing. An upgrade that stopped
|
||||
# takes the update with it rather than migrating against what is still on disk.
|
||||
omarchy-update-system-pkgs
|
||||
omarchy-migrate
|
||||
omarchy-hook post-update
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
|
||||
set -e
|
||||
|
||||
# The conflict handler's last resort: pacman puts its questions to the person
|
||||
# running the update instead of answering them itself. Nothing here may capture
|
||||
# a stream, because an upgrade without --noconfirm prompts on stderr. The
|
||||
# handler has already said why, so no heading here either.
|
||||
if [[ ${OMARCHY_UPDATE_CONFLICT:-} == 1 && ${OMARCHY_UPDATE_INTERACTIVE:-} == 1 ]]; then
|
||||
exec sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --overwrite '/usr/share/omarchy/*'
|
||||
fi
|
||||
|
||||
echo -e "\e[32m\nUpdate system packages\e[0m"
|
||||
|
||||
errors=$(mktemp)
|
||||
@@ -22,9 +30,9 @@ if sudo env LC_ALL=C OMARCHY_UPDATE_PACMAN=1 pacman -Syu --noconfirm \
|
||||
fi
|
||||
cat "$errors" >&2
|
||||
|
||||
# An upgrade blocked only by files pacman doesn't own yet is the one failure
|
||||
# worth retrying: the handler clears them and runs this again. Anything else,
|
||||
# including a second failure, is for a human.
|
||||
# The handler takes it from here: it clears files pacman doesn't own yet and
|
||||
# runs this again, and puts a package conflict to whoever started the update.
|
||||
# Anything else, including a second failure, is for a human.
|
||||
[[ ${OMARCHY_UPDATE_RETRY:-} != 1 ]] || exit 1
|
||||
# exec, so the EXIT trap above does not fire and the handler can still read the
|
||||
# report. It takes over deleting it.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Retry a system package update after resolving file conflicts
|
||||
# omarchy:summary=Retry a system package update that hit a conflict
|
||||
# omarchy:hidden=true
|
||||
|
||||
# Internal to omarchy-update-system-pkgs. Not a command to run by hand: it acts
|
||||
@@ -11,6 +11,10 @@
|
||||
# release's installer, an in-place edit -- belong to nobody, and pacman refuses
|
||||
# to install over a file it doesn't own. This clears them and runs the upgrade
|
||||
# again.
|
||||
#
|
||||
# Packages that conflict with each other are the other blocked upgrade, and that
|
||||
# one is a decision rather than a cleanup, so it goes back to the person
|
||||
# watching the update.
|
||||
|
||||
set -e
|
||||
|
||||
@@ -57,6 +61,26 @@ restore_moved() {
|
||||
trap 'restore_moved; rm -f "$errors"' EXIT
|
||||
trap 'exit 1' INT TERM
|
||||
|
||||
# Pacman answers its own conflict question with No under --noconfirm, so one
|
||||
# retired package can stop every upgrade after it. Which package to drop is a
|
||||
# decision -- an upstream split retires one, but so does a package the user
|
||||
# picked on purpose -- so put the question to whoever started the update rather
|
||||
# than guess at it. Pacman printed what conflicts just above.
|
||||
if grep -q '^error: unresolvable package conflicts detected$' "$errors"; then
|
||||
# -y promised not to ask anything, and without a terminal there is nowhere to
|
||||
# ask; either way pacman would sit on a prompt nobody answers. An upgrade that
|
||||
# isn't running --noconfirm puts its questions on stderr and reads the answers
|
||||
# from stdin, so those are the two that have to be a terminal.
|
||||
if [[ ${OMARCHY_UPDATE_UNATTENDED:-} == 1 || ! -t 0 || ! -t 2 ]]; then
|
||||
echo -e "\e[33m\nThis upgrade needs an answer. Run omarchy update interactively to give it.\e[0m" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\e[33m\nA package conflict stopped this upgrade. Running it again so you can answer:\e[0m"
|
||||
OMARCHY_UPDATE_INTERACTIVE=1 omarchy-update-system-pkgs
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Paths one of these packages installs that pacman doesn't own. Moving them out
|
||||
# of the way is what lets the upgrade through, and works on a leftover directory
|
||||
# as well as a file.
|
||||
|
||||
Reference in New Issue
Block a user