mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
fix(docker): delete the per-link kernel bridge when a node stops
The bridge teardown only hung off the link-removal path, but deleting a
node or closing a project never issues a per-link delete — the veths
disappeared with their containers and left the bridge behind as an empty
orphan (reproduced: create a kernel link, DELETE the project, the
gns3{link_id} bridge survives). `_remove_kernel_veths` now deletes the
node's kernel-NIO bridges alongside the veth host ends: both endpoints do
it, the peer's still-enslaved port answers EBUSY (suppressed, last one
wins) exactly like link deletion, a relay NIO's uBridge bridge is left
alone (it dies with the process), and a node restart rebuilds the bridge
from the NIO in _connect_nio.
Found while cleaning up the window_drop e2e: seven such bridges had
accumulated on this host. Re-verified live: the bridge is gone after the
project delete, and the window_drop e2e (which includes a node restart
with the kernel link attached) still passes 15/15.
This commit is contained in:
3 files changed
+48
-1
No files matched your search
@@ -1883,12 +1883,25 @@ class DockerVM(BaseNode):
|
||||
with the container network namespace) the host end outlives the
|
||||
container and must be removed explicitly. Deleting an enslaved veth
|
||||
detaches it from its bridge automatically.
|
||||
|
||||
The per-link kernel bridges go too: deleting a node (or closing a
|
||||
project) never runs the link-teardown path, so a bridge whose ports
|
||||
just disappeared would stay behind as an empty orphan. Both link
|
||||
endpoints run this — the peer's port still enslaved makes the delete
|
||||
fail with EBUSY (suppressed) and the last one wins, the same
|
||||
contract as _remove_kernel_nio. A node restart re-creates the bridge
|
||||
from the NIO in _connect_nio, so nothing is lost by deleting it.
|
||||
"""
|
||||
|
||||
if self.ubridge:
|
||||
for host_ifc in self._kernel_veths.values():
|
||||
with contextlib.suppress(UbridgeError):
|
||||
await self._ubridge_send(f'docker delete_veth "{host_ifc}"')
|
||||
for adapter in self._ethernet_adapters:
|
||||
for nio in adapter.ports.values():
|
||||
if isinstance(nio, NIOBridge):
|
||||
with contextlib.suppress(UbridgeError):
|
||||
await self._ubridge_send(f'brctl delete "{nio.bridge}"')
|
||||
self._kernel_veths.clear()
|
||||
|
||||
async def _get_namespace(self):
|
||||
|
||||
Reference in new issue
Block a user