fix(rootless): tagsManager in-place edit via runFileOp/runInstallOp

tagsManagerUpdateUniversalTag did a bare 'sed -i "$file_path"' — works only
because start.sh runs as root today; under Model-A-as-manager the manager
can't create sed's temp file in the dockerinstall-owned containers dir
(permission denied). Make the in-place edit run AS the file's owner: classify
by path (containers/<app> -> runFileOp, manager configs/templates ->
runInstallOp), like createTouch. The awk read stays unescalated (config/compose
are world-readable). Unblocks running the whole app as the manager for tag ops.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
librelad 2026-05-24 17:55:07 +01:00
parent 574146c75e
commit eea5b41e68

View File

@ -45,9 +45,12 @@ tagsManagerUpdateUniversalTag()
esc_placeholder=$(printf '%s' "$current_placeholder" | sed 's/[][\\.*^$/|]/\\&/g')
esc_new=$(printf '%s' "$new_content" | sed 's/[\\&|]/\\&/g')
# Single-pass substitution, scoped to lines carrying this tag's
# annotation. The annotation's default-value field and any matching
# placeholder in the body of the same line both update together
# (they start identical and stay identical after each call).
sed -i "/#LIBREPORTAL|${tag_name}|/s|${esc_placeholder}|${esc_new}|g" "$file_path"
# Single-pass substitution, scoped to lines carrying this tag's annotation.
# The in-place edit runs AS the file's owner (no root): under
# /docker/containers/<app> that's the docker install user (runFileOp); the
# manager-owned configs/ + install templates use runInstallOp. The read
# (awk above) needs no escalation — config/compose files are world-readable.
local op="runInstallOp"
[[ "$file_path" == "$containers_dir"* || "$file_path" == /docker/containers/* ]] && op="runFileOp"
$op sed -i "/#LIBREPORTAL|${tag_name}|/s|${esc_placeholder}|${esc_new}|g" "$file_path"
}