Backup automatico script del 2026-08-02 07:00
This commit is contained in:
1 parent
a9bbb92090
commit
7c2efce9df
2 files changed
+50
-118
No files matched your search
@@ -1,57 +1,57 @@
|
||||
#!/bin/bash
|
||||
# Clona NPM master (Pi1) → backup Pi2 + clone dormiente DS920 (NPM3).
|
||||
# Su DS920: extract solo se extrema-npm NON è running (evita SQLite corrotto in B1).
|
||||
# Synology: SFTP spesso chrootato → verso DS920 si usa stream tar via SSH (non scp).
|
||||
set -euo pipefail
|
||||
|
||||
# --- CONFIGURAZIONE ---
|
||||
REMOTE_IP="192.168.128.81"
|
||||
REMOTE_USER="daniely"
|
||||
# Cartella che contiene 'data' e 'letsencrypt'
|
||||
SOURCE_BASE="/home/daniely/docker/npm"
|
||||
TEMP_FILE="/tmp/npm_full_clone.tar.gz"
|
||||
REMOTE_IP="${REMOTE_IP:-192.168.128.81}"
|
||||
REMOTE_USER="${REMOTE_USER:-daniely}"
|
||||
DS920_IP="${DS920_IP:-192.168.128.100}"
|
||||
DS920_USER="${DS920_USER:-daniely}"
|
||||
DS920_NPM_ROOT="${DS920_NPM_ROOT:-/volume1/extrema/npm}"
|
||||
SOURCE_BASE="${SOURCE_BASE:-/home/daniely/docker/npm}"
|
||||
TEMP_FILE="${TEMP_FILE:-/tmp/npm_full_clone.tar.gz}"
|
||||
|
||||
echo "[$(date)] Avvio clonazione totale NPM (Master -> Backup)..."
|
||||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] sync-npm: $*"; }
|
||||
|
||||
log "Avvio clonazione NPM (Master → Pi2 + DS920)..."
|
||||
|
||||
# 1. Crea un archivio compresso di TUTTO (Database SQL + Certificati)
|
||||
# Usiamo sudo per leggere i file di root senza permessi negati
|
||||
# Escludiamo i log per risparmiare spazio
|
||||
sudo tar --exclude='*.log' -czf "$TEMP_FILE" -C "$SOURCE_BASE" data letsencrypt
|
||||
sudo chown "${USER}:${USER}" "$TEMP_FILE"
|
||||
|
||||
# 2. Assegna l'archivio all'utente corrente (per poterlo spedire via SCP)
|
||||
sudo chown $USER:$USER "$TEMP_FILE"
|
||||
|
||||
# 3. Spedisce l'archivio al Pi-2
|
||||
echo "Invio archivio al Pi-2 ($REMOTE_IP)..."
|
||||
scp -o ConnectTimeout=10 "$TEMP_FILE" "$REMOTE_USER@$REMOTE_IP:/tmp/"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Trasferimento riuscito. Applicazione sul Backup..."
|
||||
|
||||
# 4. Comanda al Pi-2 di:
|
||||
# a) Arrestare NPM (per sbloccare il database)
|
||||
# b) Scompattare sovrascrivendo tutto
|
||||
# c) Ripristinare i permessi di root
|
||||
# d) Riavviare NPM
|
||||
ssh "$REMOTE_USER@$REMOTE_IP" "
|
||||
echo ' ...Stop NPM...';
|
||||
docker stop npm;
|
||||
|
||||
echo ' ...Estrazione dati...';
|
||||
# Pulisce la cartella di destinazione prima di estrarre per evitare residui
|
||||
sudo rm -rf /home/daniely/docker/npm/data/*
|
||||
sudo rm -rf /home/daniely/docker/npm/letsencrypt/*
|
||||
sudo tar -xzf /tmp/npm_full_clone.tar.gz -C /home/daniely/docker/npm/;
|
||||
|
||||
echo ' ...Fix Permessi...';
|
||||
sudo chown -R root:root /home/daniely/docker/npm/;
|
||||
|
||||
echo ' ...Start NPM...';
|
||||
docker start npm;
|
||||
|
||||
# Pulizia remota
|
||||
rm /tmp/npm_full_clone.tar.gz
|
||||
"
|
||||
echo "[$(date)] Sincronizzazione Completata con Successo."
|
||||
# --- Pi-2 (hot backup: stop/extract/start) ---
|
||||
log "Invio archivio al Pi-2 ($REMOTE_IP)..."
|
||||
if scp -o ConnectTimeout=10 -o BatchMode=yes "$TEMP_FILE" "${REMOTE_USER}@${REMOTE_IP}:/tmp/npm_full_clone.tar.gz"; then
|
||||
ssh -o ConnectTimeout=15 -o BatchMode=yes "${REMOTE_USER}@${REMOTE_IP}" bash -s <<'EOS'
|
||||
set -e
|
||||
echo " ...Stop NPM..."
|
||||
docker stop npm 2>/dev/null || true
|
||||
echo " ...Estrazione dati..."
|
||||
sudo rm -rf /home/daniely/docker/npm/data/* /home/daniely/docker/npm/letsencrypt/*
|
||||
sudo tar -xzf /tmp/npm_full_clone.tar.gz -C /home/daniely/docker/npm/
|
||||
sudo chown -R root:root /home/daniely/docker/npm/
|
||||
echo " ...Start NPM..."
|
||||
docker start npm
|
||||
rm -f /tmp/npm_full_clone.tar.gz
|
||||
EOS
|
||||
log "Pi-2 sincronizzato OK"
|
||||
else
|
||||
echo "[$(date)] ERRORE CRITICO: Trasferimento fallito."
|
||||
log "ERRORE: trasferimento Pi-2 fallito"
|
||||
fi
|
||||
|
||||
# --- DS920 NPM3 (dormiente) ---
|
||||
log "Stream archivio al DS920 ($DS920_IP)..."
|
||||
if ssh -o ConnectTimeout=15 -o BatchMode=yes "${DS920_USER}@${DS920_IP}" \
|
||||
"export PATH=/usr/local/bin:\$PATH; docker ps --format '{{.Names}}' 2>/dev/null | grep -qx extrema-npm"; then
|
||||
log "SKIP DS920: extrema-npm running (B1 armato) — sync al prossimo disarm"
|
||||
else
|
||||
if cat "$TEMP_FILE" | ssh -o ConnectTimeout=180 -o BatchMode=yes "${DS920_USER}@${DS920_IP}" \
|
||||
"export PATH=/usr/local/bin:\$PATH; NPM_ROOT=$(printf %q "$DS920_NPM_ROOT"); mkdir -p \"\$NPM_ROOT/data\" \"\$NPM_ROOT/letsencrypt\"; find \"\$NPM_ROOT/data\" -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true; find \"\$NPM_ROOT/letsencrypt\" -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true; tar -xzf - -C \"\$NPM_ROOT\"; chmod -R a+rX \"\$NPM_ROOT\" 2>/dev/null || true; echo NPM3_EXTRACT_OK; ls \"\$NPM_ROOT/data/nginx/proxy_host\" 2>/dev/null | head -5"; then
|
||||
log "DS920 NPM3 sincronizzato OK (dormiente)"
|
||||
else
|
||||
log "ERRORE: extract DS920 fallito"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 5. Pulizia locale
|
||||
sudo rm -f "$TEMP_FILE"
|
||||
log "Sincronizzazione NPM completata."
|
||||
@@ -1,71 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ================================================
|
||||
# SENTINELLA DI BACKUP (Gira su Pi-1 Master)
|
||||
# Controlla Pi-2 e attiva failover bundle IoT su Pi-1 se down.
|
||||
# ================================================
|
||||
|
||||
LOOGLE_NOTIFY="/home/daniely/docker/loogle-casa/scripts/loogle-notify.sh"
|
||||
HA_FAILOVER="/home/daniely/rete/scripts/ha-failover.sh"
|
||||
|
||||
if [[ ! -x "$LOOGLE_NOTIFY" ]]; then
|
||||
echo "Errore: loogle-notify non disponibile ($LOOGLE_NOTIFY)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_IP="192.168.128.81"
|
||||
TARGET_NAME="🍓 Pi-2 (Backup & Monitor)"
|
||||
STATE_FILE="/mnt/ha-apps/.metadata/pi2-watchdog.state"
|
||||
SIM_STATE="/mnt/ha-apps/.metadata/failover-sim.state"
|
||||
LEGACY_STATE_FILE="/tmp/pi2_watchdog.state"
|
||||
SSH_OPTS=(-o ConnectTimeout=5 -o BatchMode=yes -o StrictHostKeyChecking=accept-new)
|
||||
|
||||
if [[ -f "$SIM_STATE" ]] && [[ "$(cat "$SIM_STATE" 2>/dev/null)" != "none" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
send_alert() {
|
||||
local title="$1"
|
||||
local body="$2"
|
||||
local severity="$3"
|
||||
"$LOOGLE_NOTIFY" --title "$title" --body "$body" --category watchdog_pi2 \
|
||||
--severity "$severity" &
|
||||
}
|
||||
|
||||
pi2_reachable() {
|
||||
ping -c 3 -W 2 "$TARGET_IP" > /dev/null 2>&1 && return 0
|
||||
ssh "${SSH_OPTS[@]}" pi2 "exit 0" 2>/dev/null
|
||||
}
|
||||
|
||||
if [ ! -f "$STATE_FILE" ]; then
|
||||
if [ -f "$LEGACY_STATE_FILE" ]; then
|
||||
cp "$LEGACY_STATE_FILE" "$STATE_FILE"
|
||||
else
|
||||
echo "UP" > "$STATE_FILE"
|
||||
fi
|
||||
fi
|
||||
LAST_STATE=$(cat "$STATE_FILE")
|
||||
|
||||
if pi2_reachable; then
|
||||
if [ "$LAST_STATE" == "DOWN" ]; then
|
||||
send_alert \
|
||||
"Pi-2 online" \
|
||||
"RISOLTO: $TARGET_NAME è tornato ONLINE! Failback bundle IoT in corso." \
|
||||
"info"
|
||||
echo "UP" > "$STATE_FILE"
|
||||
if [[ -x "$HA_FAILOVER" ]]; then
|
||||
sudo bash -c "\"$HA_FAILOVER\" stop-iot-bundle >> /var/log/ha-failover.log 2>&1 &"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ "$LAST_STATE" == "UP" ]; then
|
||||
send_alert \
|
||||
"Pi-2 offline" \
|
||||
"ALLARME: $TARGET_NAME è OFFLINE! Avvio failover bundle IoT su Pi-1." \
|
||||
"warning"
|
||||
echo "DOWN" > "$STATE_FILE"
|
||||
if [[ -x "$HA_FAILOVER" ]]; then
|
||||
sudo bash -c "\"$HA_FAILOVER\" start-iot-bundle >> /var/log/ha-failover.log 2>&1 &"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
#!/usr/bin/env bash
|
||||
# Wrapper legacy — redirige al modulo infra-monitor
|
||||
exec /home/daniely/rete/infra-monitor/pi2-watchdog.sh "$@"
|
||||
Reference in new issue
Block a user