Réplication de nœuds : réseau et DNS par l'API, multipath, chrony, sysctl par SSH
Deuxième mode de réplication, séparé de la réplication cluster vers cluster
(sélecteur « Clusters (API) | Nœuds (fichiers) » en haut de page) : un profil
réplique la configuration système d'un nœud maître vers des nœuds cibles.
- réseau par /nodes/{node}/network (interfaces.new puis rechargement), adresses
et passerelles propres à chaque nœud, mapping des noms d'interfaces par cible ;
DNS par /nodes/{node}/dns ; multipath.conf, wwids (ajout seul), chrony,
sysctl.d, interfaces.d (hors sdn) par SSH
- découverte des nœuds (/cluster/status), accès SSH par nœud (mot de passe du
cluster ou propre), clé d'hôte épinglée, contrôle du nom du nœud
- dry-run avec diff des fichiers ; apply (admin) avec contrôle SHA-256,
sauvegarde et restore.sh sur le nœud, écriture atomique, rechargements,
restauration si un rechargement échoue, timer systemd de restauration si le
nœud est injoignable après le rechargement du réseau, confirmation tapée
- vue Nœuds et profils, journal séparé par mode, démo avec nœuds simulés
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
dc1a7ff40e
commit
1e667ce8b9
24 files changed
+4973
-65
No files matched your search
@@ -756,3 +756,53 @@ body.login-page { min-height: 100vh; padding: 16px; display: grid; place-items:
|
||||
.plan-kinds .seg button:disabled { cursor: default; }
|
||||
.plan-kinds .seg button:disabled:not([aria-checked="true"]) { opacity: .55; }
|
||||
@media (max-width: 560px) { .plan-kinds .pk-row { grid-template-columns: minmax(0, 1fr) auto; } .plan-kinds .pk-row .kind, .plan-kinds .pk-n { display: none; } }
|
||||
|
||||
/* ---------- node replication ---------- */
|
||||
/* the two replications, side by side in the top bar */
|
||||
.mode-sw { flex: none; }
|
||||
.mode-sw button { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px; font-weight: 600; }
|
||||
.mode-sw svg { width: 15px; height: 15px; }
|
||||
.mode-sw button[aria-checked="true"] { background: var(--accent); color: #fff; }
|
||||
body.mode-node .brand svg rect { fill: var(--k-vnet); }
|
||||
|
||||
.kind.network { --k: var(--k-zone); }
|
||||
.kind.dns { --k: var(--k-vnet); }
|
||||
.kind.multipath, .kind.wwids { --k: var(--k-acc); }
|
||||
.kind.chrony { --k: var(--k-dc); }
|
||||
.kind.sysctl { --k: var(--k-subnet); }
|
||||
.kind.interfaces-d { --k: var(--k-zone); }
|
||||
.badge.network { --c: var(--k-zone); margin-left: 4px; }
|
||||
|
||||
/* unified diff of a file */
|
||||
.udiff { margin: 4px 0 0; padding: 6px 0; border: 1px solid var(--border); border-radius: 8px; background: var(--panel-2);
|
||||
font: 12px/1.45 var(--mono); overflow-x: auto; max-height: 420px; overflow-y: auto; }
|
||||
.udiff div { padding: 0 10px; white-space: pre; min-height: 1.45em; }
|
||||
.udiff .d-add { color: var(--op-create); background: color-mix(in srgb, var(--op-create) 10%, transparent); }
|
||||
.udiff .d-del { color: var(--op-delete); background: color-mix(in srgb, var(--op-delete) 10%, transparent); }
|
||||
.udiff .d-hunk { color: var(--info); padding-top: 4px; }
|
||||
.plan .udiff { margin-left: 1.2rem; }
|
||||
.plan .reloads { margin: 6px 0 0; color: var(--muted); font-size: 12px; }
|
||||
|
||||
.sec-title { margin: 18px 0 8px; font-size: 11px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
|
||||
.sec-title:first-of-type { margin-top: 6px; }
|
||||
.citem.node { grid-template-columns: minmax(9rem, max-content) minmax(0, 1fr) max-content; }
|
||||
.citem.prof { grid-template-columns: minmax(9rem, max-content) minmax(0, 1fr) max-content; }
|
||||
.citem .items { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px; }
|
||||
.citem .items .kind { width: auto; }
|
||||
dialog.wide { width: min(980px, calc(100vw - 32px)); }
|
||||
|
||||
/* mapping of one target in the profile editor */
|
||||
.pmap { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 6px 10px; align-items: start; padding: 8px 10px;
|
||||
border: 1px solid var(--border); border-radius: 8px; }
|
||||
.pmap > b { grid-column: 1 / -1; font: 600 12.5px var(--mono); }
|
||||
.pmap label { font-size: 12px; color: var(--muted); padding-top: 6px; }
|
||||
.pmap textarea { min-height: 3.2em; font-family: var(--mono); font-size: 12px; }
|
||||
.pprot { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 6px 10px; align-items: start; }
|
||||
.pprot textarea { min-height: 2.4em; font-family: var(--mono); font-size: 12px; }
|
||||
@media (max-width: 1100px) {
|
||||
.mode-sw span { display: none; }
|
||||
.mode-sw button { padding: 0 9px; }
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
.pmap, .pprot { grid-template-columns: 1fr; }
|
||||
}
|
||||
Reference in new issue
Block a user