diff --git a/changelogs/fragments/192-docker_compose-profiles-idempotency-fix.yml b/changelogs/fragments/192-docker_compose-profiles-idempotency-fix.yml new file mode 100644 index 00000000..478943c0 --- /dev/null +++ b/changelogs/fragments/192-docker_compose-profiles-idempotency-fix.yml @@ -0,0 +1,4 @@ +--- +bugfixes: + - docker_compose - fixed incorrect ``changed`` status for services with ``profiles`` defined, but none enabled + (https://github.com/ansible-collections/community.docker/pull/192). diff --git a/plugins/modules/docker_compose.py b/plugins/modules/docker_compose.py index edb2d672..0eb9d04e 100644 --- a/plugins/modules/docker_compose.py +++ b/plugins/modules/docker_compose.py @@ -790,6 +790,8 @@ class ContainerManager(DockerBaseClass): # In case the only action is starting, and the user requested # that the service should be stopped, ignore this service. continue + if not self._service_profile_enabled(service): + continue if plan.action != 'noop': result['changed'] = True result_action = dict(service=service.name) @@ -1010,6 +1012,14 @@ class ContainerManager(DockerBaseClass): )) return result + def _service_profile_enabled(self, service): + """Returns `True` if the service has no profiles defined or has a profile which is among + the profiles passed to the `docker compose up` command. Otherwise returns `False`. + """ + if LooseVersion(compose_version) < LooseVersion('1.28.0'): + return True + return service.enabled_for_profiles(self.profiles or []) + def cmd_down(self): result = dict( changed=False, diff --git a/tests/integration/targets/docker_compose/tasks/tests/options.yml b/tests/integration/targets/docker_compose/tasks/tests/options.yml index 48c364a5..ff9406cd 100644 --- a/tests/integration/targets/docker_compose/tasks/tests/options.yml +++ b/tests/integration/targets/docker_compose/tasks/tests/options.yml @@ -30,6 +30,7 @@ - profile_all stop_grace_period: 1s test_cases: + - test_name: no services enabled - test_name: enable 1 profiles_value: - profile_1 @@ -61,7 +62,7 @@ docker_compose: project_name: "{{ pname }}" definition: "{{ test_service | from_yaml }}" - profiles: "{{ test_case.profiles_value }}" + profiles: "{{ test_case.profiles_value | default(omit) }}" stopped: "{{ test_case.stopped_value | default(omit) }}" state: present register: profiles_outputs @@ -77,20 +78,21 @@ - assert: that: - - profiles_outputs.results[0].services[cname_1][cname_1_name].state.running - - profiles_outputs.results[0].services[cname_2] == {} - - not profiles_outputs.results[1].services[cname_1][cname_1_name].state.running + - profiles_outputs.results[0] is not changed + - profiles_outputs.results[1].services[cname_1][cname_1_name].state.running - profiles_outputs.results[1].services[cname_2] == {} - not profiles_outputs.results[2].services[cname_1][cname_1_name].state.running - - profiles_outputs.results[2].services[cname_2][cname_2_name].state.running + - profiles_outputs.results[2].services[cname_2] == {} - not profiles_outputs.results[3].services[cname_1][cname_1_name].state.running - - not profiles_outputs.results[3].services[cname_2][cname_2_name].state.running - - profiles_outputs.results[4].services[cname_1][cname_1_name].state.running - - profiles_outputs.results[4].services[cname_2][cname_2_name].state.running - - not profiles_outputs.results[5].services[cname_1][cname_1_name].state.running - - not profiles_outputs.results[5].services[cname_2][cname_2_name].state.running - - profiles_outputs.results[6].services[cname_1][cname_1_name].state.running - - profiles_outputs.results[6].services[cname_2][cname_2_name].state.running + - profiles_outputs.results[3].services[cname_2][cname_2_name].state.running + - not profiles_outputs.results[4].services[cname_1][cname_1_name].state.running + - not profiles_outputs.results[4].services[cname_2][cname_2_name].state.running + - profiles_outputs.results[5].services[cname_1][cname_1_name].state.running + - profiles_outputs.results[5].services[cname_2][cname_2_name].state.running + - not profiles_outputs.results[6].services[cname_1][cname_1_name].state.running + - not profiles_outputs.results[6].services[cname_2][cname_2_name].state.running + - profiles_outputs.results[7].services[cname_1][cname_1_name].state.running + - profiles_outputs.results[7].services[cname_2][cname_2_name].state.running vars: cname_1_name: "{{ pname + '_' + cname_1 + '_1' }}" cname_2_name: "{{ pname + '_' + cname_2 + '_1' }}"