feat(uninstall): location-agnostic 'libreportal-uninstall' command (+ de-hardcode docs)

The docs were telling users to run /libreportal-system/install/uninstall.sh — a
hardcoded data path, wrong for any custom --system-dir, contradicting the whole
relocatable design.

Fix it the way the CLI already works: install uninstall.sh to the FIXED footprint
(/usr/local/lib/libreportal/uninstall.sh) and symlink it onto $PATH as
'libreportal-uninstall' (initLibrePortalCommand). It self-resolves the real data
roots from the systemd unit, so the command is the same everywhere regardless of
where data lives. Teardown removes the new symlink; FOOTPRINT.md lists it.

Docs now say 'sudo libreportal-uninstall' — no data path. (Dev-from-clone still
uses ./uninstall.sh / ./init.sh uninstall.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
librelad 2026-05-25 18:50:26 +01:00
parent 55dd62af56
commit 8472fdf0ae
3 changed files with 18 additions and 8 deletions

View File

@ -28,6 +28,7 @@ together in **`/usr/local/lib/libreportal/`**; everything else is named
| File | Owner | Purpose |
|------|-------|---------|
| `libreportal` | root | the CLI wrapper (symlinked onto `$PATH`, see below) |
| `uninstall.sh` | root | the uninstaller (symlinked onto `$PATH` as `libreportal-uninstall`) |
| `libreportal-ownership` | root | reconcile the three-root ownership model |
| `libreportal-dns` | root | edit `/etc/resolv.conf` (nameservers) |
| `libreportal-ssh-access` | root | manage admin `authorized_keys` + sshd `PasswordAuthentication` |
@ -47,6 +48,7 @@ quick-deploy).
| Path | Owner | Purpose |
|------|-------|---------|
| `/usr/local/bin/libreportal` | root | **symlink**`/usr/local/lib/libreportal/libreportal` (puts the CLI on `$PATH`) |
| `/usr/local/bin/libreportal-uninstall` | root | **symlink**`/usr/local/lib/libreportal/uninstall.sh` (location-agnostic uninstall command) |
| `/etc/sudoers.d/<manager>` | root | scoped least-privilege grant for the manager (drop-in named after the manager user) |
| `/etc/systemd/system/libreportal.service` | root | the task-processor service (`User=<manager>`; bakes the roots as `Environment=LP_*_DIR`) |
| `/etc/sysctl.d/99-libreportal-hardening.conf` | root | kernel LPE-surface hardening |
@ -73,7 +75,7 @@ config lives at `~<container-user>/.config/docker/daemon.json`.
sudo systemctl disable --now libreportal.service
sudo rm -f /etc/systemd/system/libreportal.service /etc/sudoers.d/libreportal
sudo rm -f /etc/sysctl.d/99-libreportal-*.conf
sudo rm -rf /usr/local/lib/libreportal /usr/local/bin/libreportal
sudo rm -rf /usr/local/lib/libreportal /usr/local/bin/libreportal /usr/local/bin/libreportal-uninstall
sudo rm -rf /libreportal-system /libreportal-containers /libreportal-backups
# optional: the backup-engine binaries and the two users
```

View File

@ -85,15 +85,15 @@ the required ownership and will warn.
## Uninstall
```bash
sudo /libreportal-system/install/uninstall.sh
sudo libreportal-uninstall
# keep the rootless Docker layer + image cache for a fast reinstall:
sudo /libreportal-system/install/uninstall.sh --skip-docker-images
sudo libreportal-uninstall --skip-docker-images
```
`uninstall.sh` finds your install automatically (even with custom roots — it reads
the real locations from the installed service) and removes the three roots, the
system users, and the small out-of-tree footprint (`/usr/local/lib/libreportal`,
the `/etc` integration files). `sudo init.sh uninstall` does the same thing.
`libreportal-uninstall` is a fixed command on `$PATH` (no data path to type — it
reads the real install locations from the installed service, so it works even with
custom roots). It removes the three roots, the system users, and the small
out-of-tree footprint (`/usr/local/lib/libreportal`, the `/etc` integration files).
> ⚠️ Uninstall permanently deletes all app data, configs, and the database. Take a
> backup first if you want to keep anything.

10
init.sh
View File

@ -1467,6 +1467,14 @@ EOF
sudo chown root:root $command_script
# Put it on $PATH via a symlink (replaces any older real file at this path).
sudo ln -sfn "$command_script" "$command_symlink"
# Install the uninstaller at the fixed footprint + put it on $PATH as
# `libreportal-uninstall` — a location-agnostic command (it resolves the real
# data roots from the systemd unit at run time), so users never type a data path.
if [[ -f "$script_dir/uninstall.sh" ]]; then
sudo install -m 0755 -o root -g root "$script_dir/uninstall.sh" "$lp_lib_dir/uninstall.sh"
sudo ln -sfn "$lp_lib_dir/uninstall.sh" /usr/local/bin/libreportal-uninstall
fi
source $sudo_bashrc
}
@ -1643,7 +1651,7 @@ runFullUninstall()
fi
# 3. Remove the out-of-/docker footprint (see docs/FOOTPRINT.md).
rm -f /usr/local/bin/libreportal
rm -f /usr/local/bin/libreportal /usr/local/bin/libreportal-uninstall
rm -rf /usr/local/lib/libreportal
rm -f "/etc/sudoers.d/$mgr"
# Keep the sysctl drop-ins when preserving docker — removing + reloading them