v1.5.1: Sauvegarde/restauration intégrale AstDB et synchronisation SIP immédiate des téléphones (check-sync)

This commit is contained in:
sorcier committed 2026-11-04 12:43:32 +01:00
1 parent accec47d08
commit 65a62ca0e4
6 files changed
+89 -5

No files matched your search

+8
View File
@@ -285,6 +285,8 @@ chmod 0640 /etc/asterisk/keys/* 2>/dev/null || true
# Inclusions custom dans Asterisk & initialisation des fichiers cibles
touch /etc/asterisk/pjsip.conf \
/etc/asterisk/pjsip.custom.conf \
/etc/asterisk/pjsip_notify.conf \
/etc/asterisk/pjsip_notify.custom.conf \
/etc/asterisk/extensions.conf \
/etc/asterisk/extensions.custom.conf \
/etc/asterisk/musiconhold.conf \
@@ -308,6 +310,12 @@ fi
if ! grep -q 'pjsip.custom.conf' /etc/asterisk/pjsip.conf 2>/dev/null; then
printf '\n#tryinclude "pjsip.custom.conf"\n' >> /etc/asterisk/pjsip.conf
fi
if ! grep -q 'pjsip_notify.custom.conf' /etc/asterisk/pjsip_notify.conf 2>/dev/null; then
printf '\n#tryinclude "pjsip_notify.custom.conf"\n' >> /etc/asterisk/pjsip_notify.conf
fi
if [ ! -s /etc/asterisk/pjsip_notify.custom.conf ]; then
printf '[check-sync]\nEvent=>check-sync\\;reboot=false\n\n[resync]\nEvent=>check-sync\\;reboot=false\n' > /etc/asterisk/pjsip_notify.custom.conf
fi
if ! grep -q 'extensions.custom.conf' /etc/asterisk/extensions.conf 2>/dev/null; then
printf '\n#tryinclude "extensions.custom.conf"\n' >> /etc/asterisk/extensions.conf
fi
+8
View File
@@ -63,6 +63,8 @@ chmod 2775 /var/www/nexus-pbx/storage /var/www/nexus-pbx/storage/backups /var/ww
touch /etc/asterisk/pjsip.conf \
/etc/asterisk/pjsip.custom.conf \
/etc/asterisk/pjsip_notify.conf \
/etc/asterisk/pjsip_notify.custom.conf \
/etc/asterisk/extensions.conf \
/etc/asterisk/extensions.custom.conf \
/etc/asterisk/musiconhold.conf \
@@ -86,6 +88,12 @@ fi
if ! grep -q 'pjsip.custom.conf' /etc/asterisk/pjsip.conf 2>/dev/null; then
printf '\n#tryinclude "pjsip.custom.conf"\n' >> /etc/asterisk/pjsip.conf
fi
if ! grep -q 'pjsip_notify.custom.conf' /etc/asterisk/pjsip_notify.conf 2>/dev/null; then
printf '\n#tryinclude "pjsip_notify.custom.conf"\n' >> /etc/asterisk/pjsip_notify.conf
fi
if [ ! -s /etc/asterisk/pjsip_notify.custom.conf ]; then
printf '[check-sync]\nEvent=>check-sync\\;reboot=false\n\n[resync]\nEvent=>check-sync\\;reboot=false\n' > /etc/asterisk/pjsip_notify.custom.conf
fi
if ! grep -q 'extensions.custom.conf' /etc/asterisk/extensions.conf 2>/dev/null; then
printf '\n#tryinclude "extensions.custom.conf"\n' >> /etc/asterisk/extensions.conf
fi
+39
View File
@@ -257,6 +257,17 @@ class BackupManager
}
$manifestFiles['asterisk_custom_conf'] = ['count' => count(glob($destConfs . '/*'))];
// E2. Base interne Asterisk AstDB (contacts enregistrés, renvois, DND)
$astDbPath = '/var/lib/asterisk/astdb.sqlite3';
if (file_exists($astDbPath)) {
$destAstDb = $stageDir . '/astdb.sqlite3';
copy($astDbPath, $destAstDb);
$manifestFiles['astdb.sqlite3'] = [
'size' => filesize($destAstDb),
'md5' => md5_file($destAstDb),
];
}
// F. Avatars et photos des contacts de l'annuaire (/var/www/nexus-pbx/public/avatars/)
$publicAvatars = '/var/www/nexus-pbx/public/avatars';
if (is_dir($publicAvatars)) {
@@ -595,6 +606,15 @@ class BackupManager
exec("chmod -R 775 " . escapeshellarg($destAvatars));
}
// 9c. Restauration de la base interne AstDB (contacts enregistrés, renvois, DND)
if (file_exists($stageDir . '/astdb.sqlite3')) {
$targetAstDb = '/var/lib/asterisk/astdb.sqlite3';
copy($stageDir . '/astdb.sqlite3', $targetAstDb);
@chown($targetAstDb, 'asterisk');
@chgrp($targetAstDb, 'asterisk');
@chmod($targetAstDb, 0664);
}
// 10. Régénération intégrale des configurations Asterisk avec la nouvelle base restaurée
Database::resetConnection();
$dbFresh = Database::getConnection(true);
@@ -609,6 +629,25 @@ class BackupManager
$reloadRes = ['success' => false, 'error' => $e->getMessage()];
}
// 12. Notification de réenregistrement immédiat des téléphones IP (check-sync)
try {
$extList = $dbFresh->query("SELECT extension FROM extensions WHERE enabled = 1")->fetchAll(\PDO::FETCH_COLUMN);
foreach ($extList as $extItem) {
$ami->runCommand("pjsip send notify snom-check-cfg endpoint {$extItem}");
}
$astContacts = $ami->runCommand("database show registrar/contact");
foreach (preg_split('/\r?\n/', $astContacts) ?: [] as $cLine) {
if (preg_match('/^\/registrar\/contact\/([^;]+);@[a-f0-9]+:\s*(\{.*\})/i', $cLine, $cM)) {
$meta = json_decode($cM[2], true);
if (!empty($meta['uri'])) {
$ami->runCommand("pjsip send notify snom-check-cfg uri " . escapeshellarg($meta['uri']));
}
}
}
} catch (Exception $e) {
// Silencieux si échec d'envoi NOTIFY
}
return [
'success' => true,
'message' => 'Restauration complète effectuée avec succès ! Base de données réintégrée, fichiers audio, messageries vocales et configurations Asterisk rechargées.',
+14
View File
@@ -178,6 +178,17 @@ class ConfigGenerator
$lines[] = "allow_reload = no";
$lines[] = "";
$lines[] = "; --- CONFIGURATION GLOBALE & POINT DE SORTIE PAR DÉFAUT (NOTIFY / RESYNC) ---";
$lines[] = "[global]";
$lines[] = "type = global";
$lines[] = "default_outbound_endpoint = default_outbound_endpoint";
$lines[] = "";
$lines[] = "[default_outbound_endpoint]";
$lines[] = "type = endpoint";
$lines[] = "context = from-internal";
$lines[] = "transport = transport-udp";
$lines[] = "";
// 3. Extensions (Postes téléphoniques hybrides UDP vs TLS+SRTP)
$lines[] = "; ===========================================================================";
$lines[] = "; POSTES TÉLÉPHONIQUES (EXTENSIONS)";
@@ -256,6 +267,9 @@ class ConfigGenerator
$lines[] = "type = aor";
$lines[] = "max_contacts = {$maxContacts}";
$lines[] = "remove_existing = yes";
$lines[] = "default_expiration = 120";
$lines[] = "maximum_expiration = 300";
$lines[] = "minimum_expiration = 60";
$lines[] = "qualify_frequency = 30";
if ($hasVm) {
$lines[] = "mailboxes = {$num}@default";
+15
View File
@@ -174,6 +174,21 @@ class SystemChecker
}
}
$notifyConf = '/etc/asterisk/pjsip_notify.conf';
if (is_file($notifyConf) && is_writable($notifyConf)) {
$content = (string)file_get_contents($notifyConf);
if (!str_contains($content, 'pjsip_notify.custom.conf')) {
file_put_contents($notifyConf, rtrim($content) . "\n\n#tryinclude \"pjsip_notify.custom.conf\"\n");
}
}
$customNotify = '/etc/asterisk/pjsip_notify.custom.conf';
if (!file_exists($customNotify)) {
@file_put_contents($customNotify, "[check-sync]\nEvent=>check-sync\\;reboot=false\n\n[resync]\nEvent=>check-sync\\;reboot=false\n");
@chown($customNotify, 'asterisk');
@chgrp($customNotify, 'asterisk');
@chmod($customNotify, 0664);
}
$extConf = '/etc/asterisk/extensions.conf';
if (is_file($extConf) && is_writable($extConf)) {
$content = (string)file_get_contents($extConf);
+5 -5
View File
@@ -1,12 +1,12 @@
{
"version": "1.5.0",
"version": "1.5.1",
"codename": "Helios",
"release_date": "2026-11-04",
"min_php_version": "8.2",
"changelog": [
"Gestion native et universelle des sons personnalisés par chemin absolu Asterisk (compatible multilingue français, anglais, italien, espagnol sans dépendance aux liens symboliques)",
"Préservation automatique des invites système par langue (fr, en, it, es)",
"Résolution définitive et propre des conflits de préfixes Dialplan sur les SVI/IVR (*801-*899)",
"Restauration instantanée du statut en ligne des postes après restauration de sauvegarde"
"Sauvegarde et restauration intégrale de la base interne Asterisk AstDB (contacts enregistrés, renvois, DND)",
"Notification et synchronisation SIP immédiate des téléphones IP (check-sync) après toute restauration",
"Plafond d'expiration d'enregistrement SIP (maximum_expiration = 300s, default = 120s) empêchant les téléphones de rester déconnectés",
"Support universel PJSIP Notify et point de sortie par défaut pour la réinitialisation à chaud des téléphones"
]
}