odoov18-compta/1.0.BootStrap-host.sh

178 lines
No EOL
6.9 KiB
Bash

#!/bin/bash
# ═══════════════════════════════════════════════════════════════
# 00-bootstrap-host.sh
# Bootstrap firewalld + Docker pour USINE_APPLICATIONS
#
# A lancer une fois sur chaque host Fedora avant tout déploiement.
# Idempotent. peut être relancé sans risque.
#
# Usage. sudo ./00-bootstrap-host.sh
# ═══════════════════════════════════════════════════════════════
set -euo pipefail
# ── Configuration ─────────────────────────────────────────────
DNS_PRIMARY="${DNS_PRIMARY:-8.8.8.8}"
DNS_SECONDARY="${DNS_SECONDARY:-8.8.4.4}"
DOCKER_DAEMON_CONF="/etc/docker/daemon.json"
TEST_IMAGE="alpine:latest"
LOG_PREFIX="[bootstrap-host]"
# ── Helpers ───────────────────────────────────────────────────
log() { echo "${LOG_PREFIX} $*"; }
warn() { echo "${LOG_PREFIX} WARN. $*" >&2; }
err() { echo "${LOG_PREFIX} ERREUR. $*" >&2; }
die() { err "$*"; exit 1; }
confirm() {
local prompt="${1:-Continuer ?} [o/N] "
read -r -p "$prompt" response
[[ "$response" =~ ^[oOyY]$ ]] || die "Annulation utilisateur."
}
# ── Phase 0. Vérifications préalables ─────────────────────────
log "Phase 0. vérifications préalables..."
[[ $EUID -eq 0 ]] || die "Script à lancer en root (sudo $0)."
[[ -f /etc/fedora-release ]] || warn "Système non-Fedora détecté. Le script peut nécessiter des adaptations."
command -v docker >/dev/null 2>&1 || die "Docker non installé."
command -v firewall-cmd >/dev/null 2>&1 || die "firewalld non installé."
systemctl is-active --quiet firewalld || die "firewalld non actif. systemctl start firewalld"
systemctl is-active --quiet docker || die "Docker non actif. systemctl start docker"
log " Toutes les vérifications passent."
# ── Avertissement utilisateur ─────────────────────────────────
log ""
log "Ce script va."
log " 1. Réécrire ${DOCKER_DAEMON_CONF} (backup automatique)"
log " 2. Modifier la configuration firewalld (zone trusted + masquerade)"
log " 3. Redémarrer le service Docker (tous les containers vont stopper)"
log " 4. Exécuter des tests de validation (pull image alpine)"
log ""
if [[ "${1:-}" != "--force" ]]; then
confirm "Confirmer le bootstrap ?"
fi
# ── Phase 1. Configuration daemon Docker ──────────────────────
log ""
log "Phase 1. configuration de ${DOCKER_DAEMON_CONF}..."
mkdir -p /etc/docker
if [[ -f "${DOCKER_DAEMON_CONF}" ]]; then
BACKUP="${DOCKER_DAEMON_CONF}.bak.$(date +%Y%m%d-%H%M%S)"
cp "${DOCKER_DAEMON_CONF}" "${BACKUP}"
log " Backup. ${BACKUP}"
fi
cat > "${DOCKER_DAEMON_CONF}" <<EOF
{
"iptables": true,
"ip-masq": true,
"dns": ["${DNS_PRIMARY}", "${DNS_SECONDARY}"],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
log " daemon.json écrit."
# ── Phase 2. Configuration firewalld ──────────────────────────
log ""
log "Phase 2. configuration firewalld..."
DEFAULT_ZONE=$(firewall-cmd --get-default-zone)
log " Zone par défaut. ${DEFAULT_ZONE}"
# docker0 (toujours présent quand Docker est installé)
firewall-cmd --permanent --zone=trusted --add-interface=docker0 2>/dev/null || true
log " docker0 ajouté à la zone trusted."
# Bridges Docker custom (br-*)
BRIDGES=$(ip -o link show | awk -F: '/br-/{print $2}' | tr -d ' ' | cut -d@ -f1)
if [[ -n "${BRIDGES}" ]]; then
BRIDGE_COUNT=$(echo "${BRIDGES}" | wc -l)
log " ${BRIDGE_COUNT} bridge(s) custom détecté(s)."
while IFS= read -r iface; do
firewall-cmd --permanent --zone=trusted --add-interface="${iface}" 2>/dev/null || true
log " + ${iface}"
done <<< "${BRIDGES}"
else
log " Aucun bridge custom détecté."
fi
# Masquerade sur la zone par défaut
firewall-cmd --permanent --zone="${DEFAULT_ZONE}" --add-masquerade 2>/dev/null || true
log " Masquerade activé sur la zone ${DEFAULT_ZONE}."
# Reload
firewall-cmd --reload
log " firewalld rechargé."
# ── Phase 3. Redémarrage Docker ───────────────────────────────
log ""
log "Phase 3. redémarrage du service Docker..."
systemctl restart docker
# Attente que Docker soit pleinement opérationnel
for i in {1..15}; do
if docker info >/dev/null 2>&1; then
log " Docker opérationnel après ${i}s."
break
fi
sleep 1
if [[ $i -eq 15 ]]; then
die "Docker ne répond pas après 15s."
fi
done
# ── Phase 4. Tests de validation ──────────────────────────────
log ""
log "Phase 4. tests de validation..."
log " Test 1. pull image de test (${TEST_IMAGE})..."
docker pull "${TEST_IMAGE}" >/dev/null 2>&1 || die "Pull image échoué. DNS du host probablement HS."
log " OK"
log " Test 2. résolution DNS depuis un container..."
if docker run --rm "${TEST_IMAGE}" nslookup archive.ubuntu.com >/dev/null 2>&1; then
log " OK"
else
err " Échec résolution DNS."
err " Lancer manuellement. docker run --rm alpine nslookup archive.ubuntu.com"
exit 2
fi
log " Test 3. connectivité HTTPS sortante depuis un container..."
if docker run --rm "${TEST_IMAGE}" wget -q --spider https://www.cloudflare.com 2>/dev/null; then
log " OK"
else
err " Échec connectivité HTTPS sortante."
exit 2
fi
# ── Phase 5. Résumé ───────────────────────────────────────────
log ""
log "═══════════════════════════════════════════════════════════"
log " Bootstrap terminé avec succès."
log "═══════════════════════════════════════════════════════════"
log " Zone par défaut. ${DEFAULT_ZONE}"
log " Masquerade. actif"
log " DNS Docker. ${DNS_PRIMARY}, ${DNS_SECONDARY}"
log " Daemon config. ${DOCKER_DAEMON_CONF}"
log ""
log " Interfaces en zone trusted."
firewall-cmd --zone=trusted --list-interfaces | tr ' ' '\n' | sed 's/^/ - /'
log ""
log " USINE_APPLICATIONS prêt pour déploiement."
log "═══════════════════════════════════════════════════════════"