From 602d02be5f8bef1fd57b26ef6b1d5bad29c47e97 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 6 Nov 2018 16:08:28 +0100 Subject: [PATCH] Add docker_container_facts module. (#48062) --- .../cloud/docker/docker_container_facts.py | 141 ++++++++++++++++++ .../targets/docker_container_facts/aliases | 4 + .../docker_container_facts/meta/main.yml | 3 + .../docker_container_facts/tasks/main.yml | 62 ++++++++ 4 files changed, 210 insertions(+) create mode 100644 lib/ansible/modules/cloud/docker/docker_container_facts.py create mode 100644 test/integration/targets/docker_container_facts/aliases create mode 100644 test/integration/targets/docker_container_facts/meta/main.yml create mode 100644 test/integration/targets/docker_container_facts/tasks/main.yml diff --git a/lib/ansible/modules/cloud/docker/docker_container_facts.py b/lib/ansible/modules/cloud/docker/docker_container_facts.py new file mode 100644 index 00000000000..683d160f57a --- /dev/null +++ b/lib/ansible/modules/cloud/docker/docker_container_facts.py @@ -0,0 +1,141 @@ +#!/usr/bin/python +# +# Copyright 2016 Red Hat | Ansible +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: docker_container_facts + +short_description: Retrieves facts about docker container + +description: + - Retrieves facts about a docker container. + - Essentially returns the output of C(docker inspect ), similar to what M(docker_container) + returns for a non-absent container. + +version_added: "2.8" + +options: + name: + description: + - The name of the container to inspect. + - When identifying an existing container name may be a name or a long or short container ID. + required: true +extends_documentation_fragment: + - docker + +author: + - "Felix Fontein (@felixfontein)" + +requirements: + - "python >= 2.6" + - "docker-py >= 1.8.0" + - "Please note that the L(docker-py,https://pypi.org/project/docker-py/) Python + module has been superseded by L(docker,https://pypi.org/project/docker/) + (see L(here,https://github.com/docker/docker-py/issues/1310) for details). + For Python 2.6, C(docker-py) must be used. Otherwise, it is recommended to + install the C(docker) Python module. Note that both modules should I(not) + be installed at the same time. Also note that when both modules are installed + and one of them is uninstalled, the other might no longer function and a + reinstall of it is required." + - "Docker API >= 1.20" +''' + +EXAMPLES = ''' +- name: Get infos on container + docker_container_facts: + name: mydata + register: result + +- name: Does container exist? + debug: + msg: "The container {{ 'exists' if result.exists else 'does not exist' }}" + +- name: Print information about container + debug: + var: result.docker_container + when: result.exists +''' + +RETURN = ''' +exists: + description: + - Returns whether the container exists. + type: bool + returned: always + sample: true +docker_container: + description: + - Facts representing the current state of the container. Matches the docker inspection output. + - Will be empty if container does not exist. + returned: always + type: dict + sample: '{ + "AppArmorProfile": "", + "Args": [], + "Config": { + "AttachStderr": false, + "AttachStdin": false, + "AttachStdout": false, + "Cmd": [ + "/usr/bin/supervisord" + ], + "Domainname": "", + "Entrypoint": null, + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "ExposedPorts": { + "443/tcp": {}, + "80/tcp": {} + }, + "Hostname": "8e47bf643eb9", + "Image": "lnmp_nginx:v1", + "Labels": {}, + "OnBuild": null, + "OpenStdin": false, + "StdinOnce": false, + "Tty": false, + "User": "", + "Volumes": { + "/tmp/lnmp/nginx-sites/logs/": {} + }, + ... + }' +''' + +from ansible.module_utils.docker_common import AnsibleDockerClient + + +def main(): + argument_spec = dict( + name=dict(type='str', required=True), + ) + + client = AnsibleDockerClient( + argument_spec=argument_spec, + supports_check_mode=True, + min_docker_api_version='1.20', + ) + + container = client.get_container(client.module.params['name']) + + client.module.exit_json( + changed=False, + exists=(True if container else False), + docker_container=container, + ) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/docker_container_facts/aliases b/test/integration/targets/docker_container_facts/aliases new file mode 100644 index 00000000000..2b3832dde58 --- /dev/null +++ b/test/integration/targets/docker_container_facts/aliases @@ -0,0 +1,4 @@ +shippable/posix/group2 +skip/osx +skip/freebsd +destructive diff --git a/test/integration/targets/docker_container_facts/meta/main.yml b/test/integration/targets/docker_container_facts/meta/main.yml new file mode 100644 index 00000000000..07da8c6ddae --- /dev/null +++ b/test/integration/targets/docker_container_facts/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - setup_docker diff --git a/test/integration/targets/docker_container_facts/tasks/main.yml b/test/integration/targets/docker_container_facts/tasks/main.yml new file mode 100644 index 00000000000..584da2e3188 --- /dev/null +++ b/test/integration/targets/docker_container_facts/tasks/main.yml @@ -0,0 +1,62 @@ +--- +- block: + - name: Create random container name + set_fact: + cname: "{{ 'ansible-test-%0x' % ((2**32) | random) }}" + + - name: Make sure container is not there + docker_container: + name: "{{ cname }}" + state: absent + stop_timeout: 1 + + - name: Inspect a non-present container + docker_container_facts: + name: "{{ cname }}" + register: result + + - assert: + that: + - "not result.exists" + - "'docker_container' in result" + - "not result.docker_container" + + - name: Make sure container exists + docker_container: + name: "{{ cname }}" + image: alpine:3.8 + command: '/bin/sh -c "sleep 10m"' + state: started + auto_remove: yes + stop_timeout: 1 + + - name: Inspect a present container + docker_container_facts: + name: "{{ cname }}" + register: result + - name: Dump docker_container_facts result + debug: var=result + + - name: "Comparison: use 'docker inspect'" + command: docker inspect "{{ cname }}" + register: docker_inspect + - set_fact: + docker_inspect_result: "{{ docker_inspect.stdout | from_json }}" + - name: Dump docker inspect result + debug: var=docker_inspect_result + + - name: Cleanup + docker_container: + name: "{{ cname }}" + state: absent + stop_timeout: 1 + + - assert: + that: + - result.exists + - "'docker_container' in result" + - "result.docker_container" + - "result.docker_container == docker_inspect_result[0]" + + # Skip for CentOS 6 + when: ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6