From 59ba27068b524bdbfe60dd74762e28acd709caea Mon Sep 17 00:00:00 2001 From: Aaron Cowdin Date: Fri, 28 Apr 2017 14:36:43 -0700 Subject: [PATCH 1/3] Handle multiple success messages during image building. Signed-off-by: Aaron Cowdin --- docker/models/images.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docker/models/images.py b/docker/models/images.py index 3fd3dc19..cb9c80d2 100644 --- a/docker/models/images.py +++ b/docker/models/images.py @@ -169,14 +169,15 @@ class ImageCollection(Collection): events = list(json_stream(resp)) if not events: return BuildError('Unknown') - event = events[-1] - if 'stream' in event: - match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)', - event.get('stream', '')) - if match: - image_id = match.group(2) - return self.get(image_id) + for event in events: + if 'stream' in event: + match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)', + event.get('stream', '')) + if match: + image_id = match.group(2) + return self.get(image_id) + event = events[-1] raise BuildError(event.get('error') or event) def get(self, name): From 7dffc4623485d705ff088817f4439f1edb734547 Mon Sep 17 00:00:00 2001 From: Aaron Cowdin Date: Tue, 2 May 2017 17:01:34 -0700 Subject: [PATCH 2/3] Add integration tests Signed-off-by: Aaron Cowdin --- tests/integration/models_images_test.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/integration/models_images_test.py b/tests/integration/models_images_test.py index 4f8bb26c..49e06f69 100644 --- a/tests/integration/models_images_test.py +++ b/tests/integration/models_images_test.py @@ -28,6 +28,15 @@ class ImageCollectionTest(BaseIntegrationTest): assert str(cm.exception) == ("Unknown instruction: " "NOTADOCKERFILECOMMAND") + def test_build_with_multiple_success(self): + client = docker.from_env(version=TEST_API_VERSION) + image = client.images.build(tag='some-tag', fileobj=io.BytesIO( + "FROM alpine\n" + "CMD echo hello world".encode('ascii') + )) + self.tmp_imgs.append(image.id) + assert client.containers.run(image) == b"hello world\n" + def test_list(self): client = docker.from_env(version=TEST_API_VERSION) image = client.images.pull('alpine:latest') From a164f4661bb92eb962e6954836b33f6d10b173d0 Mon Sep 17 00:00:00 2001 From: Aaron Cowdin Date: Tue, 2 May 2017 17:14:05 -0700 Subject: [PATCH 3/3] Better error handling, itterate on json stream directly. Signed-off-by: Aaron Cowdin --- docker/models/images.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docker/models/images.py b/docker/models/images.py index cb9c80d2..55e7ced8 100644 --- a/docker/models/images.py +++ b/docker/models/images.py @@ -166,19 +166,18 @@ class ImageCollection(Collection): resp = self.client.api.build(**kwargs) if isinstance(resp, six.string_types): return self.get(resp) - events = list(json_stream(resp)) - if not events: - return BuildError('Unknown') - for event in events: - if 'stream' in event: + for chunk in json_stream(resp): + if 'error' in chunk: + raise BuildError(chunk['error']) + break + if 'stream' in chunk: match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)', - event.get('stream', '')) + chunk['stream']) if match: image_id = match.group(2) return self.get(image_id) - event = events[-1] - raise BuildError(event.get('error') or event) + return BuildError('Unknown') def get(self, name): """