|
| 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: "quay.io/prometheus/busybox: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_service_url: >- |
| 31 | + http://{{ cifmw_bootc_ipa_server_name }}.{{ cifmw_bootc_ipa_server_namespace }}.svc.cluster.local:{{ cifmw_bootc_ipa_server_port }} |
| 32 | + tasks: |
| 33 | + - name: Ensure IPA artifact directory exists |
| 34 | + ansible.builtin.file: |
| 35 | + path: "{{ cifmw_bootc_ipa_artifact_dir }}" |
| 36 | + state: directory |
| 37 | + mode: "0755" |
| 38 | + |
| 39 | + - name: Ensure IPA build directory exists |
| 40 | + when: cifmw_bootc_ipa_build_enabled | bool |
| 41 | + ansible.builtin.file: |
| 42 | + path: "{{ cifmw_bootc_ipa_build_dir }}" |
| 43 | + state: directory |
| 44 | + mode: "0755" |
| 45 | + |
| 46 | + - name: Write minimal container steps file |
| 47 | + when: cifmw_bootc_ipa_build_enabled | bool |
| 48 | + ansible.builtin.copy: |
| 49 | + dest: "{{ cifmw_bootc_ipa_build_dir }}/mysteps.yaml" |
| 50 | + content: | |
| 51 | + steps: [] |
| 52 | + mode: "0644" |
| 53 | + |
| 54 | + - name: Build podman-enabled IPA artifacts |
| 55 | + when: cifmw_bootc_ipa_build_enabled | bool |
| 56 | + args: |
| 57 | + chdir: "{{ cifmw_bootc_ipa_artifact_dir }}" |
| 58 | + creates: "{{ cifmw_bootc_ipa_raw_initramfs_file }}" |
| 59 | + executable: /bin/bash |
| 60 | + ansible.builtin.shell: | |
| 61 | + set -euo pipefail |
| 62 | + python3 -m venv "{{ cifmw_bootc_ipa_build_dir }}/.venv" |
| 63 | + . "{{ cifmw_bootc_ipa_build_dir }}/.venv/bin/activate" |
| 64 | + python -m pip install --upgrade pip setuptools wheel |
| 65 | + python -m pip install ironic-python-agent-builder |
| 66 | + export DIB_ALLOW_ARBITRARY_CONTAINERS=true |
| 67 | + export DIB_RUNNER=podman |
| 68 | + export DIB_STEPS_FILE_PATH="{{ cifmw_bootc_ipa_build_dir }}/mysteps.yaml" |
| 69 | + ironic-python-agent-builder \ |
| 70 | + -o "{{ cifmw_bootc_ipa_build_output_prefix }}" \ |
| 71 | + -r "{{ cifmw_bootc_ipa_release }}" \ |
| 72 | + -b "{{ cifmw_bootc_ipa_branch }}" \ |
| 73 | + -e ironic-python-agent-podman \ |
| 74 | + -v "{{ cifmw_bootc_ipa_distro }}" |
| 75 | +
|
| 76 | + - name: Check for raw IPA artifacts |
| 77 | + ansible.builtin.stat: |
| 78 | + path: "{{ item }}" |
| 79 | + loop: |
| 80 | + - "{{ cifmw_bootc_ipa_raw_kernel_file }}" |
| 81 | + - "{{ cifmw_bootc_ipa_raw_initramfs_file }}" |
| 82 | + register: cifmw_bootc_ipa_raw_artifacts |
| 83 | + |
| 84 | + - name: Assert raw IPA artifacts exist |
| 85 | + ansible.builtin.assert: |
| 86 | + that: |
| 87 | + - cifmw_bootc_ipa_raw_artifacts.results | map(attribute='stat.exists') | min |
| 88 | + fail_msg: >- |
| 89 | + Missing raw IPA artifacts. Expected |
| 90 | + {{ cifmw_bootc_ipa_raw_kernel_file }} and |
| 91 | + {{ cifmw_bootc_ipa_raw_initramfs_file }}. |
| 92 | +
|
| 93 | + - name: Copy kernel to published filename |
| 94 | + ansible.builtin.copy: |
| 95 | + src: "{{ cifmw_bootc_ipa_raw_kernel_file }}" |
| 96 | + dest: "{{ cifmw_bootc_ipa_kernel_file }}" |
| 97 | + mode: "0644" |
| 98 | + remote_src: true |
| 99 | + |
| 100 | + - name: Copy initramfs to published filename |
| 101 | + ansible.builtin.copy: |
| 102 | + src: "{{ cifmw_bootc_ipa_raw_initramfs_file }}" |
| 103 | + dest: "{{ cifmw_bootc_ipa_initramfs_file }}" |
| 104 | + mode: "0644" |
| 105 | + remote_src: true |
| 106 | + |
| 107 | + - name: Package IPA tarball with downloader-compatible filenames |
| 108 | + args: |
| 109 | + chdir: "{{ cifmw_bootc_ipa_artifact_dir }}" |
| 110 | + executable: /bin/bash |
| 111 | + ansible.builtin.shell: | |
| 112 | + set -euo pipefail |
| 113 | + tar -caf "{{ cifmw_bootc_ipa_tarball }}" \ |
| 114 | + "{{ cifmw_bootc_ipa_published_basename }}.kernel" \ |
| 115 | + "{{ cifmw_bootc_ipa_published_basename }}.initramfs" |
| 116 | +
|
| 117 | + - name: Ensure IPA hosting namespace exists |
| 118 | + kubernetes.core.k8s: |
| 119 | + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" |
| 120 | + state: present |
| 121 | + definition: |
| 122 | + apiVersion: v1 |
| 123 | + kind: Namespace |
| 124 | + metadata: |
| 125 | + name: "{{ cifmw_bootc_ipa_server_namespace }}" |
| 126 | + |
| 127 | + - name: Create IPA hosting deployment |
| 128 | + kubernetes.core.k8s: |
| 129 | + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" |
| 130 | + state: present |
| 131 | + definition: |
| 132 | + apiVersion: apps/v1 |
| 133 | + kind: Deployment |
| 134 | + metadata: |
| 135 | + name: "{{ cifmw_bootc_ipa_server_name }}" |
| 136 | + namespace: "{{ cifmw_bootc_ipa_server_namespace }}" |
| 137 | + spec: |
| 138 | + replicas: 1 |
| 139 | + selector: |
| 140 | + matchLabels: |
| 141 | + app: "{{ cifmw_bootc_ipa_server_name }}" |
| 142 | + template: |
| 143 | + metadata: |
| 144 | + labels: |
| 145 | + app: "{{ cifmw_bootc_ipa_server_name }}" |
| 146 | + spec: |
| 147 | + containers: |
| 148 | + - name: server |
| 149 | + image: "{{ cifmw_bootc_ipa_server_image }}" |
| 150 | + command: |
| 151 | + - sh |
| 152 | + - -c |
| 153 | + - >- |
| 154 | + mkdir -p /srv && |
| 155 | + exec busybox httpd -f -p {{ cifmw_bootc_ipa_server_port }} -h /srv |
| 156 | + ports: |
| 157 | + - containerPort: "{{ cifmw_bootc_ipa_server_port }}" |
| 158 | + volumeMounts: |
| 159 | + - name: content |
| 160 | + mountPath: /srv |
| 161 | + volumes: |
| 162 | + - name: content |
| 163 | + emptyDir: {} |
| 164 | + |
| 165 | + - name: Create IPA hosting service |
| 166 | + kubernetes.core.k8s: |
| 167 | + kubeconfig: "{{ cifmw_openshift_kubeconfig }}" |
| 168 | + state: present |
| 169 | + definition: |
| 170 | + apiVersion: v1 |
| 171 | + kind: Service |
| 172 | + metadata: |
| 173 | + name: "{{ cifmw_bootc_ipa_server_name }}" |
| 174 | + namespace: "{{ cifmw_bootc_ipa_server_namespace }}" |
| 175 | + spec: |
| 176 | + selector: |
| 177 | + app: "{{ cifmw_bootc_ipa_server_name }}" |
| 178 | + ports: |
| 179 | + - name: http |
| 180 | + port: "{{ cifmw_bootc_ipa_server_port }}" |
| 181 | + targetPort: "{{ cifmw_bootc_ipa_server_port }}" |
| 182 | + |
| 183 | + - name: Wait for IPA hosting pod to be ready |
| 184 | + environment: |
| 185 | + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" |
| 186 | + PATH: "{{ cifmw_path }}" |
| 187 | + ansible.builtin.command: |
| 188 | + cmd: >- |
| 189 | + oc wait pod -n {{ cifmw_bootc_ipa_server_namespace }} |
| 190 | + -l app={{ cifmw_bootc_ipa_server_name }} |
| 191 | + --for=condition=Ready |
| 192 | + --timeout=300s |
| 193 | +
|
| 194 | + - name: Get IPA hosting pod name |
| 195 | + environment: |
| 196 | + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" |
| 197 | + PATH: "{{ cifmw_path }}" |
| 198 | + ansible.builtin.command: |
| 199 | + cmd: >- |
| 200 | + oc get pod -n {{ cifmw_bootc_ipa_server_namespace }} |
| 201 | + -l app={{ cifmw_bootc_ipa_server_name }} |
| 202 | + -o jsonpath='{.items[0].metadata.name}' |
| 203 | + register: cifmw_bootc_ipa_server_pod |
| 204 | + changed_when: false |
| 205 | + |
| 206 | + - name: Copy IPA tarball into hosting pod |
| 207 | + environment: |
| 208 | + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" |
| 209 | + PATH: "{{ cifmw_path }}" |
| 210 | + ansible.builtin.command: |
| 211 | + cmd: >- |
| 212 | + oc cp |
| 213 | + "{{ cifmw_bootc_ipa_tarball }}" |
| 214 | + "{{ cifmw_bootc_ipa_server_namespace }}/{{ cifmw_bootc_ipa_server_pod.stdout }}:/srv/{{ cifmw_bootc_ipa_tarball | basename }}" |
| 215 | +
|
| 216 | + - name: Verify IPA tarball is served from hosting pod |
| 217 | + environment: |
| 218 | + KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}" |
| 219 | + PATH: "{{ cifmw_path }}" |
| 220 | + ansible.builtin.command: |
| 221 | + cmd: >- |
| 222 | + oc exec -n {{ cifmw_bootc_ipa_server_namespace }} |
| 223 | + {{ cifmw_bootc_ipa_server_pod.stdout }} -- |
| 224 | + sh -c "wget -qO /dev/null http://127.0.0.1:{{ cifmw_bootc_ipa_server_port }}/{{ cifmw_bootc_ipa_tarball | basename }}" |
| 225 | +
|
| 226 | + - name: Feed generated install_yamls vars patch back to main play |
| 227 | + ansible.builtin.copy: |
| 228 | + dest: "{{ cifmw_basedir }}/artifacts/{{ step }}_{{ hook_name }}.yml" |
| 229 | + mode: "0644" |
| 230 | + content: | |
| 231 | + cifmw_install_yamls_vars_patch_90_bootc_ipa: |
| 232 | + BMO_IPA_BASEURI: "{{ cifmw_bootc_ipa_service_url }}" |
| 233 | + BMO_IPA_BRANCH: "{{ cifmw_bootc_ipa_branch }}" |
| 234 | + BMO_IPA_FLAVOR: "{{ cifmw_bootc_ipa_flavor }}" |
0 commit comments