From 5d244ef6d89f79bb9323b2ecf74a7895d7a46b8d Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Fri, 22 Apr 2016 14:45:51 -0700 Subject: [PATCH 1/3] Unset env vars behavior in 'run' mirroring engine Unset env vars passed to `run` via command line options take the value of the system's var with the same name. Signed-off-by: Joffrey F --- compose/cli/main.py | 4 +++- compose/config/environment.py | 12 ++++++++++++ tests/acceptance/cli_test.py | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/compose/cli/main.py b/compose/cli/main.py index ae0175d5..5d2b4fa2 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -891,7 +891,9 @@ def build_container_options(options, detach, command): } if options['-e']: - container_options['environment'] = parse_environment(options['-e']) + container_options['environment'] = Environment.from_command_line( + parse_environment(options['-e']) + ) if options['--entrypoint']: container_options['entrypoint'] = options.get('--entrypoint') diff --git a/compose/config/environment.py b/compose/config/environment.py index ff08b771..5d6b5af6 100644 --- a/compose/config/environment.py +++ b/compose/config/environment.py @@ -60,6 +60,18 @@ class Environment(dict): instance.update(os.environ) return instance + @classmethod + def from_command_line(cls, parsed_env_opts): + result = cls() + for k, v in parsed_env_opts.items(): + # Values from the command line take priority, unless they're unset + # in which case they take the value from the system's environment + if v is None and k in os.environ: + result[k] = os.environ[k] + else: + result[k] = v + return result + def __getitem__(self, key): try: return super(Environment, self).__getitem__(key) diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 7b1785ee..43fe5650 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -1216,6 +1216,14 @@ class CLITestCase(DockerClientTestCase): 'simplecomposefile_simple_run_1', 'exited')) + @mock.patch.dict(os.environ) + def test_run_env_values_from_system(self): + os.environ['FOO'] = 'bar' + os.environ['BAR'] = 'baz' + result = self.dispatch(['run', '-e', 'FOO', 'simple', 'env'], None) + assert 'FOO=bar' in result.stdout + assert 'BAR=baz' not in result.stdout + def test_rm(self): service = self.project.get_service('simple') service.create_container() From 10ae81f8cf94b71bdea03bcb622d972baf39f011 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Thu, 30 Jun 2016 15:18:05 -0700 Subject: [PATCH 2/3] Post-merge fix - restore Environment import in main.py Signed-off-by: Aanand Prasad --- compose/cli/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/compose/cli/main.py b/compose/cli/main.py index 5d2b4fa2..f4c17167 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -19,6 +19,7 @@ from ..bundle import MissingDigests from ..bundle import serialize_bundle from ..config import ConfigurationError from ..config import parse_environment +from ..config.environment import Environment from ..config.serialize import serialize_config from ..const import DEFAULT_TIMEOUT from ..const import IS_WINDOWS_PLATFORM From 50d5aab8adbb4463aec49e31d0b90080de3733e3 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Thu, 30 Jun 2016 16:26:12 -0700 Subject: [PATCH 3/3] Fix test: check container's Env array instead of the output of 'env' Signed-off-by: Aanand Prasad --- tests/acceptance/cli_test.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 43fe5650..64662654 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -1220,9 +1220,13 @@ class CLITestCase(DockerClientTestCase): def test_run_env_values_from_system(self): os.environ['FOO'] = 'bar' os.environ['BAR'] = 'baz' - result = self.dispatch(['run', '-e', 'FOO', 'simple', 'env'], None) - assert 'FOO=bar' in result.stdout - assert 'BAR=baz' not in result.stdout + + self.dispatch(['run', '-e', 'FOO', 'simple', 'true'], None) + + container = self.project.containers(one_off=OneOffFilter.only, stopped=True)[0] + environment = container.get('Config.Env') + assert 'FOO=bar' in environment + assert 'BAR=baz' not in environment def test_rm(self): service = self.project.get_service('simple')