forked from extern/podman-compose
Support extends
https://docs.docker.com/compose/extends/ Doesn't yet support referring to another file. Needs Python 3.5+ (for merging dicts using **)
This commit is contained in:
parent
dee813a4b6
commit
3e2381f040
@ -759,6 +759,9 @@ class PodmanCompose:
|
|||||||
print(" ** merged:\n", json.dumps(compose, indent = 2))
|
print(" ** merged:\n", json.dumps(compose, indent = 2))
|
||||||
ver = compose.get('version')
|
ver = compose.get('version')
|
||||||
services = compose.get('services')
|
services = compose.get('services')
|
||||||
|
|
||||||
|
services = self._resolve_service_extends(services)
|
||||||
|
|
||||||
# volumes: [...]
|
# volumes: [...]
|
||||||
shared_vols = compose.get('volumes', {})
|
shared_vols = compose.get('volumes', {})
|
||||||
# shared_vols = list(shared_vols.keys())
|
# shared_vols = list(shared_vols.keys())
|
||||||
@ -821,6 +824,62 @@ class PodmanCompose:
|
|||||||
self.containers = containers
|
self.containers = containers
|
||||||
self.container_by_name = dict([ (c["name"], c) for c in containers])
|
self.container_by_name = dict([ (c["name"], c) for c in containers])
|
||||||
|
|
||||||
|
def _resolve_service_extends(self, services):
|
||||||
|
"""
|
||||||
|
Resolve service extends (https://docs.docker.com/compose/extends/)
|
||||||
|
TODO: Doesn't yet support file
|
||||||
|
"""
|
||||||
|
services_to_resolve = len(services)
|
||||||
|
resolved_services = {}
|
||||||
|
for service_name, service_desc in services.items():
|
||||||
|
if not "extends" in service_desc:
|
||||||
|
resolved_services[service_name] = service_desc
|
||||||
|
services_to_resolve -= 1
|
||||||
|
while services_to_resolve:
|
||||||
|
services_to_resolve_before = services_to_resolve
|
||||||
|
for service_name, service_desc in services.items():
|
||||||
|
if not service_name in resolved_services and service_desc['extends']['service'] in resolved_services:
|
||||||
|
cust_service_desc = service_desc
|
||||||
|
service_desc = resolved_services[service_desc['extends']['service']].copy()
|
||||||
|
service_desc = self._merge_service_extends(service_desc, cust_service_desc)
|
||||||
|
del(service_desc['extends'])
|
||||||
|
resolved_services[service_name] = service_desc
|
||||||
|
services_to_resolve -= 1
|
||||||
|
if services_to_resolve == services_to_resolve_before:
|
||||||
|
print('Failed to resolve extends services')
|
||||||
|
exit(-1)
|
||||||
|
return resolved_services
|
||||||
|
|
||||||
|
def _merge_service_extends(self, base, custom):
|
||||||
|
"""
|
||||||
|
Merges the service description from custom into base, as described at
|
||||||
|
https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
|
||||||
|
"""
|
||||||
|
result = base
|
||||||
|
for key, value in custom.items():
|
||||||
|
if key in ('ports', 'expose', 'external_links', 'dns', 'dns_search', 'tmpfs'):
|
||||||
|
if not key in result:
|
||||||
|
result[key] = []
|
||||||
|
result[key].extend(value)
|
||||||
|
elif key in ('environment', 'labels'):
|
||||||
|
if not key in base:
|
||||||
|
base[key] = {}
|
||||||
|
result[key] = {**base[key], **custom[key]}
|
||||||
|
elif key in ('volumes', 'devices'):
|
||||||
|
# Index by mount path, then merge
|
||||||
|
base_by_mount_path = {}
|
||||||
|
custom_by_mount_path = {}
|
||||||
|
if key in base:
|
||||||
|
for label, label_value in [[label_value_pair.split(':', 2)[1], label_value_pair] for label_value_pair in base[key] ]:
|
||||||
|
base_by_mount_path[label] = label_value
|
||||||
|
if key in custom:
|
||||||
|
for label, label_value in [[label_value_pair.split(':', 2)[1], label_value_pair] for label_value_pair in custom[key] ]:
|
||||||
|
custom_by_mount_path[label] = label_value
|
||||||
|
result[key] = list({**base_by_mount_path, **custom_by_mount_path}.values())
|
||||||
|
else:
|
||||||
|
# Single value option, replace
|
||||||
|
result[key] = value
|
||||||
|
return result
|
||||||
|
|
||||||
def _parse_args(self):
|
def _parse_args(self):
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
29
tests/extends/docker-compose.yaml
Normal file
29
tests/extends/docker-compose.yaml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
echo:
|
||||||
|
image: busybox
|
||||||
|
command: ["/bin/busybox", "echo", "Zero"]
|
||||||
|
ports:
|
||||||
|
- '1234:1234'
|
||||||
|
environment:
|
||||||
|
- FOO=original
|
||||||
|
- BAR=original
|
||||||
|
# volumes:
|
||||||
|
# - ./original:/foo
|
||||||
|
# - ./original:/bar
|
||||||
|
echo1:
|
||||||
|
extends:
|
||||||
|
service: echo
|
||||||
|
command: ["/bin/busybox", "echo", "One"]
|
||||||
|
ports:
|
||||||
|
- '12345:12345'
|
||||||
|
# volumes:
|
||||||
|
# - ./local:/bar
|
||||||
|
# - ./local:/baz
|
||||||
|
env1:
|
||||||
|
extends:
|
||||||
|
service: echo
|
||||||
|
command: ["/bin/busybox", "env"]
|
||||||
|
environment:
|
||||||
|
- BAR=local
|
||||||
|
- BAZ=local
|
Loading…
Reference in New Issue
Block a user