From 78da67824a9b25d7f465646742a5f6b70d657026 Mon Sep 17 00:00:00 2001 From: Gabriele Cerami Date: Tue, 30 Jul 2019 11:47:14 +0100 Subject: [PATCH] expand login subtasks so it can be used in all rdo jobs With the upcoming activation of RHEL8 pipeline, we decided with infra it was better to switch rdo registry to restricted access. This means that all the job in rdo must login to registry to pull containers. All the Centos7 jobs must now call this role to login to the registry, so we are expanding the login part to satisfy the workflow RHEL8 job with podman will use a internal role instead. Change-Id: I6e55bdcf493d04bfc88ae22154124a7888563147 --- README.rst | 3 +- defaults/main.yml | 1 + molecule/default/molecule.yml | 6 +- molecule/login/molecule.yml | 7 +- molecule/login/playbook.yml | 166 +++++++++++++++++++++++++++++++++- tasks/cleanup-engine.yml | 16 ++++ tasks/docker.yml | 5 +- tasks/install-engine.yml | 17 ++++ tasks/registry-login.yml | 28 ++++++ 9 files changed, 233 insertions(+), 16 deletions(-) create mode 100644 tasks/cleanup-engine.yml create mode 100644 tasks/install-engine.yml create mode 100644 tasks/registry-login.yml diff --git a/README.rst b/README.rst index a462a6d..34191d6 100644 --- a/README.rst +++ b/README.rst @@ -1,8 +1,9 @@ ansible-role-container-registry =============================== -A role to deploy a container registry. +A role to deploy a container registry and provide methods to login to it. For now, the role only support Docker Registry v2. +The login currently doesn't work with hub.docker.com. Role Variables diff --git a/defaults/main.yml b/defaults/main.yml index 467ea0c..3916b31 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -15,3 +15,4 @@ container_registry_selinux: false container_registry_additional_sockets: [] container_registry_skip_reconfiguration: false container_registry_logins: {} +container_registry_cleanup_client: false diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 7409d6b..504a4a9 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -12,14 +12,14 @@ driver: -o VerifyHostKeyDNS=no -o ForwardX11=no -o ForwardAgent=no - {instance} + {instance-default} ansible_connection_options: ansible_connection: ssh log: true platforms: - - name: instance + - name: instance-default provisioner: name: ansible @@ -31,7 +31,7 @@ provisioner: hosts: all: hosts: - instance: + instance-default: ansible_host: localhost log: true env: diff --git a/molecule/login/molecule.yml b/molecule/login/molecule.yml index 19c52b5..ad7b6f5 100644 --- a/molecule/login/molecule.yml +++ b/molecule/login/molecule.yml @@ -12,14 +12,14 @@ driver: -o VerifyHostKeyDNS=no -o ForwardX11=no -o ForwardAgent=no - {instance} + {instance-login} ansible_connection_options: ansible_connection: ssh log: true platforms: - - name: instance + - name: instance-login provisioner: name: ansible @@ -31,8 +31,9 @@ provisioner: hosts: all: hosts: - instance: + instance-login: ansible_host: localhost + ansible_user: zuul log: true env: ANSIBLE_STDOUT_CALLBACK: yaml diff --git a/molecule/login/playbook.yml b/molecule/login/playbook.yml index c29731d..c521c2d 100644 --- a/molecule/login/playbook.yml +++ b/molecule/login/playbook.yml @@ -14,17 +14,173 @@ # License for the specific language governing permissions and limitations # under the License. - -- name: Converge - become: false +#### +# Testing that the role fails with information when we are not passing +# credentials for the login +# +- name: Ensure role checks for missing information hosts: all + tasks: + - set_fact: + role_failed: false + + - name: ensure role fails when credentials missing + block: + - include_role: + name: ansible-role-container-registry + tasks_from: registry-login + vars: + ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python" + rescue: + - set_fact: + role_failed: true + + - name: assert on missing credentials + assert: + that: role_failed != false + fail_msg: Role did not fail and it should have while passing no credential + success_msg: Role failed correctly while passing no credentials + +##### +# We don't want to pollute the host by installing packages that +# should be installed elsewhere and maybe from different repository +# Here we test that we are removing any client package after installing it +# As sometimes the package is installed before we run this role, we are also +# testing that we are removing packages if and only if we were the ones +# installing it. +# +- name: Check role behaviour with docker installation + hosts: instance-login vars: + docker_login_cache: /root/.docker/config.json + docker_socket: /var/run/docker.sock container_registry_logins: localhost:5000: testuser: testpassword tasks: - - include_role: + - name: preinstall docker + become: true + package: + name: docker + state: present + + - name: Include role with docker preinstalled + include_role: name: ansible-role-container-registry - tasks_from: docker-login + tasks_from: install-engine vars: ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python" + + - name: remove clients with docker preinstalled + include_role: + name: ansible-role-container-registry + tasks_from: cleanup-engine + vars: + ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python" + container_registry_cleanup_client: true + + - name: Check if tasks removed docker and it shouldn't + assert: + that: + - remove_docker is not defined or remove_docker is skipped + fail_msg: Role removed docker when it shouldn't have + success_msg: Role correctly left docker as it was installed before + + - name: remove docker + become: true + package: + name: docker + state: absent + + - name: Install client without docker preinstalled + include_role: + name: ansible-role-container-registry + tasks_from: install-engine + vars: + ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python" + + - name: Cleanup client without docker preinstalled + include_role: + name: ansible-role-container-registry + tasks_from: cleanup-engine + vars: + ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python" + container_registry_cleanup_client: true + + - name: Check if tasks removed docker + assert: + that: + - remove_docker is defined + fail_msg: Role did not remove docker when it should have + success_msg: Role correctly removed docker as it was not present before call + +#### +# This play tests that docker is chosen in centos7 and the login successfully +# created a auth cache file +# it also ensure that docker deamon is still running after we remove the client +# +- name: Test login behaviour in centos7 + hosts: instance-login + vars: + docker_login_cache: /root/.docker/config.json + docker_socket: /var/run/docker.sock + container_registry_logins: + localhost:5000: + testuser: testpassword + tasks: + - include_role: + name: ansible-role-container-registry + tasks_from: registry-login + + - name: check credentials file + become: true + stat: + path: "{{ docker_login_cache }}" + register: cache_file + + - block: + - name: assert on file existence + assert: + that: + - cache_file.stat.exists + fail_msg: Credential file was not created + success_msg: Credential file correctly present + failed_when: false + rescue: + - debug: + msg: noop + + - name: Verify credentials can be used + block: + - name: create build dir + file: + path: /tmp/tempimage + state: directory + + - name: create Dockerfile + copy: + content: | + FROM scratch + ADD nothing / + dest: /tmp/tempimage/Dockerfile + + - name: Build test image + become: true + shell: | + cd /tmp/tempimage + touch nothing + docker build -t localhost:5000/test/testimage:v1 . + register: build + + - name: Verify authenticated push works + become: true + shell: | + docker push localhost:5000/test/testimage:v1 + + - name: Cleanup + include_role: + name: ansible-role-container-registry + tasks_from: cleanup-engine + vars: + ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python" + container_registry_cleanup_client: true diff --git a/tasks/cleanup-engine.yml b/tasks/cleanup-engine.yml new file mode 100644 index 0000000..5ca752e --- /dev/null +++ b/tasks/cleanup-engine.yml @@ -0,0 +1,16 @@ +- name: Cleanup Engine + block: + - name: Remove docker + package: + name: + - docker + state: absent + register: remove_docker + when: + - container_registry_docker_install is defined + - container_registry_docker_install is changed + rescue: + - debug: + msg: "unable to remove docker" + become: true + diff --git a/tasks/docker.yml b/tasks/docker.yml index 7638f77..525b02e 100644 --- a/tasks/docker.yml +++ b/tasks/docker.yml @@ -52,10 +52,7 @@ - not ansible_check_mode - ftype.stdout == 'ftype=0' - - name: ensure docker is installed - package: - name: docker - state: present + - include_tasks: install-engine.yml - name: manage /etc/systemd/system/docker.service.d file: diff --git a/tasks/install-engine.yml b/tasks/install-engine.yml new file mode 100644 index 0000000..3526131 --- /dev/null +++ b/tasks/install-engine.yml @@ -0,0 +1,17 @@ +--- +- name: Install and Start Docker + when: + - ansible_distribution == "CentOS" + - ansible_distribution_major_version|int < 8 + become: true + block: + - name: Install Docker + package: + name: docker + state: present + register: container_registry_docker_install + + - name: Start Docker daemon + service: + name: docker + state: started diff --git a/tasks/registry-login.yml b/tasks/registry-login.yml new file mode 100644 index 0000000..168743c --- /dev/null +++ b/tasks/registry-login.yml @@ -0,0 +1,28 @@ +--- +# TODO(gcerami): The login process does not work with dockerhub, as dockerhub requires an +# auth API call to pass an email address (aven a fake one) + +- name: Fail if credentials are not defined or empty + fail: + msg: "Registry credentials are missing" + when: container_registry_logins|default({}) == {} + +- import_tasks: install-engine.yml + +- name: Try docker command line for authentication + block: + - name: Login via docker command + become: true + command: > + docker login "{{ item.key }}" + --username "{{ lookup('dict', item.value).key }}" + --password "{{ lookup('dict', item.value).value }}" + loop: "{{ query('dict', container_registry_logins | default({})) }}" + register: registry_login_docker + rescue: + - debug: + msg: "Warning: login failed for some credentials while using docker login" + +- import_tasks: cleanup-engine.yml + when: container_registry_cleanup_client +