1 contributor
#!/bin/bash
# AutoNAS - Unified AutoNAS Management Tool
# Combines manager, configuration, and all other functionality into one script
# Usage: autonas <command> [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 <command> [options]
DISK OPERATIONS:
attach <uuid> - Attach disk with specified UUID
detach <uuid> - Detach disk with specified UUID
mount <uuid|name> - Manually mount configured disk
unmount <uuid|name> - Manually unmount configured disk
import <uuid> <source> <dest> [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 <UUID>"
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 <uuid>"
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 <uuid>"
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