mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-13 22:50:48 +01:00
Eight checks assigned status="warning" unconditionally, so a check running
later in the same function overwrote the status="error" an earlier one had
set. The five other sites in this family already guard the assignment with
`if [[ $status != "error" ]]`, so this was an inconsistency, not a design.
Only half of it was load-bearing, and the two halves fail differently:
services_units.sh (4 sites) reports through report_and_fix, which repairs
ONLY on "error". A downgrade there meant no repair ran at all. The is-active
check is the LAST status assignment in each of the three functions, so it
could mask any error above it -- in check_periodic_systems, three separate
is-enabled checks. A timer that was both disabled and inactive, which is the
ordinary shape of a broken timer, was reported and then left broken.
services_hosts.sh (4 sites) gates its own repair on `status != "ok"`, so the
repair still ran. There the bug printed a real error as a yellow [!] warning
and understated the summary row.
Demonstrated rather than argued, against a simulated broken machine (timer
disabled AND inactive, unit files present):
without the guards: status=warning, repair ran 0 times
with the guards: status=error, repair ran 1 time
The seven assertions that previously pinned the broken behaviour now assert
the correct behaviour; they were rewritten first and failed, then the guards
made them pass. Two further cases cover the masking shape directly: a broken
guard-lib instance must still be repaired when a later check warns.
`--status --dry-run` output is still byte-identical to rev 6691cb26, because
this machine has no disabled timer and no missing pacman hook -- the buggy
path is never taken here, which is precisely why it went unnoticed. The A/B
above is the evidence the live diff cannot provide.
222 assertions across 10 files. services_units.sh holds 100% coverage;
services_hosts.sh rises from 86.05% to 93.02%. test_services_hosts.sh needed
splitting twice to stay under the 250-line cap (hosts_fix, resolved), and
stage_hosts_ok moved into the harness so both new files can use it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3PzGc75gBcdxP3PkHXGcV
170 lines
5.3 KiB
Bash
Executable File
170 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# lib/services_units.sh — systemd timer/service checks for the three units that
|
|
# are installed by their own setup scripts (midnight shutdown, PC startup
|
|
# monitor, periodic maintenance).
|
|
#
|
|
# Sourced by check_and_enable_services.sh. All three funnel their findings
|
|
# through report_and_fix, which owns the reinstall-and-reverify path.
|
|
|
|
# Absolute paths the checks below probe are prefixed with $SYSROOT, which is
|
|
# empty in production and a fixture tree under test. It is deliberately NOT
|
|
# defaulted here: several repairs in this family write outside `run` (chattr,
|
|
# find -delete, an append to resolved.conf), so a test that forgot to set it
|
|
# would edit the real /etc. Unset is a hard error; empty is the real filesystem.
|
|
SYSROOT="${SERVICES_ROOT?SERVICES_ROOT must be set (empty = the real filesystem)}"
|
|
|
|
check_midnight_shutdown() {
|
|
header "Midnight Shutdown (Day-Specific Auto-Shutdown)"
|
|
|
|
local status="ok"
|
|
local issues=()
|
|
|
|
# Check timer
|
|
if systemctl is-enabled day-specific-shutdown.timer &>/dev/null; then
|
|
msg "day-specific-shutdown.timer is enabled"
|
|
else
|
|
issues+=("day-specific-shutdown.timer is not enabled")
|
|
status="error"
|
|
fi
|
|
|
|
if systemctl is-active day-specific-shutdown.timer &>/dev/null; then
|
|
msg "day-specific-shutdown.timer is active"
|
|
else
|
|
issues+=("day-specific-shutdown.timer is not active")
|
|
if [[ $status != "error" ]]; then status="warning"; fi
|
|
fi
|
|
|
|
# Check service file exists
|
|
if [[ -f "${SYSROOT}/etc/systemd/system/day-specific-shutdown.service" ]]; then
|
|
msg "day-specific-shutdown.service file exists"
|
|
else
|
|
issues+=("day-specific-shutdown.service file missing")
|
|
status="error"
|
|
fi
|
|
|
|
# Check management script
|
|
if [[ -f "${SYSROOT}/usr/local/bin/day-specific-shutdown-manager.sh" ]]; then
|
|
msg "Shutdown manager script exists"
|
|
else
|
|
issues+=("day-specific-shutdown-manager.sh not found")
|
|
status="error"
|
|
fi
|
|
|
|
report_and_fix issues status "midnight_shutdown" \
|
|
"Setting up midnight shutdown..." \
|
|
"$MIDNIGHT_SHUTDOWN_SCRIPT" \
|
|
"day-specific-shutdown.timer" \
|
|
enable
|
|
}
|
|
|
|
check_startup_monitor() {
|
|
header "PC Startup Monitor"
|
|
|
|
local status="ok"
|
|
local issues=()
|
|
|
|
# Check timer (the timer triggers the service, so we check the timer)
|
|
if systemctl is-enabled pc-startup-monitor.timer &>/dev/null; then
|
|
msg "pc-startup-monitor.timer is enabled"
|
|
else
|
|
issues+=("pc-startup-monitor.timer is not enabled")
|
|
status="error"
|
|
fi
|
|
|
|
if systemctl is-active pc-startup-monitor.timer &>/dev/null; then
|
|
msg "pc-startup-monitor.timer is active"
|
|
else
|
|
issues+=("pc-startup-monitor.timer is not active")
|
|
if [[ $status != "error" ]]; then status="warning"; fi
|
|
fi
|
|
|
|
# Check service file exists
|
|
if [[ -f "${SYSROOT}/etc/systemd/system/pc-startup-monitor.service" ]]; then
|
|
msg "pc-startup-monitor.service file exists"
|
|
else
|
|
issues+=("pc-startup-monitor.service file missing")
|
|
status="error"
|
|
fi
|
|
|
|
# Check monitor script
|
|
if [[ -f "${SYSROOT}/usr/local/bin/pc-startup-check.sh" ]]; then
|
|
msg "Startup check script exists"
|
|
else
|
|
issues+=("pc-startup-check.sh not found")
|
|
status="error"
|
|
fi
|
|
|
|
report_and_fix issues status "startup_monitor" \
|
|
"Setting up startup monitor..." \
|
|
"$STARTUP_MONITOR_SCRIPT" \
|
|
"pc-startup-monitor.timer"
|
|
}
|
|
|
|
check_periodic_systems() {
|
|
header "Periodic System Maintenance"
|
|
|
|
local status="ok"
|
|
local issues=()
|
|
|
|
# Check timer
|
|
if systemctl is-enabled periodic-system-maintenance.timer &>/dev/null; then
|
|
msg "periodic-system-maintenance.timer is enabled"
|
|
else
|
|
issues+=("periodic-system-maintenance.timer is not enabled")
|
|
status="error"
|
|
fi
|
|
|
|
if systemctl is-active periodic-system-maintenance.timer &>/dev/null; then
|
|
msg "periodic-system-maintenance.timer is active"
|
|
else
|
|
issues+=("periodic-system-maintenance.timer is not active")
|
|
if [[ $status != "error" ]]; then status="warning"; fi
|
|
fi
|
|
|
|
# Check startup service
|
|
if systemctl is-enabled periodic-system-startup.service &>/dev/null; then
|
|
msg "periodic-system-startup.service is enabled"
|
|
else
|
|
issues+=("periodic-system-startup.service is not enabled")
|
|
status="error"
|
|
fi
|
|
|
|
# Check hosts file monitor
|
|
if systemctl is-enabled hosts-file-monitor.service &>/dev/null; then
|
|
msg "hosts-file-monitor.service is enabled"
|
|
else
|
|
issues+=("hosts-file-monitor.service is not enabled")
|
|
status="error"
|
|
fi
|
|
|
|
if systemctl is-active hosts-file-monitor.service &>/dev/null; then
|
|
msg "hosts-file-monitor.service is active"
|
|
else
|
|
issues+=("hosts-file-monitor.service is not active")
|
|
if [[ $status != "error" ]]; then status="warning"; fi
|
|
fi
|
|
|
|
# Check maintenance script
|
|
if [[ -f "${SYSROOT}/usr/local/bin/periodic-system-maintenance.sh" ]]; then
|
|
msg "Maintenance script exists"
|
|
else
|
|
issues+=("periodic-system-maintenance.sh not found")
|
|
status="error"
|
|
fi
|
|
|
|
# report_and_fix takes `status` by nameref and both reads and rewrites it,
|
|
# so passing the bare name is the whole interface. shellcheck cannot see
|
|
# through a nameref, though, and standalone it reports the assignments
|
|
# above as write-only (SC2034). This early return is a genuine read: an
|
|
# "ok" service has nothing to report and nothing to fix, so skipping the
|
|
# call is also marginally cheaper than having it decide the same thing.
|
|
if [[ $status == "ok" ]]; then
|
|
set_service_status "periodic_systems" "ok"
|
|
return 0
|
|
fi
|
|
report_and_fix issues status "periodic_systems" \
|
|
"Setting up periodic systems..." \
|
|
"$PERIODIC_SYSTEM_SCRIPT" \
|
|
"periodic-system-maintenance.timer"
|
|
}
|