ownership: find an app wherever it lives, not only under the primary root
_app_dir resolved an app name to "$CONTAINERS_DIR/$app" and gave up if that did
not exist. An app on a registered storage location is not there, so every root
action keyed on an app name quietly did nothing for those:
app-data-remove linkding -> rc=0, nothing removed
which is what restoreAppStart calls at step 4, "Wiping existing app folder". So
restoring an app that lives on a second disk laid the snapshot over whatever was
already there instead of replacing it, and files deleted since the backup would
survive a restore meant to undo their deletion.
Search the primary root first, then each REGISTERED location. Candidate paths
come from the root-owned registry and never from the caller, so this cannot be
pointed anywhere root does not already own. app_data_remove goes through the
resolver now instead of building the path itself.
Found by the flow test: destroying linkding on disk1 reported success and left
all nineteen files in place.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
2d5674108b
commit
b0a00649f7
@ -89,13 +89,38 @@ _container_owner() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Validate + resolve an app name to its container dir (reject traversal/odd names).
|
# Validate + resolve an app name to its container dir (reject traversal/odd names).
|
||||||
|
#
|
||||||
|
# An app does not have to be under CONTAINERS_DIR: it can live on any REGISTERED
|
||||||
|
# storage location. Looking only in the primary root meant every action keyed on
|
||||||
|
# an app name silently did nothing for those — app-data-remove returned 0 having
|
||||||
|
# removed nothing, so restore's "Wiping existing app folder" wiped nothing and a
|
||||||
|
# restore laid new data over old.
|
||||||
|
#
|
||||||
|
# Candidate roots come from the root-owned registry, never from the caller, so
|
||||||
|
# this still cannot be pointed anywhere root does not already own.
|
||||||
_app_dir() {
|
_app_dir() {
|
||||||
local app="$1"
|
local app="$1"
|
||||||
[[ "$app" =~ ^[A-Za-z0-9._-]+$ && "$app" != "." && "$app" != ".." ]] \
|
[[ "$app" =~ ^[A-Za-z0-9._-]+$ && "$app" != "." && "$app" != ".." ]] \
|
||||||
|| { echo "libreportal-ownership: invalid app name" >&2; return 1; }
|
|| { echo "libreportal-ownership: invalid app name" >&2; return 1; }
|
||||||
local d="$CONTAINERS_DIR/$app"
|
|
||||||
[[ -d "$d" ]] || { echo "libreportal-ownership: no such app dir: $d" >&2; return 1; }
|
if [[ -d "$CONTAINERS_DIR/$app" ]]; then
|
||||||
printf '%s' "$d"
|
printf '%s' "$CONTAINERS_DIR/$app"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -r "$STORAGE_REGISTRY" ]]; then
|
||||||
|
local _id _path _rest
|
||||||
|
while IFS=$'\t' read -r _id _path _rest || [[ -n "$_id" ]]; do
|
||||||
|
[[ -z "$_path" || "$_id" == \#* ]] && continue
|
||||||
|
if [[ -d "${_path%/}/$app" ]]; then
|
||||||
|
printf '%s' "${_path%/}/$app"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done < "$STORAGE_REGISTRY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "libreportal-ownership: no such app dir for '$app'" >&2
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Let the rootless container user reach the few system-tree files it must read as
|
# Let the rootless container user reach the few system-tree files it must read as
|
||||||
@ -273,8 +298,10 @@ app_data_remove() {
|
|||||||
|| { echo "libreportal-ownership: invalid app name" >&2; return 1; }
|
|| { echo "libreportal-ownership: invalid app name" >&2; return 1; }
|
||||||
[[ "$app" == "libreportal" ]] \
|
[[ "$app" == "libreportal" ]] \
|
||||||
&& { echo "libreportal-ownership: refusing to remove the WebUI app dir" >&2; return 1; }
|
&& { echo "libreportal-ownership: refusing to remove the WebUI app dir" >&2; return 1; }
|
||||||
local d="$CONTAINERS_DIR/$app"
|
# Through the resolver, so an app on a registered location is found rather
|
||||||
[[ -d "$d" ]] || return 0
|
# than quietly skipped.
|
||||||
|
local d
|
||||||
|
d=$(_app_dir "$app" 2>/dev/null) || return 0
|
||||||
rm -rf -- "$d"
|
rm -rf -- "$d"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user