Newer Older
f16725e 3 months ago History
755 lines | 21.281kb
Bogdan Timofte authored 3 months ago
1
#!/bin/bash
2

            
3
# autoSMART Node Installation Script
4
# Version: 1.0
5
# Description: Install autoSMART on target nodes (Linux systems only)
6
# Note: This script is called by deploy.sh and should run on target nodes
7

            
8
set -e
9

            
10
SCRIPT_DIR="$(cd "$(dirnameverify_dependencies() {
11
    log_info "🔍 Verifying system dependencies..."
12

            
13
    local missing_packages=()
14
    local package_manager=""SH_SOURCE[0]}")" && pwd)"
15
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
16
INSTALL_DIR="/opt/autoSMART"
17
CONFIG_DIR="/etc/autosmart"
18
SERVICE_NAME="autosmart"
19
SYSTEMD_SERVICE="/etc/systemd/system/${SERVICE_NAME}.service"
20

            
21
# Default configuration (can be overridden by command line)
22
DB_HOST="${DB_HOST:-192.168.2.102}"
23
DB_USER="${DB_USER:-autosmart}"
24
DB_PASS="${DB_PASS:-autoSMART2025!}"
25
DB_NAME="${DB_NAME:-autosmart}"
26

            
27
# Node configuration
28
NODE_ID="${NODE_ID:-$(hostname -s)}"
29
SCAN_INTERVAL="${SCAN_INTERVAL:-300}"
30
FULL_SCAN_INTERVAL="${FULL_SCAN_INTERVAL:-3600}"
31

            
32
# Operation modes
33
UNINSTALL=false
34
FORCE_REINSTALL=false
35
CONFIG_ONLY=false
36

            
37
# Colors for output
38
RED='\033[0;31m'
39
GREEN='\033[0;32m'
40
YELLOW='\033[1;33m'
41
BLUE='\033[0;34m'
42
NC='\033[0m' # No Color
43

            
44
log_info() {
45
    echo -e "${BLUE}[INFO]${NC} $1"
46
}
47

            
48
log_success() {
49
    echo -e "${GREEN}[SUCCESS]${NC} $1"
50
}
51

            
52
log_warning() {
53
    echo -e "${YELLOW}[WARNING]${NC} $1"
54
}
55

            
56
log_error() {
57
    echo -e "${RED}[ERROR]${NC} $1"
58
}
59

            
60
show_usage() {
61
    echo "autoSMART Node Installation Script v1.0"
62
    echo "========================================"
63
    echo ""
64
    echo "Usage: $0 [COMMAND] [OPTIONS]"
65
    echo ""
66
    echo "Commands:"
67
    echo "  install               Install autoSMART on current node (default)"
68
    echo "  uninstall             Remove autoSMART completely from current node"
69
    echo ""
70
    echo "Options:"
71
    echo "  --help                Show this help message"
72
    echo "  --force-reinstall     Clean installation (removes previous version)"
73
    echo "  --config-only         Only create/update configuration files"
74
    echo "  --db-host HOST        Database host (default: 192.168.2.102)"
75
    echo "  --db-user USER        Database user (default: autosmart)"
76
    echo "  --db-pass PASS        Database password (default: autoSMART2025!)"
77
    echo "  --db-name NAME        Database name (default: autosmart)"
78
    echo "  --node-id ID          Node identifier (default: hostname)"
79
    echo "  --scan-interval SEC   Scan interval in seconds (default: 300)"
80
    echo ""
81
    echo "Note: This script should be called by deploy.sh, not run directly."
82
    echo "For deployment from development machine, use: deploy.sh install <IP>"
83
    echo ""
84
}
85

            
86
parse_arguments() {
87
    COMMAND="install"  # Default command
88

            
89
    while [[ $# -gt 0 ]]; do
90
        case $1 in
91
            install|uninstall)
92
                COMMAND="$1"
93
                shift
94
                ;;
95
            --help)
96
                show_usage
97
                exit 0
98
                ;;
99
            --force-reinstall)
100
                FORCE_REINSTALL=true
101
                shift
102
                ;;
103
            --config-only)
104
                CONFIG_ONLY=true
105
                shift
106
                ;;
107
            --db-host)
108
                DB_HOST="$2"
109
                shift 2
110
                ;;
111
            --db-user)
112
                DB_USER="$2"
113
                shift 2
114
                ;;
115
            --db-pass)
116
                DB_PASS="$2"
117
                shift 2
118
                ;;
119
            --db-name)
120
                DB_NAME="$2"
121
                shift 2
122
                ;;
123
            --node-id)
124
                NODE_ID="$2"
125
                shift 2
126
                ;;
127
            --scan-interval)
128
                SCAN_INTERVAL="$2"
129
                shift 2
130
                ;;
131
            *)
132
                log_error "Unknown option: $1"
133
                show_usage
134
                exit 1
135
                ;;
136
        esac
137
    done
138
}
139

            
140
show_header() {
141
    log_info "🔧 autoSMART Node Installation v1.0"
142
    log_info "==================================="
143
    log_info "Installing on target node: $(hostname)"
144
    log_info ""
145
    log_info "Operation: $COMMAND"
146
    log_info "Node ID: $NODE_ID"
147
    log_info "Database: $DB_HOST:5432/$DB_NAME"
148
    if [[ "$COMMAND" == "install" ]]; then
149
        log_info "Install Directory: $INSTALL_DIR"
150
        log_info "Config Directory: $CONFIG_DIR"
151
    fi
152
    log_info ""
153
}
154

            
155
check_requirements() {
156
    log_info "🔍 Checking system requirements..."
157

            
158
    # Check if running as root
159
    if [[ $EUID -ne 0 ]]; then
160
        log_error "This script must be run as root (use sudo)"
161
        exit 1
162
    fi
163

            
164
    # Check if running on Linux
165
    if [[ "$(uname)" != "Linux" ]]; then
166
        log_error "autoSMART can only be installed on Linux systems"
167
        log_error "Current system: $(uname)"
168
        exit 1
169
    fi
170

            
171
    # Check systemd
172
    if ! command -v systemctl &> /dev/null; then
173
        log_error "systemd is required but not found"
174
        exit 1
175
    fi
176

            
177
    # Check and report dependency status
178
    if ! verify_dependencies >/dev/null 2>&1; then
179
        log_warning "Some dependencies are missing (will be installed automatically)"
180
    fi
181

            
182
    # Check available space
183
    AVAILABLE_SPACE=$(df / | tail -1 | awk '{print $4}')
184
    if [[ $AVAILABLE_SPACE -lt 100000 ]]; then
185
        log_warning "Less than 100MB available space. Installation may fail."
186
    fi
187

            
188
    log_success "System requirements check passed"
189
}
190

            
191
handle_uninstall() {
192
    log_info "🗑️  Uninstalling autoSMART..."
193

            
194
    # Stop and disable service
195
    if systemctl is-active --quiet autosmart; then
196
        systemctl stop autosmart
197
    fi
198
    if systemctl is-enabled --quiet autosmart; then
199
        systemctl disable autosmart
200
    fi
201

            
202
    # Remove service file
203
    if [[ -f "$SYSTEMD_SERVICE" ]]; then
204
        rm "$SYSTEMD_SERVICE"
205
        systemctl daemon-reload
206
    fi
207

            
208
    # Remove installation directory
209
    if [[ -d "$INSTALL_DIR" ]]; then
210
        rm -rf "$INSTALL_DIR"
211
    fi
212

            
213
    # Remove configuration directory
214
    if [[ -d "$CONFIG_DIR" ]]; then
215
        rm -rf "$CONFIG_DIR"
216
    fi
217

            
218
    # Remove log rotation
219
    if [[ -f "/etc/logrotate.d/autosmart" ]]; then
220
        rm "/etc/logrotate.d/autosmart"
221
    fi
222

            
223
    log_success "✅ autoSMART uninstalled successfully"
224
    exit 0
225
}
226

            
227
# Function to check if a package is installed
228
check_package_installed() {
229
    local package="$1"
230
    local package_manager="$2"
231

            
232
    case "$package_manager" in
233
        "apt-get")
234
            dpkg -l | grep -q "^ii  $package " 2>/dev/null
235
            ;;
236
        "yum"|"dnf")
237
            rpm -qa | grep -q "$package" 2>/dev/null
238
            ;;
239
        "zypper")
240
            zypper se -i "$package" | grep -q "^i" 2>/dev/null
241
            ;;
242
        "pacman")
243
            pacman -Q "$package" >/dev/null 2>&1
244
            ;;
245
        *)
246
            return 1
247
            ;;
248
    esac
249
}
250

            
251
# Function to verify all dependencies are installed
252
verify_dependencies() {
253
    log_info "� Verifying system dependencies..."
254

            
255
    local missing_packages=()
256
    local missing_perl_modules=()
257
    local package_manager=""
258

            
259
    # Detect package manager
260
    if command -v apt-get &> /dev/null; then
261
        package_manager="apt-get"
262
    elif command -v yum &> /dev/null; then
263
        package_manager="yum"
264
    elif command -v dnf &> /dev/null; then
265
        package_manager="dnf"
266
    elif command -v zypper &> /dev/null; then
267
        package_manager="zypper"
268
    elif command -v pacman &> /dev/null; then
269
        package_manager="pacman"
270
    else
271
        log_warning "Unknown package manager. Dependency verification limited."
272
        return 1
273
    fi
274

            
275
    # Check system packages (including Perl modules from distribution)
276
    local system_packages=("perl" "smartmontools" "postgresql-client" "curl" "wget")
277
    local perl_packages=()
278

            
279
    # Add Perl module packages based on package manager
280
    case "$package_manager" in
281
        "apt-get")
282
            perl_packages+=("libdbi-perl" "libdbd-pg-perl" "libjson-perl" "libfile-slurp-perl"
283
                           "libgetopt-long-descriptive-perl" "libconfig-simple-perl")
284
            ;;
285
        "yum"|"dnf")
286
            perl_packages+=("perl-DBI" "perl-DBD-Pg" "perl-JSON" "perl-File-Slurp"
287
                           "perl-Getopt-Long" "perl-Config-Simple")
288
            ;;
289
        "zypper")
290
            perl_packages+=("perl-DBI" "perl-DBD-Pg" "perl-JSON" "perl-File-Slurp"
291
                           "perl-Getopt-Long-Descriptive" "perl-Config-Simple")
292
            ;;
293
        "pacman")
294
            perl_packages+=("perl-dbi" "perl-dbd-pg" "perl-json" "perl-file-slurp")
295
            ;;
296
    esac
297

            
298
    # Check system packages
299
    for package in "${system_packages[@]}"; do
300
        if ! check_package_installed "$package" "$package_manager"; then
301
            missing_packages+=("$package")
302
        fi
303
    done
304

            
305
    # Check Perl packages from distribution
306
    for package in "${perl_packages[@]}"; do
307
        if ! check_package_installed "$package" "$package_manager"; then
308
            missing_packages+=("$package")
309
        fi
310
    done
311

            
312
    # Report results
313
    if [[ ${#missing_packages[@]} -eq 0 ]]; then
314
        log_success "✅ All dependencies are available"
315
        return 0
316
    else
317
        log_warning "Missing dependencies detected:"
318
        if [[ ${#missing_packages[@]} -gt 0 ]]; then
319
            log_warning "  Missing packages: ${missing_packages[*]}"
320
        fi
321
        return 1
322
    fi
323
}
324

            
325
# Function to install dependencies from local packages (offline)
326
install_dependencies_offline() {
327
    log_info "�📦 Installing dependencies from local packages..."
328

            
329
    local packages_dir="$PROJECT_ROOT/packages"
330

            
331
    if [[ ! -d "$packages_dir" ]]; then
332
        log_warning "Local packages directory not found: $packages_dir"
333
        log_info "Falling back to online installation..."
334
        return 1
335
    fi
336

            
337
    local package_manager=""
338
    if command -v apt-get &> /dev/null; then
339
        package_manager="apt-get"
340
        local deb_files=("$packages_dir"/*.deb)
341
        if [[ -f "${deb_files[0]}" ]]; then
342
            log_info "Installing .deb packages..."
343
            dpkg -i "$packages_dir"/*.deb 2>/dev/null || {
344
                log_info "Fixing broken dependencies..."
345
                apt-get install -f -y >/dev/null 2>&1
346
            }
347
        fi
348
    elif command -v yum &> /dev/null || command -v dnf &> /dev/null; then
349
        package_manager="yum"
350
        local rpm_files=("$packages_dir"/*.rpm)
351
        if [[ -f "${rpm_files[0]}" ]]; then
352
            log_info "Installing .rpm packages..."
353
            if command -v dnf &> /dev/null; then
354
                dnf install -y "$packages_dir"/*.rpm >/dev/null 2>&1
355
            else
356
                yum localinstall -y "$packages_dir"/*.rpm >/dev/null 2>&1
357
            fi
358
        fi
359
    fi
360

            
361
    # Verify installation
362
    if verify_dependencies >/dev/null 2>&1; then
363
        log_success "✅ Offline dependencies installed successfully"
364
        return 0
365
    else
366
        log_warning "Offline installation incomplete"
367
        return 1
368
    fi
369
}
370

            
371
# Enhanced dependency installation with offline support
372
install_dependencies() {
373
    log_info "📦 Installing system dependencies..."
374

            
375
    # First try to verify if dependencies are already installed
376
    if verify_dependencies >/dev/null 2>&1; then
377
        log_success "All dependencies already installed"
378
        return 0
379
    fi
380

            
381
    # If offline mode is enabled, only try offline installation
382
    if [[ "$OFFLINE_MODE" == true ]]; then
383
        log_info "Offline mode enabled - using local packages only"
384
        if install_dependencies_offline; then
385
            return 0
386
        else
387
            log_error "Offline installation failed and online installation is disabled"
388
            log_error "Please check packages directory: $PROJECT_ROOT/packages"
389
            exit 1
390
        fi
391
    fi
392

            
393
    # Try offline installation first
394
    if install_dependencies_offline; then
395
        return 0
396
    fi
397

            
398
    # Fall back to online installation
399
    log_info "Attempting online installation..."
400

            
401
    if command -v apt-get &> /dev/null; then
402
        # Debian/Ubuntu
403
        apt-get update -qq
404
        PACKAGES=(
405
            "perl"
406
            "libdbi-perl"
407
            "libdbd-pg-perl"
408
            "libjson-perl"
409
            "libfile-slurp-perl"
410
            "libgetopt-long-descriptive-perl"
411
            "libconfig-simple-perl"
412
            "smartmontools"
413
            "postgresql-client"
414
            "curl"
415
            "wget"
416
        )
417

            
418
        for package in "${PACKAGES[@]}"; do
419
            if ! dpkg -l | grep -q "^ii  $package "; then
420
                log_info "Installing $package..."
421
                apt-get install -y "$package" >/dev/null 2>&1
422
            fi
423
        done
424

            
425
    elif command -v yum &> /dev/null; then
426
        # RHEL/CentOS
427
        yum update -y -q
428
        PACKAGES=(
429
            "perl"
430
            "perl-DBI"
431
            "perl-DBD-Pg"
432
            "perl-JSON"
433
            "perl-File-Slurp"
434
            "perl-Getopt-Long"
435
            "perl-Config-Simple"
436
            "smartmontools"
437
            "postgresql"
438
            "curl"
439
            "wget"
440
        )
441

            
442
        for package in "${PACKAGES[@]}"; do
443
            if ! rpm -qa | grep -q "$package"; then
444
                log_info "Installing $package..."
445
                yum install -y "$package" >/dev/null 2>&1
446
            fi
447
        done
448

            
449
    else
450
        log_error "Unsupported package manager. Please install dependencies manually."
451
        exit 1
452
    fi
453

            
454
    log_success "Dependencies installed"
455
}
456

            
457
create_directories() {
458
    log_info "📁 Creating directory structure..."
459

            
460
    # Create main directories
461
    mkdir -p "$INSTALL_DIR"/{scripts,lib,config,docs}
462
    mkdir -p "$CONFIG_DIR"
463

            
464
    # Set permissions
465
    chmod 755 "$INSTALL_DIR"
466
    chmod 755 "$CONFIG_DIR"
467

            
468
    log_success "Directories created"
469
}
470

            
471
copy_files() {
472
    log_info "📋 Copying autoSMART files..."
473

            
474
    # Copy scripts
475
    if [[ -d "$PROJECT_ROOT/scripts" ]]; then
476
        cp -r "$PROJECT_ROOT/scripts"/* "$INSTALL_DIR/scripts/"
477
        chmod +x "$INSTALL_DIR/scripts"/*.sh 2>/dev/null || true
478
        chmod +x "$INSTALL_DIR/scripts"/*.pl 2>/dev/null || true
479
    fi
480

            
481
    # Copy libraries
482
    if [[ -d "$PROJECT_ROOT/lib" ]]; then
483
        cp -r "$PROJECT_ROOT/lib"/* "$INSTALL_DIR/lib/"
484
    fi
485

            
486
    # Copy documentation
487
    if [[ -d "$PROJECT_ROOT/docs" ]]; then
488
        cp -r "$PROJECT_ROOT/docs"/* "$INSTALL_DIR/docs/"
489
    fi
490

            
491
    # Copy SQL files
492
    if [[ -d "$PROJECT_ROOT/sql" ]]; then
493
        cp -r "$PROJECT_ROOT/sql" "$INSTALL_DIR/"
494
    fi
495

            
496
    log_success "Files copied"
497
}
498

            
499
create_configuration() {
500
    log_info "⚙️  Creating configuration files..."
501

            
502
    # Main configuration file
503
    cat > "$CONFIG_DIR/autosmart.conf" << EOF
504
# autoSMART Configuration File
505
# Generated on $(date)
506

            
507
[database]
508
host = $DB_HOST
509
port = 5432
510
user = $DB_USER
511
password = $DB_PASS
512
database = $DB_NAME
513
timeout = 30
514

            
515
[node]
516
id = $NODE_ID
517
scan_interval = $SCAN_INTERVAL
518
full_scan_interval = $FULL_SCAN_INTERVAL
519
store_unchanged = false
520
max_retries = 3
521

            
522
[collection]
523
temperature_threshold = 5
524
parameter_changes_only = true
525
enable_predictive_analysis = true
526
health_check_interval = 86400
527

            
528
[logging]
529
level = INFO
530
max_size = 10M
531
rotate_count = 5
532
syslog = true
533

            
534
[alerts]
535
enable = true
536
temperature_critical = 60
537
reallocated_sectors_warning = 1
538
pending_sectors_critical = 5
539
EOF
540

            
541
    # YAML format configuration for Perl daemon
542
    cat > "$CONFIG_DIR/cluster-$NODE_ID.conf" << EOF
543
# autoSMART YAML Configuration for $NODE_ID
544
database:
545
  host: $DB_HOST
546
  port: 5432
547
  user: $DB_USER
548
  password: $DB_PASS
549
  database: $DB_NAME
550

            
551
node:
552
  id: $NODE_ID
553
  scan_interval: $SCAN_INTERVAL
554
  store_unchanged: false
555

            
556
collection:
557
  temperature_threshold: 5
558
  parameter_changes_only: true
559
  full_scan_interval: $FULL_SCAN_INTERVAL
560
EOF
561

            
562
    # Set secure permissions on config files
563
    chmod 600 "$CONFIG_DIR"/*.conf
564

            
565
    log_success "Configuration created"
566
}
567

            
568
create_systemd_service() {
569
    log_info "🔧 Creating systemd service..."
570

            
571
    cat > "$SYSTEMD_SERVICE" << EOF
572
[Unit]
573
Description=autoSMART SMART Data Collector
574
Documentation=file://$INSTALL_DIR/docs/README.md
575
After=network.target postgresql.service
576
Wants=postgresql.service
577

            
578
[Service]
579
Type=simple
580
ExecStart=$INSTALL_DIR/scripts/smart-collector-daemon.pl --config $CONFIG_DIR/cluster-$NODE_ID.conf --foreground
581
ExecReload=/bin/kill -HUP \$MAINPID
582
KillMode=process
583
Restart=always
584
RestartSec=30
585
User=root
586
Group=root
587

            
588
# Security settings
589
NoNewPrivileges=true
590
ProtectSystem=strict
591
ProtectHome=true
592
ReadWritePaths=$CONFIG_DIR
593
PrivateTmp=true
594

            
595
# Resource limits
596
LimitNOFILE=1024
597
MemoryMax=100M
598
CPUQuota=10%
599

            
600
# Logging
601
StandardOutput=journal
602
StandardError=journal
603
SyslogIdentifier=autosmart
604

            
605
[Install]
606
WantedBy=multi-user.target
607
EOF
608

            
609
    # Reload systemd
610
    systemctl daemon-reload
611

            
612
    log_success "Systemd service created"
613
}
614

            
615
test_database_connection() {
616
    log_info "🔗 Testing database connection..."
617

            
618
    # Test connection using psql
619
    if command -v psql &> /dev/null; then
620
        if PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -c "SELECT version();" >/dev/null 2>&1; then
621
            log_success "Database connection successful"
622
        else
623
            log_warning "Database connection failed. Service may not start correctly."
624
            log_info "Please ensure:"
625
            log_info "  • PostgreSQL server is running on $DB_HOST"
626
            log_info "  • Database '$DB_NAME' exists"
627
            log_info "  • User '$DB_USER' has proper permissions"
628
        fi
629
    else
630
        log_warning "psql not found. Cannot test database connection."
631
    fi
632
}
633

            
634
test_smart_detection() {
635
    log_info "🔍 Testing SMART device detection..."
636

            
637
    DEVICES_FOUND=0
638
    for device in /dev/sd? /dev/nvme?n?; do
639
        if [[ -b "$device" ]] && smartctl -i "$device" >/dev/null 2>&1; then
640
            MODEL=$(smartctl -i "$device" | grep "Device Model\|Model Number" | head -1 | cut -d: -f2 | xargs)
641
            if [[ -n "$MODEL" ]]; then
642
                log_info "  Found: $device - $MODEL"
643
                ((DEVICES_FOUND++))
644
            fi
645
        fi
646
    done
647

            
648
    if [[ $DEVICES_FOUND -gt 0 ]]; then
649
        log_success "Detected $DEVICES_FOUND SMART-capable devices"
650
    else
651
        log_warning "No SMART-capable devices detected"
652
    fi
653
}
654

            
655
finalize_installation() {
656
    log_info "🎯 Finalizing installation..."
657

            
658
    # Enable service (but don't start yet)
659
    systemctl enable "$SERVICE_NAME"
660

            
661
    # Create log rotation
662
    cat > "/etc/logrotate.d/autosmart" << EOF
663
/var/log/autosmart/*.log {
664
    daily
665
    rotate 7
666
    compress
667
    delaycompress
668
    missingok
669
    notifempty
670
    postrotate
671
        systemctl reload-or-restart autosmart
672
    endscript
673
}
674
EOF
675

            
676
    log_success "Installation finalized"
677
}
678

            
679
show_completion_message() {
680
    log_success "✅ autoSMART installation completed successfully!"
681
    log_info ""
682
    log_info "📋 Installation Summary:"
683
    log_info "  • Install Directory: $INSTALL_DIR"
684
    log_info "  • Config Directory: $CONFIG_DIR"
685
    log_info "  • Service Name: $SERVICE_NAME"
686
    log_info "  • Node ID: $NODE_ID"
687
    log_info ""
688
    log_info "🚀 Next Steps:"
689
    log_info "  1. Start the service:"
690
    log_info "     systemctl start $SERVICE_NAME"
691
    log_info ""
692
    log_info "  2. Check service status:"
693
    log_info "     systemctl status $SERVICE_NAME"
694
    log_info ""
695
    log_info "  3. View logs:"
696
    log_info "     journalctl -u $SERVICE_NAME -f"
697
    log_info ""
698
    log_info "📖 Documentation: $INSTALL_DIR/docs/README.md"
699
    log_info "⚙️  Configuration: $CONFIG_DIR/autosmart.conf"
700
    log_info ""
701
    log_info "🎉 autoSMART is ready to monitor your storage devices!"
702
}
703

            
704
# Main execution
705
main() {
706
    parse_arguments "$@"
707
    show_header
708

            
709
    case "$COMMAND" in
710
        uninstall)
711
            handle_uninstall
712
            ;;
713
        install)
714
            check_requirements
715

            
716
            # Handle force reinstall
717
            if [[ "$FORCE_REINSTALL" == true ]]; then
718
                log_info "🗑️  Force reinstall: cleaning previous installation..."
719
                handle_uninstall 2>/dev/null || true
720
                sleep 2
721
            fi
722

            
723
            # Handle config-only mode
724
            if [[ "$CONFIG_ONLY" == true ]]; then
725
                log_info "⚙️  Configuration-only mode"
726
                if [[ ! -d "$INSTALL_DIR" ]]; then
727
                    log_error "autoSMART is not installed. Run full installation first."
728
                    exit 1
729
                fi
730
                create_configuration
731
                log_success "✅ Configuration updated successfully!"
732
                exit 0
733
            fi
734

            
735
            # Full installation
736
            install_dependencies
737
            create_directories
738
            copy_files
739
            create_configuration
740
            create_systemd_service
741
            test_database_connection
742
            test_smart_detection
743
            finalize_installation
744
            show_completion_message
745
            ;;
746
        *)
747
            log_error "Unknown command: $COMMAND"
748
            show_usage
749
            exit 1
750
            ;;
751
    esac
752
}
753

            
754
# Run main function
755
main "$@"