From fbbbc827314228a91f7442c66695b8ec3b22b9bd Mon Sep 17 00:00:00 2001 From: Hongbin Lu Date: Sun, 30 Dec 2018 22:39:26 +0000 Subject: [PATCH] Support auth with docker registry This allows allow operators to configure username/password of the default registry. The credential is used to authenticate with registry on pulling docker images. Partial-Bug: #1702830 Change-Id: I429a4a88623b984238b65159232ea55c880f6cd3 --- zun/conf/docker.py | 4 ++++ zun/image/docker/driver.py | 10 +++++++++- zun/tests/unit/image/docker/test_driver.py | 15 +++++---------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/zun/conf/docker.py b/zun/conf/docker.py index 94f97f168..c8c127c3b 100644 --- a/zun/conf/docker.py +++ b/zun/conf/docker.py @@ -61,6 +61,10 @@ docker_opts = [ help='The default registry from which docker images are ' 'pulled. Its value can be the registry domain name ' '(e.g. docker.io) or None.'), + cfg.StrOpt('default_registry_username', + help='The username of the default registry.'), + cfg.StrOpt('default_registry_password', + help='The password of the default registry.'), ] ALL_OPTS = (docker_opts) diff --git a/zun/image/docker/driver.py b/zun/image/docker/driver.py index 77561670a..005c61d30 100644 --- a/zun/image/docker/driver.py +++ b/zun/image/docker/driver.py @@ -66,9 +66,17 @@ class DockerDriver(driver.ContainerImageDriver): return None def _pull_image(self, repo, tag): + auth_config = None + image_ref = docker_image.Reference.parse(repo) + registry, remainder = image_ref.split_hostname() + if (registry and registry == CONF.docker.default_registry and + CONF.docker.default_registry_username): + auth_config = {'username': CONF.docker.default_registry_username, + 'password': CONF.docker.default_registry_password} + with docker_utils.docker_client() as docker: try: - docker.pull(repo, tag=tag) + docker.pull(repo, tag=tag, auth_config=auth_config) except errors.NotFound as e: raise exception.ImageNotFound(message=six.text_type(e)) except errors.APIError as e: diff --git a/zun/tests/unit/image/docker/test_driver.py b/zun/tests/unit/image/docker/test_driver.py index 7ace5e3f1..18fa4a805 100644 --- a/zun/tests/unit/image/docker/test_driver.py +++ b/zun/tests/unit/image/docker/test_driver.py @@ -68,8 +68,7 @@ class TestDriver(base.BaseTestCase): ret = self.driver.pull_image(None, 'test_image', 'latest', 'always') self.assertEqual(({'image': 'test_image', 'path': None}, True), ret) self.mock_docker.pull.assert_called_once_with( - 'test_image', - tag='latest') + 'test_image', tag='latest', auth_config=None) @mock.patch('zun.common.utils.parse_image_name') @mock.patch.object(driver.DockerDriver, @@ -85,8 +84,7 @@ class TestDriver(base.BaseTestCase): self.assertRaises(exception.ZunException, self.driver.pull_image, None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( - 'repo', - tag='tag') + 'repo', tag='tag', auth_config=None) @mock.patch('zun.common.utils.parse_image_name') @mock.patch.object(driver.DockerDriver, @@ -104,8 +102,7 @@ class TestDriver(base.BaseTestCase): self.assertRaises(exception.ImageNotFound, self.driver.pull_image, None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( - 'repo', - tag='tag') + 'repo', tag='tag', auth_config=None) self.assertEqual(1, mock_pull.call_count) @mock.patch('zun.common.utils.parse_image_name') @@ -124,8 +121,7 @@ class TestDriver(base.BaseTestCase): self.assertRaises(exception.DockerError, self.driver.pull_image, None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( - 'repo', - tag='tag') + 'repo', tag='tag', auth_config=None) self.assertEqual(1, mock_pull.call_count) @mock.patch('zun.common.utils.parse_image_name') @@ -145,8 +141,7 @@ class TestDriver(base.BaseTestCase): self.assertRaises(exception.ZunException, self.driver.pull_image, None, 'repo', 'tag', 'always') self.mock_docker.pull.assert_called_once_with( - 'repo', - tag='tag') + 'repo', tag='tag', auth_config=None) self.assertEqual(1, mock_init.call_count) def test_search_image_success(self):