Files
Varaverk/Transcodes/ramdisk_setup.sh
T

267 lines
11 KiB
Bash

#!/bin/bash
# -----------------------------------------------------------------------------------------------
# --------------------------------- Ramdisk Setup Script ---------------------------------------
# -----------------------------------------------------------------------------------------------
# Creates a tmpfs ramdisk for Emby transcodes and points the transcode symlink at it.
# Run once at array start via User Scripts plugin — scheduled as "At Startup of Array".
# If ramdisk already mounted reports status and exits cleanly without remounting.
#
# Creates:
# RAMDISK_PATH — tmpfs mount point (fast, in-memory transcode location)
# TRANSCODE_SSD — SSD fallback directory (created if missing)
# TRANSCODE_LINK — symlink pointing at ramdisk by default
#
# All configuration in Master.conf under Transcode Manager section.
# Supports --dry-run to preview what would be created without making changes.
# -----------------------------------------------------------------------------------------------
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 ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
fi
success "Running as root"
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_SUMMARY Status ━━━
# -----------------------------------------------------------------------------------------------
if [[ "$SHOW_STATUS" == true ]]; then
echo ""
echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━"
echo "$ICON_RAM Ramdisk path: $RAMDISK_PATH"
echo "$ICON_RAM Ramdisk size: $RAMDISK_SIZE"
echo "$ICON_LINK Transcode link: $TRANSCODE_LINK"
echo "$ICON_DISK SSD fallback: $TRANSCODE_SSD"
echo "$ICON_GEAR Owner: $TRANSCODE_OWNER"
echo "$ICON_GEAR Mode: $TRANSCODE_MODE"
echo "$ICON_GEAR Dry Run: $DRY_RUN"
# Show current mount state
if mountpoint -q "$RAMDISK_PATH" 2>/dev/null; then
CURRENT_USAGE=$(df -BG "$RAMDISK_PATH" | awk 'NR==2 {print $3}')
CURRENT_AVAIL=$(df -BG "$RAMDISK_PATH" | awk 'NR==2 {print $4}')
echo "$ICON_RAM Current usage: $CURRENT_USAGE used / $CURRENT_AVAIL available"
else
echo "$ICON_RAM Ramdisk: not mounted"
fi
if [[ -L "$TRANSCODE_LINK" ]]; then
echo "$ICON_LINK Current target: $(readlink "$TRANSCODE_LINK")"
else
echo "$ICON_LINK Symlink: not set"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━"
exit 0
fi
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made"
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_RAM Ramdisk Setup ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_RAM Ramdisk Setup ━━━"
echo "$ICON_RAM Path: $RAMDISK_PATH"
echo "$ICON_RAM Size: $RAMDISK_SIZE"
echo ""
START=$(date +%s)
SETUP_SUCCESS=true
# Check if ramdisk already mounted
if mountpoint -q "$RAMDISK_PATH" 2>/dev/null; then
CURRENT_USAGE=$(df -BG "$RAMDISK_PATH" | awk 'NR==2 {print $3}')
CURRENT_AVAIL=$(df -BG "$RAMDISK_PATH" | awk 'NR==2 {print $4}')
info "$ICON_RAM Ramdisk already mounted — $CURRENT_USAGE used / $CURRENT_AVAIL available"
info "Skipping mount — verifying symlink and permissions"
else
# Create mount point
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would create $RAMDISK_PATH"
warn "DRY RUN — would mount tmpfs ${RAMDISK_SIZE} at $RAMDISK_PATH"
else
info "Creating ramdisk mount point: $RAMDISK_PATH"
mkdir -p "$RAMDISK_PATH" || {
error "Failed to create $RAMDISK_PATH"
notify "Ramdisk setup failed on $(hostname) — could not create mount point" "Ramdisk Setup" "warning"
exit 1
}
info "$ICON_RAM Mounting tmpfs ${RAMDISK_SIZE} at $RAMDISK_PATH..."
if mount -t tmpfs -o size="$RAMDISK_SIZE" tmpfs "$RAMDISK_PATH"; then
success "Ramdisk mounted — ${RAMDISK_SIZE} at $RAMDISK_PATH"
else
error "Failed to mount ramdisk at $RAMDISK_PATH"
notify "Ramdisk setup failed on $(hostname) — mount failed" "Ramdisk Setup" "warning"
exit 1
fi
fi
fi
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_DISK SSD Fallback ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_DISK SSD Fallback ━━━"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would create SSD fallback: $TRANSCODE_SSD"
else
if [[ -d "$TRANSCODE_SSD" ]]; then
info "$ICON_DISK SSD fallback already exists: $TRANSCODE_SSD"
else
info "Creating SSD fallback directory: $TRANSCODE_SSD"
if mkdir -p "$TRANSCODE_SSD"; then
success "SSD fallback created: $TRANSCODE_SSD"
else
error "Failed to create SSD fallback: $TRANSCODE_SSD"
SETUP_SUCCESS=false
fi
fi
fi
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_LINK Symlink ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_LINK Symlink ━━━"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would set $TRANSCODE_LINK$RAMDISK_PATH"
else
# Remove existing symlink or directory at link path
if [[ -L "$TRANSCODE_LINK" ]]; then
CURRENT_TARGET=$(readlink "$TRANSCODE_LINK")
if [[ "$CURRENT_TARGET" == "$RAMDISK_PATH" ]]; then
info "$ICON_LINK Symlink already points to ramdisk — no change needed"
else
info "$ICON_LINK Updating symlink: $CURRENT_TARGET$RAMDISK_PATH"
ln -sfn "$RAMDISK_PATH" "$TRANSCODE_LINK" || {
error "Failed to update symlink"
SETUP_SUCCESS=false
}
fi
elif [[ -e "$TRANSCODE_LINK" ]]; then
warn "$TRANSCODE_LINK exists but is not a symlink — removing and replacing"
rm -rf "$TRANSCODE_LINK"
ln -sfn "$RAMDISK_PATH" "$TRANSCODE_LINK" || {
error "Failed to create symlink"
SETUP_SUCCESS=false
}
else
info "Creating symlink: $TRANSCODE_LINK$RAMDISK_PATH"
# Ensure parent directory exists
mkdir -p "$(dirname "$TRANSCODE_LINK")"
ln -sfn "$RAMDISK_PATH" "$TRANSCODE_LINK" || {
error "Failed to create symlink"
SETUP_SUCCESS=false
}
fi
if [[ "$SETUP_SUCCESS" == true ]]; then
success "$ICON_LINK $TRANSCODE_LINK$RAMDISK_PATH"
fi
fi
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_GEAR Transcoding-temp Directory ━━━
# Creates the transcoding-temp folder on the ramdisk proactively.
# If this folder doesn't exist on the ramdisk Emby creates it wherever it finds
# a writable path first — which may be the SSD fallback — locking all sessions
# onto SSD even when the symlink points at the ramdisk.
# Creating it here guarantees Emby always finds it on the ramdisk at session start.
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_GEAR Transcoding Temp Directory ━━━"
TRANSCODE_TEMP_DIR="${RAMDISK_PATH}/transcoding-temp"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would create $TRANSCODE_TEMP_DIR"
else
if [[ -d "$TRANSCODE_TEMP_DIR" ]]; then
info "transcoding-temp already exists on ramdisk"
else
mkdir -p "$TRANSCODE_TEMP_DIR" && \
success "Created transcoding-temp on ramdisk: $TRANSCODE_TEMP_DIR" || \
{ error "Failed to create transcoding-temp on ramdisk"; SETUP_SUCCESS=false; }
fi
# Apply correct permissions so Emby (abc/nobody:users) can write to it
if [[ -d "$TRANSCODE_TEMP_DIR" ]]; then
chmod "$TRANSCODE_CHMOD" "$TRANSCODE_TEMP_DIR"
chown "$TRANSCODE_OWNER" "$TRANSCODE_TEMP_DIR"
success "Permissions set on transcoding-temp"
fi
fi
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_GEAR Permissions ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_GEAR Permissions ━━━"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would apply $TRANSCODE_MODE $TRANSCODE_OWNER to $RAMDISK_PATH and $TRANSCODE_SSD"
else
for path in "$RAMDISK_PATH" "$TRANSCODE_SSD"; do
if [[ -d "$path" ]]; then
chmod "$TRANSCODE_MODE" "$path"
chown "$TRANSCODE_OWNER" "$path"
success "Permissions set: $path"
fi
done
fi
# -----------------------------------------------------------------------------------------------
# Initialise state file
# -----------------------------------------------------------------------------------------------
if [[ "$DRY_RUN" == false ]]; then
STATE_FILE="/tmp/transcode_state.db"
NOW=$(date +%s)
cat > "$STATE_FILE" <<EOF
current_target=$RAMDISK_PATH
last_flip_time=$NOW
flip_count_hour=0
flip_hour_start=$NOW
EOF
log "State file initialised: $STATE_FILE"
fi
END=$(date +%s)
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_SUMMARY Summary ━━━
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━━━ $ICON_SUMMARY RAMDISK SETUP SUMMARY ━━━━━"
echo "$ICON_RAM Ramdisk: $RAMDISK_PATH ($RAMDISK_SIZE)"
echo "$ICON_DISK Fallback: $TRANSCODE_SSD"
echo "$ICON_LINK Symlink: $TRANSCODE_LINK"
echo "$ICON_TIME Duration: $(format_duration $((END - START)))"
if [[ "$DRY_RUN" == true ]]; then
echo "$ICON_WARN Status: DRY RUN — no changes made"
elif [[ "$SETUP_SUCCESS" == true ]]; then
echo "$ICON_DONE Status: $ICON_SUCCESS DONE"
notify "Ramdisk setup complete on $(hostname)${RAMDISK_SIZE} mounted at $RAMDISK_PATH" "Ramdisk Setup" "normal"
else
echo "$ICON_ERROR Status: $ICON_ERROR SETUP HAD ERRORS"
notify "Ramdisk setup completed with errors on $(hostname)" "Ramdisk Setup" "warning"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
[[ "$SETUP_SUCCESS" == false ]] && exit 1
exit 0