diff --git a/zun/common/nova.py b/zun/common/nova.py index b2f7cc33f..2ab521f55 100644 --- a/zun/common/nova.py +++ b/zun/common/nova.py @@ -190,6 +190,12 @@ class NovaClient(object): self.client().servers.delete(server_id) return server_id + def stop_server(self, server): + server_id = self.get_server_id(server, raise_on_error=False) + if server_id: + self.client().servers.stop(server_id) + return server_id + def check_delete_server_complete(self, server_id): """Wait for server to disappear from Nova.""" try: diff --git a/zun/compute/manager.py b/zun/compute/manager.py index 3fbec9ac3..632b2aece 100644 --- a/zun/compute/manager.py +++ b/zun/compute/manager.py @@ -73,6 +73,13 @@ class Manager(object): reraise=True) return self._do_container_start(context, created_container) + def _do_sandbox_cleanup(self, context, sandbox_id): + try: + self.driver.delete_sandbox(context, sandbox_id) + except Exception as e: + LOG.error(_LE("Error occured while deleting sandbox: %s"), + six.text_type(e)) + def _do_container_create(self, context, container, reraise=False): LOG.debug('Creating container...', context=context, container=container) @@ -105,6 +112,7 @@ class Manager(object): except exception.ImageNotFound as e: with excutils.save_and_reraise_exception(reraise=reraise): LOG.error(six.text_type(e)) + self._do_sandbox_cleanup(context, sandbox_id) self._fail_container(container, six.text_type(e)) return except exception.DockerError as e: @@ -112,12 +120,14 @@ class Manager(object): LOG.error(_LE( "Error occured while calling docker image API: %s"), six.text_type(e)) + self._do_sandbox_cleanup(context, sandbox_id) self._fail_container(container, six.text_type(e)) return except Exception as e: with excutils.save_and_reraise_exception(reraise=reraise): LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e)) + self._do_sandbox_cleanup(context, sandbox_id) self._fail_container(container, six.text_type(e)) return @@ -135,12 +145,14 @@ class Manager(object): LOG.error(_LE( "Error occured while calling docker create API: %s"), six.text_type(e)) + self._do_sandbox_cleanup(context, sandbox_id) self._fail_container(container, six.text_type(e)) return except Exception as e: with excutils.save_and_reraise_exception(reraise=reraise): LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e)) + self._do_sandbox_cleanup(context, sandbox_id) self._fail_container(container, six.text_type(e)) return diff --git a/zun/container/docker/driver.py b/zun/container/docker/driver.py index 50b96a03a..7aeb22994 100644 --- a/zun/container/docker/driver.py +++ b/zun/container/docker/driver.py @@ -230,6 +230,10 @@ class DockerDriver(driver.ContainerDriver): with docker_utils.docker_client() as docker: docker.remove_container(sandbox_id, force=True) + def stop_sandbox(self, context, sandbox_id): + with docker_utils.docker_client() as docker: + docker.stop(sandbox_id) + def get_sandbox_id(self, container): if container.meta: return container.meta.get('sandbox_id', None) @@ -301,6 +305,15 @@ class NovaDockerDriver(DockerDriver): server_id = novaclient.delete_server(server_name) self._ensure_deleted(novaclient, server_id) + def stop_sandbox(self, context, sandbox_id): + novaclient = nova.NovaClient(context) + server_name = self._find_server_by_container_id(sandbox_id) + if not server_name: + LOG.warning(_LW("Cannot find server name for sandbox %s") % + sandbox_id) + return + novaclient.stop_server(server_name) + def _ensure_deleted(self, novaclient, server_id, timeout=300): '''Wait until the Nova instance to be deleted.''' def _check_delete_complete(): diff --git a/zun/container/driver.py b/zun/container/driver.py index 7dd5d2469..dd3a1d657 100644 --- a/zun/container/driver.py +++ b/zun/container/driver.py @@ -114,6 +114,12 @@ class ContainerDriver(object): """Delete a sandbox.""" raise NotImplementedError() + # Note: This is not currently used, but + # may be used later + def stop_sandbox(self, context, sandbox_id): + """Stop a sandbox.""" + raise NotImplementedError() + def get_sandbox_id(self, container): """Retrieve sandbox ID.""" raise NotImplementedError()