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