瀏覽代碼

Merge pull request #5769 from docker/5766-fix-secopt-extend

Preserve security_opt values in extends
Joffrey F 7 年之前
父節點
當前提交
867ad1550b
共有 3 個文件被更改,包括 31 次插入1 次删除
  1. 2 1
      compose/config/config.py
  2. 6 0
      compose/config/types.py
  3. 23 0
      tests/unit/config/config_test.py

+ 2 - 1
compose/config/config.py

@@ -1040,6 +1040,7 @@ def merge_service_dicts(base, override, version):
     md.merge_sequence('links', ServiceLink.parse)
     md.merge_sequence('secrets', types.ServiceSecret.parse)
     md.merge_sequence('configs', types.ServiceConfig.parse)
+    md.merge_sequence('security_opt', types.SecurityOpt.parse)
     md.merge_mapping('extra_hosts', parse_extra_hosts)
 
     for field in ['volumes', 'devices']:
@@ -1047,7 +1048,7 @@ def merge_service_dicts(base, override, version):
 
     for field in [
         'cap_add', 'cap_drop', 'expose', 'external_links',
-        'security_opt', 'volumes_from', 'device_cgroup_rules',
+        'volumes_from', 'device_cgroup_rules',
     ]:
         md.merge_field(field, merge_unique_items_lists, default=[])
 

+ 6 - 0
compose/config/types.py

@@ -464,6 +464,8 @@ def normalize_port_dict(port):
 class SecurityOpt(namedtuple('_SecurityOpt', 'value src_file')):
     @classmethod
     def parse(cls, value):
+        if not isinstance(value, six.string_types):
+            return value
         # based on https://github.com/docker/cli/blob/9de1b162f/cli/command/container/opts.go#L673-L697
         con = value.split('=', 2)
         if len(con) == 1 and con[0] != 'no-new-privileges':
@@ -486,3 +488,7 @@ class SecurityOpt(namedtuple('_SecurityOpt', 'value src_file')):
         if self.src_file is not None:
             return 'seccomp:{}'.format(self.src_file)
         return self.value
+
+    @property
+    def merge_field(self):
+        return self.value

+ 23 - 0
tests/unit/config/config_test.py

@@ -4508,6 +4508,29 @@ class ExtendsTest(unittest.TestCase):
         for svc in services:
             assert svc['ports'] == [types.ServicePort('80', None, None, None, None)]
 
+    def test_extends_with_security_opt(self):
+        tmpdir = py.test.ensuretemp('test_extends_with_ports')
+        self.addCleanup(tmpdir.remove)
+        tmpdir.join('docker-compose.yml').write("""
+            version: '2'
+
+            services:
+              a:
+                image: nginx
+                security_opt:
+                  - apparmor:unconfined
+                  - seccomp:unconfined
+
+              b:
+                extends:
+                  service: a
+        """)
+        services = load_from_filename(str(tmpdir.join('docker-compose.yml')))
+        assert len(services) == 2
+        for svc in services:
+            assert types.SecurityOpt.parse('apparmor:unconfined') in svc['security_opt']
+            assert types.SecurityOpt.parse('seccomp:unconfined') in svc['security_opt']
+
 
 @pytest.mark.xfail(IS_WINDOWS_PLATFORM, reason='paths use slash')
 class ExpandPathTest(unittest.TestCase):