summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Tomecek <ttomecek@redhat.com>2016-04-21 14:03:02 +0200
committerTomas Tomecek <ttomecek@redhat.com>2016-07-11 10:45:27 +0200
commitfea970dff3df60c7579eb06959444160a570927e (patch)
treedc7f17aa1fe4d92ee57f98bc5711a2c5826fe7e3
parentc3fd6a8f4d4388316499d89a38afbb4e34346ce7 (diff)
service: detailed error messages for create and start
Fixes: #3355 Signed-off-by: Tomas Tomecek <ttomecek@redhat.com>
-rw-r--r--compose/cli/main.py4
-rw-r--r--compose/errors.py7
-rw-r--r--compose/parallel.py4
-rw-r--r--compose/service.py12
-rw-r--r--tests/integration/service_test.py5
5 files changed, 28 insertions, 4 deletions
diff --git a/compose/cli/main.py b/compose/cli/main.py
index c924d89d..ed15d6a5 100644
--- a/compose/cli/main.py
+++ b/compose/cli/main.py
@@ -32,6 +32,7 @@ from ..service import BuildError
from ..service import ConvergenceStrategy
from ..service import ImageType
from ..service import NeedsBuildError
+from ..service import OperationFailedError
from .command import get_config_from_options
from .command import project_from_options
from .docopt_command import DocoptDispatcher
@@ -61,7 +62,8 @@ def main():
except (KeyboardInterrupt, signals.ShutdownException):
log.error("Aborting.")
sys.exit(1)
- except (UserError, NoSuchService, ConfigurationError, ProjectError) as e:
+ except (UserError, NoSuchService, ConfigurationError,
+ ProjectError, OperationFailedError) as e:
log.error(e.msg)
sys.exit(1)
except BuildError as e:
diff --git a/compose/errors.py b/compose/errors.py
new file mode 100644
index 00000000..9f68760d
--- /dev/null
+++ b/compose/errors.py
@@ -0,0 +1,7 @@
+from __future__ import absolute_import
+from __future__ import unicode_literals
+
+
+class OperationFailedError(Exception):
+ def __init__(self, reason):
+ self.msg = reason
diff --git a/compose/parallel.py b/compose/parallel.py
index 50b2dbea..7ac66b37 100644
--- a/compose/parallel.py
+++ b/compose/parallel.py
@@ -12,6 +12,7 @@ from six.moves.queue import Empty
from six.moves.queue import Queue
from compose.cli.signals import ShutdownException
+from compose.errors import OperationFailedError
from compose.utils import get_output_stream
@@ -47,6 +48,9 @@ def parallel_execute(objects, func, get_name, msg, get_deps=None):
elif isinstance(exception, APIError):
errors[get_name(obj)] = exception.explanation
writer.write(get_name(obj), 'error')
+ elif isinstance(exception, OperationFailedError):
+ errors[get_name(obj)] = exception.msg
+ writer.write(get_name(obj), 'error')
elif isinstance(exception, UpstreamError):
writer.write(get_name(obj), 'error')
else:
diff --git a/compose/service.py b/compose/service.py
index 73381466..60343542 100644
--- a/compose/service.py
+++ b/compose/service.py
@@ -27,6 +27,7 @@ from .const import LABEL_PROJECT
from .const import LABEL_SERVICE
from .const import LABEL_VERSION
from .container import Container
+from .errors import OperationFailedError
from .parallel import parallel_execute
from .parallel import parallel_start
from .progress_stream import stream_output
@@ -278,7 +279,11 @@ class Service(object):
if 'name' in container_options and not quiet:
log.info("Creating %s" % container_options['name'])
- return Container.create(self.client, **container_options)
+ try:
+ return Container.create(self.client, **container_options)
+ except APIError as ex:
+ raise OperationFailedError("Cannot create container for service %s: %s" %
+ (self.name, ex.explanation))
def ensure_image_exists(self, do_build=BuildAction.none):
if self.can_be_built() and do_build == BuildAction.force:
@@ -448,7 +453,10 @@ class Service(object):
def start_container(self, container):
self.connect_container_to_networks(container)
- container.start()
+ try:
+ container.start()
+ except APIError as ex:
+ raise OperationFailedError("Cannot start service %s: %s" % (self.name, ex.explanation))
return container
def connect_container_to_networks(self, container):
diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py
index 7d2f03d3..97ad7476 100644
--- a/tests/integration/service_test.py
+++ b/tests/integration/service_test.py
@@ -738,7 +738,10 @@ class ServiceTest(DockerClientTestCase):
self.assertEqual(len(service.containers()), 1)
self.assertTrue(service.containers()[0].is_running)
- self.assertIn("ERROR: for composetest_web_2 Boom", mock_stderr.getvalue())
+ self.assertIn(
+ "ERROR: for composetest_web_2 Cannot create container for service web: Boom",
+ mock_stderr.getvalue()
+ )
def test_scale_with_unexpected_exception(self):
"""Test that when scaling if the API returns an error, that is not of type