added notification support, and added to a few scripts . need to update the rest
This commit is contained in:
@@ -0,0 +1,184 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# --------------------------------- Docker Daily Restart ---------------------------------------
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# Restarts or starts specified Docker containers with retry logic.
|
||||||
|
# Containers are configured in Master.conf under DAILY_RESTART_CONTAINERS.
|
||||||
|
# Uses global RETRY_COUNT and SLEEP from Master.conf for retry behaviour.
|
||||||
|
# Sends notifications on completion or failure via common.sh notify().
|
||||||
|
# Supports --dry-run to preview what would be restarted without taking action.
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
source "$SCRIPT_DIR/../Master.conf"
|
||||||
|
source "$SCRIPT_DIR/../common.sh"
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# ━━━ $ICON_GEAR Setup ━━━
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
echo ""
|
||||||
|
echo "━━━ $ICON_GEAR Setup ━━━"
|
||||||
|
|
||||||
|
# ROOT CHECK
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
error "Must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Running as root"
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
error "Docker command not found — check PATH or Docker installation"
|
||||||
|
notify "Docker daily restart failed — Docker not found on $(hostname)" "Docker Daily Restart" "alert"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Docker found"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# ━━━ $ICON_SUMMARY Status ━━━
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
if [[ "$SHOW_STATUS" == true ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━"
|
||||||
|
echo "$ICON_CONTAINERS Containers: ${DAILY_RESTART_CONTAINERS[*]}"
|
||||||
|
echo "$ICON_RETRY Retries: $RETRY_COUNT"
|
||||||
|
echo "$ICON_TIME Sleep: ${SLEEP}s between retries"
|
||||||
|
echo "$ICON_NOTIFY Notifications: unRAID=${NOTIFY_UNRAID:-false} Discord=$([[ -n "${DISCORD_WEBHOOK:-}" ]] && echo enabled || echo disabled)"
|
||||||
|
echo "$ICON_GEAR Dry Run: $DRY_RUN"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no containers will be restarted"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# FUNCTIONS
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Attempts a docker command up to RETRY_COUNT times with SLEEP seconds between attempts.
|
||||||
|
# Returns 0 on success, 1 if all attempts fail.
|
||||||
|
# Usage: retry_docker docker restart Emby
|
||||||
|
retry_docker() {
|
||||||
|
local attempt=1
|
||||||
|
|
||||||
|
while [[ "$attempt" -le "$RETRY_COUNT" ]]; do
|
||||||
|
info "$ICON_RETRY Attempt $attempt of $RETRY_COUNT: $*"
|
||||||
|
|
||||||
|
if "$@"; then
|
||||||
|
success "Succeeded on attempt $attempt"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
warn "Attempt $attempt failed"
|
||||||
|
(( attempt++ ))
|
||||||
|
[[ "$attempt" -le "$RETRY_COUNT" ]] && sleep "$SLEEP"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
error "Command failed after $RETRY_COUNT attempts: $*"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# ━━━ $ICON_CONTAINERS $ICON_STOP $ICON_START Daily Restart ━━━
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
echo ""
|
||||||
|
echo "━━━ $ICON_CONTAINERS Daily Restart — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
|
||||||
|
echo "$ICON_CONTAINERS Containers: ${DAILY_RESTART_CONTAINERS[*]}"
|
||||||
|
echo "$ICON_RETRY Retries: $RETRY_COUNT"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
START=$(date +%s)
|
||||||
|
FAILED=()
|
||||||
|
RESTARTED=()
|
||||||
|
STARTED=()
|
||||||
|
|
||||||
|
for container in "${DAILY_RESTART_CONTAINERS[@]}"; do
|
||||||
|
echo "━━━ $ICON_CONTAINERS $container ━━━"
|
||||||
|
|
||||||
|
# Verify container exists
|
||||||
|
if ! docker inspect "$container" &>/dev/null; then
|
||||||
|
error "$container does not exist — skipping"
|
||||||
|
FAILED+=("$container")
|
||||||
|
echo ""
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
STATUS=$(docker inspect -f '{{.State.Running}}' "$container" 2>/dev/null)
|
||||||
|
|
||||||
|
case "$STATUS" in
|
||||||
|
true)
|
||||||
|
echo "$ICON_RUNNING $container is running — restarting..."
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
warn "DRY RUN — would restart $container"
|
||||||
|
else
|
||||||
|
if retry_docker docker restart "$container"; then
|
||||||
|
echo "$ICON_STARTED $container restarted"
|
||||||
|
RESTARTED+=("$container")
|
||||||
|
else
|
||||||
|
error "Failed to restart $container"
|
||||||
|
FAILED+=("$container")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
false)
|
||||||
|
echo "$ICON_NOT_RUNNING $container is stopped — starting..."
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
warn "DRY RUN — would start $container"
|
||||||
|
else
|
||||||
|
if retry_docker docker start "$container"; then
|
||||||
|
echo "$ICON_STARTED $container started"
|
||||||
|
STARTED+=("$container")
|
||||||
|
else
|
||||||
|
error "Failed to start $container"
|
||||||
|
FAILED+=("$container")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unknown status for $container: $STATUS"
|
||||||
|
FAILED+=("$container")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
END=$(date +%s)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# ━━━ $ICON_SUMMARY Summary ━━━
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
echo "━━━━━ $ICON_SUMMARY DAILY RESTART SUMMARY ━━━━━"
|
||||||
|
echo "$ICON_TIME Duration: $(format_duration $((END - START)))"
|
||||||
|
|
||||||
|
if [[ ${#RESTARTED[@]} -gt 0 ]]; then
|
||||||
|
echo "$ICON_STARTED Restarted: ${RESTARTED[*]}"
|
||||||
|
fi
|
||||||
|
if [[ ${#STARTED[@]} -gt 0 ]]; then
|
||||||
|
echo "$ICON_STARTED Started: ${STARTED[*]}"
|
||||||
|
fi
|
||||||
|
if [[ ${#FAILED[@]} -gt 0 ]]; then
|
||||||
|
echo "$ICON_ERROR Failed: ${FAILED[*]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
echo "$ICON_WARN Status: DRY RUN — no changes made"
|
||||||
|
elif [[ ${#FAILED[@]} -eq 0 ]]; then
|
||||||
|
echo "$ICON_DONE Status: $ICON_SUCCESS ALL DONE"
|
||||||
|
notify "Daily restart complete — ${#RESTARTED[@]} restarted, ${#STARTED[@]} started" "Docker Daily Restart" "normal"
|
||||||
|
else
|
||||||
|
echo "$ICON_ERROR Status: $ICON_ERROR ${#FAILED[@]} container(s) failed"
|
||||||
|
notify "Daily restart completed with errors — failed: ${FAILED[*]}" "Docker Daily Restart" "alert"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
|
||||||
|
[[ ${#FAILED[@]} -gt 0 ]] && exit 1
|
||||||
|
exit 0
|
||||||
@@ -66,6 +66,7 @@ if [[ "$SHOW_STATUS" == true ]]; then
|
|||||||
echo "$ICON_RETRY CPU fail limit: ${CPU_FAIL_LIMIT} strikes"
|
echo "$ICON_RETRY CPU fail limit: ${CPU_FAIL_LIMIT} strikes"
|
||||||
echo "$ICON_PING Resp fail limit: ${RESP_FAIL_LIMIT} strikes"
|
echo "$ICON_PING Resp fail limit: ${RESP_FAIL_LIMIT} strikes"
|
||||||
echo "$ICON_TIME Curl timeout: ${CURL_TIMEOUT}s"
|
echo "$ICON_TIME Curl timeout: ${CURL_TIMEOUT}s"
|
||||||
|
echo "$ICON_NOTIFY Notifications: unRAID=${NOTIFY_UNRAID:-false} Discord=$([[ -n "${DISCORD_WEBHOOK:-}" ]] && echo enabled || echo disabled)"
|
||||||
echo "$ICON_GEAR Dry Run: $DRY_RUN"
|
echo "$ICON_GEAR Dry Run: $DRY_RUN"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -118,7 +119,7 @@ convert_to_mb() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restarts a container locally.
|
# Restarts a container locally and sends a notification.
|
||||||
# In dry run mode reports what would happen without acting.
|
# In dry run mode reports what would happen without acting.
|
||||||
restart_container() {
|
restart_container() {
|
||||||
local container="$1" reason="$2"
|
local container="$1" reason="$2"
|
||||||
@@ -131,9 +132,11 @@ restart_container() {
|
|||||||
info "Restarting $container ($reason)..."
|
info "Restarting $container ($reason)..."
|
||||||
if docker restart "$container" >/dev/null 2>&1; then
|
if docker restart "$container" >/dev/null 2>&1; then
|
||||||
echo "$ICON_STARTED $container restarted"
|
echo "$ICON_STARTED $container restarted"
|
||||||
|
notify "$container restarted — $reason" "Docker Watchdog" "warning"
|
||||||
log "Restarted $container — reason: $reason"
|
log "Restarted $container — reason: $reason"
|
||||||
else
|
else
|
||||||
error "Failed to restart $container"
|
error "Failed to restart $container"
|
||||||
|
notify "Failed to restart $container — $reason" "Docker Watchdog" "alert"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,8 +261,8 @@ echo ""
|
|||||||
echo "━━━ $ICON_WATCHDOG Watchdog Check — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
|
echo "━━━ $ICON_WATCHDOG Watchdog Check — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
RESTARTED=()
|
|
||||||
SKIPPED=()
|
SKIPPED=()
|
||||||
|
RESTARTED=0
|
||||||
|
|
||||||
START=$(date +%s)
|
START=$(date +%s)
|
||||||
|
|
||||||
|
|||||||
+19
@@ -15,6 +15,13 @@
|
|||||||
# ━━━ Logging ━━━
|
# ━━━ Logging ━━━
|
||||||
ENABLE_LOGGING=true # false = only echo user-facing messages
|
ENABLE_LOGGING=true # false = only echo user-facing messages
|
||||||
|
|
||||||
|
# ━━━ Notifications ━━━
|
||||||
|
# unRAID native notification system — set to true to enable
|
||||||
|
# Configure unRAID to send errors only: Settings → Notification Settings
|
||||||
|
NOTIFY_UNRAID=true
|
||||||
|
# Discord webhook URL — leave blank to disable
|
||||||
|
DISCORD_WEBHOOK=""
|
||||||
|
|
||||||
# ━━━ Git, Pull & Execute Script ━━━
|
# ━━━ Git, Pull & Execute Script ━━━
|
||||||
REPO_SSH="git@192.168.50.2:FailedProxy/Unraid_Scripts.git"
|
REPO_SSH="git@192.168.50.2:FailedProxy/Unraid_Scripts.git"
|
||||||
TARGET_DIR="/mnt/user/appdata/unraid_scripts"
|
TARGET_DIR="/mnt/user/appdata/unraid_scripts"
|
||||||
@@ -80,6 +87,18 @@ DAILY_SYNC_SHARES=(
|
|||||||
# clear_logs.sh system log file paths
|
# clear_logs.sh system log file paths
|
||||||
LOG_FILES=(/var/log/syslog /var/log/messages /var/log/dmesg)
|
LOG_FILES=(/var/log/syslog /var/log/messages /var/log/dmesg)
|
||||||
|
|
||||||
|
# ━━━ Docker Daily Restart ━━━
|
||||||
|
# Containers to restart daily — space-separated, case-sensitive
|
||||||
|
# These are the same containers as critical-data and other rsync profiles
|
||||||
|
DAILY_RESTART_CONTAINERS=(
|
||||||
|
"NginxProxyManager"
|
||||||
|
"Authelia"
|
||||||
|
"Dispatcharr-Iptv-Users"
|
||||||
|
"Dispatcharr"
|
||||||
|
"Dispatcharr-Basic"
|
||||||
|
"Code-Server"
|
||||||
|
)
|
||||||
|
|
||||||
# ━━━ Docker Watchdog ━━━
|
# ━━━ Docker Watchdog ━━━
|
||||||
# Containers to monitor with their memory hard limits in MB
|
# Containers to monitor with their memory hard limits in MB
|
||||||
# 20GB=20480 16GB=16384 14GB=14336 12GB=12288 10GB=10240 8GB=8192 6GB=6144 4GB=4096 1GB=1024
|
# 20GB=20480 16GB=16384 14GB=14336 12GB=12288 10GB=10240 8GB=8192 6GB=6144 4GB=4096 1GB=1024
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
# ----------------- UNRAID OPS COMMON LIBRARY (STABLE FRAMEWORK v1) ----------------------------
|
# ----------------- UNRAID OPS COMMON LIBRARY (STABLE FRAMEWORK v1) ----------------------------
|
||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
# Version: 2.2
|
# Version: 2.3
|
||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
# Changelog:
|
# Changelog:
|
||||||
# v1.0 — Initial stable framework
|
# v1.0 — Initial stable framework
|
||||||
@@ -34,6 +34,9 @@
|
|||||||
# v2.1 — ICON_ZFS and ICON_MEM added for ZFS and memory diagnostics
|
# v2.1 — ICON_ZFS and ICON_MEM added for ZFS and memory diagnostics
|
||||||
# Diagnostics icon group added to icon block
|
# Diagnostics icon group added to icon block
|
||||||
# v2.2 — ICON_WATCHDOG added for Docker watchdog monitoring operations
|
# v2.2 — ICON_WATCHDOG added for Docker watchdog monitoring operations
|
||||||
|
# v2.3 — ICON_NOTIFY added for notification operations
|
||||||
|
# notify() added — shared notification function supporting unRAID native and Discord
|
||||||
|
# NOTIFY_UNRAID and DISCORD_WEBHOOK configured in Master.conf
|
||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
@@ -82,6 +85,9 @@ ICON_ZFS="📊" # ZFS ARC statistics
|
|||||||
ICON_MEM="🧠" # memory status
|
ICON_MEM="🧠" # memory status
|
||||||
ICON_WATCHDOG="🐾" # docker watchdog monitoring operations
|
ICON_WATCHDOG="🐾" # docker watchdog monitoring operations
|
||||||
|
|
||||||
|
# Notifications
|
||||||
|
ICON_NOTIFY="🔔" # notification operations
|
||||||
|
|
||||||
# Output
|
# Output
|
||||||
ICON_INFO="ℹ️"
|
ICON_INFO="ℹ️"
|
||||||
ICON_WARN="⚠️"
|
ICON_WARN="⚠️"
|
||||||
@@ -102,6 +108,51 @@ log() {
|
|||||||
[[ "${ENABLE_LOGGING:-false}" == true ]] && echo "[LOG] $*"
|
[[ "${ENABLE_LOGGING:-false}" == true ]] && echo "[LOG] $*"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
# NOTIFICATION
|
||||||
|
# Sends a notification via unRAID native system and/or Discord webhook.
|
||||||
|
# Both channels are optional and independently controlled via Master.conf.
|
||||||
|
# unRAID native: requires NOTIFY_UNRAID=true and the dynamix notify script to be present.
|
||||||
|
# Discord: requires DISCORD_WEBHOOK to be set to a valid webhook URL.
|
||||||
|
# Severity levels: normal, warning, alert — maps to unRAID notification severity.
|
||||||
|
# Usage: notify "message" "subject" "severity"
|
||||||
|
# notify "Rsync failed: Movies" "Rsync Alert" "alert"
|
||||||
|
# notify "Daily sync complete" "Daily Sync" "normal"
|
||||||
|
# -----------------------------------------------------------------------------------------------
|
||||||
|
notify() {
|
||||||
|
local message="$1"
|
||||||
|
local subject="${2:-unRAID Notification}"
|
||||||
|
local severity="${3:-normal}"
|
||||||
|
|
||||||
|
log "$ICON_NOTIFY Sending notification: $subject — $message"
|
||||||
|
|
||||||
|
# unRAID native notification
|
||||||
|
if [[ "${NOTIFY_UNRAID:-false}" == true ]]; then
|
||||||
|
local notify_script="/usr/local/emhttp/plugins/dynamix/scripts/notify"
|
||||||
|
if [[ -x "$notify_script" ]]; then
|
||||||
|
"$notify_script" -s "$subject" -d "$message" -i "$severity" 2>/dev/null
|
||||||
|
log "$ICON_NOTIFY unRAID notification sent"
|
||||||
|
else
|
||||||
|
log "$ICON_NOTIFY unRAID notify script not found — skipping"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Discord webhook notification
|
||||||
|
if [[ -n "${DISCORD_WEBHOOK:-}" ]]; then
|
||||||
|
local hostname
|
||||||
|
hostname=$(hostname)
|
||||||
|
local payload
|
||||||
|
payload=$(printf '{"content": "%s — **%s**\\n%s"}' \
|
||||||
|
"$ICON_NOTIFY" "$subject" "$message")
|
||||||
|
if curl -s -H "Content-Type: application/json" \
|
||||||
|
-d "$payload" "$DISCORD_WEBHOOK" >/dev/null 2>&1; then
|
||||||
|
log "$ICON_NOTIFY Discord notification sent"
|
||||||
|
else
|
||||||
|
warn "Discord notification failed — check DISCORD_WEBHOOK in Master.conf"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
# DURATION FORMATTER
|
# DURATION FORMATTER
|
||||||
# Converts raw seconds into a human readable string — e.g. 10m53s or 47s
|
# Converts raw seconds into a human readable string — e.g. 10m53s or 47s
|
||||||
|
|||||||
Reference in New Issue
Block a user