diff --git a/gns3server/modules/base_vm.py b/gns3server/modules/base_vm.py index 6a3f29c1..67db308a 100644 --- a/gns3server/modules/base_vm.py +++ b/gns3server/modules/base_vm.py @@ -47,9 +47,9 @@ class BaseVM: self._console = console if self._console is not None: - self._console = self._manager.port_manager.reserve_console_port(self._console) + self._console = self._manager.port_manager.reserve_tcp_port(self._console) else: - self._console = self._manager.port_manager.get_free_console_port() + self._console = self._manager.port_manager.get_free_tcp_port() log.debug("{module}: {name} [{id}] initialized. Console port {console}".format( module=self.manager.module_name, @@ -188,8 +188,8 @@ class BaseVM: if console == self._console: return if self._console: - self._manager.port_manager.release_console_port(self._console) - self._console = self._manager.port_manager.reserve_console_port(console) + self._manager.port_manager.release_tcp_port(self._console) + self._console = self._manager.port_manager.reserve_tcp_port(console) log.info("{module}: '{name}' [{id}]: console port set to {port}".format( module=self.manager.module_name, name=self.name, diff --git a/gns3server/modules/dynamips/nodes/router.py b/gns3server/modules/dynamips/nodes/router.py index a94f4af5..eb16c275 100644 --- a/gns3server/modules/dynamips/nodes/router.py +++ b/gns3server/modules/dynamips/nodes/router.py @@ -106,11 +106,15 @@ class Router(BaseVM): self._dynamips_ids[project.id].append(self._dynamips_id) if self._aux is not None: - self._aux = self._manager.port_manager.reserve_console_port(self._aux) + self._aux = self._manager.port_manager.reserve_tcp_port(self._aux) else: - self._aux = self._manager.port_manager.get_free_console_port() + self._aux = self._manager.port_manager.get_free_tcp_port() else: log.info("Creating a new ghost IOS instance") + if self._console: + # Ghost VMs do not need a console port. + self._manager.port_manager.release_tcp_port(self._console) + self._console = None self._dynamips_id = 0 self._name = "Ghost" @@ -320,11 +324,11 @@ class Router(BaseVM): yield from self.hypervisor.stop() if self._console: - self._manager.port_manager.release_console_port(self._console) + self._manager.port_manager.release_tcp_port(self._console) self._console = None if self._aux: - self._manager.port_manager.release_console_port(self._aux) + self._manager.port_manager.release_tcp_port(self._aux) self._aux = None self._closed = True @@ -873,8 +877,8 @@ class Router(BaseVM): old_console=self._console, new_console=console)) - self._manager.port_manager.release_console_port(self._console) - self._console = self._manager.port_manager.reserve_console_port(console) + self._manager.port_manager.release_tcp_port(self._console) + self._console = self._manager.port_manager.reserve_tcp_port(console) @property def aux(self): @@ -901,8 +905,8 @@ class Router(BaseVM): old_aux=self._aux, new_aux=aux)) - self._manager.port_manager.release_console_port(self._aux) - self._aux = self._manager.port_manager.reserve_console_port(aux) + self._manager.port_manager.release_tcp_port(self._aux) + self._aux = self._manager.port_manager.reserve_tcp_port(aux) @asyncio.coroutine def get_cpu_usage(self, cpu_id=0): diff --git a/gns3server/modules/iou/iou_vm.py b/gns3server/modules/iou/iou_vm.py index 7751cd3e..1ab6302d 100644 --- a/gns3server/modules/iou/iou_vm.py +++ b/gns3server/modules/iou/iou_vm.py @@ -106,7 +106,7 @@ class IOUVM(BaseVM): yield from self.stop() if self._console: - self._manager.port_manager.release_console_port(self._console) + self._manager.port_manager.release_tcp_port(self._console) self._console = None @property diff --git a/gns3server/modules/port_manager.py b/gns3server/modules/port_manager.py index da448cd6..79b8b6eb 100644 --- a/gns3server/modules/port_manager.py +++ b/gns3server/modules/port_manager.py @@ -116,6 +116,16 @@ class PortManager: assert isinstance(new_range, tuple) self._udp_port_range = new_range + @property + def tcp_ports(self): + + return self._used_tcp_ports + + @property + def udp_ports(self): + + return self._used_udp_ports + @staticmethod def find_unused_port(start_port, end_port, host="127.0.0.1", socket_type="TCP", ignore_ports=[]): """ @@ -163,9 +173,9 @@ class PortManager: host, last_exception)) - def get_free_console_port(self): + def get_free_tcp_port(self): """ - Get an available TCP console port and reserve it + Get an available TCP port and reserve it """ port = self.find_unused_port(self._console_port_range[0], @@ -175,11 +185,12 @@ class PortManager: ignore_ports=self._used_tcp_ports) self._used_tcp_ports.add(port) + log.debug("TCP port {} has been allocated".format(port)) return port - def reserve_console_port(self, port): + def reserve_tcp_port(self, port): """ - Reserve a specific TCP console port number + Reserve a specific TCP port number :param port: TCP port number """ @@ -187,17 +198,19 @@ class PortManager: if port in self._used_tcp_ports: raise HTTPConflict(text="TCP port {} already in use on host".format(port, self._console_host)) self._used_tcp_ports.add(port) + log.debug("TCP port {} has been reserved".format(port)) return port - def release_console_port(self, port): + def release_tcp_port(self, port): """ - Release a specific TCP console port number + Release a specific TCP port number :param port: TCP port number """ if port in self._used_tcp_ports: self._used_tcp_ports.remove(port) + log.debug("TCP port {} has been released".format(port)) def get_free_udp_port(self): """ @@ -211,6 +224,7 @@ class PortManager: ignore_ports=self._used_udp_ports) self._used_udp_ports.add(port) + log.debug("UDP port {} has been allocated".format(port)) return port def reserve_udp_port(self, port): @@ -223,6 +237,7 @@ class PortManager: if port in self._used_udp_ports: raise HTTPConflict(text="UDP port {} already in use on host".format(port, self._console_host)) self._used_udp_ports.add(port) + log.debug("UDP port {} has been reserved".format(port)) def release_udp_port(self, port): """ @@ -233,3 +248,4 @@ class PortManager: if port in self._used_udp_ports: self._used_udp_ports.remove(port) + log.debug("UDP port {} has been released".format(port)) diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index 829bbfe7..0e89a4ef 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -97,9 +97,9 @@ class QemuVM(BaseVM): self._process_priority = "low" if self._monitor is not None: - self._monitor = self._manager.port_manager.reserve_console_port(self._monitor) + self._monitor = self._manager.port_manager.reserve_tcp_port(self._monitor) else: - self._monitor = self._manager.port_manager.get_free_console_port() + self._monitor = self._manager.port_manager.get_free_tcp_port() self.adapters = 1 # creates 1 adapter by default log.info("QEMU VM {name} [id={id}] has been created".format(name=self._name, @@ -649,10 +649,10 @@ class QemuVM(BaseVM): yield from self.stop() if self._console: - self._manager.port_manager.release_console_port(self._console) + self._manager.port_manager.release_tcp_port(self._console) self._console = None if self._monitor: - self._manager.port_manager.release_console_port(self._monitor) + self._manager.port_manager.release_tcp_port(self._monitor) self._monitor = None @asyncio.coroutine diff --git a/gns3server/modules/virtualbox/virtualbox_vm.py b/gns3server/modules/virtualbox/virtualbox_vm.py index 708aa6ec..4b77b090 100644 --- a/gns3server/modules/virtualbox/virtualbox_vm.py +++ b/gns3server/modules/virtualbox/virtualbox_vm.py @@ -299,7 +299,7 @@ class VirtualBoxVM(BaseVM): yield from self.stop() if self._console: - self._manager.port_manager.release_console_port(self._console) + self._manager.port_manager.release_tcp_port(self._console) self._console = None if self._linked_clone: diff --git a/gns3server/modules/vpcs/vpcs_vm.py b/gns3server/modules/vpcs/vpcs_vm.py index 6bd5a4ba..52c1736e 100644 --- a/gns3server/modules/vpcs/vpcs_vm.py +++ b/gns3server/modules/vpcs/vpcs_vm.py @@ -72,7 +72,7 @@ class VPCSVM(BaseVM): self._terminate_process() if self._console: - self._manager.port_manager.release_console_port(self._console) + self._manager.port_manager.release_tcp_port(self._console) self._console = None @asyncio.coroutine diff --git a/gns3server/server.py b/gns3server/server.py index cb8d5b7f..13b76f3d 100644 --- a/gns3server/server.py +++ b/gns3server/server.py @@ -72,6 +72,13 @@ class Server: log.debug("Unloading module {}".format(module.__name__)) m = module.instance() yield from m.unload() + + if self._port_manager.tcp_ports: + log.warning("TCP ports are still used {}".format(self._port_manager.tcp_ports)) + + if self._port_manager.udp_ports: + log.warning("UDP ports are still used {}".format(self._port_manager.udp_ports)) + self._loop.stop() def _signal_handling(self, handler): diff --git a/tests/conftest.py b/tests/conftest.py index 51b5cee6..a64d9535 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -116,10 +116,10 @@ def free_console_port(request, port_manager): """Get a free TCP port""" # In case of already use ports we will raise an exception - port = port_manager.get_free_console_port() + port = port_manager.get_free_tcp_port() # We release the port immediately in order to allow # the test do whatever the test want - port_manager.release_console_port(port) + port_manager.release_tcp_port(port) return port diff --git a/tests/modules/iou/test_iou_vm.py b/tests/modules/iou/test_iou_vm.py index 6b1f976f..4ee16327 100644 --- a/tests/modules/iou/test_iou_vm.py +++ b/tests/modules/iou/test_iou_vm.py @@ -165,7 +165,7 @@ def test_close(vm, port_manager, loop): port = vm.console loop.run_until_complete(asyncio.async(vm.close())) # Raise an exception if the port is not free - port_manager.reserve_console_port(port) + port_manager.reserve_tcp_port(port) assert vm.is_running() is False diff --git a/tests/modules/qemu/test_qemu_vm.py b/tests/modules/qemu/test_qemu_vm.py index fe0f8cd4..1cc9596e 100644 --- a/tests/modules/qemu/test_qemu_vm.py +++ b/tests/modules/qemu/test_qemu_vm.py @@ -138,9 +138,9 @@ def test_close(vm, port_manager, loop): loop.run_until_complete(asyncio.async(vm.close())) # Raise an exception if the port is not free - port_manager.reserve_console_port(console_port) + port_manager.reserve_tcp_port(console_port) # Raise an exception if the port is not free - port_manager.reserve_console_port(monitor_port) + port_manager.reserve_tcp_port(monitor_port) assert vm.is_running() is False diff --git a/tests/modules/test_port_manager.py b/tests/modules/test_port_manager.py index 06735272..7b2f9193 100644 --- a/tests/modules/test_port_manager.py +++ b/tests/modules/test_port_manager.py @@ -20,8 +20,8 @@ import pytest from gns3server.modules.port_manager import PortManager -def test_reserve_console_port(): +def test_reserve_tcp_port(): pm = PortManager() - pm.reserve_console_port(4242) + pm.reserve_tcp_port(4242) with pytest.raises(aiohttp.web.HTTPConflict): - pm.reserve_console_port(4242) + pm.reserve_tcp_port(4242) diff --git a/tests/modules/vpcs/test_vpcs_vm.py b/tests/modules/vpcs/test_vpcs_vm.py index 990a386e..0ac186f7 100644 --- a/tests/modules/vpcs/test_vpcs_vm.py +++ b/tests/modules/vpcs/test_vpcs_vm.py @@ -191,14 +191,14 @@ def test_get_startup_script_using_default_script(vm): def test_change_console_port(vm, port_manager): - port1 = port_manager.get_free_console_port() - port2 = port_manager.get_free_console_port() - port_manager.release_console_port(port1) - port_manager.release_console_port(port2) + port1 = port_manager.get_free_tcp_port() + port2 = port_manager.get_free_tcp_port() + port_manager.release_tcp_port(port1) + port_manager.release_tcp_port(port2) vm.console = port1 vm.console = port2 assert vm.console == port2 - port_manager.reserve_console_port(port1) + port_manager.reserve_tcp_port(port1) def test_change_name(vm, tmpdir): @@ -219,5 +219,5 @@ def test_close(vm, port_manager, loop): port = vm.console loop.run_until_complete(asyncio.async(vm.close())) # Raise an exception if the port is not free - port_manager.reserve_console_port(port) + port_manager.reserve_tcp_port(port) assert vm.is_running() is False