From 061b459abe603c404aac45cfbe7e06c50d463d40 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Tue, 29 Dec 2015 12:40:22 +0100 Subject: [PATCH] Prevent error when quick close of gns3 server after docker usage Fix #382 --- gns3server/modules/docker/__init__.py | 3 ++ gns3server/modules/docker/docker_vm.py | 67 +++++++++++++++----------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/gns3server/modules/docker/__init__.py b/gns3server/modules/docker/__init__.py index f835aef6..56a6f48c 100644 --- a/gns3server/modules/docker/__init__.py +++ b/gns3server/modules/docker/__init__.py @@ -44,6 +44,9 @@ class Docker(BaseManager): # Allow locking during ubridge operations self.ubridge_lock = asyncio.Lock() + def __del__(self): + self._connector.close() + @asyncio.coroutine def query(self, method, path, data={}, params={}): """ diff --git a/gns3server/modules/docker/docker_vm.py b/gns3server/modules/docker/docker_vm.py index 6e803764..fce53c35 100644 --- a/gns3server/modules/docker/docker_vm.py +++ b/gns3server/modules/docker/docker_vm.py @@ -248,20 +248,25 @@ class DockerVM(BaseVM): def stop(self): """Stops this Docker container.""" - if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): - yield from self._ubridge_hypervisor.stop() + try: + if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): + yield from self._ubridge_hypervisor.stop() - state = yield from self._get_container_state() - if state == "paused": - yield from self.unpause() + state = yield from self._get_container_state() + if state == "paused": + yield from self.unpause() - if self._telnet_server: - self._telnet_server.close() - self._telnet_server = None - # t=5 number of seconds to wait before killing the container - yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5}) - log.info("Docker container '{name}' [{image}] stopped".format( - name=self._name, image=self._image)) + if self._telnet_server: + self._telnet_server.close() + self._telnet_server = None + # t=5 number of seconds to wait before killing the container + yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5}) + log.info("Docker container '{name}' [{image}] stopped".format( + name=self._name, image=self._image)) + # Ignore runtime error because when closing the server + except RuntimeError as e: + log.debug("Docker runtime error when closing: {}".format(str(e))) + return @asyncio.coroutine def pause(self): @@ -282,24 +287,30 @@ class DockerVM(BaseVM): @asyncio.coroutine def remove(self): """Removes this Docker container.""" - state = yield from self._get_container_state() - if state == "paused": - yield from self.unpause() - if state == "running": - yield from self.stop() - yield from self.manager.query("DELETE", "containers/{}".format(self._cid), params={"force": 1}) - log.info("Docker container '{name}' [{image}] removed".format( - name=self._name, image=self._image)) - if self._console: - self._manager.port_manager.release_tcp_port(self._console, self._project) - self._console = None + try: + state = yield from self._get_container_state() + if state == "paused": + yield from self.unpause() + if state == "running": + yield from self.stop() + yield from self.manager.query("DELETE", "containers/{}".format(self._cid), params={"force": 1}) + log.info("Docker container '{name}' [{image}] removed".format( + name=self._name, image=self._image)) - for adapter in self._ethernet_adapters: - if adapter is not None: - for nio in adapter.ports.values(): - if nio and isinstance(nio, NIOUDP): - self.manager.port_manager.release_udp_port(nio.lport, self._project) + if self._console: + self._manager.port_manager.release_tcp_port(self._console, self._project) + self._console = None + + for adapter in self._ethernet_adapters: + if adapter is not None: + for nio in adapter.ports.values(): + if nio and isinstance(nio, NIOUDP): + self.manager.port_manager.release_udp_port(nio.lport, self._project) + # Ignore runtime error because when closing the server + except RuntimeError as e: + log.debug("Docker runtime error when closing: {}".format(str(e))) + return @asyncio.coroutine def close(self):