diff --git a/init.sh b/init.sh index 7e75d7f..4321a42 100755 --- a/init.sh +++ b/init.sh @@ -1545,8 +1545,32 @@ completeInitMessage() # systemd --user service, so stop those BEFORE removing the users. Self-contained: # uses only init.sh's inline helpers, so it still works as it deletes /docker. # Keep in sync with docs/FOOTPRINT.md. +# Discover where THIS box was actually installed — custom installs put the roots +# anywhere, and a bare `init.sh uninstall` has no LP_*_DIR in scope. The systemd +# unit is the authoritative baked record (Environment=LP_*_DIR + User=). +# Sets LP_*_DIR + sudo_user_name so the following libreportalDerivePaths resolves +# the real locations; silently no-ops on a legacy unit (then the derive defaults / +# /docker compat shim apply). +libreportalReadBakedRoots() { + local unit=/etc/systemd/system/libreportal.service + [[ -f "$unit" ]] || return 0 + local s c b m + s=$(grep -oE 'LP_SYSTEM_DIR=\S+' "$unit" | head -1 | cut -d= -f2) + c=$(grep -oE 'LP_CONTAINERS_DIR=\S+' "$unit" | head -1 | cut -d= -f2) + b=$(grep -oE 'LP_BACKUPS_DIR=\S+' "$unit" | head -1 | cut -d= -f2) + m=$(grep -oE '^User=\S+' "$unit" | head -1 | cut -d= -f2) + [[ -n "$s" ]] && LP_SYSTEM_DIR="$s" + [[ -n "$c" ]] && LP_CONTAINERS_DIR="$c" + [[ -n "$b" ]] && LP_BACKUPS_DIR="$b" + [[ -n "$m" ]] && { LP_MANAGER_USER="$m"; sudo_user_name="$m"; } +} + runFullUninstall() { + # Resolve the ACTUAL install roots/manager for this box before removing anything. + libreportalReadBakedRoots + libreportalDerivePaths + local mgr="${sudo_user_name:-libreportal}" local iuser iuser=$(grep -h '^CFG_DOCKER_INSTALL_USER=' "${configs_dir}general/general_docker_install" 2>/dev/null | head -1 | cut -d= -f2 | awk '{print $1}') diff --git a/uninstall.sh b/uninstall.sh new file mode 100644 index 0000000..59bc1de --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# +# LibrePortal uninstaller — convenience launcher. +# +# sudo ./uninstall.sh # remove everything +# sudo ./uninstall.sh --skip-docker-images # keep the rootless docker layer +# +# The real teardown lives in init.sh (runFullUninstall), which self-resolves the +# install's actual roots/manager from the baked systemd unit — so this just finds +# the installed init.sh and runs it. Works regardless of where LibrePortal was +# installed (custom --system-dir, etc.). +set -euo pipefail + +[[ $EUID -eq 0 ]] || { echo "uninstall.sh must run as root (try: sudo)" >&2; exit 1; } + +# Prefer the system root baked into the systemd unit; then common defaults; then +# the bootstrap copy in /root; then a sibling init.sh next to this script. +unit=/etc/systemd/system/libreportal.service +sysdir="" +[[ -f "$unit" ]] && sysdir=$(grep -oE 'LP_SYSTEM_DIR=\S+' "$unit" | head -1 | cut -d= -f2) + +init="" +for cand in \ + ${sysdir:+"$sysdir/install/init.sh"} \ + /libreportal-system/install/init.sh \ + /docker/install/init.sh \ + /root/init.sh \ + "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/init.sh"; do + [[ -n "$cand" && -f "$cand" ]] && { init="$cand"; break; } +done + +[[ -n "$init" ]] || { echo "uninstall.sh: could not find init.sh to run the uninstall." >&2; exit 1; } + +echo "Running uninstall via $init ..." +exec bash "$init" "$@" uninstall