mirror of https://github.com/docker/docker-py.git
Make sure the build command in the client sends the auth credentials along. Required for "FROM " lines that pull from private registries
This commit is contained in:
parent
2d56149831
commit
9ae3bcd2f3
|
@ -87,6 +87,10 @@ def resolve_authconfig(authconfig, registry=None):
|
|||
return authconfig.get(swap_protocol(registry), None)
|
||||
|
||||
|
||||
def encode_auth(auth_info):
|
||||
return base64.b64encode(auth_info.get('username', '') + b':' +
|
||||
auth_info.get('password', ''))
|
||||
|
||||
def decode_auth(auth):
|
||||
if isinstance(auth, six.string_types):
|
||||
auth = auth.encode('ascii')
|
||||
|
@ -100,6 +104,12 @@ def encode_header(auth):
|
|||
return base64.b64encode(auth_json)
|
||||
|
||||
|
||||
def encode_full_header(auth):
|
||||
""" Returns the given auth block encoded for the X-Registry-Config header.
|
||||
"""
|
||||
return encode_header({'configs': auth})
|
||||
|
||||
|
||||
def load_config(root=None):
|
||||
"""Loads authentication data from a Docker configuration file in the given
|
||||
root directory."""
|
||||
|
|
|
@ -28,7 +28,7 @@ from .utils import utils
|
|||
if not six.PY3:
|
||||
import websocket
|
||||
|
||||
DEFAULT_DOCKER_API_VERSION = '1.8'
|
||||
DEFAULT_DOCKER_API_VERSION = '1.9'
|
||||
DEFAULT_TIMEOUT_SECONDS = 60
|
||||
STREAM_HEADER_SIZE_BYTES = 8
|
||||
|
||||
|
@ -361,6 +361,17 @@ class Client(requests.Session):
|
|||
if context is not None:
|
||||
headers = {'Content-Type': 'application/tar'}
|
||||
|
||||
if utils.compare_version('1.9', self._version) >= 0:
|
||||
# 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 not self._auth_configs:
|
||||
self._auth_configs = auth.load_config()
|
||||
|
||||
# Send the full auth configuration (if any exists), since the build
|
||||
# could use any (or all) of the registries.
|
||||
if self._auth_configs:
|
||||
headers['X-Registry-Config'] = auth.encode_full_header(self._auth_configs)
|
||||
|
||||
response = self._post(
|
||||
u,
|
||||
data=context,
|
||||
|
@ -618,7 +629,7 @@ class Client(requests.Session):
|
|||
self._auth_configs = auth.load_config()
|
||||
authcfg = auth.resolve_authconfig(self._auth_configs, registry)
|
||||
|
||||
# Do not fail here if no atuhentication exists for this specific
|
||||
# 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.
|
||||
if authcfg:
|
||||
|
@ -644,7 +655,7 @@ class Client(requests.Session):
|
|||
self._auth_configs = auth.load_config()
|
||||
authcfg = auth.resolve_authconfig(self._auth_configs, registry)
|
||||
|
||||
# Do not fail here if no atuhentication exists for this specific
|
||||
# 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.
|
||||
if authcfg:
|
||||
|
|
|
@ -32,7 +32,7 @@ class BaseTestCase(unittest.TestCase):
|
|||
tmp_containers = []
|
||||
|
||||
def setUp(self):
|
||||
self.client = docker.Client()
|
||||
self.client = docker.Client(base_url='http://localhost:4243')
|
||||
self.client.pull('busybox')
|
||||
self.tmp_imgs = []
|
||||
self.tmp_containers = []
|
||||
|
@ -755,6 +755,29 @@ class TestBuildFromStringIO(BaseTestCase):
|
|||
self.assertNotEqual(logs, '')
|
||||
|
||||
|
||||
class TestBuildWithAuth(BaseTestCase):
|
||||
def runTest(self):
|
||||
if self.client._version < 1.9:
|
||||
return
|
||||
|
||||
key = 'K4104GON3P4Q6ZUJFZRRC2ZQTBJ5YT0UMZD7TGT7ZVIR8Y05FAH2TJQI6Y90SMIB'
|
||||
self.client.login('quay+fortesting', key, registry='https://quay.io/v1/', email='')
|
||||
|
||||
script = io.BytesIO('\n'.join([
|
||||
'FROM quay.io/quay/teststuff',
|
||||
'MAINTAINER docker-py',
|
||||
'RUN mkdir -p /tmp/test',
|
||||
]).encode('ascii'))
|
||||
|
||||
stream = self.client.build(fileobj=script, stream=True)
|
||||
logs = ''
|
||||
for chunk in stream:
|
||||
logs += chunk
|
||||
|
||||
self.assertNotEqual(logs, '')
|
||||
self.assertEqual(logs.find('HTTP code: 403'), -1)
|
||||
|
||||
|
||||
#######################
|
||||
# PY SPECIFIC TESTS #
|
||||
#######################
|
||||
|
@ -820,7 +843,7 @@ class TestLoadJSONConfig(BaseTestCase):
|
|||
class TestConnectionTimeout(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.timeout = 0.5
|
||||
self.client = docker.client.Client(base_url='http://192.168.10.2:4243',
|
||||
self.client = docker.client.Client(base_url='http://localhost:4243',
|
||||
timeout=self.timeout)
|
||||
|
||||
def runTest(self):
|
||||
|
|
Loading…
Reference in New Issue