diff --git a/roles/build-docker-image/common.rst b/roles/build-docker-image/common.rst index 10753e62e..5b899a8d6 100644 --- a/roles/build-docker-image/common.rst +++ b/roles/build-docker-image/common.rst @@ -51,6 +51,12 @@ using this role. when building all images from different folders with similarily named dockerfiles. +.. zuul:rolevar:: docker_registry + :default: '' + + The container registry the images should be tagged for, by default + zuul will push the image to dockerhub. + .. zuul:rolevar:: docker_credentials :type: dict diff --git a/roles/build-docker-image/defaults/main.yaml b/roles/build-docker-image/defaults/main.yaml index d702500de..24a195ad1 100644 --- a/roles/build-docker-image/defaults/main.yaml +++ b/roles/build-docker-image/defaults/main.yaml @@ -1,2 +1,3 @@ zuul_work_dir: "{{ zuul.project.src_dir }}" docker_dockerfile: "Dockerfile" +docker_registry: '' diff --git a/roles/build-docker-image/tasks/build.yaml b/roles/build-docker-image/tasks/build.yaml index 8c622aaeb..a02ac21d6 100644 --- a/roles/build-docker-image/tasks/build.yaml +++ b/roles/build-docker-image/tasks/build.yaml @@ -15,9 +15,9 @@ {% endif -%} {% for tag in zj_image.tags | default(['latest']) -%} {% if zuul.change | default(false) -%} - --tag {{ zj_image.repository }}:change_{{ zuul.change }}_{{ tag }} + --tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:change_{{ zuul.change }}_{{ tag }} {% endif -%} - --tag {{ zj_image.repository }}:{{ tag }} + --tag {{ docker_registry | ternary(docker_registry + '/', '') }}{{ zj_image.repository }}:{{ tag }} {% endfor -%} {% for label in zj_image.labels | default([]) -%} --label "{{ label }}" diff --git a/roles/upload-docker-image/defaults/main.yaml b/roles/upload-docker-image/defaults/main.yaml index 0c5fa0c84..fceb40e62 100644 --- a/roles/upload-docker-image/defaults/main.yaml +++ b/roles/upload-docker-image/defaults/main.yaml @@ -1,3 +1,4 @@ zuul_work_dir: "{{ zuul.project.src_dir }}" docker_dockerfile: "Dockerfile" upload_docker_image_promote: true +docker_registry: '' diff --git a/roles/upload-docker-image/tasks/main.yaml b/roles/upload-docker-image/tasks/main.yaml index e84d725d3..1e545d9c5 100644 --- a/roles/upload-docker-image/tasks/main.yaml +++ b/roles/upload-docker-image/tasks/main.yaml @@ -8,8 +8,8 @@ fail: msg: "{{ zj_image.repository }} not permitted by {{ docker_credentials.repository }}" -- name: Log in to dockerhub - command: "docker login -u {{ docker_credentials.username }} -p {{ docker_credentials.password }}" +- name: Log in to registry + command: "docker login -u {{ docker_credentials.username }} -p {{ docker_credentials.password }} {{ docker_registry }}" no_log: true - name: Determine if we need to use buildx diff --git a/roles/upload-docker-image/tasks/push.yaml b/roles/upload-docker-image/tasks/push.yaml index b6c8fccff..f1d36ca7d 100644 --- a/roles/upload-docker-image/tasks/push.yaml +++ b/roles/upload-docker-image/tasks/push.yaml @@ -1,5 +1,5 @@ -- name: Upload tag to dockerhub - command: "docker push {{ zj_image.repository }}:{{ upload_docker_image_promote | ternary('change_' + zuul.get('change', '') + '_', '') }}{{ zj_image_tag }}" +- name: Upload tag to registry + command: "docker push {{ docker_registry | ternary(docker_registry + '/', '' ) }}{{ zj_image.repository }}:{{ upload_docker_image_promote | ternary('change_' + zuul.get('change', '') + '_', '') }}{{ zj_image_tag }}" loop: "{{ zj_image.tags | default(['latest']) }}" loop_control: loop_var: zj_image_tag diff --git a/test-playbooks/container/test-build-container-image-release.yaml b/test-playbooks/container/test-build-container-image-release.yaml index 9d5243e1e..d749d2d66 100644 --- a/test-playbooks/container/test-build-container-image-release.yaml +++ b/test-playbooks/container/test-build-container-image-release.yaml @@ -1,5 +1,18 @@ - hosts: all - tasks: + vars: + docker_registry: localhost:5000 + upload_docker_image_promote: false + docker_credentials: + username: zuul + password: testpassword + repository: testrepo + docker_images: + - context: test-playbooks/container/docker + repository: "testrepo" + # This is what the Zuul repo uses to tag its releases: + tags: "{{ zuul.tag is defined | ternary([zuul.get('tag', '').split('.')[0], '.'.join(zuul.get('tag', '').split('.')[:2]), zuul.get('tag', '')], ['latest']) }}" + container_images: "{{ docker_images }}" + pre_tasks: - name: Save zuul variables set_fact: old_zuul: "{{ zuul }}" @@ -16,10 +29,72 @@ include_role: name: "build-{{ (container_command == 'docker') | ternary('docker', 'container') }}-image" vars: - docker_images: - - context: test-playbooks/container/docker - repository: "testrepo" - # This is what the Zuul repo uses to tag its releases: - tags: "{{ zuul.tag is defined | ternary([zuul.get('tag', '').split('.')[0], '.'.join(zuul.get('tag', '').split('.')[:2]), zuul.get('tag', '')], ['latest']) }}" - container_images: "{{ docker_images }}" + zuul: "{{ new_zuul }}" + + - name: Create temporary registry working directory + tempfile: + state: directory + register: registry_tempdir + + - name: Create auth directory + file: + path: "{{ registry_tempdir.path }}/auth" + state: directory + - name: Install passlib for htpasswd + become: true + package: + name: + - python3-passlib + - python3-bcrypt + state: present + - name: Write htpasswd file + htpasswd: + create: true + crypt_scheme: bcrypt + path: "{{ registry_tempdir.path }}/auth/htpasswd" + name: "{{ docker_credentials.username }}" + password: "{{ docker_credentials.password }}" + + - name: Create certs directory + file: + state: directory + path: "{{ registry_tempdir.path }}/certs" + - name: Create self signed certificates + command: > + openssl req + -newkey rsa:4096 -nodes -sha256 -keyout certs/localhost.key + -x509 -days 365 -out certs/localhost.crt + -subj '/CN=localhost' + args: + chdir: "{{ registry_tempdir.path }}" + - name: Create docker certs dir + file: + state: directory + path: /etc/docker/certs.d/localhost:5000/ + become: true + - name: Configure docker to trust certificate + copy: + src: "{{ registry_tempdir.path }}/certs/localhost.crt" + dest: /etc/docker/certs.d/localhost:5000/ca.crt + remote_src: true + become: true + + - name: Start registry with basic auth + command: >- + {{ container_command }} run -d \ + -p 5000:5000 \ + -v {{ registry_tempdir.path }}/auth:/auth \ + -e "REGISTRY_AUTH=htpasswd" \ + -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ + -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ + -v {{ registry_tempdir.path }}/certs:/certs \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/localhost.crt \ + -e REGISTRY_HTTP_TLS_KEY=/certs/localhost.key \ + registry:2 + args: + chdir: "{{ registry_tempdir.path }}" + + - include_role: + name: "upload-{{ (container_command == 'docker') | ternary('docker', 'container') }}-image" + vars: zuul: "{{ new_zuul }}"