diff --git a/plex32_update_check.sh b/plex32_update_check.sh index 02ecee2..7f11275 100644 --- a/plex32_update_check.sh +++ b/plex32_update_check.sh @@ -47,61 +47,38 @@ fi echo "[INFO] APT updates available: $APT_UPDATES" # ============================================================= -# STEP 2 — CHECK PLEX DOCKER IMAGE UPDATE +# STEP 2 — CHECK PLEX DOCKER IMAGE UPDATE (SKOPEO MANIFEST CHECK) # ============================================================= -echo "[INFO] Checking Plex Docker image..." +echo "[INFO] Checking Plex Docker image via Skopeo..." PLEX_FAILED=false PLEX_UPDATE_AVAILABLE=false PLEX_ERROR_HTML="" -# lscr.io occasionally returns "error from registry: unauthorized" on the -# final manifest step of a large multi-layer pull, even after every layer -# downloaded successfully — a transient token/rate-limit issue on their end, -# not a credentials problem. Retry a few times before treating it as a real -# failure, since it usually resolves within one or two attempts. -PLEX_PULL_MAX_RETRIES=3 -PLEX_PULL_RETRY_DELAY=30 -plex_pull_attempt=1 -PLEX_PULL_STATUS=1 -PLEX_PULL_OUTPUT="" +# Fetch digest of remote latest image from lscr.io +REMOTE_DIGEST=$(skopeo inspect docker://lscr.io/linuxserver/plex:latest --format '{{.Digest}}' 2>/dev/null) -while [ $plex_pull_attempt -le $PLEX_PULL_MAX_RETRIES ]; do - PLEX_PULL_OUTPUT=$(docker pull lscr.io/linuxserver/plex:latest 2>&1) - PLEX_PULL_STATUS=$? - if [ $PLEX_PULL_STATUS -eq 0 ]; then - break - fi - echo "[WARN] docker pull attempt $plex_pull_attempt/$PLEX_PULL_MAX_RETRIES failed (exit $PLEX_PULL_STATUS)." - if [ $plex_pull_attempt -lt $PLEX_PULL_MAX_RETRIES ]; then - echo "[WARN] Retrying in ${PLEX_PULL_RETRY_DELAY}s..." - sleep $PLEX_PULL_RETRY_DELAY - fi - plex_pull_attempt=$((plex_pull_attempt + 1)) -done +# Fetch digest of currently running/local image +LOCAL_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' lscr.io/linuxserver/plex:latest 2>/dev/null | cut -d'@' -f2) -PLEX_IMAGE_VERSION=$(docker inspect lscr.io/linuxserver/plex:latest --format '{{index .Config.Labels "build_version"}}' 2>/dev/null || echo "unknown") -CURRENT_IMAGE_DATE=$(docker inspect --format='{{.Created}}' lscr.io/linuxserver/plex:latest 2>/dev/null | cut -d'T' -f1) - -if [ $PLEX_PULL_STATUS -ne 0 ]; then +if [ -z "$REMOTE_DIGEST" ]; then PLEX_FAILED=true - PLEX_STATUS_TEXT="Check failed after $PLEX_PULL_MAX_RETRIES attempts — see error detail below" - echo "[ERROR] docker pull failed after $PLEX_PULL_MAX_RETRIES attempts. Final output:" - echo "$PLEX_PULL_OUTPUT" - PLEX_ERROR_HTML="
⚠ Docker Pull Error (exit $PLEX_PULL_STATUS, after $PLEX_PULL_MAX_RETRIES attempts)
$(echo "$PLEX_PULL_OUTPUT" | sed 's/&/\&/g; s//\>/g')
" -elif echo "$PLEX_PULL_OUTPUT" | grep -q "Pull complete"; then + PLEX_STATUS_TEXT="Check failed — unable to reach registry manifest" + echo "[ERROR] skopeo inspect failed to fetch digest for lscr.io/linuxserver/plex:latest" + PLEX_ERROR_HTML="
⚠ Registry Query Error
Failed to inspect remote image digest from lscr.io via skopeo.
" +elif [ "$REMOTE_DIGEST" != "$LOCAL_DIGEST" ]; then PLEX_UPDATE_AVAILABLE=true - PLEX_STATUS_TEXT="Update available — new image pulled" - if [ $plex_pull_attempt -gt 1 ]; then - PLEX_STATUS_TEXT="$PLEX_STATUS_TEXT (succeeded on retry, attempt $plex_pull_attempt)" - fi + PLEX_STATUS_TEXT="Update available — new digest found on registry" else PLEX_STATUS_TEXT="Up to date" fi +PLEX_IMAGE_VERSION=$(docker inspect lscr.io/linuxserver/plex:latest --format '{{index .Config.Labels "build_version"}}' 2>/dev/null || echo "unknown") +CURRENT_IMAGE_DATE=$(docker inspect --format='{{.Created}}' lscr.io/linuxserver/plex:latest 2>/dev/null | cut -d'T' -f1) + echo "[INFO] Plex status: $PLEX_STATUS_TEXT" # ============================================================= -# STEP 2B — VERIFY RUNNING CONTAINER (independent of pull result) +# STEP 2B — VERIFY RUNNING CONTAINER # ============================================================= echo "[INFO] Checking actual running Plex container..." @@ -169,25 +146,27 @@ ANY_UPDATES=false [ "$F2B_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true [ "$DOCKER_UPDATE_AVAILABLE" = true ] && ANY_UPDATES=true -# A failed registry pull (rate-limit, transient network blip, etc.) is not the -# same severity as the actual Plex container being down. If the pull check -# failed but the running container is confirmed healthy, badge it as a lower -# severity "registry check failed" rather than a full CHECK FAILED/critical state. +# Prioritize status: +# 1. Container Down (Red) +# 2. Updates Available (Blue) - Shows update banner even if a non-critical check warning occurred +# 3. Check Failed (Amber) - Only if checks failed AND no updates were found +# 4. All Current (Green) + if [ "$CONTAINER_OK" = false ]; then STATUS_COLOR="#b91c1c" STATUS_BADGE="🔴 CONTAINER DOWN" STATUS_BANNER_MSG="🔴  Plex container is NOT running — investigate immediately" SUBJECT="🔴 PLEX32 — Plex Container Down — $DATE_SHORT" -elif [ "$ANY_FAILED" = true ]; then - STATUS_COLOR="#b45309" - STATUS_BADGE="⚠ CHECK FAILED" - STATUS_BANNER_MSG="⚠  Registry/update check failed, but Plex container itself is confirmed running — no action required unless this repeats daily" - SUBJECT="⚠ PLEX32 — Update Check Failed — $DATE_SHORT" elif [ "$ANY_UPDATES" = true ]; then STATUS_COLOR="#1d6fa8" STATUS_BADGE="🔄 UPDATES AVAILABLE" - STATUS_BANNER_MSG="🔄  Updates are available for one or more components" + STATUS_BANNER_MSG="🔄  Updates are available for one or more components — run commands below to apply" SUBJECT="🔄 PLEX32 — Updates Available — $DATE_SHORT" +elif [ "$ANY_FAILED" = true ]; then + STATUS_COLOR="#b45309" + STATUS_BADGE="⚠ CHECK FAILED" + STATUS_BANNER_MSG="⚠  Update check experienced a registry/network error — Plex container itself is running normally" + SUBJECT="⚠ PLEX32 — Update Check Failed — $DATE_SHORT" else STATUS_COLOR="#1a7f4b" STATUS_BADGE="✅ ALL CURRENT" @@ -196,7 +175,7 @@ else fi # ============================================================= -# STEP 6 — BUILD COMMAND BLOCKS (click to select) +# STEP 6 — BUILD COMMAND BLOCKS # ============================================================= make_cmd_block() { local step_num="$1" @@ -223,6 +202,7 @@ if [ "$ANY_UPDATES" = true ]; then if [ "$PLEX_UPDATE_AVAILABLE" = true ]; then CMD="cd ~/docker/plex +docker compose pull docker compose up -d" UPDATE_COMMANDS_HTML+=$(make_cmd_block "$STEP" "Plex Media Server (Docker)" "$CMD") STEP=$((STEP+1))