autoNAS / scripts / autonas.sh
Newer Older
5bf8614 3 months ago History
1064 lines | 34.386kb
Bogdan Timofte authored 3 months ago
1
#!/bin/bash
2

            
3
# AutoNAS - Unified AutoNAS Management Tool
4
# Combines manager, configuration, and all other functionality into one script
5
# Usage: autonas <command> [options]
6

            
7
# Load core AutoNAS library
Bogdan Timofte authored 3 months ago
8
AUTONAS_RUNTIME_DIR="${AUTONAS_RUNTIME_DIR:-/usr/local/lib/xdev/autonas}"
9
AUTONAS_CORE_LIB="${AUTONAS_CORE_LIB:-${AUTONAS_RUNTIME_DIR}/autonas-core.sh}"
10
AUTONAS_DEFAULTS_FILE="${AUTONAS_DEFAULTS_FILE:-/etc/default/xdev-autonas}"
11
AUTONAS_MEDIA_IMPORTER="${AUTONAS_MEDIA_IMPORTER:-${AUTONAS_RUNTIME_DIR}/autonas-media-importer.sh}"
12

            
13
if [[ -f "${AUTONAS_CORE_LIB}" ]]; then
14
    source "${AUTONAS_CORE_LIB}"
Bogdan Timofte authored 3 months ago
15
else
Bogdan Timofte authored 3 months ago
16
    echo "Error: AutoNAS core library not found at ${AUTONAS_CORE_LIB}" >&2
Bogdan Timofte authored 3 months ago
17
    exit 1
18
fi
19

            
20
# Function to handle disk attachment
21
handle_attach() {
Bogdan Timofte authored 3 months ago
22
    local identifier="$1"
23

            
24
    log_message "AutoNAS attach operation started for identifier: $identifier"
25

            
26
    # Get configuration by UUID, name, or mount point
Bogdan Timofte authored 3 months ago
27
    local config
Bogdan Timofte authored 3 months ago
28
    config=$(resolve_config_identifier "$identifier")
29

            
Bogdan Timofte authored 3 months ago
30
    if [[ -z "$config" ]]; then
Bogdan Timofte authored 3 months ago
31
        log_message "No configuration found for identifier: $identifier - disk will be ignored"
Bogdan Timofte authored 3 months ago
32
        log_message "To configure this disk, run: autonas-config.sh add"
33
        return 1
34
    fi
Bogdan Timofte authored 3 months ago
35

            
Bogdan Timofte authored 3 months ago
36
    # Parse configuration
37
    local parsed
38
    parsed=($(parse_config "$config"))
39
    local cfg_uuid="${parsed[0]}"
40
    local name="${parsed[1]}"
41
    local ip="${parsed[2]}"
42
    local interface="${parsed[3]}"
43
    local mount_point="${parsed[4]}"
44
    local nfs_options="${parsed[5]}"
Bogdan Timofte authored 3 months ago
45

            
46
    log_message "Handling disk attachment for UUID: $cfg_uuid"
Bogdan Timofte authored 3 months ago
47
    log_message "Processing disk: $name (IP: $ip, Mount: $mount_point)"
Bogdan Timofte authored 3 months ago
48

            
Bogdan Timofte authored 3 months ago
49
    # Handle different disk types
50
    if [[ "$ip" == "IMPORT" && "$interface" == "IMPORT" ]]; then
51
        # Camera import workflow: mount temporarily, import, then unmount
Bogdan Timofte authored 3 months ago
52
        log_message "Detected camera import configuration for UUID: $cfg_uuid"
53

            
Bogdan Timofte authored 3 months ago
54
        # Mount disk for import
Bogdan Timofte authored 3 months ago
55
        if mount_disk "$cfg_uuid" "$mount_point"; then
Bogdan Timofte authored 3 months ago
56
            # Start import process
Bogdan Timofte authored 3 months ago
57
            handle_camera_import "$cfg_uuid" "$mount_point" "$nfs_options"
Bogdan Timofte authored 3 months ago
58
            return $?
59
        else
60
            log_message "Error: Failed to mount camera device" "err"
61
            return 1
62
        fi
63
    elif [[ "$ip" == "LOCAL" ]]; then
64
        # Local mount only (no network sharing)
Bogdan Timofte authored 3 months ago
65
        if mount_disk "$cfg_uuid" "$mount_point"; then
Bogdan Timofte authored 3 months ago
66
            log_message "Local disk mounted successfully at $mount_point"
67
            return 0
68
        else
69
            return 1
70
        fi
71
    else
72
        # Regular NFS workflow: activate IP, mount, export via NFS
73
        if activate_ip "$ip" "$interface"; then
Bogdan Timofte authored 3 months ago
74
            if mount_disk "$cfg_uuid" "$mount_point"; then
Bogdan Timofte authored 3 months ago
75
                if add_nfs_export "$mount_point" "$nfs_options"; then
76
                    log_message "Disk attached successfully: $name"
77
                    return 0
78
                else
79
                    log_message "Warning: Disk mounted but NFS export failed" "warning"
80
                    return 1
81
                fi
82
            else
83
                deactivate_ip "$ip" "$interface"
84
                return 1
85
            fi
86
        else
87
            return 1
88
        fi
89
    fi
90
}
91

            
92
# Function to handle disk detachment
93
handle_detach() {
Bogdan Timofte authored 3 months ago
94
    local identifier="$1"
95

            
96
    log_message "AutoNAS detach operation started for identifier: $identifier"
97

            
98
    # Get configuration by UUID, name, or mount point
Bogdan Timofte authored 3 months ago
99
    local config
Bogdan Timofte authored 3 months ago
100
    config=$(resolve_config_identifier "$identifier")
101

            
Bogdan Timofte authored 3 months ago
102
    if [[ -z "$config" ]]; then
Bogdan Timofte authored 3 months ago
103
        log_message "No configuration found for identifier: $identifier"
Bogdan Timofte authored 3 months ago
104
        return 1
105
    fi
Bogdan Timofte authored 3 months ago
106

            
Bogdan Timofte authored 3 months ago
107
    # Parse configuration
108
    local parsed
109
    parsed=($(parse_config "$config"))
110
    local cfg_uuid="${parsed[0]}"
111
    local name="${parsed[1]}"
112
    local ip="${parsed[2]}"
113
    local interface="${parsed[3]}"
114
    local mount_point="${parsed[4]}"
115
    local nfs_options="${parsed[5]}"
Bogdan Timofte authored 3 months ago
116

            
117
    log_message "Handling disk detachment for UUID: $cfg_uuid"
Bogdan Timofte authored 3 months ago
118
    log_message "Processing disk: $name (Mount: $mount_point)"
119

            
120
    # Remove NFS export (if applicable)
121
    if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then
122
        remove_nfs_export "$mount_point"
123
    fi
124

            
125
    # Unmount disk
126
    if unmount_disk "$mount_point"; then
127
        # Deactivate IP (if applicable)
128
        if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then
129
            deactivate_ip "$ip" "$interface"
130
        fi
131

            
132
        log_message "Disk detached successfully: $name"
133
        return 0
134
    else
135
        log_message "Error: Failed to detach disk: $name" "err"
136
        return 1
137
    fi
138
}
139

            
140
# Function to reload configuration
141
handle_reload() {
142
    log_message "Reloading AutoNAS configuration"
143

            
144
    log_message "Reloading udev rules"
145
    udevadm control --reload-rules
146
    udevadm trigger --subsystem-match=block
147

            
148
    log_message "Reloading NFS exports"
149
    exportfs -ra || log_message "Warning: Failed to reload NFS exports" "warning"
Bogdan Timofte authored 3 months ago
150

            
151
    local sync_script="${AUTONAS_RUNTIME_DIR}/autonas-sync-systemd-ordering.sh"
152
    if [[ -x "${sync_script}" ]]; then
153
        log_message "Refreshing self-hosted Proxmox shutdown ordering"
154
        "${sync_script}" || log_message "Warning: Failed to refresh self-hosted Proxmox shutdown ordering" "warning"
155
    fi
Bogdan Timofte authored 3 months ago
156

            
157
    log_message "Reloading systemd daemon"
158
    systemctl daemon-reload || log_message "Warning: Failed to reload systemd daemon" "warning"
159

            
160
    log_message "AutoNAS configuration reload completed"
161
    return 0
162
}
163

            
164
# Show usage information
165
show_usage() {
166
    cat << EOF
167
AutoNAS - Unified AutoNAS Management Tool
168

            
169
Usage: $0 <command> [options]
170

            
171
DISK OPERATIONS:
Bogdan Timofte authored 3 months ago
172
  attach <uuid|name|mount>   - Attach configured disk
173
  detach <uuid|name|mount>   - Detach configured disk
Bogdan Timofte authored 3 months ago
174
  import <uuid> <source> <dest> [script] - Run background import (internal use)
175
  reload                     - Reload AutoNAS configuration
176

            
177
CONFIGURATION MANAGEMENT:
178
  add [uuid]                 - Add new disk configuration
Bogdan Timofte authored 3 months ago
179
  remove [uuid|name|mount]   - Remove disk configuration
Bogdan Timofte authored 3 months ago
180
  list                       - List all configured disks
Bogdan Timofte authored 3 months ago
181
  test [uuid|name|mount]     - Test disk configuration
Bogdan Timofte authored 3 months ago
182
  show                       - Show available disks
183

            
184
MAINTENANCE:
185
  status                     - Show system status
186
  debug enable               - Enable debug mode (verbose logging)
187
  debug disable              - Disable debug mode
188
  debug status               - Show current debug status
189

            
190
Examples:
191
  $0 attach f6ac3d86-5681-4b33-bc64-aa272b333057
192
  $0 add 8765-4321
193
  $0 list
194
  $0 show
195
  $0 status
196

            
197
EOF
198
}
199

            
200
# Function to show available disks
201
show_available_disks() {
202
    echo "=== Available Storage Devices ==="
203
    echo
204

            
205
    local found_devices=0
206
    local blkid_output
207

            
208
    # Get blkid output and process it
209
    if ! blkid_output=$(blkid 2>/dev/null); then
210
        echo "Error: Unable to scan for block devices (are you running as root?)"
211
        return 1
212
    fi
213

            
214
    while IFS= read -r blkid_line; do
215
        [[ -z "$blkid_line" ]] && continue
216

            
217
        local device=$(echo "$blkid_line" | cut -d: -f1)
218

            
219
        # Skip if device doesn't exist (shouldn't happen with blkid, but just in case)
220
        [[ ! -b "$device" ]] && continue
221

            
222
        # Skip loop devices, ram disks, and other virtual devices
223
        case "$device" in
224
            /dev/loop*|/dev/ram*|/dev/dm-*) continue ;;
225
        esac
226

            
227
        # Extract device information
228
        local uuid=$(echo "$blkid_line" | grep -o 'UUID="[^"]*"' | cut -d'"' -f2)
229
        local label=$(echo "$blkid_line" | grep -o 'LABEL="[^"]*"' | cut -d'"' -f2)
230
        local fstype=$(echo "$blkid_line" | grep -o 'TYPE="[^"]*"' | cut -d'"' -f2)
231
        local partuuid=$(echo "$blkid_line" | grep -o 'PARTUUID="[^"]*"' | cut -d'"' -f2)
232

            
233
        # Skip if no UUID (we need UUID for AutoNAS)
234
        [[ -z "$uuid" ]] && continue
235

            
236
        found_devices=$((found_devices + 1))
237

            
238
        # Get device size
239
        local size=""
240
        if [[ -b "$device" ]]; then
241
            size=$(lsblk -b -d -o SIZE "$device" 2>/dev/null | tail -n1)
242
            if [[ -n "$size" ]] && [[ "$size" =~ ^[0-9]+$ ]]; then
243
                # Convert to human readable
244
                size=$(numfmt --to=iec --suffix=B "$size" 2>/dev/null || echo "${size}B")
245
            fi
246
        fi
247

            
248
        # Display device information
249
        echo "Device: $device"
250
        [[ -n "$size" ]] && echo "  Size: $size"
251
        echo "  UUID: $uuid"
252
        [[ -n "$label" ]] && echo "  Label: $label"
253
        [[ -n "$fstype" ]] && echo "  Filesystem: $fstype"
254

            
255
        # Check if already configured
256
        if grep -q "^${uuid}:" "$CONFIG_FILE" 2>/dev/null; then
257
            local config_line=$(grep "^${uuid}:" "$CONFIG_FILE" 2>/dev/null)
258
            local config_name=$(echo "$config_line" | cut -d: -f2)
259
            echo "  Status: ✅ Configured as '$config_name'"
260
        else
261
            echo "  Status: ⚠️  Not configured"
262
        fi
263

            
264
        # Check if currently mounted
265
        local mount_info
266
        mount_info=$(findmnt -n -o TARGET "$device" 2>/dev/null)
267
        if [[ -n "$mount_info" ]]; then
268
            echo "  Mount: 🟢 $mount_info"
269
        else
270
            echo "  Mount: ⚪ Not mounted"
271
        fi
272

            
273
        echo
274
    done <<< "$blkid_output"
275

            
276
    if [[ $found_devices -eq 0 ]]; then
277
        echo "No storage devices with UUIDs found."
278
        echo "Make sure devices are connected and you're running as root."
279
    else
280
        echo "Found $found_devices storage device(s)"
281
        echo
282
        echo "To configure a device: autonas add <UUID>"
283
        echo "To list configured devices: autonas list"
284
    fi
285

            
286
    return 0
287
}
288

            
289
# Show usage information
290

            
291
# Function to check if UUID exists in configuration
292
check_uuid_exists() {
293
    local uuid="$1"
294
    grep -q "^${uuid}:" "$CONFIG_FILE" 2>/dev/null
295
}
296

            
297
# Function to get device information
298
get_device_info() {
299
    local uuid="$1"
300

            
301
    # Find device by UUID using blkid
302
    local device_line
303
    device_line=$(blkid | grep "UUID=\"$uuid\"")
304

            
305
    if [[ -z "$device_line" ]]; then
306
        return 1
307
    fi
308

            
309
    local device=$(echo "$device_line" | cut -d: -f1)
310
    local blkid_info=$(echo "$device_line" | cut -d: -f2-)
311

            
312
    echo "device:$device"
313
    echo "$blkid_info"
314
    return 0
315
}
316

            
317
# Function to list configured disks
318
list_disks() {
319
    echo "AutoNAS Disk Configurations:"
320
    echo "============================"
321
    echo ""
322

            
323
    if [[ ! -f "$CONFIG_FILE" ]]; then
324
        echo "No configuration file found at: $CONFIG_FILE"
325
        echo "Use 'autonas add' to add your first disk configuration."
326
        return 1
327
    fi
328

            
329
    local config_count=0
330
    while IFS=':' read -r uuid name ip interface mount_point nfs_options; do
331
        # Skip empty lines and comments
332
        [[ -z "$uuid" || "$uuid" =~ ^# ]] && continue
333

            
334
        config_count=$((config_count + 1))
335

            
336
        echo "UUID: $uuid"
337
        echo "Name: $name"
338

            
339
        # Check if it's a local mount configuration
340
        if [[ "$ip" == "LOCAL" && "$interface" == "LOCAL" && "$nfs_options" == "LOCAL" ]]; then
341
            echo "Type: 📁 Local Mount (no network sharing)"
342
            echo "Mount Point: $mount_point"
343
        elif [[ "$ip" == "IMPORT" && "$interface" == "IMPORT" ]]; then
344
            echo "Type: 📷 Camera Import (mount, import, unmount)"
345
            echo "Import Destination: $nfs_options"
Bogdan Timofte authored 3 months ago
346
            echo "Import Script: ${AUTONAS_MEDIA_IMPORTER} (built-in, non-configurable)"
Bogdan Timofte authored 3 months ago
347
            echo "Temp Mount Point: $mount_point"
348
        else
349
            echo "Type: 🌐 NFS Network Share"
350
            echo "IP: $ip"
351
            echo "Interface: $interface"
352
            echo "Mount Point: $mount_point"
353
            echo "NFS Options: $nfs_options"
354
        fi
355

            
356
        # Check device status
357
        local device_info
358
        if device_info=$(get_device_info "$uuid" 2>/dev/null); then
359
            local device=$(echo "$device_info" | grep "^device:" | cut -d: -f2)
360
            echo "Status: ✅ Connected"
361

            
362
            # Check if mounted
363
            if mountpoint -q "$mount_point" 2>/dev/null; then
364
                echo "Mount Status: 🟢 Mounted"
365
                echo "Current Mount: $mount_point"
366
            else
367
                echo "Mount Status: 🔴 Not Mounted"
368
            fi
369
        else
370
            echo "Status: 🔴 Not Connected"
371
        fi
372

            
373
        echo "----"
374
    done < <(grep -v '^#' "$CONFIG_FILE" 2>/dev/null | grep -v '^$')
375

            
376
    if [[ $config_count -eq 0 ]]; then
377
        echo "No disk configurations found."
378
        echo "Use 'autonas add' to add your first disk configuration."
379
        return 1
380
    fi
381

            
382
    echo ""
383
    echo "Total configurations: $config_count"
384
    return 0
385
}
386

            
387
# Function to add disk configuration
388
add_disk() {
389
    local preset_uuid="$1"  # Optional UUID parameter
390

            
391
    echo "AutoNAS - Add New Disk Configuration"
392
    echo "===================================="
393
    echo ""
394

            
395
    # Show available disks first
396
    show_available_disks
397
    if [ $? -ne 0 ]; then
398
        echo "Cannot proceed without available disks."
399
        return 1
400
    fi
401

            
402
    echo "Please enter the configuration for your disk:"
403
    echo ""
404

            
405
    # Get UUID with validation
406
    local uuid="$preset_uuid"
407
    if [ -n "$uuid" ]; then
408
        echo "Using provided UUID: $uuid"
409

            
410
        if ! validate_uuid "$uuid"; then
411
            echo "Error: Invalid UUID format. Expected format: 12345678-1234-1234-1234-123456789abc"
412
            echo "Please run without UUID parameter to enter manually."
413
            return 1
414
        fi
415

            
416
        if check_uuid_exists "$uuid"; then
417
            echo "Error: UUID $uuid is already configured."
418
            echo "Use 'autonas remove $uuid' to remove existing configuration first."
419
            return 1
420
        fi
421
    else
422
        while true; do
423
            read -p "Enter disk UUID: " uuid
424
            if [ -z "$uuid" ]; then
425
                echo "Error: UUID cannot be empty"
426
                continue
427
            fi
428

            
429
            if ! validate_uuid "$uuid"; then
430
                echo "Error: Invalid UUID format. Expected format: 12345678-1234-1234-1234-123456789abc"
431
                continue
432
            fi
433

            
434
            if check_uuid_exists "$uuid"; then
435
                echo "Error: UUID $uuid is already configured."
436
                echo "Use 'autonas remove $uuid' to remove existing configuration first."
437
                continue
438
            fi
439

            
440
            break
441
        done
442
    fi
443

            
444
    # Get and validate disk name
445
    local name
446
    while true; do
447
        read -p "Enter disk name (letters, numbers, hyphens, underscores, @ allowed): " name
448
        if [ -z "$name" ]; then
449
            echo "Error: Disk name cannot be empty"
450
            continue
451
        fi
452

            
453
        if ! validate_disk_name_complete "$name"; then
454
            local validation_result=$?
455
            if [[ $validation_result -eq 2 ]]; then
456
                echo "Error: Disk name '$name' already exists. Please choose another name."
457
                echo ""
458
                list_existing_disk_names
459
                echo ""
460
                continue
461
            else
462
                echo "Error: Invalid disk name. Requirements:"
463
                echo "  - Max 50 characters"
464
                echo "  - Must start with letter or number"
465
                echo "  - Only letters, numbers, hyphens (-), underscores (_), and at symbol (@)"
466
                echo "  - Cannot be reserved names (root, home, tmp, etc.)"
467
                continue
468
            fi
469
        fi
470

            
471
        break
472
    done
473

            
474
    # Choose configuration type
475
    echo ""
476
    echo "Select disk type:"
477
    echo "1) NFS Network Share (default) - Share disk over network"
478
    echo "2) Camera Import - Import photos/videos from camera and unmount"
479
    echo "3) Local Mount - Mount locally without network sharing"
480
    echo ""
481

            
482
    local config_type
483
    read -p "Choose type [1-3] (default: 1): " config_type
484
    config_type=${config_type:-1}
485

            
486
    case "$config_type" in
487
        1)
488
            configure_nfs_disk "$uuid" "$name"
489
            ;;
490
        2)
491
            configure_import_disk "$uuid" "$name"
492
            ;;
493
        3)
494
            configure_local_disk "$uuid" "$name"
495
            ;;
496
        *)
497
            echo "Invalid choice. Using NFS Network Share (default)."
498
            configure_nfs_disk "$uuid" "$name"
499
            ;;
500
    esac
501
}
502

            
503
# Function to configure NFS disk
504
configure_nfs_disk() {
505
    local uuid="$1"
506
    local name="$2"
507

            
508
    echo ""
509
    echo "=== NFS Network Share Configuration ==="
510

            
511
    # Get IP address
512
    local ip
513
    while true; do
514
        read -p "Enter IP address for NFS sharing (e.g., 192.168.1.100): " ip
515
        if [ -z "$ip" ]; then
516
            echo "Error: IP address cannot be empty"
517
            continue
518
        fi
519

            
520
        # Basic IP validation
521
        if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
522
            echo "Error: Invalid IP address format"
523
            continue
524
        fi
525

            
526
        # Check each octet
527
        local valid_ip=true
528
        IFS='.' read -ra OCTETS <<< "$ip"
529
        for octet in "${OCTETS[@]}"; do
530
            if [ "$octet" -lt 0 ] || [ "$octet" -gt 255 ]; then
531
                valid_ip=false
532
                break
533
            fi
534
        done
535

            
536
        if [ "$valid_ip" = false ]; then
537
            echo "Error: IP address octets must be between 0-255"
538
            continue
539
        fi
540

            
541
        break
542
    done
543

            
544
    # Get network interface
545
    local interface
546
    echo ""
547
    echo "Available network interfaces:"
548
    ip link show | grep "^[0-9]" | cut -d: -f2 | sed 's/^ *//' | grep -v "^lo$"
549
    echo ""
550

            
551
    while true; do
552
        read -p "Enter network interface (e.g., eth0, enp0s3): " interface
553
        if [ -z "$interface" ]; then
554
            echo "Error: Network interface cannot be empty"
555
            continue
556
        fi
557

            
558
        # Check if interface exists
559
        if ! ip link show "$interface" >/dev/null 2>&1; then
560
            echo "Error: Network interface '$interface' does not exist"
561
            echo "Available interfaces:"
562
            ip link show | grep "^[0-9]" | cut -d: -f2 | sed 's/^ *//' | grep -v "^lo$"
563
            continue
564
        fi
565

            
566
        break
567
    done
568

            
569
    # Generate mount point
570
    local mount_point="$MOUNT_BASE/$name"
571
    echo ""
572
    echo "Mount point will be: $mount_point"
573

            
574
    # Get NFS options
575
    local nfs_options
576
    echo ""
577
    echo "NFS Options (press Enter for default):"
578
    echo "Default: *(rw,all_squash,insecure,async,no_subtree_check,anonuid=0,anongid=0)"
579
    read -p "Enter custom NFS options or press Enter for default: " nfs_options
580

            
581
    if [ -z "$nfs_options" ]; then
582
        nfs_options="*(rw,all_squash,insecure,async,no_subtree_check,anonuid=0,anongid=0)"
583
    fi
584

            
585
    # Create configuration entry
586
    local config_entry="${uuid}:${name}:${ip}:${interface}:${mount_point}:${nfs_options}"
587

            
588
    # Show configuration summary
589
    echo ""
590
    echo "=== Configuration Summary ==="
591
    echo "UUID: $uuid"
592
    echo "Name: $name"
593
    echo "Type: NFS Network Share"
594
    echo "IP: $ip"
595
    echo "Interface: $interface"
596
    echo "Mount Point: $mount_point"
597
    echo "NFS Options: $nfs_options"
598
    echo ""
599

            
600
    # Confirm configuration
601
    read -p "Save this configuration? (Y/n): " confirm
602
    if [[ "$confirm" =~ ^[Nn]$ ]]; then
603
        echo "Configuration cancelled."
604
        return 1
605
    fi
606

            
607
    # Save configuration
608
    echo "$config_entry" >> "$CONFIG_FILE"
609
    echo ""
610
    echo "✅ Configuration saved successfully!"
611
    echo ""
612
    echo "To test this configuration: autonas test $uuid"
613
    echo "To attach this disk when connected: autonas attach $uuid"
614

            
615
    return 0
616
}
617

            
618
# Function to configure local disk
619
configure_local_disk() {
620
    local uuid="$1"
621
    local name="$2"
622

            
623
    echo ""
624
    echo "=== Local Mount Configuration ==="
625
    echo "This disk will be mounted locally without network sharing."
626
    echo ""
627

            
628
    # Generate mount point
629
    local mount_point="$MOUNT_BASE/$name"
630
    echo "Mount point will be: $mount_point"
631
    echo ""
632

            
633
    # Create configuration entry
634
    local config_entry="${uuid}:${name}:LOCAL:LOCAL:${mount_point}:LOCAL"
635

            
636
    # Show configuration summary
637
    echo "=== Configuration Summary ==="
638
    echo "UUID: $uuid"
639
    echo "Name: $name"
640
    echo "Type: Local Mount (no network sharing)"
641
    echo "Mount Point: $mount_point"
642
    echo ""
643

            
644
    # Confirm configuration
645
    read -p "Save this configuration? (Y/n): " confirm
646
    if [[ "$confirm" =~ ^[Nn]$ ]]; then
647
        echo "Configuration cancelled."
648
        return 1
649
    fi
650

            
651
    # Save configuration
652
    echo "$config_entry" >> "$CONFIG_FILE"
653
    echo ""
654
    echo "✅ Configuration saved successfully!"
655
    echo ""
656
    echo "To test this configuration: autonas test $uuid"
657
    echo "To attach this disk when connected: autonas attach $uuid"
658

            
659
    return 0
660
}
661

            
662
# Function to configure import disk (camera)
663
configure_import_disk() {
664
    local uuid="$1"
665
    local name="$2"
666

            
667
    echo ""
668
    echo "=== Camera Import Configuration ==="
669
    echo "This device will be mounted temporarily, media imported, then unmounted."
670
    echo ""
671

            
672
    # Get destination path for import
673
    local destination_path
674
    while true; do
675
        read -p "Enter destination path for imported media: " destination_path
676
        if [ -z "$destination_path" ]; then
677
            echo "Error: Destination path cannot be empty"
678
            continue
679
        fi
680

            
681
        # Convert relative path to absolute
682
        if [[ ! "$destination_path" =~ ^/ ]]; then
683
            destination_path="$(pwd)/$destination_path"
684
        fi
685

            
686
        # Validate parent directory exists
687
        local parent_dir=$(dirname "$destination_path")
688
        if [ ! -d "$parent_dir" ]; then
689
            echo "Warning: Parent directory '$parent_dir' does not exist."
690
            read -p "Create parent directories? (Y/n): " create_dirs
691
            if [[ ! "$create_dirs" =~ ^[Nn]$ ]]; then
692
                if mkdir -p "$parent_dir" 2>/dev/null; then
693
                    echo "Created parent directories."
694
                else
695
                    echo "Error: Failed to create parent directories. Please check permissions."
696
                    continue
697
                fi
698
            else
699
                echo "Please enter a valid destination path."
700
                continue
701
            fi
702
        fi
703

            
704
        break
705
    done
706

            
707
    # Generate temporary mount point for import
708
    local temp_mount_point="$MOUNT_BASE/$name"
709

            
710
    # Create configuration entry (simplified format - no script path)
711
    local config_entry="${uuid}:${name}:IMPORT:IMPORT:${temp_mount_point}:${destination_path}"
712

            
713
    # Show configuration summary
714
    echo ""
715
    echo "=== Configuration Summary ==="
716
    echo "UUID: $uuid"
717
    echo "Name: $name"
718
    echo "Type: Camera Import (mount, import, unmount)"
719
    echo "Import destination: $destination_path"
Bogdan Timofte authored 3 months ago
720
    echo "Import script: ${AUTONAS_MEDIA_IMPORTER} (built-in, non-configurable)"
Bogdan Timofte authored 3 months ago
721
    echo "Temp mount point: $temp_mount_point"
722
    echo ""
723

            
724
    # Confirm configuration
725
    read -p "Save this configuration? (Y/n): " confirm
726
    if [[ "$confirm" =~ ^[Nn]$ ]]; then
727
        echo "Configuration cancelled."
728
        return 1
729
    fi
730

            
731
    # Save configuration
732
    echo "$config_entry" >> "$CONFIG_FILE"
733
    echo ""
734
    echo "✅ Configuration saved successfully!"
735
    echo ""
736
    echo "To test this configuration: autonas test $uuid"
737
    echo "When camera is connected, media will be imported automatically to: $destination_path"
738

            
739
    return 0
740
}
741

            
742
# Function to remove disk configuration
743
remove_disk() {
Bogdan Timofte authored 3 months ago
744
    local identifier="$1"
Bogdan Timofte authored 3 months ago
745

            
Bogdan Timofte authored 3 months ago
746
    if [[ -z "$identifier" ]]; then
747
        echo "Usage: autonas remove <uuid|name|mount_point>"
Bogdan Timofte authored 3 months ago
748
        return 1
749
    fi
750

            
751
    if [[ ! -f "$CONFIG_FILE" ]]; then
752
        echo "No configuration file found."
753
        return 1
754
    fi
755

            
Bogdan Timofte authored 3 months ago
756
    local config
757
    config=$(resolve_config_identifier "$identifier")
758
    if [[ -z "$config" ]]; then
759
        echo "Error: Entry '$identifier' not found in configuration."
Bogdan Timofte authored 3 months ago
760
        return 1
761
    fi
Bogdan Timofte authored 3 months ago
762

            
763
    local parsed=($(parse_config "$config"))
764
    local uuid="${parsed[0]}"
765

            
Bogdan Timofte authored 3 months ago
766
    # Show current configuration
Bogdan Timofte authored 3 months ago
767
    echo "Current configuration for identifier: $identifier"
Bogdan Timofte authored 3 months ago
768
    echo "=================================="
769
    echo "Name: ${parsed[1]}"
770
    echo "Type: ${parsed[2]}:${parsed[3]}"
771
    echo "Mount: ${parsed[4]}"
772
    echo ""
773

            
774
    # Confirm removal
775
    read -p "Remove this configuration? (y/N): " confirm
776
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
777
        echo "Removal cancelled."
778
        return 1
779
    fi
780

            
781
    # Remove configuration
782
    local temp_file=$(mktemp)
783
    grep -v "^${uuid}:" "$CONFIG_FILE" > "$temp_file"
784
    mv "$temp_file" "$CONFIG_FILE"
785

            
786
    echo "✅ Configuration removed successfully!"
787
    return 0
788
}
789

            
790
# Function to test disk configuration
791
test_config() {
Bogdan Timofte authored 3 months ago
792
    local identifier="$1"
793

            
794
    if [[ -z "$identifier" ]]; then
795
        echo "Usage: autonas test <uuid|name|mount_point>"
Bogdan Timofte authored 3 months ago
796
        return 1
797
    fi
798

            
799
    echo "AutoNAS Configuration Test"
800
    echo "========================="
801
    echo ""
802

            
803
    # Check if configuration exists
804
    local config
Bogdan Timofte authored 3 months ago
805
    config=$(resolve_config_identifier "$identifier")
806

            
Bogdan Timofte authored 3 months ago
807
    if [[ -z "$config" ]]; then
Bogdan Timofte authored 3 months ago
808
        echo "❌ Configuration not found for identifier: $identifier"
Bogdan Timofte authored 3 months ago
809
        echo ""
810
        echo "Available configurations:"
811
        list_disks
812
        return 1
813
    fi
814

            
815
    # Parse configuration
816
    local parsed=($(parse_config "$config"))
817
    local cfg_uuid="${parsed[0]}"
818
    local name="${parsed[1]}"
819
    local ip="${parsed[2]}"
820
    local interface="${parsed[3]}"
821
    local mount_point="${parsed[4]}"
822
    local nfs_options="${parsed[5]}"
Bogdan Timofte authored 3 months ago
823

            
824
    echo "✅ Configuration found"
825
    echo "   UUID: $cfg_uuid"
826
    echo "   Identifier used: $identifier"
Bogdan Timofte authored 3 months ago
827
    echo "   Name: $name"
828
    echo "   Type: $ip:$interface"
829
    echo "   Mount Point: $mount_point"
830
    echo ""
831

            
832
    # Test device detection
833
    echo "🔍 Testing device detection..."
834
    local device_info
Bogdan Timofte authored 3 months ago
835
    if device_info=$(get_device_info "$cfg_uuid" 2>/dev/null); then
Bogdan Timofte authored 3 months ago
836
        local device=$(echo "$device_info" | grep "^device:" | cut -d: -f2)
837
        echo "✅ Device found: $device"
838

            
839
        # Show device details
840
        echo "$device_info" | grep -v "^device:" | while IFS= read -r line; do
841
            echo "   $line"
842
        done
843
    else
844
        echo "❌ Device not found or not connected"
Bogdan Timofte authored 3 months ago
845
        echo "   Make sure the device with UUID $cfg_uuid is connected"
Bogdan Timofte authored 3 months ago
846
        return 1
847
    fi
848
    echo ""
849

            
850
    # Test network configuration (if applicable)
851
    if [[ "$ip" != "LOCAL" && "$ip" != "IMPORT" ]]; then
852
        echo "🌐 Testing network configuration..."
853

            
854
        # Test interface
855
        if interface_exists "$interface"; then
856
            echo "✅ Network interface exists: $interface"
857
        else
858
            echo "❌ Network interface not found: $interface"
859
            echo "   Available interfaces:"
860
            ip link show | grep "^[0-9]" | cut -d: -f2 | sed 's/^ *//' | grep -v "^lo$" | sed 's/^/     /'
861
            return 1
862
        fi
863

            
864
        # Test IP configuration
865
        if is_ip_configured "$ip" "$interface"; then
866
            echo "✅ IP already configured: $ip on $interface"
867
        else
868
            echo "ℹ️  IP not currently configured: $ip on $interface"
869
            echo "   (This is normal - IP will be activated during attach)"
870
        fi
871
        echo ""
872
    fi
873

            
874
    # Test mount point
875
    echo "📁 Testing mount point..."
876
    if [[ -d "$mount_point" ]]; then
877
        if mountpoint -q "$mount_point" 2>/dev/null; then
878
            echo "✅ Mount point exists and is mounted: $mount_point"
879
            local mounted_device=$(findmnt -n -o SOURCE "$mount_point")
880
            echo "   Mounted device: $mounted_device"
881
        else
882
            echo "ℹ️  Mount point directory exists but not mounted: $mount_point"
883
        fi
884
    else
885
        echo "ℹ️  Mount point directory will be created: $mount_point"
886
    fi
887
    echo ""
888

            
889
    # Test import configuration (if applicable)
890
    if [[ "$ip" == "IMPORT" && "$interface" == "IMPORT" ]]; then
891
        echo "📷 Testing camera import configuration..."
892
        local destination="$nfs_options"
893

            
894
        if [[ -d "$destination" ]]; then
895
            echo "✅ Import destination exists: $destination"
896
            if [[ -w "$destination" ]]; then
897
                echo "✅ Import destination is writable"
898
            else
899
                echo "⚠️  Import destination is not writable"
900
                echo "   You may need to check permissions"
901
            fi
902
        else
903
            echo "ℹ️  Import destination will be created: $destination"
904
            local parent_dir=$(dirname "$destination")
905
            if [[ -d "$parent_dir" && -w "$parent_dir" ]]; then
906
                echo "✅ Parent directory exists and is writable"
907
            else
908
                echo "❌ Cannot create import destination"
909
                echo "   Parent directory: $parent_dir"
910
                return 1
911
            fi
912
        fi
913

            
914
        # Test import script
Bogdan Timofte authored 3 months ago
915
        if [[ -x "${AUTONAS_MEDIA_IMPORTER}" ]]; then
Bogdan Timofte authored 3 months ago
916
            echo "✅ Media import script is available and executable"
917
        else
918
            echo "❌ Media import script not found or not executable"
Bogdan Timofte authored 3 months ago
919
            echo "   Expected: ${AUTONAS_MEDIA_IMPORTER}"
Bogdan Timofte authored 3 months ago
920
            return 1
921
        fi
922
        echo ""
923
    fi
924

            
925
    echo "🎉 Configuration test completed successfully!"
926
    echo ""
Bogdan Timofte authored 3 months ago
927
    echo "You can now attach this disk with: autonas attach $cfg_uuid"
Bogdan Timofte authored 3 months ago
928
    return 0
929
}
930

            
931
# Main configuration functions would go here...
932

            
933
# Main command dispatcher
934
case "${1:-}" in
935
    "attach")
936
        if [[ -z "$2" ]]; then
Bogdan Timofte authored 3 months ago
937
            echo "Error: UUID, disk name, or mount point required for attach command"
Bogdan Timofte authored 3 months ago
938
            show_usage
939
            exit 1
940
        fi
941
        handle_attach "$2"
942
        ;;
943
    "detach")
944
        if [[ -z "$2" ]]; then
Bogdan Timofte authored 3 months ago
945
            echo "Error: UUID, disk name, or mount point required for detach command"
Bogdan Timofte authored 3 months ago
946
            show_usage
947
            exit 1
948
        fi
949
        handle_detach "$2"
950
        ;;
951
    "import")
952
        # Internal use only - background import process
953
        if [[ -z "$4" ]]; then
954
            echo "Error: Missing arguments for import command"
955
            exit 1
956
        fi
957
        run_background_import "$2" "$3" "$4" "$5"
958
        ;;
959
    "reload")
960
        handle_reload
961
        ;;
962
    "add")
963
        add_disk "$2"
964
        ;;
965
    "remove")
966
        if [[ -z "$2" ]]; then
Bogdan Timofte authored 3 months ago
967
            echo "Error: UUID, disk name, or mount point required for remove command"
Bogdan Timofte authored 3 months ago
968
            show_usage
969
            exit 1
970
        fi
971
        remove_disk "$2"
972
        ;;
973
    "list")
974
        list_disks
975
        ;;
976
    "test")
977
        if [[ -z "$2" ]]; then
Bogdan Timofte authored 3 months ago
978
            echo "Error: UUID, disk name, or mount point required for test command"
Bogdan Timofte authored 3 months ago
979
            show_usage
980
            exit 1
981
        fi
982
        test_config "$2"
983
        ;;
984
    "show")
985
        show_available_disks
986
        ;;
987
    "status")
988
        echo "=== AutoNAS System Status ==="
989
        echo "Configuration file: $CONFIG_FILE"
990
        if [[ -f "$CONFIG_FILE" ]]; then
991
            count=$(grep -c "^[^#].*:.*:.*:" "$CONFIG_FILE" 2>/dev/null || echo "0")
992
            echo "Configured disks: $count"
993
        else
994
            echo "Configured disks: 0 (no config file)"
995
        fi
996
        echo "NFS server: $(systemctl is-active nfs-kernel-server 2>/dev/null || echo "unknown")"
997
        echo "AutoNAS service: $(systemctl is-active autonas 2>/dev/null || echo "unknown")"
998
        echo "Boot scan service: $(systemctl is-active autonas-boot-scan 2>/dev/null || echo "unknown")"
999
        echo ""
1000
        echo "Recent logs:"
1001
        journalctl -t autonas -n 5 --no-pager 2>/dev/null || echo "No recent logs found"
1002
        ;;
1003
    "debug")
1004
        case "${2:-}" in
1005
            "enable")
Bogdan Timofte authored 3 months ago
1006
                if [ -f "${AUTONAS_DEFAULTS_FILE}" ]; then
1007
                    sed -i 's/AUTONAS_DEBUG="false"/AUTONAS_DEBUG="true"/' "${AUTONAS_DEFAULTS_FILE}"
Bogdan Timofte authored 3 months ago
1008
                    echo "✓ Debug mode enabled - verbose logging is now active"
1009
                    echo "  All AutoNAS operations will produce detailed debug output"
1010
                else
Bogdan Timofte authored 3 months ago
1011
                    echo "Error: Configuration file ${AUTONAS_DEFAULTS_FILE} not found"
Bogdan Timofte authored 3 months ago
1012
                    exit 1
1013
                fi
1014
                ;;
1015
            "disable")
Bogdan Timofte authored 3 months ago
1016
                if [ -f "${AUTONAS_DEFAULTS_FILE}" ]; then
1017
                    sed -i 's/AUTONAS_DEBUG="true"/AUTONAS_DEBUG="false"/' "${AUTONAS_DEFAULTS_FILE}"
Bogdan Timofte authored 3 months ago
1018
                    echo "✓ Debug mode disabled - normal logging restored"
1019
                else
Bogdan Timofte authored 3 months ago
1020
                    echo "Error: Configuration file ${AUTONAS_DEFAULTS_FILE} not found"
Bogdan Timofte authored 3 months ago
1021
                    exit 1
1022
                fi
1023
                ;;
1024
            "status")
Bogdan Timofte authored 3 months ago
1025
                if [ -f "${AUTONAS_DEFAULTS_FILE}" ]; then
Bogdan Timofte authored 3 months ago
1026
                    echo "=== AutoNAS Debug Configuration ==="
Bogdan Timofte authored 3 months ago
1027
                    source "${AUTONAS_DEFAULTS_FILE}"
Bogdan Timofte authored 3 months ago
1028
                    echo "Debug mode: ${AUTONAS_DEBUG:-false}"
1029
                    echo "Log level: ${AUTONAS_LOG_LEVEL:-info}"
1030
                    if [ "$AUTONAS_DEBUG" = "true" ]; then
1031
                        echo "Status: 🟢 Debug logging is ENABLED"
1032
                        echo "  - Verbose messages will appear in logs and stderr"
1033
                        echo "  - All operations will be traced in detail"
1034
                    else
1035
                        echo "Status: 🔴 Debug logging is DISABLED"
1036
                        echo "  - Only normal info/warning/error messages will appear"
1037
                    fi
1038
                else
Bogdan Timofte authored 3 months ago
1039
                    echo "Error: Configuration file ${AUTONAS_DEFAULTS_FILE} not found"
Bogdan Timofte authored 3 months ago
1040
                    exit 1
1041
                fi
1042
                ;;
1043
            "")
1044
                echo "Error: Debug command requires an argument"
1045
                echo "Usage: $0 debug {enable|disable|status}"
1046
                exit 1
1047
                ;;
1048
            *)
1049
                echo "Error: Unknown debug command '$2'"
1050
                echo "Usage: $0 debug {enable|disable|status}"
1051
                exit 1
1052
                ;;
1053
        esac
1054
        ;;
1055
    "help"|"-h"|"--help"|"")
1056
        show_usage
1057
        ;;
1058
    *)
1059
        echo "Error: Unknown command '$1'"
1060
        echo
1061
        show_usage
1062
        exit 1
1063
        ;;
1064
esac