forked from kay/RouterOS
Wizard: idempotenter WAN-Apply fuer DHCP-Client/PPPoE (Bug 21)
Wizard erneut auf einem Interface durchlaufen, das schon einen DHCP-Client hat (hier: aus einer zurueckgespielten Sicherung), scheiterte live mit "failure: dhcp-client on that interface already exists" - WanConfig.buildCommands() erzeugt fuer DHCP-Client/PPPoE immer .add, ohne vorher zu pruefen, ob auf dem Interface schon einer existiert. Fix: SetupViewModel.applyIdempotently faengt einen .add-Fehlschlag auf /ip dhcp-client bzw. /interface pppoe-client ab und wiederholt ihn als .set (nach "interface" gematcht) - bewusst nur fuer diese zwei Menues mit "maximal ein Eintrag pro Interface"-Semantik, nicht generell fuer jedes .add (z.B. /ip address erlaubt legitim mehrere Adressen pro Interface). Gefunden beim Versuch, M8 (Netzwerk-Isolation) live durchzutesten - dieser Test selbst ist noch nicht abgeschlossen, naechste Session dort weitermachen (siehe HANDOFF.md Naechste Schritte Punkt 1). HANDOFF.md/CHATLOG.md aktualisiert: Bug 21, Sessionende-Stand. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CTgRxJTzaQwaRkngbaE1GJ
This commit is contained in:
@@ -213,7 +213,7 @@ final class SetupViewModel: ObservableObject {
|
||||
|
||||
for command in plannedCommands {
|
||||
applyLog.append(command.summary)
|
||||
try await connectionService.apply(command)
|
||||
try await applyIdempotently(command)
|
||||
}
|
||||
|
||||
didApplySuccessfully = true
|
||||
@@ -223,4 +223,36 @@ final class SetupViewModel: ObservableObject {
|
||||
isApplying = false
|
||||
}
|
||||
}
|
||||
|
||||
/// RouterOS allows at most one item per interface on some menus (a DHCP client, a PPPoE
|
||||
/// client) — re-running the wizard's WAN step on an interface that already has one makes the
|
||||
/// wizard's own `.add` fail live-confirmed: "failure: dhcp-client on that interface already
|
||||
/// exists". Rather than hard-fail the whole apply here, retry once as a `.set` matched by
|
||||
/// "interface" instead — reconfigures the existing entry in place, which is what re-running
|
||||
/// the wizard on the same interface should mean anyway. Scoped to exactly these two
|
||||
/// known-unique-per-interface menus, not applied generally to every `.add` — other menus
|
||||
/// (e.g. "/ip address") legitimately allow multiple items per interface, where silently
|
||||
/// converting a would-be-duplicate `.add` into a `.set` would be wrong, not helpful.
|
||||
private static let interfaceUniqueMenuPaths: Set<String> = ["/ip dhcp-client", "/interface pppoe-client"]
|
||||
|
||||
private func applyIdempotently(_ command: RouterOSCommand) async throws {
|
||||
do {
|
||||
try await connectionService.apply(command)
|
||||
} catch {
|
||||
guard case .add = command.operation,
|
||||
Self.interfaceUniqueMenuPaths.contains(command.menuPath),
|
||||
let interfaceName = command.arguments["interface"] else {
|
||||
throw error
|
||||
}
|
||||
let retryCommand = RouterOSCommand.set(
|
||||
menuPath: command.menuPath,
|
||||
restPath: command.restPath,
|
||||
matchField: "interface",
|
||||
matchValue: interfaceName,
|
||||
arguments: command.arguments,
|
||||
summary: command.summary
|
||||
)
|
||||
try await connectionService.apply(retryCommand)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user