diff --git a/changelogs/fragments/167-docker_compose-profiles-option.yml b/changelogs/fragments/167-docker_compose-profiles-option.yml new file mode 100644 index 00000000..402d9a7d --- /dev/null +++ b/changelogs/fragments/167-docker_compose-profiles-option.yml @@ -0,0 +1,4 @@ +--- +minor_changes: + - docker_compose - added ``profiles`` option to specify service profiles when starting services + (https://github.com/ansible-collections/community.docker/pull/167). diff --git a/plugins/modules/docker_compose.py b/plugins/modules/docker_compose.py index 767b09f2..258704c6 100644 --- a/plugins/modules/docker_compose.py +++ b/plugins/modules/docker_compose.py @@ -42,6 +42,14 @@ options: - Files are loaded and merged in the order given. type: list elements: path + profiles: + description: + - List of profiles to enable when starting services. + - Equivalent to C(docker-compose --profile). + - Requires C(docker-compose) version 1.28.0 or greater. + type: list + elements: str + version_added: 1.8.0 state: description: - Desired state of the project. @@ -632,6 +640,9 @@ class ContainerManager(DockerBaseClass): if self.files: self.options[u'--file'] = self.files + if self.profiles: + self.options[u'--profile'] = self.profiles + if not HAS_COMPOSE: self.client.fail("Unable to load docker-compose. Try `pip install docker-compose`. Error: %s" % to_native(HAS_COMPOSE_EXC)) @@ -1114,6 +1125,7 @@ def main(): project_src=dict(type='path'), project_name=dict(type='str',), files=dict(type='list', elements='path'), + profiles=dict(type='list', elements='str'), state=dict(type='str', default='present', choices=['absent', 'present']), definition=dict(type='dict'), hostname_check=dict(type='bool', default=False), diff --git a/tests/integration/targets/docker_compose/tasks/tests/options.yml b/tests/integration/targets/docker_compose/tasks/tests/options.yml new file mode 100644 index 00000000..05f82f1a --- /dev/null +++ b/tests/integration/targets/docker_compose/tasks/tests/options.yml @@ -0,0 +1,97 @@ +--- +- name: Registering container name + set_fact: + pname: "{{ cname_prefix }}" + cname_1: "{{ cname_prefix ~ '1' }}" + cname_2: "{{ cname_prefix ~ '2' }}" + +#################################################################### +## Profiles ######################################################## +#################################################################### + +- block: + - name: Define service + set_fact: + test_service: | + version: '2' + services: + {{ cname_1 }}: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + profiles: + - profile_1 + - profile_all + stop_grace_period: 1s + {{ cname_2 }}: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + profiles: + - profile_2 + - profile_all + stop_grace_period: 1s + test_cases: + - test_name: enable 1 + profiles_value: + - profile_1 + - test_name: stop all services + profiles_value: + - profile_1 + stopped_value: true + - test_name: enable 2 + profiles_value: + - profile_2 + - test_name: stop all services + profiles_value: + - profile_2 + stopped_value: true + - test_name: enable both + profiles_value: + - profile_1 + - profile_2 + - test_name: stop all services + profiles_value: + - profile_1 + - profile_2 + stopped_value: true + - test_name: enable all + profiles_value: + - profile_all + + - name: Profiles ({{ test_case.test_name }}) + docker_compose: + project_name: "{{ pname }}" + definition: "{{ test_service | from_yaml }}" + profiles: "{{ test_case.profiles_value }}" + stopped: "{{ test_case.stopped_value | default(omit) }}" + state: present + register: profiles_outputs + loop: "{{ test_cases }}" + loop_control: + loop_var: test_case + + - name: Cleanup + docker_compose: + project_name: "{{ pname }}" + state: absent + definition: "{{ test_service | from_yaml }}" + + - 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[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 + - 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 + vars: + cname_1_name: "{{ pname + '_' + cname_1 + '_1' }}" + cname_2_name: "{{ pname + '_' + cname_2 + '_1' }}" + when: docker_compose_version is version('1.28.0', '>=') \ No newline at end of file diff --git a/tests/integration/targets/setup_docker_compose/tasks/setup.yml b/tests/integration/targets/setup_docker_compose/tasks/setup.yml index 4de31bf9..c82fb817 100644 --- a/tests/integration/targets/setup_docker_compose/tasks/setup.yml +++ b/tests/integration/targets/setup_docker_compose/tasks/setup.yml @@ -39,6 +39,15 @@ name: "{{ docker_compose_pip_packages }}" extra_args: "-c {{ remote_constraints }}" + - name: Register docker-compose version + command: "{{ ansible_python.executable }} -c 'import compose; print(compose.__version__)'" + register: docker_compose_version + ignore_errors: true + + - name: Declare docker-compose version + set_fact: + docker_compose_version: "{{ docker_compose_version.stdout | default('0.0.0') }}" + - name: Declare docker-compose as existing set_fact: has_docker_compose: true