Skip to content

Commit de89ee6

Browse files
aanandshin-
authored andcommitted
Fix auth config path on Windows
The Engine client looks *only* at the USERPROFILE environment variable on Windows, so we should do that too. Signed-off-by: Aanand Prasad <[email protected]>
1 parent 8c4fd81 commit de89ee6

File tree

2 files changed

+77
-12
lines changed

2 files changed

+77
-12
lines changed

docker/auth.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import six
88

99
from . import errors
10+
from .constants import IS_WINDOWS_PLATFORM
1011

1112
INDEX_NAME = 'docker.io'
1213
INDEX_URL = 'https://{0}/v1/'.format(INDEX_NAME)
@@ -210,19 +211,12 @@ def parse_auth(entries, raise_on_error=False):
210211

211212

212213
def find_config_file(config_path=None):
213-
environment_path = os.path.join(
214-
os.environ.get('DOCKER_CONFIG'),
215-
os.path.basename(DOCKER_CONFIG_FILENAME)
216-
) if os.environ.get('DOCKER_CONFIG') else None
217-
218-
paths = filter(None, [
214+
paths = list(filter(None, [
219215
config_path, # 1
220-
environment_path, # 2
221-
os.path.join(os.path.expanduser('~'), DOCKER_CONFIG_FILENAME), # 3
222-
os.path.join(
223-
os.path.expanduser('~'), LEGACY_DOCKER_CONFIG_FILENAME
224-
) # 4
225-
])
216+
config_path_from_environment(), # 2
217+
os.path.join(home_dir(), DOCKER_CONFIG_FILENAME), # 3
218+
os.path.join(home_dir(), LEGACY_DOCKER_CONFIG_FILENAME), # 4
219+
]))
226220

227221
log.debug("Trying paths: {0}".format(repr(paths)))
228222

@@ -236,6 +230,24 @@ def find_config_file(config_path=None):
236230
return None
237231

238232

233+
def config_path_from_environment():
234+
config_dir = os.environ.get('DOCKER_CONFIG')
235+
if not config_dir:
236+
return None
237+
return os.path.join(config_dir, os.path.basename(DOCKER_CONFIG_FILENAME))
238+
239+
240+
def home_dir():
241+
"""
242+
Get the user's home directory, using the same logic as the Docker Engine
243+
client - use %USERPROFILE% on Windows, $HOME/getuid on POSIX.
244+
"""
245+
if IS_WINDOWS_PLATFORM:
246+
return os.environ.get('USERPROFILE', '')
247+
else:
248+
return os.path.expanduser('~')
249+
250+
239251
def load_config(config_path=None):
240252
"""
241253
Loads authentication data from a Docker configuration file in the given

tests/unit/auth_test.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import tempfile
1010
import unittest
1111

12+
from py.test import ensuretemp
13+
from pytest import mark
14+
1215
from docker import auth, errors
1316

1417
try:
@@ -269,6 +272,56 @@ def test_resolve_registry_and_auth_unauthenticated_registry(self):
269272
)
270273

271274

275+
class FindConfigFileTest(unittest.TestCase):
276+
def tmpdir(self, name):
277+
tmpdir = ensuretemp(name)
278+
self.addCleanup(tmpdir.remove)
279+
return tmpdir
280+
281+
def test_find_config_fallback(self):
282+
tmpdir = self.tmpdir('test_find_config_fallback')
283+
284+
with mock.patch.dict(os.environ, {'HOME': str(tmpdir)}):
285+
assert auth.find_config_file() is None
286+
287+
def test_find_config_from_explicit_path(self):
288+
tmpdir = self.tmpdir('test_find_config_from_explicit_path')
289+
config_path = tmpdir.ensure('my-config-file.json')
290+
291+
assert auth.find_config_file(str(config_path)) == str(config_path)
292+
293+
def test_find_config_from_environment(self):
294+
tmpdir = self.tmpdir('test_find_config_from_environment')
295+
config_path = tmpdir.ensure('config.json')
296+
297+
with mock.patch.dict(os.environ, {'DOCKER_CONFIG': str(tmpdir)}):
298+
assert auth.find_config_file() == str(config_path)
299+
300+
@mark.skipif("sys.platform == 'win32'")
301+
def test_find_config_from_home_posix(self):
302+
tmpdir = self.tmpdir('test_find_config_from_home_posix')
303+
config_path = tmpdir.ensure('.docker', 'config.json')
304+
305+
with mock.patch.dict(os.environ, {'HOME': str(tmpdir)}):
306+
assert auth.find_config_file() == str(config_path)
307+
308+
@mark.skipif("sys.platform == 'win32'")
309+
def test_find_config_from_home_legacy_name(self):
310+
tmpdir = self.tmpdir('test_find_config_from_home_legacy_name')
311+
config_path = tmpdir.ensure('.dockercfg')
312+
313+
with mock.patch.dict(os.environ, {'HOME': str(tmpdir)}):
314+
assert auth.find_config_file() == str(config_path)
315+
316+
@mark.skipif("sys.platform != 'win32'")
317+
def test_find_config_from_home_windows(self):
318+
tmpdir = self.tmpdir('test_find_config_from_home_windows')
319+
config_path = tmpdir.ensure('.docker', 'config.json')
320+
321+
with mock.patch.dict(os.environ, {'USERPROFILE': str(tmpdir)}):
322+
assert auth.find_config_file() == str(config_path)
323+
324+
272325
class LoadConfigTest(unittest.TestCase):
273326
def test_load_config_no_file(self):
274327
folder = tempfile.mkdtemp()

0 commit comments

Comments
 (0)