From 0ebc3e0a088df8828e656310879a9c0a82c0413f Mon Sep 17 00:00:00 2001 From: Zsombor Welker <fedora@zdeqb.com> Date: Mon, 4 Jul 2022 11:10:41 +0200 Subject: [PATCH] Add compose short names This allows compose service names to be used without the project name. --- README.md | 7 ++++- src/systemd_resolved_docker/dockerwatcher.py | 26 +++++++++++++----- test/integration/test_compose.sh | 28 +++++++++++++++++--- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index c3d7060..9cd5e99 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,12 @@ an exact match is required. If a generated domain address doesn't match the list ``` When the project's name is in the list of _allowed domains_ (`ALLOWED_DOMAINS=.docker,.someproject`), then the - `default_domain` will not be appended: + `default_domain` will not be appended. + + If a `<service>` name is unique, then it is available also as `<service>.<default_domain>`. + ``` + host webserver.docker # webserver.docker has address 172.16.238.3 + ``` If configured correctly then `resolvectl status` should show the configured link-specific DNS server: diff --git a/src/systemd_resolved_docker/dockerwatcher.py b/src/systemd_resolved_docker/dockerwatcher.py index cee24d4..a12691f 100644 --- a/src/systemd_resolved_docker/dockerwatcher.py +++ b/src/systemd_resolved_docker/dockerwatcher.py @@ -42,6 +42,9 @@ class DockerWatcher(Thread): def collect_from_containers(self): domain_records = {} + non_unique_hostnames = set() + duplicate_hostnames = set() + for c in self.cli.containers.list(): common_hostnames = [] @@ -64,14 +67,20 @@ class DockerWatcher(Thread): # for docker-compose services service.project (.docker) names are created if c.attrs['Config'].get('Labels') and c.attrs['Config']['Labels'].get('com.docker.compose.service') and \ c.attrs['Config']['Labels'].get('com.docker.compose.project'): - common_hostnames.append("%s.%s" % (c.attrs['Config']['Labels'].get('com.docker.compose.service'), - c.attrs['Config']['Labels'].get('com.docker.compose.project'))) + compose_service = c.attrs['Config']['Labels'].get('com.docker.compose.service') + compose_project = c.attrs['Config']['Labels'].get('com.docker.compose.project') + + common_hostnames.append(compose_service) + common_hostnames.append("%s.%s" % (compose_service, compose_project)) - if c.attrs['Config']['Labels'].get('com.docker.compose.container-number'): - common_hostnames.append("%s.%s.%s" % (c.attrs['Config']['Labels'].get('com.docker.compose.container-number'), - c.attrs['Config']['Labels'].get('com.docker.compose.service'), - c.attrs['Config']['Labels'].get( - 'com.docker.compose.project'))) + if compose_service in non_unique_hostnames: + duplicate_hostnames.add(compose_service) + else: + non_unique_hostnames.add(compose_service) + + compose_container_number = c.attrs['Config']['Labels'].get('com.docker.compose.container-number') + if compose_container_number: + common_hostnames.append("%s.%s.%s" % (compose_container_number, compose_service, compose_project)) name = c.attrs['Name'][1:] settings = c.attrs['NetworkSettings'] @@ -93,6 +102,9 @@ class DockerWatcher(Thread): domain_records[ip] = record + for ip, hosts in domain_records.items(): + domain_records[ip] = list(filter(lambda h: h not in duplicate_hostnames, hosts)) + hostnames = [DockerHost(hosts, ip) for ip, hosts in domain_records.items()] self.handler.handle_hosts(hostnames) diff --git a/test/integration/test_compose.sh b/test/integration/test_compose.sh index cd136a6..6aed18c 100755 --- a/test/integration/test_compose.sh +++ b/test/integration/test_compose.sh @@ -26,9 +26,26 @@ networks: - $TEST_LABEL ipam: driver: default - config: - - subnet: 172.16.238.0/24 - gateway: 172.16.238.1 +EOF + +exec 20<<EOF +version: "2.1" +services: + broker: + image: redis + labels: + - $TEST_LABEL + networks: + - network + +networks: + network: + driver: bridge + enable_ipv6: false + labels: + - $TEST_LABEL + ipam: + driver: default EOF ALLOWED_DOMAINS=.docker,.$TEST_PREFIX start_systemd_resolved_docker @@ -46,3 +63,8 @@ query_ok webserver.$TEST_PREFIX $webserver1_ip query_ok webserver.$TEST_PREFIX $webserver2_ip query_ok 1.webserver.$TEST_PREFIX $webserver1_ip query_ok 2.webserver.$TEST_PREFIX $webserver2_ip + +query_ok broker.docker $broker1_ip + +docker-compose --file /dev/fd/20 --project-name ${TEST_PREFIX}_2 up --detach +query_fail broker.docker -- GitLab