1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 17:28:08 +00:00

Fix Can't delete link between docker VM after they were in use

Fix #818
This commit is contained in:
Julien Duponchelle 2016-12-14 12:01:34 +01:00
parent 30f29d00c4
commit d0f65aebff
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
7 changed files with 30 additions and 25 deletions

View File

@ -478,6 +478,8 @@ class BaseNode:
:returns: path to uBridge :returns: path to uBridge
""" """
if self._ubridge_hypervisor and not self._ubridge_hypervisor.is_running():
self._ubridge_hypervisor = None
return self._ubridge_hypervisor return self._ubridge_hypervisor
@ubridge.setter @ubridge.setter
@ -547,6 +549,7 @@ class BaseNode:
if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running():
log.info("Stopping uBridge hypervisor {}:{}".format(self._ubridge_hypervisor.host, self._ubridge_hypervisor.port)) log.info("Stopping uBridge hypervisor {}:{}".format(self._ubridge_hypervisor.host, self._ubridge_hypervisor.port))
yield from self._ubridge_hypervisor.stop() yield from self._ubridge_hypervisor.stop()
self._ubridge_hypervisor = None
@asyncio.coroutine @asyncio.coroutine
def _add_ubridge_udp_connection(self, bridge_name, source_nio, destination_nio): def _add_ubridge_udp_connection(self, bridge_name, source_nio, destination_nio):

View File

@ -704,7 +704,7 @@ class DockerVM(BaseNode):
raise DockerError("Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(name=self.name, raise DockerError("Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(name=self.name,
adapter_number=adapter_number)) adapter_number=adapter_number))
if self.status == "started" and self.ubridge and self.ubridge.is_running(): if self.status == "started" and self.ubridge:
# the container is running, let's add the UDP tunnel to connect to another node # the container is running, let's add the UDP tunnel to connect to another node
yield from self._ubridge_send('bridge create bridge{}'.format(adapter_number)) yield from self._ubridge_send('bridge create bridge{}'.format(adapter_number))
yield from self._ubridge_send('bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(ifc=adapter.host_ifc, adapter=adapter_number)) yield from self._ubridge_send('bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(ifc=adapter.host_ifc, adapter=adapter_number))
@ -716,7 +716,7 @@ class DockerVM(BaseNode):
yield from self._ubridge_send('bridge start bridge{adapter}'.format(adapter=adapter_number)) yield from self._ubridge_send('bridge start bridge{adapter}'.format(adapter=adapter_number))
if self.status == "started" and self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): if self.status == "started" and self.ubridge:
# the container is running, let's add the UDP tunnel to connect to another node # the container is running, let's add the UDP tunnel to connect to another node
yield from self._ubridge_hypervisor.send('bridge create bridge{}'.format(adapter_number)) yield from self._ubridge_hypervisor.send('bridge create bridge{}'.format(adapter_number))
yield from self._ubridge_hypervisor.send('bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(ifc=adapter.host_ifc, adapter=adapter_number)) yield from self._ubridge_hypervisor.send('bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(ifc=adapter.host_ifc, adapter=adapter_number))
@ -750,7 +750,7 @@ class DockerVM(BaseNode):
adapter_number=adapter_number)) adapter_number=adapter_number))
adapter.remove_nio(0) adapter.remove_nio(0)
if self.status == "started" and self.ubridge and self.ubridge.is_running(): if self.status == "started" and self.ubridge:
# the container is running, just delete the UDP tunnel so we can reconnect it later if needed # the container is running, just delete the UDP tunnel so we can reconnect it later if needed
yield from self._ubridge_send("bridge delete bridge{name}".format(name=adapter_number)) yield from self._ubridge_send("bridge delete bridge{name}".format(name=adapter_number))
else: else:
@ -825,7 +825,7 @@ class DockerVM(BaseNode):
""" """
adapter = "bridge{}".format(adapter_number) adapter = "bridge{}".format(adapter_number)
if not self._ubridge_hypervisor or not self._ubridge_hypervisor.is_running(): if not self.ubridge:
raise DockerError("Cannot start the packet capture: uBridge is not running") raise DockerError("Cannot start the packet capture: uBridge is not running")
yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name=adapter, output_file=output_file)) yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name=adapter, output_file=output_file))
@ -838,7 +838,7 @@ class DockerVM(BaseNode):
""" """
adapter = "bridge{}".format(adapter_number) adapter = "bridge{}".format(adapter_number)
if not self._ubridge_hypervisor or not self._ubridge_hypervisor.is_running(): if not self.ubridge:
raise DockerError("Cannot stop the packet capture: uBridge is not running") raise DockerError("Cannot stop the packet capture: uBridge is not running")
yield from self._ubridge_send("bridge stop_capture {name}".format(name=adapter)) yield from self._ubridge_send("bridge stop_capture {name}".format(name=adapter))
@ -867,7 +867,7 @@ class DockerVM(BaseNode):
nio.startPacketCapture(output_file) nio.startPacketCapture(output_file)
if self.status == "started" and self.ubridge and self.ubridge.is_running(): if self.status == "started" and self.ubridge:
yield from self._start_ubridge_capture(adapter_number, output_file) yield from self._start_ubridge_capture(adapter_number, output_file)
log.info("Docker VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(name=self.name, log.info("Docker VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(name=self.name,
@ -894,7 +894,7 @@ class DockerVM(BaseNode):
nio.stopPacketCapture() nio.stopPacketCapture()
if self.status == "started" and self.ubridge and self.ubridge.is_running(): if self.status == "started" and self.ubridge:
yield from self._stop_ubridge_capture(adapter_number) yield from self._stop_ubridge_capture(adapter_number)
log.info("Docker VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(name=self.name, log.info("Docker VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(name=self.name,

View File

@ -824,7 +824,7 @@ class IOUVM(BaseNode):
adapter_number=adapter_number, adapter_number=adapter_number,
port_number=port_number)) port_number=port_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512) bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
yield from self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name, yield from self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
iol_id=self.application_id, iol_id=self.application_id,
@ -864,7 +864,7 @@ class IOUVM(BaseNode):
adapter_number=adapter_number, adapter_number=adapter_number,
port_number=port_number)) port_number=port_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512) bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
yield from self._ubridge_send("iol_bridge delete_nio_udp {name} {bay} {unit}".format(name=bridge_name, yield from self._ubridge_send("iol_bridge delete_nio_udp {name} {bay} {unit}".format(name=bridge_name,
bay=adapter_number, bay=adapter_number,
@ -1157,7 +1157,7 @@ class IOUVM(BaseNode):
port_number=port_number, port_number=port_number,
output_file=output_file)) output_file=output_file))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512) bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
yield from self._ubridge_send('iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(name=bridge_name, yield from self._ubridge_send('iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(name=bridge_name,
bay=adapter_number, bay=adapter_number,
@ -1194,7 +1194,7 @@ class IOUVM(BaseNode):
id=self._id, id=self._id,
adapter_number=adapter_number, adapter_number=adapter_number,
port_number=port_number)) port_number=port_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512) bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
yield from self._ubridge_send('iol_bridge stop_capture {name} {bay} {unit}'.format(name=bridge_name, yield from self._ubridge_send('iol_bridge stop_capture {name} {bay} {unit}'.format(name=bridge_name,
bay=adapter_number, bay=adapter_number,

View File

@ -1124,7 +1124,7 @@ class QemuVM(BaseNode):
raise QemuError('Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(name=self._name, raise QemuError('Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(name=self._name,
adapter_number=adapter_number)) adapter_number=adapter_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._add_ubridge_udp_connection("QEMU-{}-{}".format(self._id, adapter_number), yield from self._add_ubridge_udp_connection("QEMU-{}-{}".format(self._id, adapter_number),
self._local_udp_tunnels[adapter_number][1], self._local_udp_tunnels[adapter_number][1],
nio) nio)
@ -1153,7 +1153,7 @@ class QemuVM(BaseNode):
raise QemuError('Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(name=self._name, raise QemuError('Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(name=self._name,
adapter_number=adapter_number)) adapter_number=adapter_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send("bridge delete {name}".format(name="QEMU-{}-{}".format(self._id, adapter_number))) yield from self._ubridge_send("bridge delete {name}".format(name="QEMU-{}-{}".format(self._id, adapter_number)))
elif self.is_running(): elif self.is_running():
raise QemuError("Sorry, removing a link to a started Qemu VM is not supported without using uBridge.") raise QemuError("Sorry, removing a link to a started Qemu VM is not supported without using uBridge.")
@ -1197,7 +1197,7 @@ class QemuVM(BaseNode):
nio.startPacketCapture(output_file) nio.startPacketCapture(output_file)
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="QEMU-{}-{}".format(self._id, adapter_number), yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="QEMU-{}-{}".format(self._id, adapter_number),
output_file=output_file)) output_file=output_file))
@ -1224,7 +1224,7 @@ class QemuVM(BaseNode):
nio.stopPacketCapture() nio.stopPacketCapture()
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send('bridge stop_capture {name}'.format(name="QEMU-{}-{}".format(self._id, adapter_number))) yield from self._ubridge_send('bridge stop_capture {name}'.format(name="QEMU-{}-{}".format(self._id, adapter_number)))
log.info("QEMU VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(name=self.name, log.info("QEMU VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(name=self.name,

View File

@ -932,7 +932,7 @@ class VirtualBoxVM(BaseNode):
raise VirtualBoxError("Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(name=self.name, raise VirtualBoxError("Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(name=self.name,
adapter_number=adapter_number)) adapter_number=adapter_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._add_ubridge_udp_connection("VBOX-{}-{}".format(self._id, adapter_number), yield from self._add_ubridge_udp_connection("VBOX-{}-{}".format(self._id, adapter_number),
self._local_udp_tunnels[adapter_number][1], self._local_udp_tunnels[adapter_number][1],
nio) nio)
@ -976,7 +976,7 @@ class VirtualBoxVM(BaseNode):
raise VirtualBoxError("Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(name=self.name, raise VirtualBoxError("Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(name=self.name,
adapter_number=adapter_number)) adapter_number=adapter_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send("bridge delete {name}".format(name="VBOX-{}-{}".format(self._id, adapter_number))) yield from self._ubridge_send("bridge delete {name}".format(name="VBOX-{}-{}".format(self._id, adapter_number)))
else: else:
vm_state = yield from self._get_vm_state() vm_state = yield from self._get_vm_state()
@ -1026,7 +1026,7 @@ class VirtualBoxVM(BaseNode):
nio.startPacketCapture(output_file) nio.startPacketCapture(output_file)
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="VBOX-{}-{}".format(self._id, adapter_number), yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="VBOX-{}-{}".format(self._id, adapter_number),
output_file=output_file)) output_file=output_file))
@ -1054,7 +1054,7 @@ class VirtualBoxVM(BaseNode):
nio.stopPacketCapture() nio.stopPacketCapture()
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send('bridge stop_capture {name}'.format(name="VBOX-{}-{}".format(self._id, adapter_number))) yield from self._ubridge_send('bridge stop_capture {name}'.format(name="VBOX-{}-{}".format(self._id, adapter_number)))
log.info("VirtualBox VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(name=self.name, log.info("VirtualBox VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(name=self.name,

View File

@ -375,7 +375,7 @@ class VPCSVM(BaseNode):
raise VPCSError("Port {port_number} doesn't exist in adapter {adapter}".format(adapter=self._ethernet_adapter, raise VPCSError("Port {port_number} doesn't exist in adapter {adapter}".format(adapter=self._ethernet_adapter,
port_number=port_number)) port_number=port_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._add_ubridge_udp_connection("VPCS-{}".format(self._id), self._local_udp_tunnel[1], nio) yield from self._add_ubridge_udp_connection("VPCS-{}".format(self._id), self._local_udp_tunnel[1], nio)
elif self.is_running(): elif self.is_running():
raise VPCSError("Sorry, adding a link to a started VPCS instance is not supported without using uBridge.") raise VPCSError("Sorry, adding a link to a started VPCS instance is not supported without using uBridge.")
@ -402,7 +402,7 @@ class VPCSVM(BaseNode):
raise VPCSError("Port {port_number} doesn't exist in adapter {adapter}".format(adapter=self._ethernet_adapter, raise VPCSError("Port {port_number} doesn't exist in adapter {adapter}".format(adapter=self._ethernet_adapter,
port_number=port_number)) port_number=port_number))
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send("bridge delete {name}".format(name="VPCS-{}".format(self._id))) yield from self._ubridge_send("bridge delete {name}".format(name="VPCS-{}".format(self._id)))
elif self.is_running(): elif self.is_running():
raise VPCSError("Sorry, adding a link to a started VPCS instance is not supported without using uBridge.") raise VPCSError("Sorry, adding a link to a started VPCS instance is not supported without using uBridge.")
@ -444,7 +444,7 @@ class VPCSVM(BaseNode):
nio.startPacketCapture(output_file) nio.startPacketCapture(output_file)
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="VPCS-{}".format(self._id), yield from self._ubridge_send('bridge start_capture {name} "{output_file}"'.format(name="VPCS-{}".format(self._id),
output_file=output_file)) output_file=output_file))
@ -471,7 +471,7 @@ class VPCSVM(BaseNode):
nio.stopPacketCapture() nio.stopPacketCapture()
if self.ubridge and self.ubridge.is_running(): if self.ubridge:
yield from self._ubridge_send('bridge stop_capture {name}'.format(name="VPCS-{}".format(self._id))) yield from self._ubridge_send('bridge stop_capture {name}'.format(name="VPCS-{}".format(self._id)))
log.info("VPCS '{name}' [{id}]: stopping packet capture on port {port_number}".format(name=self.name, log.info("VPCS '{name}' [{id}]: stopping packet capture on port {port_number}".format(name=self.name,

View File

@ -491,7 +491,8 @@ def test_restart(loop, vm):
def test_stop(loop, vm): def test_stop(loop, vm):
vm._ubridge_hypervisor = MagicMock() mock = MagicMock()
vm._ubridge_hypervisor = mock
vm._ubridge_hypervisor.is_running.return_value = True vm._ubridge_hypervisor.is_running.return_value = True
vm._fix_permissions = MagicMock() vm._fix_permissions = MagicMock()
@ -499,7 +500,8 @@ def test_stop(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query: with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
loop.run_until_complete(asyncio.async(vm.stop())) loop.run_until_complete(asyncio.async(vm.stop()))
mock_query.assert_called_with("POST", "containers/e90e34656842/stop", params={"t": 5}) mock_query.assert_called_with("POST", "containers/e90e34656842/stop", params={"t": 5})
assert vm._ubridge_hypervisor.stop.called assert mock.stop.called
assert vm._ubridge_hypervisor is None
assert vm._fix_permissions.called assert vm._fix_permissions.called