From e0c7928942b17ce6bb4aa928a2db8b36e15cb25d Mon Sep 17 00:00:00 2001 From: librelad Date: Sun, 24 May 2026 21:51:20 +0100 Subject: [PATCH] fix(switcher): enumerate containers/ as the old-mode owner mid-switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two docker-type-switcher finds run mid-switch, BEFORE reconcileDockerOwnership, so containers/ is still owned by the OLD mode's container user while CFG_DOCKER_INSTALL_TYPE is already the target. A plain runFileOp resolves to the target user, which can't list the old-mode-owned (751) dir under rootless — so enumerate as the old-mode owner instead: - switchMigrateBackupApps: move the find inside the existing old_mode/resolveDockerInstallUser window (runFileOp now resolves to the old owner). It previously ran as the manager and silently enumerated nothing under rootless, so no app got backed up before the switch. - dockerSwitcherUpdateContainersToDockerType: take old_mode as an arg, flip CFG to it only for the find (restore before the per-app socket scan + restart, which need the new daemon). Callers in swap_docker_type pass $docker_type. The two former rooted/rootless branches were byte-identical and are collapsed. NOTE: the full rooted<->rootless switch round-trip is still unvalidated on the VM (needs a stateful app + an enabled backup location); this fixes the container enumeration, not yet the end-to-end migration. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../docker/type_switcher/swap_docker_type.sh | 11 +++-- .../type_switcher/switch_containers_type.sh | 43 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/scripts/docker/type_switcher/swap_docker_type.sh b/scripts/docker/type_switcher/swap_docker_type.sh index d225da1..4173497 100755 --- a/scripts/docker/type_switcher/swap_docker_type.sh +++ b/scripts/docker/type_switcher/swap_docker_type.sh @@ -70,7 +70,7 @@ dockerSwitcherSwap() installDocker; fi dockerServiceStart rooted; - dockerSwitcherUpdateContainersToDockerType; + dockerSwitcherUpdateContainersToDockerType "$docker_type"; reconcileDockerOwnership "$CFG_DOCKER_INSTALL_TYPE"; dockerStartAllApps; databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE; @@ -109,7 +109,7 @@ dockerSwitcherSwap() dockerServiceStop rooted; fi dockerServiceStart rootless; - dockerSwitcherUpdateContainersToDockerType; + dockerSwitcherUpdateContainersToDockerType "$docker_type"; reconcileDockerOwnership "$CFG_DOCKER_INSTALL_TYPE"; dockerStartAllApps; databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE; @@ -145,12 +145,15 @@ switchMigrateBackupApps() 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 + # Enumerate under the OLD mode — containers/ is still owned by its container + # user here, so runFileOp (now resolved to that user) can list it (the + # manager can't list the 751 dockerinstall-owned dir under rootless). + local subdirectories=($(runFileOp find "$containers_dir" -mindepth 1 -maxdepth 1 -type d)) + local failed=() local dir app_name for dir in "${subdirectories[@]}"; do diff --git a/scripts/docker/type_switcher/switch_containers_type.sh b/scripts/docker/type_switcher/switch_containers_type.sh index cf1227c..e1eb91e 100755 --- a/scripts/docker/type_switcher/switch_containers_type.sh +++ b/scripts/docker/type_switcher/switch_containers_type.sh @@ -2,27 +2,28 @@ dockerSwitcherUpdateContainersToDockerType() { - if [[ $CFG_DOCKER_INSTALL_TYPE == "rooted" ]]; then - # Scannning the containers folder - local subdirectories=($(find "$containers_dir" -maxdepth 1 -type d)) - for dir in "${subdirectories[@]}"; do - dockerSwitcherScanContainersForSocket "$dir" - if [[ $docker_socket_file_updated == "true" ]]; then - dockerRestartAppViaInstall $(basename $dir); - fi - docker_socket_file_updated="false" - done - fi + # Called mid-switch (new daemon up, BEFORE reconcileDockerOwnership), so + # containers/ is still owned by the OLD mode's container user. Enumerate as + # that user — containers/ isn't list-readable by the manager under rootless, + # and CFG is already the TARGET mode — by flipping CFG to old_mode just for + # the find, then restoring it so the per-app socket scan + restart below talk + # to the NEW daemon. (The two former rooted/rootless branches were identical.) + local old_mode="$1" - if [[ $CFG_DOCKER_INSTALL_TYPE == "rootless" ]]; then - # Scannning the containers folder - local subdirectories=($(find "$containers_dir" -maxdepth 1 -type d)) - for dir in "${subdirectories[@]}"; do - dockerSwitcherScanContainersForSocket "$dir" - if [[ $docker_socket_file_updated == "true" ]]; then - dockerRestartAppViaInstall $(basename $dir); - fi - docker_socket_file_updated="false" - done + local saved_type="$CFG_DOCKER_INSTALL_TYPE" + if [[ -n "$old_mode" ]]; then + CFG_DOCKER_INSTALL_TYPE="$old_mode" + resolveDockerInstallUser fi + local subdirectories=($(runFileOp find "$containers_dir" -maxdepth 1 -type d)) + CFG_DOCKER_INSTALL_TYPE="$saved_type" + resolveDockerInstallUser + + for dir in "${subdirectories[@]}"; do + dockerSwitcherScanContainersForSocket "$dir" + if [[ $docker_socket_file_updated == "true" ]]; then + dockerRestartAppViaInstall $(basename $dir); + fi + docker_socket_file_updated="false" + done }