Newer Older
f16725e 3 months ago History
789 lines | 22.073kb
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 "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
12
INSTALL_DIR="/opt/autoSMART"
13
CONFIG_DIR="/etc/autosmart"
14
SERVICE_NAME="autosmart"
15
SYSTEMD_SERVICE="/etc/systemd/system/${SERVICE_NAME}.service"
16

            
17
# Default configuration (can be overridden by command line)
18
DB_HOST="${DB_HOST:-192.168.2.102}"
19
DB_USER="${DB_USER:-autosmart}"
20
DB_PASS="${DB_PASS:-autoSMART2025!}"
21
DB_NAME="${DB_NAME:-autosmart}"
22

            
23
# Node configuration
24
NODE_ID="${NODE_ID:-$(hostname -s)}"
25
SCAN_INTERVAL="${SCAN_INTERVAL:-300}"
26
FULL_SCAN_INTERVAL="${FULL_SCAN_INTERVAL:-3600}"
27

            
28
# Operation modes
29
UNINSTALL=false
30
FORCE_REINSTALL=false
31
CONFIG_ONLY=false
32

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

            
40
log_info() {
41
    echo -e "${BLUE}[INFO]${NC} $1"
42
}
43

            
44
log_success() {
45
    echo -e "${GREEN}[SUCCESS]${NC} $1"
46
}
47

            
48
log_warning() {
49
    echo -e "${YELLOW}[WARNING]${NC} $1"
50
}
51

            
52
log_error() {
53
    echo -e "${RED}[ERROR]${NC} $1"
54
}
55

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

            
82
parse_arguments() {
83
    COMMAND="install"  # Default command
84

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

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

            
151
check_requirements() {
152
    log_info "🔍 Checking system requirements..."
153

            
154
    # Check if running as root
155
    if [[ $EUID -ne 0 ]]; then
156
        log_error "This script must be run as root (use sudo)"
157
        exit 1
158
    fi
159

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

            
167
    # Check systemd
168
    if ! command -v systemctl &> /dev/null; then
169
        log_error "systemd is required but not found"
170
        exit 1
171
    fi
172

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

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

            
184
    log_success "System requirements check passed"
185
}
186

            
187
handle_uninstall() {
188
    log_info "🗑️  Uninstalling autoSMART..."
189

            
190
    # Stop and disable service
191
    if systemctl is-active --quiet autosmart; then
192
        systemctl stop autosmart
193
    fi
194
    if systemctl is-enabled --quiet autosmart; then
195
        systemctl disable autosmart
196
    fi
197

            
198
    # Remove service file
199
    if [[ -f "$SYSTEMD_SERVICE" ]]; then
200
        rm "$SYSTEMD_SERVICE"
201
        systemctl daemon-reload
202
    fi
203

            
204
    # Remove installation directory
205
    if [[ -d "$INSTALL_DIR" ]]; then
206
        rm -rf "$INSTALL_DIR"
207
    fi
208

            
209
    # Remove configuration directory
210
    if [[ -d "$CONFIG_DIR" ]]; then
211
        rm -rf "$CONFIG_DIR"
212
    fi
213

            
214
    # Remove log rotation
215
    if [[ -f "/etc/logrotate.d/autosmart" ]]; then
216
        rm "/etc/logrotate.d/autosmart"
217
    fi
218

            
219
    log_success "✅ autoSMART uninstalled successfully"
220
    exit 0
221
}
222

            
223
# Function to check if a package is installed
224
check_package_installed() {
225
    local package="$1"
226
    local package_manager="$2"
227

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

            
247
# Function to verify all dependencies are installed
248
verify_dependencies() {
249
    log_info "🔍 Verifying system dependencies..."
250

            
251
    local missing_packages=()
252
    local package_manager=""
253

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

            
270
    # Check system packages (including Perl modules from distribution)
271
    local system_packages=("perl" "smartmontools" "postgresql-client" "curl" "wget")
272
    local perl_packages=()
273

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

            
293
    # Check system packages
294
    for package in "${system_packages[@]}"; do
295
        if ! check_package_installed "$package" "$package_manager"; then
296
            missing_packages+=("$package")
297
        fi
298
    done
299

            
300
    # Check Perl packages from distribution
301
    for package in "${perl_packages[@]}"; do
302
        if ! check_package_installed "$package" "$package_manager"; then
303
            missing_packages+=("$package")
304
        fi
305
    done
306

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

            
320
# Function to install dependencies
321
install_dependencies() {
322
    log_info "📦 Installing system dependencies..."
323

            
324
    # First check if dependencies are already installed
325
    if verify_dependencies >/dev/null 2>&1; then
326
        log_success "All dependencies already installed"
327
        return 0
328
    fi
329

            
330
    log_info "Installing missing dependencies..."
331

            
332
    if command -v apt-get &> /dev/null; then
333
        # Debian/Ubuntu
334
        log_info "Updating package lists..."
335
        apt-get update -qq
336

            
337
        PACKAGES=(
338
            "perl"
339
            "libdbi-perl"
340
            "libdbd-pg-perl"
341
            "libjson-perl"
342
            "libfile-slurp-perl"
343
            "libgetopt-long-descriptive-perl"
344
            "libconfig-simple-perl"
345
            "smartmontools"
346
            "postgresql-client"
347
            "curl"
348
            "wget"
349
        )
350

            
351
        for package in "${PACKAGES[@]}"; do
352
            if ! check_package_installed "$package" "apt-get"; then
353
                log_info "Installing $package..."
354
                if ! apt-get install -y "$package" >/dev/null 2>&1; then
355
                    log_error "Failed to install $package"
356
                    exit 1
357
                fi
358
            fi
359
        done
360

            
361
    elif command -v dnf &> /dev/null; then
362
        # Fedora/RHEL 8+
363
        log_info "Updating package lists..."
364
        dnf update -y -q
365

            
366
        PACKAGES=(
367
            "perl"
368
            "perl-DBI"
369
            "perl-DBD-Pg"
370
            "perl-JSON"
371
            "perl-File-Slurp"
372
            "perl-Getopt-Long"
373
            "perl-Config-Simple"
374
            "smartmontools"
375
            "postgresql"
376
            "curl"
377
            "wget"
378
        )
379

            
380
        for package in "${PACKAGES[@]}"; do
381
            if ! check_package_installed "$package" "dnf"; then
382
                log_info "Installing $package..."
383
                if ! dnf install -y "$package" >/dev/null 2>&1; then
384
                    log_error "Failed to install $package"
385
                    exit 1
386
                fi
387
            fi
388
        done
389

            
390
    elif command -v yum &> /dev/null; then
391
        # RHEL/CentOS 7
392
        log_info "Updating package lists..."
393
        yum update -y -q
394

            
395
        PACKAGES=(
396
            "perl"
397
            "perl-DBI"
398
            "perl-DBD-Pg"
399
            "perl-JSON"
400
            "perl-File-Slurp"
401
            "perl-Getopt-Long"
402
            "perl-Config-Simple"
403
            "smartmontools"
404
            "postgresql"
405
            "curl"
406
            "wget"
407
        )
408

            
409
        for package in "${PACKAGES[@]}"; do
410
            if ! check_package_installed "$package" "yum"; then
411
                log_info "Installing $package..."
412
                if ! yum install -y "$package" >/dev/null 2>&1; then
413
                    log_error "Failed to install $package"
414
                    exit 1
415
                fi
416
            fi
417
        done
418

            
419
    elif command -v zypper &> /dev/null; then
420
        # openSUSE
421
        log_info "Updating package lists..."
422
        zypper refresh -q
423

            
424
        PACKAGES=(
425
            "perl"
426
            "perl-DBI"
427
            "perl-DBD-Pg"
428
            "perl-JSON"
429
            "perl-File-Slurp"
430
            "perl-Getopt-Long-Descriptive"
431
            "perl-Config-Simple"
432
            "smartmontools"
433
            "postgresql"
434
            "curl"
435
            "wget"
436
        )
437

            
438
        for package in "${PACKAGES[@]}"; do
439
            if ! check_package_installed "$package" "zypper"; then
440
                log_info "Installing $package..."
441
                if ! zypper install -y "$package" >/dev/null 2>&1; then
442
                    log_error "Failed to install $package"
443
                    exit 1
444
                fi
445
            fi
446
        done
447

            
448
    elif command -v pacman &> /dev/null; then
449
        # Arch Linux
450
        log_info "Updating package lists..."
451
        pacman -Sy --noconfirm
452

            
453
        PACKAGES=(
454
            "perl"
455
            "perl-dbi"
456
            "perl-dbd-pg"
457
            "perl-json"
458
            "perl-file-slurp"
459
            "smartmontools"
460
            "postgresql"
461
            "curl"
462
            "wget"
463
        )
464

            
465
        for package in "${PACKAGES[@]}"; do
466
            if ! check_package_installed "$package" "pacman"; then
467
                log_info "Installing $package..."
468
                if ! pacman -S --noconfirm "$package" >/dev/null 2>&1; then
469
                    log_error "Failed to install $package"
470
                    exit 1
471
                fi
472
            fi
473
        done
474

            
475
    else
476
        log_error "Unsupported package manager. Please install dependencies manually:"
477
        log_error "  - perl, smartmontools, postgresql-client, curl, wget"
478
        log_error "  - Perl modules: DBI, DBD::Pg, JSON, File::Slurp, Getopt::Long, Config::Simple"
479
        exit 1
480
    fi
481

            
482
    # Verify installation was successful
483
    if verify_dependencies >/dev/null 2>&1; then
484
        log_success "✅ All dependencies installed successfully"
485
    else
486
        log_error "Some dependencies may not have installed correctly"
487
        exit 1
488
    fi
489
}
490

            
491
create_directories() {
492
    log_info "📁 Creating directory structure..."
493

            
494
    # Create main directories
495
    mkdir -p "$INSTALL_DIR"/{scripts,lib,config,docs}
496
    mkdir -p "$CONFIG_DIR"
497

            
498
    # Set permissions
499
    chmod 755 "$INSTALL_DIR"
500
    chmod 755 "$CONFIG_DIR"
501

            
502
    log_success "Directories created"
503
}
504

            
505
copy_files() {
506
    log_info "📋 Copying autoSMART files..."
507

            
508
    # Copy scripts
509
    if [[ -d "$PROJECT_ROOT/scripts" ]]; then
510
        cp -r "$PROJECT_ROOT/scripts"/* "$INSTALL_DIR/scripts/"
511
        chmod +x "$INSTALL_DIR/scripts"/*.sh 2>/dev/null || true
512
        chmod +x "$INSTALL_DIR/scripts"/*.pl 2>/dev/null || true
513
    fi
514

            
515
    # Copy libraries
516
    if [[ -d "$PROJECT_ROOT/lib" ]]; then
517
        cp -r "$PROJECT_ROOT/lib"/* "$INSTALL_DIR/lib/"
518
    fi
519

            
520
    # Copy documentation
521
    if [[ -d "$PROJECT_ROOT/docs" ]]; then
522
        cp -r "$PROJECT_ROOT/docs"/* "$INSTALL_DIR/docs/"
523
    fi
524

            
525
    # Copy SQL files
526
    if [[ -d "$PROJECT_ROOT/sql" ]]; then
527
        cp -r "$PROJECT_ROOT/sql" "$INSTALL_DIR/"
528
    fi
529

            
530
    log_success "Files copied"
531
}
532

            
533
create_configuration() {
534
    log_info "⚙️  Creating configuration files..."
535

            
536
    # Main configuration file
537
    cat > "$CONFIG_DIR/autosmart.conf" << EOF
538
# autoSMART Configuration File
539
# Generated on $(date)
540

            
541
[database]
542
host = $DB_HOST
543
port = 5432
544
user = $DB_USER
545
password = $DB_PASS
546
database = $DB_NAME
547
timeout = 30
548

            
549
[node]
550
id = $NODE_ID
551
scan_interval = $SCAN_INTERVAL
552
full_scan_interval = $FULL_SCAN_INTERVAL
553
store_unchanged = false
554
max_retries = 3
555

            
556
[collection]
557
temperature_threshold = 5
558
parameter_changes_only = true
559
enable_predictive_analysis = true
560
health_check_interval = 86400
561

            
562
[logging]
563
level = INFO
564
max_size = 10M
565
rotate_count = 5
566
syslog = true
567

            
568
[alerts]
569
enable = true
570
temperature_critical = 60
571
reallocated_sectors_warning = 1
572
pending_sectors_critical = 5
573
EOF
574

            
575
    # YAML format configuration for Perl daemon
576
    cat > "$CONFIG_DIR/cluster-$NODE_ID.conf" << EOF
577
# autoSMART YAML Configuration for $NODE_ID
578
database:
579
  host: $DB_HOST
580
  port: 5432
581
  user: $DB_USER
582
  password: $DB_PASS
583
  database: $DB_NAME
584

            
585
node:
586
  id: $NODE_ID
587
  scan_interval: $SCAN_INTERVAL
588
  store_unchanged: false
589

            
590
collection:
591
  temperature_threshold: 5
592
  parameter_changes_only: true
593
  full_scan_interval: $FULL_SCAN_INTERVAL
594
EOF
595

            
596
    # Set secure permissions on config files
597
    chmod 600 "$CONFIG_DIR"/*.conf
598

            
599
    log_success "Configuration created"
600
}
601

            
602
create_systemd_service() {
603
    log_info "🔧 Creating systemd service..."
604

            
605
    cat > "$SYSTEMD_SERVICE" << EOF
606
[Unit]
607
Description=autoSMART SMART Data Collector
608
Documentation=file://$INSTALL_DIR/docs/README.md
609
After=network.target postgresql.service
610
Wants=postgresql.service
611

            
612
[Service]
613
Type=simple
614
ExecStart=$INSTALL_DIR/scripts/smart-collector-daemon.pl --config $CONFIG_DIR/cluster-$NODE_ID.conf --foreground
615
ExecReload=/bin/kill -HUP \$MAINPID
616
KillMode=process
617
Restart=always
618
RestartSec=30
619
User=root
620
Group=root
621

            
622
# Security settings
623
NoNewPrivileges=true
624
ProtectSystem=strict
625
ProtectHome=true
626
ReadWritePaths=$CONFIG_DIR
627
PrivateTmp=true
628

            
629
# Resource limits
630
LimitNOFILE=1024
631
MemoryMax=100M
632
CPUQuota=10%
633

            
634
# Logging
635
StandardOutput=journal
636
StandardError=journal
637
SyslogIdentifier=autosmart
638

            
639
[Install]
640
WantedBy=multi-user.target
641
EOF
642

            
643
    # Reload systemd
644
    systemctl daemon-reload
645

            
646
    log_success "Systemd service created"
647
}
648

            
649
test_database_connection() {
650
    log_info "🔗 Testing database connection..."
651

            
652
    # Test connection using psql
653
    if command -v psql &> /dev/null; then
654
        if PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -c "SELECT version();" >/dev/null 2>&1; then
655
            log_success "Database connection successful"
656
        else
657
            log_warning "Database connection failed. Service may not start correctly."
658
            log_info "Please ensure:"
659
            log_info "  • PostgreSQL server is running on $DB_HOST"
660
            log_info "  • Database '$DB_NAME' exists"
661
            log_info "  • User '$DB_USER' has proper permissions"
662
        fi
663
    else
664
        log_warning "psql not found. Cannot test database connection."
665
    fi
666
}
667

            
668
test_smart_detection() {
669
    log_info "🔍 Testing SMART device detection..."
670

            
671
    DEVICES_FOUND=0
672
    for device in /dev/sd? /dev/nvme?n?; do
673
        if [[ -b "$device" ]] && smartctl -i "$device" >/dev/null 2>&1; then
674
            MODEL=$(smartctl -i "$device" | grep "Device Model\|Model Number" | head -1 | cut -d: -f2 | xargs)
675
            if [[ -n "$MODEL" ]]; then
676
                log_info "  Found: $device - $MODEL"
677
                ((DEVICES_FOUND++))
678
            fi
679
        fi
680
    done
681

            
682
    if [[ $DEVICES_FOUND -gt 0 ]]; then
683
        log_success "Detected $DEVICES_FOUND SMART-capable devices"
684
    else
685
        log_warning "No SMART-capable devices detected"
686
    fi
687
}
688

            
689
finalize_installation() {
690
    log_info "🎯 Finalizing installation..."
691

            
692
    # Enable service (but don't start yet)
693
    systemctl enable "$SERVICE_NAME"
694

            
695
    # Create log rotation
696
    cat > "/etc/logrotate.d/autosmart" << EOF
697
/var/log/autosmart/*.log {
698
    daily
699
    rotate 7
700
    compress
701
    delaycompress
702
    missingok
703
    notifempty
704
    postrotate
705
        systemctl reload-or-restart autosmart
706
    endscript
707
}
708
EOF
709

            
710
    log_success "Installation finalized"
711
}
712

            
713
show_completion_message() {
714
    log_success "✅ autoSMART installation completed successfully!"
715
    log_info ""
716
    log_info "📋 Installation Summary:"
717
    log_info "  • Install Directory: $INSTALL_DIR"
718
    log_info "  • Config Directory: $CONFIG_DIR"
719
    log_info "  • Service Name: $SERVICE_NAME"
720
    log_info "  • Node ID: $NODE_ID"
721
    log_info ""
722
    log_info "🚀 Next Steps:"
723
    log_info "  1. Start the service:"
724
    log_info "     systemctl start $SERVICE_NAME"
725
    log_info ""
726
    log_info "  2. Check service status:"
727
    log_info "     systemctl status $SERVICE_NAME"
728
    log_info ""
729
    log_info "  3. View logs:"
730
    log_info "     journalctl -u $SERVICE_NAME -f"
731
    log_info ""
732
    log_info "📖 Documentation: $INSTALL_DIR/docs/README.md"
733
    log_info "⚙️  Configuration: $CONFIG_DIR/autosmart.conf"
734
    log_info ""
735
    log_info "🎉 autoSMART is ready to monitor your storage devices!"
736
}
737

            
738
# Main execution
739
main() {
740
    parse_arguments "$@"
741
    show_header
742

            
743
    case "$COMMAND" in
744
        uninstall)
745
            handle_uninstall
746
            ;;
747
        install)
748
            check_requirements
749

            
750
            # Handle force reinstall
751
            if [[ "$FORCE_REINSTALL" == true ]]; then
752
                log_info "🗑️  Force reinstall: cleaning previous installation..."
753
                handle_uninstall 2>/dev/null || true
754
                sleep 2
755
            fi
756

            
757
            # Handle config-only mode
758
            if [[ "$CONFIG_ONLY" == true ]]; then
759
                log_info "⚙️  Configuration-only mode"
760
                if [[ ! -d "$INSTALL_DIR" ]]; then
761
                    log_error "autoSMART is not installed. Run full installation first."
762
                    exit 1
763
                fi
764
                create_configuration
765
                log_success "✅ Configuration updated successfully!"
766
                exit 0
767
            fi
768

            
769
            # Full installation
770
            install_dependencies
771
            create_directories
772
            copy_files
773
            create_configuration
774
            create_systemd_service
775
            test_database_connection
776
            test_smart_detection
777
            finalize_installation
778
            show_completion_message
779
            ;;
780
        *)
781
            log_error "Unknown command: $COMMAND"
782
            show_usage
783
            exit 1
784
            ;;
785
    esac
786
}
787

            
788
# Run main function
789
main "$@"