Complete restructure from patterns/examples/reference to technology-focused directories: • Created technology-specific directories with comprehensive documentation: - /tdarr/ - Transcoding automation with gaming-aware scheduling - /docker/ - Container management with GPU acceleration patterns - /vm-management/ - Virtual machine automation and cloud-init - /networking/ - SSH infrastructure, reverse proxy, and security - /monitoring/ - System health checks and Discord notifications - /databases/ - Database patterns and troubleshooting - /development/ - Programming language patterns (bash, nodejs, python, vuejs) • Enhanced CLAUDE.md with intelligent context loading: - Technology-first loading rules for automatic context provision - Troubleshooting keyword triggers for emergency scenarios - Documentation maintenance protocols with automated reminders - Context window management for optimal documentation updates • Preserved valuable content from .claude/tmp/: - SSH security improvements and server inventory - Tdarr CIFS troubleshooting and Docker iptables solutions - Operational scripts with proper technology classification • Benefits achieved: - Self-contained technology directories with complete context - Automatic loading of relevant documentation based on keywords - Emergency-ready troubleshooting with comprehensive guides - Scalable structure for future technology additions - Eliminated context bloat through targeted loading 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
142 lines
5.0 KiB
Bash
Executable File
142 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# Configurable Tdarr Gaming Scheduler (Cron Version)
|
|
# Uses tdarr-schedule.conf for flexible time-based scheduling
|
|
|
|
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
|
CONFIG_FILE="${SCRIPT_DIR}/tdarr-schedule.conf"
|
|
|
|
# Load configuration
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
source "$CONFIG_FILE"
|
|
else
|
|
echo "ERROR: Configuration file not found: $CONFIG_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Set defaults if not configured
|
|
GAMING_PROCESSES=${GAMING_PROCESSES:-("steam" "lutris" "heroic" "gamemode")}
|
|
GPU_THRESHOLD=${GPU_THRESHOLD:-15}
|
|
CONTAINER_NAME=${CONTAINER_NAME:-"tdarr-node-gpu-unmapped"}
|
|
LOG_FILE=${LOG_FILE:-"/tmp/tdarr-scheduler.log"}
|
|
CHECK_GAMING_ONLY=${CHECK_GAMING_ONLY:-false}
|
|
QUIET_MODE=${QUIET_MODE:-false}
|
|
|
|
log() {
|
|
if [[ "$QUIET_MODE" != "true" ]]; then
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
|
|
fi
|
|
}
|
|
|
|
is_gaming() {
|
|
# Check for gaming processes
|
|
for process in "${GAMING_PROCESSES[@]}"; do
|
|
if pgrep -f "$process" >/dev/null 2>&1; then
|
|
return 0 # Gaming detected
|
|
fi
|
|
done
|
|
|
|
# Check GPU usage as backup indicator, but exclude Tdarr's own usage
|
|
if command -v nvidia-smi >/dev/null 2>&1; then
|
|
local gpu_usage=$(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits 2>/dev/null || echo "0")
|
|
if [[ $gpu_usage -gt $GPU_THRESHOLD ]]; then
|
|
# Check if Tdarr is running and likely causing the GPU usage
|
|
if is_tdarr_running && podman exec "$CONTAINER_NAME" pgrep -f "ffmpeg" >/dev/null 2>&1; then
|
|
log "📹 High GPU usage (${gpu_usage}%) but Tdarr transcoding active - ignoring"
|
|
return 1 # Not gaming, just Tdarr working
|
|
else
|
|
log "🎮 High GPU usage detected: ${gpu_usage}%"
|
|
return 0 # Gaming likely happening
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
return 1 # No gaming
|
|
}
|
|
|
|
is_tdarr_running() {
|
|
podman ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"
|
|
}
|
|
|
|
is_time_allowed() {
|
|
# If gaming-only mode, always allow (time restrictions ignored)
|
|
if [[ "$CHECK_GAMING_ONLY" == "true" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
local current_hour=$(date +%H | sed 's/^0//') # Remove leading zero
|
|
local current_day=$(date +%u) # 1=Monday, 7=Sunday
|
|
|
|
# Check each time block in ALLOWED_TIMES
|
|
for time_block in "${ALLOWED_TIMES[@]}"; do
|
|
# Parse format: HOUR_START-HOUR_END:DAYS
|
|
local hours_part=$(echo "$time_block" | cut -d':' -f1)
|
|
local days_part=$(echo "$time_block" | cut -d':' -f2)
|
|
|
|
local start_hour=$(echo "$hours_part" | cut -d'-' -f1 | sed 's/^0//')
|
|
local end_hour=$(echo "$hours_part" | cut -d'-' -f2 | sed 's/^0//')
|
|
|
|
# Check if current day matches
|
|
local day_match=false
|
|
if [[ "$days_part" == "daily" ]]; then
|
|
day_match=true
|
|
else
|
|
# Check specific days (e.g., "1-5" or "3,5")
|
|
if [[ "$days_part" =~ ^[0-9]-[0-9]$ ]]; then
|
|
# Range format (e.g., "1-5")
|
|
local start_day=$(echo "$days_part" | cut -d'-' -f1)
|
|
local end_day=$(echo "$days_part" | cut -d'-' -f2)
|
|
if [[ $current_day -ge $start_day && $current_day -le $end_day ]]; then
|
|
day_match=true
|
|
fi
|
|
else
|
|
# Comma-separated format (e.g., "1,3,5")
|
|
if [[ ",$days_part," =~ ,$current_day, ]]; then
|
|
day_match=true
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Check if current time matches and day matches
|
|
if [[ "$day_match" == "true" ]]; then
|
|
# Handle overnight periods (e.g., 22-07)
|
|
if [[ $start_hour -gt $end_hour ]]; then
|
|
# Overnight: 22-07 means 22:00-23:59 OR 00:00-07:59
|
|
if [[ $current_hour -ge $start_hour || $current_hour -le $end_hour ]]; then
|
|
return 0 # Time allowed
|
|
fi
|
|
else
|
|
# Same day: 09-17 means 09:00-17:59
|
|
if [[ $current_hour -ge $start_hour && $current_hour -le $end_hour ]]; then
|
|
return 0 # Time allowed
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
return 1 # Time not allowed
|
|
}
|
|
|
|
# Main logic
|
|
if is_gaming; then
|
|
# Gaming detected - stop Tdarr if running
|
|
if is_tdarr_running; then
|
|
log "🎮 Gaming detected - Stopping Tdarr Node"
|
|
"${SCRIPT_DIR}/stop-tdarr-gpu-podman.sh" >/dev/null 2>&1
|
|
fi
|
|
else
|
|
# No gaming - check if we should start Tdarr
|
|
if is_time_allowed; then
|
|
if ! is_tdarr_running; then
|
|
local current_time=$(date '+%H:%M')
|
|
log "🎬 Starting Tdarr Node at ${current_time} (allowed time, no gaming)"
|
|
"${SCRIPT_DIR}/start-tdarr-gpu-podman-clean.sh" >/dev/null 2>&1
|
|
fi
|
|
else
|
|
# Not allowed time - stop if running
|
|
if is_tdarr_running; then
|
|
local current_time=$(date '+%H:%M')
|
|
log "⏰ Stopping Tdarr Node at ${current_time} (outside allowed hours)"
|
|
"${SCRIPT_DIR}/stop-tdarr-gpu-podman.sh" >/dev/null 2>&1
|
|
fi
|
|
fi
|
|
fi |