mirror of
https://github.com/samjage/lab.git
synced 2026-06-06 04:10:42 +00:00
added stacks for backup
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================
|
||||
# update-check.sh
|
||||
# Reads Watchtower's recent logs to find outdated images,
|
||||
# maps them to containers, and fetches GitHub release notes.
|
||||
#
|
||||
# Usage:
|
||||
# bash /opt/stacks/scripts/update-check.sh
|
||||
# =============================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/image-sources.conf"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
GRAY='\033[0;90m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
SEP="${GRAY}$(printf '─%.0s' $(seq 1 60))${NC}"
|
||||
|
||||
# ── Check Watchtower is running ───────────────────────────────
|
||||
if ! docker inspect watchtower &>/dev/null; then
|
||||
echo -e "${RED}✗ Watchtower is not running.${NC}"
|
||||
echo -e " Start it: cd /opt/stacks/watchtower && docker compose up -d"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Parse Watchtower logs for outdated images (last 36h) ─────
|
||||
echo -e "${BOLD}Checking Watchtower logs for updates...${NC}"
|
||||
echo ""
|
||||
|
||||
OUTDATED_IMAGES=()
|
||||
while IFS= read -r line; do
|
||||
# Extract image name from: "Found new some/image:tag image (sha256:...)"
|
||||
img=$(echo "$line" | grep -oP '(?<=Found new )\S+(?= image)')
|
||||
[ -n "$img" ] && OUTDATED_IMAGES+=("$img")
|
||||
done < <(docker logs watchtower --since 36h 2>&1 | grep "Found new")
|
||||
|
||||
if [ ${#OUTDATED_IMAGES[@]} -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All images are up to date${NC} ${GRAY}(per last Watchtower scan)${NC}"
|
||||
echo ""
|
||||
LAST=$(docker logs watchtower --since 72h 2>&1 | grep "Session done" | tail -1 | grep -oP '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}')
|
||||
[ -n "$LAST" ] && echo -e "${GRAY} Last scan: ${LAST}${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}${BOLD}${#OUTDATED_IMAGES[@]} image update(s) available:${NC}"
|
||||
echo ""
|
||||
|
||||
# ── For each outdated image: find container + fetch notes ─────
|
||||
gh_release_notes() {
|
||||
local repo=$1
|
||||
local result
|
||||
result=$(curl -sf "https://api.github.com/repos/${repo}/releases/latest" 2>/dev/null) || true
|
||||
if [ -n "$result" ]; then
|
||||
TAG=$(echo "$result" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tag_name','?'))" 2>/dev/null)
|
||||
BODY=$(echo "$result" | python3 -c "
|
||||
import sys,json,re
|
||||
d=json.load(sys.stdin)
|
||||
body=d.get('body','No release notes available.')
|
||||
# Strip markdown links/badges, collapse whitespace
|
||||
body=re.sub(r'!\[.*?\]\(.*?\)','',body)
|
||||
body=re.sub(r'\[([^\]]+)\]\([^\)]+\)',r'\1',body)
|
||||
body=re.sub(r'<!--.*?-->','',body,flags=re.DOTALL)
|
||||
lines=[l.strip() for l in body.split('\n') if l.strip()]
|
||||
print('\n'.join(lines[:6]))
|
||||
" 2>/dev/null || echo "No release notes available.")
|
||||
echo "$TAG|$BODY"
|
||||
fi
|
||||
}
|
||||
|
||||
for image in "${OUTDATED_IMAGES[@]}"; do
|
||||
# Find container(s) using this image
|
||||
CONTAINERS=$(docker ps -a --format '{{.Names}}|{{.Image}}' | awk -F'|' -v img="$image" '$2==img {print $1}' | tr '\n' ' ')
|
||||
[ -z "$CONTAINERS" ] && CONTAINERS="${GRAY}(no running containers)${NC}"
|
||||
|
||||
echo -e "$SEP"
|
||||
echo -e " ${CYAN}${BOLD}${image}${NC}"
|
||||
echo -e " ${GRAY}containers:${NC} ${CONTAINERS}"
|
||||
|
||||
# Strip tag for image name lookup
|
||||
base_image=$(echo "$image" | sed 's/:.*//')
|
||||
|
||||
if [ -n "${IMAGE_REPOS[$base_image]+_}" ]; then
|
||||
REPO="${IMAGE_REPOS[$base_image]}"
|
||||
RELEASE=$(gh_release_notes "$REPO")
|
||||
if [ -n "$RELEASE" ]; then
|
||||
TAG=$(echo "$RELEASE" | cut -d'|' -f1)
|
||||
NOTES=$(echo "$RELEASE" | cut -d'|' -f2-)
|
||||
echo -e " ${GRAY}latest tag:${NC} ${GREEN}${TAG}${NC}"
|
||||
echo -e " ${GRAY}notes:${NC}"
|
||||
while IFS= read -r line; do
|
||||
echo -e " ${GRAY}${line}${NC}"
|
||||
done <<< "$NOTES"
|
||||
echo -e " ${GRAY}full notes:${NC} https://github.com/${REPO}/releases/latest"
|
||||
else
|
||||
echo -e " ${GRAY}→ https://hub.docker.com/r/${base_image}/tags${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e " ${GRAY}no GitHub mapping — add to scripts/image-sources.conf${NC}"
|
||||
echo -e " ${GRAY}→ https://hub.docker.com/r/${base_image}/tags${NC}"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo -e "$SEP"
|
||||
echo ""
|
||||
echo -e " Ready to update? Run: ${CYAN}bash /opt/stacks/scripts/do-update.sh${NC}"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user