diff --git a/.github/workflows/package-build-ofed.yml b/.github/workflows/package-build-ofed.yml new file mode 100644 index 000000000..98674bbe4 --- /dev/null +++ b/.github/workflows/package-build-ofed.yml @@ -0,0 +1,197 @@ +--- +name: Build OFED packages +on: + workflow_dispatch: + inputs: + rocky9: + description: Build Rocky Linux 9 + type: boolean + default: true + secrets: + KAYOBE_VAULT_PASSWORD: + required: true + CLOUDS_YAML: + required: true + OS_APPLICATION_CREDENTIAL_ID: + required: true + OS_APPLICATION_CREDENTIAL_SECRET: + required: true + +env: + ANSIBLE_FORCE_COLOR: True + KAYOBE_ENVIRONMENT: ci-builder + KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} +jobs: + overcloud-ofed-packages: + name: Build OFED packages + if: github.repository == 'stackhpc/stackhpc-kayobe-config' + runs-on: arc-skc-host-image-builder-runner + permissions: {} + steps: + - name: Install Package + uses: ConorMacBride/install-package@main + with: + apt: git unzip nodejs python3-pip python3-venv openssh-server openssh-client jq + + - name: Start the SSH service + run: | + sudo /etc/init.d/ssh start + + - name: Checkout + uses: actions/checkout@v4 + with: + path: src/kayobe-config + + - name: Output image tag of the builder + id: builder_image_tag + run: | + echo image_tag=$(grep stackhpc_rocky_9_overcloud_host_image_version: etc/kayobe/pulp-host-image-versions.yml | awk '{print $2}') >> $GITHUB_OUTPUT + + - name: Determine OpenStack release + id: openstack_release + run: | + BRANCH=$(awk -F'=' '/defaultbranch/ {print $2}' src/kayobe-config/.gitreview) + echo "openstack_release=${BRANCH}" | sed -E "s,(stable|unmaintained)/,," >> $GITHUB_OUTPUT + + - name: Clone StackHPC Kayobe repository + uses: actions/checkout@v4 + with: + repository: stackhpc/kayobe + ref: refs/heads/stackhpc/${{ steps.openstack_release.outputs.openstack_release }} + path: src/kayobe + + - name: Install Kayobe + run: | + mkdir -p venvs && + pushd venvs && + python3 -m venv kayobe && + source kayobe/bin/activate && + pip install -U pip && + pip install ../src/kayobe + + - name: Install terraform + uses: hashicorp/setup-terraform@v2 + + - name: Initialise terraform + run: terraform init + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + + - name: Generate SSH keypair + run: ssh-keygen -f id_rsa -N '' + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + + - name: Generate clouds.yaml + run: | + cat << EOF > clouds.yaml + ${{ secrets.CLOUDS_YAML }} + EOF + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + + - name: Generate terraform.tfvars + run: | + cat << EOF > terraform.tfvars + ssh_public_key = "id_rsa.pub" + ssh_username = "rocky" + aio_vm_name = "skc-host-image-builder" + # Must be a Rocky Linux 9 host to successfully build all images + # This MUST NOT be an LVM image. It can cause confusing conficts with the built image. + aio_vm_image = "Rocky-9-GenericCloud-Base-9.3-20231113.0.x86_64.qcow2" + aio_vm_flavor = "en1.medium" + aio_vm_network = "stackhpc-ci" + aio_vm_subnet = "stackhpc-ci" + aio_vm_interface = "eth0" + EOF + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + + - name: Terraform Plan + run: terraform plan + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + env: + OS_CLOUD: "openstack" + OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} + OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} + + - name: Terraform Apply + run: | + for attempt in $(seq 5); do + if terraform apply -auto-approve; then + echo "Created infrastructure on attempt $attempt" + exit 0 + fi + echo "Failed to create infrastructure on attempt $attempt" + sleep 10 + terraform destroy -auto-approve + sleep 60 + done + echo "Failed to create infrastructure after $attempt attempts" + exit 1 + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + env: + OS_CLOUD: "openstack" + OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} + OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} + + - name: Get Terraform outputs + id: tf_outputs + run: | + terraform output -json + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + + - name: Write Terraform outputs + run: | + cat << EOF > src/kayobe-config/etc/kayobe/environments/ci-builder/tf-outputs.yml + ${{ steps.tf_outputs.outputs.stdout }} + EOF + + - name: Write Terraform network config + run: | + cat << EOF > src/kayobe-config/etc/kayobe/environments/ci-builder/tf-network-allocation.yml + --- + aio_ips: + builder: "{{ access_ip_v4.value }}" + EOF + + - name: Write Terraform network interface config + run: | + mkdir -p src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed + rm -f src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed/network-interfaces + cat << EOF > src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed/network-interfaces + admin_interface: "{{ access_interface.value }}" + aio_interface: "{{ access_interface.value }}" + EOF + + - name: Manage SSH keys + run: | + mkdir -p ~/.ssh + touch ~/.ssh/authorized_keys + cat src/kayobe-config/terraform/aio/id_rsa.pub >> ~/.ssh/authorized_keys + cp src/kayobe-config/terraform/aio/id_rsa* ~/.ssh/ + + - name: Bootstrap the control host + run: | + source venvs/kayobe/bin/activate && + source src/kayobe-config/kayobe-env --environment ci-builder && + kayobe control host bootstrap + + - name: Configure the seed host (Builder VM) + run: | + source venvs/kayobe/bin/activate && + source src/kayobe-config/kayobe-env --environment ci-builder && + kayobe seed host configure -e seed_bootstrap_user=rocky --skip-tags network + + - name: Run OFED builder playbook + run: | + source venvs/kayobe/bin/activate && + source src/kayobe-config/kayobe-env --environment ci-builder && + kayobe playbook run src/kayobe-config/etc/kayobe/ansible/build-ofed.yml + env: + KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD } + + - name: Destroy + run: terraform destroy -auto-approve + working-directory: ${{ github.workspace }}/src/kayobe-config/terraform/aio + env: + OS_CLOUD: openstack + OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} + OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} + if: always() diff --git a/etc/kayobe/ansible/build-ofed.yml b/etc/kayobe/ansible/build-ofed.yml new file mode 100644 index 000000000..6994210bf --- /dev/null +++ b/etc/kayobe/ansible/build-ofed.yml @@ -0,0 +1,102 @@ +--- +- name: Build OFED packages + hosts: ofed-builder + gather_facts: false + vars: + stackhpc_mlnx_ofed_file_string: MLNX_OFED_LINUX-{{ stackhpc_pulp_mlnx_ofed_version }}-rhel9.{{ stackhpc_pulp_repo_rocky_9_minor_version }}-x86_64 + tasks: + - name: Install package dependencies + ansible.builtin.dnf: + name: + - std + - debootstrap + - kpartx + - cloud-init + - perl + - rpm-build + - automake + - patch + - kernel-devel + - autoconf + - pciutils + - kernel-rpm-macros + - lsof + - libtool + - tk + - gcc-gfortran + - tcl + state: present + + - name: Install python dependencies + ansible.builtin.pip: + name: pulp-cli + + - name: Create build directory + ansible.builtin.file: + path: /opt/ofed + state: directory + mode: 0777 + become: true + + - name: Download MellanoxOFED archive + ansible.builtin.get_url: + url: https://content.mellanox.com/ofed/MLNX_OFED-{{ stackhpc_pulp_mlnx_ofed_version }}/{{ stackhpc_mlnx_ofed_file_string }}.tgz + dest: /opt/ofed/ofed-archive + + - name: Extract MellanoxOFED archive + ansible.builtin.unarchive: + src: /opt/ofed/ofed-archive + dest: /opt/ofed + + - name: Ensure the current kernel is supported + ansible.builtin.shell: + cmd: | + /opt/ofed/{{ stackhpc_mlnx_ofed_file_string }}/mlnx_add_kernel_support.sh \ + --mlnx_ofed /opt/ofed/{{ stackhpc_mlnx_ofed_file_string }} \ + --make-tgz -y \ + become: true + + - name: Extract the new archive + ansible.builtin.unarchive: + src: /tmp/{{ stackhpc_mlnx_ofed_file_string }}-ext.tgz + dest: /opt/ofed + become: true + + - name: Create Pulp repository for OFED + pulp.squeezer.rpm_repository: + pulp_url: "{{ stackhpc_release_pulp_url }}" + username: "{{ stackhpc_release_pulp_username }}" + password: "{{ stackhpc_release_pulp_password }}" + name: "{{ stackhpc_pulp_repo_mlnx_ofed.name }}" + state: present + retries: "{{ pulp_repository_rpm_repositories_retries }}" + + - name: Upload OFED RPMs to Pulp + ansible.builtin.shell: + cmd: | + pulp \ + --base-url '{{ stackhpc_release_pulp_url }}' \ + --username '{{ stackhpc_release_pulp_username }}' \ + --password '{{ stackhpc_release_pulp_password }}' \ + rpm content \ + --type package upload \ + --repository '{{ stackhpc_pulp_repo_mlnx_ofed.name }}' \ + --file {{ item }} \ + with_fileglob: "/opt/ofed/{{ stackhpc_mlnx_ofed_file_string }}-ext/RPMS/*.rpm" + no_log: true + + - name: Create Pulp publication for OFED + pulp.squeezer.rpm_publication: + pulp_url: "{{ stackhpc_release_pulp_url }}" + username: "{{ stackhpc_release_pulp_username }}" + password: "{{ stackhpc_release_pulp_password }}" + repository: "{{ stackhpc_pulp_repo_mlnx_ofed.name }}" + state: present + + - name: Create Pulp distribution for OFED + pulp.squeezer.rpm_distribution: + pulp_url: "{{ stackhpc_release_pulp_url }}" + username: "{{ stackhpc_release_pulp_username }}" + password: "{{ stackhpc_release_pulp_password }}" + name: "{{ stackhpc_pulp_repo_mlnx_ofed.distribution_name }}" + base_path: "{{ stackhpc_pulp_repo_mlnx_ofed.base_path }}" diff --git a/etc/kayobe/environments/ci-builder/inventory/hosts b/etc/kayobe/environments/ci-builder/inventory/hosts index 33fda8b73..759e41184 100644 --- a/etc/kayobe/environments/ci-builder/inventory/hosts +++ b/etc/kayobe/environments/ci-builder/inventory/hosts @@ -1,3 +1,7 @@ # A 'seed' host used for building images. + +[ofed-builder:children] +seed + [seed] builder diff --git a/etc/kayobe/pulp.yml b/etc/kayobe/pulp.yml index 368643a11..cb53a1704 100644 --- a/etc/kayobe/pulp.yml +++ b/etc/kayobe/pulp.yml @@ -369,6 +369,16 @@ stackhpc_pulp_repository_rpm_repos: >- {%- endfor -%} {{ rpm_repos }} +# Mellanox OFED version +stackhpc_pulp_mlnx_ofed_version: 24.04-0.7.0.0 + +# Mellanox OFED repositories +stackhpc_pulp_repo_mlnx_ofed: + name: Mellanox Technologies mlnx_ofed {{ stackhpc_pulp_mlnx_ofed_version }} + url: "{{ stackhpc_release_pulp_content_url }}/mlnx_ofed/{{ stackhpc_pulp_mlnx_ofed_version }}/rhel9.{{ stackhpc_pulp_repo_rocky_9_minor_version }}/x86_64/{{ stackhpc_pulp_repo_mlnx_ofed_version }}" + distribution_name: "mlnx_ofed_{{ stackhpc_pulp_mlnx_ofed_version }}-" + base_path: "mlnx_ofed/{{ stackhpc_pulp_mlnx_ofed_version }}/rhel9.{{ stackhpc_pulp_repo_rocky_9_minor_version }}/x86_64/" + # Publication format is a subset of distribution. stackhpc_pulp_publication_rpm_development: "{{ stackhpc_pulp_distribution_rpm_development }}"