diff --git a/ci/playbooks/content_provider/content_provider.yml b/ci/playbooks/content_provider/content_provider.yml index 9034fa2f4..39ea3a3fa 100644 --- a/ci/playbooks/content_provider/content_provider.yml +++ b/ci/playbooks/content_provider/content_provider.yml @@ -21,6 +21,14 @@ ansible.builtin.include_role: name: registry_deploy + - name: Build content provider images + when: >- + (cifmw_edpm_build_images_all | default(false) | bool) or + (cifmw_edpm_build_images_hardened_uefi | default(false) | bool) or + (cifmw_edpm_build_images_ironic_python_agent | default(false) | bool) or + (cifmw_edpm_build_images_bootc | default(false) | bool) + ansible.builtin.import_tasks: "{{ playbook_dir }}/../edpm_build_images/content_provider_tasks.yml" + - name: Set var for cifmw_operator_build_operators var # It handles the case of setting image_base for # openstack-ansibleee-operator and openstack-operator project diff --git a/ci/playbooks/content_provider/run.yml b/ci/playbooks/content_provider/run.yml index 5dee1c01f..e0462d595 100644 --- a/ci/playbooks/content_provider/run.yml +++ b/ci/playbooks/content_provider/run.yml @@ -53,6 +53,7 @@ zuul: pause: true cifmw_operator_build_output: "{{ inner_ansible_vars.cifmw_operator_build_output }}" + cifmw_build_images_output: "{{ inner_ansible_vars.cifmw_build_images_output | default({}) }}" content_provider_registry_available: "{{ _registry_available }}" content_provider_registry_ip: "{{ _registry_ip }}" content_provider_registry_ip_port: "{{ _registry_ip_port if _registry_available else '' }}" diff --git a/ci/playbooks/edpm_build_images/content_provider_tasks.yml b/ci/playbooks/edpm_build_images/content_provider_tasks.yml new file mode 100644 index 000000000..06b35e154 --- /dev/null +++ b/ci/playbooks/edpm_build_images/content_provider_tasks.yml @@ -0,0 +1,106 @@ +--- +- name: Construct project change list + ansible.builtin.set_fact: + zuul_change_list: "{{ zuul_change_list | default([]) + [item.project.short_name] }}" + cacheable: true + loop: "{{ zuul['items'] }}" + when: + - zuul is defined + - "'items' in zuul" + - "'change_url' in item" + +- name: Build EDPM content provider images + when: + - (cifmw_edpm_build_images_force | default(false) | bool) or + ('edpm-image-builder' in (zuul_change_list | default([]))) + block: + - name: Call repo setup + ansible.builtin.import_role: + name: repo_setup + vars: + cifmw_repo_setup_output: "/etc/yum.repos.d/" + + - name: Get latest commit when no PR is provided + ansible.builtin.command: # noqa: command-instead-of-module + cmd: git show-ref --head --hash head + args: + chdir: "{{ ansible_user_dir }}/src/github.com/openstack-k8s-operators/edpm-image-builder" + register: git_head_out + + - name: Set pr_sha to be used as image tag + ansible.builtin.set_fact: + pr_sha: "{{ git_head_out.stdout | trim }}" + cacheable: true + + - name: Build edpm and ipa images + ansible.builtin.include_role: + name: edpm_build_images + vars: + cifmw_edpm_build_images_via_rpm: false + cifmw_edpm_build_images_tag: "{{ pr_sha }}" + cifmw_edpm_build_images_push_container_images: true + cifmw_edpm_build_images_push_registry: "{{ cifmw_rp_registry_ip | default('localhost') }}:5001" + cifmw_edpm_build_images_push_registry_namespace: "" + cifmw_edpm_build_images_bootc_repo: "{{ cifmw_rp_registry_ip | default('localhost') }}:5001/edpm-bootc" + + - name: Set build images output + ansible.builtin.set_fact: + cifmw_build_images_output: >- + {{ + { + 'images': {} + } + | + combine( + { + 'images': { + 'edpm-hardened-uefi': { + 'image': (cifmw_rp_registry_ip | default('localhost')) ~ ':5001/edpm-hardened-uefi:' ~ pr_sha + } + } + } + if ( + ( + cifmw_edpm_build_images_hardened_uefi | default(false) | bool + ) or ( + cifmw_edpm_build_images_all | default(false) | bool + ) + ) and ( + cifmw_edpm_build_images_hardened_uefi_package | default(true) | bool + ) + else {}, + recursive=true + ) + | + combine( + { + 'images': { + 'ironic-python-agent': { + 'image': (cifmw_rp_registry_ip | default('localhost')) ~ ':5001/ironic-python-agent:' ~ pr_sha + } + } + } + if ( + ( + cifmw_edpm_build_images_ironic_python_agent | default(false) | bool + ) or ( + cifmw_edpm_build_images_all | default(false) | bool + ) + ) and ( + cifmw_edpm_build_images_ironic_python_agent_package | default(true) | bool + ) + else {}, + recursive=true + ) + | + combine(cifmw_edpm_build_images_bootc_output | default({}), recursive=true) + }} + cacheable: true + +- name: Set build images output when EDPM image is not built + when: + - not (cifmw_edpm_build_images_force | default(false) | bool) + - "'edpm-image-builder' not in (zuul_change_list | default([]))" + ansible.builtin.set_fact: + cifmw_build_images_output: {} + cacheable: true diff --git a/ci/playbooks/edpm_build_images/edpm_build_images_content_provider.yaml b/ci/playbooks/edpm_build_images/edpm_build_images_content_provider.yaml index cb1e39044..4c7c81b55 100644 --- a/ci/playbooks/edpm_build_images/edpm_build_images_content_provider.yaml +++ b/ci/playbooks/edpm_build_images/edpm_build_images_content_provider.yaml @@ -7,50 +7,8 @@ ansible.builtin.include_role: name: registry_deploy - - name: Call repo setup - ansible.builtin.import_role: - name: repo_setup - vars: - cifmw_repo_setup_output: "/etc/yum.repos.d/" - - - name: Get latest commit when no PR is provided - ansible.builtin.command: # noqa: command-instead-of-module - cmd: git show-ref --head --hash head - args: - chdir: "{{ ansible_user_dir }}/src/github.com/openstack-k8s-operators/edpm-image-builder" - register: git_head_out - - - name: Set pr_sha to be used as image tag - ansible.builtin.set_fact: - pr_sha: "{{ git_head_out.stdout | trim }}" - cacheable: true - - - name: Build edpm and ipa images - ansible.builtin.include_role: - name: edpm_build_images - vars: - cifmw_edpm_build_images_tag: "{{ pr_sha }}" - - - name: Push edpm-hardened-uefi image to registry - containers.podman.podman_image: - name: "{{ item }}" - push_args: - dest: "{{ cifmw_rp_registry_ip | default('localhost') }}:5001/{{ item }}:{{ pr_sha }}" - tag: "{{ pr_sha }}" - push: true - loop: - - edpm-hardened-uefi - - ironic-python-agent - - - name: Set build images output - ansible.builtin.set_fact: - cifmw_build_images_output: - images: - edpm-hardened-uefi: - image: "{{ cifmw_rp_registry_ip | default('localhost') }}:5001/edpm-hardened-uefi:{{ pr_sha }}" - ironic-python-agent: - image: "{{ cifmw_rp_registry_ip | default('localhost') }}:5001/ironic-python-agent:{{ pr_sha }}" - cacheable: true + - name: Build content provider images + ansible.builtin.import_tasks: "{{ playbook_dir }}/content_provider_tasks.yml" - name: Get the containers list from container registry ansible.builtin.uri: diff --git a/ci/templates/projects.yaml b/ci/templates/projects.yaml index b0bba71c6..e190eb144 100644 --- a/ci/templates/projects.yaml +++ b/ci/templates/projects.yaml @@ -7,6 +7,7 @@ name: openstack-k8s-operators/ci-framework templates: - podified-multinode-edpm-ci-framework-pipeline + - podified-multinode-edpm-baremetal-bootc-pipeline - data-plane-adoption-ci-framework-pipeline - whitebox-neutron-tempest-plugin-podified-pipeline github-check: @@ -22,4 +23,12 @@ - cifmw-tcib - cifmw-architecture-validate-hci - ci-framework-openstack-meta-content-provider + # Build EDPM OS container images on ci-framework PRs to validate CP wiring here. + # Other repos using the same templates build OS container images only on edpm-image-builder changes. + - openstack-k8s-operators-content-provider: + vars: + cifmw_edpm_build_images_force: true + - openstack-k8s-operators-content-provider-bootc: + vars: + cifmw_edpm_build_images_force: true # Start generated content diff --git a/roles/edpm_build_images/defaults/main.yml b/roles/edpm_build_images/defaults/main.yml index 9ef825552..434058303 100644 --- a/roles/edpm_build_images/defaults/main.yml +++ b/roles/edpm_build_images/defaults/main.yml @@ -36,8 +36,17 @@ cifmw_edpm_build_images_elements: cifmw_edpm_build_images_all: true cifmw_edpm_build_images_hardened_uefi: false cifmw_edpm_build_images_ironic_python_agent: false +cifmw_edpm_build_images_bootc: false cifmw_edpm_build_images_hardened_uefi_package: true cifmw_edpm_build_images_ironic_python_agent_package: true +cifmw_edpm_build_images_bootc_repo: "{{ cifmw_edpm_build_images_push_registry }}/edpm-bootc" +cifmw_edpm_build_images_bootc_repo_path: "{{ cifmw_edpm_image_builder_repo_path }}/bootc" +cifmw_edpm_build_images_bootc_base_image: "quay.io/centos-bootc/centos-bootc:stream9" +cifmw_edpm_build_images_bootc_builder_image: "quay.io/centos-bootc/bootc-image-builder:latest" +cifmw_edpm_build_images_bootc_qcow2_name: "edpm-bootc.qcow2" +cifmw_edpm_build_images_bootc_rhsm_script: "empty.sh" +cifmw_edpm_build_images_bootc_fips: "1" +cifmw_edpm_build_images_bootc_user_packages: "" cifmw_edpm_build_images_dib_yum_repo_conf_centos: - /etc/yum.repos.d/* cifmw_edpm_build_images_dib_yum_repo_conf_rhel: diff --git a/roles/edpm_build_images/tasks/bootc.yml b/roles/edpm_build_images/tasks/bootc.yml new file mode 100644 index 000000000..de66fc3a2 --- /dev/null +++ b/roles/edpm_build_images/tasks/bootc.yml @@ -0,0 +1,118 @@ +--- +- name: Ensure bootc output directories exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: "0755" + loop: + - "{{ cifmw_edpm_build_images_bootc_repo_path }}/output" + - "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/yum.repos.d" + +- name: Discover repo files for bootc build + ansible.builtin.find: + paths: /etc/yum.repos.d + file_type: file + recurse: false + register: cifmw_edpm_build_images_bootc_repo_files + +- name: Copy repo files for bootc build + become: true + ansible.builtin.copy: + src: "{{ item.path }}" + dest: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/yum.repos.d/{{ item.path | basename }}" + remote_src: true + mode: "0644" + loop: "{{ cifmw_edpm_build_images_bootc_repo_files.files }}" + loop_control: + label: "{{ item.path | basename }}" + +- name: Build bootc container image + become: true + args: + chdir: "{{ cifmw_edpm_build_images_bootc_repo_path }}" + ansible.builtin.shell: >- + buildah bud + --network host + --build-arg EDPM_BASE_IMAGE={{ cifmw_edpm_build_images_bootc_base_image }} + --build-arg RHSM_SCRIPT={{ cifmw_edpm_build_images_bootc_rhsm_script }} + --build-arg FIPS={{ cifmw_edpm_build_images_bootc_fips }} + --build-arg USER_PACKAGES={{ cifmw_edpm_build_images_bootc_user_packages }} + --volume /etc/pki/ca-trust:/etc/pki/ca-trust:ro,Z + --volume {{ cifmw_edpm_build_images_bootc_repo_path }}/output/yum.repos.d:/etc/yum.repos.d:rw,Z + -f ./Containerfile + -t localhost/edpm-bootc:{{ cifmw_edpm_build_images_tag }} + . > {{ cifmw_edpm_build_images_basedir }}/logs/edpm_images/edpm_bootc_image_build.log + 2> {{ cifmw_edpm_build_images_basedir }}/logs/edpm_images/edpm_bootc_image_build_err.log + +- name: Generate bootc qcow2 image + become: true + args: + chdir: "{{ cifmw_edpm_build_images_bootc_repo_path }}" + ansible.builtin.shell: >- + podman run --rm --privileged + --security-opt label=type:unconfined_t + -v ./output:/output + -v /var/lib/containers/storage:/var/lib/containers/storage + {{ cifmw_edpm_build_images_bootc_builder_image }} + --type qcow2 + --local + localhost/edpm-bootc:{{ cifmw_edpm_build_images_tag }} + > {{ cifmw_edpm_build_images_basedir }}/logs/edpm_images/edpm_bootc_qcow2_build.log + 2> {{ cifmw_edpm_build_images_basedir }}/logs/edpm_images/edpm_bootc_qcow2_build_err.log + +- name: Rename generated bootc qcow2 image + become: true + ansible.builtin.command: + cmd: >- + mv + {{ cifmw_edpm_build_images_bootc_repo_path }}/output/qcow2/disk.qcow2 + {{ cifmw_edpm_build_images_bootc_repo_path }}/output/{{ cifmw_edpm_build_images_bootc_qcow2_name }} + creates: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/{{ cifmw_edpm_build_images_bootc_qcow2_name }}" + removes: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/qcow2/disk.qcow2" + +- name: Get bootc qcow2 checksum + ansible.builtin.stat: + path: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/{{ cifmw_edpm_build_images_bootc_qcow2_name }}" + checksum_algorithm: sha256 + register: cifmw_edpm_build_images_bootc_qcow2_stat + +- name: Write bootc qcow2 checksum file + ansible.builtin.copy: + dest: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/{{ cifmw_edpm_build_images_bootc_qcow2_name }}.sha256" + content: | + {{ cifmw_edpm_build_images_bootc_qcow2_stat.stat.checksum }} {{ cifmw_edpm_build_images_bootc_qcow2_name }} + mode: "0644" + +- name: Copy bootc qcow2 packaging helper files + ansible.builtin.copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + remote_src: true + mode: "{{ item.mode }}" + loop: + - src: "{{ cifmw_edpm_image_builder_repo_path }}/copy_out.sh" + dest: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/copy_out.sh" + mode: "0755" + - src: "{{ cifmw_edpm_image_builder_repo_path }}/Containerfile.image" + dest: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output/Containerfile.image" + mode: "0644" + +- name: Package bootc qcow2 image inside container image + become: true + args: + chdir: "{{ cifmw_edpm_build_images_bootc_repo_path }}/output" + ansible.builtin.command: + cmd: >- + buildah bud -f ./Containerfile.image + -t edpm-bootc:{{ cifmw_edpm_build_images_tag }}-qcow2 + --build-arg IMAGE_NAME=edpm-bootc + --build-arg BASE_IMAGE={{ cifmw_edpm_build_images_base_image }} + --logfile {{ cifmw_edpm_build_images_basedir }}/logs/edpm_images/edpm_bootc_qcow2_container_package.log + +- name: Set bootc build images output + ansible.builtin.set_fact: + cifmw_edpm_build_images_bootc_output: + images: + edpm-bootc-qcow2: + image: "{{ cifmw_edpm_build_images_bootc_repo }}:{{ cifmw_edpm_build_images_tag }}-qcow2" + cacheable: true diff --git a/roles/edpm_build_images/tasks/install.yml b/roles/edpm_build_images/tasks/install.yml index 01adbde38..3b2287cde 100644 --- a/roles/edpm_build_images/tasks/install.yml +++ b/roles/edpm_build_images/tasks/install.yml @@ -6,6 +6,13 @@ - cifmw_edpm_build_images_via_rpm - not cifmw_edpm_build_images_dry_run +- name: Add bootc host packages when needed + ansible.builtin.set_fact: + cifmw_edpm_build_images_host_packages: "{{ cifmw_edpm_build_images_host_packages + ['podman', 'osbuild-selinux'] }}" + when: + - cifmw_edpm_build_images_bootc | bool + - not cifmw_edpm_build_images_dry_run + - name: Install required packages when: - not cifmw_edpm_build_images_dry_run diff --git a/roles/edpm_build_images/tasks/main.yml b/roles/edpm_build_images/tasks/main.yml index 02309ad89..6af4ea1e0 100644 --- a/roles/edpm_build_images/tasks/main.yml +++ b/roles/edpm_build_images/tasks/main.yml @@ -47,6 +47,10 @@ - name: Package build images inside container image ansible.builtin.import_tasks: package.yml +- name: Build bootc images + when: cifmw_edpm_build_images_bootc | bool + ansible.builtin.import_tasks: bootc.yml + - name: Push container images to quay.rdoproject.org when: cifmw_edpm_build_images_push_container_images | bool ansible.builtin.import_tasks: post.yaml diff --git a/roles/edpm_build_images/tasks/post.yaml b/roles/edpm_build_images/tasks/post.yaml index c4066986e..d7eefea79 100644 --- a/roles/edpm_build_images/tasks/post.yaml +++ b/roles/edpm_build_images/tasks/post.yaml @@ -1,45 +1,195 @@ --- -- name: "Push images to registry with tag {{ cifmw_edpm_build_images_tag }}" +- name: Set push destination base + ansible.builtin.set_fact: + cifmw_edpm_build_images_push_destination_base: >- + {{ + cifmw_edpm_build_images_push_registry ~ + ( + '/' ~ cifmw_edpm_build_images_push_registry_namespace + if cifmw_edpm_build_images_push_registry_namespace | length > 0 + else '' + ) + }} + +- name: Push edpm-hardened-uefi image to registry with tag {{ cifmw_edpm_build_images_tag }} + when: + - (cifmw_edpm_build_images_hardened_uefi | bool) or (cifmw_edpm_build_images_all | bool) + - cifmw_edpm_build_images_hardened_uefi_package | bool + containers.podman.podman_image: + name: edpm-hardened-uefi + push_args: + dest: "{{ cifmw_edpm_build_images_push_destination_base }}/edpm-hardened-uefi" + tag: "{{ cifmw_edpm_build_images_tag }}" + pull: false + push: true + +- name: Push ironic-python-agent image to registry with tag {{ cifmw_edpm_build_images_tag }} + when: + - (cifmw_edpm_build_images_ironic_python_agent | bool) or (cifmw_edpm_build_images_all | bool) + - cifmw_edpm_build_images_ironic_python_agent_package | bool containers.podman.podman_image: - name: "{{ item }}" + name: ironic-python-agent push_args: - dest: "{{ cifmw_edpm_build_images_push_registry }}/{{ cifmw_edpm_build_images_push_registry_namespace }}" + dest: "{{ cifmw_edpm_build_images_push_destination_base }}/ironic-python-agent" tag: "{{ cifmw_edpm_build_images_tag }}" pull: false push: true - loop: - - edpm-hardened-uefi - - ironic-python-agent + +- name: Push bootc qcow2 image to registry with tag {{ cifmw_edpm_build_images_tag }} + when: cifmw_edpm_build_images_bootc | bool + become: true + ansible.builtin.command: + cmd: >- + podman push + localhost/edpm-bootc:{{ cifmw_edpm_build_images_tag }}-qcow2 + docker://{{ cifmw_edpm_build_images_bootc_repo }}:{{ cifmw_edpm_build_images_tag }}-qcow2 + +- name: Set bootc registry verification facts + when: cifmw_edpm_build_images_bootc | bool + ansible.builtin.set_fact: + _cifmw_edpm_build_images_bootc_registry: >- + {{ cifmw_edpm_build_images_bootc_repo | split('/', 1) | first }} + _cifmw_edpm_build_images_bootc_repository: >- + {{ cifmw_edpm_build_images_bootc_repo | split('/', 1) | last }} + +- name: Verify bootc qcow2 image manifest is available in registry + when: cifmw_edpm_build_images_bootc | bool + ansible.builtin.uri: + url: >- + http://{{ _cifmw_edpm_build_images_bootc_registry }}/v2/{{ + _cifmw_edpm_build_images_bootc_repository + }}/manifests/{{ cifmw_edpm_build_images_tag }}-qcow2 + method: GET + headers: + Accept: "application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json" + status_code: 200 + register: _cifmw_edpm_build_images_bootc_manifest_check + retries: 12 + delay: 5 + until: _cifmw_edpm_build_images_bootc_manifest_check.status == 200 + +- name: Smoke test bootc qcow2 image extraction + when: cifmw_edpm_build_images_bootc | bool + block: + - name: Create temporary directory for bootc qcow2 extraction test + ansible.builtin.tempfile: + state: directory + prefix: bootc-qcow2-smoke- + register: _cifmw_edpm_build_images_bootc_smoke_dir + + - name: Extract bootc qcow2 image into temporary directory + become: true + ansible.builtin.command: + cmd: >- + podman run --rm + --volume {{ _cifmw_edpm_build_images_bootc_smoke_dir.path }}:/target:Z + localhost/edpm-bootc:{{ cifmw_edpm_build_images_tag }}-qcow2 + + - name: List files extracted from bootc qcow2 image + ansible.builtin.command: + cmd: >- + ls -lah {{ _cifmw_edpm_build_images_bootc_smoke_dir.path }} + register: _cifmw_edpm_build_images_bootc_smoke_listing + changed_when: false + + - name: Check for extracted bootc qcow2 image file + ansible.builtin.stat: + path: >- + {{ _cifmw_edpm_build_images_bootc_smoke_dir.path }}/{{ + cifmw_edpm_build_images_bootc_qcow2_name }} + register: _cifmw_edpm_build_images_bootc_smoke_qcow2 + + - name: Check for extracted bootc qcow2 checksum file + ansible.builtin.stat: + path: >- + {{ _cifmw_edpm_build_images_bootc_smoke_dir.path }}/{{ + cifmw_edpm_build_images_bootc_qcow2_name }}.sha256 + register: _cifmw_edpm_build_images_bootc_smoke_checksum + + - name: Assert bootc qcow2 image extraction produced expected files + ansible.builtin.assert: + that: + - _cifmw_edpm_build_images_bootc_smoke_qcow2.stat.exists + - _cifmw_edpm_build_images_bootc_smoke_checksum.stat.exists + fail_msg: >- + Bootc qcow2 image extraction did not produce both + {{ cifmw_edpm_build_images_bootc_qcow2_name }} and its checksum file. + always: + - name: Remove temporary directory for bootc qcow2 extraction test + ansible.builtin.file: + path: "{{ _cifmw_edpm_build_images_bootc_smoke_dir.path }}" + state: absent + when: + - _cifmw_edpm_build_images_bootc_smoke_dir is defined + - _cifmw_edpm_build_images_bootc_smoke_dir.path is defined - name: Retag and push the images with podified-ci-testing tag when: cifmw_repo_setup_promotion in ("podified-ci-testing", "podified-ci-testing-tcib") block: - - name: Retag the images with podified-ci-testing tag + - name: Retag the edpm-hardened-uefi image with podified-ci-testing tag + when: + - (cifmw_edpm_build_images_hardened_uefi | bool) or (cifmw_edpm_build_images_all | bool) + - cifmw_edpm_build_images_hardened_uefi_package | bool + containers.podman.podman_tag: + image: "edpm-hardened-uefi:{{ cifmw_edpm_build_images_tag }}" + target_names: + - "edpm-hardened-uefi:podified-ci-testing" + + - name: Retag the ironic-python-agent image with podified-ci-testing tag + when: + - (cifmw_edpm_build_images_ironic_python_agent | bool) or (cifmw_edpm_build_images_all | bool) + - cifmw_edpm_build_images_ironic_python_agent_package | bool + containers.podman.podman_tag: + image: "ironic-python-agent:{{ cifmw_edpm_build_images_tag }}" + target_names: + - "ironic-python-agent:podified-ci-testing" + + - name: Retag the bootc qcow2 image with podified-ci-testing tag + when: cifmw_edpm_build_images_bootc | bool + become: true containers.podman.podman_tag: - image: "{{ item }}:{{ cifmw_edpm_build_images_tag }}" + image: "edpm-bootc:{{ cifmw_edpm_build_images_tag }}-qcow2" target_names: - - "{{ item }}:podified-ci-testing" - loop: - - edpm-hardened-uefi - - ironic-python-agent + - "edpm-bootc:podified-ci-testing-qcow2" - - name: Push images to registry with podified-ci-testing tag + - name: Push edpm-hardened-uefi image to registry with podified-ci-testing tag + when: + - (cifmw_edpm_build_images_hardened_uefi | bool) or (cifmw_edpm_build_images_all | bool) + - cifmw_edpm_build_images_hardened_uefi_package | bool containers.podman.podman_image: - name: "{{ item }}" + name: edpm-hardened-uefi push_args: - dest: "{{ cifmw_edpm_build_images_push_registry }}/{{ cifmw_edpm_build_images_push_registry_namespace }}" + dest: "{{ cifmw_edpm_build_images_push_destination_base }}/edpm-hardened-uefi" tag: podified-ci-testing pull: false push: true - loop: - - edpm-hardened-uefi - - ironic-python-agent + + - name: Push ironic-python-agent image to registry with podified-ci-testing tag + when: + - (cifmw_edpm_build_images_ironic_python_agent | bool) or (cifmw_edpm_build_images_all | bool) + - cifmw_edpm_build_images_ironic_python_agent_package | bool + containers.podman.podman_image: + name: ironic-python-agent + push_args: + dest: "{{ cifmw_edpm_build_images_push_destination_base }}/ironic-python-agent" + tag: podified-ci-testing + pull: false + push: true + + - name: Push bootc qcow2 image to registry with podified-ci-testing tag + when: cifmw_edpm_build_images_bootc | bool + become: true + ansible.builtin.command: + cmd: >- + podman push + localhost/edpm-bootc:podified-ci-testing-qcow2 + docker://{{ cifmw_edpm_build_images_bootc_repo }}:podified-ci-testing-qcow2 - name: Dump edpm container images in the file # noqa: risky-shell-pipe args: chdir: "{{ cifmw_edpm_image_builder_repo_path }}" ansible.builtin.shell: >- buildah images | - grep -E '(edpm-hardened-uefi|ironic-python-agent)' | + grep -E '(edpm-hardened-uefi|ironic-python-agent|edpm-bootc)' | tee -a {{ cifmw_edpm_build_images_basedir }}/logs/containers-built.log diff --git a/roles/edpm_deploy_baremetal/tasks/main.yml b/roles/edpm_deploy_baremetal/tasks/main.yml index 874262aee..3aa82cb30 100644 --- a/roles/edpm_deploy_baremetal/tasks/main.yml +++ b/roles/edpm_deploy_baremetal/tasks/main.yml @@ -244,6 +244,66 @@ --for condition=Available --timeout={{ cifmw_edpm_deploy_baremetal_wait_provisionserver_timeout_mins }}m + - name: Get OpenStack Provision Server local image URL + environment: + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" + PATH: "{{ cifmw_path }}" + ansible.builtin.command: + cmd: >- + oc get openstackprovisionserver + -n {{ cifmw_install_yamls_defaults['NAMESPACE'] }} + -o jsonpath='{.items[0].status.localImageUrl}' + register: cifmw_edpm_deploy_baremetal_provisionserver_local_image_url + changed_when: false + + - name: Get OpenStack Provision Server local image checksum URL + environment: + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" + PATH: "{{ cifmw_path }}" + ansible.builtin.command: + cmd: >- + oc get openstackprovisionserver + -n {{ cifmw_install_yamls_defaults['NAMESPACE'] }} + -o jsonpath='{.items[0].status.localImageChecksumUrl}' + register: cifmw_edpm_deploy_baremetal_provisionserver_local_image_checksum_url + changed_when: false + + - name: Set OpenStack Provision Server local image checksum URL fallback + ansible.builtin.set_fact: + cifmw_edpm_deploy_baremetal_provisionserver_local_image_checksum_url_effective: >- + {{ + cifmw_edpm_deploy_baremetal_provisionserver_local_image_checksum_url.stdout + if ( + cifmw_edpm_deploy_baremetal_provisionserver_local_image_checksum_url.stdout + | trim | length + ) > 0 + else + ( + cifmw_edpm_deploy_baremetal_provisionserver_local_image_url.stdout + ~ '.sha256' + ) + }} + + - name: Verify OpenStack Provision Server image is reachable + ansible.builtin.uri: + url: "{{ cifmw_edpm_deploy_baremetal_provisionserver_local_image_url.stdout }}" + method: HEAD + status_code: 200 + register: cifmw_edpm_deploy_baremetal_provisionserver_image_head + retries: 12 + delay: 5 + until: cifmw_edpm_deploy_baremetal_provisionserver_image_head.status == 200 + + - name: Verify OpenStack Provision Server image checksum is reachable + ansible.builtin.uri: + url: "{{ cifmw_edpm_deploy_baremetal_provisionserver_local_image_checksum_url_effective }}" + method: HEAD + status_code: 200 + register: cifmw_edpm_deploy_baremetal_provisionserver_checksum_head + retries: 12 + delay: 5 + until: cifmw_edpm_deploy_baremetal_provisionserver_checksum_head.status == 200 + - name: Wait for baremetal nodes to reach 'provisioned' state environment: KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" diff --git a/roles/edpm_prepare/tasks/main.yml b/roles/edpm_prepare/tasks/main.yml index 9029dab6f..285565cf4 100644 --- a/roles/edpm_prepare/tasks/main.yml +++ b/roles/edpm_prepare/tasks/main.yml @@ -158,13 +158,29 @@ ansible.builtin.include_role: name: set_openstack_containers -- name: Set facts for baremetal UEFI image url +- name: Set facts for baremetal image url ansible.builtin.set_fact: - cifmw_update_containers_edpm_image_url: "{{ cifmw_build_images_output['images']['edpm-hardened-uefi']['image'] }}" + cifmw_update_containers_edpm_image_url: >- + {{ + cifmw_build_images_output['images'][ + 'edpm-bootc-qcow2' + if (cifmw_edpm_deploy_baremetal_bootc | default(false) | bool) + else 'edpm-hardened-uefi' + ]['image'] + }} cacheable: true when: + - cifmw_update_containers_edpm_image_url is not defined - cifmw_build_images_output is defined - - cifmw_build_images_output.keys() | length > 0 + - "'images' in cifmw_build_images_output" + - >- + ( + cifmw_edpm_deploy_baremetal_bootc | default(false) | bool and + 'edpm-bootc-qcow2' in cifmw_build_images_output['images'] + ) or ( + not (cifmw_edpm_deploy_baremetal_bootc | default(false) | bool) and + 'edpm-hardened-uefi' in cifmw_build_images_output['images'] + ) # Prepare and kustomize the OpenStackControlPlane CR - name: Prepare OpenStack control plane CR diff --git a/zuul.d/base.yaml b/zuul.d/base.yaml index 9fb9caf96..e105b262b 100644 --- a/zuul.d/base.yaml +++ b/zuul.d/base.yaml @@ -81,6 +81,7 @@ - openstack-k8s-operators/ci-framework - openstack-k8s-operators/cinder-operator - openstack-k8s-operators/designate-operator + - openstack-k8s-operators/edpm-image-builder - openstack-k8s-operators/glance-operator - openstack-k8s-operators/heat-operator - openstack-k8s-operators/horizon-operator diff --git a/zuul.d/content_provider.yaml b/zuul.d/content_provider.yaml index 7ad7303ae..7c52c733a 100644 --- a/zuul.d/content_provider.yaml +++ b/zuul.d/content_provider.yaml @@ -3,6 +3,21 @@ name: content-provider-base parent: openstack-k8s-operators-content-provider +- job: + name: openstack-k8s-operators-content-provider-bootc + parent: openstack-k8s-operators-content-provider + timeout: 2700 + description: | + A zuul job to build and publish bootc qcow2 and ironic-python-agent + content for dependent jobs. + vars: + cifmw_edpm_build_images_all: false + cifmw_edpm_build_images_hardened_uefi: false + cifmw_edpm_build_images_hardened_uefi_package: false + cifmw_edpm_build_images_ironic_python_agent: true + cifmw_edpm_build_images_ironic_python_agent_package: true + cifmw_edpm_build_images_bootc: true + - job: name: openstack-meta-content-provider parent: openstack-k8s-operators-content-provider diff --git a/zuul.d/edpm.yaml b/zuul.d/edpm.yaml index 9debdedef..e9a33c68e 100644 --- a/zuul.d/edpm.yaml +++ b/zuul.d/edpm.yaml @@ -28,6 +28,8 @@ crc_parameters: "--memory 32000 --disk-size 240 --cpus 12" cifmw_manage_secrets_pullsecret_content: '{}' cifmw_rhol_crc_binary_folder: "/usr/local/bin" + cifmw_update_containers: true + cifmw_update_containers_openstack: true # Virtual Baremetal job with CRC and single bootc compute node. - job: @@ -39,13 +41,11 @@ crc_parameters: "--memory 32000 --disk-size 240 --cpus 12" cifmw_manage_secrets_pullsecret_content: '{}' cifmw_rhol_crc_binary_folder: "/usr/local/bin" - # This needs to be updated later to not use hardcoded image url but the one pushed by - # the periodic job for pushing the bootc images to the registry - cifmw_update_containers_edpm_image_url: quay.io/openstack-k8s-operators/edpm-bootc:latest-qcow2 cifmw_install_yamls_vars: BAREMETAL_OS_IMG: edpm-bootc.qcow2 cifmw_edpm_deploy_baremetal_bootc: true cifmw_update_containers: true + cifmw_update_containers_openstack: true # Virtual Baremetal job with CRC for minor update testing. # First deploys with pre-update index image (Phase 1), then updates with PR index image (Phase 2). @@ -66,6 +66,8 @@ cifmw_install_yamls_vars: OPENSTACK_CTLPLANE: "config/samples/core_v1beta1_openstackcontrolplane_galera_network_isolation_fr1.yaml" BMAAS_INSTANCE_DISK_SIZE: 60 + cifmw_update_containers: true + cifmw_update_containers_openstack: true # Podified galera job - job: diff --git a/zuul.d/edpm_build_images_content_provider.yaml b/zuul.d/edpm_build_images_content_provider.yaml index 568060c1b..85810ec22 100644 --- a/zuul.d/edpm_build_images_content_provider.yaml +++ b/zuul.d/edpm_build_images_content_provider.yaml @@ -29,6 +29,10 @@ - job: name: cifmw-content-provider-build-images parent: content-provider-build-images-base + timeout: 2700 + vars: + cifmw_edpm_build_images_force: true + cifmw_edpm_build_images_bootc: true files: - ^ci/playbooks/edpm_build_images/edpm_build_images_content_provider.yaml - ^ci/playbooks/edpm_build_images/edpm_build_images_content_provider_run.yaml diff --git a/zuul.d/project-templates.yaml b/zuul.d/project-templates.yaml index f480a3042..70e1ee025 100644 --- a/zuul.d/project-templates.yaml +++ b/zuul.d/project-templates.yaml @@ -7,7 +7,10 @@ baremetal job. github-check: jobs: - - openstack-k8s-operators-content-provider + - openstack-k8s-operators-content-provider: &edpm_image_content_provider + vars: + cifmw_edpm_build_images_all: true + cifmw_edpm_build_images_bootc: false - podified-multinode-edpm-deployment-crc: &content_provider dependencies: - openstack-k8s-operators-content-provider @@ -21,7 +24,11 @@ baremetal job. github-check: jobs: - - cifmw-crc-podified-edpm-baremetal-bootc: *content_provider + - openstack-k8s-operators-content-provider-bootc + - cifmw-crc-podified-edpm-baremetal-bootc: + dependencies: + - openstack-k8s-operators-content-provider-bootc + - cifmw-pod-zuul-files - project-template: name: podified-multinode-edpm-pipeline @@ -54,6 +61,7 @@ github-check: jobs: - openstack-k8s-operators-content-provider: + <<: *edpm_image_content_provider requires: - cifmw-pod-pre-commit - cifmw-molecule diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 9b4b8e84b..940d5131c 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -12,6 +12,12 @@ - cifmw-tcib - cifmw-architecture-validate-hci - ci-framework-openstack-meta-content-provider + - openstack-k8s-operators-content-provider: + vars: + cifmw_edpm_build_images_force: true + - openstack-k8s-operators-content-provider-bootc: + vars: + cifmw_edpm_build_images_force: true - cifmw-molecule-adoption_osp_deploy - cifmw-molecule-artifacts - cifmw-molecule-bm_sno @@ -118,5 +124,6 @@ name: openstack-k8s-operators/ci-framework templates: - podified-multinode-edpm-ci-framework-pipeline + - podified-multinode-edpm-baremetal-bootc-pipeline - data-plane-adoption-ci-framework-pipeline - whitebox-neutron-tempest-plugin-podified-pipeline