diff --git a/changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml b/changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml new file mode 100644 index 00000000000..3664fe8b92d --- /dev/null +++ b/changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml @@ -0,0 +1,2 @@ +bugfixes: + - "docker_swarm_service - fix use of Docker API so that services are not detected as present if there is an existing service whose name is a substring of the desired service" diff --git a/lib/ansible/modules/cloud/docker/docker_swarm_service.py b/lib/ansible/modules/cloud/docker/docker_swarm_service.py index 0294abc8ce9..3045fdbc6b4 100644 --- a/lib/ansible/modules/cloud/docker/docker_swarm_service.py +++ b/lib/ansible/modules/cloud/docker/docker_swarm_service.py @@ -875,7 +875,16 @@ class DockerServiceManager(): return [{'name': n['Name'], 'id': n['Id']} for n in self.client.networks()] def get_service(self, name): - raw_data = self.client.services(filters={'name': name}) + # The Docker API allows filtering services by name but the filter looks + # for a substring match, not an exact match. (Filtering for "foo" would + # return information for services "foobar" and "foobuzz" even if the + # service "foo" doesn't exist.) Avoid incorrectly determining that a + # service is present by filtering the list of services returned from the + # Docker API so that the name must be an exact match. + raw_data = [ + service for service in self.client.services(filters={'name': name}) + if service['Spec']['Name'] == name + ] if len(raw_data) == 0: return None