Skip to content

Commit f70545e

Browse files
authored
Merge pull request #2062 from docker/3.4.0-release
3.4.0 Release
2 parents e88751c + e5f5624 commit f70545e

21 files changed

+191
-53
lines changed

docker/api/build.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ def _set_auth_headers(self, headers):
302302
# credentials/native_store.go#L68-L83
303303
for registry in self._auth_configs.get('auths', {}).keys():
304304
auth_data[registry] = auth.resolve_authconfig(
305-
self._auth_configs, registry
305+
self._auth_configs, registry,
306+
credstore_env=self.credstore_env,
306307
)
307308
else:
308309
auth_data = self._auth_configs.get('auths', {}).copy()
@@ -341,4 +342,9 @@ def process_dockerfile(dockerfile, path):
341342
)
342343

343344
# Dockerfile is inside the context - return path relative to context root
344-
return (os.path.relpath(abs_dockerfile, path), None)
345+
if dockerfile == abs_dockerfile:
346+
# Only calculate relpath if necessary to avoid errors
347+
# on Windows client -> Linux Docker
348+
# see https://github.com/docker/compose/issues/5969
349+
dockerfile = os.path.relpath(abs_dockerfile, path)
350+
return (dockerfile, None)

docker/api/client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class APIClient(
8383
:py:class:`~docker.tls.TLSConfig` object to use custom
8484
configuration.
8585
user_agent (str): Set a custom user agent for requests to the server.
86+
credstore_env (dict): Override environment variables when calling the
87+
credential store process.
8688
"""
8789

8890
__attrs__ = requests.Session.__attrs__ + ['_auth_configs',
@@ -93,7 +95,8 @@ class APIClient(
9395

9496
def __init__(self, base_url=None, version=None,
9597
timeout=DEFAULT_TIMEOUT_SECONDS, tls=False,
96-
user_agent=DEFAULT_USER_AGENT, num_pools=DEFAULT_NUM_POOLS):
98+
user_agent=DEFAULT_USER_AGENT, num_pools=DEFAULT_NUM_POOLS,
99+
credstore_env=None):
97100
super(APIClient, self).__init__()
98101

99102
if tls and not base_url:
@@ -109,6 +112,7 @@ def __init__(self, base_url=None, version=None,
109112
self._auth_configs = auth.load_config(
110113
config_dict=self._general_configs
111114
)
115+
self.credstore_env = credstore_env
112116

113117
base_url = utils.parse_host(
114118
base_url, IS_WINDOWS_PLATFORM, tls=bool(tls)

docker/api/daemon.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ def login(self, username, password=None, email=None, registry=None,
128128
elif not self._auth_configs:
129129
self._auth_configs = auth.load_config()
130130

131-
authcfg = auth.resolve_authconfig(self._auth_configs, registry)
131+
authcfg = auth.resolve_authconfig(
132+
self._auth_configs, registry, credstore_env=self.credstore_env,
133+
)
132134
# If we found an existing auth config for this registry and username
133135
# combination, we can return it immediately unless reauth is requested.
134136
if authcfg and authcfg.get('username', None) == username \

docker/api/plugin.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ def create_plugin(self, name, plugin_data_dir, gzip=False):
4444
"""
4545
url = self._url('/plugins/create')
4646

47-
with utils.create_archive(root=plugin_data_dir, gzip=gzip) as archv:
47+
with utils.create_archive(
48+
root=plugin_data_dir, gzip=gzip,
49+
files=set(utils.build.walk(plugin_data_dir, []))
50+
) as archv:
4851
res = self._post(url, params={'name': name}, data=archv)
4952
self._raise_for_status(res)
5053
return True
@@ -167,8 +170,16 @@ def plugin_privileges(self, name):
167170
'remote': name,
168171
}
169172

173+
headers = {}
174+
registry, repo_name = auth.resolve_repository_name(name)
175+
header = auth.get_config_header(self, registry)
176+
if header:
177+
headers['X-Registry-Auth'] = header
178+
170179
url = self._url('/plugins/privileges')
171-
return self._result(self._get(url, params=params), True)
180+
return self._result(
181+
self._get(url, params=params, headers=headers), True
182+
)
172183

173184
@utils.minimum_version('1.25')
174185
@utils.check_resource('name')

docker/auth.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ def get_config_header(client, registry):
4444
"No auth config in memory - loading from filesystem"
4545
)
4646
client._auth_configs = load_config()
47-
authcfg = resolve_authconfig(client._auth_configs, registry)
47+
authcfg = resolve_authconfig(
48+
client._auth_configs, registry, credstore_env=client.credstore_env
49+
)
4850
# Do not fail here if no authentication exists for this
4951
# specific registry as we can have a readonly pull. Just
5052
# put the header if we can.
@@ -76,7 +78,7 @@ def get_credential_store(authconfig, registry):
7678
)
7779

7880

79-
def resolve_authconfig(authconfig, registry=None):
81+
def resolve_authconfig(authconfig, registry=None, credstore_env=None):
8082
"""
8183
Returns the authentication data from the given auth configuration for a
8284
specific registry. As with the Docker client, legacy entries in the config
@@ -91,7 +93,7 @@ def resolve_authconfig(authconfig, registry=None):
9193
'Using credentials store "{0}"'.format(store_name)
9294
)
9395
cfg = _resolve_authconfig_credstore(
94-
authconfig, registry, store_name
96+
authconfig, registry, store_name, env=credstore_env
9597
)
9698
if cfg is not None:
9799
return cfg
@@ -115,13 +117,14 @@ def resolve_authconfig(authconfig, registry=None):
115117
return None
116118

117119

118-
def _resolve_authconfig_credstore(authconfig, registry, credstore_name):
120+
def _resolve_authconfig_credstore(authconfig, registry, credstore_name,
121+
env=None):
119122
if not registry or registry == INDEX_NAME:
120123
# The ecosystem is a little schizophrenic with index.docker.io VS
121124
# docker.io - in that case, it seems the full URL is necessary.
122125
registry = INDEX_URL
123126
log.debug("Looking for auth entry for {0}".format(repr(registry)))
124-
store = dockerpycreds.Store(credstore_name)
127+
store = dockerpycreds.Store(credstore_name, environment=env)
125128
try:
126129
data = store.get(registry)
127130
res = {

docker/client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class DockerClient(object):
3333
:py:class:`~docker.tls.TLSConfig` object to use custom
3434
configuration.
3535
user_agent (str): Set a custom user agent for requests to the server.
36+
credstore_env (dict): Override environment variables when calling the
37+
credential store process.
3638
"""
3739
def __init__(self, *args, **kwargs):
3840
self.api = APIClient(*args, **kwargs)
@@ -66,6 +68,8 @@ def from_env(cls, **kwargs):
6668
assert_hostname (bool): Verify the hostname of the server.
6769
environment (dict): The environment to read environment variables
6870
from. Default: the value of ``os.environ``
71+
credstore_env (dict): Override environment variables when calling
72+
the credential store process.
6973
7074
Example:
7175
@@ -77,8 +81,9 @@ def from_env(cls, **kwargs):
7781
"""
7882
timeout = kwargs.pop('timeout', DEFAULT_TIMEOUT_SECONDS)
7983
version = kwargs.pop('version', None)
80-
return cls(timeout=timeout, version=version,
81-
**kwargs_from_env(**kwargs))
84+
return cls(
85+
timeout=timeout, version=version, **kwargs_from_env(**kwargs)
86+
)
8287

8388
# Resources
8489
@property

docker/models/networks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,5 +211,5 @@ def list(self, *args, **kwargs):
211211
return networks
212212

213213
def prune(self, filters=None):
214-
self.client.api.prune_networks(filters=filters)
214+
return self.client.api.prune_networks(filters=filters)
215215
prune.__doc__ = APIClient.prune_networks.__doc__

docker/models/services.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def scale(self, replicas):
126126

127127
service_mode = ServiceMode('replicated', replicas)
128128
return self.client.api.update_service(self.id, self.version,
129-
service_mode,
129+
mode=service_mode,
130130
fetch_current_spec=True)
131131

132132
def force_update(self):
@@ -276,7 +276,7 @@ def list(self, **kwargs):
276276
'labels',
277277
'mounts',
278278
'open_stdin',
279-
'privileges'
279+
'privileges',
280280
'read_only',
281281
'secrets',
282282
'stop_grace_period',

docker/transport/unixconn.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import six
22
import requests.adapters
33
import socket
4+
from six.moves import http_client as httplib
45

56
from .. import constants
67

7-
if six.PY3:
8-
import http.client as httplib
9-
else:
10-
import httplib
11-
128
try:
139
import requests.packages.urllib3 as urllib3
1410
except ImportError:

docker/types/daemon.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ def close(self):
5757

5858
else:
5959
sock = sock_fp._sock
60+
if isinstance(sock, urllib3.contrib.pyopenssl.WrappedSocket):
61+
sock = sock.socket
6062

6163
sock.shutdown(socket.SHUT_RDWR)
6264
sock.close()

0 commit comments

Comments
 (0)