Two small uninstall-output tweaks. 1. dockerComposeDownRemove now ALWAYS calls dockerRemoveApp (the `docker ps -aqf name=…` → stop + rm sweep) as a fallback, even when the compose-down step is skipped because the app dir is missing. Before, a partial prior uninstall (compose file gone but containers still running) produced "App directory not found. Skipping container shutdown." and then proceeded as if the uninstall were complete — leaving the actual containers running. The name-based sweep also runs after a successful compose-down to catch anything compose wouldn't pick up (renamed services, orphans from earlier failures). While here: the OS_TYPE gate (only Ubuntu/Debian) is gone too — `docker compose down` works on any OS with docker, and gating it meant Arch/etc. users got NO compose teardown at all. 2. The step-2 header "Keeping Docker images (pass --delete-images to remove)" trimmed to just "Keeping Docker images". The `isNotice` line below already explains the reuse-on-reinstall behaviour; the CLI-flag hint reads as noise in the WebUI task log where users can't act on it anyway. CLI users can still pass --delete-images (cli_app_commands.sh wires it as before) or tick the WebUI's "Also delete docker image" checkbox. Signed-off-by: librelad <librelad@digitalangels.vip>
127 lines
4.8 KiB
Bash
Executable File
127 lines
4.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
dockerUninstallApp()
|
|
{
|
|
local app_name="$1"
|
|
# Optional: delete the app's docker images too. Default false so a
|
|
# plain `libreportal app uninstall <app>` keeps cached images for a
|
|
# quick reinstall. The WebUI's Uninstall modal exposes this as the
|
|
# "Also delete docker image" checkbox.
|
|
local delete_images="${2:-false}"
|
|
local delete_tasks="${3:-false}"
|
|
local stored_app_name=$app_name
|
|
|
|
if [[ "$stored_app_name" == "" ]]; then
|
|
isError "No app_name provided, unable to continue..."
|
|
else
|
|
isHeader "Uninstalling $stored_app_name"
|
|
initializeAppVariables $stored_app_name;
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Removing app where docker compose is installed"
|
|
echo ""
|
|
|
|
dockerComposeDownRemove $stored_app_name;
|
|
|
|
# App-specific uninstall hook. Host-installed apps (and any app needing
|
|
# teardown beyond the generic docker/DB cleanup) define an uninstall<App>
|
|
# function — it runs the app-specific bits (apt purge, systemd units,
|
|
# cscli state, ...) while the shared compose/data/DB/WebUI teardown below
|
|
# stays generic. The CLI and menu both route uninstalls through here, so
|
|
# this is the single point every uninstall passes through.
|
|
local app_name_ucfirst="$(tr '[:lower:]' '[:upper:]' <<< ${stored_app_name:0:1})${stored_app_name:1}"
|
|
local uninstallFuncName="uninstall${app_name_ucfirst}"
|
|
if declare -f "$uninstallFuncName" >/dev/null 2>&1; then
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Running $stored_app_name-specific uninstall steps"
|
|
echo ""
|
|
"$uninstallFuncName"
|
|
fi
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
if [[ "$delete_images" == "true" ]]; then
|
|
echo "---- $menu_number. Removing Docker images for the app"
|
|
echo ""
|
|
dockerRemoveAppImages $stored_app_name;
|
|
else
|
|
echo "---- $menu_number. Keeping Docker images"
|
|
echo ""
|
|
isNotice "Docker images for '$stored_app_name' left in place. A reinstall will reuse them."
|
|
fi
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Deleting all app data from docker folder"
|
|
echo ""
|
|
|
|
dockerDeleteData $stored_app_name;
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Removing unused Docker networks."
|
|
echo ""
|
|
|
|
dockerPruneAppNetworks $stored_app_name;
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Removing app from the database"
|
|
echo ""
|
|
|
|
ipRemoveFromDatabase $stored_app_name;
|
|
portsRemoveFromDatabase $stored_app_name;
|
|
databaseUninstallApp $stored_app_name;
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Updating the WebUI config file."
|
|
echo ""
|
|
|
|
webuiContainerSetup $stored_app_name uninstall;
|
|
|
|
# A removed app may have been routed through a network gateway (e.g.
|
|
# gluetun); let each provider refresh its forwarded-port registration.
|
|
# Each hook self-skips when its provider isn't installed.
|
|
local _np_fn
|
|
for _np_fn in $(compgen -A function 2>/dev/null | grep '^appNetworkRegisterPorts_'); do
|
|
"$_np_fn"
|
|
done
|
|
|
|
if [[ "$delete_tasks" == "true" ]]; then
|
|
((menu_number++))
|
|
echo ""
|
|
echo "---- $menu_number. Removing related task history"
|
|
echo ""
|
|
local _tasks_dir="${containers_dir}libreportal/frontend/data/tasks"
|
|
local _removed=0
|
|
if [[ -d "$_tasks_dir" ]]; then
|
|
for _tf in "$_tasks_dir"/task_*.json; do
|
|
[[ ! -f "$_tf" ]] && continue
|
|
# Skip in-flight tasks — that includes the uninstall task
|
|
# we're currently inside, plus anything queued or running.
|
|
if runFileOp grep -qE "\"status\"[[:space:]]*:[[:space:]]*\"(running|queued|pending)\"" "$_tf" 2>/dev/null; then
|
|
continue
|
|
fi
|
|
if runFileOp grep -q "\"app\"[[:space:]]*:[[:space:]]*\"${stored_app_name}\"" "$_tf" 2>/dev/null; then
|
|
local _id=$(basename "$_tf" .json)
|
|
runFileOp rm -f "$_tf" "$_tasks_dir/${_id}.log" "$_tasks_dir/${_id}.cancel" 2>/dev/null
|
|
_removed=$((_removed + 1))
|
|
fi
|
|
done
|
|
fi
|
|
isSuccessful "Removed $_removed task record(s) for $stored_app_name (in-flight task left for the WebUI to clean up after completion)."
|
|
fi
|
|
|
|
((menu_number++))
|
|
echo ""
|
|
isSuccessful "$stored_app_name has been removed from your system!"
|
|
echo ""
|
|
|
|
menu_number=0
|
|
cd
|
|
fi
|
|
}
|