267 lines
11 KiB
Bash
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 |