Compare commits
No commits in common. "b04cae228ac3f34a9b6c0adeb7f33c1716777766" and "67e807c617fbc14710ed48c13020802585c1918d" have entirely different histories.
b04cae228a
...
67e807c617
@ -97,46 +97,6 @@ cliHandleUpdaterCommands()
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Digest (sha256:…) of a locally-present image ref; "" if absent. Rootless-aware.
|
|
||||||
updaterRefDigest()
|
|
||||||
{
|
|
||||||
local ref="$1" out
|
|
||||||
out="$(dockerCommandRun "docker inspect --format '{{index .RepoDigests 0}}' $ref" 2>/dev/null | tr -d '\r' | head -1)"
|
|
||||||
out="${out##*@}"; case "$out" in sha256:*) printf '%s' "$out";; esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rewrite the app's ANCHOR (<slug>-service) image line to $newref, preserving the
|
|
||||||
# original indent and any trailing ` #LIBREPORTAL|…` version sentinel. Targets the
|
|
||||||
# anchor by service name (not the first image line — some apps list a companion
|
|
||||||
# first), so it's correct for ollama et al.
|
|
||||||
updaterSetAnchorRef()
|
|
||||||
{
|
|
||||||
local app="$1" newref="$2"
|
|
||||||
local compose="${containers_dir%/}/$app/docker-compose.yml"
|
|
||||||
[ -f "$compose" ] || return 1
|
|
||||||
local tmp; tmp="$(mktemp)"
|
|
||||||
awk -v s="${app//_/-}-service" -v ref="$newref" '
|
|
||||||
!done && seen && /^[[:space:]]*image:/ {
|
|
||||||
match($0,/^[[:space:]]*/); ind=substr($0,1,RLENGTH)
|
|
||||||
cmt=""; if (match($0,/#.*/)) cmt=" " substr($0,RSTART)
|
|
||||||
print ind "image: " ref cmt; done=1; next
|
|
||||||
}
|
|
||||||
$0 ~ ("^[[:space:]]*" s ":") { seen=1 }
|
|
||||||
{ print }
|
|
||||||
' "$compose" > "$tmp" || { rm -f "$tmp"; return 1; }
|
|
||||||
runFileWrite "$compose" < "$tmp"; local rc=$?
|
|
||||||
rm -f "$tmp"; return $rc
|
|
||||||
}
|
|
||||||
|
|
||||||
# The image ref (repo:tag@sha256:…) the app ran BEFORE its last successful update
|
|
||||||
# — i.e. the roll-back target. Read from history.json's most recent update/ok.
|
|
||||||
updaterLastUpdateFrom()
|
|
||||||
{
|
|
||||||
local app="$1" hist="$containers_dir/libreportal/frontend/data/updater/generated/history.json"
|
|
||||||
[ -f "$hist" ] && command -v jq >/dev/null 2>&1 || return 0
|
|
||||||
jq -r --arg a "$app" 'first(.entries[]? | select(.app==$a and .action=="update" and .result=="ok") | .from) // ""' "$hist" 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update one app with disaster-recovery: snapshot -> pull -> recreate -> verify,
|
# Update one app with disaster-recovery: snapshot -> pull -> recreate -> verify,
|
||||||
# auto-rolling-back on failure. Uses existing primitives (the backup CLI for the
|
# auto-rolling-back on failure. Uses existing primitives (the backup CLI for the
|
||||||
# snapshot, docker compose for the image swap) so it shares their locking/logging.
|
# snapshot, docker compose for the image swap) so it shares their locking/logging.
|
||||||
@ -161,21 +121,13 @@ updaterApplyApp()
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Capture the current ANCHOR image + its running digest, so from->to is an
|
# 2. Capture the current image so we can record from->to / roll back.
|
||||||
# exact build reference (repo:tag@sha256:…) even for a floating tag. Anchor is
|
local before; before="$(grep -m1 -E '^\s*image:' "$app_dir/docker-compose.yml" 2>/dev/null | sed -E 's/^\s*image:\s*//; s/["'"'"']//g')"
|
||||||
# the <slug>-service image (updaterPrimaryImage), NOT the first line. If a
|
|
||||||
# prior rollback pinned a digest, unpin it first so we track the channel again.
|
|
||||||
local anchor; anchor="$(updaterPrimaryImage "$app" "$app_dir/docker-compose.yml")"
|
|
||||||
case "$anchor" in *@sha256:*) updaterSetAnchorRef "$app" "${anchor%%@*}"; anchor="${anchor%%@*}";; esac
|
|
||||||
local before_dig; before_dig="$(updaterRefDigest "$anchor")"
|
|
||||||
local before="$anchor${before_dig:+@$before_dig}"
|
|
||||||
|
|
||||||
# 3. Pull + recreate (uses the real, install-type-aware compose helpers).
|
# 3. Pull + recreate (uses the real, install-type-aware compose helpers).
|
||||||
isNotice "Pulling new image(s) for $app…"
|
isNotice "Pulling new image(s) for $app…"
|
||||||
if updaterComposePull "$app" && dockerComposeUp "$app" >/dev/null 2>&1; then
|
if updaterComposePull "$app" && dockerComposeUp "$app" >/dev/null 2>&1; then
|
||||||
local after_ref; after_ref="$(updaterPrimaryImage "$app" "$app_dir/docker-compose.yml")"; after_ref="${after_ref%%@*}"
|
local after; after="$(grep -m1 -E '^\s*image:' "$app_dir/docker-compose.yml" 2>/dev/null | sed -E 's/^\s*image:\s*//; s/["'"'"']//g')"
|
||||||
local after_dig; after_dig="$(updaterRefDigest "$after_ref")"
|
|
||||||
local after="$after_ref${after_dig:+@$after_dig}"
|
|
||||||
updaterRecordHistory "$app" "update" "$before" "$after" "ok"
|
updaterRecordHistory "$app" "update" "$before" "$after" "ok"
|
||||||
isSuccessful "$app updated. Rollback point retained."
|
isSuccessful "$app updated. Rollback point retained."
|
||||||
webuiUpdaterScan >/dev/null 2>&1 || true
|
webuiUpdaterScan >/dev/null 2>&1 || true
|
||||||
@ -210,15 +162,6 @@ updaterRollbackApp()
|
|||||||
{
|
{
|
||||||
local app="$1" mode="$2"
|
local app="$1" mode="$2"
|
||||||
[[ "$mode" != "auto" ]] && isHeader "Rolling $app back to its pre-update snapshot"
|
[[ "$mode" != "auto" ]] && isHeader "Rolling $app back to its pre-update snapshot"
|
||||||
# Re-pin the ANCHOR image to the exact build the app ran before the last
|
|
||||||
# update, so `up` below runs the OLD code — not the current channel head.
|
|
||||||
# Without this, restoring the data snapshot but recreating on the new `latest`
|
|
||||||
# image is "new code on old data", the hole a floating tag makes invisible.
|
|
||||||
# (Preserves the version sentinel; apply un-pins it again on the next update.)
|
|
||||||
local prev_ref; prev_ref="$(updaterLastUpdateFrom "$app")"
|
|
||||||
if [[ -n "$prev_ref" && "$prev_ref" == *@sha256:* ]]; then
|
|
||||||
updaterSetAnchorRef "$app" "$prev_ref" && isNotice "Pinned $app back to its pre-update build."
|
|
||||||
fi
|
|
||||||
# Delegate to the restore engine (latest snapshot for this app). Call the
|
# Delegate to the restore engine (latest snapshot for this app). Call the
|
||||||
# function directly — the old `backup app "$app" restore latest` CLI form was
|
# function directly — the old `backup app "$app" restore latest` CLI form was
|
||||||
# malformed (parsed as action="$app") so it silently did nothing yet exited 0.
|
# malformed (parsed as action="$app") so it silently did nothing yet exited 0.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user