162 lines
9.0 KiB
Bash
Executable File
162 lines
9.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# ==============================================================================================
|
|
# ============================= Transcode Management ===========================================
|
|
# ==============================================================================================
|
|
# Orchestrator — runs transcode_cleanup.sh then transcode_manager.sh in the correct order.
|
|
# Replace individual transcode_manager and transcode_cleanup cron entries with this.
|
|
# Schedule: */7 * * * * (every 7 minutes via User Scripts plugin)
|
|
#
|
|
# ── WHY CLEANUP BEFORE MANAGER ────────────────────────────────────────────────────────────────
|
|
# Cleanup runs first — removes stale segment files from ended sessions.
|
|
# Manager runs after — threshold decisions based on real current usage post-cleanup.
|
|
# Without this order, stale files inflate the ramdisk usage reading and trigger
|
|
# unnecessary SSD flips even when active sessions would fit on the ramdisk.
|
|
#
|
|
# ── WHAT EACH SCRIPT DOES ─────────────────────────────────────────────────────────────────────
|
|
# transcode_cleanup.sh — removes aged segment files not open by any process
|
|
# uses lsof for O(1) per-file active check (never per-file lsof)
|
|
# also triggers flip-back to ramdisk after cleanup if recovered ✅
|
|
#
|
|
# transcode_manager.sh — checks ramdisk usage against thresholds
|
|
# flips symlink between ramdisk and SSD as needed
|
|
# writes one entry to TRANSCODE_DAILY_LOG after each run
|
|
# shows active Emby sessions with play method
|
|
#
|
|
# ── DAILY LOG ─────────────────────────────────────────────────────────────────────────────────
|
|
# transcode_manager.sh writes to TRANSCODE_DAILY_LOG after each run:
|
|
# Format: DATE|RAMDISK_USED_GB|FLIP_COUNT|RAM_SESSIONS|SSD_SESSIONS
|
|
# This orchestrator does NOT write its own log — manager handles it ✅
|
|
# Log trimmed to TRANSCODE_LOG_RETENTION days by manager on each write.
|
|
# Read by sunday_morning_coffee_report.sh and weekly_health_digest.sh.
|
|
#
|
|
# ── HOST AWARENESS ────────────────────────────────────────────────────────────────────────────
|
|
# detect_hosts() sets MY_ID and aliases RAMDISK_PATH, TRANSCODE_SSD, RAMDISK_WARN_GB etc.
|
|
# Each server manages its own transcode location independently.
|
|
#
|
|
# ── SAFEGUARDS ────────────────────────────────────────────────────────────────────────────────
|
|
# Root check — mount and docker operations require root
|
|
# acquire_lock — prevents concurrent 3-minute cycles overlapping
|
|
# detect_hosts() — correct paths per host
|
|
# --dry-run — passed through to both child scripts
|
|
# Exit code — worst exit code of both scripts returned
|
|
#
|
|
# ── CONFIGURATION (master.conf) ───────────────────────────────────────────────────────────────
|
|
# TRANSCODE_DAILY_LOG — daily stats log (written by transcode_manager.sh)
|
|
# TRANSCODE_LOG_RETENTION — days to keep (trimmed by manager)
|
|
# TRANSCODE_STATE_FILE — current state (ramdisk_used, flip_count etc.)
|
|
# All TRANSCODE_* threshold vars — see master.conf Transcode Manager section
|
|
#
|
|
# ── USAGE ─────────────────────────────────────────────────────────────────────────────────────
|
|
# transcode_management.sh — normal run (every 7 minutes via cron)
|
|
# transcode_management.sh --dry-run — preview without changes (passed to children)
|
|
# transcode_management.sh --status — show configuration and current state
|
|
# transcode_management.sh --log — verbose output from both child scripts
|
|
# ==============================================================================================
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
source "$SCRIPT_DIR/../load_config.sh"
|
|
|
|
parse_args "$@"
|
|
|
|
CLEANUP_SCRIPT="$SCRIPT_DIR/../Transcodes/transcode_cleanup.sh"
|
|
MANAGER_SCRIPT="$SCRIPT_DIR/../Transcodes/transcode_manager.sh"
|
|
|
|
# ==============================================================================================
|
|
# ━━━ Setup ━━━
|
|
# ==============================================================================================
|
|
if [[ "$EUID" -ne 0 ]]; then
|
|
error "Must be run as root"
|
|
exit 1
|
|
fi
|
|
|
|
acquire_lock "wait"
|
|
|
|
if ! command -v docker &>/dev/null; then
|
|
error "Docker command not found"
|
|
exit 1
|
|
fi
|
|
|
|
# detect_hosts() sets MY_ID and aliases all HOST*_TRANSCODE_* vars
|
|
detect_hosts
|
|
|
|
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — passing through to child scripts"
|
|
|
|
# ==============================================================================================
|
|
# ━━━ Status ━━━
|
|
# ==============================================================================================
|
|
if [[ "$SHOW_STATUS" == true ]]; then
|
|
echo ""
|
|
echo "━━━━━ $ICON_SUMMARY TRANSCODE MANAGEMENT STATUS ━━━━━"
|
|
echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)"
|
|
echo "$ICON_RAM Ramdisk: $RAMDISK_PATH ($RAMDISK_SIZE)"
|
|
echo "$ICON_DISK SSD fallback: $TRANSCODE_SSD"
|
|
echo "$ICON_LINK Symlink: $TRANSCODE_LINK"
|
|
echo "$ICON_TIME Schedule: every 7 minutes"
|
|
echo ""
|
|
echo "━━━ Child Scripts ━━━"
|
|
[[ -f "$CLEANUP_SCRIPT" ]] && \
|
|
echo " $ICON_SUCCESS transcode_cleanup.sh — found" || \
|
|
echo " $ICON_ERROR transcode_cleanup.sh — NOT FOUND at $CLEANUP_SCRIPT"
|
|
[[ -f "$MANAGER_SCRIPT" ]] && \
|
|
echo " $ICON_SUCCESS transcode_manager.sh — found" || \
|
|
echo " $ICON_ERROR transcode_manager.sh — NOT FOUND at $MANAGER_SCRIPT"
|
|
echo ""
|
|
echo "━━━ Daily Log ━━━"
|
|
if [[ -f "${TRANSCODE_DAILY_LOG:-}" ]] && [[ -s "$TRANSCODE_DAILY_LOG" ]]; then
|
|
ENTRY_COUNT=$(wc -l < "$TRANSCODE_DAILY_LOG")
|
|
OLDEST=$(awk -F'|' 'NR==1{print $1}' "$TRANSCODE_DAILY_LOG")
|
|
NEWEST=$(awk -F'|' 'END{print $1}' "$TRANSCODE_DAILY_LOG")
|
|
echo " $ICON_SUCCESS $TRANSCODE_DAILY_LOG ($ENTRY_COUNT entries, $OLDEST → $NEWEST)"
|
|
else
|
|
echo " $ICON_SKIP $TRANSCODE_DAILY_LOG — no data yet"
|
|
fi
|
|
echo ""
|
|
echo "━━━ Current State ━━━"
|
|
if [[ -f "${TRANSCODE_STATE_FILE:-/tmp/transcode_state.db}" ]]; then
|
|
while IFS='=' read -r key val; do
|
|
[[ -n "$key" ]] && echo " $key = $val"
|
|
done < "${TRANSCODE_STATE_FILE:-/tmp/transcode_state.db}"
|
|
else
|
|
echo " State file not found (ramdisk_setup.sh creates it at array start)"
|
|
fi
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━"
|
|
exit 0
|
|
fi
|
|
|
|
# ==============================================================================================
|
|
# ━━━ Validate Child Scripts ━━━
|
|
# ==============================================================================================
|
|
if [[ ! -f "$CLEANUP_SCRIPT" ]]; then
|
|
error "transcode_cleanup.sh not found: $CLEANUP_SCRIPT"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$MANAGER_SCRIPT" ]]; then
|
|
error "transcode_manager.sh not found: $MANAGER_SCRIPT"
|
|
exit 1
|
|
fi
|
|
|
|
# ==============================================================================================
|
|
# ━━━ Run Cleanup ━━━
|
|
# ==============================================================================================
|
|
DRY_FLAG=""
|
|
[[ "$DRY_RUN" == true ]] && DRY_FLAG="--dry-run"
|
|
|
|
bash "$CLEANUP_SCRIPT" $DRY_FLAG
|
|
CLEANUP_EXIT=$?
|
|
|
|
# ==============================================================================================
|
|
# ━━━ Run Manager ━━━
|
|
# ==============================================================================================
|
|
# transcode_manager.sh writes to TRANSCODE_DAILY_LOG after each run
|
|
# No --no-log flag here — manager owns the log write for this cycle ✅
|
|
bash "$MANAGER_SCRIPT" $DRY_FLAG
|
|
MANAGER_EXIT=$?
|
|
|
|
# ==============================================================================================
|
|
# ━━━ Exit ━━━
|
|
# ==============================================================================================
|
|
# Return worst exit code — caller knows if either script failed
|
|
[[ "$CLEANUP_EXIT" -ne 0 || "$MANAGER_EXIT" -ne 0 ]] && exit 1
|
|
exit 0 |