feat(uninstall): --skip-docker-images keeps the docker layer for fast reinstall
A full uninstall tears down the rootless daemon and removes the docker-install user's home, which destroys the WebUI image AND the build cache — so every reinstall's `docker build` runs from scratch (slow, re-pulls the base image + reinstalls deps). On a slow local box that dominates the iteration loop. --skip-docker-images on `init.sh ... uninstall` preserves the rootless docker layer: it still removes stale containers, the control plane, manager user, footprint and /docker, but keeps the daemon running, the docker-install user + home (image/layer cache), and the rootless sysctl drop-in. The following reinstall then finds rootless already set up and rebuilds the WebUI image from cache — fast. No effect on install. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
a42f2c6618
commit
50d11a7728
66
init.sh
66
init.sh
@ -10,11 +10,17 @@
|
|||||||
# --unattended Run in unattended mode (skip confirmations)
|
# --unattended Run in unattended mode (skip confirmations)
|
||||||
# --skip-os-update Skip operating system update
|
# --skip-os-update Skip operating system update
|
||||||
# --skip-prereqs Skip installing prerequisite apps
|
# --skip-prereqs Skip installing prerequisite apps
|
||||||
|
# --skip-docker-images On UNINSTALL: keep the rootless docker daemon, the
|
||||||
|
# docker-install user, and the image/build cache instead
|
||||||
|
# of tearing them down — so a following reinstall rebuilds
|
||||||
|
# the WebUI image from cache (fast) instead of from
|
||||||
|
# scratch. (No effect on install.)
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
# ./init.sh --random-password --local init
|
# ./init.sh --random-password --local init
|
||||||
# ./init.sh --random-password --local --unattended init
|
# ./init.sh --random-password --local --unattended init
|
||||||
# ./init.sh --random-password --local --skip-os-update --skip-prereqs init
|
# ./init.sh --random-password --local --skip-os-update --skip-prereqs init
|
||||||
|
# ./init.sh --unattended --skip-docker-images uninstall # keep docker layer
|
||||||
# ./init.sh init mypassword myuser mytoken https://github.com/user/repo.git
|
# ./init.sh init mypassword myuser mytoken https://github.com/user/repo.git
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -90,6 +96,7 @@ init_local_install=false
|
|||||||
init_unattended_mode=false
|
init_unattended_mode=false
|
||||||
init_skip_os_update=false
|
init_skip_os_update=false
|
||||||
init_skip_prereqs=false
|
init_skip_prereqs=false
|
||||||
|
init_skip_docker_images=false
|
||||||
|
|
||||||
install_param="init"
|
install_param="init"
|
||||||
sudo_user_name=libreportal
|
sudo_user_name=libreportal
|
||||||
@ -144,6 +151,13 @@ for ((i=1; i<=$#; i++)); do
|
|||||||
init_skip_prereqs=true
|
init_skip_prereqs=true
|
||||||
((init_shift_count++))
|
((init_shift_count++))
|
||||||
;;
|
;;
|
||||||
|
--skip-docker-images)
|
||||||
|
# On uninstall: preserve the rootless docker layer (daemon +
|
||||||
|
# docker-install user + image/build cache) so the next reinstall's
|
||||||
|
# `docker build` is cache-fast. Honored in runFullUninstall.
|
||||||
|
init_skip_docker_images=true
|
||||||
|
((init_shift_count++))
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -1305,6 +1319,13 @@ runFullUninstall()
|
|||||||
iuser=$(grep -h '^CFG_DOCKER_INSTALL_USER=' /docker/configs/general/general_docker_install 2>/dev/null | head -1 | cut -d= -f2 | awk '{print $1}')
|
iuser=$(grep -h '^CFG_DOCKER_INSTALL_USER=' /docker/configs/general/general_docker_install 2>/dev/null | head -1 | cut -d= -f2 | awk '{print $1}')
|
||||||
iuser="${iuser:-dockerinstall}"
|
iuser="${iuser:-dockerinstall}"
|
||||||
|
|
||||||
|
# --skip-docker-images: keep the rootless docker layer (the daemon, the
|
||||||
|
# "$iuser" user, the image/build cache + the rootless sysctl drop-in) instead
|
||||||
|
# of tearing it down, so a following reinstall's `docker build` is cache-fast
|
||||||
|
# instead of from-scratch. Everything else (control plane, manager, footprint,
|
||||||
|
# /docker) is still removed.
|
||||||
|
local keep_docker="${init_skip_docker_images:-false}"
|
||||||
|
|
||||||
isHeader "LibrePortal — FULL Uninstall"
|
isHeader "LibrePortal — FULL Uninstall"
|
||||||
isError "This PERMANENTLY removes EVERYTHING — there is no undo:"
|
isError "This PERMANENTLY removes EVERYTHING — there is no undo:"
|
||||||
echo " - all containers + images + the rootless docker setup"
|
echo " - all containers + images + the rootless docker setup"
|
||||||
@ -1317,6 +1338,10 @@ runFullUninstall()
|
|||||||
isNotice "LEFT IN PLACE: the docker engine, docker-compose, apt-installed deps,"
|
isNotice "LEFT IN PLACE: the docker engine, docker-compose, apt-installed deps,"
|
||||||
isNotice "and your SSH config (so you can't get locked out)."
|
isNotice "and your SSH config (so you can't get locked out)."
|
||||||
echo ""
|
echo ""
|
||||||
|
if [[ "$keep_docker" == "true" ]]; then
|
||||||
|
isNotice "--skip-docker-images: KEEPING the rootless docker daemon, the '$iuser' user, and the image/build cache (for a faster reinstall)."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
if [[ "$init_unattended_mode" == true ]]; then
|
if [[ "$init_unattended_mode" == true ]]; then
|
||||||
isNotice "Unattended mode — proceeding without the DELETE LIBREPORTAL prompt."
|
isNotice "Unattended mode — proceeding without the DELETE LIBREPORTAL prompt."
|
||||||
else
|
else
|
||||||
@ -1340,23 +1365,35 @@ runFullUninstall()
|
|||||||
# user's session (stops the rootless dockerd + any survivors).
|
# user's session (stops the rootless dockerd + any survivors).
|
||||||
local uid; uid=$(id -u "$iuser" 2>/dev/null)
|
local uid; uid=$(id -u "$iuser" 2>/dev/null)
|
||||||
if [[ -n "$uid" ]]; then
|
if [[ -n "$uid" ]]; then
|
||||||
|
# Remove stale containers either way — they bind-mount the about-to-be-
|
||||||
|
# wiped /docker. The images + build cache live in the user's home and are
|
||||||
|
# untouched by `docker rm`.
|
||||||
sudo -u "$iuser" env XDG_RUNTIME_DIR="/run/user/$uid" \
|
sudo -u "$iuser" env XDG_RUNTIME_DIR="/run/user/$uid" \
|
||||||
DOCKER_HOST="unix:///run/user/$uid/docker.sock" \
|
DOCKER_HOST="unix:///run/user/$uid/docker.sock" \
|
||||||
bash -c 'docker ps -aq | xargs -r docker rm -f' >/dev/null 2>&1 || true
|
bash -c 'docker ps -aq | xargs -r docker rm -f' >/dev/null 2>&1 || true
|
||||||
sudo -u "$iuser" env XDG_RUNTIME_DIR="/run/user/$uid" \
|
if [[ "$keep_docker" == "true" ]]; then
|
||||||
dockerd-rootless-setuptool.sh uninstall >/dev/null 2>&1 || true
|
isSuccessful "Removed containers; kept the rootless docker daemon + images for '$iuser'"
|
||||||
loginctl disable-linger "$iuser" >/dev/null 2>&1 || true
|
else
|
||||||
loginctl terminate-user "$iuser" >/dev/null 2>&1 || true
|
sudo -u "$iuser" env XDG_RUNTIME_DIR="/run/user/$uid" \
|
||||||
pkill -9 -u "$iuser" >/dev/null 2>&1 || true
|
dockerd-rootless-setuptool.sh uninstall >/dev/null 2>&1 || true
|
||||||
isSuccessful "Stopped containers + rootless docker for '$iuser'"
|
loginctl disable-linger "$iuser" >/dev/null 2>&1 || true
|
||||||
|
loginctl terminate-user "$iuser" >/dev/null 2>&1 || true
|
||||||
|
pkill -9 -u "$iuser" >/dev/null 2>&1 || true
|
||||||
|
isSuccessful "Stopped containers + rootless docker for '$iuser'"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. Remove the out-of-/docker footprint (see FOOTPRINT.md).
|
# 3. Remove the out-of-/docker footprint (see FOOTPRINT.md).
|
||||||
rm -f /usr/local/bin/libreportal
|
rm -f /usr/local/bin/libreportal
|
||||||
rm -rf /usr/local/lib/libreportal
|
rm -rf /usr/local/lib/libreportal
|
||||||
rm -f "/etc/sudoers.d/$mgr"
|
rm -f "/etc/sudoers.d/$mgr"
|
||||||
rm -f /etc/sysctl.d/99-libreportal-hardening.conf /etc/sysctl.d/99-libreportal-rootless.conf
|
# Keep the sysctl drop-ins when preserving docker — removing + reloading them
|
||||||
sysctl --system >/dev/null 2>&1
|
# would reset ip_unprivileged_port_start etc. out from under the still-running
|
||||||
|
# rootless daemon. (The reinstall re-adds them idempotently.)
|
||||||
|
if [[ "$keep_docker" != "true" ]]; then
|
||||||
|
rm -f /etc/sysctl.d/99-libreportal-hardening.conf /etc/sysctl.d/99-libreportal-rootless.conf
|
||||||
|
sysctl --system >/dev/null 2>&1
|
||||||
|
fi
|
||||||
rm -f /usr/local/bin/restic /usr/local/bin/kopia /usr/local/bin/ufw-docker
|
rm -f /usr/local/bin/restic /usr/local/bin/kopia /usr/local/bin/ufw-docker
|
||||||
rm -f /root/init.sh
|
rm -f /root/init.sh
|
||||||
isSuccessful "Removed the system-integration footprint"
|
isSuccessful "Removed the system-integration footprint"
|
||||||
@ -1370,15 +1407,22 @@ runFullUninstall()
|
|||||||
# `userdel -r` leaves the home behind ("user currently used"); rm -rf the
|
# `userdel -r` leaves the home behind ("user currently used"); rm -rf the
|
||||||
# home afterwards as a backstop.
|
# home afterwards as a backstop.
|
||||||
local u
|
local u
|
||||||
for u in "$mgr" "$iuser"; do
|
local users_to_remove=("$mgr")
|
||||||
|
[[ "$keep_docker" == "true" ]] || users_to_remove+=("$iuser")
|
||||||
|
for u in "${users_to_remove[@]}"; do
|
||||||
loginctl disable-linger "$u" >/dev/null 2>&1 || true
|
loginctl disable-linger "$u" >/dev/null 2>&1 || true
|
||||||
loginctl terminate-user "$u" >/dev/null 2>&1 || true
|
loginctl terminate-user "$u" >/dev/null 2>&1 || true
|
||||||
pkill -9 -u "$u" >/dev/null 2>&1 || true
|
pkill -9 -u "$u" >/dev/null 2>&1 || true
|
||||||
userdel -r "$u" >/dev/null 2>&1 || true
|
userdel -r "$u" >/dev/null 2>&1 || true
|
||||||
[[ -n "$u" ]] && rm -rf "/home/$u"
|
[[ -n "$u" ]] && rm -rf "/home/$u"
|
||||||
done
|
done
|
||||||
sed -i "/^${mgr}:/d;/^${iuser}:/d" /etc/subuid /etc/subgid 2>/dev/null || true
|
if [[ "$keep_docker" == "true" ]]; then
|
||||||
isSuccessful "Removed users '$mgr' + '$iuser' (+ home dirs)"
|
sed -i "/^${mgr}:/d" /etc/subuid /etc/subgid 2>/dev/null || true
|
||||||
|
isSuccessful "Removed user '$mgr' (+ home); kept '$iuser' + its docker image store"
|
||||||
|
else
|
||||||
|
sed -i "/^${mgr}:/d;/^${iuser}:/d" /etc/subuid /etc/subgid 2>/dev/null || true
|
||||||
|
isSuccessful "Removed users '$mgr' + '$iuser' (+ home dirs)"
|
||||||
|
fi
|
||||||
|
|
||||||
isHeader "LibrePortal uninstalled"
|
isHeader "LibrePortal uninstalled"
|
||||||
isNotice "Left in place: docker engine, docker-compose, apt deps, SSH config."
|
isNotice "Left in place: docker engine, docker-compose, apt deps, SSH config."
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user