-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathmass-update.sh
executable file
·137 lines (116 loc) · 4.93 KB
/
mass-update.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/bash
# Define file directory and endings
WORK_DIR="tmp"
FILE_ENDINGS=".itb .bin .gz"
# Extract hosts from YAML files
mapfile -t COREROUTERS < <(yq '.hosts[] | select(.role == "corerouter" or .role == "gateway") | .hostname' locations/*.yml | tr -d '"')
mapfile -t APS < <(yq '.hosts[] | select(.role == "ap") | .hostname' locations/*.yml | tr -d '"')
# Find files matching the specified endings
FILES=()
for ENDING in $FILE_ENDINGS; do
while IFS= read -r FILE_PATH; do
FILES+=("$FILE_PATH")
done < <(find "$WORK_DIR/images" -type f -name "*$ENDING")
done
# Separate files for APs and corerouters
AP_FILES=()
COREROUTER_FILES=()
for FILE_PATH in "${FILES[@]}"; do
FILENAME=$(basename "$FILE_PATH")
NODENAME="${FILENAME%.*}"
# Check if the node belongs to APS or COREROUTERS
if [[ " ${APS[*]} " == *" $NODENAME "* ]]; then
AP_FILES+=("$FILE_PATH")
elif [[ " ${COREROUTERS[*]} " == *" $NODENAME "* ]]; then
COREROUTER_FILES+=("$FILE_PATH")
fi
done
# Combine APs first, then corerouters
SORTED_FILES=("${AP_FILES[@]}" "${COREROUTER_FILES[@]}")
# Print information and prompt for confirmation
echo ""
echo "This script will do the following:"
echo ""
echo "- flash all the following hosts with the corresponding firmware files currently present in $WORK_DIR/images"
echo "- first flash APs, then corerouters and gateways based on the role derived from host within the YAML files"
echo "- check the availability of the hosts before and after flashing"
echo "- ignore keychecking"
echo "- make sure that at least 'image size + 1 MB' of RAM is available before starting a firmware upgrade"
echo "- delete the local firmware file, build log, build and config files from disk after flashing"
echo ""
echo "The following firmware files will be flashed:"
for FILE_PATH in "${SORTED_FILES[@]}"; do
echo "- $(basename "$FILE_PATH")"
done
echo ""
read -rp "Do you want to proceed [y/N]? " choice
echo ""
if [[ ! "$choice" =~ ^[Yy]$ ]]; then
echo "Exiting..."
exit 0
fi
# Function to check reachability
check_reachability() {
local hostname="$1"
if ping -4 -c 1 "$hostname" >/dev/null 2>&1 || ping -6 -c 1 "$hostname" >/dev/null 2>&1; then
return 0
else
return 1
fi
}
# Loop through each file
for FILE_PATH in "${SORTED_FILES[@]}"; do
# Horizontal line to separate iterations
echo "----------------------------------------"
# Extract filename
FILENAME=$(basename "$FILE_PATH")
echo "Processing file: $FILENAME"
# Build nodename by omitting the ending
NODENAME="${FILENAME%.*}"
echo "Nodename: $NODENAME"
# Build hostname
HOSTNAME="$NODENAME.ff"
echo "Hostname: $HOSTNAME"
# Check if hostname is reachable
echo "Checking if $HOSTNAME is reachable..."
if check_reachability "$HOSTNAME"; then
echo "Hostname $HOSTNAME is reachable"
# Check memory on remote host
MEMORY=$(ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "root@$HOSTNAME" "free | awk 'NR==2 {print \$7}'")
if [ "$MEMORY" -ge $(( $(stat -c %s "$FILE_PATH") / 1024 + 1024 )) ]; then # File size in KB + 1 MB
echo "Memory on $HOSTNAME is sufficient ($MEMORY KB)"
# SCP the file
echo "Copying $FILENAME to $HOSTNAME:/tmp/"
if scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -O "$FILE_PATH" "root@$HOSTNAME:/tmp/"; then
# Debug output: Executing sysupgrade
echo "Executing sysupgrade on $HOSTNAME"
# shellcheck disable=SC2029
# Perform the sysupgrade; Ensure the connection terminates within 5 seconds using keep-alive
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ServerAliveInterval=1 -o ServerAliveCountMax=5 "root@$HOSTNAME" "sysupgrade '/tmp/$FILENAME'"
# Wait for hostname to become unreachable
echo "Waiting for $HOSTNAME to become unreachable..."
while check_reachability "$HOSTNAME"; do sleep 1; done
# Wait 20 seconds and then wait for hostname to become reachable again
echo "Waiting for $HOSTNAME to become reachable again..."
sleep 20
while ! check_reachability "$HOSTNAME"; do sleep 1; done
# Remove local files
echo "Removing local files for $NODENAME from $WORK_DIR"
rm "$FILE_PATH"
rm "$WORK_DIR/images/$NODENAME.log"
rm -rf "$WORK_DIR/build/$NODENAME"
rm -rf "$WORK_DIR/configs/$NODENAME"
else
echo "SCP command failed. Exiting..."
exit 1
fi
else
echo "Skipping file transfer due to insufficient memory on $HOSTNAME"
fi
else
echo "Hostname $HOSTNAME is not reachable"
fi
done
# Horizontal line to separate iterations
echo "----------------------------------------"
echo "Finished"