From 7e3bbef4369d0bcb9ed1e64a13ddbbb2961874a4 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Thu, 8 Mar 2018 18:03:54 -0800 Subject: [PATCH] Preserve security_opt values in extends Signed-off-by: Joffrey F --- compose/config/config.py | 3 ++- compose/config/types.py | 6 ++++++ tests/unit/config/config_test.py | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/compose/config/config.py b/compose/config/config.py index 0b5c7df0a..508ceafbf 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -1039,6 +1039,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']: @@ -1046,7 +1047,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=[]) diff --git a/compose/config/types.py b/compose/config/types.py index 47e7222a3..ff9875218 100644 --- a/compose/config/types.py +++ b/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 diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py index e03298221..7a9bb944d 100644 --- a/tests/unit/config/config_test.py +++ b/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):