refactor(marker): converge to filter single-path model, remove dual-apply endpoints

Markers now follow exactly the same apply pattern as packet filters:
state lives in Link._markers, application goes through NIO
(update() -> PUT /nio -> _ubridge_apply_markers). The former
immediate-apply REST endpoints (/markers/start, /markers/stop on
the compute side) and the per-node start_marker/stop_marker methods
are removed — they were a legacy of the original capture-inspired
design and have been superseded by the NIO flow.

Changes:
- controller/udp_link: start_marker/stop_marker/update_marker now
  set _markers state + call self.update() (mirrors update_filters).
  Removed _marker_capture_nodes runtime dict and its helpers.
- controller/project: _create_link_from_topology_data restores
  _markers directly from persisted data (with BPF validation,
  like filter reload). No long calls start_marker during load.
- compute: _ubridge_apply_markers swallows BPF compile errors
  (warn+skip), matching _ubridge_apply_filters behaviour so a
  single bad expression cannot break link creation / node restart.
- Removed: /markers/start,stop endpoints (6 handlers across
  vpcs/qemu/docker route files), node start_marker/stop_marker
  methods (3 VM files), _ubridge_delete_marker_filter,
  _marker_capture_nodes, MarkerDelete schema.

Net: ~280 lines of dead code removed; marker and packet filter now
share a single, unified apply path via the NIO.
This commit is contained in:
YueGuobin committed 2026-07-16 00:39:51 +08:00
1 parent 88c03d1431
commit c62b9b0283
11 files changed
+73 -412

No files matched your search

+12 -14
View File
@@ -1101,19 +1101,6 @@ class BaseNode:
# bad expression must surface instead of being silently dropped.
await self._ubridge_send(cmd)
async def _ubridge_delete_marker_filter(self, bridge_name, name):
"""
Remove a `mark` filter from a uBridge bridge.
uBridge closes and flushes the filter's pcap on delete; the file itself
persists on disk for later replay.
:param bridge_name: uBridge bridge the filter is attached to
:param name: filter name previously passed to _ubridge_add_marker_filter
"""
await self._ubridge_send(f"bridge delete_packet_filter {bridge_name} {name}")
async def _ubridge_apply_markers(self, bridge_name, nio):
"""
(Re-)apply every traffic-insight marker carried by *nio* to the uBridge
@@ -1137,7 +1124,18 @@ class BaseNode:
pcap_path = os.path.join(
markers_dir, f"{self._id}_{link_id}_{name}.pcap"
)
await self._ubridge_add_marker_filter(bridge_name, name, bpf, pcap_path, tag)
try:
await self._ubridge_add_marker_filter(bridge_name, name, bpf, pcap_path, tag)
except UbridgeError as e:
# Swallow BPF compile errors (warn + skip) so a single bad
# expression can't break link creation / node restart — mirrors
# _ubridge_apply_filters, which does the same for packet filters.
if "syntax error" in str(e).lower() or "compile filter" in str(e).lower():
message = f"Warning: ignoring marker '{name}' due to BPF syntax error: {e}"
log.warning(message)
self.project.emit("log.warning", {"message": message})
continue
raise
manager.register(
str(self.project.id), self._id, name, link_id, tag
)