wrolpi/help.sh

514 lines
17 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
MEDIA_DIRECTORY=/media/wrolpi
# Source environment file after declaring globals.
[ -f /opt/wrolpi/.env ] && source /opt/wrolpi/.env
# Re-execute this script if it wasn't called with sudo.
if [ $EUID != 0 ]; then
sudo "$0" "$@"
exit $?
fi
function check_directory() {
directory=$1
good_message=$2
bad_message=$3
if [ -d "${directory}" ]; then
echo "OK: ${good_message}"
else
echo "FAILED: ${bad_message}"
fi
}
function check_file() {
file=$1
good_message=$2
bad_message=$3
if [ -f "${file}" ]; then
echo "OK: ${good_message}"
else
echo "FAILED: ${bad_message}"
fi
}
echo
echo "WROLPi version: $(cat /opt/wrolpi/wrolpi/version.txt)"
echo
rpi=false
rpi4=false
rpi5=false
debian12=false
grep -q 'Raspberry Pi' /proc/cpuinfo >/dev/null && rpi=true
grep -q 'Raspberry Pi 4' /proc/cpuinfo >/dev/null && rpi4=true
grep -q 'Raspberry Pi 5' /proc/cpuinfo >/dev/null && rpi5=true
grep -q 'PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"' /etc/os-release >/dev/null && debian12=true
if [[ ${rpi4} == true ]]; then
echo 'OK: Running on Raspberry Pi 4'
elif [[ ${rpi5} == true ]]; then
echo 'OK: Running on Raspberry Pi 5'
elif [[ ${rpi} == true ]]; then
echo 'OK: Running on unknown Raspberry Pi'
elif [[ ${debian12} == true ]]; then
echo 'OK: Running on Debian 12'
else
echo "FAILED: Running on unknown operating system"
fi
if dmesg | grep -q 'Undervoltage detected' >/dev/null 2>&1; then
echo 'FAILED: Under voltage detected! Use a more powerful power supply.'
fi
if dmesg | grep -q 'over-current change' >/dev/null 2>&1; then
echo 'FAILED: Over current detected! Your peripherals are using too much power!'
fi
if id -u wrolpi >/dev/null 2>&1; then
echo "OK: Found wrolpi user"
else
echo "FAILED: No wrolpi user found"
fi
check_directory /opt/wrolpi "The WROLPi directory exists" "The WROLPi directory does not exist at /opt/wrolpi"
check_directory /opt/wrolpi-blobs "The WROLPi blobs directory exists" "The WROLPi blobs directory does not exist at /opt/wrolpi-blobs"
check_file /opt/wrolpi/main.py "The WROLPi main script exists" "The WROLPi main script does not exist at /opt/wrolpi/main.py"
check_file ${MEDIA_DIRECTORY}/config/wrolpi.yaml "The WROLPi config file exists" "The WROLPi config file does not exist"
echo
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
# Database (SQLite in the media directory)
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
WROLPI_DB="${MEDIA_DIRECTORY}/config/wrolpi.db"
if [ -f "${WROLPI_DB}" ]; then
echo "OK: Found wrolpi database at ${WROLPI_DB}"
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
if command -v sqlite3 >/dev/null 2>&1; then
# Run as the wrolpi user: a read of a WAL database needs write access to
# the -shm sidecar, which root-created files would break for the API.
wrolpi_sqlite() {
sudo -u wrolpi sqlite3 "${WROLPI_DB}" "$@" 2>/dev/null
}
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
if [ "$(wrolpi_sqlite 'PRAGMA quick_check;' | head -1)" = "ok" ]; then
echo "OK: WROLPi database passes quick_check"
else
echo "FAILED: WROLPi database is corrupt or unreadable (PRAGMA quick_check)"
fi
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
if wrolpi_sqlite ".tables" | grep -q "file_group"; then
echo "OK: WROLPi database is initialized"
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
if [ "$(wrolpi_sqlite 'select count(*) from file_group;')" -gt 0 ] 2>/dev/null; then
echo "OK: WROLPi database has files"
else
echo "FAILED: WROLPi database has no files. You need to refresh your files: https://$(hostname).local/files"
fi
else
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
echo "FAILED: WROLPi is not initialized"
fi
else
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
echo "Note: sqlite3 CLI not installed; skipping database integrity checks"
fi
else
Debian 13 (trixie) rebase: docker, debian-live-config, and pi-gen builds. All three build targets move from Debian 12/bookworm to Debian 13/trixie for fresh installs; existing Debian 12 systems remain supported in place. Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie, app on node:20-trixie (matches trixie's nodejs 20), samba/zim on debian:13. Full backend suite passes on Python 3.13 in the api container. debian-live-config: --distribution trixie; postgres teardown for the SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no longer creates a cluster or calls the deleted initialize_api_db.sh — the API creates wrolpi.db itself on first start). README documents the SQLite layout and drops Etcher recommendations. pi-gen: upstream has no trixie branch — the arm64 branch now defaults to RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres .pgpass into /etc/skel. Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common and cpufrequtils removed from trixie (Controller CPU throttle falls back to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added (no longer arrive transitively under --apt-recommends false); sqlite3 CLI added for reset_tags.sh. help.sh: replace the Postgres service/port/socket/cluster/psql checks (all false FAILEDs after the SQLite cutover) with SQLite checks: wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run as the wrolpi user so root never creates the -shm sidecar. Both build scripts take a WROLPI_BUILD_DIR override so development builds can run beside the release pipeline's build trees; the sudo re-exec passes it through explicitly (a plain sudo would drop it). test_common.py: the truncate tests hard-coded sys.getsizeof results from the 3.11 object layout (str/list shrank in 3.12); assert the contract (fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13. Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built from scratch and passed their sanity checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:16:00 -06:00
echo "FAILED: Unable to find wrolpi database at ${WROLPI_DB} (the API creates it on first start)"
fi
echo
# Controller
if [ -f /opt/wrolpi/controller/venv/bin/python3 ]; then
echo "OK: Controller Python virtual environment exists"
if /opt/wrolpi/controller/venv/bin/python3 --version 2>/dev/null > /dev/null; then
echo 'OK: Controller Python can be run'
else
echo "FAILED: Controller Python could not be run"
fi
else
echo "FAILED: Controller Python virtual environment does not exist"
fi
if systemctl list-unit-files "*wrolpi-controller*" >/dev/null 2>&1; then
echo "OK: WROLPi Controller systemd exists"
else
echo "FAILED: WROLPi Controller systemd does not exist"
fi
if [ -f /etc/systemd/system/wrolpi-controller.service ]; then
if systemctl status wrolpi-controller.service >/dev/null 2>&1; then
echo "OK: WROLPi Controller service is up"
else
echo "FAILED: WROLPi Controller service is not up"
fi
fi
if curl -s http://0.0.0.0:80/api/health --max-time 5 >/dev/null 2>&1; then
echo "OK: WROLPi Controller health check passed"
else
echo "FAILED: WROLPi Controller health check failed"
fi
# WROL Mode status
if [ -f /media/wrolpi/config/.wrol_mode ]; then
echo "Note: WROL Mode is ACTIVE"
else
echo "OK: WROL Mode is inactive"
fi
echo
# API
if [ -f /opt/wrolpi/venv/bin/python3 ]; then
echo "OK: WROLPi Python virtual environment exists"
2023-11-23 17:02:03 -07:00
if /opt/wrolpi/venv/bin/python3 /opt/wrolpi/main.py -h 2>/dev/null > /dev/null; then
echo 'OK: WROLPi main can be run'
else
echo "FAILED: WROLPi main could not be run"
fi
if /opt/wrolpi/venv/bin/sanic --help 2>/dev/null > /dev/null; then
echo 'OK: Sanic can be run'
else
echo "FAILED: Sanic could not be run"
fi
else
echo "FAILED: WROLPi Python virtual environment does not exist"
fi
if systemctl list-unit-files "*wrolpi-api*" >/dev/null; then
echo "OK: WROLPi API systemd exists"
else
echo "FAILED: WROLPi API systemd does not exist"
fi
if [ -f /etc/systemd/system/wrolpi-api.service ]; then
if systemctl status wrolpi-api.service >/dev/null; then
echo "OK: WROLPi API service is up"
else
echo "FAILED: WROLPi API service is not up"
fi
fi
if curl -s http://0.0.0.0:8081/api/echo --max-time 5 | grep -i '"method":"GET"' >/dev/null; then
echo "OK: WROLPi API echoed correctly"
else
echo "FAILED: WROLPi API did not echo correctly"
fi
echo
# Webapp
if [ -d /opt/wrolpi/app ]; then
echo "OK: WROLPi app directory exists"
if (cd /opt/wrolpi/app && npm ls >/dev/null 2>&1); then
echo "OK: WROLPi app exists"
else
echo "FAILED: WROLPi app does not exist"
fi
else
echo "FAILED: WROLPi app directory does not exist"
fi
if systemctl list-unit-files "*wrolpi-app*" >/dev/null; then
echo "OK: WROLPi app systemd exists"
else
echo "FAILED: WROLPi app systemd does not exist"
fi
if [ -f /etc/systemd/system/wrolpi-app.service ]; then
if systemctl status wrolpi-app.service >/dev/null; then
echo "OK: WROLPi app service is up"
else
echo "FAILED: WROLPi app service is not up"
fi
fi
if curl -s http://0.0.0.0:3000 --max-time 5 | grep -i wrolpi >/dev/null; then
2024-10-01 11:29:57 -06:00
echo "OK: WROLPi app responded with UI"
else
2024-10-01 11:29:57 -06:00
echo "FAILED: WROLPi app did not respond with UI"
fi
if curl -s http://0.0.0.0:3000/epub/epub.html --max-time 5 | grep -i epub.js >/dev/null; then
2024-10-01 11:29:57 -06:00
echo "OK: WROLPi app responded with ebook interface"
else
echo "FAILED: WROLPi app did not respond with ebook interface"
fi
echo
# Caddy
if command -v caddy &>/dev/null; then
echo "OK: Caddy is installed ($(caddy version 2>/dev/null | head -1))"
else
echo "FAILED: Caddy is not installed"
fi
if systemctl list-unit-files "*caddy*" >/dev/null 2>&1; then
echo "OK: Caddy systemd exists"
if systemctl status caddy >/dev/null 2>&1; then
echo "OK: Caddy service is running"
else
echo "FAILED: Caddy service is not running"
fi
else
echo "FAILED: Caddy systemd does not exist"
fi
check_file /etc/caddy/Caddyfile "Caddyfile exists" "Caddyfile does not exist at /etc/caddy/Caddyfile"
check_file /etc/ssl/wrolpi/cert.crt "TLS certificate exists" "TLS certificate does not exist at /etc/ssl/wrolpi/cert.crt"
check_file /etc/ssl/wrolpi/cert.key "TLS key exists" "TLS key does not exist at /etc/ssl/wrolpi/cert.key"
check_file ${MEDIA_DIRECTORY}/config/ssl/ca.crt "Root CA certificate exists" "Root CA certificate does not exist at ${MEDIA_DIRECTORY}/config/ssl/ca.crt"
check_file ${MEDIA_DIRECTORY}/config/ssl/ca.key "Root CA key exists" "Root CA key does not exist at ${MEDIA_DIRECTORY}/config/ssl/ca.key"
if [ -f ${MEDIA_DIRECTORY}/config/ssl/ca.crt ] && [ -f /etc/ssl/wrolpi/cert.crt ]; then
if openssl verify -CAfile ${MEDIA_DIRECTORY}/config/ssl/ca.crt /etc/ssl/wrolpi/cert.crt >/dev/null 2>&1; then
echo "OK: Leaf certificate is signed by root CA"
else
echo "FAILED: Leaf certificate is NOT signed by root CA (regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
fi
fi
if [ -f ${MEDIA_DIRECTORY}/config/ssl/ca.crt ]; then
if ! openssl x509 -noout -in ${MEDIA_DIRECTORY}/config/ssl/ca.crt >/dev/null 2>&1; then
echo "FAILED: Root CA certificate cannot be parsed (regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
elif ! openssl x509 -checkend 0 -noout -in ${MEDIA_DIRECTORY}/config/ssl/ca.crt >/dev/null 2>&1; then
echo "FAILED: Root CA certificate is expired (delete ${MEDIA_DIRECTORY}/config/ssl and regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
else
echo "OK: Root CA certificate is valid (expires $(openssl x509 -enddate -noout -in ${MEDIA_DIRECTORY}/config/ssl/ca.crt | cut -d= -f2))"
fi
fi
if [ -f /etc/ssl/wrolpi/cert.crt ]; then
if ! openssl x509 -noout -in /etc/ssl/wrolpi/cert.crt >/dev/null 2>&1; then
echo "FAILED: TLS certificate cannot be parsed (regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
elif ! openssl x509 -checkend 0 -noout -in /etc/ssl/wrolpi/cert.crt >/dev/null 2>&1; then
echo "FAILED: TLS certificate is expired (regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
elif ! openssl x509 -checkend 2592000 -noout -in /etc/ssl/wrolpi/cert.crt >/dev/null 2>&1; then
echo "Note: TLS certificate expires within 30 days ($(openssl x509 -enddate -noout -in /etc/ssl/wrolpi/cert.crt | cut -d= -f2))"
else
echo "OK: TLS certificate is valid (expires $(openssl x509 -enddate -noout -in /etc/ssl/wrolpi/cert.crt | cut -d= -f2))"
fi
if openssl x509 -in /etc/ssl/wrolpi/cert.crt -noout -checkhost "$(hostname).local" 2>/dev/null | grep -q "does match certificate"; then
echo "OK: TLS certificate covers $(hostname).local"
else
echo "FAILED: TLS certificate does not cover $(hostname).local (was the hostname changed? regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
fi
fi
if [ -f /etc/ssl/wrolpi/cert.crt ] && [ -f /etc/ssl/wrolpi/cert.key ]; then
cert_pubkey=$(openssl x509 -in /etc/ssl/wrolpi/cert.crt -noout -pubkey 2>/dev/null)
key_pubkey=$(openssl pkey -in /etc/ssl/wrolpi/cert.key -pubout 2>/dev/null)
if [ -n "${cert_pubkey}" ] && [ "${cert_pubkey}" = "${key_pubkey}" ]; then
echo "OK: TLS certificate matches its private key"
else
echo "FAILED: TLS certificate does not match its private key (regenerate with /opt/wrolpi/scripts/generate_certificates.sh)"
fi
fi
# Compare the certificate Caddy is actually serving to the one on disk. A mismatch means
# Caddy was not reloaded after the certificate was regenerated.
if [ -f /etc/ssl/wrolpi/cert.crt ]; then
served_fingerprint=$(echo | timeout 5 openssl s_client -connect 127.0.0.1:443 2>/dev/null | openssl x509 -noout -fingerprint -sha256 2>/dev/null)
disk_fingerprint=$(openssl x509 -in /etc/ssl/wrolpi/cert.crt -noout -fingerprint -sha256 2>/dev/null)
if [ -z "${served_fingerprint}" ]; then
echo "FAILED: Could not fetch the TLS certificate being served on port 443"
elif [ "${served_fingerprint}" = "${disk_fingerprint}" ]; then
echo "OK: Caddy is serving the TLS certificate on disk"
else
echo "FAILED: Caddy is serving a different TLS certificate than the one on disk (reload with: systemctl reload caddy)"
fi
fi
if [ -x /opt/wrolpi/scripts/renew_certificates.sh ]; then
echo "OK: Certificate renewal script is executable"
else
echo "FAILED: Certificate renewal script is not executable (fix with: chmod +x /opt/wrolpi/scripts/renew_certificates.sh)"
fi
if systemctl is-enabled wrolpi-cert-renew.timer >/dev/null 2>&1; then
echo "OK: Certificate renewal timer is enabled"
else
echo "FAILED: Certificate renewal timer is not enabled (fix with: systemctl enable --now wrolpi-cert-renew.timer)"
fi
# Port 80 belongs to the Controller (checked above); Caddy proxies to it.
for port in 443 8084 8085 8086; do
if netstat -ant | grep LISTEN | grep -E "(0\.0\.0\.0:|:::)${port}\b" >/dev/null; then
echo "OK: Caddy port ${port} is occupied"
else
echo "FAILED: Caddy port ${port} is not occupied"
fi
done
if curl -k -s https://0.0.0.0/ --max-time 5 | grep -i wrolpi >/dev/null; then
echo "OK: Caddy HTTPS proxy responded on :443"
else
echo "FAILED: Caddy HTTPS proxy did not respond on :443"
fi
echo
# Map
if curl -k -s https://0.0.0.0:8084 --max-time 5 2>/dev/null | grep -i "WROLPi Map" >/dev/null; then
echo "OK: Map viewer responded"
else
echo "FAILED: Map viewer did not respond on port 8084"
fi
check_directory /opt/wrolpi/modules/map/static "Map static assets exist" "Map static assets missing at /opt/wrolpi/modules/map/static"
if ls /media/wrolpi/map/*.pmtiles >/dev/null 2>&1; then
echo "OK: Found $(ls /media/wrolpi/map/*.pmtiles 2>/dev/null | wc -l | tr -d ' ') PMTiles map files"
else
echo "Note: No PMTiles map files found in /media/wrolpi/map/"
fi
if [ -f /opt/wrolpi/.protomaps_installed ]; then
echo "OK: Protomaps migration completed"
else
echo "Note: Protomaps migration has not been run (old map stack may still be active)"
fi
echo
# Kiwix
check_file /media/wrolpi/zims/library.xml "The kiwix library file exists" "The kiwix library file does not exist at /media/wrolpi/zims/library.xml"
if curl -k -s https://0.0.0.0:8085 --max-time 5 2>/dev/null | grep -i kiwix >/dev/null; then
echo "OK: Kiwix app responded"
else
echo "FAILED: Kiwix app did not respond"
fi
echo
# Media Directory
check_directory "${MEDIA_DIRECTORY}" "The media directory exists" "The media directory does not exist at ${MEDIA_DIRECTORY}"
if [ -d "${MEDIA_DIRECTORY}" ] && [ -d ${MEDIA_DIRECTORY}/config ]; then
if touch ${MEDIA_DIRECTORY}/config; then
echo "OK: Can modify media directory"
else
echo "FAILED: Cannot modify media directory"
fi
fi
if grep -qs "${MEDIA_DIRECTORY}" /proc/mounts >/dev/null 2>&1 ; then
echo "OK: Media directory is a mounted drive"
else
echo "FAILED: Media directory is not a mounted drive. (This is fine if you don't have an external drive.)"
fi
if curl -k -s https://0.0.0.0/media/ --max-time 5 | grep -i "media" >/dev/null; then
echo "OK: Media directory files are served by caddy"
if curl -k -s -I https://0.0.0.0/media/config/wrolpi.yaml --max-time 5 | grep -E '200( OK)?' >/dev/null; then
echo "OK: Config can be fetched from caddy"
else
echo "FAILED: Media directory files are not being served"
fi
else
echo "FAILED: Media directory files are not being served"
fi
if curl -k -s -I https://0.0.0.0/download/ --max-time 5 | grep -E '200( OK)?' >/dev/null; then
echo "OK: Media download directory files are served by caddy"
if curl -k -s -I https://0.0.0.0/download/config/wrolpi.yaml --max-time 5 | grep -E '200( OK)?' >/dev/null; then
echo "OK: Config can be downloaded from caddy"
2024-10-01 11:29:57 -06:00
else
echo "FAILED: Media download directory files are not being served"
fi
else
echo "FAILED: Media download directory files are not being served"
fi
if [ "$(stat -c '%U' /media/wrolpi/)" == 'wrolpi' ]; then
echo "OK: Media directory is owned by wrolpi user"
else
echo "FAILED: Media directory is not owned by wrolpi user"
fi
echo
# 3rd party commands
if single-file -h >/dev/null 2>&1; then
echo "OK: Singlefile can be run"
else
echo "FAILED: Singlefile cannot be run"
fi
if [ -f /usr/bin/readability-extractor ]; then
echo "OK: readability exists"
else
if [ -f /usr/local/bin/readability-extractor ]; then
echo "OK: readability exists"
else
echo "FAILED: readability does not exist"
fi
fi
if wget -h >/dev/null 2>&1; then
echo "OK: wget can be run"
else
echo "FAILED: wget cannot be run"
fi
if aria2c -h >/dev/null 2>&1; then
echo "OK: aria2c can be run"
else
echo "FAILED: aria2c cannot be run"
fi
if /opt/wrolpi/venv/bin/yt-dlp -h >/dev/null 2>&1; then
echo "OK: yt-dlp can be run"
else
echo "FAILED: yt-dlp cannot be run"
fi
if chromium-browser -h >/dev/null 2>&1; then
echo "OK: Chromium can be run"
else
if chromium -h >/dev/null 2>&1; then
echo "OK: Chromium can be run"
else
echo "FAILED: Chromium cannot be run"
fi
fi
if ffmpeg -h >/dev/null 2>&1; then
echo "OK: ffmpeg can be run"
else
echo "FAILED: ffmpeg cannot be run"
fi
2023-11-23 17:02:03 -07:00
echo
# Help Service
if /opt/wrolpi-help/venv/bin/mkdocs --help &>/dev/null; then
echo "OK: Help mkdocs can be run"
else
echo "FAILED: Help mkdocs cannot be run"
fi
if curl -k -s https://0.0.0.0:8086/ --max-time 5 | grep MkDocs 2>/dev/null >/dev/null; then
2023-11-23 17:02:03 -07:00
echo "OK: Help service is running"
else
echo "FAILED: Help service is not running"
fi
echo
# Internet
if ping -c1 1.1.1.1 -W 5 &>/dev/null; then
echo "OK: Can ping 1.1.1.1"
else
echo "FAILED: Cannot ping 1.1.1.1. Is internet working?"
fi
if ping -c1 one.one.one.one -W 5 &>/dev/null; then
echo "OK: Can ping one.one.one.one"
else
echo "FAILED: Cannot ping one.one.one.one Is internet working?"
fi