Wait on the profile being repaired, not on every browser (#6837)
The migration asked a user to close every running browser before repairing the Copy URL shortcut, but a browser only ever rewrites its own Preferences on exit. Waiting on all browsers deadlocks `omarchy update` for anyone whose main browser is effectively never closed: the pending ghosts commonly sit in a stale profile nobody has open, yet the migration blocks on the always-open browser until the prompt is declined, failing the whole update. A running Chromium-family browser holds a SingletonLock (and socket) inside its user-data-dir, so whether the profile being repaired is open is mechanical. Gate on that instead of on the sheer presence of a browser process — the repair proceeds where the affected profile is closed, and browsers attached to other profiles no longer hold the update hostage. The gate stays conservative while an affected profile actually is open, and the existing post-repair verification still catches a browser that starts mid-repair and restores stale Preferences on exit. The migration test now simulates an open profile with its SingletonLock instead of a pgrep stub; every prior scenario still passes.
This commit is contained in:
+42
-16
@@ -122,10 +122,36 @@ unverified_repairs_exist() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Only this user's browsers matter — another user's cannot rewrite these
|
||||
# Preferences.
|
||||
browsers_running() {
|
||||
pgrep -x -u "$UID" 'chromium|chrome|brave|msedge|vivaldi-bin|vivaldi|opera|helium' >/dev/null 2>&1
|
||||
# A browser only rewrites its own Preferences on exit, so a repair can only be
|
||||
# reverted by a browser attached to a profile this migration has to touch.
|
||||
# Whether a profile is open is mechanical: a running Chromium-family browser
|
||||
# holds a SingletonLock (and socket) inside its user-data-dir.
|
||||
profile_open() {
|
||||
# -L catches a SingletonLock left as a dangling symlink; -e covers a plain
|
||||
# file, and -S the socket — any of them means a browser is attached.
|
||||
[[ -L $1/SingletonLock || -e $1/SingletonLock || -S $1/SingletonSocket ]]
|
||||
}
|
||||
|
||||
# Gate on a pending — or to-be-verified — profile actually being open, not on
|
||||
# browsers in general. Waiting on every browser process deadlocks the update on
|
||||
# machines whose main browser is effectively never closed: the pending ghosts
|
||||
# commonly sit in a stale profile nobody has open, yet the update blocks on the
|
||||
# always-open one.
|
||||
affected_profile_open() {
|
||||
local preferences backup profile_root
|
||||
|
||||
for preferences in "${pending[@]}"; do
|
||||
profile_open "$(dirname "$(dirname "$preferences")")" && return 0
|
||||
done
|
||||
|
||||
for profile_root in "${profile_roots[@]}"; do
|
||||
for backup in "$profile_root"/*/Preferences.omarchy-copy-url-repair.bak; do
|
||||
[[ -f $backup ]] || continue
|
||||
profile_open "$(dirname "$(dirname "$backup")")" && return 0
|
||||
done
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
find_pending
|
||||
@@ -134,16 +160,16 @@ if (( ! ${#pending[@]} )) && ! unverified_repairs_exist; then
|
||||
fi
|
||||
|
||||
# A running browser holds Preferences in memory and rewrites the file on exit,
|
||||
# reverting the repair, so ask for the windows to be closed first. gum draws
|
||||
# the prompt on stderr, so it must stay attached: suppressing it leaves gum
|
||||
# waiting for a keypress behind an unpainted screen. Without a terminal to ask
|
||||
# in, gum fails; then — as on decline — fail so the migration stays pending,
|
||||
# and the login notifier keeps prompting until a rerun goes through with
|
||||
# browsers closed.
|
||||
while browsers_running; do
|
||||
if ! gum confirm "Close all browser windows to repair the Copy URL shortcut, then continue"; then
|
||||
# reverting the repair, so ask for the affected windows to be closed first. gum
|
||||
# draws the prompt on stderr, so it must stay attached: suppressing it leaves
|
||||
# gum waiting for a keypress behind an unpainted screen. Without a terminal to
|
||||
# ask in, gum fails; then — as on decline — fail so the migration stays
|
||||
# pending, and the login notifier keeps prompting until a rerun goes through
|
||||
# with the affected profiles closed.
|
||||
while affected_profile_open; do
|
||||
if ! gum confirm "Close the browser windows to repair the Copy URL shortcut, then continue"; then
|
||||
echo "A running browser would undo the Copy URL shortcut repair." >&2
|
||||
echo "Close all browser windows, then run: omarchy-migrate" >&2
|
||||
echo "Close the browser windows, then run: omarchy-migrate" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
@@ -159,9 +185,9 @@ done
|
||||
# A browser that started mid-repair read the stale Preferences and will write
|
||||
# them back on exit; stay pending so the next browser-free run can verify the
|
||||
# repair stuck.
|
||||
if browsers_running; then
|
||||
if affected_profile_open; then
|
||||
echo "A browser started during the Copy URL shortcut repair and may undo it on exit." >&2
|
||||
echo "Close all browser windows, then run: omarchy-migrate" >&2
|
||||
echo "Close the browser windows, then run: omarchy-migrate" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -172,7 +198,7 @@ fi
|
||||
for preferences in "${pending[@]}"; do
|
||||
if python3 -c "$repair_py" "$preferences" "$pinned_id" check; then
|
||||
echo "A browser undid the Copy URL shortcut repair on exit." >&2
|
||||
echo "Close all browser windows, then run: omarchy-migrate" >&2
|
||||
echo "Close the browser windows, then run: omarchy-migrate" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user