deploy-remote: privileged rename + deep merge in migrate_data_root
rename() of a directory requires write on the directory itself; mariadb/ redis data roots are owned by the containers' mapped subuids (100998), so the deploy user cannot move them. Use run_privileged mv (numeric ownership preserved = rootless mapping contract) and skip the chown pass for romm via the new keep mode — chowning mapped subuid data to the deploy uid breaks the in-container mysql/redis users. Collisions with rescued anonymous-volume stubs now merge one level deep instead of stranding real data under /opt. Reverse the podman rm order so the dependent romm container is removed before its backends.
This commit is contained in:
+37
-19
@@ -537,25 +537,43 @@ wait_container_healthy() {
|
||||
# the unit; re-running the handler on an already-active unit restarts only the
|
||||
# selected unit.
|
||||
|
||||
migrate_data_root() { # $1 = old /opt path, $2 = new data-root path (same fs: rename/merge)
|
||||
local from="$1" to="$2" entry
|
||||
migrate_data_root() { # $1=old /opt path, $2=new data root, $3=chown|keep (default chown)
|
||||
local from="$1" to="$2" mode="${3:-chown}" entry sub base
|
||||
[[ -d "$from" ]] || return 0
|
||||
if [[ -d "$to" && -n "$(ls -A "$to" 2>/dev/null)" ]]; then
|
||||
# The destination already holds seeded state (env file, rescued
|
||||
# anonymous-volume data). Merge the old root into it without ever
|
||||
# overwriting an existing entry, then drop the emptied source.
|
||||
shopt -s dotglob
|
||||
for entry in "$from"/*; do
|
||||
[[ -e "$entry" ]] || continue
|
||||
mv -n -- "$entry" "$to/"
|
||||
done
|
||||
shopt -u dotglob
|
||||
rmdir -- "$from" 2>/dev/null || \
|
||||
echo "WARN: $from not empty after merge (collisions kept old side); left in place" >&2
|
||||
else
|
||||
mv -- "$from" "$to"
|
||||
# Renaming a directory needs WRITE permission on the directory being
|
||||
# renamed itself. Compose-era data roots contain directories owned by
|
||||
# the containers' mapped host uids (mariadb/redis land in the subuid
|
||||
# range as 100998), which the deploy user cannot rename. Privileged mv
|
||||
# preserves numeric ownership — the rootless mapping contract.
|
||||
mkdir -p "$to"
|
||||
shopt -s dotglob
|
||||
for entry in "$from"/*; do
|
||||
[[ -e "$entry" || -L "$entry" ]] || continue
|
||||
base="${entry##*/}"
|
||||
if [[ -e "$to/$base" ]]; then
|
||||
# Collides with pre-seeded state (env file) or a rescued
|
||||
# anonymous-volume stub: merge one level deep, never overwriting
|
||||
# an existing entry.
|
||||
if [[ -d "$entry" && -d "$to/$base" ]]; then
|
||||
for sub in "$entry"/*; do
|
||||
[[ -e "$sub" || -L "$sub" ]] || continue
|
||||
run_privileged mv -n -- "$sub" "$to/$base/"
|
||||
done
|
||||
run_privileged rmdir -- "$entry" 2>/dev/null || \
|
||||
echo "WARN: $entry not empty after merge; left in place" >&2
|
||||
else
|
||||
echo "WARN: collision on $to/$base kept existing; $entry left in place" >&2
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
run_privileged mv -- "$entry" "$to/"
|
||||
done
|
||||
shopt -u dotglob
|
||||
run_privileged rmdir -- "$from" 2>/dev/null || \
|
||||
echo "WARN: $from not empty after migration; left in place" >&2
|
||||
if [[ "$mode" == chown ]]; then
|
||||
chown -R "$(id -u):$(id -g)" "$to"
|
||||
fi
|
||||
chown -R "$(id -u):$(id -g)" "$to"
|
||||
}
|
||||
|
||||
deploy_romm_stack() {
|
||||
@@ -580,7 +598,7 @@ deploy_romm_stack() {
|
||||
local vols
|
||||
vols="$(podman inspect -f '{{range .Mounts}}{{if eq .Type "volume"}}{{.Name}} {{end}}{{end}}' romm 2>/dev/null || true)"
|
||||
podman stop -t 60 romm-mariadb romm-redis romm || true
|
||||
podman rm romm-mariadb romm-redis romm || true
|
||||
podman rm romm romm-redis romm-mariadb || true
|
||||
for vol in $vols; do
|
||||
tmp="$(mktemp -d)"
|
||||
podman volume export --output "$tmp/v.tar" "$vol"
|
||||
@@ -589,7 +607,7 @@ deploy_romm_stack() {
|
||||
tar --skip-old-files -C /home/dank/Containers/romm -xf "$tmp/v.tar"
|
||||
rm -rf -- "$tmp"
|
||||
done
|
||||
migrate_data_root /opt/romm /home/dank/Containers/romm
|
||||
migrate_data_root /opt/romm /home/dank/Containers/romm keep
|
||||
systemctl --user start romm-mariadb.service
|
||||
wait_container_healthy romm-mariadb 120 || return 1
|
||||
systemctl --user start romm-redis.service
|
||||
|
||||
Reference in New Issue
Block a user