diff --git a/migrations/1785608166.sh b/migrations/1785608166.sh index cdfc6e610ae..9e922c4b14a 100644 --- a/migrations/1785608166.sh +++ b/migrations/1785608166.sh @@ -45,12 +45,23 @@ if ! graphical_state=$(systemctl --user show --property=ActiveState --value grap exit 1 fi +# A unit the manager cannot load — never packaged onto this machine, or +# deliberately masked by the user — has no failed state to clear and nothing +# to restart, so there is nothing to repair. +if ! load_state=$(systemctl --user show --property=LoadState --value omarchy-sleep-lock.service 2>&1); then + echo "Could not inspect omarchy-sleep-lock.service: $load_state" + echo "The pre-suspend lock repair will be retried by omarchy-migrate." + exit 1 +elif [[ $load_state != "loaded" ]]; then + echo "omarchy-sleep-lock.service is not loadable here; skipping the live repair." + exit 0 +fi + if [[ $graphical_state == "active" ]]; then - if ! error=$(systemctl --user reset-failed omarchy-sleep-lock.service 2>&1); then - echo "Could not reset omarchy-sleep-lock.service: $error" - echo "The pre-suspend lock repair will be retried by omarchy-migrate." - exit 1 - elif ! error=$(systemctl --user restart omarchy-sleep-lock.service 2>&1); then + # reset-failed on a unit that never failed — or never loaded — is an ordinary + # no-op, not a repair problem. The restart is what matters. + systemctl --user reset-failed omarchy-sleep-lock.service >/dev/null 2>&1 || true + if ! error=$(systemctl --user restart omarchy-sleep-lock.service 2>&1); then echo "Could not restart omarchy-sleep-lock.service: $error" echo "The pre-suspend lock repair will be retried by omarchy-migrate." exit 1 @@ -71,9 +82,6 @@ else echo "Could not stop stale omarchy-sleep-lock.service: $error" echo "The pre-suspend lock repair will be retried by omarchy-migrate." exit 1 - elif ! error=$(systemctl --user reset-failed omarchy-sleep-lock.service 2>&1); then - echo "Could not reset omarchy-sleep-lock.service: $error" - echo "The pre-suspend lock repair will be retried by omarchy-migrate." - exit 1 fi + systemctl --user reset-failed omarchy-sleep-lock.service >/dev/null 2>&1 || true fi diff --git a/test/shell.d/sleep-lock-environment-migration-test.sh b/test/shell.d/sleep-lock-environment-migration-test.sh index e778c1c0d78..317f9f4e35e 100755 --- a/test/shell.d/sleep-lock-environment-migration-test.sh +++ b/test/shell.d/sleep-lock-environment-migration-test.sh @@ -32,6 +32,13 @@ case "$*" in fi printf '%s\n' "${GRAPHICAL_STATE:-inactive}" ;; + '--user show --property=LoadState --value omarchy-sleep-lock.service') + if [[ ${FAIL_SYSTEMCTL_ACTION:-} == "show-loadstate" ]]; then + echo "load state lookup failed" >&2 + exit 1 + fi + printf '%s\n' "${SLEEP_LOCK_LOAD_STATE:-loaded}" + ;; '--user show --property=ActiveState --value omarchy-sleep-lock.service') printf '%s\n' "${SLEEP_LOCK_STATE:-inactive}" ;; @@ -47,7 +54,12 @@ case "$*" in exit 1 fi ;; - '--user reset-failed omarchy-sleep-lock.service') ;; + '--user reset-failed omarchy-sleep-lock.service') + if [[ ${FAIL_SYSTEMCTL_ACTION:-} == "reset-failed" ]]; then + echo "Failed to reset failed state of unit omarchy-sleep-lock.service: Unit omarchy-sleep-lock.service not loaded." >&2 + exit 1 + fi + ;; *) exit 1 ;; esac STUB @@ -146,6 +158,37 @@ grep -F 'Could not inspect graphical-session.target' "$test_tmp/state-failed-out fail "sleep lock migration does not report a failed session-state inspection" pass "sleep lock migration keeps an indeterminate session repair retryable" +# reset-failed on a unit that never loaded is a normal no-op, not a repair +# problem: the migration must still drive the restart that actually repairs. +reset_failed_calls="$test_tmp/reset-failed-calls" +run_migration "$test_tmp/reset-failed-home" "$reset_failed_calls" \ + env GRAPHICAL_STATE=active SLEEP_LOCK_STATE=active FAIL_SYSTEMCTL_ACTION=reset-failed >/dev/null || + fail "sleep lock migration fails an update over a never-loaded unit" +grep -Fx -- '--user restart omarchy-sleep-lock.service' "$reset_failed_calls" >/dev/null || + fail "sleep lock migration does not restart the monitor after a benign reset-failed" +pass "sleep lock migration tolerates reset-failed on a never-loaded unit" + +# A unit the manager cannot load at all — never packaged here, or masked by the +# user — has nothing to repair and must not be restarted. +for absent_state in not-found masked; do + absent_calls="$test_tmp/absent-$absent_state-calls" + run_migration "$test_tmp/absent-$absent_state-home" "$absent_calls" \ + env GRAPHICAL_STATE=active SLEEP_LOCK_LOAD_STATE="$absent_state" >/dev/null || + fail "sleep lock migration fails on a $absent_state unit" + grep -F -- '--user restart omarchy-sleep-lock.service' "$absent_calls" >/dev/null && + fail "sleep lock migration restarts a $absent_state unit" + pass "sleep lock migration skips the repair when the unit is $absent_state" +done + +loadstate_failed_calls="$test_tmp/loadstate-failed-calls" +if run_migration "$test_tmp/loadstate-failed-home" "$loadstate_failed_calls" \ + env FAIL_SYSTEMCTL_ACTION=show-loadstate >"$test_tmp/loadstate-failed-output" 2>&1; then + fail "sleep lock migration ignores a failed unit-load inspection" +fi +grep -F 'will be retried by omarchy-migrate' "$test_tmp/loadstate-failed-output" >/dev/null || + fail "sleep lock migration does not report a failed load-state inspection" +pass "sleep lock migration keeps a failed load-state inspection retryable" + deferred_home="$test_tmp/deferred-home" deferred_calls="$test_tmp/deferred-calls" mkdir -p "$deferred_home/.config/systemd/user"