#!/bin/bash # AutoNAS - Unified AutoNAS Management Tool # Combines manager, configuration, and all other functionality into one script # Usage: autonas [options] # Load core AutoNAS library if [[ -f "/usr/local/bin/autonas-core.sh" ]]; then source "/usr/local/bin/autonas-core.sh" else echo "Error: AutoNAS core library not found at /usr/local/bin/autonas-core.sh" >&2 exit 1 fi # Function to handle disk attachment handle_attach() { local uuid="$1" log_message "AutoNAS attach operation started for UUID: $uuid" # Get configuration for this UUID local config config=$(get_disk_config "$uuid") if [[ -z "$config" ]]; then log_message "No configuration found for UUID: $uuid - disk will be ignored" log_message "To configure this disk, run: autonas-config.sh add" return 1 fi log_message "Handling disk attachment for UUID: $uuid" # Parse configuration local parsed parsed=($(parse_config "$config")) local cfg_uuid="${parsed[0]}" local name="${parsed[1]}" local ip="${parsed[2]}" local interface="${parsed[3]}" local mount_point="${parsed[4]}" local nfs_options="${parsed[5]}" log_message "Processing disk: $name (IP: $ip, Mount: $mount_point)" # Handle different disk types if [[ "$ip" == "IMPORT" && "$interface" == "IMPORT" ]]; then # Camera import workflow: mount temporarily, import, then unmount log_message "Detected camera import configuration for UUID: $uuid" # Mount disk for import if mount_disk "$uuid" "$mount_point"; then # Start import process handle_camera_import "$uuid" "$mount_point" "$nfs_options" return $? else log_message "Error: Failed to mount camera device" "err" return 1 fi elif [[ "$ip" == "LOCAL" ]]; then # Local mount only (no network sharing) if mount_disk "$uuid" "$mount_point"; then log_message "Local disk mounted successfully at $mount_point" return 0 else return 1 fi else # Regular NFS workflow: activate IP, mount, export via NFS if activate_ip "$ip" "$interface"; then if mount_disk "$uuid" "$mount_point"; then if add_nfs_export "$mount_point" "$nfs_options"; then log_message "Disk attached successfully: $name" return 0 else log_message "Warning: Disk mounted but NFS export failed" "warning" return 1 fi else deactivate_ip "$ip" "$interface" return 1 fi else return 1 fi fi } # Function to handle disk detachment handle_detach() { local uuid="$1" log_message "AutoNAS detach operation started for UUID: $uuid" # Get configuration for this UUID local config config=$(get_disk_config "$uuid") if [[ -z "$config" ]]; then log_message "No configuration found for UUID: $uuid" return 1 fi log_message "Handling disk detachment for UUID: $uuid" # Parse configuration local parsed parsed=($(parse_config "$config")) local cfg_uuid="${parsed[0]}" local name="${parsed[1]}" local ip="${parsed[2]}" local interface="${parsed[3]}" local mount_point="${parsed[4]}" local nfs_options="${parsed[5]}" log_message "Processing disk: $name (Mount: $mount_point)" # Remove NFS export (if applicable) if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then remove_nfs_export "$mount_point" fi # Unmount disk if unmount_disk "$mount_point"; then # Deactivate IP (if applicable) if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then deactivate_ip "$ip" "$interface" fi log_message "Disk detached successfully: $name" return 0 else log_message "Error: Failed to detach disk: $name" "err" return 1 fi } # Function to reload configuration handle_reload() { log_message "Reloading AutoNAS configuration" log_message "Reloading udev rules" udevadm control --reload-rules udevadm trigger --subsystem-match=block log_message "Reloading NFS exports" exportfs -ra || log_message "Warning: Failed to reload NFS exports" "warning" log_message "Reloading systemd daemon" systemctl daemon-reload || log_message "Warning: Failed to reload systemd daemon" "warning" log_message "AutoNAS configuration reload completed" return 0 } # Function to manually mount a configured disk handle_manual_mount() { local identifier="$1" # UUID or name if [[ -z "$identifier" ]]; then echo "Error: UUID or disk name required" return 1 fi echo "Looking for disk configuration: $identifier" # Try to find configuration by UUID first, then by name local config config=$(get_disk_config "$identifier") || config=$(get_config_by_name "$identifier") if [[ -z "$config" ]]; then echo "Error: No configuration found for '$identifier'" echo "Use 'autonas list' to see configured disks" return 1 fi # Parse configuration local parsed parsed=($(parse_config "$config")) local uuid="${parsed[0]}" local name="${parsed[1]}" local ip="${parsed[2]}" local interface="${parsed[3]}" local mount_point="${parsed[4]}" local nfs_options="${parsed[5]}" echo "Found configuration: $name (UUID: $uuid)" # Check if already mounted if mountpoint -q "$mount_point" 2>/dev/null; then echo "✅ Disk already mounted at: $mount_point" return 0 fi # Handle different disk types for mounting if [[ "$ip" == "IMPORT" ]]; then echo "âš ī¸ Camera import disks are not meant for manual mounting" echo " They are automatically imported when connected" return 1 elif [[ "$ip" == "LOCAL" ]]; then # Local mount only echo "đŸ”ĩ Mounting local disk..." if mount_disk "$uuid" "$mount_point"; then echo "✅ Local disk mounted successfully at: $mount_point" return 0 else echo "❌ Failed to mount local disk" return 1 fi else # Network mount - need to activate IP first echo "🌐 Mounting network disk..." if activate_ip "$ip" "$interface"; then if mount_disk "$uuid" "$mount_point"; then if add_nfs_export "$mount_point" "$nfs_options" "$uuid" "$name"; then echo "✅ Network disk mounted and exported successfully" echo " Mount point: $mount_point" echo " NFS export: $mount_point $nfs_options" return 0 else echo "âš ī¸ Disk mounted but NFS export failed" return 1 fi else deactivate_ip "$ip" "$interface" echo "❌ Failed to mount network disk" return 1 fi else echo "❌ Failed to activate network interface" return 1 fi fi } # Function to manually unmount a configured disk handle_manual_unmount() { local identifier="$1" # UUID or name if [[ -z "$identifier" ]]; then echo "Error: UUID or disk name required" return 1 fi echo "Looking for disk configuration: $identifier" # Try to find configuration by UUID first, then by name local config config=$(get_disk_config "$identifier") || config=$(get_config_by_name "$identifier") if [[ -z "$config" ]]; then echo "Error: No configuration found for '$identifier'" echo "Use 'autonas list' to see configured disks" return 1 fi # Parse configuration local parsed parsed=($(parse_config "$config")) local uuid="${parsed[0]}" local name="${parsed[1]}" local ip="${parsed[2]}" local interface="${parsed[3]}" local mount_point="${parsed[4]}" local nfs_options="${parsed[5]}" echo "Found configuration: $name (UUID: $uuid)" # Check if actually mounted if ! mountpoint -q "$mount_point" 2>/dev/null; then echo "â„šī¸ Disk is not currently mounted: $mount_point" return 0 fi echo "đŸ”Ŋ Unmounting disk..." # Remove NFS export first (if applicable) if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then remove_nfs_export "$mount_point" "$uuid" "$name" "$nfs_options" fi # Unmount disk if unmount_disk "$mount_point"; then # Deactivate IP if network disk if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then deactivate_ip "$ip" "$interface" fi echo "✅ Disk unmounted successfully: $name" return 0 else echo "❌ Failed to unmount disk: $name" return 1 fi } # Show usage information show_usage() { cat << EOF AutoNAS - Unified AutoNAS Management Tool Usage: $0 [options] DISK OPERATIONS: attach - Attach disk with specified UUID detach - Detach disk with specified UUID mount - Manually mount configured disk unmount - Manually unmount configured disk import [script] - Run background import (internal use) reload - Reload AutoNAS configuration CONFIGURATION MANAGEMENT: add [uuid] - Add new disk configuration remove [uuid] - Remove disk configuration list - List all configured disks test [uuid] - Test disk configuration show - Show available disks MAINTENANCE: status - Show system status debug enable - Enable debug mode (verbose logging) debug disable - Disable debug mode debug status - Show current debug status Examples: $0 attach f6ac3d86-5681-4b33-bc64-aa272b333057 $0 add 8765-4321 $0 list $0 show $0 status EOF } # Function to show available disks show_available_disks() { echo "=== Available Storage Devices ===" echo local found_devices=0 local blkid_output # Get blkid output and process it if ! blkid_output=$(blkid 2>/dev/null); then echo "Error: Unable to scan for block devices (are you running as root?)" return 1 fi while IFS= read -r blkid_line; do [[ -z "$blkid_line" ]] && continue local device=$(echo "$blkid_line" | cut -d: -f1) # Skip if device doesn't exist (shouldn't happen with blkid, but just in case) [[ ! -b "$device" ]] && continue # Skip loop devices, ram disks, and other virtual devices case "$device" in /dev/loop*|/dev/ram*|/dev/dm-*) continue ;; esac # Extract device information local uuid=$(echo "$blkid_line" | grep -o 'UUID="[^"]*"' | cut -d'"' -f2) local label=$(echo "$blkid_line" | grep -o 'LABEL="[^"]*"' | cut -d'"' -f2) local fstype=$(echo "$blkid_line" | grep -o 'TYPE="[^"]*"' | cut -d'"' -f2) local partuuid=$(echo "$blkid_line" | grep -o 'PARTUUID="[^"]*"' | cut -d'"' -f2) # Skip if no UUID (we need UUID for AutoNAS) [[ -z "$uuid" ]] && continue found_devices=$((found_devices + 1)) # Get device size local size="" if [[ -b "$device" ]]; then size=$(lsblk -b -d -o SIZE "$device" 2>/dev/null | tail -n1) if [[ -n "$size" ]] && [[ "$size" =~ ^[0-9]+$ ]]; then # Convert to human readable size=$(numfmt --to=iec --suffix=B "$size" 2>/dev/null || echo "${size}B") fi fi # Display device information echo "Device: $device" [[ -n "$size" ]] && echo " Size: $size" echo " UUID: $uuid" [[ -n "$label" ]] && echo " Label: $label" [[ -n "$fstype" ]] && echo " Filesystem: $fstype" # Check if already configured if grep -q "^${uuid}:" "$CONFIG_FILE" 2>/dev/null; then local config_line=$(grep "^${uuid}:" "$CONFIG_FILE" 2>/dev/null) local config_name=$(echo "$config_line" | cut -d: -f2) echo " Status: ✅ Configured as '$config_name'" else echo " Status: âš ī¸ Not configured" fi # Check if currently mounted local mount_info mount_info=$(findmnt -n -o TARGET "$device" 2>/dev/null) if [[ -n "$mount_info" ]]; then echo " Mount: đŸŸĸ $mount_info" else echo " Mount: âšĒ Not mounted" fi echo done <<< "$blkid_output" if [[ $found_devices -eq 0 ]]; then echo "No storage devices with UUIDs found." echo "Make sure devices are connected and you're running as root." else echo "Found $found_devices storage device(s)" echo echo "To configure a device: autonas add " echo "To list configured devices: autonas list" fi return 0 } # Show usage information # Function to check if UUID exists in configuration check_uuid_exists() { local uuid="$1" grep -q "^${uuid}:" "$CONFIG_FILE" 2>/dev/null } # Function to get device information get_device_info() { local uuid="$1" # Find device by UUID using blkid local device_line device_line=$(blkid | grep "UUID=\"$uuid\"") if [[ -z "$device_line" ]]; then return 1 fi local device=$(echo "$device_line" | cut -d: -f1) local blkid_info=$(echo "$device_line" | cut -d: -f2-) echo "device:$device" echo "$blkid_info" return 0 } # Function to list configured disks list_disks() { echo "AutoNAS Disk Configurations:" echo "============================" echo "" if [[ ! -f "$CONFIG_FILE" ]]; then echo "No configuration file found at: $CONFIG_FILE" echo "Use 'autonas add' to add your first disk configuration." return 1 fi local config_count=0 while IFS=':' read -r uuid name ip interface mount_point nfs_options; do # Skip empty lines and comments [[ -z "$uuid" || "$uuid" =~ ^# ]] && continue config_count=$((config_count + 1)) echo "UUID: $uuid" echo "Name: $name" # Check if it's a local mount configuration if [[ "$ip" == "LOCAL" && "$interface" == "LOCAL" && "$nfs_options" == "LOCAL" ]]; then echo "Type: 📁 Local Mount (no network sharing)" echo "Mount Point: $mount_point" elif [[ "$ip" == "IMPORT" && "$interface" == "IMPORT" ]]; then echo "Type: 📷 Camera Import (mount, import, unmount)" echo "Import Destination: $nfs_options" echo "Import Script: /usr/local/bin/autonas-media-importer.sh (built-in, non-configurable)" echo "Temp Mount Point: $mount_point" else echo "Type: 🌐 NFS Network Share" echo "IP: $ip" echo "Interface: $interface" echo "Mount Point: $mount_point" echo "NFS Options: $nfs_options" fi # Check device status local device_info if device_info=$(get_device_info "$uuid" 2>/dev/null); then local device=$(echo "$device_info" | grep "^device:" | cut -d: -f2) echo "Status: ✅ Connected" # Check if mounted if mountpoint -q "$mount_point" 2>/dev/null; then echo "Mount Status: đŸŸĸ Mounted" echo "Current Mount: $mount_point" else echo "Mount Status: 🔴 Not Mounted" fi else echo "Status: 🔴 Not Connected" fi echo "----" done < <(grep -v '^#' "$CONFIG_FILE" 2>/dev/null | grep -v '^$') if [[ $config_count -eq 0 ]]; then echo "No disk configurations found." echo "Use 'autonas add' to add your first disk configuration." return 1 fi echo "" echo "Total configurations: $config_count" return 0 } # Function to add disk configuration add_disk() { local preset_uuid="$1" # Optional UUID parameter echo "AutoNAS - Add New Disk Configuration" echo "====================================" echo "" # Show available disks first show_available_disks if [ $? -ne 0 ]; then echo "Cannot proceed without available disks." return 1 fi echo "Please enter the configuration for your disk:" echo "" # Get UUID with validation local uuid="$preset_uuid" if [ -n "$uuid" ]; then echo "Using provided UUID: $uuid" if ! validate_uuid "$uuid"; then echo "Error: Invalid UUID format. Expected format: 12345678-1234-1234-1234-123456789abc" echo "Please run without UUID parameter to enter manually." return 1 fi if check_uuid_exists "$uuid"; then echo "Error: UUID $uuid is already configured." echo "Use 'autonas remove $uuid' to remove existing configuration first." return 1 fi else while true; do read -p "Enter disk UUID: " uuid if [ -z "$uuid" ]; then echo "Error: UUID cannot be empty" continue fi if ! validate_uuid "$uuid"; then echo "Error: Invalid UUID format. Expected format: 12345678-1234-1234-1234-123456789abc" continue fi if check_uuid_exists "$uuid"; then echo "Error: UUID $uuid is already configured." echo "Use 'autonas remove $uuid' to remove existing configuration first." continue fi break done fi # Get and validate disk name local name while true; do read -p "Enter disk name (letters, numbers, hyphens, underscores, @ allowed): " name if [ -z "$name" ]; then echo "Error: Disk name cannot be empty" continue fi if ! validate_disk_name_complete "$name"; then local validation_result=$? if [[ $validation_result -eq 2 ]]; then echo "Error: Disk name '$name' already exists. Please choose another name." echo "" list_existing_disk_names echo "" continue else echo "Error: Invalid disk name. Requirements:" echo " - Max 50 characters" echo " - Must start with letter or number" echo " - Only letters, numbers, hyphens (-), underscores (_), and at symbol (@)" echo " - Cannot be reserved names (root, home, tmp, etc.)" continue fi fi break done # Choose configuration type echo "" echo "Select disk type:" echo "1) NFS Network Share (default) - Share disk over network" echo "2) Camera Import - Import photos/videos from camera and unmount" echo "3) Local Mount - Mount locally without network sharing" echo "" local config_type read -p "Choose type [1-3] (default: 1): " config_type config_type=${config_type:-1} case "$config_type" in 1) configure_nfs_disk "$uuid" "$name" ;; 2) configure_import_disk "$uuid" "$name" ;; 3) configure_local_disk "$uuid" "$name" ;; *) echo "Invalid choice. Using NFS Network Share (default)." configure_nfs_disk "$uuid" "$name" ;; esac } # Function to configure NFS disk configure_nfs_disk() { local uuid="$1" local name="$2" echo "" echo "=== NFS Network Share Configuration ===" # Get IP address local ip while true; do read -p "Enter IP address for NFS sharing (e.g., 192.168.1.100): " ip if [ -z "$ip" ]; then echo "Error: IP address cannot be empty" continue fi # Basic IP validation if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then echo "Error: Invalid IP address format" continue fi # Check each octet local valid_ip=true IFS='.' read -ra OCTETS <<< "$ip" for octet in "${OCTETS[@]}"; do if [ "$octet" -lt 0 ] || [ "$octet" -gt 255 ]; then valid_ip=false break fi done if [ "$valid_ip" = false ]; then echo "Error: IP address octets must be between 0-255" continue fi break done # Get network interface local interface echo "" echo "Available network interfaces:" ip link show | grep "^[0-9]" | cut -d: -f2 | sed 's/^ *//' | grep -v "^lo$" echo "" while true; do read -p "Enter network interface (e.g., eth0, enp0s3): " interface if [ -z "$interface" ]; then echo "Error: Network interface cannot be empty" continue fi # Check if interface exists if ! ip link show "$interface" >/dev/null 2>&1; then echo "Error: Network interface '$interface' does not exist" echo "Available interfaces:" ip link show | grep "^[0-9]" | cut -d: -f2 | sed 's/^ *//' | grep -v "^lo$" continue fi break done # Generate mount point local mount_point="$MOUNT_BASE/$name" echo "" echo "Mount point will be: $mount_point" # Get NFS options local nfs_options echo "" echo "NFS Options (press Enter for default):" echo "Default: *(rw,all_squash,insecure,async,no_subtree_check,anonuid=0,anongid=0)" read -p "Enter custom NFS options or press Enter for default: " nfs_options if [ -z "$nfs_options" ]; then nfs_options="*(rw,all_squash,insecure,async,no_subtree_check,anonuid=0,anongid=0)" fi # Create configuration entry local config_entry="${uuid}:${name}:${ip}:${interface}:${mount_point}:${nfs_options}" # Show configuration summary echo "" echo "=== Configuration Summary ===" echo "UUID: $uuid" echo "Name: $name" echo "Type: NFS Network Share" echo "IP: $ip" echo "Interface: $interface" echo "Mount Point: $mount_point" echo "NFS Options: $nfs_options" echo "" # Confirm configuration read -p "Save this configuration? (Y/n): " confirm if [[ "$confirm" =~ ^[Nn]$ ]]; then echo "Configuration cancelled." return 1 fi # Save configuration echo "$config_entry" >> "$CONFIG_FILE" echo "" echo "✅ Configuration saved successfully!" echo "" echo "To test this configuration: autonas test $uuid" echo "To attach this disk when connected: autonas attach $uuid" return 0 } # Function to configure local disk configure_local_disk() { local uuid="$1" local name="$2" echo "" echo "=== Local Mount Configuration ===" echo "This disk will be mounted locally without network sharing." echo "" # Generate mount point local mount_point="$MOUNT_BASE/$name" echo "Mount point will be: $mount_point" echo "" # Create configuration entry local config_entry="${uuid}:${name}:LOCAL:LOCAL:${mount_point}:LOCAL" # Show configuration summary echo "=== Configuration Summary ===" echo "UUID: $uuid" echo "Name: $name" echo "Type: Local Mount (no network sharing)" echo "Mount Point: $mount_point" echo "" # Confirm configuration read -p "Save this configuration? (Y/n): " confirm if [[ "$confirm" =~ ^[Nn]$ ]]; then echo "Configuration cancelled." return 1 fi # Save configuration echo "$config_entry" >> "$CONFIG_FILE" echo "" echo "✅ Configuration saved successfully!" echo "" echo "To test this configuration: autonas test $uuid" echo "To attach this disk when connected: autonas attach $uuid" return 0 } # Function to configure import disk (camera) configure_import_disk() { local uuid="$1" local name="$2" echo "" echo "=== Camera Import Configuration ===" echo "This device will be mounted temporarily, media imported, then unmounted." echo "" # Get destination path for import local destination_path while true; do read -p "Enter destination path for imported media: " destination_path if [ -z "$destination_path" ]; then echo "Error: Destination path cannot be empty" continue fi # Convert relative path to absolute if [[ ! "$destination_path" =~ ^/ ]]; then destination_path="$(pwd)/$destination_path" fi # Validate parent directory exists local parent_dir=$(dirname "$destination_path") if [ ! -d "$parent_dir" ]; then echo "Warning: Parent directory '$parent_dir' does not exist." read -p "Create parent directories? (Y/n): " create_dirs if [[ ! "$create_dirs" =~ ^[Nn]$ ]]; then if mkdir -p "$parent_dir" 2>/dev/null; then echo "Created parent directories." else echo "Error: Failed to create parent directories. Please check permissions." continue fi else echo "Please enter a valid destination path." continue fi fi break done # Generate temporary mount point for import local temp_mount_point="$MOUNT_BASE/$name" # Create configuration entry (simplified format - no script path) local config_entry="${uuid}:${name}:IMPORT:IMPORT:${temp_mount_point}:${destination_path}" # Show configuration summary echo "" echo "=== Configuration Summary ===" echo "UUID: $uuid" echo "Name: $name" echo "Type: Camera Import (mount, import, unmount)" echo "Import destination: $destination_path" echo "Import script: /usr/local/bin/autonas-media-importer.sh (built-in, non-configurable)" echo "Temp mount point: $temp_mount_point" echo "" # Confirm configuration read -p "Save this configuration? (Y/n): " confirm if [[ "$confirm" =~ ^[Nn]$ ]]; then echo "Configuration cancelled." return 1 fi # Save configuration echo "$config_entry" >> "$CONFIG_FILE" echo "" echo "✅ Configuration saved successfully!" echo "" echo "To test this configuration: autonas test $uuid" echo "When camera is connected, media will be imported automatically to: $destination_path" return 0 } # Function to remove disk configuration remove_disk() { local uuid="$1" if [[ -z "$uuid" ]]; then echo "Usage: autonas remove " return 1 fi if [[ ! -f "$CONFIG_FILE" ]]; then echo "No configuration file found." return 1 fi # Check if UUID exists if ! check_uuid_exists "$uuid"; then echo "Error: UUID '$uuid' not found in configuration." return 1 fi # Show current configuration echo "Current configuration for UUID: $uuid" echo "==================================" local config=$(get_disk_config "$uuid") local parsed=($(parse_config "$config")) echo "Name: ${parsed[1]}" echo "Type: ${parsed[2]}:${parsed[3]}" echo "Mount: ${parsed[4]}" echo "" # Confirm removal read -p "Remove this configuration? (y/N): " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "Removal cancelled." return 1 fi # Remove configuration local temp_file=$(mktemp) grep -v "^${uuid}:" "$CONFIG_FILE" > "$temp_file" mv "$temp_file" "$CONFIG_FILE" echo "✅ Configuration removed successfully!" return 0 } # Function to test disk configuration test_config() { local uuid="$1" if [[ -z "$uuid" ]]; then echo "Usage: autonas test " return 1 fi echo "AutoNAS Configuration Test" echo "=========================" echo "" # Check if configuration exists local config config=$(get_disk_config "$uuid") if [[ -z "$config" ]]; then echo "❌ Configuration not found for UUID: $uuid" echo "" echo "Available configurations:" list_disks return 1 fi echo "✅ Configuration found for UUID: $uuid" # Parse configuration local parsed=($(parse_config "$config")) local cfg_uuid="${parsed[0]}" local name="${parsed[1]}" local ip="${parsed[2]}" local interface="${parsed[3]}" local mount_point="${parsed[4]}" local nfs_options="${parsed[5]}" echo " Name: $name" echo " Type: $ip:$interface" echo " Mount Point: $mount_point" echo "" # Test device detection echo "🔍 Testing device detection..." local device_info if device_info=$(get_device_info "$uuid" 2>/dev/null); then local device=$(echo "$device_info" | grep "^device:" | cut -d: -f2) echo "✅ Device found: $device" # Show device details echo "$device_info" | grep -v "^device:" | while IFS= read -r line; do echo " $line" done else echo "❌ Device not found or not connected" echo " Make sure the device with UUID $uuid is connected" return 1 fi echo "" # Test network configuration (if applicable) if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then echo "🌐 Testing network configuration..." # Test interface if interface_exists "$interface"; then echo "✅ Network interface exists: $interface" else echo "❌ Network interface not found: $interface" echo " Available interfaces:" ip link show | grep "^[0-9]" | cut -d: -f2 | sed 's/^ *//' | grep -v "^lo$" | sed 's/^/ /' return 1 fi # Test IP configuration if is_ip_configured "$ip" "$interface"; then echo "✅ IP already configured: $ip on $interface" else echo "â„šī¸ IP not currently configured: $ip on $interface" echo " (This is normal - IP will be activated during attach)" fi echo "" fi # Test mount point echo "📁 Testing mount point..." if [[ -d "$mount_point" ]]; then if mountpoint -q "$mount_point" 2>/dev/null; then echo "✅ Mount point exists and is mounted: $mount_point" local mounted_device=$(findmnt -n -o SOURCE "$mount_point") echo " Mounted device: $mounted_device" else echo "â„šī¸ Mount point directory exists but not mounted: $mount_point" fi else echo "â„šī¸ Mount point directory will be created: $mount_point" fi echo "" # Test import configuration (if applicable) if [[ "$ip" == "IMPORT" && "$interface" == "IMPORT" ]]; then echo "📷 Testing camera import configuration..." local destination="$nfs_options" if [[ -d "$destination" ]]; then echo "✅ Import destination exists: $destination" if [[ -w "$destination" ]]; then echo "✅ Import destination is writable" else echo "âš ī¸ Import destination is not writable" echo " You may need to check permissions" fi else echo "â„šī¸ Import destination will be created: $destination" local parent_dir=$(dirname "$destination") if [[ -d "$parent_dir" && -w "$parent_dir" ]]; then echo "✅ Parent directory exists and is writable" else echo "❌ Cannot create import destination" echo " Parent directory: $parent_dir" return 1 fi fi # Test import script if [[ -x "/usr/local/bin/autonas-media-importer.sh" ]]; then echo "✅ Media import script is available and executable" else echo "❌ Media import script not found or not executable" echo " Expected: /usr/local/bin/autonas-media-importer.sh" return 1 fi echo "" fi echo "🎉 Configuration test completed successfully!" echo "" echo "You can now attach this disk with: autonas attach $uuid" return 0 } # Main configuration functions would go here... # Main command dispatcher case "${1:-}" in "attach") if [[ -z "$2" ]]; then echo "Error: UUID required for attach command" show_usage exit 1 fi handle_attach "$2" ;; "detach") if [[ -z "$2" ]]; then echo "Error: UUID required for detach command" show_usage exit 1 fi handle_detach "$2" ;; "mount") if [[ -z "$2" ]]; then echo "Error: UUID or disk name required for mount command" show_usage exit 1 fi handle_manual_mount "$2" ;; "unmount"|"umount") if [[ -z "$2" ]]; then echo "Error: UUID or disk name required for unmount command" show_usage exit 1 fi handle_manual_unmount "$2" ;; "import") # Internal use only - background import process if [[ -z "$4" ]]; then echo "Error: Missing arguments for import command" exit 1 fi run_background_import "$2" "$3" "$4" "$5" ;; "reload") handle_reload ;; "add") add_disk "$2" ;; "remove") if [[ -z "$2" ]]; then echo "Error: UUID required for remove command" show_usage exit 1 fi remove_disk "$2" ;; "list") list_disks ;; "test") if [[ -z "$2" ]]; then echo "Error: UUID required for test command" show_usage exit 1 fi test_config "$2" ;; "show") show_available_disks ;; "status") echo "=== AutoNAS System Status ===" echo "Configuration file: $CONFIG_FILE" if [[ -f "$CONFIG_FILE" ]]; then count=$(grep -c "^[^#].*:.*:.*:" "$CONFIG_FILE" 2>/dev/null || echo "0") echo "Configured disks: $count" else echo "Configured disks: 0 (no config file)" fi echo "NFS server: $(systemctl is-active nfs-kernel-server 2>/dev/null || echo "unknown")" echo "AutoNAS service: $(systemctl is-active autonas 2>/dev/null || echo "unknown")" echo "Boot scan service: $(systemctl is-active autonas-boot-scan 2>/dev/null || echo "unknown")" echo "" echo "Recent logs:" journalctl -t autonas -n 5 --no-pager 2>/dev/null || echo "No recent logs found" ;; "debug") case "${2:-}" in "enable") if [ -f "/etc/default/autonas" ]; then sed -i 's/AUTONAS_DEBUG="false"/AUTONAS_DEBUG="true"/' /etc/default/autonas echo "✓ Debug mode enabled - verbose logging is now active" echo " All AutoNAS operations will produce detailed debug output" else echo "Error: Configuration file /etc/default/autonas not found" exit 1 fi ;; "disable") if [ -f "/etc/default/autonas" ]; then sed -i 's/AUTONAS_DEBUG="true"/AUTONAS_DEBUG="false"/' /etc/default/autonas echo "✓ Debug mode disabled - normal logging restored" else echo "Error: Configuration file /etc/default/autonas not found" exit 1 fi ;; "status") if [ -f "/etc/default/autonas" ]; then echo "=== AutoNAS Debug Configuration ===" source /etc/default/autonas echo "Debug mode: ${AUTONAS_DEBUG:-false}" echo "Log level: ${AUTONAS_LOG_LEVEL:-info}" if [ "$AUTONAS_DEBUG" = "true" ]; then echo "Status: đŸŸĸ Debug logging is ENABLED" echo " - Verbose messages will appear in logs and stderr" echo " - All operations will be traced in detail" else echo "Status: 🔴 Debug logging is DISABLED" echo " - Only normal info/warning/error messages will appear" fi else echo "Error: Configuration file /etc/default/autonas not found" exit 1 fi ;; "") echo "Error: Debug command requires an argument" echo "Usage: $0 debug {enable|disable|status}" exit 1 ;; *) echo "Error: Unknown debug command '$2'" echo "Usage: $0 debug {enable|disable|status}" exit 1 ;; esac ;; "help"|"-h"|"--help"|"") show_usage ;; *) echo "Error: Unknown command '$1'" echo show_usage exit 1 ;; esac