From 6fca49f44587e3addac91c415491fbf60ddfe518 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 20 May 2020 08:40:04 +0200 Subject: [PATCH] Don't die when docker CLI doesn't want to work with docker daemon (#366) * Don't die when docker CLI doesn't want to work with docker daemon. * Allow more 'docker volume ls' failures * More. * Fix more failures. * Forgot ignore_errors. * Another one. * More places. * Try to install newer docker on RHEL8. * Also restrict docker-ce-cli. --- .../tasks/test_docker_config.yml | 6 + .../docker_container_info/tasks/main.yml | 19 +- .../docker_login/tasks/tests/docker_login.yml | 241 +++++++++--------- .../docker_network_info/tasks/main.yml | 19 +- .../targets/docker_node/tasks/main.yml | 1 + .../docker_secret/tasks/test_secrets.yml | 6 + .../targets/docker_volume_info/tasks/main.yml | 19 +- .../targets/setup_docker/tasks/main.yml | 21 +- .../targets/setup_docker/vars/RedHat-8.yml | 1 + .../handlers/cleanup.yml | 10 +- .../setup_docker_registry/tasks/setup.yml | 89 ++++--- 11 files changed, 251 insertions(+), 181 deletions(-) diff --git a/tests/integration/targets/docker_config/tasks/test_docker_config.yml b/tests/integration/targets/docker_config/tasks/test_docker_config.yml index ded7eab488..8220e8f54b 100644 --- a/tests/integration/targets/docker_config/tasks/test_docker_config.yml +++ b/tests/integration/targets/docker_config/tasks/test_docker_config.yml @@ -53,6 +53,7 @@ - name: Inspect config command: "docker config inspect {{ config_id }}" register: inspect + ignore_errors: yes - debug: var=inspect @@ -61,6 +62,11 @@ that: - "'db_password' in inspect.stdout" - "'ansible_key' in inspect.stdout" + when: inspect is not failed + - assert: + that: + - "'is too new. Maximum supported API version is' in inspect.stderr" + when: inspect is failed - name: Create config again docker_config: diff --git a/tests/integration/targets/docker_container_info/tasks/main.yml b/tests/integration/targets/docker_container_info/tasks/main.yml index 71d07fe0df..4e7118fce4 100644 --- a/tests/integration/targets/docker_container_info/tasks/main.yml +++ b/tests/integration/targets/docker_container_info/tasks/main.yml @@ -39,17 +39,28 @@ - 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 + ignore_errors: yes + - block: + - set_fact: + docker_inspect_result: "{{ docker_inspect.stdout | from_json }}" + - name: Dump docker inspect result + debug: var=docker_inspect_result + when: docker_inspect is not failed - assert: that: - result.exists - "'container' in result" - "result.container" + + - assert: + that: - "result.container == docker_inspect_result[0]" + when: docker_inspect is not failed + - assert: + that: + - "'is too new. Maximum supported API version is' in docker_inspect.stderr" + when: docker_inspect is failed always: - name: Cleanup diff --git a/tests/integration/targets/docker_login/tasks/tests/docker_login.yml b/tests/integration/targets/docker_login/tasks/tests/docker_login.yml index 33aaf08fea..1c584c0f47 100644 --- a/tests/integration/targets/docker_login/tasks/tests/docker_login.yml +++ b/tests/integration/targets/docker_login/tasks/tests/docker_login.yml @@ -1,136 +1,139 @@ --- -- name: Log in with wrong password (check mode) - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: "1234" - state: present - register: login_failed_check - ignore_errors: yes - check_mode: yes +- block: + - name: Log in with wrong password (check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: "1234" + state: present + register: login_failed_check + ignore_errors: yes + check_mode: yes -- name: Log in with wrong password - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: "1234" - state: present - register: login_failed - ignore_errors: yes + - name: Log in with wrong password + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: "1234" + state: present + register: login_failed + ignore_errors: yes -- name: Make sure that login failed - assert: - that: - - login_failed_check is failed - - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed_check.msg" - - login_failed is failed - - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed.msg" + - name: Make sure that login failed + assert: + that: + - login_failed_check is failed + - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed_check.msg" + - login_failed is failed + - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed.msg" -- name: Log in (check mode) - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: hunter2 - state: present - register: login_1 - check_mode: yes + - name: Log in (check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: hunter2 + state: present + register: login_1 + check_mode: yes -- name: Log in - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: hunter2 - state: present - register: login_2 + - name: Log in + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: hunter2 + state: present + register: login_2 -- name: Get permissions of ~/.docker/config.json - stat: - path: ~/.docker/config.json - register: login_2_stat + - name: Get permissions of ~/.docker/config.json + stat: + path: ~/.docker/config.json + register: login_2_stat -- name: Log in (idempotent) - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: hunter2 - state: present - register: login_3 + - name: Log in (idempotent) + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: hunter2 + state: present + register: login_3 -- name: Log in (idempotent, check mode) - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: hunter2 - state: present - register: login_4 - check_mode: yes + - name: Log in (idempotent, check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: hunter2 + state: present + register: login_4 + check_mode: yes -- name: Make sure that login worked - assert: - that: - - login_1 is changed - - login_2 is changed - - login_3 is not changed - - login_4 is not changed - - login_2_stat.stat.mode == '0600' + - name: Make sure that login worked + assert: + that: + - login_1 is changed + - login_2 is changed + - login_3 is not changed + - login_4 is not changed + - login_2_stat.stat.mode == '0600' -- name: Log in again with wrong password (check mode) - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: "1234" - state: present - register: login_failed_check - ignore_errors: yes - check_mode: yes + - name: Log in again with wrong password (check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: "1234" + state: present + register: login_failed_check + ignore_errors: yes + check_mode: yes -- name: Log in again with wrong password - docker_login: - registry_url: "{{ registry_frontend_address }}" - username: testuser - password: "1234" - state: present - register: login_failed - ignore_errors: yes + - name: Log in again with wrong password + docker_login: + registry_url: "{{ registry_frontend_address }}" + username: testuser + password: "1234" + state: present + register: login_failed + ignore_errors: yes -- name: Make sure that login failed again - assert: - that: - - login_failed_check is failed - - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed_check.msg" - - login_failed is failed - - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed.msg" + - name: Make sure that login failed again + assert: + that: + - login_failed_check is failed + - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed_check.msg" + - login_failed is failed + - "('login attempt to http://' ~ registry_frontend_address ~ '/v2/ failed') in login_failed.msg" -- name: Log out (check mode) - docker_login: - registry_url: "{{ registry_frontend_address }}" - state: absent - register: logout_1 - check_mode: yes + - name: Log out (check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + state: absent + register: logout_1 + check_mode: yes -- name: Log out - docker_login: - registry_url: "{{ registry_frontend_address }}" - state: absent - register: logout_2 + - name: Log out + docker_login: + registry_url: "{{ registry_frontend_address }}" + state: absent + register: logout_2 -- name: Log out (idempotent) - docker_login: - registry_url: "{{ registry_frontend_address }}" - state: absent - register: logout_3 + - name: Log out (idempotent) + docker_login: + registry_url: "{{ registry_frontend_address }}" + state: absent + register: logout_3 -- name: Log out (idempotent, check mode) - docker_login: - registry_url: "{{ registry_frontend_address }}" - state: absent - register: logout_4 - check_mode: yes + - name: Log out (idempotent, check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + state: absent + register: logout_4 + check_mode: yes -- name: Make sure that login worked - assert: - that: - - logout_1 is changed - - logout_2 is changed - - logout_3 is not changed - - logout_4 is not changed + - name: Make sure that login worked + assert: + that: + - logout_1 is changed + - logout_2 is changed + - logout_3 is not changed + - logout_4 is not changed + + when: registry_frontend_address != 'n/a' diff --git a/tests/integration/targets/docker_network_info/tasks/main.yml b/tests/integration/targets/docker_network_info/tasks/main.yml index f8bce0ebcc..5498270e2e 100644 --- a/tests/integration/targets/docker_network_info/tasks/main.yml +++ b/tests/integration/targets/docker_network_info/tasks/main.yml @@ -36,10 +36,13 @@ - name: "Comparison: use 'docker network inspect'" command: docker network inspect "{{ nname }}" register: docker_inspect - - set_fact: - docker_inspect_result: "{{ docker_inspect.stdout | from_json }}" - - name: Dump docker inspect result - debug: var=docker_inspect_result + ignore_errors: yes + - block: + - set_fact: + docker_inspect_result: "{{ docker_inspect.stdout | from_json }}" + - name: Dump docker inspect result + debug: var=docker_inspect_result + when: docker_inspect is not failed - name: Cleanup docker_network: @@ -52,7 +55,15 @@ - result.exists - "'network' in result" - "result.network" + + - assert: + that: - "result.network == docker_inspect_result[0]" + when: docker_inspect is not failed + - assert: + that: + - "'is too new. Maximum supported API version is' in docker_inspect.stderr" + when: docker_inspect is failed when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.21', '>=') diff --git a/tests/integration/targets/docker_node/tasks/main.yml b/tests/integration/targets/docker_node/tasks/main.yml index ccac80691d..482f766810 100644 --- a/tests/integration/targets/docker_node/tasks/main.yml +++ b/tests/integration/targets/docker_node/tasks/main.yml @@ -18,6 +18,7 @@ become: yes - name: Wait for docker daemon to be fully restarted command: docker ps + ignore_errors: yes - name: Cleanup docker_swarm: diff --git a/tests/integration/targets/docker_secret/tasks/test_secrets.yml b/tests/integration/targets/docker_secret/tasks/test_secrets.yml index b99f059e05..2c07848895 100644 --- a/tests/integration/targets/docker_secret/tasks/test_secrets.yml +++ b/tests/integration/targets/docker_secret/tasks/test_secrets.yml @@ -49,6 +49,7 @@ - name: Inspect secret command: "docker secret inspect {{ secret_id }}" register: inspect + ignore_errors: yes - debug: var=inspect @@ -57,6 +58,11 @@ that: - "'db_password' in inspect.stdout" - "'ansible_key' in inspect.stdout" + when: inspect is not failed + - assert: + that: + - "'is too new. Maximum supported API version is' in inspect.stderr" + when: inspect is failed - name: Create secret again docker_secret: diff --git a/tests/integration/targets/docker_volume_info/tasks/main.yml b/tests/integration/targets/docker_volume_info/tasks/main.yml index 26b14a6599..539b8afdf1 100644 --- a/tests/integration/targets/docker_volume_info/tasks/main.yml +++ b/tests/integration/targets/docker_volume_info/tasks/main.yml @@ -34,10 +34,13 @@ - name: "Comparison: use 'docker volume inspect'" command: docker volume inspect "{{ cname }}" register: docker_volume_inspect - - set_fact: - docker_volume_inspect_result: "{{ docker_volume_inspect.stdout | from_json }}" - - name: Dump docker volume inspect result - debug: var=docker_volume_inspect_result + ignore_errors: yes + - block: + - set_fact: + docker_volume_inspect_result: "{{ docker_volume_inspect.stdout | from_json }}" + - name: Dump docker volume inspect result + debug: var=docker_volume_inspect_result + when: docker_volume_inspect is not failed - name: Cleanup docker_volume: @@ -49,7 +52,15 @@ - result.exists - "'volume' in result" - "result.volume" + + - assert: + that: - "result.volume == docker_volume_inspect_result[0]" + when: docker_volume_inspect is not failed + - assert: + that: + - "'is too new. Maximum supported API version is' in docker_volume_inspect.stderr" + when: docker_volume_inspect is failed # Requirements for docker_volume when: docker_py_version is version('1.10.0', '>=') and docker_api_version is version('1.24', '>=') diff --git a/tests/integration/targets/setup_docker/tasks/main.yml b/tests/integration/targets/setup_docker/tasks/main.yml index f5a8064705..f7c41986ac 100644 --- a/tests/integration/targets/setup_docker/tasks/main.yml +++ b/tests/integration/targets/setup_docker/tasks/main.yml @@ -66,49 +66,56 @@ retries: 3 delay: 3 until: docker_containers is success + ignore_errors: yes - name: "Remove all ansible-test-* docker volumes" shell: 'docker volume ls --format {% raw %}"{{.Name}}"{% endraw %} | grep "^ansible-test-" | xargs -r docker volume rm -f' register: docker_volumes + ignore_errors: yes - name: "Remove all ansible-test-* docker networks" shell: 'docker network ls --no-trunc --format {% raw %}"{{.Name}}"{% endraw %} | grep "^ansible-test-" | xargs -r docker network rm' register: docker_networks + ignore_errors: yes - name: Cleaned docker resources debug: var: docker_resources vars: docker_resources: - containers: "{{ docker_containers.stdout_lines }}" - volumes: "{{ docker_volumes.stdout_lines }}" - networks: "{{ docker_networks.stdout_lines }}" + containers: "{{ docker_containers.stdout_lines | default([]) }}" + volumes: "{{ docker_volumes.stdout_lines | default([]) }}" + networks: "{{ docker_networks.stdout_lines | default([]) }}" # List all existing docker resources - name: List all docker containers command: docker ps --no-trunc -a register: docker_containers + ignore_errors: yes - name: List all docker volumes command: docker volume ls register: docker_volumes + ignore_errors: yes - name: List all docker networks command: docker network ls --no-trunc register: docker_networks + ignore_errors: yes - name: List all docker images command: docker images --no-trunc -a register: docker_images + ignore_errors: yes - name: Still existing docker resources debug: var: docker_resources vars: docker_resources: - containers: "{{ docker_containers.stdout_lines }}" - volumes: "{{ docker_volumes.stdout_lines }}" - networks: "{{ docker_networks.stdout_lines }}" - images: "{{ docker_images.stdout_lines }}" + containers: "{{ docker_containers.stdout_lines | default([]) }}" + volumes: "{{ docker_volumes.stdout_lines | default([]) }}" + networks: "{{ docker_networks.stdout_lines | default([]) }}" + images: "{{ docker_images.stdout_lines | default([]) }}" when: docker_cli_version is version('0.0', '>') diff --git a/tests/integration/targets/setup_docker/vars/RedHat-8.yml b/tests/integration/targets/setup_docker/vars/RedHat-8.yml index 3e15293354..faaad8625f 100644 --- a/tests/integration/targets/setup_docker/vars/RedHat-8.yml +++ b/tests/integration/targets/setup_docker/vars/RedHat-8.yml @@ -7,3 +7,4 @@ docker_prereq_packages: # Docker CE > 3:18.09.1 requires containerd.io >= 1.2.2-3 which is unavaible at this time docker_packages: - docker-ce-3:18.09.1 + - docker-ce-cli-1:18.09.1 # otherwise 19.03.9 is installed, which won't work with docker daemon 18.09.1 diff --git a/tests/integration/targets/setup_docker_registry/handlers/cleanup.yml b/tests/integration/targets/setup_docker_registry/handlers/cleanup.yml index b789174700..8353038038 100644 --- a/tests/integration/targets/setup_docker_registry/handlers/cleanup.yml +++ b/tests/integration/targets/setup_docker_registry/handlers/cleanup.yml @@ -7,14 +7,20 @@ command: "docker logs {{ registry_name }}" register: registry_logs no_log: yes + ignore_errors: yes - name: "Printing registry logs" - debug: var=registry_logs.stdout_lines + debug: + var: registry_logs.stdout_lines + when: registry_logs is not failed - name: "Get nginx logs" command: "docker logs {{ nginx_name }}" register: nginx_logs no_log: yes + ignore_errors: yes - name: "Printing nginx logs" - debug: var=nginx_logs.stdout_lines + debug: + var: nginx_logs.stdout_lines + when: nginx_logs is not failed - name: "Make sure all containers are removed" docker_container: name: "{{ item }}" diff --git a/tests/integration/targets/setup_docker_registry/tasks/setup.yml b/tests/integration/targets/setup_docker_registry/tasks/setup.yml index bf11e9f708..f42bc592b5 100644 --- a/tests/integration/targets/setup_docker_registry/tasks/setup.yml +++ b/tests/integration/targets/setup_docker_registry/tasks/setup.yml @@ -52,47 +52,54 @@ loop: - nginx.conf - nginx.htpasswd - - name: Create private key for frontend certificate - community.crypto.openssl_privatekey: - path: '{{ output_dir }}/cert.key' - type: ECC - curve: secp256r1 - - name: Create CSR for frontend certificate - community.crypto.openssl_csr: - path: '{{ output_dir }}/cert.csr' - privatekey_path: '{{ output_dir }}/cert.key' - subject_alt_name: - - DNS:test-registry.ansible.com - - name: Create frontend certificate - community.crypto.openssl_certificate: - path: '{{ output_dir }}/cert.pem' - csr_path: '{{ output_dir }}/cert.csr' - privatekey_path: '{{ output_dir }}/cert.key' - provider: selfsigned - - name: Copy dynamic files into volume - command: docker cp {{ output_dir }}/{{ item }} {{ nginx_name }}:/etc/nginx/{{ item }} - loop: - - cert.pem - - cert.key - - name: Start nginx frontend for registry - docker_container: - name: '{{ nginx_name }}' - state: started - register: nginx_container - - debug: var=nginx_container.container.NetworkSettings - - name: Wait for registry frontend - uri: - url: https://{{ nginx_container.container.NetworkSettings.IPAddress }}:5000/v2/ - url_username: testuser - url_password: hunter2 - validate_certs: false - register: result - until: result is success - retries: 5 - delay: 1 - - name: Get registry URL - set_fact: - registry_frontend_address: localhost:{{ nginx_container.container.NetworkSettings.Ports['5000/tcp'].0.HostPort }} + register: can_copy_files + ignore_errors: yes + - block: + - name: Create private key for frontend certificate + community.crypto.openssl_privatekey: + path: '{{ output_dir }}/cert.key' + type: ECC + curve: secp256r1 + - name: Create CSR for frontend certificate + community.crypto.openssl_csr: + path: '{{ output_dir }}/cert.csr' + privatekey_path: '{{ output_dir }}/cert.key' + subject_alt_name: + - DNS:test-registry.ansible.com + - name: Create frontend certificate + community.crypto.openssl_certificate: + path: '{{ output_dir }}/cert.pem' + csr_path: '{{ output_dir }}/cert.csr' + privatekey_path: '{{ output_dir }}/cert.key' + provider: selfsigned + - name: Copy dynamic files into volume + command: docker cp {{ output_dir }}/{{ item }} {{ nginx_name }}:/etc/nginx/{{ item }} + loop: + - cert.pem + - cert.key + - name: Start nginx frontend for registry + docker_container: + name: '{{ nginx_name }}' + state: started + register: nginx_container + - debug: var=nginx_container.container.NetworkSettings + - name: Wait for registry frontend + uri: + url: https://{{ nginx_container.container.NetworkSettings.IPAddress }}:5000/v2/ + url_username: testuser + url_password: hunter2 + validate_certs: false + register: result + until: result is success + retries: 5 + delay: 1 + - name: Get registry URL + set_fact: + registry_frontend_address: localhost:{{ nginx_container.container.NetworkSettings.Ports['5000/tcp'].0.HostPort }} + when: can_copy_files is not failed + - set_fact: + registry_frontend_address: 'n/a' + when: can_copy_files is failed - debug: msg="Registry available under {{ registry_address }}, NGINX frontend available under {{ registry_frontend_address }}" when: docker_py_version is version('1.8.0', '>=') and docker_api_version is version('1.20', '>=') - fail: msg="Too old docker / docker-py version to run docker_image tests!"