Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

scripts/remote/check-maintenance.sh

Raw
#!/usr/bin/env bash
set -uo pipefail

# Root-run weekly maintenance freshness checks on klops.
# Prints one TSV line per check (status, name, detail) and exits nonzero on
# any failure so OnFailure=bugabinga-alert@ can notify.

service_user="oli"
ci_user="ci"
toad_user="toad"
rollback_image="localhost/bugabinga-luci:rollback"
gc_max_age=$((8 * 24 * 3600))
update_max_age=$((25 * 3600))
disk_max_percent=90
failures=0

pass() { printf 'ok\t%s\t%s\n' "$1" "$2"; }
fail() {
  printf 'fail\t%s\t%s\n' "$1" "$2"
  failures=$((failures + 1))
}

user_shell() {
  local user="$1" command="$2"
  # cd / keeps the invocation independent of an unreadable caller cwd.
  cd /
  runuser -u "${user}" -- /usr/bin/bash -c "export HOME=\$(getent passwd ${user} | cut -d: -f6) XDG_RUNTIME_DIR=/run/user/\$(id -u ${user}) DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/\$(id -u ${user})/bus; exec ${command}"
}

check_success_age() {
  local name="$1" unit="$2" max_age="$3" age='' now='' timestamp=''
  timestamp="$(systemctl show "${unit}" --property=ExecMainExitTimestamp --value)"
  if [[ -n "${timestamp}" ]] && age="$(date -d "${timestamp}" +%s 2>/dev/null)"; then
    now="$(date +%s)"
    if ((now - age <= max_age)); then
      pass "${name}" "last success ${timestamp}"
    else
      fail "${name}" "last success ${timestamp} is stale"
    fi
  else
    fail "${name}" "no recorded successful run"
  fi
}

check_disk() {
  local name="$1" path="$2" usage=''
  usage="$(df -P "${path}" | awk 'NR==2 {gsub(/%/, "", $5); print $5}')"
  if [[ "${usage}" =~ ^[0-9]+$ ]] && ((usage < disk_max_percent)); then
    pass "${name}" "${usage}% used on ${path}"
  else
    fail "${name}" "${usage:-unknown}% used on ${path} exceeds ${disk_max_percent}%"
  fi
}

check_success_age "gc-${service_user}" "bugabinga-gc@${service_user}.service" "${gc_max_age}"
check_success_age "gc-${ci_user}" "bugabinga-gc@${ci_user}.service" "${gc_max_age}"
check_success_age "gc-${toad_user}" "bugabinga-gc@${toad_user}.service" "${gc_max_age}"
check_success_age "gc-host" "bugabinga-gc-host.service" "${gc_max_age}"

update_trigger="$(user_shell "${service_user}" 'systemctl --user show podman-auto-update.timer --property=LastTriggerUSec --value')"
update_age=''
if [[ -n "${update_trigger}" ]] && update_age="$(date -d "${update_trigger}" +%s 2>/dev/null)"; then
  now="$(date +%s)"
  if ((now - update_age <= update_max_age)); then
    pass "auto-update" "last trigger ${update_trigger}"
  else
    fail "auto-update" "last trigger ${update_trigger} is stale"
  fi
else
  fail "auto-update" "no recorded trigger"
fi

if user_shell "${ci_user}" "podman image exists '${rollback_image}'" >/dev/null 2>&1; then
  pass "luci-rollback" "${rollback_image} exists"
else
  fail "luci-rollback" "${rollback_image} missing"
fi

check_disk "disk-data-ci" "/data/ci"
check_disk "disk-root" "/"

exit "$((failures > 0 ? 1 : 0))"