Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 284 additions & 0 deletions ci/playbooks/bootc-ipa-pre-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
---
- name: Build and host bootc IPA artifacts
hosts: "{{ cifmw_target_hook_host | default(cifmw_target_host | default('localhost')) }}"
gather_facts: false
vars:
cifmw_bootc_ipa_artifact_dir: "{{ cifmw_basedir }}/artifacts/bootc-ipa"
cifmw_bootc_ipa_build_dir: "{{ ansible_user_dir }}/bootc-ipa-build"
cifmw_bootc_ipa_build_enabled: false
cifmw_bootc_ipa_build_output_prefix: "ipa-centos9-stable-2025.2-podman"
cifmw_bootc_ipa_release: "9-stream"
cifmw_bootc_ipa_branch: "stable/2025.2"
cifmw_bootc_ipa_flavor: "centos9"
cifmw_bootc_ipa_distro: "centos"
cifmw_bootc_ipa_server_namespace: "openstack"
cifmw_bootc_ipa_server_name: "bootc-ipa-artifacts"
cifmw_bootc_ipa_server_port: 8080
cifmw_bootc_ipa_server_image: "quay.io/prometheus/busybox:latest"
cifmw_bootc_ipa_published_basename: >-
ipa-{{ cifmw_bootc_ipa_flavor }}-{{ cifmw_bootc_ipa_branch | replace('/', '-') }}
cifmw_bootc_ipa_raw_kernel_file: >-
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_build_output_prefix }}.kernel
cifmw_bootc_ipa_raw_initramfs_file: >-
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_build_output_prefix }}.initramfs
cifmw_bootc_ipa_kernel_file: >-
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_published_basename }}.kernel
cifmw_bootc_ipa_initramfs_file: >-
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_published_basename }}.initramfs
cifmw_bootc_ipa_tarball: >-
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_published_basename }}.tar.gz
cifmw_bootc_ipa_service_url: >-
http://{{ cifmw_bootc_ipa_server_name }}.{{ cifmw_bootc_ipa_server_namespace }}.svc.cluster.local:{{ cifmw_bootc_ipa_server_port }}
tasks:
- name: Ensure IPA artifact directory exists
ansible.builtin.file:
path: "{{ cifmw_bootc_ipa_artifact_dir }}"
state: directory
mode: "0755"

- name: Ensure IPA build directory exists
when: cifmw_bootc_ipa_build_enabled | bool
ansible.builtin.file:
path: "{{ cifmw_bootc_ipa_build_dir }}"
state: directory
mode: "0755"

- name: Write minimal container steps file
when: cifmw_bootc_ipa_build_enabled | bool
ansible.builtin.copy:
dest: "{{ cifmw_bootc_ipa_build_dir }}/mysteps.yaml"
content: |
steps: []
mode: "0644"

- name: Build podman-enabled IPA artifacts
when: cifmw_bootc_ipa_build_enabled | bool
args:
chdir: "{{ cifmw_bootc_ipa_artifact_dir }}"
creates: "{{ cifmw_bootc_ipa_raw_initramfs_file }}"
executable: /bin/bash
ansible.builtin.shell: |
set -euo pipefail
python3 -m venv "{{ cifmw_bootc_ipa_build_dir }}/.venv"
. "{{ cifmw_bootc_ipa_build_dir }}/.venv/bin/activate"
python -m pip install --upgrade pip setuptools wheel
python -m pip install ironic-python-agent-builder
export DIB_ALLOW_ARBITRARY_CONTAINERS=true
export DIB_RUNNER=podman
export DIB_STEPS_FILE_PATH="{{ cifmw_bootc_ipa_build_dir }}/mysteps.yaml"
ironic-python-agent-builder \
-o "{{ cifmw_bootc_ipa_build_output_prefix }}" \
-r "{{ cifmw_bootc_ipa_release }}" \
-b "{{ cifmw_bootc_ipa_branch }}" \
-e ironic-python-agent-podman \
-v "{{ cifmw_bootc_ipa_distro }}"

- name: Check for raw IPA artifacts
ansible.builtin.stat:
path: "{{ item }}"
loop:
- "{{ cifmw_bootc_ipa_raw_kernel_file }}"
- "{{ cifmw_bootc_ipa_raw_initramfs_file }}"
register: cifmw_bootc_ipa_raw_artifacts

- name: Assert raw IPA artifacts exist
ansible.builtin.assert:
that:
- cifmw_bootc_ipa_raw_artifacts.results | map(attribute='stat.exists') | min
fail_msg: >-
Missing raw IPA artifacts. Expected
{{ cifmw_bootc_ipa_raw_kernel_file }} and
{{ cifmw_bootc_ipa_raw_initramfs_file }}.

- name: Copy kernel to published filename
ansible.builtin.copy:
src: "{{ cifmw_bootc_ipa_raw_kernel_file }}"
dest: "{{ cifmw_bootc_ipa_kernel_file }}"
mode: "0644"
remote_src: true

- name: Copy initramfs to published filename
ansible.builtin.copy:
src: "{{ cifmw_bootc_ipa_raw_initramfs_file }}"
dest: "{{ cifmw_bootc_ipa_initramfs_file }}"
mode: "0644"
remote_src: true

- name: Package IPA tarball with downloader-compatible filenames
args:
chdir: "{{ cifmw_bootc_ipa_artifact_dir }}"
executable: /bin/bash
ansible.builtin.shell: |
set -euo pipefail
tar -caf "{{ cifmw_bootc_ipa_tarball }}" \
"{{ cifmw_bootc_ipa_published_basename }}.kernel" \
"{{ cifmw_bootc_ipa_published_basename }}.initramfs"

- name: Ensure IPA hosting namespace exists
kubernetes.core.k8s:
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: "{{ cifmw_bootc_ipa_server_namespace }}"

- name: Create IPA hosting deployment
kubernetes.core.k8s:
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ cifmw_bootc_ipa_server_name }}"
namespace: "{{ cifmw_bootc_ipa_server_namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app: "{{ cifmw_bootc_ipa_server_name }}"
template:
metadata:
labels:
app: "{{ cifmw_bootc_ipa_server_name }}"
spec:
containers:
- name: server
image: "{{ cifmw_bootc_ipa_server_image }}"
command:
- sh
- -c
- >-
mkdir -p /srv &&
exec busybox httpd -f -p {{ cifmw_bootc_ipa_server_port }} -h /srv
ports:
- containerPort: "{{ cifmw_bootc_ipa_server_port }}"
volumeMounts:
- name: content
mountPath: /srv
volumes:
- name: content
emptyDir: {}

- name: Create IPA hosting service
kubernetes.core.k8s:
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: "{{ cifmw_bootc_ipa_server_name }}"
namespace: "{{ cifmw_bootc_ipa_server_namespace }}"
spec:
selector:
app: "{{ cifmw_bootc_ipa_server_name }}"
ports:
- name: http
port: "{{ cifmw_bootc_ipa_server_port }}"
targetPort: "{{ cifmw_bootc_ipa_server_port }}"

- name: Wait for IPA hosting pod to be ready
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc wait pod -n {{ cifmw_bootc_ipa_server_namespace }}
-l app={{ cifmw_bootc_ipa_server_name }}
--for=condition=Ready
--timeout=300s

- name: Get IPA hosting pod name
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc get pod -n {{ cifmw_bootc_ipa_server_namespace }}
-l app={{ cifmw_bootc_ipa_server_name }}
-o jsonpath='{.items[0].metadata.name}'
register: cifmw_bootc_ipa_server_pod
changed_when: false

- name: Copy IPA tarball into hosting pod
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc cp
"{{ cifmw_bootc_ipa_tarball }}"
"{{ cifmw_bootc_ipa_server_namespace }}/{{ cifmw_bootc_ipa_server_pod.stdout }}:/srv/{{ cifmw_bootc_ipa_tarball | basename }}"

- name: Verify IPA tarball is served from hosting pod
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc exec -n {{ cifmw_bootc_ipa_server_namespace }}
{{ cifmw_bootc_ipa_server_pod.stdout }} --
sh -c "wget -qO /dev/null http://127.0.0.1:{{ cifmw_bootc_ipa_server_port }}/{{ cifmw_bootc_ipa_tarball | basename }}"

- name: Feed generated bootc IPA values back to main play
ansible.builtin.copy:
dest: "{{ cifmw_basedir }}/artifacts/{{ step }}_{{ hook_name }}.yml"
mode: "0644"
content: |
cifmw_bootc_ipa_service_url: "{{ cifmw_bootc_ipa_service_url }}"
cifmw_edpm_prepare_extra_vars:
BMO_IPA_BASEURI: "{{ cifmw_bootc_ipa_service_url }}"
BMO_IPA_BRANCH: "{{ cifmw_bootc_ipa_branch }}"
BMO_IPA_FLAVOR: "{{ cifmw_bootc_ipa_flavor }}"

- name: Find ironic configmap namespace
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc get configmap ironic-bmo-configmap -A
-o jsonpath='{.items[0].metadata.namespace}'
register: cifmw_bootc_ipa_ironic_namespace
changed_when: false
failed_when: false

- name: Patch live ironic configmap with bootc IPA source
when: cifmw_bootc_ipa_ironic_namespace.rc == 0 and cifmw_bootc_ipa_ironic_namespace.stdout | length > 0
kubernetes.core.k8s:
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
state: patched
definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: ironic-bmo-configmap
namespace: "{{ cifmw_bootc_ipa_ironic_namespace.stdout }}"
data:
IPA_BASEURI: "{{ cifmw_bootc_ipa_service_url }}"
IPA_BRANCH: "{{ cifmw_bootc_ipa_branch }}"
IPA_FLAVOR: "{{ cifmw_bootc_ipa_flavor }}"

- name: Restart ironic deployment to re-run IPA downloader
when: cifmw_bootc_ipa_ironic_namespace.rc == 0 and cifmw_bootc_ipa_ironic_namespace.stdout | length > 0
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc rollout restart deployment/ironic
-n {{ cifmw_bootc_ipa_ironic_namespace.stdout }}

- name: Wait for ironic rollout after configmap patch
when: cifmw_bootc_ipa_ironic_namespace.rc == 0 and cifmw_bootc_ipa_ironic_namespace.stdout | length > 0
environment:
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
PATH: "{{ cifmw_path }}"
ansible.builtin.command:
cmd: >-
oc rollout status deployment/ironic
-n {{ cifmw_bootc_ipa_ironic_namespace.stdout }}
--timeout=10m
24 changes: 24 additions & 0 deletions zuul.d/jobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@
- job:
name: openstack-baremetal-operator-crc-podified-edpm-baremetal
parent: cifmw-crc-podified-edpm-baremetal

- job:
name: openstack-baremetal-operator-crc-podified-edpm-baremetal-bootc
parent: cifmw-crc-podified-edpm-baremetal-bootc
vars:
cifmw_update_containers: true
cifmw_update_containers_openstack: true
cifmw_update_containers_edpm_image_url: oci://quay.io/rabi/edpm-bootc:oci-test
pre_deploy:
- name: 61 Bootc IPA artifacts
type: playbook
source: "{{ ansible_user_dir }}/src/github.com/openstack-k8s-operators/openstack-baremetal-operator/ci/playbooks/bootc-ipa-pre-deploy.yml"
extra_vars:
cifmw_bootc_ipa_build_enabled: true
post_ctlplane_deploy:
- name: 61 Bootc IPA reconfigure ironic
type: playbook
source: "{{ ansible_user_dir }}/src/github.com/openstack-k8s-operators/openstack-baremetal-operator/ci/playbooks/bootc-ipa-pre-deploy.yml"
extra_vars:
cifmw_bootc_ipa_build_enabled: false
cifmw_install_yamls_vars:
BAREMETAL_OS_IMG_TYPE: PassThrough
BMO_DEFAULT_DEPLOY_INTERFACE: bootc

- job:
name: openstack-baremetal-operator-edpm-baremetal-minor-update
parent: cifmw-crc-podified-edpm-baremetal-minor-update
3 changes: 3 additions & 0 deletions zuul.d/projects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
- openstack-baremetal-operator-crc-podified-edpm-baremetal:
dependencies:
- openstack-baremetal-operator-content-provider
- openstack-baremetal-operator-crc-podified-edpm-baremetal-bootc:
dependencies:
- openstack-baremetal-operator-content-provider
- openstack-baremetal-operator-edpm-baremetal-minor-update:
dependencies:
- openstack-baremetal-operator-content-provider