Fix root cause of ControlSocket already exists errors

**Motivations:**
- SSH errors 'ControlSocket already exists, disabling multiplexing' were occurring
- Socket could become invalid between check and execution
- ControlMaster=auto detects invalid socket but doesn't remove it, just disables multiplexing
- Dead socket remains and causes issues for subsequent commands

**Root causes:**
- ControlMaster socket can exist but connection can be dead
- Socket can become invalid between check_ssh_connection() and ssh_exec() execution
- ControlMaster=auto detects invalid socket but doesn't remove it, leaving dead socket
- Dead socket causes 'ControlSocket already exists' errors on subsequent commands
- Previous cleanup was not aggressive enough to remove dead sockets

**Correctifs:**
- Improved check_ssh_connection() to test actual connection with 'true' command instead of just 'ssh -O check'
- Enhanced cleanup_dead_ssh() to remove entire directory instead of just socket file
- This ensures socket is truly removed even if process is still holding it
- Removed complex multi-step cleanup, using simple directory removal and recreation
- Socket validation now tests actual connection usability, not just socket existence

**Evolutions:**
- More robust socket cleanup that guarantees removal of dead sockets
- Better detection of invalid sockets before command execution

**Pages affectées:**
- deploy.sh: Improved cleanup_dead_ssh() and check_ssh_connection() functions
This commit is contained in:
Nicolas Cantu 2026-01-06 14:36:41 +01:00
parent f6cd63a34d
commit 01110cd322

View File

@ -22,20 +22,29 @@ cleanup_dead_ssh() {
# Attendre un peu pour que la fermeture se termine
sleep 0.5
fi
# Forcer la suppression du socket même s'il existe encore
rm -f "${SSH_CONTROL_PATH}" 2>/dev/null || true
# Nettoyer aussi le répertoire parent s'il est vide
rmdir "${SSH_CONTROL_DIR}" 2>/dev/null || true
# Forcer la suppression du socket et du répertoire parent
# Supprimer le répertoire entier garantit que le socket est vraiment supprimé
rm -rf "${SSH_CONTROL_DIR}" 2>/dev/null || true
# Recréer le répertoire pour les prochaines connexions
mkdir -p "${SSH_CONTROL_DIR}" 2>/dev/null || true
}
# Fonction pour vérifier si la connexion SSH maître est valide
check_ssh_connection() {
ssh -O check -o ControlPath="${SSH_CONTROL_PATH}" ${SERVER} 2>/dev/null || return 1
# Vérifier si le socket existe
if [ ! -S "${SSH_CONTROL_PATH}" ]; then
return 1
fi
# Tester la connexion en essayant de l'utiliser avec une commande simple
# Cela détecte si le socket existe mais la connexion est morte
ssh -o ControlPath="${SSH_CONTROL_PATH}" ${SERVER} "true" 2>/dev/null || return 1
return 0
}
# Fonction pour exécuter une commande SSH avec connexion persistante
ssh_exec() {
# Nettoyer le socket s'il existe mais est invalide
# Toujours vérifier et nettoyer le socket avant chaque commande
# pour éviter les sockets morts qui causent "ControlSocket already exists, disabling multiplexing"
if [ -S "${SSH_CONTROL_PATH}" ]; then
if ! check_ssh_connection; then
# Connexion morte, nettoyer avant d'exécuter
@ -44,6 +53,8 @@ ssh_exec() {
fi
# Exécuter la commande SSH (une seule tentative, pas de retry)
# ControlMaster=auto va créer une nouvelle connexion si le socket n'existe pas,
# ou réutiliser s'il est valide
ssh -o ControlMaster=auto \
-o ControlPath="${SSH_CONTROL_PATH}" \
-o ControlPersist=300 \