Catch more specific exception in compute manager

Currently in compute manager, we simply treat all the exception
as general 'Exception', we should catch more specific exception.

Change-Id: Id20c663eed308f1c0d94b3528f3694ad8c532226
This commit is contained in:
Wenzhi Yu 2016-08-29 21:38:39 +08:00
parent 4b389bc03b
commit 6983c1f88f
3 changed files with 123 additions and 35 deletions

View File

@ -345,3 +345,7 @@ class ContainerRunningException(ZunException):
message = _("The container %(id)s is running."
"Please stop and delete the container.")
code = 409
class DockerError(ZunException):
message = _("Docker internal error: %(error_msg)s.")

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from oslo_log import log as logging
from zun.common import exception
@ -32,6 +34,11 @@ class Manager(object):
super(Manager, self).__init__()
self.driver = driver.load_container_driver(container_driver)
def _fail_container(self, container):
container.status = fields.ContainerStatus.ERROR
container.task_state = None
container.save()
def container_create(self, context, container):
utils.spawn_n(self._do_container_create, context, container)
@ -43,21 +50,26 @@ class Manager(object):
container.save()
try:
self.driver.pull_image(container.image)
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
self._fail_container(container)
return
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
container.status = fields.ContainerStatus.ERROR
container.task_state = None
container.save()
self._fail_container(container)
return
container.task_state = fields.TaskState.CONTAINER_CREATING
container.save()
try:
container = self.driver.create(container)
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
container.status = fields.ContainerStatus.ERROR
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
if not isinstance(e, exception.ZunException):
e = exception.ZunException("Unexpected Error: %s" % str(e))
container.status = fields.ContainerStatus.ERROR
finally:
container.task_state = None
@ -70,6 +82,10 @@ class Manager(object):
try:
self.driver.delete(container)
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
if e.response.status_code == 409:
@ -82,6 +98,10 @@ class Manager(object):
LOG.debug('Listing container...', context=context)
try:
return self.driver.list()
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -94,6 +114,10 @@ class Manager(object):
container = self.driver.show(container)
container.save()
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -106,6 +130,10 @@ class Manager(object):
container = self.driver.reboot(container)
container.save()
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -118,6 +146,10 @@ class Manager(object):
container = self.driver.stop(container)
container.save()
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -130,6 +162,10 @@ class Manager(object):
container = self.driver.start(container)
container.save()
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -142,6 +178,10 @@ class Manager(object):
container = self.driver.pause(container)
container.save()
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s,"), str(e))
raise e
@ -154,6 +194,10 @@ class Manager(object):
container = self.driver.unpause(container)
container.save()
return container
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -164,6 +208,10 @@ class Manager(object):
container=container)
try:
return self.driver.show_logs(container)
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e
@ -175,6 +223,10 @@ class Manager(object):
container=container)
try:
return self.driver.execute(container, command)
except exception.DockerError as e:
LOG.error(_LE("Error occured while calling docker API: %s"),
six.text_type(e))
raise e
except Exception as e:
LOG.exception(_LE("Unexpected exception: %s"), str(e))
raise e

View File

@ -17,6 +17,7 @@ import six
from oslo_config import cfg
from oslo_log import log as logging
from zun.common import exception
from zun.common.utils import check_container_id
from zun.container.docker import utils as docker_utils
from zun.container import driver
@ -37,7 +38,10 @@ class DockerDriver(driver.ContainerDriver):
with docker_utils.docker_client() as docker:
LOG.debug('Pulling image %s' % image)
image_repo, image_tag = docker_utils.parse_docker_image(image)
try:
docker.pull(image_repo, tag=image_tag)
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
def create(self, container):
with docker_utils.docker_client() as docker:
@ -63,18 +67,24 @@ class DockerDriver(driver.ContainerDriver):
except errors.APIError as e:
container.status = fields.ContainerStatus.ERROR
container.status_reason = six.text_type(e)
raise
raise exception.DockerError(error_msg=six.text_type(e))
container.save()
return container
def delete(self, container):
with docker_utils.docker_client() as docker:
try:
if container.container_id:
docker.remove_container(container.container_id)
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
def list(self):
with docker_utils.docker_client() as docker:
try:
return docker.list_instances()
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
def show(self, container):
with docker_utils.docker_client() as docker:
@ -88,7 +98,7 @@ class DockerDriver(driver.ContainerDriver):
if '404' in str(api_error):
container.status = fields.ContainerStatus.ERROR
return container
raise
raise exception.DockerError(error_msg=six.text_type(api_error))
status = result.get('State')
if status:
@ -105,54 +115,76 @@ class DockerDriver(driver.ContainerDriver):
@check_container_id
def reboot(self, container):
with docker_utils.docker_client() as docker:
try:
docker.restart(container.container_id)
container.status = fields.ContainerStatus.RUNNING
return container
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
@check_container_id
def stop(self, container):
with docker_utils.docker_client() as docker:
try:
docker.stop(container.container_id)
container.status = fields.ContainerStatus.STOPPED
return container
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
@check_container_id
def start(self, container):
with docker_utils.docker_client() as docker:
try:
docker.start(container.container_id)
container.status = fields.ContainerStatus.RUNNING
return container
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
@check_container_id
def pause(self, container):
with docker_utils.docker_client() as docker:
try:
docker.pause(container.container_id)
container.status = fields.ContainerStatus.PAUSED
return container
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
@check_container_id
def unpause(self, container):
with docker_utils.docker_client() as docker:
try:
docker.unpause(container.container_id)
container.status = fields.ContainerStatus.RUNNING
return container
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
@check_container_id
def show_logs(self, container):
with docker_utils.docker_client() as docker:
try:
return docker.get_container_logs(container.container_id)
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
@check_container_id
def execute(self, container, command):
with docker_utils.docker_client() as docker:
try:
if docker_utils.is_docker_library_version_atleast('1.2.0'):
create_res = docker.exec_create(
container.container_id, command, True, True, False)
exec_output = docker.exec_start(create_res, False, False,
False)
else:
exec_output = docker.execute(container.container_id, command)
exec_output = docker.execute(
container.container_id, command)
return exec_output
except errors.APIError as e:
raise exception.DockerError(error_msg=six.text_type(e))
def _encode_utf8(self, value):
if six.PY2 and not isinstance(value, unicode):