mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-14 18:10:48 +01:00
fix(services): report and remove a stale compulsive-block <app>.orig
check_compulsive_blocker said "<app> wrapper installed (original backed
up)" whenever /usr/bin/<app>.orig existed, even after the package was
removed. A .orig whose /usr/bin/<app> no package owns (read from
${SYSROOT}/var/lib/pacman/local, not pacman -Qqo) is now a warning,
"stale <app>.orig left after package removal", and the repair deletes
it (plus a dangling wrapper) via run, honouring --status/--dry-run.
Unreadable db: never prunes. Pairs with digital-wellbeing 6867f29.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014yhTkYV6ZeuAbQYvykFGFc
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8be1fac8f9
commit
2dc4081dc9
@ -0,0 +1,36 @@
|
||||
{
|
||||
"intent": "check_compulsive_blocker stops reporting a messaging app as wrapped when its package was removed and only /usr/bin/<app>.orig (the real launcher, a blocker bypass) is left; the repair deletes it.",
|
||||
"scope": [
|
||||
"linux_configuration/periodic_background/lib/services_apps.sh, linux_configuration/periodic_background/lib/tests/test_services_apps.sh",
|
||||
"Installer/hook side lives in digital-wellbeing (commit 6867f29); non-goal: no change to the full-installer repair path"
|
||||
],
|
||||
"changes": [
|
||||
"_pkg_owns_path reads ${SYSROOT}/var/lib/pacman/local/*/files (0 owned, 1 unowned, 2 undeterminable) instead of calling the wrapped pacman",
|
||||
"A .orig on an unowned /usr/bin/<app> is a warning 'stale <app>.orig left after package removal' and is removed via run (plus a dangling wrapper) unless --status; an unreadable db never prunes"
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "periodic_background/lib/tests/run_all.sh",
|
||||
"result": "pass",
|
||||
"evidence": "test_services_apps.sh 38 passed 0 failed (new cases fail 8/38 against HEAD); all services suites pass"
|
||||
},
|
||||
{
|
||||
"command": "vmbox guest cco: check_compulsive_blocker on a real stranded /usr/bin/discord.orig",
|
||||
"result": "pass",
|
||||
"evidence": "--status: warning, file kept; repair: FIXES=1, file gone; rerun: ok. Passed in vmbox, not verified on the host"
|
||||
},
|
||||
{
|
||||
"command": "shellcheck -x services_apps.sh test_services_apps.sh",
|
||||
"result": "pass",
|
||||
"evidence": "clean"
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"A package that ships the app under a different path than /usr/bin/<app> would make its .orig look stale",
|
||||
"The host's next periodic run will delete /usr/bin/discord.orig itself"
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit",
|
||||
"Run check_and_enable_services.sh --status and confirm the compulsive_blocker section"
|
||||
]
|
||||
}
|
||||
@ -27,9 +27,19 @@ check_compulsive_blocker() {
|
||||
|
||||
# Check if wrappers are installed for known apps
|
||||
local checked_any=false
|
||||
local stale=()
|
||||
for app in beeper signal-desktop discord; do
|
||||
local wrapper_path="${SYSROOT}/usr/bin/$app"
|
||||
if [[ -f "${wrapper_path}.orig" ]] || [[ -L "$wrapper_path" ]]; then
|
||||
local owned=0
|
||||
_pkg_owns_path "/usr/bin/$app" || owned=$?
|
||||
if [[ -f "${wrapper_path}.orig" && $owned -eq 1 ]]; then
|
||||
# Package removed: pacman deleted the wrapper but not the backup,
|
||||
# so `<app>.orig` still launches the app around the blocker.
|
||||
issues+=("stale $app.orig left after package removal")
|
||||
stale+=("$app")
|
||||
if [[ $status != "error" ]]; then status="warning"; fi
|
||||
checked_any=true
|
||||
elif [[ -f "${wrapper_path}.orig" ]] || [[ -L "$wrapper_path" ]]; then
|
||||
if [[ -f "${wrapper_path}.orig" ]]; then
|
||||
msg "$app wrapper installed (original backed up)"
|
||||
checked_any=true
|
||||
@ -64,11 +74,38 @@ check_compulsive_blocker() {
|
||||
err_missing_script "Install script not found: $COMPULSIVE_BLOCK_SCRIPT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# A stale backup is repaired on its own, whatever the status: the full
|
||||
# installer is only for a missing blocker.
|
||||
if [[ $STATUS_ONLY -eq 0 ]]; then
|
||||
for app in "${stale[@]}"; do
|
||||
local stale_path="${SYSROOT}/usr/bin/$app"
|
||||
note "Removing stale ${stale_path}.orig..."
|
||||
run rm -f "${stale_path}.orig"
|
||||
# A wrapper left behind would exec the .orig just deleted.
|
||||
if grep -q "block-compulsive-opening" "$stale_path" 2>/dev/null; then
|
||||
run rm -f "$stale_path"
|
||||
fi
|
||||
((FIXES_APPLIED++)) || true
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
set_service_status "compulsive_blocker" "$status"
|
||||
}
|
||||
|
||||
# Does an installed package own <abs-path>? Read from ${SYSROOT}'s pacman db
|
||||
# rather than `pacman -Qqo`, so it honours SYSROOT and skips the pacman
|
||||
# wrapper. grep's exit code is the answer: 0 owned, 1 unowned, 2 undeterminable
|
||||
# (no db) -- only a definite 1 makes a .orig stale.
|
||||
_pkg_owns_path() { # <abs-path>
|
||||
local lists=("${SYSROOT}"/var/lib/pacman/local/*/files)
|
||||
[[ -e ${lists[0]} ]] || return 2
|
||||
local rc=0
|
||||
grep -qxF -- "${1#/}" "${lists[@]}" 2>/dev/null || rc=$?
|
||||
return "$rc"
|
||||
}
|
||||
|
||||
check_leechblock() {
|
||||
header "LeechBlock Browser Extension"
|
||||
|
||||
|
||||
@ -24,6 +24,30 @@ _t_called_in() { # <haystack> <needle> <what>
|
||||
fi
|
||||
}
|
||||
|
||||
_t_not_in() { # <haystack> <needle> <what>
|
||||
if [[ "$1" == *"$2"* ]]; then
|
||||
_t_fail "$3 (unexpected '$2')"
|
||||
else
|
||||
_t_pass "$3"
|
||||
fi
|
||||
}
|
||||
|
||||
# What install_wrapper leaves on /usr/bin/<app>: the marker the repair greps.
|
||||
wrapper_marker() { # <relative-path>
|
||||
sysfile "$1"
|
||||
printf 'exec /usr/local/bin/block-compulsive-opening.sh wrapper x\n' >"${SYSROOT_DIR}/$1"
|
||||
}
|
||||
|
||||
# Register <relative-path> as owned by <pkg> in the fixture pacman db.
|
||||
own_path() { # <pkg> <relative-path>
|
||||
sysfile "var/lib/pacman/local/$1-1-1/files"
|
||||
printf '%%FILES%%\n%s\n' "$2" >"${SYSROOT_DIR}/var/lib/pacman/local/$1-1-1/files"
|
||||
}
|
||||
|
||||
sys_state() { # <relative-path> -> present|absent
|
||||
if [[ -e "${SYSROOT_DIR}/$1" ]]; then echo present; else echo absent; fi
|
||||
}
|
||||
|
||||
TEST_USER="${SUDO_USER:-$USER}"
|
||||
|
||||
echo "== check_compulsive_blocker: no target apps present =="
|
||||
@ -58,9 +82,70 @@ sysfile usr/local/bin/block-compulsive-opening.sh
|
||||
present_command discord
|
||||
absent_command beeper signal-desktop
|
||||
sysfile usr/bin/discord.orig
|
||||
wrapper_marker usr/bin/discord
|
||||
own_path discord usr/bin/discord
|
||||
check_compulsive_blocker >"${TEST_TMPDIR}/out.txt"
|
||||
_t_called_in "$(cat "${TEST_TMPDIR}/out.txt")" "discord wrapper installed" "a backed-up original counts as wrapped"
|
||||
_t_eq "ok" "$(get_service_status "compulsive_blocker")" "a wrapped app leaves status ok"
|
||||
_t_eq "0" "$FIXES_APPLIED" "an owned wrap is not touched"
|
||||
|
||||
echo "== check_compulsive_blocker: a .orig left by a package removal is stale =="
|
||||
reset_state
|
||||
sysfile usr/local/bin/block-compulsive-opening.sh
|
||||
absent_command beeper signal-desktop discord
|
||||
# pacman removed /usr/bin/discord (our wrapper) but not the backup; another
|
||||
# package in the db proves the db is readable, so "unowned" is definite.
|
||||
sysfile usr/bin/discord.orig
|
||||
own_path signal-desktop usr/bin/signal-desktop
|
||||
check_compulsive_blocker >"${TEST_TMPDIR}/out.txt"
|
||||
_t_called_in "$(cat "${TEST_TMPDIR}/out.txt")" "stale discord.orig left after package removal" "the stale backup is named"
|
||||
_t_not_in "$(cat "${TEST_TMPDIR}/out.txt")" "discord wrapper installed" "a stale backup is not reported as a wrapper"
|
||||
_t_eq "warning" "$(get_service_status "compulsive_blocker")" "a stale backup is a warning"
|
||||
_t_eq "absent" "$(sys_state usr/bin/discord.orig)" "the repair deletes the stale .orig"
|
||||
_t_eq "1" "$FIXES_APPLIED" "the removal is counted as a fix"
|
||||
_t_not_called 'ran block_compulsive_opening' "a stale backup does not rerun the installer"
|
||||
|
||||
echo "== check_compulsive_blocker: a stale .orig takes its dangling wrapper with it =="
|
||||
reset_state
|
||||
sysfile usr/local/bin/block-compulsive-opening.sh
|
||||
absent_command beeper signal-desktop discord
|
||||
sysfile usr/bin/discord.orig
|
||||
wrapper_marker usr/bin/discord
|
||||
own_path signal-desktop usr/bin/signal-desktop
|
||||
check_compulsive_blocker >/dev/null
|
||||
_t_eq "absent" "$(sys_state usr/bin/discord)" "our wrapper on an unowned path is deleted"
|
||||
_t_eq "absent" "$(sys_state usr/bin/discord.orig)" "and so is its .orig"
|
||||
|
||||
echo "== check_compulsive_blocker: --status reports a stale .orig but keeps it =="
|
||||
reset_state
|
||||
sysfile usr/local/bin/block-compulsive-opening.sh
|
||||
absent_command beeper signal-desktop discord
|
||||
sysfile usr/bin/discord.orig
|
||||
own_path signal-desktop usr/bin/signal-desktop
|
||||
STATUS_ONLY=1
|
||||
check_compulsive_blocker >"${TEST_TMPDIR}/out.txt"
|
||||
_t_called_in "$(cat "${TEST_TMPDIR}/out.txt")" "stale discord.orig" "--status still names the stale backup"
|
||||
_t_eq "present" "$(sys_state usr/bin/discord.orig)" "--status deletes nothing"
|
||||
|
||||
echo "== check_compulsive_blocker: --dry-run reports a stale .orig but keeps it =="
|
||||
reset_state
|
||||
sysfile usr/local/bin/block-compulsive-opening.sh
|
||||
absent_command beeper signal-desktop discord
|
||||
sysfile usr/bin/discord.orig
|
||||
own_path signal-desktop usr/bin/signal-desktop
|
||||
DRY_RUN=1
|
||||
check_compulsive_blocker >/dev/null
|
||||
_t_eq "present" "$(sys_state usr/bin/discord.orig)" "--dry-run deletes nothing"
|
||||
|
||||
echo "== check_compulsive_blocker: an unreadable pacman db never prunes =="
|
||||
reset_state
|
||||
sysfile usr/local/bin/block-compulsive-opening.sh
|
||||
present_command discord
|
||||
absent_command beeper signal-desktop
|
||||
sysfile usr/bin/discord.orig
|
||||
check_compulsive_blocker >"${TEST_TMPDIR}/out.txt"
|
||||
_t_called_in "$(cat "${TEST_TMPDIR}/out.txt")" "discord wrapper installed" "no db: the backup still counts as a wrapper"
|
||||
_t_eq "present" "$(sys_state usr/bin/discord.orig)" "no db: the .orig is kept"
|
||||
|
||||
echo "== check_compulsive_blocker: a symlinked wrapper without .orig is skipped =="
|
||||
reset_state
|
||||
|
||||
Loading…
Reference in New Issue
Block a user