mirror of https://github.com/docker/docker-py.git
				
				
				
			Stop pinging registries from the client
The daemon already pings the registry, so doing it on our end is redundant and error-prone. The `insecure_registry` argument to `push()`, `pull()` and `login()` has been deprecated - in the latter case, it wasn't being used anyway. The `insecure` argument to `docker.auth.resolve_repository_name()` has also been deprecated. `docker.utils.ping_registry()` has been deprecated. `docker.auth.expand_registry_url()` has been removed. Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
		
							parent
							
								
									946eb964ad
								
							
						
					
					
						commit
						33e1a58b60
					
				|  | @ -1,4 +1,5 @@ | |||
| from .auth import ( | ||||
|     INDEX_NAME, | ||||
|     INDEX_URL, | ||||
|     encode_header, | ||||
|     load_config, | ||||
|  |  | |||
|  | @ -16,38 +16,33 @@ import base64 | |||
| import fileinput | ||||
| import json | ||||
| import os | ||||
| import warnings | ||||
| 
 | ||||
| import six | ||||
| 
 | ||||
| from ..utils import utils | ||||
| from .. import errors | ||||
| 
 | ||||
| INDEX_URL = 'https://index.docker.io/v1/' | ||||
| INDEX_NAME = 'index.docker.io' | ||||
| INDEX_URL = 'https://{0}/v1/'.format(INDEX_NAME) | ||||
| DOCKER_CONFIG_FILENAME = os.path.join('.docker', 'config.json') | ||||
| LEGACY_DOCKER_CONFIG_FILENAME = '.dockercfg' | ||||
| 
 | ||||
| 
 | ||||
| def expand_registry_url(hostname, insecure=False): | ||||
|     if hostname.startswith('http:') or hostname.startswith('https:'): | ||||
|         return hostname | ||||
|     if utils.ping_registry('https://' + hostname): | ||||
|         return 'https://' + hostname | ||||
|     elif insecure: | ||||
|         return 'http://' + hostname | ||||
|     else: | ||||
|         raise errors.DockerException( | ||||
|             "HTTPS endpoint unresponsive and insecure mode isn't enabled." | ||||
| def resolve_repository_name(repo_name, insecure=False): | ||||
|     if insecure: | ||||
|         warnings.warn( | ||||
|             'The `insecure` argument to resolve_repository_name() ' | ||||
|             'is deprecated and non-functional. Please remove it.', | ||||
|             DeprecationWarning | ||||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| def resolve_repository_name(repo_name, insecure=False): | ||||
|     if '://' in repo_name: | ||||
|         raise errors.InvalidRepository( | ||||
|             'Repository name cannot contain a scheme ({0})'.format(repo_name)) | ||||
|     parts = repo_name.split('/', 1) | ||||
|     if '.' not in parts[0] and ':' not in parts[0] and parts[0] != 'localhost': | ||||
|         # This is a docker index repo (ex: foo/bar or ubuntu) | ||||
|         return INDEX_URL, repo_name | ||||
|         return INDEX_NAME, repo_name | ||||
|     if len(parts) < 2: | ||||
|         raise errors.InvalidRepository( | ||||
|             'Invalid repository name ({0})'.format(repo_name)) | ||||
|  | @ -57,7 +52,7 @@ def resolve_repository_name(repo_name, insecure=False): | |||
|             'Invalid repository name, try "{0}" instead'.format(parts[1]) | ||||
|         ) | ||||
| 
 | ||||
|     return expand_registry_url(parts[0], insecure), parts[1] | ||||
|     return parts[0], parts[1] | ||||
| 
 | ||||
| 
 | ||||
| def resolve_authconfig(authconfig, registry=None): | ||||
|  | @ -68,7 +63,7 @@ def resolve_authconfig(authconfig, registry=None): | |||
|     Returns None if no match was found. | ||||
|     """ | ||||
|     # Default to the public index server | ||||
|     registry = convert_to_hostname(registry) if registry else INDEX_URL | ||||
|     registry = convert_to_hostname(registry) if registry else INDEX_NAME | ||||
| 
 | ||||
|     if registry in authconfig: | ||||
|         return authconfig[registry] | ||||
|  | @ -185,7 +180,7 @@ def load_config(config_path=None): | |||
|                 'Invalid or empty configuration file!') | ||||
| 
 | ||||
|         username, password = decode_auth(data[0]) | ||||
|         conf[INDEX_URL] = { | ||||
|         conf[INDEX_NAME] = { | ||||
|             'username': username, | ||||
|             'password': password, | ||||
|             'email': data[1], | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ from . import constants | |||
| from . import errors | ||||
| from .auth import auth | ||||
| from .utils import utils, check_resource | ||||
| from .constants import INSECURE_REGISTRY_DEPRECATION_WARNING | ||||
| 
 | ||||
| 
 | ||||
| class Client(clientbase.ClientBase): | ||||
|  | @ -499,6 +500,12 @@ class Client(clientbase.ClientBase): | |||
| 
 | ||||
|     def login(self, username, password=None, email=None, registry=None, | ||||
|               reauth=False, insecure_registry=False, dockercfg_path=None): | ||||
|         if insecure_registry: | ||||
|             warnings.warn( | ||||
|                 INSECURE_REGISTRY_DEPRECATION_WARNING.format('login()'), | ||||
|                 DeprecationWarning | ||||
|             ) | ||||
| 
 | ||||
|         # If we don't have any auth data so far, try reloading the config file | ||||
|         # one more time in case anything showed up in there. | ||||
|         # If dockercfg_path is passed check to see if the config file exists, | ||||
|  | @ -584,11 +591,15 @@ class Client(clientbase.ClientBase): | |||
| 
 | ||||
|     def pull(self, repository, tag=None, stream=False, | ||||
|              insecure_registry=False, auth_config=None): | ||||
|         if insecure_registry: | ||||
|             warnings.warn( | ||||
|                 INSECURE_REGISTRY_DEPRECATION_WARNING.format('pull()'), | ||||
|                 DeprecationWarning | ||||
|             ) | ||||
| 
 | ||||
|         if not tag: | ||||
|             repository, tag = utils.parse_repository_tag(repository) | ||||
|         registry, repo_name = auth.resolve_repository_name( | ||||
|             repository, insecure=insecure_registry | ||||
|         ) | ||||
|         registry, repo_name = auth.resolve_repository_name(repository) | ||||
|         if repo_name.count(":") == 1: | ||||
|             repository, tag = repository.rsplit(":", 1) | ||||
| 
 | ||||
|  | @ -631,11 +642,15 @@ class Client(clientbase.ClientBase): | |||
| 
 | ||||
|     def push(self, repository, tag=None, stream=False, | ||||
|              insecure_registry=False): | ||||
|         if insecure_registry: | ||||
|             warnings.warn( | ||||
|                 INSECURE_REGISTRY_DEPRECATION_WARNING.format('push()'), | ||||
|                 DeprecationWarning | ||||
|             ) | ||||
| 
 | ||||
|         if not tag: | ||||
|             repository, tag = utils.parse_repository_tag(repository) | ||||
|         registry, repo_name = auth.resolve_repository_name( | ||||
|             repository, insecure=insecure_registry | ||||
|         ) | ||||
|         registry, repo_name = auth.resolve_repository_name(repository) | ||||
|         u = self._url("/images/{0}/push".format(repository)) | ||||
|         params = { | ||||
|             'tag': tag | ||||
|  |  | |||
|  | @ -4,3 +4,7 @@ STREAM_HEADER_SIZE_BYTES = 8 | |||
| CONTAINER_LIMITS_KEYS = [ | ||||
|     'memory', 'memswap', 'cpushares', 'cpusetcpus' | ||||
| ] | ||||
| 
 | ||||
| INSECURE_REGISTRY_DEPRECATION_WARNING = \ | ||||
|     'The `insecure_registry` argument to {} ' \ | ||||
|     'is deprecated and non-functional. Please remove it.' | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ import json | |||
| import shlex | ||||
| import tarfile | ||||
| import tempfile | ||||
| import warnings | ||||
| from distutils.version import StrictVersion | ||||
| from fnmatch import fnmatch | ||||
| from datetime import datetime | ||||
|  | @ -120,6 +121,11 @@ def compare_version(v1, v2): | |||
| 
 | ||||
| 
 | ||||
| def ping_registry(url): | ||||
|     warnings.warn( | ||||
|         'The `ping_registry` method is deprecated and will be removed.', | ||||
|         DeprecationWarning | ||||
|     ) | ||||
| 
 | ||||
|     return ping(url + '/v2/', [401]) or ping(url + '/v1/_ping') | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -2424,9 +2424,9 @@ class DockerClientTest(Cleanup, base.BaseTestCase): | |||
|             f.write('auth = {0}\n'.format(auth_)) | ||||
|             f.write('email = sakuya@scarlet.net') | ||||
|         cfg = docker.auth.load_config(dockercfg_path) | ||||
|         self.assertTrue(docker.auth.INDEX_URL in cfg) | ||||
|         self.assertNotEqual(cfg[docker.auth.INDEX_URL], None) | ||||
|         cfg = cfg[docker.auth.INDEX_URL] | ||||
|         self.assertTrue(docker.auth.INDEX_NAME in cfg) | ||||
|         self.assertNotEqual(cfg[docker.auth.INDEX_NAME], None) | ||||
|         cfg = cfg[docker.auth.INDEX_NAME] | ||||
|         self.assertEqual(cfg['username'], 'sakuya') | ||||
|         self.assertEqual(cfg['password'], 'izayoi') | ||||
|         self.assertEqual(cfg['email'], 'sakuya@scarlet.net') | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ from docker.utils import ( | |||
|     create_host_config, Ulimit, LogConfig, parse_bytes | ||||
| ) | ||||
| from docker.utils.ports import build_port_bindings, split_port | ||||
| from docker.auth import resolve_authconfig | ||||
| from docker.auth import resolve_repository_name, resolve_authconfig | ||||
| 
 | ||||
| import base | ||||
| 
 | ||||
|  | @ -167,6 +167,61 @@ class UtilsTest(base.BaseTestCase): | |||
|             type=LogConfig.types.JSON, config='helloworld' | ||||
|         )) | ||||
| 
 | ||||
|     def test_resolve_repository_name(self): | ||||
|         # docker hub library image | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('image'), | ||||
|             ('index.docker.io', 'image'), | ||||
|         ) | ||||
| 
 | ||||
|         # docker hub image | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('username/image'), | ||||
|             ('index.docker.io', 'username/image'), | ||||
|         ) | ||||
| 
 | ||||
|         # private registry | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('my.registry.net/image'), | ||||
|             ('my.registry.net', 'image'), | ||||
|         ) | ||||
| 
 | ||||
|         # private registry with port | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('my.registry.net:5000/image'), | ||||
|             ('my.registry.net:5000', 'image'), | ||||
|         ) | ||||
| 
 | ||||
|         # private registry with username | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('my.registry.net/username/image'), | ||||
|             ('my.registry.net', 'username/image'), | ||||
|         ) | ||||
| 
 | ||||
|         # no dots but port | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('hostname:5000/image'), | ||||
|             ('hostname:5000', 'image'), | ||||
|         ) | ||||
| 
 | ||||
|         # no dots but port and username | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('hostname:5000/username/image'), | ||||
|             ('hostname:5000', 'username/image'), | ||||
|         ) | ||||
| 
 | ||||
|         # localhost | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('localhost/image'), | ||||
|             ('localhost', 'image'), | ||||
|         ) | ||||
| 
 | ||||
|         # localhost with username | ||||
|         self.assertEqual( | ||||
|             resolve_repository_name('localhost/username/image'), | ||||
|             ('localhost', 'username/image'), | ||||
|         ) | ||||
| 
 | ||||
|     def test_resolve_authconfig(self): | ||||
|         auth_config = { | ||||
|             'https://index.docker.io/v1/': {'auth': 'indexuser'}, | ||||
|  | @ -231,6 +286,40 @@ class UtilsTest(base.BaseTestCase): | |||
|             resolve_authconfig(auth_config, 'does.not.exist') is None | ||||
|         ) | ||||
| 
 | ||||
|     def test_resolve_registry_and_auth(self): | ||||
|         auth_config = { | ||||
|             'https://index.docker.io/v1/': {'auth': 'indexuser'}, | ||||
|             'my.registry.net': {'auth': 'privateuser'}, | ||||
|         } | ||||
| 
 | ||||
|         # library image | ||||
|         image = 'image' | ||||
|         self.assertEqual( | ||||
|             resolve_authconfig(auth_config, resolve_repository_name(image)[0]), | ||||
|             {'auth': 'indexuser'}, | ||||
|         ) | ||||
| 
 | ||||
|         # docker hub image | ||||
|         image = 'username/image' | ||||
|         self.assertEqual( | ||||
|             resolve_authconfig(auth_config, resolve_repository_name(image)[0]), | ||||
|             {'auth': 'indexuser'}, | ||||
|         ) | ||||
| 
 | ||||
|         # private registry | ||||
|         image = 'my.registry.net/image' | ||||
|         self.assertEqual( | ||||
|             resolve_authconfig(auth_config, resolve_repository_name(image)[0]), | ||||
|             {'auth': 'privateuser'}, | ||||
|         ) | ||||
| 
 | ||||
|         # unauthenticated registry | ||||
|         image = 'other.registry.net/image' | ||||
|         self.assertEqual( | ||||
|             resolve_authconfig(auth_config, resolve_repository_name(image)[0]), | ||||
|             None, | ||||
|         ) | ||||
| 
 | ||||
|     def test_split_port_with_host_ip(self): | ||||
|         internal_port, external_port = split_port("127.0.0.1:1000:2000") | ||||
|         self.assertEqual(internal_port, ["2000"]) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue