Skip to content

Commit 1f665b5

Browse files
committed
Add bootc passthrough baremetal CI job
Add a bootc EDPM baremetal job variant that reuses the normal content provider while switching the deployment to PassThrough with the direct bootc image. Depends-On: openstack-k8s-operators/install_yamls#1149 Signed-off-by: rabi <ramishra@redhat.com>
1 parent 7d7c29a commit 1f665b5

4 files changed

Lines changed: 476 additions & 0 deletions

File tree

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
---
2+
- name: Build and host bootc IPA artifacts
3+
hosts: "{{ cifmw_target_hook_host | default(cifmw_target_host | default('localhost')) }}"
4+
gather_facts: false
5+
vars:
6+
cifmw_bootc_ipa_artifact_dir: "{{ cifmw_basedir }}/artifacts/bootc-ipa"
7+
cifmw_bootc_ipa_build_dir: "{{ ansible_user_dir }}/bootc-ipa-build"
8+
cifmw_bootc_ipa_build_enabled: false
9+
cifmw_bootc_ipa_build_output_prefix: "ipa-centos9-stable-2025.2-podman"
10+
cifmw_bootc_ipa_release: "9-stream"
11+
cifmw_bootc_ipa_branch: "stable/2025.2"
12+
cifmw_bootc_ipa_flavor: "centos9"
13+
cifmw_bootc_ipa_distro: "centos"
14+
cifmw_bootc_ipa_server_namespace: "openstack"
15+
cifmw_bootc_ipa_server_name: "bootc-ipa-artifacts"
16+
cifmw_bootc_ipa_server_port: 8080
17+
cifmw_bootc_ipa_server_image: "registry.access.redhat.com/ubi9/ubi:latest"
18+
cifmw_bootc_ipa_published_basename: >-
19+
ipa-{{ cifmw_bootc_ipa_flavor }}-{{ cifmw_bootc_ipa_branch | replace('/', '-') }}
20+
cifmw_bootc_ipa_raw_kernel_file: >-
21+
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_build_output_prefix }}.kernel
22+
cifmw_bootc_ipa_raw_initramfs_file: >-
23+
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_build_output_prefix }}.initramfs
24+
cifmw_bootc_ipa_kernel_file: >-
25+
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_published_basename }}.kernel
26+
cifmw_bootc_ipa_initramfs_file: >-
27+
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_published_basename }}.initramfs
28+
cifmw_bootc_ipa_tarball: >-
29+
{{ cifmw_bootc_ipa_artifact_dir }}/{{ cifmw_bootc_ipa_published_basename }}.tar.gz
30+
cifmw_bootc_ipa_source_dir: "{{ cifmw_bootc_ipa_build_dir }}/ironic-python-agent"
31+
cifmw_bootc_ipa_fips_patch_enabled: true
32+
cifmw_bootc_ipa_service_ip: ""
33+
cifmw_bootc_ipa_service_url: ""
34+
tasks:
35+
- name: Ensure IPA artifact directory exists
36+
ansible.builtin.file:
37+
path: "{{ cifmw_bootc_ipa_artifact_dir }}"
38+
state: directory
39+
mode: "0755"
40+
41+
- name: Ensure IPA build directory exists
42+
when: cifmw_bootc_ipa_build_enabled | bool
43+
ansible.builtin.file:
44+
path: "{{ cifmw_bootc_ipa_build_dir }}"
45+
state: directory
46+
mode: "0755"
47+
48+
- name: Write minimal container steps file
49+
when: cifmw_bootc_ipa_build_enabled | bool
50+
ansible.builtin.copy:
51+
dest: "{{ cifmw_bootc_ipa_build_dir }}/mysteps.yaml"
52+
content: |
53+
steps: []
54+
mode: "0644"
55+
56+
- name: Clone IPA source for FIPS boot karg patch
57+
when: cifmw_bootc_ipa_build_enabled | bool and cifmw_bootc_ipa_fips_patch_enabled | bool
58+
ansible.builtin.git:
59+
repo: "https://opendev.org/openstack/ironic-python-agent.git"
60+
dest: "{{ cifmw_bootc_ipa_source_dir }}"
61+
version: "{{ cifmw_bootc_ipa_branch }}"
62+
63+
- name: Patch IPA with FIPS boot karg fixup
64+
when: cifmw_bootc_ipa_build_enabled | bool and cifmw_bootc_ipa_fips_patch_enabled | bool
65+
ansible.builtin.command:
66+
cmd: >-
67+
python3 {{ playbook_dir }}/../scripts/patch_ipa_fips_boot_karg.py
68+
{{ cifmw_bootc_ipa_source_dir }}/ironic_python_agent/extensions/standby.py
69+
70+
- name: Build podman-enabled IPA artifacts
71+
when: cifmw_bootc_ipa_build_enabled | bool
72+
args:
73+
chdir: "{{ cifmw_bootc_ipa_artifact_dir }}"
74+
creates: "{{ cifmw_bootc_ipa_raw_initramfs_file }}"
75+
executable: /bin/bash
76+
ansible.builtin.shell: |
77+
set -euo pipefail
78+
python3 -m venv "{{ cifmw_bootc_ipa_build_dir }}/.venv"
79+
. "{{ cifmw_bootc_ipa_build_dir }}/.venv/bin/activate"
80+
python -m pip install --upgrade pip setuptools wheel
81+
python -m pip install ironic-python-agent-builder
82+
export DIB_ALLOW_ARBITRARY_CONTAINERS=true
83+
export DIB_RUNNER=podman
84+
export DIB_STEPS_FILE_PATH="{{ cifmw_bootc_ipa_build_dir }}/mysteps.yaml"
85+
{% if cifmw_bootc_ipa_fips_patch_enabled | bool %}
86+
export DIB_REPOLOCATION_ironic_python_agent="{{ cifmw_bootc_ipa_source_dir }}"
87+
export DIB_REPOREF_ironic_python_agent="{{ cifmw_bootc_ipa_branch }}"
88+
{% endif %}
89+
ironic-python-agent-builder \
90+
-o "{{ cifmw_bootc_ipa_build_output_prefix }}" \
91+
-r "{{ cifmw_bootc_ipa_release }}" \
92+
-b "{{ cifmw_bootc_ipa_branch }}" \
93+
-e ironic-python-agent-podman \
94+
-v "{{ cifmw_bootc_ipa_distro }}"
95+
96+
- name: Prepare IPA artifacts for hosting
97+
when: cifmw_bootc_ipa_build_enabled | bool
98+
block:
99+
- name: Check for raw IPA artifacts
100+
ansible.builtin.stat:
101+
path: "{{ item }}"
102+
loop:
103+
- "{{ cifmw_bootc_ipa_raw_kernel_file }}"
104+
- "{{ cifmw_bootc_ipa_raw_initramfs_file }}"
105+
register: cifmw_bootc_ipa_raw_artifacts
106+
107+
- name: Assert raw IPA artifacts exist
108+
ansible.builtin.assert:
109+
that:
110+
- cifmw_bootc_ipa_raw_artifacts.results | map(attribute='stat.exists') | min
111+
fail_msg: >-
112+
Missing raw IPA artifacts. Expected
113+
{{ cifmw_bootc_ipa_raw_kernel_file }} and
114+
{{ cifmw_bootc_ipa_raw_initramfs_file }}.
115+
116+
- name: Copy kernel to published filename
117+
ansible.builtin.copy:
118+
src: "{{ cifmw_bootc_ipa_raw_kernel_file }}"
119+
dest: "{{ cifmw_bootc_ipa_kernel_file }}"
120+
mode: "0644"
121+
remote_src: true
122+
123+
- name: Copy initramfs to published filename
124+
ansible.builtin.copy:
125+
src: "{{ cifmw_bootc_ipa_raw_initramfs_file }}"
126+
dest: "{{ cifmw_bootc_ipa_initramfs_file }}"
127+
mode: "0644"
128+
remote_src: true
129+
130+
- name: Package IPA tarball with downloader-compatible filenames
131+
args:
132+
chdir: "{{ cifmw_bootc_ipa_artifact_dir }}"
133+
creates: "{{ cifmw_bootc_ipa_tarball }}"
134+
executable: /bin/bash
135+
ansible.builtin.shell: |
136+
set -euo pipefail
137+
tar -caf "{{ cifmw_bootc_ipa_tarball }}" \
138+
"{{ cifmw_bootc_ipa_published_basename }}.kernel" \
139+
"{{ cifmw_bootc_ipa_published_basename }}.initramfs"
140+
141+
- name: Ensure IPA hosting namespace exists
142+
kubernetes.core.k8s:
143+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
144+
state: present
145+
definition:
146+
apiVersion: v1
147+
kind: Namespace
148+
metadata:
149+
name: "{{ cifmw_bootc_ipa_server_namespace }}"
150+
151+
- name: Create IPA hosting deployment
152+
kubernetes.core.k8s:
153+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
154+
state: present
155+
definition:
156+
apiVersion: apps/v1
157+
kind: Deployment
158+
metadata:
159+
name: "{{ cifmw_bootc_ipa_server_name }}"
160+
namespace: "{{ cifmw_bootc_ipa_server_namespace }}"
161+
spec:
162+
replicas: 1
163+
selector:
164+
matchLabels:
165+
app: "{{ cifmw_bootc_ipa_server_name }}"
166+
template:
167+
metadata:
168+
labels:
169+
app: "{{ cifmw_bootc_ipa_server_name }}"
170+
spec:
171+
containers:
172+
- name: server
173+
image: "{{ cifmw_bootc_ipa_server_image }}"
174+
command:
175+
- python3
176+
- -m
177+
- http.server
178+
- "{{ cifmw_bootc_ipa_server_port | string }}"
179+
- --directory
180+
- /srv
181+
ports:
182+
- containerPort: "{{ cifmw_bootc_ipa_server_port }}"
183+
volumeMounts:
184+
- name: content
185+
mountPath: /srv
186+
volumes:
187+
- name: content
188+
emptyDir: {}
189+
190+
- name: Create IPA hosting service
191+
kubernetes.core.k8s:
192+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
193+
state: present
194+
definition:
195+
apiVersion: v1
196+
kind: Service
197+
metadata:
198+
name: "{{ cifmw_bootc_ipa_server_name }}"
199+
namespace: "{{ cifmw_bootc_ipa_server_namespace }}"
200+
spec:
201+
selector:
202+
app: "{{ cifmw_bootc_ipa_server_name }}"
203+
ports:
204+
- name: http
205+
port: "{{ cifmw_bootc_ipa_server_port }}"
206+
targetPort: "{{ cifmw_bootc_ipa_server_port }}"
207+
208+
- name: Get IPA hosting service cluster IP
209+
kubernetes.core.k8s_info:
210+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
211+
api_version: v1
212+
kind: Service
213+
name: "{{ cifmw_bootc_ipa_server_name }}"
214+
namespace: "{{ cifmw_bootc_ipa_server_namespace }}"
215+
register: cifmw_bootc_ipa_service
216+
217+
- name: Set IPA hosting service URL from cluster IP
218+
ansible.builtin.set_fact:
219+
cifmw_bootc_ipa_service_ip: "{{ cifmw_bootc_ipa_service.resources[0].spec.clusterIP }}"
220+
cifmw_bootc_ipa_service_url: "http://{{ cifmw_bootc_ipa_service.resources[0].spec.clusterIP }}:{{ cifmw_bootc_ipa_server_port }}"
221+
222+
- name: Wait for IPA hosting pod to be ready
223+
environment:
224+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
225+
PATH: "{{ cifmw_path }}"
226+
ansible.builtin.command:
227+
cmd: >-
228+
oc wait pod -n {{ cifmw_bootc_ipa_server_namespace }}
229+
-l app={{ cifmw_bootc_ipa_server_name }}
230+
--for=condition=Ready
231+
--timeout=300s
232+
233+
- name: Get IPA hosting pod name
234+
environment:
235+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
236+
PATH: "{{ cifmw_path }}"
237+
ansible.builtin.command:
238+
cmd: >-
239+
oc get pod -n {{ cifmw_bootc_ipa_server_namespace }}
240+
-l app={{ cifmw_bootc_ipa_server_name }}
241+
-o jsonpath='{.items[0].metadata.name}'
242+
register: cifmw_bootc_ipa_server_pod
243+
changed_when: false
244+
245+
- name: Copy IPA tarball into hosting pod
246+
environment:
247+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
248+
PATH: "{{ cifmw_path }}"
249+
ansible.builtin.command:
250+
cmd: >-
251+
oc cp
252+
"{{ cifmw_bootc_ipa_tarball }}"
253+
"{{ cifmw_bootc_ipa_server_namespace }}/{{ cifmw_bootc_ipa_server_pod.stdout }}:/srv/{{ cifmw_bootc_ipa_tarball | basename }}"
254+
255+
- name: Verify IPA tarball is served from hosting pod
256+
environment:
257+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
258+
PATH: "{{ cifmw_path }}"
259+
ansible.builtin.command:
260+
cmd: >-
261+
oc exec -n {{ cifmw_bootc_ipa_server_namespace }}
262+
{{ cifmw_bootc_ipa_server_pod.stdout }} --
263+
sh -c "curl -sf -o /dev/null http://127.0.0.1:{{ cifmw_bootc_ipa_server_port }}/{{ cifmw_bootc_ipa_tarball | basename }}"
264+
265+
- name: Feed generated bootc IPA values back to main play
266+
ansible.builtin.copy:
267+
dest: "{{ cifmw_basedir }}/artifacts/{{ step }}_{{ hook_name }}.yml"
268+
mode: "0644"
269+
content: |
270+
cifmw_bootc_ipa_service_url: "{{ cifmw_bootc_ipa_service_url }}"
271+
cifmw_edpm_prepare_extra_vars:
272+
BMO_IPA_BASEURI: "{{ cifmw_bootc_ipa_service_url }}"
273+
BMO_IPA_BRANCH: "{{ cifmw_bootc_ipa_branch }}"
274+
BMO_IPA_FLAVOR: "{{ cifmw_bootc_ipa_flavor }}"
275+
276+
- name: Find ironic configmap namespace
277+
environment:
278+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
279+
PATH: "{{ cifmw_path }}"
280+
ansible.builtin.command:
281+
cmd: >-
282+
oc get configmap ironic-bmo-configmap -A
283+
-o jsonpath='{.items[0].metadata.namespace}'
284+
register: cifmw_bootc_ipa_ironic_namespace
285+
changed_when: false
286+
failed_when: false
287+
288+
- name: Patch live ironic configmap with bootc IPA source
289+
when: cifmw_bootc_ipa_ironic_namespace.rc == 0 and cifmw_bootc_ipa_ironic_namespace.stdout | length > 0
290+
kubernetes.core.k8s:
291+
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
292+
state: patched
293+
definition:
294+
apiVersion: v1
295+
kind: ConfigMap
296+
metadata:
297+
name: ironic-bmo-configmap
298+
namespace: "{{ cifmw_bootc_ipa_ironic_namespace.stdout }}"
299+
data:
300+
IPA_BASEURI: "{{ cifmw_bootc_ipa_service_url }}"
301+
IPA_BRANCH: "{{ cifmw_bootc_ipa_branch }}"
302+
IPA_FLAVOR: "{{ cifmw_bootc_ipa_flavor }}"
303+
304+
- name: Restart ironic deployment to re-run IPA downloader
305+
when: cifmw_bootc_ipa_ironic_namespace.rc == 0 and cifmw_bootc_ipa_ironic_namespace.stdout | length > 0
306+
environment:
307+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
308+
PATH: "{{ cifmw_path }}"
309+
ansible.builtin.command:
310+
cmd: >-
311+
oc rollout restart deployment/ironic
312+
-n {{ cifmw_bootc_ipa_ironic_namespace.stdout }}
313+
314+
- name: Wait for ironic rollout after configmap patch
315+
when: cifmw_bootc_ipa_ironic_namespace.rc == 0 and cifmw_bootc_ipa_ironic_namespace.stdout | length > 0
316+
environment:
317+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
318+
PATH: "{{ cifmw_path }}"
319+
ansible.builtin.command:
320+
cmd: >-
321+
oc rollout status deployment/ironic
322+
-n {{ cifmw_bootc_ipa_ironic_namespace.stdout }}
323+
--timeout=10m

0 commit comments

Comments
 (0)