#!/bin/bash # AutoNAS Remote Deploy Script # Instalează și gestionează AutoNAS pe serverele remote 192.168.2.91-93 set -e # Exit on any error # Configurații SSH_USER="root" REMOTE_DIR="/tmp/autonas-deploy" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Parse cluster.json for nodes parse_cluster_nodes() { local json_file="$SCRIPT_DIR/cluster.json" if ! [ -f "$json_file" ]; then log_error "cluster.json not found in $SCRIPT_DIR" exit 1 fi jq -c '.cluster.nodes[]' "$json_file" 2>/dev/null } # Build arrays of IPs and hostnames get_targets() { local nodes_json nodes_json=$(parse_cluster_nodes) local ips=() local names=() while IFS= read -r node; do local ip name ip=$(echo "$node" | jq -r '.ip') name=$(echo "$node" | jq -r '.hostname') ips+=("$ip") names+=("$name") done <<< "$nodes_json" echo "${ips[@]}" } # Get node name by IP get_node_name() { local search_ip="$1" local nodes_json nodes_json=$(parse_cluster_nodes) while IFS= read -r node; do local ip name ip=$(echo "$node" | jq -r '.ip') name=$(echo "$node" | jq -r '.hostname') if [[ "$ip" == "$search_ip" ]]; then echo "$name" return fi done <<< "$nodes_json" echo "$search_ip" } # Culori pentru output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Funcții helper log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } print_banner() { echo "======================================" echo " AutoNAS Remote Deploy Script" echo "======================================" echo "" } # Funcție pentru verificarea dacă hostul este up check_host_up() { local target="$1" log_info "Verificare dacă hostul $target este accesibil..." # Pentru simplitate, verificăm direct SSH în loc de ping pe macOS if [[ "$OSTYPE" == "darwin"* ]]; then # macOS: verificare directă SSH cu timeout rapid if ssh -o ConnectTimeout=3 -o BatchMode=yes -o LogLevel=ERROR "$SSH_USER@$target" "echo 'OK'" >/dev/null 2>&1; then log_success "Host $target este UP și SSH funcționează" return 0 else log_warning "Host $target nu este accesibil prin SSH" return 1 fi else # Linux: folosim ping normal if timeout 5 ping -c 2 -W 3 "$target" >/dev/null 2>&1; then log_success "Host $target este UP" return 0 else log_warning "Host $target este DOWN sau nu răspunde la ping" return 1 fi fi } # Funcție pentru verificarea conectivității SSH check_ssh_connectivity() { local target="$1" # Verifică mai întâi dacă hostul este up if ! check_host_up "$target"; then log_warning "Skipping SSH test pentru $target - hostul nu este up" return 1 fi log_info "Verificare conectivitate SSH pentru $target..." if ssh -o ConnectTimeout=5 -o BatchMode=yes -o LogLevel=ERROR "$SSH_USER@$target" "echo 'SSH OK'" >/dev/null 2>&1; then log_success "SSH conectare OK pentru $target" return 0 else log_error "SSH conectare FAILED pentru $target - verifică cheia SSH" return 1 fi } # Funcție pentru copierea fișierelor pe ținta remotă copy_files() { local target="$1" log_info "Copierea fișierelor pe $target..." # Creare director temporar pe țintă ssh -o LogLevel=ERROR "$SSH_USER@$target" "mkdir -p $REMOTE_DIR" # Copierea tuturor fișierelor proiectului rsync -avz --delete --quiet \ --exclude='.git' \ --exclude='deploy.sh' \ --exclude='*.log' \ "$SCRIPT_DIR/" "$SSH_USER@$target:$REMOTE_DIR/" log_success "Fișiere copiate pe $target" } # Funcție generică pentru executarea unei comenzi pe ținta remotă run_on_target() { local target="$1" local action="$2" local success_msg="$3" local error_msg="$4" local cmd_arg="${5:-$action}" log_info "$action pe $target..." if ssh -o LogLevel=ERROR "$SSH_USER@$target" "bash $REMOTE_DIR/scripts/install.sh $cmd_arg"; then log_success "$success_msg" else log_error "$error_msg" return 1 fi } # Funcție pentru verificarea statusului (nu necesită rsync) check_status() { local target="$1" log_info "Verificarea statusului AutoNAS pe $target..." # Încearcă să folosească uninstaller pentru status sau install.sh dacă există ssh -o LogLevel=ERROR "$SSH_USER@$target" " if [ -f '$REMOTE_DIR/scripts/install.sh' ]; then bash $REMOTE_DIR/scripts/install.sh status elif [ -f '/usr/local/sbin/autonas' ]; then /usr/local/sbin/autonas --version 2>/dev/null || echo 'AutoNAS instalat dar versiune necunoscută' else echo 'AutoNAS nu este instalat' fi " } # Funcție pentru cleanup (ștergerea fișierelor temporare) cleanup() { local target="$1" log_info "Cleanup fișiere temporare pe $target..." ssh -o LogLevel=ERROR "$SSH_USER@$target" "rm -rf $REMOTE_DIR" || true log_success "Cleanup realizat pe $target" } # Funcție pentru cleanup complet (delegat către uninstaller) force_cleanup() { local target="$1" log_info "Cleanup forțat AutoNAS pe $target..." # Încearcă să folosească uninstaller-ul existent ssh -o LogLevel=ERROR "$SSH_USER@$target" " if [ -f '/usr/local/lib/xdev/autonas/uninstall.sh' ]; then bash /usr/local/lib/xdev/autonas/uninstall.sh --force elif [ -f '/usr/local/bin/autonas-uninstall.sh' ]; then bash /usr/local/bin/autonas-uninstall.sh --force elif [ -f '/usr/local/lib/autonas/autonas-uninstall.sh' ]; then bash /usr/local/lib/autonas/autonas-uninstall.sh --force else echo 'WARNING: Nu s-a găsit uninstaller-ul AutoNAS' fi " || true ssh -o LogLevel=ERROR "$SSH_USER@$target" "rm -rf $REMOTE_DIR" || true log_success "Cleanup forțat completat pe $target" } # Funcție pentru uninstall AutoNAS (delegat către uninstaller) uninstall_autonas() { local target="$1" log_info "Dezinstalarea AutoNAS pe $target..." if ssh -o LogLevel=ERROR "$SSH_USER@$target" " if [ -f '/usr/local/lib/xdev/autonas/uninstall.sh' ]; then bash /usr/local/lib/xdev/autonas/uninstall.sh echo 'AutoNAS dezinstalat cu succes!' elif [ -f '/usr/local/bin/autonas-uninstall.sh' ]; then bash /usr/local/bin/autonas-uninstall.sh rm -f '/usr/local/bin/autonas-uninstall.sh' echo 'AutoNAS dezinstalat cu succes!' elif [ -f '/usr/local/lib/autonas/autonas-uninstall.sh' ]; then bash /usr/local/lib/autonas/autonas-uninstall.sh echo 'AutoNAS dezinstalat cu succes!' else echo 'ERROR: Scriptul de dezinstalare nu a fost găsit!' exit 1 fi "; then log_success "AutoNAS dezinstalat cu succes de pe $target" else log_error "Dezinstalarea AutoNAS a eșuat pe $target" return 1 fi } # Funcții de delegare pentru operațiunile de servicii install_autonas() { run_on_target "$1" "Instalarea AutoNAS" "AutoNAS instalat cu succes pe $1" "Instalarea AutoNAS a eșuat pe $1" "install" } start_services() { run_on_target "$1" "Pornirea serviciilor AutoNAS" "Serviciile AutoNAS pornite cu succes pe $1" "Pornirea serviciilor AutoNAS a eșuat pe $1" "start" } restart_services() { run_on_target "$1" "Restartarea serviciilor AutoNAS" "Serviciile AutoNAS restartate cu succes pe $1" "Restartarea serviciilor AutoNAS a eșuat pe $1" "restart" } stop_services() { run_on_target "$1" "Oprirea serviciilor AutoNAS" "Serviciile AutoNAS oprite cu succes pe $1" "Oprirea serviciilor AutoNAS a eșuat pe $1" "stop" } check_dependencies() { run_on_target "$1" "Verificarea dependințelor" "Verificarea dependințelor completată pe $1" "Verificarea dependințelor a eșuat pe $1" "check-deps" } install_dependencies() { run_on_target "$1" "Instalarea dependințelor" "Dependințele instalate cu succes pe $1" "Instalarea dependințelor a eșuat pe $1" "install-deps" } # Funcție pentru afișarea ajutorului show_help() { echo "Utilizare: $0 [COMANDĂ] [ȚINTE]" echo "" echo "COMENZI:" echo " install - Instalare completă AutoNAS pe toate țintele" echo " install-deps - Instalare doar dependințe (nfs-kernel-server, autofs, etc.)" echo " check-deps - Verificare dependințe fără instalare" echo " uninstall - Dezinstalare completă AutoNAS de pe toate țintele" echo " start - Pornește serviciile AutoNAS" echo " restart - Restartează serviciile AutoNAS" echo " stop - Oprește serviciile AutoNAS" echo " status - Afișează statusul serviciilor" echo " cleanup - Șterge fișierele temporare" echo " force-cleanup - Cleanup agresiv (inclusiv fișiere orfane)" echo " help - Afișează acest ajutor" echo "" echo "ȚINTE (opțional):" echo " 192.168.2.91, 192.168.2.92, 192.168.2.93" echo " Dacă nu se specifică ținte, se rulează pe toate" echo "" echo "Exemple:" echo " $0 check-deps # Verifică dependințele pe toate țintele" echo " $0 install-deps # Instalează dependințele pe toate țintele" echo " $0 install # Instalează pe toate țintele" echo " $0 install 192.168.2.91 # Instalează doar pe .91" echo " $0 restart 192.168.2.91 192.168.2.92 # Restart pe .91 și .92" echo " $0 status # Verifică statusul pe toate țintele" echo " $0 force-cleanup # Cleanup agresiv pe toate nodurile" } # Funcție pentru executarea unei comenzi pe ținte specifice execute_command() { local command="$1" shift local targets_to_use=("$@") # Dacă nu sunt specificate ținte, folosește toate din cluster.json if [ ${#targets_to_use[@]} -eq 0 ]; then targets_to_use=( $(get_targets) ) fi log_info "Executare comandă '$command' pe noduri: ${targets_to_use[*]}" for target in "${targets_to_use[@]}"; do local node_name node_name=$(get_node_name "$target") echo "" echo "======================================" echo " $command pe $node_name ($target)" echo "======================================" if ! check_ssh_connectivity "$target"; then log_error "Nu se poate conecta la $target - skip" continue fi case "$command" in "install") copy_files "$target" install_autonas "$target" cleanup "$target" ;; "install-deps") copy_files "$target" install_dependencies "$target" cleanup "$target" ;; "check-deps") copy_files "$target" check_dependencies "$target" cleanup "$target" ;; "uninstall") uninstall_autonas "$target" cleanup "$target" ;; "start") start_services "$target" ;; "restart") restart_services "$target" ;; "stop") stop_services "$target" ;; "status") check_status "$target" ;; "cleanup") cleanup "$target" ;; "force-cleanup") force_cleanup "$target" ;; *) log_error "Comandă necunoscută: $command" return 1 ;; esac if [ $? -eq 0 ]; then log_success "Comandă '$command' executată cu succes pe $target" else log_error "Comandă '$command' a eșuat pe $target" fi done } # Main function main() { print_banner # Verifică dacă avem argumente if [ $# -eq 0 ]; then show_help exit 1 fi local command="$1" shift case "$command" in "install"|"install-deps"|"check-deps"|"uninstall"|"start"|"restart"|"stop"|"status"|"cleanup"|"force-cleanup") execute_command "$command" "$@" ;; "help"|"--help"|"-h") show_help ;; *) log_error "Comandă necunoscută: $command" echo "" show_help exit 1 ;; esac } # Verifică dacă rulează ca script principal if [ "${BASH_SOURCE[0]}" = "${0}" ]; then main "$@" fi