--- - name: Get cluster version kubernetes.core.k8s_info: api_version: config.openshift.io/v1 kind: ClusterVersion name: version kubeconfig: "{{ ocp_cluster_auth }}/kubeconfig" validate_certs: false register: cluster_version - name: Set OCP version fact ansible.builtin.set_fact: ocp_version: "{{ cluster_version.resources[0].status.desired.version }}" - name: Check if cluster supports multi-architecture kubernetes.core.k8s_info: api_version: config.openshift.io/v1 kind: ClusterVersion name: version kubeconfig: "{{ ocp_cluster_auth }}/kubeconfig" validate_certs: false register: cluster_version_detail - name: Enable multi-architecture support if not already enabled ansible.builtin.command: cmd: "/usr/local/bin/oc adm upgrade --to-multi-arch" environment: KUBECONFIG: "{{ ocp_cluster_auth }}/kubeconfig" when: cluster_version_detail.resources[0].spec.architecture is not defined or cluster_version_detail.resources[0].spec.architecture != "Multi" register: multiarch_result failed_when: false - name: Display multi-architecture enablement result ansible.builtin.debug: msg: | Multi-architecture support: {{ 'Already enabled' if (cluster_version_detail.resources[0].spec.architecture | default('') == 'Multi') else 'Enabled for s390x support' }} {% if multiarch_result.changed %} Command output: {{ multiarch_result.stdout }} {% endif %} - name: Ensure /srv/tmp directory exists ansible.builtin.file: path: /srv/tmp state: directory mode: '0755' delegate_to: srv08d become: true - name: Create temporary directory for s390x artifacts ansible.builtin.tempfile: state: directory suffix: s390x path: /srv/tmp register: temp_dir delegate_to: srv08d become: true - name: Login to quay.io containers.podman.podman_login: username: "{{ (((ocp_pull_secret | string | from_json).auths['quay.io'].auth | b64decode) | split(':'))[0] }}" password: "{{ (((ocp_pull_secret | string | from_json).auths['quay.io'].auth | b64decode) | split(':'))[1] }}" registry: quay.io delegate_to: srv08d become: true - name: Extract s390x release tools ansible.builtin.command: cmd: >- oc adm release extract --command=openshift-install quay.io/openshift-release-dev/ocp-release:{{ ocp_version }}-s390x --to={{ temp_dir.path }} register: extract_result changed_when: extract_result.rc == 0 delegate_to: srv08d become: true - name: Create cluster-specific srv directory structure on jumphost ansible.builtin.file: path: "/srv/{{ ocp_name | default('ocp') }}/{{ item }}" state: directory mode: '0755' owner: "{{ jumphost_user | default('hmc_sftp') }}" group: "{{ jumphost_user | default('hmc_sftp') }}" loop: - boot/s390x - boot/s390x/images - boot/s390x/images/pxeboot - www/html/boot delegate_to: srv08d become: true - name: Generate .treeinfo file for s390x boot ansible.builtin.template: src: .treeinfo.j2 dest: "/srv/{{ ocp_name | default('ocp') }}/boot/s390x/.treeinfo" mode: '0644' owner: "{{ jumphost_user | default('hmc_sftp') }}" group: "{{ jumphost_user | default('hmc_sftp') }}" delegate_to: srv08d become: true - name: Get RHCOS bootimages from configmap kubernetes.core.k8s_info: api_version: v1 kind: ConfigMap name: coreos-bootimages namespace: openshift-machine-config-operator kubeconfig: "{{ ocp_cluster_auth }}/kubeconfig" validate_certs: false register: bootimages_cm - name: Parse s390x boot image URLs ansible.builtin.set_fact: rhcos_urls: "{{ (bootimages_cm.resources[0].data.stream | from_json).architectures.s390x.artifacts.metal.formats }}" rhcos_checksums: "{{ (bootimages_cm.resources[0].data.stream | from_json).architectures.s390x.artifacts.metal.formats }}" - name: Get worker ignition config from Machine Config Server ansible.builtin.uri: url: "https://api.{{ ocp_name }}.{{ ocp_base_domain | default('kvant.cloud') }}:22623/config/worker" method: GET validate_certs: false return_content: true timeout: 30 status_code: [200] register: worker_ignition_response retries: 3 delay: 10 until: worker_ignition_response.status == 200 - name: Get cluster CA certificate ansible.builtin.command: cmd: "oc get configmap/kube-root-ca.crt -n kube-system -o jsonpath='{.data.ca\\.crt}'" environment: KUBECONFIG: "{{ ocp_cluster_auth }}/kubeconfig" register: cluster_ca_cert delegate_to: srv08d - name: Create butane config for CA trust ansible.builtin.template: src: add-ca.bu.j2 dest: "{{ temp_dir.path }}/add-ca.bu" mode: '0644' delegate_to: srv08d become: true - name: Read SSH public keys from files if paths provided ansible.builtin.slurp: src: "{{ item }}" register: ssh_key_files_content loop: "{{ ssh_public_key_files | default([]) }}" when: (add_ssh_keys | default(false)) and ssh_public_key_files is defined delegate_to: srv08d - name: Extract SSH key content from slurp results ansible.builtin.set_fact: ssh_keys_content: "{{ ssh_keys_content | default([]) + [item.content | b64decode | trim] }}" loop: "{{ ssh_key_files_content.results | default([]) }}" when: (add_ssh_keys | default(false)) and ssh_key_files_content is defined and not item.skipped | default(false) delegate_to: srv08d - name: Combine SSH keys from variables and files ansible.builtin.set_fact: combined_ssh_keys: "{{ (ssh_public_keys | default([])) + (ssh_keys_content | default([])) }}" when: (add_ssh_keys | default(false)) delegate_to: srv08d - name: Create butane config for SSH keys ansible.builtin.template: src: add-ssh-key.bu.j2 dest: "{{ temp_dir.path }}/add-ssh-key.bu" mode: '0644' when: (add_ssh_keys | default(false)) and combined_ssh_keys is defined and combined_ssh_keys | length > 0 delegate_to: srv08d become: true - name: Convert butane configs to ignition ansible.builtin.command: cmd: "butane {{ item }} -o {{ temp_dir.path }}/{{ item | basename | regex_replace('\\.bu$', '.ign') }}" chdir: "{{ temp_dir.path }}" loop: - "{{ temp_dir.path }}/add-ca.bu" - "{{ temp_dir.path }}/add-ssh-key.bu" when: item | basename == 'add-ssh-key.bu' and (add_ssh_keys | default(false)) and combined_ssh_keys is defined and combined_ssh_keys | length > 0 or item | basename == 'add-ca.bu' delegate_to: srv08d become: true - name: Save original worker ignition config to file ansible.builtin.copy: content: "{{ worker_ignition_response.content }}" dest: "{{ temp_dir.path }}/worker-original.ign" mode: '0644' delegate_to: srv08d become: true - name: Merge ignition configs ansible.builtin.shell: cmd: | jq -s '.[0] * .[1]{{ " * .[2]" if (add_ssh_keys | default(false)) and combined_ssh_keys is defined and combined_ssh_keys | length > 0 else "" }}' \ worker-original.ign add-ca.ign{{ " add-ssh-key.ign" if (add_ssh_keys | default(false)) and combined_ssh_keys is defined and combined_ssh_keys | length > 0 else "" }} > worker.ign chdir: "{{ temp_dir.path }}" delegate_to: srv08d become: true - name: Download s390x boot files directly to SFTP directory ansible.builtin.get_url: url: "{{ item.url }}" dest: "/srv/{{ ocp_name | default('ocp') }}/boot/s390x/{{ item.dest }}" checksum: "sha256:{{ item.checksum }}" mode: '0644' timeout: 300 owner: "{{ jumphost_user | default('hmc_sftp') }}" group: "{{ jumphost_user | default('hmc_sftp') }}" force: yes loop: - { url: "{{ rhcos_urls.pxe.kernel.location }}", dest: "images/pxeboot/kernel.img", checksum: "{{ rhcos_checksums.pxe.kernel.sha256 }}" } - { url: "{{ rhcos_urls.pxe.initramfs.location }}", dest: "images/pxeboot/initrd.img", checksum: "{{ rhcos_checksums.pxe.initramfs.sha256 }}" } retries: 2 delay: 30 delegate_to: srv08d become: true - name: Ensure correct SELinux context for SFTP boot files ansible.builtin.command: cmd: "restorecon -Rv /srv/{{ ocp_name | default('ocp') }}/boot/" delegate_to: srv08d become: true changed_when: false - name: Ensure Apache boot directory exists ansible.builtin.file: path: "/var/www/html/boot" state: directory mode: '0755' owner: apache group: apache delegate_to: srv08d become: true - name: Download rootfs.img to Apache web directory ansible.builtin.get_url: url: "{{ rhcos_urls.pxe.rootfs.location }}" dest: "/var/www/html/boot/rootfs.img" checksum: "sha256:{{ rhcos_checksums.pxe.rootfs.sha256 }}" mode: '0644' timeout: 300 owner: apache group: apache force: yes retries: 2 delay: 30 delegate_to: srv08d become: true - name: Copy worker ignition config to HTTP directory ansible.builtin.copy: src: "{{ temp_dir.path }}/worker.ign" dest: "/var/www/html/boot/worker.ign" remote_src: true mode: '0644' owner: apache group: apache delegate_to: srv08d become: true - name: Ensure correct SELinux context for HTTP boot files ansible.builtin.command: cmd: "restorecon -Rv /var/www/html/boot/" delegate_to: srv08d become: true changed_when: false - name: Display boot files location ansible.builtin.debug: msg: | s390x boot files prepared: SFTP Directory: {{ sftp_boot_dir | default('/var/ftp/boot') }}/s390x/ - generic.ins (zIPL instruction file) - images/pxeboot/kernel.img - images/pxeboot/initrd.img - images/[hostname].prm (worker-specific boot parameters - generated per LPAR) HTTP Directory: {{ http_boot_dir | default('/var/www/html/boot') }}/ - worker.ign (ignition config) - rootfs.img (root filesystem)