Private
Public Access
1
0

fix: clean up gitapply.sh and improve node status handling

This commit is contained in:
2025-12-23 20:53:12 -05:00
parent 1376b734f3
commit f9f951cd2c

View File

@@ -5,7 +5,6 @@
# ============================================================================ # ============================================================================
# 256-Color Gradient Palette (Blue to Teal) # 256-Color Gradient Palette (Blue to Teal)
# #0c00ff -> #0066ff -> #008dff -> #00a6ff -> #00bbe7 -> #00cd9a
C1='\e[38;5;21m' # Deep Blue C1='\e[38;5;21m' # Deep Blue
C2='\e[38;5;27m' # Blue C2='\e[38;5;27m' # Blue
C3='\e[38;5;33m' # Light Blue C3='\e[38;5;33m' # Light Blue
@@ -41,6 +40,8 @@ NODES=(
"10.0.254.110" "10.0.254.110"
) )
MAX_RETRIES=3
# Get current node IP # Get current node IP
CURRENT_IP=$(hostname -I | awk '{print $1}') CURRENT_IP=$(hostname -I | awk '{print $1}')
@@ -48,7 +49,7 @@ CURRENT_IP=$(hostname -I | awk '{print $1}')
STATUS_DIR="/tmp/virtnet_deploy_$$" STATUS_DIR="/tmp/virtnet_deploy_$$"
mkdir -p "$STATUS_DIR" mkdir -p "$STATUS_DIR"
# SSH Key (stored securely) # SSH Key
SSH_KEY="/root/.ssh/virtnet_deploy" SSH_KEY="/root/.ssh/virtnet_deploy"
# ============================================================================ # ============================================================================
@@ -66,9 +67,9 @@ print_header() {
echo -e " ${C1} ╚═══╝ ${C2}╚═╝${C3}╚═╝ ╚═╝${C3} ╚═╝ ${C4}╚═╝ ╚═══╝${C5}╚══════╝${C6} ╚═╝ ${NC}" echo -e " ${C1} ╚═══╝ ${C2}╚═╝${C3}╚═╝ ╚═╝${C3} ╚═╝ ${C4}╚═╝ ╚═══╝${C5}╚══════╝${C6} ╚═╝ ${NC}"
echo -e " ${C6}${BOLD}.bond${NC}" echo -e " ${C6}${BOLD}.bond${NC}"
echo "" echo ""
echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e " ${WHITE}${BOLD} Paymenter Load Balancer - Git Update & Apply${NC}" echo -e " ${WHITE}${BOLD} Paymenter Load Balancer - Git Update & Apply${NC}"
echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo "" echo ""
} }
@@ -77,7 +78,7 @@ spinner() {
local msg=$2 local msg=$2
local i=0 local i=0
while kill -0 "$pid" 2>/dev/null; do while kill -0 "$pid" 2>/dev/null; do
printf "\r ${C3}${SPIN[$i]}${NC} ${msg}" printf "\r ${C3}${SPIN[$i]}${NC} %s" "$msg"
i=$(( (i + 1) % 8 )) i=$(( (i + 1) % 8 ))
sleep 0.1 sleep 0.1
done done
@@ -89,31 +90,27 @@ task_start() {
echo -e "\n${C4}┌─${NC} ${C5}${BOLD}$1${NC}" echo -e "\n${C4}┌─${NC} ${C5}${BOLD}$1${NC}"
} }
task_item() {
printf " ${C3}○${NC} $1"
}
task_done() { task_done() {
printf "\r ${C6}●${NC} $1 ${GREEN}✓${NC}\n" printf "\r ${C6}●${NC} %s ${GREEN}✓${NC}\n" "$1"
} }
task_fail() { task_fail() {
printf "\r ${RED}●${NC} $1 ${RED}✗${NC}\n" printf "\r ${RED}●${NC} %s ${RED}✗${NC}\n" "$1"
} }
countdown() { countdown() {
local secs=$1 local secs=$1
for ((i=secs; i>0; i--)); do for ((i=secs; i>0; i--)); do
printf "\r ${C3}◐${NC} Waiting ${C5}${BOLD}$i${NC}s " printf "\r ${C3}◐${NC} Waiting ${C5}${BOLD}%d${NC}s " "$i"
sleep 0.25 sleep 0.25
printf "\r ${C3}◓${NC} Waiting ${C5}${BOLD}$i${NC}s " printf "\r ${C3}◓${NC} Waiting ${C5}${BOLD}%d${NC}s " "$i"
sleep 0.25 sleep 0.25
printf "\r ${C3}◑${NC} Waiting ${C5}${BOLD}$i${NC}s " printf "\r ${C3}◑${NC} Waiting ${C5}${BOLD}%d${NC}s " "$i"
sleep 0.25 sleep 0.25
printf "\r ${C3}◒${NC} Waiting ${C5}${BOLD}$i${NC}s " printf "\r ${C3}◒${NC} Waiting ${C5}${BOLD}%d${NC}s " "$i"
sleep 0.25 sleep 0.25
done done
printf "\r ${C6}●${NC} Ready! ${GREEN}✓${NC}\n" printf "\r ${C6}●${NC} Ready! ${GREEN}✓${NC}\n"
} }
# Run update on remote node # Run update on remote node
@@ -122,116 +119,107 @@ run_remote_update() {
local status_file="$STATUS_DIR/$node" local status_file="$STATUS_DIR/$node"
echo "pending" > "$status_file" echo "pending" > "$status_file"
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -i "$SSH_KEY" root@"$node" \ ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o BatchMode=yes -i "$SSH_KEY" root@"$node" \
'cd /var/www/paymenter && git pull && php artisan view:clear && php artisan cache:clear && systemctl restart php8.3-fpm' \ 'cd /var/www/paymenter && git pull && php artisan view:clear && php artisan cache:clear && systemctl restart php8.3-fpm' \
> "$STATUS_DIR/${node}.log" 2>&1 > "$STATUS_DIR/${node}.log" 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "done" > "$status_file" echo "done" > "$status_file"
return 0
else else
echo "failed" > "$status_file" echo "failed" > "$status_file"
return 1
fi fi
} }
# Display node status panel # Get list of remote nodes (excluding current)
print_node_status() { get_remote_nodes() {
local cols=3 local remotes=()
local count=0
echo -e "\n${C4}┌─${NC} ${C5}${BOLD}Cluster Node Status${NC}"
echo -e " ${GRAY}┌─────────────────┬─────────────────┬─────────────────┐${NC}"
local row=""
for node in "${NODES[@]}"; do for node in "${NODES[@]}"; do
if [[ "$node" == "$CURRENT_IP" ]]; then if [[ "$node" != "$CURRENT_IP" ]]; then
continue remotes+=("$node")
fi
local status_file="$STATUS_DIR/$node"
local status="waiting"
[[ -f "$status_file" ]] && status=$(cat "$status_file")
local icon=""
local color=""
case "$status" in
"pending") icon="◐"; color="$C3" ;;
"done") icon="●"; color="$GREEN" ;;
"failed") icon="●"; color="$RED" ;;
*) icon="○"; color="$GRAY" ;;
esac
local short_ip="${node##*.}"
row+=" ${color}${icon}${NC} .${short_ip}"
count=$((count + 1))
if [ $((count % cols)) -eq 0 ]; then
printf " │%-17s│%-17s│%-17s│\n" $row
row=""
fi fi
done done
echo "${remotes[@]}"
# Print remaining nodes
if [ -n "$row" ]; then
while [ $((count % cols)) -ne 0 ]; do
row+=" "
count=$((count + 1))
done
printf " │%-17s│%-17s│%-17s│\n" $row
fi
echo -e " ${GRAY}└─────────────────┴─────────────────┴─────────────────┘${NC}"
} }
# Animated node status display # Print node grid
update_node_display() { print_node_grid() {
local all_done=false local title=$1
while ! $all_done; do shift
all_done=true local show_status=$1
shift
local nodes=("$@")
# Move cursor up and redraw echo -e "\n${C4}┌─${NC} ${C5}${BOLD}${title}${NC}"
tput sc # Save cursor position echo -e " ${GRAY}┌──────────┬──────────┬──────────┬──────────┬──────────┐${NC}"
echo -e "\r ${GRAY}┌─────────────────────────────────────────────────────┐${NC}" local col=0
local row_started=0
for node in "${NODES[@]}"; do for node in "${nodes[@]}"; do
if [[ "$node" == "$CURRENT_IP" ]]; then if [ $row_started -eq 0 ]; then
continue printf " ${GRAY}│${NC}"
fi row_started=1
fi
local short="${node##*.}"
local icon="○"
local color="$GRAY"
if [ "$show_status" = "true" ]; then
local status_file="$STATUS_DIR/$node" local status_file="$STATUS_DIR/$node"
local status="waiting" local status="waiting"
[[ -f "$status_file" ]] && status=$(cat "$status_file") [[ -f "$status_file" ]] && status=$(cat "$status_file")
local icon="" color=""
case "$status" in case "$status" in
"pending") icon="⣾"; color="$C3"; all_done=false ;;
"done") icon="●"; color="$GREEN" ;; "done") icon="●"; color="$GREEN" ;;
"failed") icon="●"; color="$RED" ;; "failed") icon="●"; color="$RED" ;;
*) icon="○"; color="$GRAY"; all_done=false ;; "pending") icon="◐"; color="$C3" ;;
*) icon="○"; color="$GRAY" ;;
esac esac
fi
printf " ${GRAY}│${NC} ${color}${icon}${NC} %-15s" "$node" printf " ${color}${icon}${NC} .%-6s${GRAY}│${NC}" "$short"
done col=$((col + 1))
echo -e "\r ${GRAY}└─────────────────────────────────────────────────────┘${NC}" if [ $((col % 5)) -eq 0 ]; then
echo ""
sleep 0.3 row_started=0
if ! $all_done; then
tput rc # Restore cursor position
fi fi
done done
# Fill remaining cells if row not complete
while [ $((col % 5)) -ne 0 ]; do
printf " ${GRAY}│${NC}"
col=$((col + 1))
done
if [ $row_started -eq 1 ]; then
echo ""
fi
echo -e " ${GRAY}└──────────┴──────────┴──────────┴──────────┴──────────┘${NC}"
} }
print_complete() { # Get failed nodes
echo "" get_failed_nodes() {
echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" local failed=()
echo "" for node in "${NODES[@]}"; do
echo -e " ${C6}${BOLD}🚀 UPDATE COMPLETE${NC}" if [[ "$node" != "$CURRENT_IP" ]]; then
echo "" local status_file="$STATUS_DIR/$node"
if [[ -f "$status_file" ]] && [[ "$(cat "$status_file")" == "failed" ]]; then
failed+=("$node")
fi
fi
done
echo "${failed[@]}"
}
# Count results
count_results() {
local success=0
local failed=0
# Count successes and failures
local success=0 failed=0
for node in "${NODES[@]}"; do for node in "${NODES[@]}"; do
if [[ "$node" == "$CURRENT_IP" ]]; then if [[ "$node" == "$CURRENT_IP" ]]; then
success=$((success + 1)) success=$((success + 1))
@@ -245,10 +233,24 @@ print_complete() {
fi fi
done done
echo -e " ${GRAY}Local node updated successfully.${NC}" echo "$success $failed"
echo -e " ${GREEN}●${NC} ${success} nodes updated ${RED}●${NC} ${failed} nodes failed" }
print_complete() {
local results
results=$(count_results)
local success=$(echo $results | cut -d' ' -f1)
local failed=$(echo $results | cut -d' ' -f2)
echo "" echo ""
echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e " ${C6}${BOLD}🚀 UPDATE COMPLETE${NC}"
echo ""
echo -e " ${GRAY}Local node updated successfully.${NC}"
echo -e " ${GREEN}●${NC} ${success} nodes updated ${RED}●${NC} ${failed} nodes failed"
echo ""
echo -e " ${C4}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo "" echo ""
} }
@@ -266,6 +268,9 @@ print_header
echo -e " ${C3}→${NC} ${GRAY}Current Node:${NC} ${C5}${CURRENT_IP}${NC}" echo -e " ${C3}→${NC} ${GRAY}Current Node:${NC} ${C5}${CURRENT_IP}${NC}"
echo -e " ${C3}→${NC} ${GRAY}Target Nodes:${NC} ${C5}${#NODES[@]} nodes in cluster${NC}" echo -e " ${C3}→${NC} ${GRAY}Target Nodes:${NC} ${C5}${#NODES[@]} nodes in cluster${NC}"
# Get remote nodes
REMOTE_NODES=($(get_remote_nodes))
# Random delay # Random delay
sleep_time=$((RANDOM % 5 + 1)) sleep_time=$((RANDOM % 5 + 1))
cd /var/www/paymenter cd /var/www/paymenter
@@ -276,37 +281,18 @@ countdown "$sleep_time"
# Start remote updates in background # Start remote updates in background
task_start "Deploying to Remote Nodes" task_start "Deploying to Remote Nodes"
for node in "${NODES[@]}"; do echo -e " ${GRAY}Starting deployment on ${#REMOTE_NODES[@]} remote nodes...${NC}"
if [[ "$node" != "$CURRENT_IP" ]]; then
run_remote_update "$node" & for node in "${REMOTE_NODES[@]}"; do
fi run_remote_update "$node" &
done done
# Show initial node status # Show initial node grid
echo -e " ${GRAY}Background deployment started on remote nodes...${NC}" print_node_grid "Initial Cluster Status" "false" "${REMOTE_NODES[@]}"
echo ""
# Display node grid
echo -e " ${GRAY}┌───────────────┬───────────────┬───────────────┬───────────────┐${NC}"
printf " ${GRAY}│${NC}"
col=0
for node in "${NODES[@]}"; do
if [[ "$node" == "$CURRENT_IP" ]]; then
continue
fi
short="${node##*.}"
printf " ${GRAY}○${NC} .%-11s${GRAY}│${NC}" "$short"
col=$((col + 1))
if [ $((col % 4)) -eq 0 ]; then
echo ""
printf " ${GRAY}│${NC}"
fi
done
echo -e "\n ${GRAY}└───────────────┴───────────────┴───────────────┴───────────────┘${NC}"
# Local Git Pull # Local Git Pull
task_start "Local: Pulling Latest Changes" task_start "Local: Pulling Latest Changes"
task_item "Fetching from remote..." printf " ${C3}○${NC} Fetching from remote..."
git pull > /tmp/git_output.txt 2>&1 & git pull > /tmp/git_output.txt 2>&1 &
spinner $! "Fetching from remote..." spinner $! "Fetching from remote..."
GIT_STATUS=$? GIT_STATUS=$?
@@ -322,69 +308,66 @@ if [ $GIT_STATUS -ne 0 ]; then
fi fi
task_done "Git pull completed" task_done "Git pull completed"
head -3 /tmp/git_output.txt | while IFS= read -r line; do head -3 /tmp/git_output.txt 2>/dev/null | while IFS= read -r line; do
echo -e " ${DIM}$line${NC}" echo -e " ${DIM}${line}${NC}"
done done
# Clear Caches # Clear Caches
task_start "Local: Clearing Caches" task_start "Local: Clearing Caches"
task_item "View cache..." printf " ${C3}○${NC} View cache..."
php artisan view:clear > /dev/null 2>&1 & php artisan view:clear > /dev/null 2>&1 &
spinner $! "View cache..." spinner $! "View cache..."
task_done "View cache cleared" task_done "View cache cleared"
task_item "Application cache..." printf " ${C3}○${NC} Application cache..."
php artisan cache:clear > /dev/null 2>&1 & php artisan cache:clear > /dev/null 2>&1 &
spinner $! "Application cache..." spinner $! "Application cache..."
task_done "Application cache cleared" task_done "Application cache cleared"
# Restart PHP-FPM # Restart PHP-FPM
task_start "Local: Restarting Services" task_start "Local: Restarting Services"
task_item "PHP 8.3 FPM..." printf " ${C3}○${NC} PHP 8.3 FPM..."
systemctl restart php8.3-fpm & systemctl restart php8.3-fpm &
spinner $! "PHP 8.3 FPM..." spinner $! "PHP 8.3 FPM..."
task_done "PHP 8.3 FPM restarted" task_done "PHP 8.3 FPM restarted"
# Wait for all remote nodes # Wait for initial remote deployment
task_start "Waiting for Remote Nodes" task_start "Waiting for Remote Nodes"
task_item "Syncing cluster..." printf " ${C3}○${NC} Syncing cluster..."
wait wait
task_done "All nodes synchronized" task_done "Initial sync complete"
# Final node status # Show status after first attempt
echo "" print_node_grid "Cluster Status (Attempt 1/${MAX_RETRIES})" "true" "${REMOTE_NODES[@]}"
echo -e " ${C4}┌─${NC} ${C5}${BOLD}Final Cluster Status${NC}"
echo -e " ${GRAY}┌───────────────┬───────────────┬───────────────┬───────────────┐${NC}"
printf " ${GRAY}│${NC}"
col=0
for node in "${NODES[@]}"; do
if [[ "$node" == "$CURRENT_IP" ]]; then
continue
fi
status_file="$STATUS_DIR/$node"
status="failed"
[[ -f "$status_file" ]] && status=$(cat "$status_file")
icon="" # Retry failed nodes
color="" attempt=1
if [[ "$status" == "done" ]]; then while [ $attempt -lt $MAX_RETRIES ]; do
icon="●"; color="$GREEN" FAILED_NODES=($(get_failed_nodes))
else
icon="●"; color="$RED" if [ ${#FAILED_NODES[@]} -eq 0 ]; then
break
fi fi
short="${node##*.}" attempt=$((attempt + 1))
printf " ${color}${icon}${NC} .%-11s${GRAY}│${NC}" "$short"
col=$((col + 1)) task_start "Retrying Failed Nodes (Attempt ${attempt}/${MAX_RETRIES})"
if [ $((col % 4)) -eq 0 ]; then echo -e " ${YELLOW}↻${NC} ${YELLOW}${#FAILED_NODES[@]} node(s) failed, retrying...${NC}"
echo ""
if [ $col -lt 10 ]; then for node in "${FAILED_NODES[@]}"; do
printf " ${GRAY}│${NC}" run_remote_update "$node" &
fi done
fi
printf " ${C3}○${NC} Waiting for retry..."
wait
task_done "Retry attempt ${attempt} complete"
print_node_grid "Cluster Status (Attempt ${attempt}/${MAX_RETRIES})" "true" "${REMOTE_NODES[@]}"
done done
echo -e "\n ${GRAY}└───────────────┴───────────────┴───────────────┴───────────────┘${NC}"
# Final status
print_node_grid "Final Cluster Status" "true" "${REMOTE_NODES[@]}"
# Complete # Complete
print_complete print_complete