Bash common.sh: consolidate docker_cmd/retry_docker/verify_running/emby_api, fix tailscale dups
common.sh gains: - docker_cmd() + verify_running() + retry_docker() — removed from all 3 Docker_Essentials scripts where they were byte-for-byte duplicates - emby_api(endpoint, [timeout=30]) — removed from 6 Media/Tools scripts that each defined their own _emby_api() with the same curl/parse/error pattern; call sites renamed emby_api - format_duration() extended with days/hours branch (was capped at minutes+seconds) - notify() comment: scripts do not need to preflight the notify script via validate_unraid_cmd Tailscale deduplication: - arr_sync.sh: _resolve_node_ip() and inline block in _delete_remote_item() both replaced with resolve_tailscale_ip() from common.sh - git_pull_execute.sh: inline tailscale ip -4 replaced with resolve_tailscale_ip() (adds the tailscale status fallback that was missing)
This commit is contained in:
@@ -228,6 +228,7 @@ notify() {
|
||||
|
||||
log "$ICON_NOTIFY Sending notification: $subject — $message"
|
||||
|
||||
# Guard is built in — scripts do NOT need to validate_unraid_cmd for the notify script.
|
||||
if [[ "${NOTIFY_UNRAID:-false}" == true ]]; then
|
||||
local notify_script="/usr/local/emhttp/plugins/dynamix/scripts/notify"
|
||||
if [[ -x "$notify_script" ]]; then
|
||||
@@ -261,9 +262,14 @@ notify() {
|
||||
|
||||
format_duration() {
|
||||
local secs=$1
|
||||
local mins=$((secs / 60))
|
||||
local rem=$((secs % 60))
|
||||
[[ $mins -gt 0 ]] && echo "${mins}m${rem}s" || echo "${rem}s"
|
||||
local days=$(( secs / 86400 ))
|
||||
local hrs=$(( (secs % 86400) / 3600 ))
|
||||
local mins=$(( (secs % 3600) / 60 ))
|
||||
local rem=$(( secs % 60 ))
|
||||
if [[ $days -gt 0 ]]; then echo "${days}d ${hrs}h ${mins}m"
|
||||
elif [[ $hrs -gt 0 ]]; then echo "${hrs}h ${mins}m"
|
||||
elif [[ $mins -gt 0 ]]; then echo "${mins}m${rem}s"
|
||||
else echo "${rem}s"; fi
|
||||
}
|
||||
|
||||
# ==============================================================================================
|
||||
@@ -1102,6 +1108,72 @@ check_remote_disks() {
|
||||
# Tracks which remote containers were running before stop — used by start_containers()
|
||||
RUNNING_CONTAINERS=()
|
||||
|
||||
# ── Docker command helpers (used by docker_daily_restart, docker_weekly_restart, docker_update) ──
|
||||
|
||||
# Default timeouts — scripts can override before calling.
|
||||
DOCKER_TIMEOUT=${DOCKER_TIMEOUT:-30} # seconds before docker command is killed
|
||||
RESTART_VERIFY_WAIT=${RESTART_VERIFY_WAIT:-5} # seconds to wait before checking state post-restart
|
||||
|
||||
# Run a docker command with a hard timeout. Returns 124 on timeout, else docker's exit code.
|
||||
docker_cmd() {
|
||||
timeout "$DOCKER_TIMEOUT" "$@"
|
||||
local exit_code=$?
|
||||
if [[ "$exit_code" -eq 124 ]]; then
|
||||
error "Docker command timed out after ${DOCKER_TIMEOUT}s: $*"
|
||||
return 1
|
||||
fi
|
||||
return "$exit_code"
|
||||
}
|
||||
|
||||
# Verify a container is still running after a restart.
|
||||
# Waits RESTART_VERIFY_WAIT seconds to let it settle, then checks State.Running.
|
||||
verify_running() {
|
||||
local container="$1"
|
||||
sleep "$RESTART_VERIFY_WAIT"
|
||||
local state
|
||||
state=$(docker inspect -f '{{.State.Running}}' "$container" 2>/dev/null)
|
||||
if [[ "$state" != "true" ]]; then
|
||||
error "$container failed to stay running after restart — may have crashed"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Retry a docker command up to RETRY_COUNT times, sleeping SLEEP seconds between attempts.
|
||||
retry_docker() {
|
||||
local attempt=1
|
||||
while [[ "$attempt" -le "$RETRY_COUNT" ]]; do
|
||||
log "$ICON_RETRY Attempt $attempt of $RETRY_COUNT: $*"
|
||||
if docker_cmd "$@"; then
|
||||
log "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
|
||||
}
|
||||
|
||||
# ── Emby API helper ───────────────────────────────────────────────────────────
|
||||
# General Emby REST call. Uses EMBY_URL and EMBY_API_KEY (aliased by detect_hosts).
|
||||
# Usage: emby_api <endpoint> [timeout_seconds]
|
||||
# Prints response body on 200; returns 1 on HTTP error or curl failure.
|
||||
emby_api() {
|
||||
local endpoint="$1" max_time="${2:-30}"
|
||||
local response http_code body
|
||||
response=$(curl -sf --max-time "$max_time" \
|
||||
-H "X-Emby-Token: $EMBY_API_KEY" \
|
||||
-w "\n%{http_code}" \
|
||||
"${EMBY_URL}/${endpoint}" 2>/dev/null)
|
||||
http_code=$(echo "$response" | tail -1)
|
||||
body=$(echo "$response" | head -n -1)
|
||||
[[ "$http_code" != "200" ]] && { error "Emby API HTTP $http_code: $endpoint"; return 1; }
|
||||
echo "$body"
|
||||
}
|
||||
|
||||
# Stop containers on the REMOTE server via SSH.
|
||||
# Reads CRITICAL_CONTAINER_NAMES — set from profile arrays by rsync.sh.
|
||||
# Tracks running state in RUNNING_CONTAINERS for restart after sync.
|
||||
|
||||
Reference in New Issue
Block a user