diff options
Diffstat (limited to 'docker')
-rw-r--r-- | docker/api/build.py | 10 | ||||
-rw-r--r-- | docker/api/client.py | 6 | ||||
-rw-r--r-- | docker/api/daemon.py | 4 | ||||
-rw-r--r-- | docker/api/plugin.py | 15 | ||||
-rw-r--r-- | docker/auth.py | 13 | ||||
-rw-r--r-- | docker/client.py | 9 | ||||
-rw-r--r-- | docker/models/networks.py | 2 | ||||
-rw-r--r-- | docker/models/services.py | 4 | ||||
-rw-r--r-- | docker/transport/unixconn.py | 6 | ||||
-rw-r--r-- | docker/types/daemon.py | 2 | ||||
-rw-r--r-- | docker/types/services.py | 2 | ||||
-rw-r--r-- | docker/utils/socket.py | 3 | ||||
-rw-r--r-- | docker/version.py | 2 |
13 files changed, 55 insertions, 23 deletions
diff --git a/docker/api/build.py b/docker/api/build.py index f62a731..419255f 100644 --- a/docker/api/build.py +++ b/docker/api/build.py @@ -302,7 +302,8 @@ class BuildApiMixin(object): # credentials/native_store.go#L68-L83 for registry in self._auth_configs.get('auths', {}).keys(): auth_data[registry] = auth.resolve_authconfig( - self._auth_configs, registry + self._auth_configs, registry, + credstore_env=self.credstore_env, ) else: auth_data = self._auth_configs.get('auths', {}).copy() @@ -341,4 +342,9 @@ def process_dockerfile(dockerfile, path): ) # Dockerfile is inside the context - return path relative to context root - return (os.path.relpath(abs_dockerfile, path), None) + if dockerfile == abs_dockerfile: + # Only calculate relpath if necessary to avoid errors + # on Windows client -> Linux Docker + # see https://github.com/docker/compose/issues/5969 + dockerfile = os.path.relpath(abs_dockerfile, path) + return (dockerfile, None) diff --git a/docker/api/client.py b/docker/api/client.py index 13c292a..91da1c8 100644 --- a/docker/api/client.py +++ b/docker/api/client.py @@ -83,6 +83,8 @@ class APIClient( :py:class:`~docker.tls.TLSConfig` object to use custom configuration. user_agent (str): Set a custom user agent for requests to the server. + credstore_env (dict): Override environment variables when calling the + credential store process. """ __attrs__ = requests.Session.__attrs__ + ['_auth_configs', @@ -93,7 +95,8 @@ class APIClient( def __init__(self, base_url=None, version=None, timeout=DEFAULT_TIMEOUT_SECONDS, tls=False, - user_agent=DEFAULT_USER_AGENT, num_pools=DEFAULT_NUM_POOLS): + user_agent=DEFAULT_USER_AGENT, num_pools=DEFAULT_NUM_POOLS, + credstore_env=None): super(APIClient, self).__init__() if tls and not base_url: @@ -109,6 +112,7 @@ class APIClient( self._auth_configs = auth.load_config( config_dict=self._general_configs ) + self.credstore_env = credstore_env base_url = utils.parse_host( base_url, IS_WINDOWS_PLATFORM, tls=bool(tls) diff --git a/docker/api/daemon.py b/docker/api/daemon.py index fc3692c..76a94cf 100644 --- a/docker/api/daemon.py +++ b/docker/api/daemon.py @@ -128,7 +128,9 @@ class DaemonApiMixin(object): elif not self._auth_configs: self._auth_configs = auth.load_config() - authcfg = auth.resolve_authconfig(self._auth_configs, registry) + authcfg = auth.resolve_authconfig( + self._auth_configs, registry, credstore_env=self.credstore_env, + ) # If we found an existing auth config for this registry and username # combination, we can return it immediately unless reauth is requested. if authcfg and authcfg.get('username', None) == username \ diff --git a/docker/api/plugin.py b/docker/api/plugin.py index 73f1852..f6c0b13 100644 --- a/docker/api/plugin.py +++ b/docker/api/plugin.py @@ -44,7 +44,10 @@ class PluginApiMixin(object): """ url = self._url('/plugins/create') - with utils.create_archive(root=plugin_data_dir, gzip=gzip) as archv: + with utils.create_archive( + root=plugin_data_dir, gzip=gzip, + files=set(utils.build.walk(plugin_data_dir, [])) + ) as archv: res = self._post(url, params={'name': name}, data=archv) self._raise_for_status(res) return True @@ -167,8 +170,16 @@ class PluginApiMixin(object): 'remote': name, } + headers = {} + registry, repo_name = auth.resolve_repository_name(name) + header = auth.get_config_header(self, registry) + if header: + headers['X-Registry-Auth'] = header + url = self._url('/plugins/privileges') - return self._result(self._get(url, params=params), True) + return self._result( + self._get(url, params=params, headers=headers), True + ) @utils.minimum_version('1.25') @utils.check_resource('name') diff --git a/docker/auth.py b/docker/auth.py index 48fcd8b..0c0cb20 100644 --- a/docker/auth.py +++ b/docker/auth.py @@ -44,7 +44,9 @@ def get_config_header(client, registry): "No auth config in memory - loading from filesystem" ) client._auth_configs = load_config() - authcfg = resolve_authconfig(client._auth_configs, registry) + authcfg = resolve_authconfig( + client._auth_configs, registry, credstore_env=client.credstore_env + ) # Do not fail here if no authentication exists for this # specific registry as we can have a readonly pull. Just # put the header if we can. @@ -76,7 +78,7 @@ def get_credential_store(authconfig, registry): ) -def resolve_authconfig(authconfig, registry=None): +def resolve_authconfig(authconfig, registry=None, credstore_env=None): """ Returns the authentication data from the given auth configuration for a specific registry. As with the Docker client, legacy entries in the config @@ -91,7 +93,7 @@ def resolve_authconfig(authconfig, registry=None): 'Using credentials store "{0}"'.format(store_name) ) cfg = _resolve_authconfig_credstore( - authconfig, registry, store_name + authconfig, registry, store_name, env=credstore_env ) if cfg is not None: return cfg @@ -115,13 +117,14 @@ def resolve_authconfig(authconfig, registry=None): return None -def _resolve_authconfig_credstore(authconfig, registry, credstore_name): +def _resolve_authconfig_credstore(authconfig, registry, credstore_name, + env=None): if not registry or registry == INDEX_NAME: # The ecosystem is a little schizophrenic with index.docker.io VS # docker.io - in that case, it seems the full URL is necessary. registry = INDEX_URL log.debug("Looking for auth entry for {0}".format(repr(registry))) - store = dockerpycreds.Store(credstore_name) + store = dockerpycreds.Store(credstore_name, environment=env) try: data = store.get(registry) res = { diff --git a/docker/client.py b/docker/client.py index b4364c3..8d4a52b 100644 --- a/docker/client.py +++ b/docker/client.py @@ -33,6 +33,8 @@ class DockerClient(object): :py:class:`~docker.tls.TLSConfig` object to use custom configuration. user_agent (str): Set a custom user agent for requests to the server. + credstore_env (dict): Override environment variables when calling the + credential store process. """ def __init__(self, *args, **kwargs): self.api = APIClient(*args, **kwargs) @@ -66,6 +68,8 @@ class DockerClient(object): assert_hostname (bool): Verify the hostname of the server. environment (dict): The environment to read environment variables from. Default: the value of ``os.environ`` + credstore_env (dict): Override environment variables when calling + the credential store process. Example: @@ -77,8 +81,9 @@ class DockerClient(object): """ timeout = kwargs.pop('timeout', DEFAULT_TIMEOUT_SECONDS) version = kwargs.pop('version', None) - return cls(timeout=timeout, version=version, - **kwargs_from_env(**kwargs)) + return cls( + timeout=timeout, version=version, **kwargs_from_env(**kwargs) + ) # Resources @property diff --git a/docker/models/networks.py b/docker/models/networks.py index 1c2fbf2..be3291a 100644 --- a/docker/models/networks.py +++ b/docker/models/networks.py @@ -211,5 +211,5 @@ class NetworkCollection(Collection): return networks def prune(self, filters=None): - self.client.api.prune_networks(filters=filters) + return self.client.api.prune_networks(filters=filters) prune.__doc__ = APIClient.prune_networks.__doc__ diff --git a/docker/models/services.py b/docker/models/services.py index 125896b..458d2c8 100644 --- a/docker/models/services.py +++ b/docker/models/services.py @@ -126,7 +126,7 @@ class Service(Model): service_mode = ServiceMode('replicated', replicas) return self.client.api.update_service(self.id, self.version, - service_mode, + mode=service_mode, fetch_current_spec=True) def force_update(self): @@ -276,7 +276,7 @@ CONTAINER_SPEC_KWARGS = [ 'labels', 'mounts', 'open_stdin', - 'privileges' + 'privileges', 'read_only', 'secrets', 'stop_grace_period', diff --git a/docker/transport/unixconn.py b/docker/transport/unixconn.py index cc35d00..c59821a 100644 --- a/docker/transport/unixconn.py +++ b/docker/transport/unixconn.py @@ -1,14 +1,10 @@ import six import requests.adapters import socket +from six.moves import http_client as httplib from .. import constants -if six.PY3: - import http.client as httplib -else: - import httplib - try: import requests.packages.urllib3 as urllib3 except ImportError: diff --git a/docker/types/daemon.py b/docker/types/daemon.py index 852f3d8..ee8624e 100644 --- a/docker/types/daemon.py +++ b/docker/types/daemon.py @@ -57,6 +57,8 @@ class CancellableStream(object): else: sock = sock_fp._sock + if isinstance(sock, urllib3.contrib.pyopenssl.WrappedSocket): + sock = sock.socket sock.shutdown(socket.SHUT_RDWR) sock.close() diff --git a/docker/types/services.py b/docker/types/services.py index 09eb05e..31f4750 100644 --- a/docker/types/services.py +++ b/docker/types/services.py @@ -82,7 +82,7 @@ class ContainerSpec(dict): args (:py:class:`list`): Arguments to the command. hostname (string): The hostname to set on the container. env (dict): Environment variables. - dir (string): The working directory for commands to run in. + workdir (string): The working directory for commands to run in. user (string): The user inside the container. labels (dict): A map of labels to associate with the service. mounts (:py:class:`list`): A list of specifications for mounts to be diff --git a/docker/utils/socket.py b/docker/utils/socket.py index 0945f0a..7b96d4f 100644 --- a/docker/utils/socket.py +++ b/docker/utils/socket.py @@ -1,6 +1,7 @@ import errno import os import select +import socket as pysocket import struct import six @@ -28,6 +29,8 @@ def read(socket, n=4096): try: if hasattr(socket, 'recv'): return socket.recv(n) + if six.PY3 and isinstance(socket, getattr(pysocket, 'SocketIO')): + return socket.read(n) return os.read(socket.fileno(), n) except EnvironmentError as e: if e.errno not in recoverable_errors: diff --git a/docker/version.py b/docker/version.py index 8f6e651..c504327 100644 --- a/docker/version.py +++ b/docker/version.py @@ -1,2 +1,2 @@ -version = "3.3.0" +version = "3.4.0" version_info = tuple([int(d) for d in version.split("-")[0].split(".")]) |