Add docker_context_info module (#1039)

* Vendor parts of the Docker SDK for Python

This is a combination of the latest git version
(https://github.com/docker/docker-py/tree/db7f8b8bb67e485a7192846906f600a52e0aa623)
with some fixes to make it compatible with Python 2.7
and adjusting some imports.

* Polishing.

* Fix bug that prevents contexts to be found when no Docker config file is present.

Ref: https://github.com/docker/docker-py/issues/3190

* Linting.

* Fix typos.

* Adjust more to behavior of Docker CLI.

* Add first iteration of docker_context_info module.

* Improvements.

* Add basic CI.

* Add caveat on contexts[].config result.
This commit is contained in:
Felix Fontein
2025-02-10 21:59:05 +01:00
committed by GitHub
parent ea3ac5f195
commit 3b6068e44b
16 changed files with 1180 additions and 11 deletions
@@ -0,0 +1,6 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
azp/5
destructive
@@ -0,0 +1,8 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
dependencies:
- setup_docker
- setup_docker_python_deps
@@ -0,0 +1,40 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################
# Create random name prefix (for containers, networks, ...)
- name: Create random container name prefix
set_fact:
cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}"
cnames: []
- debug:
msg: "Using container name prefix {{ cname_prefix }}"
# Run the tests
- block:
- include_tasks: run-test.yml
with_fileglob:
- "tests/*.yml"
loop_control:
loop_var: test_name
always:
- name: "Make sure all containers are removed"
docker_container:
name: "{{ item }}"
state: absent
force_kill: true
with_items: "{{ cnames }}"
diff: false
when: docker_api_version is version('1.25', '>=')
- fail: msg="Too old docker / docker-py version to run all docker_container tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)
@@ -0,0 +1,7 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: "Loading tasks from {{ test_name }}"
include_tasks: "{{ test_name }}"
@@ -0,0 +1,121 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Registering container name
set_fact:
cname: "{{ cname_prefix ~ '-hi' }}"
- name: Registering container name
set_fact:
cnames: "{{ cnames + [cname] }}"
- name: Get current context
community.docker.docker_context_info:
only_current: true
register: docker_current_context
- assert:
that:
- docker_current_context is not changed
# Some of the following tests will not be true on all machines, but they should be in CI:
- docker_current_context.current_context_name == 'default'
- docker_current_context.contexts | length == 1
- docker_current_context.contexts[0].name == 'default'
- docker_current_context.contexts[0].current == true
- docker_current_context.contexts[0].description == 'Current DOCKER_HOST based configuration'
- docker_current_context.contexts[0].meta_path is none
- docker_current_context.contexts[0].tls_path is none
- docker_current_context.contexts[0].config.docker_host == 'unix:///var/run/docker.sock'
- docker_current_context.contexts[0].config.tls == false
- name: Run community.docker modules with current context
module_defaults:
group/community.docker.docker: "{{ docker_current_context.contexts[0].config }}"
block:
- name: Create container
docker_container:
image: "{{ docker_test_image_alpine }}"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: present
register: create_1
- name: Create container (idempotent)
docker_container:
image: "{{ docker_test_image_alpine }}"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: present
register: create_2
- assert:
that:
- create_1 is changed
- create_2 is not changed
- name: Inspect container with CLI tool
ansible.builtin.command:
cmd: docker inspect {{ cname }}
register: result
- assert:
that:
- (result.stdout | from_json) | length == 1
- (result.stdout | from_json)[0].State.Status == "created"
- name: Start container
docker_container:
name: "{{ cname }}"
state: started
register: start_1
- name: Start container (idempotent)
docker_container:
name: "{{ cname }}"
state: started
register: start_2
- assert:
that:
- start_1 is changed
- start_2 is not changed
- name: Inspect container with CLI tool
ansible.builtin.command:
cmd: docker inspect {{ cname }}
register: result
- assert:
that:
- (result.stdout | from_json) | length == 1
- (result.stdout | from_json)[0].State.Status == "running"
- name: Remove container
docker_container:
name: "{{ cname }}"
state: absent
force_kill: true
register: remove_1
- name: Remove container (idempotent)
docker_container:
name: "{{ cname }}"
state: absent
force_kill: true
register: remove_2
- assert:
that:
- remove_1 is changed
- remove_2 is not changed
- name: Inspect container with CLI tool
ansible.builtin.command:
cmd: docker inspect {{ cname }}
register: result
failed_when: result.rc != 1
- assert:
that:
- (result.stdout | from_json) | length == 0