From 3f29ac6d2e260546571fb27822354b5750b099aa Mon Sep 17 00:00:00 2001 From: sorcier Date: Thu, 5 Nov 2026 19:58:58 +0100 Subject: [PATCH] feat(cluster): real-time auto-sync on apply_config + 5min cron periodic sync --- install.sh | 7 ++++++ public/api.php | 21 +++++++++++++--- scripts/nexus_cluster_sync.php | 46 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 scripts/nexus_cluster_sync.php diff --git a/install.sh b/install.sh index 1361e5e..c5bfd8b 100755 --- a/install.sh +++ b/install.sh @@ -488,6 +488,13 @@ EOF chmod 0644 /etc/cron.d/nexus-backup touch /var/log/nexus_backup.log && chown www-data:asterisk /var/log/nexus_backup.log && chmod 664 /var/log/nexus_backup.log +# Cron synchronisation Cluster HA toutes les 5 minutes +cat << 'EOF' > /etc/cron.d/nexus-cluster-sync +# Synchronisation périodique du cluster NexusPBX HA vers le nœud Backup +*/5 * * * * www-data /usr/bin/php /var/www/nexus-pbx/scripts/nexus_cluster_sync.php >> /var/log/nexus_cluster.log 2>&1 +EOF +chmod 0644 /etc/cron.d/nexus-cluster-sync + # CLI symlinks chmod +x "$TARGET_DIR/scripts/nexus-firewall" "$TARGET_DIR/scripts/nexus-banner.sh" "$TARGET_DIR/scripts/update.sh" "$TARGET_DIR/scripts/nexus-cluster" chmod +x "$TARGET_DIR"/scripts/cluster/*.sh 2>/dev/null || true diff --git a/public/api.php b/public/api.php index 6210192..8dd542b 100644 --- a/public/api.php +++ b/public/api.php @@ -1793,12 +1793,27 @@ try { $ami = AmiClient::fromDatabase($db); $reloadInfo = $ami->reloadPjsipAndDialplan(); + // Synchronisation automatique temps réel vers le nœud pair si Cluster actif et Master + $clusterSyncMsg = null; + try { + $cm = new ClusterManager($db); + $cSet = $cm->getSettings(); + if (!empty($cSet['enabled']) && !empty($cSet['auto_sync']) && ($cSet['role'] ?? '') === 'master' && !empty($cSet['peer_ip'])) { + $syncRes = $cm->pushSyncToPeer(); + $clusterSyncMsg = $syncRes['message'] ?? 'Réplication pair OK'; + } + } catch (\Throwable $ce) { + error_log("[CLUSTER] Auto-sync on apply_config error: " . $ce->getMessage()); + $clusterSyncMsg = "Alerte réplication pair : " . $ce->getMessage(); + } + echo json_encode([ 'success' => true, - 'message' => 'Configurations écrites, pile PJSIP rechargée et Re-Register SIP envoyé à tous les opérateurs !', + 'message' => 'Configurations appliquées avec succès !' . ($clusterSyncMsg ? ' (' . $clusterSyncMsg . ')' : ''), 'details' => [ - 'files' => $writeStats, - 'reload' => $reloadInfo, + 'files' => $writeStats, + 'reload' => $reloadInfo, + 'cluster_sync' => $clusterSyncMsg, ], ]); break; diff --git a/scripts/nexus_cluster_sync.php b/scripts/nexus_cluster_sync.php new file mode 100644 index 0000000..af9a014 --- /dev/null +++ b/scripts/nexus_cluster_sync.php @@ -0,0 +1,46 @@ +getSettings(); + + // 1. Si le cluster n'est pas activé ou que l'auto-sync est désactivée + if (empty($st['enabled']) || empty($st['auto_sync'])) { + exit(0); + } + + // 2. Seul le nœud MASTER actif émet la synchronisation vers le nœud BACKUP + $vip = $st['virtual_ip'] ?? ''; + $isVipActive = $cm->isVirtualIpActive($vip); + $configuredRole = $st['role'] ?? 'master'; + + // Un esclave (backup) ne doit jamais écraser le maître + if ($configuredRole !== 'master' && !$isVipActive) { + exit(0); + } + + if (empty($st['peer_ip'])) { + exit(0); + } + + // 3. Déclenchement de la réplication vers le pair + $result = $cm->pushSyncToPeer(); + echo date('[Y-m-d H:i:s] ') . "[CLUSTER-CRON] " . ($result['message'] ?? 'Synchronisation OK') . "\n"; +} catch (\Throwable $e) { + echo date('[Y-m-d H:i:s] ') . "[CLUSTER-CRON-ERROR] " . $e->getMessage() . "\n"; + exit(1); +}