Preserve security_opt values in extends

Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
Joffrey F 2018-03-08 18:03:54 -08:00
parent 331f86c7ce
commit 7e3bbef436
3 changed files with 31 additions and 1 deletions

View File

@ -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=[])

View File

@ -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

View File

@ -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):