Merge claude/2
This commit is contained in:
commit
728830f74d
58
scripts/docker/command/stranded_containers.sh
Normal file
58
scripts/docker/command/stranded_containers.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
# A containers-root wipe (fresh install, or a relocation of the containers root)
|
||||
# removes an app's project directory but NOT the container the daemon still holds
|
||||
# in its own state. Those containers are stranded: their compose file, config and
|
||||
# bind-mount sources are gone, so they can never start correctly again.
|
||||
#
|
||||
# They are not inert. `restart: unless-stopped` makes the daemon retry them on
|
||||
# every restart, and Docker materialises each missing bind-mount source before
|
||||
# handing off to runc — creating an empty DIRECTORY even where the mount is a
|
||||
# file. That is how a fresh install ends up with <app>.config as a directory: the
|
||||
# install restarts the rootless daemon, the daemon resurrects the previous
|
||||
# install's container, and the stubs it leaves behind collide with the install's
|
||||
# own file copies moments later.
|
||||
#
|
||||
# Sweep them once the daemon is up, so the next restart has nothing to resurrect.
|
||||
# Scoped to containers whose project directory sits under the LibrePortal
|
||||
# containers root — unrelated containers on the host are never touched.
|
||||
dockerRemoveStrandedContainers()
|
||||
{
|
||||
local silent_flag="${1:-silent}"
|
||||
|
||||
[[ -d "$containers_dir" ]] || return 0
|
||||
|
||||
# `systemctl restart` returns once the unit is active, which can be before
|
||||
# dockerd finishes initialising. Give the socket a bounded moment to answer.
|
||||
local attempt=0
|
||||
until runFileOp docker info >/dev/null 2>&1; do
|
||||
attempt=$((attempt + 1))
|
||||
if [[ "$attempt" -ge 15 ]]; then
|
||||
[[ "$silent_flag" == "loud" ]] && isNotice "Docker not responding — skipping stranded container sweep."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
local listing
|
||||
listing=$(runFileOp docker ps -a --format '{{.Names}} {{.Label "com.docker.compose.project.working_dir"}}' 2>/dev/null)
|
||||
[[ -z "$listing" ]] && return 0
|
||||
|
||||
local removed=0 name work_dir
|
||||
while IFS=$'\t' read -r name work_dir; do
|
||||
[[ -z "$name" || -z "$work_dir" ]] && continue
|
||||
# Only LibrePortal's own container tree, and only when the project
|
||||
# directory is provably gone.
|
||||
[[ "$work_dir" == "$containers_dir"* ]] || continue
|
||||
[[ -d "$work_dir" ]] && continue
|
||||
|
||||
if runFileOp docker rm -f "$name" >/dev/null 2>&1; then
|
||||
removed=$((removed + 1))
|
||||
[[ "$silent_flag" == "loud" ]] && isNotice "Removed stranded container '$name' (project dir $work_dir is gone)."
|
||||
fi
|
||||
done <<< "$listing"
|
||||
|
||||
if [[ "$removed" -gt 0 ]]; then
|
||||
isSuccessful "Removed $removed stranded container(s) left without a project directory"
|
||||
fi
|
||||
}
|
||||
@ -183,6 +183,12 @@ EOL"
|
||||
local result; result=$(dockerCommandRunInstallUser "systemctl --user restart docker")
|
||||
checkSuccess "Reload the systemd user docker service"
|
||||
|
||||
# The restart above runs the daemon's container-restore pass, which
|
||||
# resurrects containers left over from a previous install whose project
|
||||
# directory this install already wiped. Clear them now so the next
|
||||
# restart can't re-create their bind-mount sources as stub directories.
|
||||
dockerRemoveStrandedContainers "loud"
|
||||
|
||||
local result; result=$(sudo cp $sysctl $sysctl.bak)
|
||||
checkSuccess "Backing up sysctl file"
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ docker_scripts=(
|
||||
"docker/command/docker_run_install.sh"
|
||||
"docker/command/docker_run.sh"
|
||||
"docker/command/run_privileged.sh"
|
||||
"docker/command/stranded_containers.sh"
|
||||
"docker/compose/copy_build_context.sh"
|
||||
"docker/compose/restart_after_update.sh"
|
||||
"docker/compose/setup_compose_yml.sh"
|
||||
|
||||
@ -411,6 +411,7 @@ declare -gA LP_FN_MAP=(
|
||||
[dockerPruneAppNetworks]="docker/network/network_prune.sh"
|
||||
[dockerRemoveApp]="docker/app/docker/remove_app.sh"
|
||||
[dockerRemoveAppImages]="docker/app/uninstall/remove_images.sh"
|
||||
[dockerRemoveStrandedContainers]="docker/command/stranded_containers.sh"
|
||||
[dockerRestartApp]="docker/app/docker/restart_app.sh"
|
||||
[dockerRestartAppViaInstall]="docker/app/functions/function_restart_app.sh"
|
||||
[dockerServiceStart]="docker/service/start_docker.sh"
|
||||
@ -1416,6 +1417,7 @@ declare -gA LP_FN_ROOT=(
|
||||
[dockerPruneAppNetworks]="scripts"
|
||||
[dockerRemoveApp]="scripts"
|
||||
[dockerRemoveAppImages]="scripts"
|
||||
[dockerRemoveStrandedContainers]="scripts"
|
||||
[dockerRestartApp]="scripts"
|
||||
[dockerRestartAppViaInstall]="scripts"
|
||||
[dockerServiceStart]="scripts"
|
||||
@ -2454,6 +2456,7 @@ dockerInstallApp() { unset -f dockerInstallApp; __lpAutoload "${install_scripts_
|
||||
dockerPruneAppNetworks() { unset -f dockerPruneAppNetworks; __lpAutoload "${install_scripts_dir}docker/network/network_prune.sh"; dockerPruneAppNetworks "$@"; }
|
||||
dockerRemoveApp() { unset -f dockerRemoveApp; __lpAutoload "${install_scripts_dir}docker/app/docker/remove_app.sh"; dockerRemoveApp "$@"; }
|
||||
dockerRemoveAppImages() { unset -f dockerRemoveAppImages; __lpAutoload "${install_scripts_dir}docker/app/uninstall/remove_images.sh"; dockerRemoveAppImages "$@"; }
|
||||
dockerRemoveStrandedContainers() { unset -f dockerRemoveStrandedContainers; __lpAutoload "${install_scripts_dir}docker/command/stranded_containers.sh"; dockerRemoveStrandedContainers "$@"; }
|
||||
dockerRestartApp() { unset -f dockerRestartApp; __lpAutoload "${install_scripts_dir}docker/app/docker/restart_app.sh"; dockerRestartApp "$@"; }
|
||||
dockerRestartAppViaInstall() { unset -f dockerRestartAppViaInstall; __lpAutoload "${install_scripts_dir}docker/app/functions/function_restart_app.sh"; dockerRestartAppViaInstall "$@"; }
|
||||
dockerServiceStart() { unset -f dockerServiceStart; __lpAutoload "${install_scripts_dir}docker/service/start_docker.sh"; dockerServiceStart "$@"; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user