mirror of
https://github.com/containers/podman-compose.git
synced 2024-11-22 07:53:16 +01:00
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))
|
||||
ver = compose.get('version')
|
||||
services = compose.get('services')
|
||||
|
||||
services = self._resolve_service_extends(services)
|
||||
|
||||
# volumes: [...]
|
||||
shared_vols = compose.get('volumes', {})
|
||||
# shared_vols = list(shared_vols.keys())
|
||||
@ -821,6 +824,62 @@ class PodmanCompose:
|
||||
self.containers = 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):
|
||||
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