docker_container: simplify minimal required version per option handling (#47711)

* Store parsed docker-py / docker API versions in client.

* Began refactoring 'minimal required version' for docker_container options.

* Removing some fake defaults.

* Added changelog.

* Improve tests (check older docker versions).

* Fix comparison. The breaking point is not docker-py 2.0.0, but 1.10.0.

(Verified by testing with these versions.)

* Move docker-py/API version detection to setup_docker.

* Add YAML document starter.

* docker_network requirement for docker-py was bumped to 1.10.0 in #47492.
This commit is contained in:
Felix Fontein 2018-11-05 01:25:11 +01:00 committed by Will Thames
commit 3cca4185be
8 changed files with 410 additions and 230 deletions

View file

@ -1,4 +1,5 @@
---
# Create random name prefix (for containers, networks, ...)
- name: Create random container name prefix
set_fact:
cname_prefix: "{{ 'ansible-test-%0x' % ((2**32) | random) }}"
@ -8,6 +9,7 @@
- debug:
msg: "Using container name prefix {{ cname_prefix }}"
# Run the tests
- block:
- include_tasks: run-test.yml
with_fileglob:
@ -26,6 +28,6 @@
state: absent
force: yes
with_items: "{{ dnetworks }}"
when: docker_py_version is version('1.10.0', '>=')
# Skip for CentOS 6
when: ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6
when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=')

View file

@ -21,6 +21,7 @@
- "{{ nname_2 }}"
loop_control:
loop_var: network_name
when: docker_py_version is version('1.10.0', '>=')
####################################################################
## auto_remove #####################################################
@ -34,6 +35,7 @@
state: started
auto_remove: yes
register: auto_remove_1
ignore_errors: yes
- name: Give container 1 second to be sure it terminated
pause:
@ -44,11 +46,18 @@
name: "{{ cname }}"
state: absent
register: auto_remove_2
ignore_errors: yes
- assert:
that:
- auto_remove_1 is changed
- auto_remove_2 is not changed
when: docker_py_version is version('2.1.0', '>=')
- assert:
that:
- auto_remove_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 2.1.0') in auto_remove_1.msg"
when: docker_py_version is version('2.1.0', '<')
####################################################################
## blkio_weight ####################################################
@ -509,6 +518,7 @@
auto_remove: yes
cleanup: yes
register: detach_auto_remove
ignore_errors: yes
- name: cleanup (unnecessary)
docker_container:
@ -522,8 +532,11 @@
- detach_no_cleanup_cleanup is changed
- "'Hello from Docker!' in detach_cleanup.ansible_facts.docker_container.Output"
- detach_cleanup_cleanup is not changed
- assert:
that:
- "'Cannot retrieve result as auto_remove is enabled' == detach_auto_remove.ansible_facts.docker_container.Output"
- detach_auto_remove_cleanup is not changed
when: docker_py_version is version('2.1.0', '>=')
####################################################################
## devices #########################################################
@ -602,6 +615,7 @@
- path: /dev/urandom
rate: 10K
register: device_read_bps_1
ignore_errors: yes
- name: device_read_bps (idempotency)
docker_container:
@ -615,6 +629,7 @@
- path: /dev/random
rate: 20M
register: device_read_bps_2
ignore_errors: yes
- name: device_read_bps (lesser entries)
docker_container:
@ -626,6 +641,7 @@
- path: /dev/random
rate: 20M
register: device_read_bps_3
ignore_errors: yes
- name: device_read_bps (changed)
docker_container:
@ -640,6 +656,7 @@
rate: 5K
stop_timeout: 1
register: device_read_bps_4
ignore_errors: yes
- name: cleanup
docker_container:
@ -653,6 +670,12 @@
- device_read_bps_2 is not changed
- device_read_bps_3 is not changed
- device_read_bps_4 is changed
when: docker_py_version is version('1.9.0', '>=')
- assert:
that:
- device_read_bps_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 1.9.0') in device_read_bps_1.msg"
when: docker_py_version is version('1.9.0', '<')
####################################################################
## device_read_iops ################################################
@ -670,6 +693,7 @@
- path: /dev/urandom
rate: 20
register: device_read_iops_1
ignore_errors: yes
- name: device_read_iops (idempotency)
docker_container:
@ -683,6 +707,7 @@
- path: /dev/random
rate: 10
register: device_read_iops_2
ignore_errors: yes
- name: device_read_iops (less)
docker_container:
@ -694,6 +719,7 @@
- path: /dev/random
rate: 10
register: device_read_iops_3
ignore_errors: yes
- name: device_read_iops (changed)
docker_container:
@ -708,6 +734,7 @@
rate: 50
stop_timeout: 1
register: device_read_iops_4
ignore_errors: yes
- name: cleanup
docker_container:
@ -721,6 +748,12 @@
- device_read_iops_2 is not changed
- device_read_iops_3 is not changed
- device_read_iops_4 is changed
when: docker_py_version is version('1.9.0', '>=')
- assert:
that:
- device_read_iops_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 1.9.0') in device_read_iops_1.msg"
when: docker_py_version is version('1.9.0', '<')
####################################################################
## device_write_bps and device_write_iops ##########################
@ -739,6 +772,7 @@
- path: /dev/urandom
rate: 30
register: device_write_limit_1
ignore_errors: yes
- name: device_write_bps and device_write_iops (idempotency)
docker_container:
@ -753,6 +787,7 @@
- path: /dev/urandom
rate: 30
register: device_write_limit_2
ignore_errors: yes
- name: device_write_bps device_write_iops (changed)
docker_container:
@ -768,6 +803,7 @@
rate: 100
stop_timeout: 1
register: device_write_limit_3
ignore_errors: yes
- name: cleanup
docker_container:
@ -780,6 +816,12 @@
- device_write_limit_1 is changed
- device_write_limit_2 is not changed
- device_write_limit_3 is changed
when: docker_py_version is version('1.9.0', '>=')
- assert:
that:
- device_write_limit_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 1.9.0') in device_write_limit_1.msg"
when: docker_py_version is version('1.9.0', '<')
####################################################################
## dns_opts ########################################################
@ -795,6 +837,7 @@
- "timeout:10"
- rotate
register: dns_opts_1
ignore_errors: yes
- name: dns_opts (idempotency)
docker_container:
@ -806,6 +849,7 @@
- rotate
- "timeout:10"
register: dns_opts_2
ignore_errors: yes
- name: dns_opts (less resolv.conf options)
docker_container:
@ -816,6 +860,7 @@
dns_opts:
- "timeout:10"
register: dns_opts_3
ignore_errors: yes
- name: dns_opts (more resolv.conf options)
docker_container:
@ -828,6 +873,7 @@
- no-check-names
stop_timeout: 1
register: dns_opts_4
ignore_errors: yes
- name: cleanup
docker_container:
@ -841,6 +887,12 @@
- dns_opts_2 is not changed
- dns_opts_3 is not changed
- dns_opts_4 is changed
when: docker_py_version is version('1.10.0', '>=')
- assert:
that:
- dns_opts_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 1.10.0') in dns_opts_1.msg"
when: docker_py_version is version('1.10.0', '<')
####################################################################
## dns_search_domains ##############################################
@ -1391,6 +1443,7 @@
retries: 2
stop_timeout: 1
register: healthcheck_1
ignore_errors: yes
- name: healthcheck (idempotency)
docker_container:
@ -1408,6 +1461,7 @@
retries: 2
stop_timeout: 1
register: healthcheck_2
ignore_errors: yes
- name: healthcheck (changed)
docker_container:
@ -1425,6 +1479,7 @@
retries: 3
stop_timeout: 1
register: healthcheck_3
ignore_errors: yes
- name: healthcheck (no change)
docker_container:
@ -1434,6 +1489,7 @@
state: started
stop_timeout: 1
register: healthcheck_4
ignore_errors: yes
- name: healthcheck (disabled)
docker_container:
@ -1446,6 +1502,7 @@
- NONE
stop_timeout: 1
register: healthcheck_5
ignore_errors: yes
- name: healthcheck (disabled, idempotency)
docker_container:
@ -1458,6 +1515,7 @@
- NONE
stop_timeout: 1
register: healthcheck_6
ignore_errors: yes
- name: healthcheck (string in healthcheck test, changed)
docker_container:
@ -1469,6 +1527,7 @@
test: "sleep 1"
stop_timeout: 1
register: healthcheck_7
ignore_errors: yes
- name: healthcheck (string in healthcheck test, idempotency)
docker_container:
@ -1480,6 +1539,7 @@
test: "sleep 1"
stop_timeout: 1
register: healthcheck_8
ignore_errors: yes
- name: cleanup
docker_container:
@ -1497,6 +1557,12 @@
- healthcheck_6 is not changed
- healthcheck_7 is changed
- healthcheck_8 is not changed
when: docker_py_version is version('2.0.0', '>=')
- assert:
that:
- healthcheck_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 2.0.0') in healthcheck_1.msg"
when: docker_py_version is version('2.0.0', '<')
####################################################################
## hostname ########################################################
@ -1554,6 +1620,7 @@
init: yes
state: started
register: init_1
ignore_errors: yes
- name: init (idempotency)
docker_container:
@ -1563,6 +1630,7 @@
init: yes
state: started
register: init_2
ignore_errors: yes
- name: init (change)
docker_container:
@ -1573,6 +1641,7 @@
state: started
stop_timeout: 1
register: init_3
ignore_errors: yes
- name: cleanup
docker_container:
@ -1585,6 +1654,12 @@
- init_1 is changed
- init_2 is not changed
- init_3 is changed
when: docker_py_version is version('2.2.0', '>=')
- assert:
that:
- init_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 2.2.0') in init_1.msg"
when: docker_py_version is version('2.2.0', '<')
####################################################################
## interactive #####################################################
@ -2335,77 +2410,80 @@
## networks, purge_networks ########################################
####################################################################
- name: networks, purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_1 }}"
register: networks_1
- block:
- name: networks, purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_1 }}"
register: networks_1
- name: networks, purge_networks (idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: "{{ nname_1 }}"
- name: bridge
register: networks_2
- name: networks, purge_networks (idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: "{{ nname_1 }}"
- name: bridge
register: networks_2
- name: networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: bridge
register: networks_3
- name: networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: bridge
register: networks_3
- name: networks, purge_networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
register: networks_4
- name: networks, purge_networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
register: networks_4
- name: networks, purge_networks (more networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_2 }}"
stop_timeout: 1
register: networks_5
- name: networks, purge_networks (more networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_2 }}"
stop_timeout: 1
register: networks_5
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
stop_timeout: 1
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
stop_timeout: 1
- assert:
that:
- networks_1 is changed
- networks_2 is not changed
- networks_3 is not changed
- networks_4 is changed
- networks_5 is changed
- assert:
that:
- networks_1 is changed
- networks_2 is not changed
- networks_3 is not changed
- networks_4 is changed
- networks_5 is changed
when: docker_py_version is version('1.10.0', '>=')
####################################################################
## oom_killer ######################################################
@ -2419,6 +2497,7 @@
oom_killer: yes
state: started
register: oom_killer_1
ignore_errors: yes
- name: oom_killer (idempotency)
docker_container:
@ -2428,6 +2507,7 @@
oom_killer: yes
state: started
register: oom_killer_2
ignore_errors: yes
- name: oom_killer (change)
docker_container:
@ -2438,6 +2518,7 @@
state: started
stop_timeout: 1
register: oom_killer_3
ignore_errors: yes
- name: cleanup
docker_container:
@ -2450,6 +2531,12 @@
- oom_killer_1 is changed
- oom_killer_2 is not changed
- oom_killer_3 is changed
when: docker_py_version is version('2.0.0', '>=')
- assert:
that:
- oom_killer_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 2.0.0') in oom_killer_1.msg"
when: docker_py_version is version('2.0.0', '<')
####################################################################
## oom_score_adj ###################################################
@ -2463,6 +2550,7 @@
oom_score_adj: 5
state: started
register: oom_score_adj_1
ignore_errors: yes
- name: oom_score_adj (idempotency)
docker_container:
@ -2472,6 +2560,7 @@
oom_score_adj: 5
state: started
register: oom_score_adj_2
ignore_errors: yes
- name: oom_score_adj (change)
docker_container:
@ -2482,6 +2571,7 @@
state: started
stop_timeout: 1
register: oom_score_adj_3
ignore_errors: yes
- name: cleanup
docker_container:
@ -2494,6 +2584,12 @@
- oom_score_adj_1 is changed
- oom_score_adj_2 is not changed
- oom_score_adj_3 is changed
when: docker_py_version is version('2.0.0', '>=')
- assert:
that:
- oom_score_adj_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 2.0.0') in oom_score_adj_1.msg"
when: docker_py_version is version('2.0.0', '<')
####################################################################
## output_logs #####################################################
@ -2589,6 +2685,8 @@
state: started
pid_mode: "container:{{ pid_mode_helper.ansible_facts.docker_container.Id }}"
register: pid_mode_1
ignore_errors: yes
# docker-py < 2.0 does not support "arbitrary" pid_mode values
- name: pid_mode (idempotency)
docker_container:
@ -2598,6 +2696,8 @@
state: started
pid_mode: "container:{{ pid_mode_helper.ansible_facts.docker_container.Id }}"
register: pid_mode_2
ignore_errors: yes
# docker-py < 2.0 does not support "arbitrary" pid_mode values
- name: pid_mode (change)
docker_container:
@ -2625,6 +2725,13 @@
- pid_mode_1 is changed
- pid_mode_2 is not changed
- pid_mode_3 is changed
when: docker_py_version is version('2.0.0', '>=')
- assert:
that:
- pid_mode_1 is failed
- pid_mode_2 is failed
- pid_mode_3 is changed
when: docker_py_version is version('2.0.0', '<')
####################################################################
## privileged ######################################################
@ -2985,6 +3092,7 @@
runtime: runc
state: started
register: runtime_1
ignore_errors: yes
- name: runtime (idempotency)
docker_container:
@ -2994,6 +3102,7 @@
runtime: runc
state: started
register: runtime_2
ignore_errors: yes
- name: cleanup
docker_container:
@ -3005,6 +3114,12 @@
that:
- runtime_1 is changed
- runtime_2 is not changed
when: docker_py_version is version('2.4.0', '>=')
- assert:
that:
- runtime_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 2.4.0') in runtime_1.msg"
when: docker_py_version is version('2.4.0', '<')
####################################################################
## security_opts ###################################################
@ -3239,6 +3354,7 @@
net.ipv4.icmp_echo_ignore_all: 1
net.ipv4.ip_forward: 1
register: sysctls_1
ignore_errors: yes
- name: sysctls (idempotency)
docker_container:
@ -3250,6 +3366,7 @@
net.ipv4.ip_forward: 1
net.ipv4.icmp_echo_ignore_all: 1
register: sysctls_2
ignore_errors: yes
- name: sysctls (less sysctls)
docker_container:
@ -3260,6 +3377,7 @@
sysctls:
net.ipv4.icmp_echo_ignore_all: 1
register: sysctls_3
ignore_errors: yes
- name: sysctls (more sysctls)
docker_container:
@ -3272,6 +3390,7 @@
net.ipv6.conf.default.accept_redirects: 0
stop_timeout: 1
register: sysctls_4
ignore_errors: yes
- name: cleanup
docker_container:
@ -3285,6 +3404,12 @@
- sysctls_2 is not changed
- sysctls_3 is not changed
- sysctls_4 is changed
when: docker_py_version is version('1.10.0', '>=')
- assert:
that:
- sysctls_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 1.10.0') in sysctls_1.msg"
when: docker_py_version is version('1.10.0', '<')
####################################################################
## tmpfs ###########################################################
@ -3514,6 +3639,7 @@
userns_mode: host
state: started
register: userns_mode_1
ignore_errors: yes
- name: userns_mode (idempotency)
docker_container:
@ -3523,6 +3649,7 @@
userns_mode: host
state: started
register: userns_mode_2
ignore_errors: yes
- name: userns_mode (change)
docker_container:
@ -3533,6 +3660,7 @@
state: started
stop_timeout: 1
register: userns_mode_3
ignore_errors: yes
- name: cleanup
docker_container:
@ -3545,6 +3673,12 @@
- userns_mode_1 is changed
- userns_mode_2 is not changed
- userns_mode_3 is changed
when: docker_py_version is version('1.10.0', '>=')
- assert:
that:
- userns_mode_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 1.10.0') in userns_mode_1.msg"
when: docker_py_version is version('1.10.0', '<')
####################################################################
## uts #############################################################
@ -3558,6 +3692,7 @@
uts: host
state: started
register: uts_1
ignore_errors: yes
- name: uts (idempotency)
docker_container:
@ -3567,6 +3702,7 @@
uts: host
state: started
register: uts_2
ignore_errors: yes
- name: uts (change)
docker_container:
@ -3577,6 +3713,7 @@
state: started
stop_timeout: 1
register: uts_3
ignore_errors: yes
- name: cleanup
docker_container:
@ -3589,6 +3726,12 @@
- uts_1 is changed
- uts_2 is not changed
- uts_3 is changed
when: docker_py_version is version('3.5.0', '>=')
- assert:
that:
- uts_1 is failed
- "('version is ' ~ docker_py_version ~'. Minimum version required is 3.5.0') in uts_1.msg"
when: docker_py_version is version('3.5.0', '<')
####################################################################
## keep_volumes ####################################################
@ -3836,3 +3979,4 @@
- "{{ nname_2 }}"
loop_control:
loop_var: network_name
when: docker_py_version is version('1.10.0', '>=')