Merge claude/1

This commit is contained in:
librelad 2026-05-24 13:26:24 +01:00
commit 69d89c9e63

View File

@ -24,13 +24,17 @@ dockerSwitcherSwap()
isHeader "Docker Root/Rootless Switcher"
# Switching modes re-maps container UIDs (rootless shifts them by the
# subuid base), so a stateful app's existing data won't line up in the
# new mode. LibrePortal's own control plane is reconciled automatically
# (reconcileDockerOwnership), but app data is not touched — the safe way
# to carry stateful apps across is backup-before / restore-after.
# subuid base), so a stateful app's on-disk data won't line up in the
# new mode and a chown can't carry it. LibrePortal's control plane is
# reconciled automatically (reconcileDockerOwnership); third-party app
# data is carried by an automatic backup-before / restore-after when a
# backup location is enabled.
isNotice "Switching Docker mode re-maps container ownership."
isNotice "Back up any stateful apps (databases etc.) BEFORE switching and restore them AFTER."
isNotice "App data is intentionally left untouched here."
if [[ -n "$(resticEnabledLocations)" ]]; then
isNotice "Stateful apps will be backed up now and restored automatically after the switch."
else
isNotice "No backup location enabled — back up stateful apps by hand BEFORE switching and restore AFTER."
fi
if [[ $CFG_DOCKER_INSTALL_TYPE == "rooted" ]]; then
if [[ $flag != "cli" ]]; then
@ -50,6 +54,11 @@ dockerSwitcherSwap()
fi
if [[ "$switch_rooted_choice" == [yY] ]]; then
isNotice "Switching to the Rooted Docker now..."
# Back up every app under the old (still-running) mode first; a
# failure aborts the switch before anything changes.
if ! switchMigrateBackupApps "$docker_type"; then
return 1
fi
# Looking at the Rootless Install
if [[ $docker_rootless_found == "true" ]]; then
dockerComposeDownAllApps rootless;
@ -65,6 +74,7 @@ dockerSwitcherSwap()
reconcileDockerOwnership "$CFG_DOCKER_INSTALL_TYPE";
dockerStartAllApps;
databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE;
switchMigrateRestoreApps;
fi
fi
fi
@ -87,6 +97,11 @@ dockerSwitcherSwap()
fi
if [[ "$switch_rootless_choice" == [yY] ]]; then
isNotice "Switching to the Rootless Docker now..."
# Back up every app under the old (still-running) mode first; a
# failure aborts the switch before anything changes.
if ! switchMigrateBackupApps "$docker_type"; then
return 1
fi
# Looking at the Rooted Install
if [[ $docker_rooted_found == "true" ]]; then
dockerComposeDownAllApps rooted;
@ -97,9 +112,93 @@ dockerSwitcherSwap()
reconcileDockerOwnership "$CFG_DOCKER_INSTALL_TYPE";
dockerStartAllApps;
databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE;
switchMigrateRestoreApps;
fi
fi
elif [[ $flag == "cli" ]]; then
isSuccessful "Docker type is already setup for "$CFG_DOCKER_INSTALL_TYPE" no changes needed..."
fi
}
# Apps captured by switchMigrateBackupApps, consumed by switchMigrateRestoreApps.
# Both run inside the same dockerSwitcherSwap call, on either side of the daemon
# switch.
switch_migrated_apps=()
# Back up every installed app (except LibrePortal's own control plane, which the
# reconcile already carries) under the OLD, still-running mode so it can be
# restored under the new mode afterwards. backupAppStart talks to the daemon via
# CFG_DOCKER_INSTALL_TYPE, which the switcher has already advanced to the target
# mode, so force it (and the resolved install user) back to old_mode for the
# duration, then hand it back. Returns non-zero if any backup fails so the
# caller can abort the switch with nothing changed.
switchMigrateBackupApps()
{
local old_mode="$1"
switch_migrated_apps=()
if [[ -z "$(resticEnabledLocations)" ]]; then
isNotice "No backup location enabled — skipping automatic data migration."
return 0
fi
local subdirectories=($(find "$containers_dir" -mindepth 1 -maxdepth 1 -type d))
local saved_type="$CFG_DOCKER_INSTALL_TYPE"
CFG_DOCKER_INSTALL_TYPE="$old_mode"
resolveDockerInstallUser
local failed=()
local dir app_name
for dir in "${subdirectories[@]}"; do
app_name=$(basename "$dir")
[[ "$app_name" == "libreportal" ]] && continue
if backupAppStart "$app_name"; then
switch_migrated_apps+=("$app_name")
else
failed+=("$app_name")
fi
done
CFG_DOCKER_INSTALL_TYPE="$saved_type"
resolveDockerInstallUser
if [[ ${#failed[@]} -gt 0 ]]; then
isError "Pre-switch backup failed for: ${failed[*]}"
isNotice "Aborting the switch — nothing changed, apps remain on $old_mode."
return 1
fi
isSuccessful "Backed up ${#switch_migrated_apps[@]} app(s) before switching."
return 0
}
# Restore each app captured by switchMigrateBackupApps under the NEW mode (new
# daemon up, CFG_DOCKER_INSTALL_TYPE already the target). restoreAppStart wipes
# and re-lays each tree and re-owns it to the new mode's install user — the UID
# remap a chown can't do. Best-effort: a failed app is reported and the rest
# continue, since the daemon has already switched.
switchMigrateRestoreApps()
{
[[ ${#switch_migrated_apps[@]} -eq 0 ]] && return 0
resolveDockerInstallUser
local failed=()
local app_name
for app_name in "${switch_migrated_apps[@]}"; do
if ! restoreAppStart "$app_name" "latest"; then
failed+=("$app_name")
fi
done
if [[ ${#failed[@]} -gt 0 ]]; then
isError "Post-switch restore failed for: ${failed[*]}"
isNotice "The switch finished, but these apps need a manual restore: ${failed[*]}"
return 1
fi
isSuccessful "Restored ${#switch_migrated_apps[@]} app(s) into $CFG_DOCKER_INSTALL_TYPE."
return 0
}