Network: confirm a change only after it has been fully applied, keep the session when the old connection times out, and retry reloading so changes show up without reopening the tab
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+13
-10
@@ -149,8 +149,10 @@ class NetworkConfigManager {
|
||||
}
|
||||
|
||||
watch(id, s) {
|
||||
s.conn.on('close', () => { if (this.sessions.get(id) === s && !s.replacing) { this.close(id); s.onClose(); } });
|
||||
s.conn.on('error', () => {});
|
||||
const conn = s.conn;
|
||||
// Nur die aktuelle Verbindung darf die Sitzung beenden (nach apply wird sie ersetzt)
|
||||
conn.on('close', () => { if (this.sessions.get(id) === s && s.conn === conn) { this.close(id); s.onClose(); } });
|
||||
conn.on('error', () => {});
|
||||
}
|
||||
|
||||
async read(id) {
|
||||
@@ -226,7 +228,7 @@ class NetworkConfigManager {
|
||||
const be = BACKENDS[backendName || s.backend];
|
||||
if (!be) throw new Error(i18n.t('Editing is not supported for this network configuration ({backend}).', { backend: s.backend }));
|
||||
const script = `export PATH=$PATH:/usr/sbin:/sbin
|
||||
mkdir -p ${STATE} || exit 1; rm -f ${STATE}/pending ${STATE}/rolled-back
|
||||
mkdir -p ${STATE} || exit 1; rm -f ${STATE}/pending ${STATE}/applied ${STATE}/rolled-back
|
||||
cd / && tar czf ${STATE}/backup.tgz $(for p in ${be.paths.join(' ')}; do [ -e "$p" ] && echo "$p"; done) || exit 1
|
||||
# Schreiben in einer Subshell: bei einem Fehler sofort den alten Stand wiederherstellen
|
||||
if ! ( set -e
|
||||
@@ -234,7 +236,7 @@ ${writes.join('\n')}
|
||||
) >${STATE}/write.log 2>&1; then ${be.restore}; cat ${STATE}/write.log >&2; exit 5; fi
|
||||
if ! (${be.validate}) >${STATE}/validate.log 2>&1; then ${be.restore}; cat ${STATE}/validate.log >&2; exit 4; fi
|
||||
touch ${STATE}/pending
|
||||
nohup setsid sh -c 'export PATH=$PATH:/usr/sbin:/sbin; sleep 2; (${be.apply}) >${STATE}/apply.log 2>&1; sleep ${ROLLBACK_SECONDS}; if [ -f ${STATE}/pending ]; then ${be.restore}; (${be.apply}) >>${STATE}/apply.log 2>&1; rm -f ${STATE}/pending; date "+%Y-%m-%d %H:%M:%S" > ${STATE}/rolled-back; fi' >/dev/null 2>&1 &
|
||||
nohup setsid sh -c 'export PATH=$PATH:/usr/sbin:/sbin; sleep 2; (${be.apply}) >${STATE}/apply.log 2>&1; touch ${STATE}/applied; sleep ${ROLLBACK_SECONDS}; if [ -f ${STATE}/pending ]; then ${be.restore}; (${be.apply}) >>${STATE}/apply.log 2>&1; rm -f ${STATE}/pending; date "+%Y-%m-%d %H:%M:%S" > ${STATE}/rolled-back; fi' >/dev/null 2>&1 &
|
||||
echo started`;
|
||||
const r = await this.root(s, script);
|
||||
if (r.code === 4) throw new Error(i18n.t('The new configuration is invalid and was not applied: {err}', { err: lastLine(r.err) }));
|
||||
@@ -245,13 +247,14 @@ echo started`;
|
||||
while (Date.now() < deadline) {
|
||||
try {
|
||||
const { conn, jumps } = await this.ssh.connect(target, id);
|
||||
const c = await this.root(s, `rm -f ${STATE}/pending`, conn);
|
||||
if (c.code) { conn.end(); throw new Error(lastLine(c.err)); }
|
||||
// Erst bestätigen, wenn das Anwenden fertig ist: sonst reißt z. B. ein Bond-Neustart die neue Verbindung wieder ab
|
||||
const c = await this.root(s, `[ -f ${STATE}/applied ] || exit 7; rm -f ${STATE}/pending`, conn);
|
||||
if (c.code) { conn.on('error', () => {}); conn.end(); jumps?.forEach((x) => { try { x.end(); } catch {} }); throw new Error(lastLine(c.err) || 'not applied yet'); }
|
||||
// Neue Verbindung übernimmt die Sitzung
|
||||
s.replacing = true;
|
||||
try { s.conn.end(); } catch {}
|
||||
s.jumps?.forEach((x) => { try { x.end(); } catch {} });
|
||||
Object.assign(s, { conn, jumps, replacing: false });
|
||||
const old = { conn: s.conn, jumps: s.jumps };
|
||||
Object.assign(s, { conn, jumps });
|
||||
// Alte Verbindung ist nach dem IP-Wechsel meist tot: Fehler (z. B. Keepalive-Timeout) still verwerfen
|
||||
for (const c of [old.conn, ...(old.jumps || [])]) { c.on('error', () => {}); try { c.end(); } catch {} }
|
||||
if (verifyAddress) s.host = target;
|
||||
this.watch(id, s);
|
||||
return { confirmed: true };
|
||||
|
||||
Reference in New Issue
Block a user