diff --git a/docker/api/build.py b/docker/api/build.py index dab06d5d..53c94b0d 100644 --- a/docker/api/build.py +++ b/docker/api/build.py @@ -19,7 +19,8 @@ class BuildApiMixin(object): forcerm=False, dockerfile=None, container_limits=None, decode=False, buildargs=None, gzip=False, shmsize=None, labels=None, cache_from=None, target=None, network_mode=None, - squash=None, extra_hosts=None, platform=None, isolation=None): + squash=None, extra_hosts=None, platform=None, isolation=None, + use_config_proxy=False): """ Similar to the ``docker build`` command. Either ``path`` or ``fileobj`` needs to be set. ``path`` can be a local path (to a directory @@ -103,6 +104,10 @@ class BuildApiMixin(object): platform (str): Platform in the format ``os[/arch[/variant]]`` isolation (str): Isolation technology used during build. Default: `None`. + use_config_proxy (bool): If ``True``, and if the docker client + configuration file (``~/.docker/config.json`` by default) + contains a proxy configuration, the corresponding environment + variables will be set in the container being built. Returns: A generator for the build output. @@ -168,9 +173,10 @@ class BuildApiMixin(object): } params.update(container_limits) - proxy_args = self._proxy_configs.get_environment() - for k, v in proxy_args.items(): - buildargs.setdefault(k, v) + if use_config_proxy: + proxy_args = self._proxy_configs.get_environment() + for k, v in proxy_args.items(): + buildargs.setdefault(k, v) if buildargs: params.update({'buildargs': json.dumps(buildargs)}) diff --git a/docker/api/container.py b/docker/api/container.py index 2a80ff7d..54f9950f 100644 --- a/docker/api/container.py +++ b/docker/api/container.py @@ -221,7 +221,8 @@ class ContainerApiMixin(object): working_dir=None, domainname=None, host_config=None, mac_address=None, labels=None, stop_signal=None, networking_config=None, healthcheck=None, - stop_timeout=None, runtime=None): + stop_timeout=None, runtime=None, + use_config_proxy=False): """ Creates a container. Parameters are similar to those for the ``docker run`` command except it doesn't support the attach options (``-a``). @@ -390,6 +391,10 @@ class ContainerApiMixin(object): runtime (str): Runtime to use with this container. healthcheck (dict): Specify a test to perform to check that the container is healthy. + use_config_proxy (bool): If ``True``, and if the docker client + configuration file (``~/.docker/config.json`` by default) + contains a proxy configuration, the corresponding environment + variables will be set in the container being created. Returns: A dictionary with an image 'Id' key and a 'Warnings' key. @@ -405,7 +410,9 @@ class ContainerApiMixin(object): if isinstance(environment, dict): environment = utils.utils.format_environment(environment) - environment = self._proxy_configs.inject_proxy_environment(environment) + if use_config_proxy: + environment = \ + self._proxy_configs.inject_proxy_environment(environment) config = self.create_container_config( image, command, hostname, user, detach, stdin_open, tty, diff --git a/docker/api/exec_api.py b/docker/api/exec_api.py index 0dabdd30..830432a7 100644 --- a/docker/api/exec_api.py +++ b/docker/api/exec_api.py @@ -8,7 +8,8 @@ class ExecApiMixin(object): @utils.check_resource('container') def exec_create(self, container, cmd, stdout=True, stderr=True, stdin=False, tty=False, privileged=False, user='', - environment=None, workdir=None, detach_keys=None): + environment=None, workdir=None, detach_keys=None, + use_config_proxy=False): """ Sets up an exec instance in a running container. @@ -31,6 +32,10 @@ class ExecApiMixin(object): or `ctrl-` where `` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`. ~/.docker/config.json is used by default. + use_config_proxy (bool): If ``True``, and if the docker client + configuration file (``~/.docker/config.json`` by default) + contains a proxy configuration, the corresponding environment + variables will be set in the container being created. Returns: (dict): A dictionary with an exec ``Id`` key. @@ -50,7 +55,9 @@ class ExecApiMixin(object): if isinstance(environment, dict): environment = utils.utils.format_environment(environment) - environment = self._proxy_configs.inject_proxy_environment(environment) + if use_config_proxy: + environment = \ + self._proxy_configs.inject_proxy_environment(environment) data = { 'Container': container, diff --git a/docker/models/containers.py b/docker/models/containers.py index 41bc4da8..817d5db5 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -144,7 +144,8 @@ class Container(Model): def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False, privileged=False, user='', detach=False, stream=False, - socket=False, environment=None, workdir=None, demux=False): + socket=False, environment=None, workdir=None, demux=False, + use_config_proxy=False): """ Run a command inside this container. Similar to ``docker exec``. @@ -167,6 +168,10 @@ class Container(Model): ``{"PASSWORD": "xxx"}``. workdir (str): Path to working directory for this exec session demux (bool): Return stdout and stderr separately + use_config_proxy (bool): If ``True``, and if the docker client + configuration file (``~/.docker/config.json`` by default) + contains a proxy configuration, the corresponding environment + variables will be set in the command's environment. Returns: (ExecResult): A tuple of (exit_code, output) @@ -185,7 +190,7 @@ class Container(Model): resp = self.client.api.exec_create( self.id, cmd, stdout=stdout, stderr=stderr, stdin=stdin, tty=tty, privileged=privileged, user=user, environment=environment, - workdir=workdir + workdir=workdir, use_config_proxy=use_config_proxy, ) exec_output = self.client.api.exec_start( resp['Id'], detach=detach, tty=tty, stream=stream, socket=socket, diff --git a/docker/utils/proxy.py b/docker/utils/proxy.py index 1c4fb248..c368116e 100644 --- a/docker/utils/proxy.py +++ b/docker/utils/proxy.py @@ -7,7 +7,7 @@ class ProxyConfig(dict): ''' @property def http(self): - return self['http'] + return self.get('http') @http.setter def http(self, value): @@ -15,7 +15,7 @@ class ProxyConfig(dict): @property def https(self): - return self['https'] + return self.get('https') @https.setter def https(self, value): @@ -23,7 +23,7 @@ class ProxyConfig(dict): @property def ftp(self): - return self['ftp'] + return self.get('ftp') @ftp.setter def ftp(self, value): @@ -31,7 +31,7 @@ class ProxyConfig(dict): @property def no_proxy(self): - return self['no_proxy'] + return self.get('no_proxy') @no_proxy.setter def no_proxy(self, value): diff --git a/tests/integration/api_exec_test.py b/tests/integration/api_exec_test.py index 6d4f97da..8947b413 100644 --- a/tests/integration/api_exec_test.py +++ b/tests/integration/api_exec_test.py @@ -20,10 +20,11 @@ class ExecTest(BaseAPIIntegrationTest): self.client.start(id) self.tmp_containers.append(id) + cmd = 'sh -c "env | grep -i proxy"' + # First, just make sure the environment variables from the custom # config are set - res = self.client.exec_create( - id, cmd='sh -c "env | grep -i proxy"') + res = self.client.exec_create(id, cmd=cmd, use_config_proxy=True) output = self.client.exec_start(res).decode('utf-8').split('\n') expected = [ 'ftp_proxy=a', 'https_proxy=b', 'http_proxy=c', 'no_proxy=d', @@ -34,7 +35,7 @@ class ExecTest(BaseAPIIntegrationTest): # Overwrite some variables with a custom environment env = {'https_proxy': 'xxx', 'HTTPS_PROXY': 'XXX'} res = self.client.exec_create( - id, cmd='sh -c "env | grep -i proxy"', environment=env) + id, cmd=cmd, environment=env, use_config_proxy=True) output = self.client.exec_start(res).decode('utf-8').split('\n') expected = [ 'ftp_proxy=a', 'https_proxy=xxx', 'http_proxy=c', 'no_proxy=d', diff --git a/tests/unit/models_containers_test.py b/tests/unit/models_containers_test.py index cb92c62b..b35aeb6a 100644 --- a/tests/unit/models_containers_test.py +++ b/tests/unit/models_containers_test.py @@ -416,7 +416,7 @@ class ContainerTest(unittest.TestCase): client.api.exec_create.assert_called_with( FAKE_CONTAINER_ID, "echo hello world", stdout=True, stderr=True, stdin=False, tty=False, privileged=True, user='', environment=None, - workdir=None + workdir=None, use_config_proxy=False, ) client.api.exec_start.assert_called_with( FAKE_EXEC_ID, detach=False, tty=False, stream=True, socket=False, @@ -430,7 +430,7 @@ class ContainerTest(unittest.TestCase): client.api.exec_create.assert_called_with( FAKE_CONTAINER_ID, "docker ps", stdout=True, stderr=True, stdin=False, tty=False, privileged=True, user='', environment=None, - workdir=None + workdir=None, use_config_proxy=False, ) client.api.exec_start.assert_called_with( FAKE_EXEC_ID, detach=False, tty=False, stream=False, socket=False,