From 7cdd9345b593bb677bcd18742503801ebd709a8c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 12 Jan 2026 18:05:49 +0000 Subject: [PATCH] Implement global drive detection - detect once, use everywhere MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MAJOR IMPROVEMENT: Drive detection now happens ONCE at startup and is reused by all services, instead of each service detecting separately. 1. **New detect_drives() Function:** - Runs once before service selection menu - Scans ~/drives directory for all mounted drives - Shows drive name, path, size, used space, available space - Sets global variables for all services to use 2. **Global Variables Set:** - PRIMARY_DRIVE: name of first drive (e.g., "storage1") - PRIMARY_DRIVE_PATH: full path to first drive - DRIVES_DETECTED: true/false - DRIVES_DIR: base drives directory - AVAILABLE_DRIVES_COUNT: number of drives 3. **Display Example:** ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DETECTED DRIVES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✓ storage1 Path: /home/user/drives/storage1 Size: 2.0T (Used: 800G, Available: 1.2T) ✓ backup Path: /home/user/drives/backup Size: 4.0T (Used: 1.5T, Available: 2.5T) Using 'storage1' as primary drive for default paths ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` 4. **Updated Services to Use Global Detection:** - Immich: photos/immich-uploads - AudioBookshelf: audiobooks - Emby: media - Jellyfin: media - ARM: ripped - FileBrowser: (root browse) - LMS: music 5. **Benefits:** - Detect drives only once (faster) - Consistent paths across all services - Shows actual drive information (size, usage) - Falls back to $HOME if no ~/drives exists - All services use PRIMARY_DRIVE_PATH variable This fixes user complaint: "There is no ~/drives.... it should detect which drives are already in ~/drives and offer to use one of those" --- ubuntu-post-install.sh | 114 +++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 32 deletions(-) diff --git a/ubuntu-post-install.sh b/ubuntu-post-install.sh index 894af6a..93ada3c 100644 --- a/ubuntu-post-install.sh +++ b/ubuntu-post-install.sh @@ -1526,6 +1526,74 @@ check_service_exists() { fi } +# ============================================================================ +# DETECT AVAILABLE DRIVES (RUN ONCE) +# ============================================================================ +detect_drives() { + # Global variables set by this function: + # - DRIVES_DETECTED: true/false + # - PRIMARY_DRIVE: name of first drive (e.g., "storage1") + # - PRIMARY_DRIVE_PATH: full path to first drive + # - DRIVES_DIR: base drives directory + # - AVAILABLE_DRIVES_COUNT: number of drives found + + DRIVES_DIR="$ACTUAL_HOME/drives" + DRIVES_DETECTED=false + PRIMARY_DRIVE="" + PRIMARY_DRIVE_PATH="" + AVAILABLE_DRIVES_COUNT=0 + + if [ -d "$DRIVES_DIR" ]; then + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " DETECTED DRIVES" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + + for drive in "$DRIVES_DIR"/*; do + if [ -d "$drive" ]; then + drive_name=$(basename "$drive") + drive_size=$(df -h "$drive" 2>/dev/null | awk 'NR==2 {print $2}') + drive_used=$(df -h "$drive" 2>/dev/null | awk 'NR==2 {print $3}') + drive_avail=$(df -h "$drive" 2>/dev/null | awk 'NR==2 {print $4}') + + echo " ✓ $drive_name" + if [ -n "$drive_size" ]; then + echo " Path: $drive" + echo " Size: $drive_size (Used: $drive_used, Available: $drive_avail)" + else + echo " Path: $drive" + fi + + # Set PRIMARY_DRIVE to the first drive found + if [ -z "$PRIMARY_DRIVE" ]; then + PRIMARY_DRIVE="$drive_name" + PRIMARY_DRIVE_PATH="$drive" + fi + + AVAILABLE_DRIVES_COUNT=$((AVAILABLE_DRIVES_COUNT + 1)) + fi + done + + if [ $AVAILABLE_DRIVES_COUNT -gt 0 ]; then + DRIVES_DETECTED=true + echo "" + echo " Using '$PRIMARY_DRIVE' as primary drive for default paths" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + fi + fi + + # If no drives detected, use home directory + if [ "$DRIVES_DETECTED" = "false" ]; then + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " No ~/drives directory found" + echo " Using $ACTUAL_HOME for default paths" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + PRIMARY_DRIVE_PATH="$ACTUAL_HOME" + fi +} + # ============================================================================ # SHOW CURRENT INSTALLATION STATUS # ============================================================================ @@ -2365,6 +2433,11 @@ else chown "$ACTUAL_USER:$ACTUAL_USER" "$DOCKER_DIR" fi + # ============================================================================ + # DETECT DRIVES (ONCE FOR ALL SERVICES) + # ============================================================================ + detect_drives + # ============================================================================ # SERVICE SELECTION MENU # ============================================================================ @@ -2701,28 +2774,9 @@ else echo " 2. EXTERNAL folder - Where EXISTING photos are (read-only access)" echo "" - # Detect available drives - AVAILABLE_DRIVES="" - if [ -d "$ACTUAL_HOME/drives" ]; then - echo "Detected drives:" - for drive in "$ACTUAL_HOME/drives"/*; do - if [ -d "$drive" ]; then - drive_name=$(basename "$drive") - echo " - $drive_name ($drive)" - if [ -z "$AVAILABLE_DRIVES" ]; then - AVAILABLE_DRIVES="$drive_name" - fi - fi - done - echo "" - fi - + # Use globally detected drives # Upload location (for new photos) - if [ -n "$AVAILABLE_DRIVES" ]; then - DEFAULT_UPLOAD_DIR="$ACTUAL_HOME/drives/$AVAILABLE_DRIVES/photos/immich-uploads" - else - DEFAULT_UPLOAD_DIR="$ACTUAL_HOME/photos/immich-uploads" - fi + DEFAULT_UPLOAD_DIR="$PRIMARY_DRIVE_PATH/photos/immich-uploads" echo "NEW UPLOADS (from phone apps, web uploads):" echo " Default: $DEFAULT_UPLOAD_DIR" prompt_text " Upload folder path:" "$DEFAULT_UPLOAD_DIR" UPLOAD_LOCATION 2>/dev/null || UPLOAD_LOCATION="$DEFAULT_UPLOAD_DIR" @@ -2730,11 +2784,7 @@ else # External library (for existing photos) echo "" - if [ -n "$AVAILABLE_DRIVES" ]; then - DEFAULT_EXTERNAL_DIR="$ACTUAL_HOME/drives/$AVAILABLE_DRIVES/photos" - else - DEFAULT_EXTERNAL_DIR="$ACTUAL_HOME/photos" - fi + DEFAULT_EXTERNAL_DIR="$PRIMARY_DRIVE_PATH/photos" echo "EXISTING PHOTOS (external library, read-only):" echo " Default: $DEFAULT_EXTERNAL_DIR" echo " Leave blank if you don't have existing photos to import" @@ -2941,7 +2991,7 @@ IMMICH_ENV mkdir -p "$ABS_DIR" cd "$ABS_DIR" - prompt_text "Path to audiobooks folder [default: $ACTUAL_HOME/drives/primary/audiobooks]:" "$ACTUAL_HOME/drives/primary/audiobooks" AUDIOBOOKS_PATH + prompt_text "Path to audiobooks folder [default: $PRIMARY_DRIVE_PATH/audiobooks]:" "$PRIMARY_DRIVE_PATH/audiobooks" AUDIOBOOKS_PATH cat > docker-compose.yml << ABS_COMPOSE name: audiobookshelf @@ -3014,7 +3064,7 @@ ABS_ENV mkdir -p "$EMBY_DIR" cd "$EMBY_DIR" - prompt_text "Path to media folder [default: $ACTUAL_HOME/drives/primary/media]:" "$ACTUAL_HOME/drives/primary/media" MEDIA_PATH + prompt_text "Path to media folder [default: $PRIMARY_DRIVE_PATH/media]:" "$PRIMARY_DRIVE_PATH/media" MEDIA_PATH cat > docker-compose.yml << EMBY_COMPOSE name: emby @@ -3088,7 +3138,7 @@ EMBY_ENV mkdir -p "$ARM_DIR" cd "$ARM_DIR" - prompt_text "Path for ripped media output [default: $ACTUAL_HOME/drives/primary/ripped]:" "$ACTUAL_HOME/drives/primary/ripped" ARM_OUTPUT + prompt_text "Path for ripped media output [default: $PRIMARY_DRIVE_PATH/ripped]:" "$PRIMARY_DRIVE_PATH/ripped" ARM_OUTPUT # Detect optical drives echo "" @@ -3176,7 +3226,7 @@ ARM_ENV mkdir -p "$FB_DIR" cd "$FB_DIR" - prompt_text "Path to browse [default: $ACTUAL_HOME/drives/primary]:" "$ACTUAL_HOME/drives/primary" FB_PATH + prompt_text "Path to browse [default: $PRIMARY_DRIVE_PATH]:" "$PRIMARY_DRIVE_PATH" FB_PATH cat > docker-compose.yml << FB_COMPOSE name: filebrowser @@ -4338,7 +4388,7 @@ backend = auto" mkdir -p "$LMS_DIR" cd "$LMS_DIR" - prompt_text "Path to music folder [default: $ACTUAL_HOME/drives/primary/music]:" "$ACTUAL_HOME/drives/primary/music" MUSIC_PATH + prompt_text "Path to music folder [default: $PRIMARY_DRIVE_PATH/music]:" "$PRIMARY_DRIVE_PATH/music" MUSIC_PATH cat > docker-compose.yml << LMS_COMPOSE name: lyrion @@ -4626,7 +4676,7 @@ MC_ENV mkdir -p "$JELLYFIN_DIR" cd "$JELLYFIN_DIR" - prompt_text "Path to media folder [default: $ACTUAL_HOME/drives/primary/media]:" "$ACTUAL_HOME/drives/primary/media" MEDIA_PATH + prompt_text "Path to media folder [default: $PRIMARY_DRIVE_PATH/media]:" "$PRIMARY_DRIVE_PATH/media" MEDIA_PATH # Get render group ID for hardware acceleration RENDER_GID=$(getent group render | cut -d: -f3 2>/dev/null || echo "989")