Files
kubespray/test-infra/image-builder/roles/kubevirt-images/tasks/main.yml
Srishti Jaiswal da6b8e8b81 image-builder: run validation with Dind (#13212)
* image-builder: run validation locally with BuildKit

* upadte checksum

* set BuildKit no-process-sandbox flag for CI

* run BuildKit with rootless-safe daemon flags in CI

* update

* updating root logic

* fix ci failure for can't enable NoProcessSandbox

* switch to stable url

* add --oci-worker-no-process-sandbox ci flag in root path

* add more support

* add validate-docker and validate-single docker
2026-05-11 13:27:50 +05:30

202 lines
7.6 KiB
YAML

---
- name: Build kubevirt images
vars:
kubevirt_images_to_build: "{{ images | dict2items if kubevirt_images_selected | length == 0 else ([images] | community.general.keep_keys(target=kubevirt_images_selected))[0] | dict2items }}"
block:
- name: Validate selected image names
assert:
that:
- kubevirt_images_selected | length == 0 or kubevirt_images_to_build | length > 0
fail_msg: "No matching images found in `images` for `kubevirt_images_selected={{ kubevirt_images_selected }}`"
- name: Validate requested container builder
assert:
that:
- kubevirt_container_builder in ['docker', 'buildkit']
fail_msg: "Unsupported kubevirt_container_builder={{ kubevirt_container_builder }}"
- name: Validate BuildKit push mode
assert:
that:
- not (kubevirt_container_builder == 'buildkit' and kubevirt_images_push)
fail_msg: "BuildKit validation currently requires kubevirt_images_push=false"
- name: Check qemu-img availability
command: qemu-img --version
changed_when: false
- name: Check Docker availability
command: docker --version
changed_when: false
when: kubevirt_container_builder == 'docker'
- name: Detect BuildKit daemonless wrapper availability
shell: command -v buildctl-daemonless.sh
args:
executable: /bin/bash
register: kubevirt_buildctl_daemonless_available
changed_when: false
failed_when: false
when: kubevirt_container_builder == 'buildkit'
- name: Check BuildKit availability
shell: |
set -euo pipefail
if [ "{{ kubevirt_buildctl_daemonless_available.rc | default(1) }}" -eq 0 ]; then
buildctl-daemonless.sh --version
else
buildctl --version
buildkitd --version
fi
args:
executable: /bin/bash
changed_when: false
when: kubevirt_container_builder == 'buildkit'
- name: Create image directory
file:
state: directory
path: "{{ images_dir }}"
mode: "0755"
- name: Create buildkit output directory
file:
state: directory
path: "{{ kubevirt_buildkit_output_dir }}"
mode: "0755"
when: kubevirt_container_builder == 'buildkit'
- name: Download images files
get_url:
url: "{{ item.value.url }}"
dest: "{{ images_dir }}/{{ item.value.filename }}"
checksum: "{{ item.value.checksum }}"
mode: "0644"
loop: "{{ kubevirt_images_to_build }}"
- name: Unxz compressed images
command: unxz --force {{ images_dir }}/{{ item.value.filename }}
loop: "{{ kubevirt_images_to_build }}"
when:
- item.value.filename.endswith('.xz')
- name: Convert images which is not in qcow2 format
command: qemu-img convert -O qcow2 {{ images_dir }}/{{ item.value.filename.rstrip('.xz') }} {{ images_dir }}/{{ item.key }}.qcow2
loop: "{{ kubevirt_images_to_build }}"
when:
- not (item.value.converted | bool)
- name: Make sure all images are ending with qcow2
command: cp {{ images_dir }}/{{ item.value.filename.rstrip('.xz') }} {{ images_dir }}/{{ item.key }}.qcow2
loop: "{{ kubevirt_images_to_build }}"
when:
- item.value.converted | bool
- name: Resize images
command: qemu-img resize {{ images_dir }}/{{ item.key }}.qcow2 +8G
loop: "{{ kubevirt_images_to_build }}"
# STEP 2: Include the images inside a container
- name: Template default Dockerfile
template:
src: Dockerfile
dest: "{{ images_dir }}/Dockerfile"
mode: "0644"
- name: Create docker images for each OS
command: docker build -t {{ registry }}/vm-{{ item.key }}:{{ item.value.tag }} --build-arg cloud_image="{{ item.key }}.qcow2" {{ images_dir }}
loop: "{{ kubevirt_images_to_build }}"
when: kubevirt_container_builder == 'docker'
- name: Create container images for each OS with BuildKit
shell: |
set -euo pipefail
IMAGE_REF="{{ registry }}/vm-{{ item.key }}:{{ item.value.tag }}"
OUTPUT_TAR="{{ kubevirt_buildkit_output_dir }}/vm-{{ item.key }}-{{ item.value.tag }}.tar"
# Rootless BuildKit is the CI path; root mode must not use rootless-only flags.
if [ "$(id -u)" -eq 0 ]; then
BUILDKITD_FLAGS="${BUILDKITD_FLAGS:-}"
else
BUILDKITD_FLAGS="${BUILDKITD_FLAGS:---rootless --oci-worker-no-process-sandbox --oci-worker-snapshotter=native}"
fi
run_buildkit() {
if [ "{{ kubevirt_buildctl_daemonless_available.rc | default(1) }}" -eq 0 ]; then
export BUILDKITD_FLAGS
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context={{ images_dir }} \
--local dockerfile={{ images_dir }} \
--opt filename=Dockerfile \
--opt build-arg:cloud_image={{ item.key }}.qcow2 \
--output "{{ 'type=image,name=' ~ registry ~ '/vm-' ~ item.key ~ ':' ~ item.value.tag ~ ',push=true' if kubevirt_images_push else 'type=oci,dest=' ~ kubevirt_buildkit_output_dir ~ '/vm-' ~ item.key ~ '-' ~ item.value.tag ~ '.tar' }}"
else
BUILDKIT_ADDR="unix:///tmp/buildkitd-{{ item.key }}.sock"
buildkitd ${BUILDKITD_FLAGS} --addr "${BUILDKIT_ADDR}" >/tmp/buildkitd-{{ item.key }}.log 2>&1 &
buildkitd_pid=$!
cleanup() {
kill "${buildkitd_pid}" >/dev/null 2>&1 || true
wait "${buildkitd_pid}" >/dev/null 2>&1 || true
}
trap cleanup EXIT
for _ in $(seq 1 50); do
if buildctl --addr "${BUILDKIT_ADDR}" debug workers >/dev/null 2>&1; then
break
fi
sleep 0.2
done
buildctl --addr "${BUILDKIT_ADDR}" build \
--frontend dockerfile.v0 \
--local context={{ images_dir }} \
--local dockerfile={{ images_dir }} \
--opt filename=Dockerfile \
--opt build-arg:cloud_image={{ item.key }}.qcow2 \
--output "{{ 'type=image,name=' ~ registry ~ '/vm-' ~ item.key ~ ':' ~ item.value.tag ~ ',push=true' if kubevirt_images_push else 'type=oci,dest=' ~ kubevirt_buildkit_output_dir ~ '/vm-' ~ item.key ~ '-' ~ item.value.tag ~ '.tar' }}"
fi
}
if run_buildkit; then
exit 0
fi
echo "BuildKit failed in this environment; attempting Docker fallback for {{ item.key }}" >&2
if ! command -v docker >/dev/null 2>&1; then
echo "Docker fallback unavailable: docker command not found" >&2
exit 1
fi
docker build -t "${IMAGE_REF}" --build-arg cloud_image="{{ item.key }}.qcow2" {{ images_dir }}
{% if kubevirt_images_push %}
docker push "${IMAGE_REF}"
{% else %}
docker save -o "${OUTPUT_TAR}" "${IMAGE_REF}"
{% endif %}
args:
executable: /bin/bash
loop: "{{ kubevirt_images_to_build }}"
when: kubevirt_container_builder == 'buildkit'
- name: Docker login
command: docker login -u="{{ docker_user }}" -p="{{ docker_password }}" "{{ docker_host }}"
when:
- kubevirt_container_builder == 'docker'
- kubevirt_images_push
- name: Docker push image
command: docker push {{ registry }}/vm-{{ item.key }}:{{ item.value.tag }}
loop: "{{ kubevirt_images_to_build }}"
when:
- kubevirt_container_builder == 'docker'
- kubevirt_images_push
- name: Docker logout
command: docker logout "{{ docker_host }}"
when:
- kubevirt_container_builder == 'docker'
- kubevirt_images_push