浏览代码

Make environment variables without a value the same as docker-cli.

Signed-off-by: Daniel Nephin <[email protected]>
Daniel Nephin 9 年之前
父节点
当前提交
d451578152

+ 1 - 1
compose/config/config.py

@@ -827,7 +827,7 @@ def resolve_env_var(key, val):
     elif key in os.environ:
         return key, os.environ[key]
     else:
-        return key, ''
+        return key, None
 
 
 def env_vars_from_file(filename):

+ 5 - 1
compose/container.py

@@ -134,7 +134,11 @@ class Container(object):
 
     @property
     def environment(self):
-        return dict(var.split("=", 1) for var in self.get('Config.Env') or [])
+        def parse_env(var):
+            if '=' in var:
+                return var.split("=", 1)
+            return var, None
+        return dict(parse_env(var) for var in self.get('Config.Env') or [])
 
     @property
     def exit_code(self):

+ 11 - 0
compose/service.py

@@ -622,6 +622,8 @@ class Service(object):
             override_options,
             one_off=one_off)
 
+        container_options['environment'] = format_environment(
+            container_options['environment'])
         return container_options
 
     def _get_container_host_config(self, override_options, one_off=False):
@@ -1020,3 +1022,12 @@ def get_log_config(logging_dict):
         type=log_driver,
         config=log_options
     )
+
+
+# TODO: remove once fix is available in docker-py
+def format_environment(environment):
+    def format_env(key, value):
+        if value is None:
+            return key
+        return '{key}={value}'.format(key=key, value=value)
+    return [format_env(*item) for item in environment.items()]

+ 1 - 1
tests/integration/service_test.py

@@ -916,7 +916,7 @@ class ServiceTest(DockerClientTestCase):
             'FILE_DEF': 'F1',
             'FILE_DEF_EMPTY': '',
             'ENV_DEF': 'E3',
-            'NO_DEF': ''
+            'NO_DEF': None
         }.items():
             self.assertEqual(env[k], v)
 

+ 4 - 3
tests/unit/cli_test.py

@@ -138,9 +138,10 @@ class CLITestCase(unittest.TestCase):
         })
 
         _, _, call_kwargs = mock_client.create_container.mock_calls[0]
-        self.assertEqual(
-            call_kwargs['environment'],
-            {'FOO': 'ONE', 'BAR': 'NEW', 'OTHER': u'bär'})
+        assert (
+            sorted(call_kwargs['environment']) ==
+            sorted(['FOO=ONE', 'BAR=NEW', 'OTHER=bär'])
+        )
 
     def test_run_service_with_restart_always(self):
         command = TopLevelCommand()

+ 3 - 3
tests/unit/config/config_test.py

@@ -1975,7 +1975,7 @@ class EnvTest(unittest.TestCase):
         }
         self.assertEqual(
             resolve_environment(service_dict),
-            {'FILE_DEF': 'F1', 'FILE_DEF_EMPTY': '', 'ENV_DEF': 'E3', 'NO_DEF': ''},
+            {'FILE_DEF': 'F1', 'FILE_DEF_EMPTY': '', 'ENV_DEF': 'E3', 'NO_DEF': None},
         )
 
     def test_resolve_environment_from_env_file(self):
@@ -2016,7 +2016,7 @@ class EnvTest(unittest.TestCase):
                 'FILE_DEF': u'bär',
                 'FILE_DEF_EMPTY': '',
                 'ENV_DEF': 'E3',
-                'NO_DEF': ''
+                'NO_DEF': None
             },
         )
 
@@ -2035,7 +2035,7 @@ class EnvTest(unittest.TestCase):
         }
         self.assertEqual(
             resolve_build_args(build),
-            {'arg1': 'value1', 'empty_arg': '', 'env_arg': 'value2', 'no_env': ''},
+            {'arg1': 'value1', 'empty_arg': '', 'env_arg': 'value2', 'no_env': None},
         )
 
     @pytest.mark.xfail(IS_WINDOWS_PLATFORM, reason='paths use slash')

+ 3 - 3
tests/unit/service_test.py

@@ -267,7 +267,7 @@ class ServiceTest(unittest.TestCase):
         self.assertEqual(
             opts['labels'][LABEL_CONFIG_HASH],
             'f8bfa1058ad1f4231372a0b1639f0dfdb574dafff4e8d7938049ae993f7cf1fc')
-        assert opts['environment'] == {'also': 'real'}
+        assert opts['environment'] == ['also=real']
 
     def test_get_container_create_options_sets_affinity_with_binds(self):
         service = Service(
@@ -298,7 +298,7 @@ class ServiceTest(unittest.TestCase):
             1,
             previous_container=prev_container)
 
-        assert opts['environment'] == {'affinity:container': '=ababab'}
+        assert opts['environment'] == ['affinity:container==ababab']
 
     def test_get_container_create_options_no_affinity_without_binds(self):
         service = Service('foo', image='foo', client=self.mock_client)
@@ -312,7 +312,7 @@ class ServiceTest(unittest.TestCase):
             {},
             1,
             previous_container=prev_container)
-        assert opts['environment'] == {}
+        assert opts['environment'] == []
 
     def test_get_container_not_found(self):
         self.mock_client.containers.return_value = []