sync: add cross-subsystem event bus for config consistency

Add EventBus with loop guards to keep firewall, dnsmasq, wireguard,
and network configs consistent. Handlers emit SyncEvent after mutations;
subscribers compute diffs and write JSON without manual cascade loops.
This commit is contained in:
2026-06-29 20:44:36 +00:00
parent 348bbfbca6
commit 9088f34345
15 changed files with 2117 additions and 59 deletions
+23 -2
View File
@@ -20,7 +20,7 @@ from daemon.iface import (
POST_NETWORK_INTERFACE_RELOAD,
POST_NETWORK_SYSCTL_SET,
)
from daemon.server import NotFoundError, registry
from daemon.server import NotFoundError, refresh_state, registry
from lib.common import run, validate_interface_name
from lib.dnsmasq import set_upstreams
from lib.network import (
@@ -34,6 +34,7 @@ from lib.network import (
render_network_file,
save_config,
)
from lib.sync import SyncEvent, bus
logger = logging.getLogger(__name__)
@@ -194,7 +195,17 @@ def save_interface(_request: Any, body: dict[str, Any] | None) -> dict[str, Any]
)
logger.info("Interface '%s' config saved (applied=%s)", name, deployed)
return {"name": name, "applied": deployed}
sync_result = bus.emit(
SyncEvent(
"network", "config_saved", {"action": "interface_saved", "interface": name}
)
)
refresh_state(["network", *sync_result.affected_subsystems])
return {
"name": name,
"applied": deployed,
"synced": sync_result.affected_subsystems,
}
@registry.register(POST_NETWORK_INTERFACE_RELOAD)
@@ -251,6 +262,11 @@ def apply_all(_request: Any, _body: Any) -> dict[str, Any]:
except Exception:
logger.warning("Failed to sync DNS upstreams to dnsmasq", exc_info=True)
sync_result = bus.emit(
SyncEvent("network", "config_saved", {"action": "config_applied"})
)
refresh_state(["network", *sync_result.affected_subsystems])
logger.info(
"Network config applied: %d interfaces, %d stale cleaned",
len(generated),
@@ -260,6 +276,7 @@ def apply_all(_request: Any, _body: Any) -> dict[str, Any]:
"applied": len(generated),
"files": [str(p) for p in generated],
"cleaned": [str(p) for p in cleaned],
"synced": sync_result.affected_subsystems,
}
@@ -311,4 +328,8 @@ def set_sysctl(_request: Any, body: dict[str, Any] | None) -> dict[str, Any]:
)
logger.info("sysctl %s set to %s", name, value)
sync_result = bus.emit(
SyncEvent("network", "config_saved", {"action": "sysctl_set", "name": name})
)
refresh_state(["network", *sync_result.affected_subsystems])
return {"name": name, "value": value}