Plugin: common.php library, watchdog expansion, monitor + scheduler improvements
PHP architecture: - Extract common.php from monitor.php — shared system functions (vv_system_info, vv_memory_breakdown, vv_remote_hosts_stats, disk/GPU/UPS/network/docker/parity, etc.) now live in one place; monitor.php and watchdog.php both require common.php - Add unraid_api.php as explicit include (was implicit via config.php chain) - confform.php: add missing require_once config.php (implicit dep made explicit) - Delete orphaned pages/docs.php and pages/config.php (absorbed into scheduler) Watchdog page: - Add Storage watchdog card (growth + log strikes, baseline age, suppress ceilings) - Add Network watchdog card (NPM strikes, DDNS domain/container, NPM URL) - One host per row layout — all 5 watchdog cards equally spaced via inner grid - Watchdog now uses Unraid API for local system stats; remote nodes with API key but no SSH get system info from vv_remote_hosts_stats() with api_only flag - SSH bundle: /proc/meminfo passed as raw section instead of awk-parsed header fields — fixes RAM showing 0 on remote hosts where awk quoting was unreliable - vv_wd_local_system() rewritten as thin wrapper over vv_system_info() + vv_memory_breakdown() Monitor page: - Watchdog card: add stability strikes, storage watchdog strikes, network NPM status, live system stats (rootfs/log/tmp %, RAM free, load, CPU temp, zombies, NIC, sshd) - Row height: switch from max-height on cards to minmax(0, calc(...)) on grid track — all cards in a row now fill to the tallest card's height correctly (fixes Pools card being shorter than neighbours) Scheduler page: - Add Tools section above Custom Scripts — lists Tools/*.sh with run/dry-run/cron/log - vv_tools_scripts() function in scheduler.php include Tools: - Add docker_prune_images.sh — removes dangling Docker images; --dry-run and --status modes
This commit is contained in:
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================================
|
||||
# ============================= Docker Prune Images ============================================
|
||||
# ==============================================================================================
|
||||
#
|
||||
# PURPOSE
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Removes dangling Docker images — images no longer tagged or referenced by any
|
||||
# container. These accumulate after container updates pull a new image version,
|
||||
# leaving the old image behind with no tag.
|
||||
#
|
||||
# Safe to run at any time. Only removes images with no tag and no container
|
||||
# reference — running containers are never affected.
|
||||
#
|
||||
# ==============================================================================================
|
||||
# RUNTIME MODES
|
||||
# ==============================================================================================
|
||||
#
|
||||
# docker_prune_images.sh
|
||||
# Show dangling images and remove them.
|
||||
#
|
||||
# docker_prune_images.sh --dry-run
|
||||
# Show what would be removed without removing anything.
|
||||
#
|
||||
# docker_prune_images.sh --status
|
||||
# Show current dangling images and disk usage. No changes.
|
||||
#
|
||||
# ==============================================================================================
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
source "$SCRIPT_DIR/../load_config.sh"
|
||||
|
||||
parse_args "$@"
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Setup ━━━
|
||||
# ==============================================================================================
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
error "Must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
acquire_lock
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Status ━━━
|
||||
# ==============================================================================================
|
||||
if [[ "$SHOW_STATUS" == true ]]; then
|
||||
echo ""
|
||||
echo "━━━━━ $ICON_SUMMARY DOCKER PRUNE IMAGES STATUS ━━━━━"
|
||||
DANGLING=$(docker images -f "dangling=true" --format "{{.ID}}\t{{.Size}}\t{{.CreatedSince}}" 2>/dev/null)
|
||||
if [[ -z "$DANGLING" ]]; then
|
||||
echo "$ICON_DONE No dangling images."
|
||||
else
|
||||
COUNT=$(echo "$DANGLING" | wc -l)
|
||||
echo "$ICON_CONTAINERS $COUNT dangling image(s):"
|
||||
echo "$DANGLING" | while IFS=$'\t' read -r id size age; do
|
||||
echo " $id $size created $age"
|
||||
done
|
||||
fi
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Run ━━━
|
||||
# ==============================================================================================
|
||||
echo "━━━ $ICON_CONTAINERS Docker Prune Images — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
|
||||
|
||||
DANGLING_IDS=$(docker images -f "dangling=true" -q 2>/dev/null)
|
||||
|
||||
if [[ -z "$DANGLING_IDS" ]]; then
|
||||
success "No dangling images — nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
COUNT=$(echo "$DANGLING_IDS" | wc -l)
|
||||
log "Found $COUNT dangling image(s)"
|
||||
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
warn "DRY RUN — would remove $COUNT dangling image(s):"
|
||||
docker images -f "dangling=true" --format " {{.ID}} {{.Size}} created {{.CreatedSince}}" 2>/dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OUTPUT=$(docker image prune -f 2>&1)
|
||||
echo "$OUTPUT"
|
||||
|
||||
RECLAIMED=$(echo "$OUTPUT" | grep -E "^Total reclaimed" || echo "")
|
||||
if [[ -n "$RECLAIMED" ]]; then
|
||||
success "Done — $RECLAIMED"
|
||||
else
|
||||
success "Done — $COUNT image(s) removed"
|
||||
fi
|
||||
Reference in New Issue
Block a user