416 lines
10 KiB
Bash
Executable File
416 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Initialiser les tableaux
|
||
ignored_machines=()
|
||
ok_machines=()
|
||
error_machines=()
|
||
|
||
# Variables pour les codes de couleur ANSI
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Mise à jour des machines présentes dans .ssh/config avec choix d'ignorer certaines.
|
||
|
||
# fonction run_ssh et run_scp avec timeout + options
|
||
SSH_OPTS="-o ConnectTimeout=5 -o BatchMode=yes -o StrictHostKeyChecking=accept-new"
|
||
SSH_TIMEOUT="5"
|
||
|
||
run_ssh() {
|
||
local machine="$1"
|
||
local start_time=$(date +%s)
|
||
shift
|
||
|
||
if [ $# -eq 0 ]; then
|
||
ssh "$machine" 'bash -s' < /dev/stdin
|
||
else
|
||
ssh "$machine" "$@"
|
||
fi
|
||
|
||
local end_time=$(date +%s)
|
||
local duration=$(( end_time - start_time ))
|
||
echo -e " ⏱️ Durée : ${duration}s"
|
||
}
|
||
|
||
|
||
extract_stats_block() {
|
||
local label="$1"
|
||
grep -A2 "^>>> $label" "$logfile" | grep -E '^[0-9]+ mis à jour' | tail -n1
|
||
}
|
||
|
||
|
||
parse_summary_line() {
|
||
awk '
|
||
{
|
||
updated += $1
|
||
installed += $4
|
||
removed += $7
|
||
last_notup = $11
|
||
}
|
||
END {
|
||
print updated, installed, removed, (last_notup ? last_notup : 0)
|
||
}'
|
||
}
|
||
|
||
|
||
|
||
run_scp() {
|
||
local src="$1"
|
||
local dest="$2"
|
||
local machine="$3"
|
||
timeout "$SSH_TIMEOUT" scp $SSH_OPTS "$src" "$machine:$dest"
|
||
}
|
||
|
||
|
||
update_with_apt() {
|
||
local machine="$1"
|
||
local uniqkey="$2"
|
||
|
||
local start_time=$(date +%s)
|
||
|
||
echo -e " - Mise à jour avec apt-get sur $machine \n"
|
||
|
||
stats_tmp=$(mktemp)
|
||
|
||
run_ssh "$machine" <<'EOF' | tee "$stats_tmp"
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
|
||
echo ">>> clean"
|
||
sudo apt-get -y clean
|
||
|
||
echo ">>> update"
|
||
sudo apt-get update
|
||
|
||
echo ">>> check-upgrade"
|
||
UPGRADABLE=$(apt-get -s upgrade | grep "^Inst" | wc -l)
|
||
|
||
if [ "${UPGRADABLE:-0}" -gt 0 ] 2>/dev/null; then
|
||
echo ">>> upgrade"
|
||
sudo apt-get -y upgrade
|
||
|
||
echo ">>> full-upgrade"
|
||
sudo apt-get -y full-upgrade
|
||
|
||
echo ">>> autoremove"
|
||
sudo apt-get -y autoremove
|
||
else
|
||
echo ">>> Aucun paquet à mettre à jour"
|
||
fi
|
||
|
||
|
||
if [ -f /var/run/reboot-required ]; then
|
||
echo ">>> REDÉMARRAGE NÉCESSAIRE"
|
||
fi
|
||
EOF
|
||
|
||
|
||
local end_time=$(date +%s)
|
||
local duration=$(( end_time - start_time ))
|
||
|
||
log_capture=$(cat "$stats_tmp")
|
||
|
||
local ssh_status=$?
|
||
|
||
if [ "$ssh_status" -ne 0 ]; then
|
||
echo -e "❌ Échec SSH ou erreur distante sur $machine (code $ssh_status)"
|
||
else
|
||
echo -e "✅ $machine : Terminé avec succès"
|
||
fi
|
||
|
||
echo
|
||
|
||
# Récupération stats à partir des logs visibles en live
|
||
# On extrait les chiffres comme dans le message de apt
|
||
# Initialisation des compteurs
|
||
updated=0
|
||
installed=0
|
||
removed=0
|
||
unchanged=0
|
||
|
||
# Extraire les lignes après chaque bloc
|
||
line_upgrade=$(echo "$log_capture" | grep -A2 '^>>> upgrade' | grep -E '^[0-9]+ mis à jour' | tail -n1)
|
||
line_fullup=$(echo "$log_capture" | grep -A2 '^>>> full-upgrade' | grep -E '^[0-9]+ mis à jour' | tail -n1)
|
||
line_autorm=$(echo "$log_capture" | grep -A2 '^>>> autoremove' | grep -E '^[0-9]+ mis à jour' | tail -n1)
|
||
|
||
# Ajouter les lignes ensemble
|
||
line_all="$line_upgrade"$'\n'"$line_fullup"$'\n'"$line_autorm"
|
||
|
||
read updated installed removed unchanged <<< $(echo "$line_all" | parse_summary_line)
|
||
|
||
# Date/heure actuelle
|
||
now=$(date '+%Y-%m-%d %H:%M:%S')
|
||
|
||
# Fichier de stats
|
||
stats_file="$HOME/.config/updateall-stats"
|
||
mkdir -p "$(dirname "$stats_file")"
|
||
|
||
# Ajouter l’en-tête si le fichier est vide
|
||
if [ ! -s "$stats_file" ]; then
|
||
echo "machine,date,duree,updated,installed,removed,unchanged,uniqkey" > "$stats_file"
|
||
fi
|
||
|
||
# Ajout ligne CSV
|
||
echo "$machine,$now,$duration,$updated,$installed,$removed,$unchanged,$uniqkey" >> "$stats_file"
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# Fonction pour mettre à jour avec dnf
|
||
update_with_dnf() {
|
||
echo -e " - Mise à jour avec dnf sur $1 \n"
|
||
run_ssh "$1" 'sudo dnf check-update && sudo dnf upgrade -y'
|
||
echo -e "\n"
|
||
}
|
||
|
||
|
||
# Déclaration d'une fonction pour récupérer les alias à partir du fichier ~/.ssh/config
|
||
get_ssh_aliases() {
|
||
# Parcours du fichier ~/.ssh/config et récupération du premier Host (excluant "*")
|
||
awk 'tolower($1) == "host" && $2 != "*" && !seen[$2]++ {print $2}' ~/.ssh/config
|
||
|
||
# Parcours des fichiers dans le dossier ~/.ssh/include et récupération du premier Host (excluant "*")
|
||
for include_file in ~/.ssh/include/*; do
|
||
awk 'tolower($1) == "host" && $2 != "*" && !seen[$2]++ {print $2}' "$include_file"
|
||
done
|
||
}
|
||
|
||
|
||
check_keyinstall() {
|
||
local machine="$1"
|
||
local uniqkey="$2"
|
||
local uniqkey_file="/etc/cedrix_updateall"
|
||
|
||
echo -n " - Vérification d'une mise à jour déjà effectuée sur "$machine" : "
|
||
|
||
if ! timeout 5 ssh "$machine" '[ -f "$uniqkey_file" ]'; then
|
||
echo -e "${GREEN}mise à jour à faire.${NC}"
|
||
return 0
|
||
fi
|
||
|
||
if timeout 5 ssh "$machine" "grep -q '$uniqkey' $uniqkey_file"; then
|
||
echo -e "${RED}mise à jour déjà faite.${NC}"
|
||
return 1
|
||
fi
|
||
|
||
timeout 5 ssh "$machine" "sudo rm "$uniqkey_file""
|
||
echo -e "${GREEN}mise à jour à faire et clé à modifier.${NC}"
|
||
return 0
|
||
}
|
||
|
||
|
||
create_installkey() {
|
||
local machine="$1"
|
||
local uniqkey="$2"
|
||
local uniqkey_file="/etc/cedrix_updateall"
|
||
|
||
echo -n " - Indiquer à $machine que le script est passé ... "
|
||
# Si la clé unique n'est pas présente, la déposer dans le fichier
|
||
echo "$uniqkey" | timeout 5 ssh "$machine" "sudo su -c \"cat > $uniqkey_file\""
|
||
result="$?"
|
||
|
||
if [ $result -eq 0 ]; then
|
||
echo -e "${GREEN}OK${NC}"
|
||
else
|
||
echo -e "${RED}une erreur est survenue. Désactivation des prochaines mise à jour.${NC}"
|
||
|
||
fi
|
||
|
||
return
|
||
|
||
}
|
||
|
||
# Fonction pour récupérer la valeur de /etc/os-release
|
||
get_os_release() {
|
||
ssh "$1" 'grep "^PRETTY_NAME=" /etc/os-release' | cut -d'=' -f2 | tr -d \"
|
||
}
|
||
|
||
|
||
update_machine () {
|
||
local machine="$1"
|
||
|
||
# recupérer le nom de l'OS
|
||
os_name=$(get_os_release "$machine")
|
||
echo -e " - Système d'exploitation : ${GREEN}$os_name${NC}"
|
||
|
||
echo -n " - Détection du gestionnaire de mise à jour ... "
|
||
|
||
if timeout 5 ssh "$machine" which apt > /dev/null 2>&1; then
|
||
echo -e "${GREEN}apt${NC}"
|
||
update_with_apt "$machine" "$uniqkey"
|
||
elif timeout 5 ssh "$machine" which dnf > /dev/null 2>&1; then
|
||
echo -e "${GREEN}dnf${NC}"
|
||
update_with_dnf "$machine"
|
||
else
|
||
echo " ${RED} non détecté${NC}"
|
||
fi
|
||
}
|
||
|
||
|
||
|
||
confirm_update() {
|
||
local machine="$1"
|
||
read -p " - Executer la mise à jour pour $machine ? (o/n) " choice
|
||
if [ "$choice" = "o" ]; then
|
||
echo "$machine 1" >> ~/.config/updateall-hosts
|
||
else
|
||
echo "$machine 0" >> ~/.config/updateall-hosts
|
||
continue
|
||
fi
|
||
}
|
||
|
||
|
||
check_host() {
|
||
local machine="$1"
|
||
|
||
echo -n " - Check host "
|
||
# Vérifier la résolution du nom d'hôte
|
||
if ssh "$machine" hostname > /dev/null 2>&1; then
|
||
echo -e "... ${GREEN}OK${NC}"
|
||
return 1
|
||
else
|
||
echo -e "... ${RED}KO${NC}"
|
||
return 0
|
||
fi
|
||
|
||
}
|
||
|
||
|
||
run_custom_script() {
|
||
local machine="$1"
|
||
local custom_script="$HOME/.config/updateall.d/$machine"
|
||
|
||
if [ -f "$custom_script" ]; then
|
||
echo -e " - Exécution du script spécifique pour ${GREEN}$machine${NC}"
|
||
# Copier le script sur la machine et l'exécuter
|
||
run_scp "$custom_script" "/tmp/updateall_custom.sh" "$machine"
|
||
if [ $? -eq 0 ]; then
|
||
echo " - Script copié, exécution en cours..."
|
||
run_ssh "$machine" '
|
||
chmod +x /tmp/updateall_custom.sh
|
||
sudo /tmp/updateall_custom.sh
|
||
status=$?
|
||
sudo rm -f /tmp/updateall_custom.sh
|
||
exit $status
|
||
'
|
||
else
|
||
echo -e "${RED} - Échec du transfert du script personnalisé${NC}"
|
||
fi
|
||
|
||
else
|
||
echo " - Aucun script spécifique pour $machine."
|
||
fi
|
||
}
|
||
|
||
|
||
|
||
# Générer une clé unique
|
||
uniqkey=$(uuidgen)
|
||
echo "Clé d'installation : $uniqkey"
|
||
|
||
# Récupérer les alias SSH
|
||
machines=($(get_ssh_aliases))
|
||
|
||
|
||
echo -e "\n--- Démarrage du traitement ---\n"
|
||
|
||
# Parcourir la liste des machines
|
||
|
||
total=${#machines[@]}
|
||
current=0
|
||
|
||
for machine in "${machines[@]}"; do
|
||
|
||
# Vérification si le nom de machine est présent dans le fichier .config/updateall-hosts
|
||
|
||
echo -e "\n"
|
||
((current++))
|
||
echo -ne ">> $machine ($current/$total)\n"
|
||
|
||
while read host status; do
|
||
# ignorer commentaires et lignes vides
|
||
[[ -z "$host" || "$host" =~ ^# ]] && continue
|
||
|
||
if [ "$machine" = "$host" ]; then
|
||
if [ "$status" = "1" ]; then
|
||
echo -e "${GREEN}connue${NC}"
|
||
|
||
check_host "$machine"
|
||
machine_online="$?"
|
||
|
||
if [ "$machine_online" -eq 1 ]; then
|
||
check_keyinstall "$machine" "$uniqkey"
|
||
keyinstall_present="$?"
|
||
|
||
if [ "$keyinstall_present" -eq 0 ]; then
|
||
update_machine "$machine"
|
||
create_installkey "$machine" "$uniqkey"
|
||
ok_machines+=("$machine")
|
||
fi
|
||
else
|
||
error_machines+=("$machine")
|
||
fi
|
||
else
|
||
echo -e "${RED}ignorée${NC}"
|
||
ignored_machines+=("$machine")
|
||
fi
|
||
matched=1
|
||
break
|
||
fi
|
||
done < ~/.config/updateall-hosts
|
||
|
||
if [ "$matched" != "1" ]; then
|
||
check_host "$machine"
|
||
machine_online="$?"
|
||
|
||
if [ "$machine_online" -eq 1 ]; then
|
||
echo -e "${RED}vue pour la 1re fois${NC}"
|
||
confirm_update "$machine"
|
||
update_machine "$machine"
|
||
run_custom_script "$machine"
|
||
create_installkey "$machine" "$uniqkey"
|
||
ok_machines+=("$machine")
|
||
else
|
||
echo -e "${RED}non accessible${NC}"
|
||
error_machines+=("$machine")
|
||
fi
|
||
fi
|
||
|
||
|
||
done
|
||
|
||
echo -e "\n--- Résumé des machines ---\n"
|
||
|
||
# Afficher les machines ignorées
|
||
echo -e "${RED}Machines ignorées :${NC}"
|
||
for machine in "${ignored_machines[@]}"; do
|
||
echo " - $machine"
|
||
done
|
||
|
||
echo ""
|
||
|
||
# Afficher les machines en erreur
|
||
echo -e "${RED}Machines en erreur :${NC}"
|
||
for machine in "${error_machines[@]}"; do
|
||
echo " - $machine"
|
||
done
|
||
|
||
echo ""
|
||
|
||
# Afficher les machines ok
|
||
echo -e "${GREEN}Machines mises à jour avec succès :${NC}"
|
||
for machine in "${ok_machines[@]}"; do
|
||
echo " - $machine"
|
||
done
|
||
|
||
echo ""
|
||
|
||
|