diff --git a/tripleo_common/image/image_uploader.py b/tripleo_common/image/image_uploader.py index 4293dfbbf..6b58f04f4 100644 --- a/tripleo_common/image/image_uploader.py +++ b/tripleo_common/image/image_uploader.py @@ -846,8 +846,16 @@ class BaseImageUploader(object): fallback_tag=None, username=None, password=None): image_url = self._image_to_url(image) self.is_insecure_registry(registry_host=image_url.netloc) - session = self.authenticate( - image_url, username=username, password=password) + try: + session = self.authenticate( + image_url, username=username, password=password) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 401: + raise ImageUploaderException( + 'Unable to authenticate. This may indicate ' + 'missing registry credentials or the provided ' + 'container or namespace does not exist. %s' % e) + raise i = self._inspect(image_url, session) return self._discover_tag_from_inspect(i, image, tag_from_label, @@ -859,8 +867,16 @@ class BaseImageUploader(object): for image in images: url = self._image_to_url(image) self.is_insecure_registry(registry_host=url.netloc) - session = self.authenticate( - url, username=username, password=password) + try: + session = self.authenticate( + url, username=username, password=password) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 401: + raise ImageUploaderException( + 'Unable to authenticate. This may indicate ' + 'missing registry credentials or the provided ' + 'container or namespace does not exist. %s' % e) + raise image_labels = self._image_labels( url, session=session) if set(labels).issubset(set(image_labels)): @@ -1296,11 +1312,19 @@ class PythonImageUploader(BaseImageUploader): target_username, target_password = self.credentials_for_registry( t.target_image_url.netloc) - target_session = self.authenticate( - t.target_image_url, - username=target_username, - password=target_password - ) + try: + target_session = self.authenticate( + t.target_image_url, + username=target_username, + password=target_password + ) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 401: + raise ImageUploaderException( + 'Unable to authenticate. This may indicate ' + 'missing registry credentials or the provided ' + 'container or namespace does not exist. %s' % e) + raise try: self._detect_target_export(t.target_image_url, target_session) @@ -1356,11 +1380,19 @@ class PythonImageUploader(BaseImageUploader): source_username, source_password = self.credentials_for_registry( t.source_image_url.netloc) - source_session = self.authenticate( - t.source_image_url, - username=source_username, - password=source_password - ) + try: + source_session = self.authenticate( + t.source_image_url, + username=source_username, + password=source_password + ) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 401: + raise ImageUploaderException( + 'Unable to authenticate. This may indicate ' + 'missing registry credentials or the provided ' + 'container or namespace does not exist. %s' % e) + raise source_layers = [] manifests_str = [] @@ -2313,8 +2345,16 @@ def discover_tag_from_inspect(args): self, image, tag_from_label = args image_url = self._image_to_url(image) username, password = self.credentials_for_registry(image_url.netloc) - session = self.authenticate( - image_url, username=username, password=password) + try: + session = self.authenticate( + image_url, username=username, password=password) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 401: + raise ImageUploaderException( + 'Unable to authenticate. This may indicate ' + 'missing registry credentials or the provided ' + 'container or namespace does not exist. %s' % e) + raise i = self._inspect(image_url, session=session) session.close() if ':' in image_url.path: diff --git a/tripleo_common/tests/image/test_image_uploader.py b/tripleo_common/tests/image/test_image_uploader.py index fc30f4d48..4f6b1fbc0 100644 --- a/tripleo_common/tests/image/test_image_uploader.py +++ b/tripleo_common/tests/image/test_image_uploader.py @@ -394,6 +394,25 @@ class TestBaseImageUploader(base.TestCase): 'docker.io/t/foo:b', 'rdo_version') + # handle auth issues + mock_401 = mock.Mock() + mock_401.status_code = 401 + mock_401_except = requests.exceptions.HTTPError(response=mock_401) + mock_404 = mock.Mock() + mock_404.status_code = 404 + mock_404_except = requests.exceptions.HTTPError(response=mock_404) + mock_auth.side_effect = [mock_401_except, mock_404_except] + self.assertRaises( + ImageUploaderException, + image_uploader.discover_tag_from_inspect, + (self.uploader, 'docker.io/t/foo', 'rdo_version') + ) + self.assertRaises( + requests.exceptions.HTTPError, + image_uploader.discover_tag_from_inspect, + (self.uploader, 'docker.io/t/foo', 'rdo_version') + ) + @mock.patch('tripleo_common.image.image_uploader.' 'BaseImageUploader.authenticate') @mock.patch('tripleo_common.image.image_uploader.' @@ -480,6 +499,25 @@ class TestBaseImageUploader(base.TestCase): (self.uploader, 'docker.io/t/foo', 'rdo_version') ) + # handle auth issues + mock_401 = mock.Mock() + mock_401.status_code = 401 + mock_401_except = requests.exceptions.HTTPError(response=mock_401) + mock_404 = mock.Mock() + mock_404.status_code = 404 + mock_404_except = requests.exceptions.HTTPError(response=mock_404) + mock_auth.side_effect = [mock_401_except, mock_404_except] + self.assertRaises( + ImageUploaderException, + image_uploader.discover_tag_from_inspect, + (self.uploader, 'docker.io/t/foo', 'rdo_version') + ) + self.assertRaises( + requests.exceptions.HTTPError, + image_uploader.discover_tag_from_inspect, + (self.uploader, 'docker.io/t/foo', 'rdo_version') + ) + @mock.patch('concurrent.futures.ThreadPoolExecutor') def test_discover_image_tags(self, mock_pool): mock_map = mock.Mock()