Skip to content

Commit d6f46d5

Browse files
hrwyoctozepto
authored andcommitted
handle push error properly
If there was some error during pushing then Kolla was greeting with "all went fine" message anyway: INFO:kolla.common.utils.aodh-api:Trying to push the image ERROR:kolla.common.utils.aodh-api:Get http://10.101.16.1:5000/v2/: dial tcp 10.101.16.1:5000: connect: no route to host INFO:kolla.common.utils.aodh-api:Pushed successfully This patch changes that. Now if there is an error during push then proper exception is raised to PushTask and image is marked with PUSH_ERROR status. This way at the end of build it is easy to spot which images did not got pushed to registry: INFO:kolla.common.utils:=========================== INFO:kolla.common.utils:Images that failed to build INFO:kolla.common.utils:=========================== ERROR:kolla.common.utils:base Failed with status: push_error ERROR:kolla.common.utils:nova-api Failed with status: push_error ERROR:kolla.common.utils:nova-base Failed with status: push_error ERROR:kolla.common.utils:nova-compute Failed with status: push_error ERROR:kolla.common.utils:nova-compute-ironic Failed with status: push_error ERROR:kolla.common.utils:nova-conductor Failed with status: push_error Closes-Bug: #1848019 Change-Id: Id2ab97bf4c0dc3423268a0ea435b56f4a65f7196 (cherry picked from commit 52cac09)
1 parent 7e31dac commit d6f46d5

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

kolla/image/build.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ def run(self):
317317
self.success = True
318318

319319

320+
class PushError(Exception):
321+
"""Raised when there is a problem with pushing image to repository."""
322+
pass
323+
324+
320325
class PushTask(DockerTask):
321326
"""Task that pushes an image to a docker repository."""
322327

@@ -340,6 +345,9 @@ def run(self):
340345
' have the correct privileges to run Docker'
341346
' (root)')
342347
image.status = STATUS_CONNECTION_ERROR
348+
except PushError as exception:
349+
self.logger.error(exception)
350+
image.status = STATUS_PUSH_ERROR
343351
except Exception:
344352
self.logger.exception('Unknown error when pushing')
345353
image.status = STATUS_PUSH_ERROR
@@ -364,8 +372,7 @@ def push_image(self, image):
364372
if 'stream' in response:
365373
self.logger.info(response['stream'])
366374
elif 'errorDetail' in response:
367-
image.status = STATUS_ERROR
368-
self.logger.error(response['errorDetail']['message'])
375+
raise PushError(response['errorDetail']['message'])
369376

370377
# Reset any previous errors.
371378
image.status = STATUS_BUILT

kolla/tests/test_build.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def test_push_image(self, mock_client):
8383
@mock.patch.dict(os.environ, clear=True)
8484
@mock.patch('docker.APIClient')
8585
def test_push_image_failure(self, mock_client):
86+
"""failure on connecting Docker API"""
8687
self.dc = mock_client
8788
mock_client().push.side_effect = Exception
8889
pusher = build.PushTask(self.conf, self.image)
@@ -96,6 +97,7 @@ def test_push_image_failure(self, mock_client):
9697
@mock.patch.dict(os.environ, clear=True)
9798
@mock.patch('docker.APIClient')
9899
def test_push_image_failure_retry(self, mock_client):
100+
"""failure on connecting Docker API, success on retry"""
99101
self.dc = mock_client
100102
mock_client().push.side_effect = [Exception, []]
101103
pusher = build.PushTask(self.conf, self.image)
@@ -112,6 +114,44 @@ def test_push_image_failure_retry(self, mock_client):
112114
self.assertTrue(pusher.success)
113115
self.assertEqual(build.STATUS_BUILT, self.image.status)
114116

117+
@mock.patch('docker.version', '3.0.0')
118+
@mock.patch.dict(os.environ, clear=True)
119+
@mock.patch('docker.APIClient')
120+
def test_push_image_failure_error(self, mock_client):
121+
"""Docker connected, failure to push"""
122+
self.dc = mock_client
123+
mock_client().push.return_value = [{'errorDetail': {'message':
124+
'mock push fail'}}]
125+
pusher = build.PushTask(self.conf, self.image)
126+
pusher.run()
127+
mock_client().push.assert_called_once_with(
128+
self.image.canonical_name, decode=True, stream=True)
129+
self.assertFalse(pusher.success)
130+
self.assertEqual(build.STATUS_PUSH_ERROR, self.image.status)
131+
132+
@mock.patch('docker.version', '3.0.0')
133+
@mock.patch.dict(os.environ, clear=True)
134+
@mock.patch('docker.APIClient')
135+
def test_push_image_failure_error_retry(self, mock_client):
136+
"""Docker connected, failure to push, success on retry"""
137+
self.dc = mock_client
138+
mock_client().push.return_value = [{'errorDetail': {'message':
139+
'mock push fail'}}]
140+
pusher = build.PushTask(self.conf, self.image)
141+
pusher.run()
142+
mock_client().push.assert_called_once_with(
143+
self.image.canonical_name, decode=True, stream=True)
144+
self.assertFalse(pusher.success)
145+
self.assertEqual(build.STATUS_PUSH_ERROR, self.image.status)
146+
147+
# Try again, this time without exception.
148+
mock_client().push.return_value = [{'stream': 'mock push passes'}]
149+
pusher.reset()
150+
pusher.run()
151+
self.assertEqual(2, mock_client().push.call_count)
152+
self.assertTrue(pusher.success)
153+
self.assertEqual(build.STATUS_BUILT, self.image.status)
154+
115155
@mock.patch.dict(os.environ, clear=True)
116156
@mock.patch('docker.APIClient')
117157
def test_build_image(self, mock_client):

0 commit comments

Comments
 (0)