Browse Source

Pass environment when calling through to docker cli.

This ensures that settings from any `.env` file (such as `DOCKER_HOST`) are
passed on to the cli.

Unit tests are adjusted for the new parameter and a new case is added to ensure
it is propagated as expected.

Fixes: 6661

Signed-off-by: Ian Campbell <[email protected]>
Ian Campbell 6 years ago
parent
commit
9d2508cf58
2 changed files with 19 additions and 11 deletions
  1. 4 5
      compose/cli/main.py
  2. 15 6
      tests/unit/cli/main_test.py

+ 4 - 5
compose/cli/main.py

@@ -516,7 +516,7 @@ class TopLevelCommand(object):
         if IS_WINDOWS_PLATFORM or use_cli and not detach:
         if IS_WINDOWS_PLATFORM or use_cli and not detach:
             sys.exit(call_docker(
             sys.exit(call_docker(
                 build_exec_command(options, container.id, command),
                 build_exec_command(options, container.id, command),
-                self.toplevel_options)
+                self.toplevel_options, environment)
             )
             )
 
 
         create_exec_options = {
         create_exec_options = {
@@ -1361,7 +1361,6 @@ def run_one_off_container(container_options, project, service, options, toplevel
     environment_file = options.get('--env-file')
     environment_file = options.get('--env-file')
     environment = Environment.from_env_file(project_dir, environment_file)
     environment = Environment.from_env_file(project_dir, environment_file)
     use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI')
     use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI')
-
     signals.set_signal_handler_to_shutdown()
     signals.set_signal_handler_to_shutdown()
     signals.set_signal_handler_to_hang_up()
     signals.set_signal_handler_to_hang_up()
     try:
     try:
@@ -1370,7 +1369,7 @@ def run_one_off_container(container_options, project, service, options, toplevel
                 service.connect_container_to_networks(container, use_network_aliases)
                 service.connect_container_to_networks(container, use_network_aliases)
                 exit_code = call_docker(
                 exit_code = call_docker(
                     ["start", "--attach", "--interactive", container.id],
                     ["start", "--attach", "--interactive", container.id],
-                    toplevel_options
+                    toplevel_options, environment
                 )
                 )
             else:
             else:
                 operation = RunOperation(
                 operation = RunOperation(
@@ -1450,7 +1449,7 @@ def exit_if(condition, message, exit_code):
         raise SystemExit(exit_code)
         raise SystemExit(exit_code)
 
 
 
 
-def call_docker(args, dockeropts):
+def call_docker(args, dockeropts, environment):
     executable_path = find_executable('docker')
     executable_path = find_executable('docker')
     if not executable_path:
     if not executable_path:
         raise UserError(errors.docker_not_found_msg("Couldn't find `docker` binary."))
         raise UserError(errors.docker_not_found_msg("Couldn't find `docker` binary."))
@@ -1480,7 +1479,7 @@ def call_docker(args, dockeropts):
     args = [executable_path] + tls_options + args
     args = [executable_path] + tls_options + args
     log.debug(" ".join(map(pipes.quote, args)))
     log.debug(" ".join(map(pipes.quote, args)))
 
 
-    return subprocess.call(args)
+    return subprocess.call(args, env=environment)
 
 
 
 
 def parse_scale_args(options):
 def parse_scale_args(options):

+ 15 - 6
tests/unit/cli/main_test.py

@@ -123,13 +123,13 @@ def mock_find_executable(exe):
 class TestCallDocker(object):
 class TestCallDocker(object):
     def test_simple_no_options(self):
     def test_simple_no_options(self):
         with mock.patch('subprocess.call') as fake_call:
         with mock.patch('subprocess.call') as fake_call:
-            call_docker(['ps'], {})
+            call_docker(['ps'], {}, {})
 
 
         assert fake_call.call_args[0][0] == ['docker', 'ps']
         assert fake_call.call_args[0][0] == ['docker', 'ps']
 
 
     def test_simple_tls_option(self):
     def test_simple_tls_option(self):
         with mock.patch('subprocess.call') as fake_call:
         with mock.patch('subprocess.call') as fake_call:
-            call_docker(['ps'], {'--tls': True})
+            call_docker(['ps'], {'--tls': True}, {})
 
 
         assert fake_call.call_args[0][0] == ['docker', '--tls', 'ps']
         assert fake_call.call_args[0][0] == ['docker', '--tls', 'ps']
 
 
@@ -140,7 +140,7 @@ class TestCallDocker(object):
                 '--tlscacert': './ca.pem',
                 '--tlscacert': './ca.pem',
                 '--tlscert': './cert.pem',
                 '--tlscert': './cert.pem',
                 '--tlskey': './key.pem',
                 '--tlskey': './key.pem',
-            })
+            }, {})
 
 
         assert fake_call.call_args[0][0] == [
         assert fake_call.call_args[0][0] == [
             'docker', '--tls', '--tlscacert', './ca.pem', '--tlscert',
             'docker', '--tls', '--tlscacert', './ca.pem', '--tlscert',
@@ -149,7 +149,7 @@ class TestCallDocker(object):
 
 
     def test_with_host_option(self):
     def test_with_host_option(self):
         with mock.patch('subprocess.call') as fake_call:
         with mock.patch('subprocess.call') as fake_call:
-            call_docker(['ps'], {'--host': 'tcp://mydocker.net:2333'})
+            call_docker(['ps'], {'--host': 'tcp://mydocker.net:2333'}, {})
 
 
         assert fake_call.call_args[0][0] == [
         assert fake_call.call_args[0][0] == [
             'docker', '--host', 'tcp://mydocker.net:2333', 'ps'
             'docker', '--host', 'tcp://mydocker.net:2333', 'ps'
@@ -157,7 +157,7 @@ class TestCallDocker(object):
 
 
     def test_with_http_host(self):
     def test_with_http_host(self):
         with mock.patch('subprocess.call') as fake_call:
         with mock.patch('subprocess.call') as fake_call:
-            call_docker(['ps'], {'--host': 'http://mydocker.net:2333'})
+            call_docker(['ps'], {'--host': 'http://mydocker.net:2333'}, {})
 
 
         assert fake_call.call_args[0][0] == [
         assert fake_call.call_args[0][0] == [
             'docker', '--host', 'tcp://mydocker.net:2333', 'ps',
             'docker', '--host', 'tcp://mydocker.net:2333', 'ps',
@@ -165,8 +165,17 @@ class TestCallDocker(object):
 
 
     def test_with_host_option_shorthand_equal(self):
     def test_with_host_option_shorthand_equal(self):
         with mock.patch('subprocess.call') as fake_call:
         with mock.patch('subprocess.call') as fake_call:
-            call_docker(['ps'], {'--host': '=tcp://mydocker.net:2333'})
+            call_docker(['ps'], {'--host': '=tcp://mydocker.net:2333'}, {})
 
 
         assert fake_call.call_args[0][0] == [
         assert fake_call.call_args[0][0] == [
             'docker', '--host', 'tcp://mydocker.net:2333', 'ps'
             'docker', '--host', 'tcp://mydocker.net:2333', 'ps'
         ]
         ]
+
+    def test_with_env(self):
+        with mock.patch('subprocess.call') as fake_call:
+            call_docker(['ps'], {}, {'DOCKER_HOST': 'tcp://mydocker.net:2333'})
+
+        assert fake_call.call_args[0][0] == [
+            'docker', 'ps'
+        ]
+        assert fake_call.call_args[1]['env'] == {'DOCKER_HOST': 'tcp://mydocker.net:2333'}