diff --git a/README.md b/README.md index c3d706041e498f2fafad9ebf9f7629e89475ddfa..9cd5e996e58360f4cc5eb7ee98dc34909fbf32e0 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 cee24d419a230ec3103a882acfe577c332ce66af..a12691fd06ef77f77e8e846057a1413ed1158557 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 cd136a6afeeaf805609d9869a63128c78cbc77d5..6aed18c6778c626933aa714ee86208990b5974db 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