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:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user