3737 uses : ./.github/workflows/runner-selector.yml
3838 with :
3939 runner_env : ${{ inputs.runner_env }}
40+ validate-inputs :
41+ name : Input validation
42+ if : github.repository == 'stackhpc/stackhpc-kayobe-config'
43+ environment : ${{ inputs.runner_env }}
44+ runs-on : ${{ needs.runner-selection.outputs.runner_name_image_build }}
45+ needs :
46+ - runner-selection
47+ permissions : {}
48+ steps :
49+ - name : Validate inputs
50+ run : |
51+ if [[ ${{ inputs.rocky9 }} == 'false' && ${{ inputs.ubuntu-noble }} == 'false' ]]; then
52+ echo "At least one distribution must be selected"
53+ exit 1
54+ fi
55+
4056 create-tag :
4157 name : Create a tag to be added to resulting images
4258 if : github.repository == 'stackhpc/stackhpc-kayobe-config'
@@ -70,23 +86,16 @@ jobs:
7086 run : |
7187 echo "host_image_tag=$(date +${{ steps.openstack_release.outputs.openstack_release }}-%Y%m%dT%H%M%S)" >> $GITHUB_OUTPUT
7288
73- overcloud-host-image-build :
74- name : Build overcloud host images
75- if : github.repository == 'stackhpc/stackhpc-kayobe-config'
89+ overcloud-host-image-build-rocky :
90+ name : Build Rocky overcloud host images
91+ if : github.repository == 'stackhpc/stackhpc-kayobe-config' && ${{ inputs.rocky9 }} == 'true'
7692 environment : ${{ inputs.runner_env }}
7793 runs-on : ${{ needs.runner-selection.outputs.runner_name_image_build }}
7894 needs :
7995 - runner-selection
8096 - create-tag
8197 permissions : {}
8298 steps :
83- - name : Validate inputs
84- run : |
85- if [[ ${{ inputs.rocky9 }} == 'false' && ${{ inputs.ubuntu-noble }} == 'false' ]]; then
86- echo "At least one distribution must be selected"
87- exit 1
88- fi
89-
9099 - name : Display overcloud host image tag
91100 run : |
92101 echo "${{ needs.create-tag.outputs.host_image_tag }}"
@@ -137,7 +146,7 @@ jobs:
137146 cat << EOF > terraform.tfvars
138147 ssh_public_key = "id_rsa.pub"
139148 ssh_username = "ubuntu"
140- aio_vm_name = "skc-host-image-builder"
149+ aio_vm_name = "skc-host-image-builder-rocky "
141150 # Must be an Ubuntu Noble host to successfully build all images
142151 # This MUST NOT be an LVM image. It can cause confusing conficts with the built image.
143152 aio_vm_image = "${{ vars.HOST_IMAGE_BUILD_IMAGE }}"
@@ -272,11 +281,11 @@ jobs:
272281 kayobe playbook run \
273282 src/kayobe-config/etc/kayobe/ansible/pulp-artifact-upload.yml \
274283 -e artifact_path=/opt/kayobe/images/overcloud-rocky-9 \
275- -e artifact_tag=${{ steps.host_image_tag .outputs.host_image_tag }} \
284+ -e artifact_tag=${{ needs.create-tag .outputs.host_image_tag }} \
276285 -e artifact_type="kayobe-images" \
277286 -e file_regex="*.qcow2" \
278287 -e os_distribution="rocky" \
279- -e os_release="9"
288+ -e os_release="9" -vvv
280289 env :
281290 KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
282291 if : inputs.rocky9 && steps.build_rocky_9.outcome == 'success'
@@ -288,7 +297,7 @@ jobs:
288297 kayobe playbook run \
289298 src/kayobe-config/etc/kayobe/ansible/openstack-host-image-upload.yml \
290299 -e local_image_path="/opt/kayobe/images/overcloud-rocky-9/overcloud-rocky-9.qcow2" \
291- -e image_name=overcloud-rocky-9-${{ steps.host_image_tag .outputs.host_image_tag }}
300+ -e image_name=overcloud-rocky-9-${{ needs.create-tag .outputs.host_image_tag }}
292301 env :
293302 CLOUDS_YAML : ${{ secrets.CLOUDS_YAML }}
294303 OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
@@ -302,13 +311,208 @@ jobs:
302311 kayobe playbook run \
303312 src/kayobe-config/etc/kayobe/ansible/openstack-host-image-upload.yml \
304313 -e local_image_path="/opt/kayobe/images/overcloud-rocky-9/overcloud-rocky-9.qcow2" \
305- -e image_name=overcloud-rocky-9-${{ steps.host_image_tag .outputs.host_image_tag }}
314+ -e image_name=overcloud-rocky-9-${{ needs.create-tag .outputs.host_image_tag }}
306315 env :
307316 CLOUDS_YAML : ${{ secrets.CLOUDS_YAML_OTHER_CLOUD }}
308317 OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID_OTHER_CLOUD }}
309318 OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET_OTHER_CLOUD }}
310319 if : inputs.rocky9 && steps.build_rocky_9.outcome == 'success'
311320
321+ - name : Copy logs back
322+ continue-on-error : true
323+ run : |
324+ mkdir logs
325+ scp -r ubuntu@$(jq -r .access_ip_v4.value src/kayobe-config/etc/kayobe/environments/ci-builder/tf-outputs.yml):/opt/kayobe/images/*/*.std* ./logs/
326+ scp -r ubuntu@$(jq -r .access_ip_v4.value src/kayobe-config/etc/kayobe/environments/ci-builder/tf-outputs.yml):/tmp/updated_images.txt ./logs/ || true
327+ if : always()
328+
329+ - name : Fail if any overcloud host image builds failed
330+ run : |
331+ echo "Builds failed. See workflow artifacts for details." &&
332+ exit 1
333+ if : steps.build_rocky_9.outcome == 'failure' ||
334+ steps.build_ubuntu_noble.outcome == 'failure'
335+
336+ - name : Upload logs artifact
337+ uses : actions/upload-artifact@v4
338+ with :
339+ name : Build logs Rocky
340+ path : ./logs
341+ if : always()
342+
343+ - name : Destroy
344+ run : terraform destroy -auto-approve
345+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
346+ env :
347+ OS_CLOUD : openstack
348+ OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
349+ OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
350+ if : always()
351+
352+ overcloud-host-image-build-ubuntu :
353+ name : Build Ubuntu overcloud host images
354+ if : github.repository == 'stackhpc/stackhpc-kayobe-config' && ${{ inputs.ubuntu-noble }} == 'true'
355+ environment : ${{ inputs.runner_env }}
356+ runs-on : ${{ needs.runner-selection.outputs.runner_name_image_build }}
357+ needs :
358+ - runner-selection
359+ - create-tag
360+ permissions : {}
361+ steps :
362+ - name : Display overcloud host image tag
363+ run : |
364+ echo "${{ needs.create-tag.outputs.host_image_tag }}"
365+
366+ - name : Checkout
367+ uses : actions/checkout@v4
368+ with :
369+ path : src/kayobe-config
370+
371+ - name : Install Package
372+ uses : ConorMacBride/install-package@main
373+ with :
374+ apt : git unzip nodejs python3-pip python3-venv openssh-server openssh-client jq
375+
376+ - name : Start the SSH service
377+ run : |
378+ sudo /etc/init.d/ssh start
379+
380+ - name : Install Kayobe
381+ run : |
382+ mkdir -p venvs &&
383+ pushd venvs &&
384+ python3 -m venv kayobe &&
385+ source kayobe/bin/activate &&
386+ pip install -U pip &&
387+ pip install -r ../src/kayobe-config/requirements.txt
388+
389+ - name : Install terraform
390+ uses : hashicorp/setup-terraform@v2
391+
392+ - name : Initialise terraform
393+ run : terraform init
394+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
395+
396+ - name : Generate SSH keypair
397+ run : ssh-keygen -f id_rsa -N ''
398+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
399+
400+ - name : Generate clouds.yaml
401+ run : |
402+ cat << EOF > clouds.yaml
403+ ${{ secrets.CLOUDS_YAML }}
404+ EOF
405+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
406+
407+ - name : Generate terraform.tfvars
408+ run : |
409+ cat << EOF > terraform.tfvars
410+ ssh_public_key = "id_rsa.pub"
411+ ssh_username = "ubuntu"
412+ aio_vm_name = "skc-host-image-builder-ubuntu"
413+ # Must be an Ubuntu Noble host to successfully build all images
414+ # This MUST NOT be an LVM image. It can cause confusing conficts with the built image.
415+ aio_vm_image = "${{ vars.HOST_IMAGE_BUILD_IMAGE }}"
416+ aio_vm_flavor = "${{ vars.HOST_IMAGE_BUILD_FLAVOR }}"
417+ aio_vm_network = "${{ vars.HOST_IMAGE_BUILD_NETWORK }}"
418+ aio_vm_subnet = "${{ vars.HOST_IMAGE_BUILD_SUBNET }}"
419+ aio_vm_interface = "ens3"
420+ EOF
421+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
422+
423+ - name : Terraform Plan
424+ run : terraform plan
425+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
426+ env :
427+ OS_CLOUD : ${{ vars.OS_CLOUD }}
428+ OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
429+ OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
430+
431+ - name : Terraform Apply
432+ run : |
433+ for attempt in $(seq 5); do
434+ if terraform apply -auto-approve; then
435+ echo "Created infrastructure on attempt $attempt"
436+ exit 0
437+ fi
438+ echo "Failed to create infrastructure on attempt $attempt"
439+ sleep 10
440+ terraform destroy -auto-approve
441+ sleep 60
442+ done
443+ echo "Failed to create infrastructure after $attempt attempts"
444+ exit 1
445+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
446+ env :
447+ OS_CLOUD : ${{ vars.OS_CLOUD }}
448+ OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
449+ OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
450+
451+ - name : Get Terraform outputs
452+ id : tf_outputs
453+ run : |
454+ terraform output -json
455+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
456+
457+ - name : Write Terraform outputs
458+ run : |
459+ cat << EOF > src/kayobe-config/etc/kayobe/environments/ci-builder/tf-outputs.yml
460+ ${{ steps.tf_outputs.outputs.stdout }}
461+ EOF
462+
463+ - name : Write Terraform network config
464+ run : |
465+ cat << EOF > src/kayobe-config/etc/kayobe/environments/ci-builder/tf-network-allocation.yml
466+ ---
467+ aio_ips:
468+ builder: "{{ access_ip_v4.value }}"
469+ EOF
470+
471+ - name : Write Terraform network interface config
472+ run : |
473+ mkdir -p src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed
474+ rm -f src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed/network-interfaces
475+ cat << EOF > src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed/network-interfaces
476+ admin_interface: "{{ access_interface.value }}"
477+ aio_interface: "{{ access_interface.value }}"
478+ EOF
479+
480+ - name : Manage SSH keys
481+ run : |
482+ mkdir -p ~/.ssh
483+ touch ~/.ssh/authorized_keys
484+ cat src/kayobe-config/terraform/aio/id_rsa.pub >> ~/.ssh/authorized_keys
485+ cp src/kayobe-config/terraform/aio/id_rsa* ~/.ssh/
486+
487+ - name : Bootstrap the control host
488+ run : |
489+ source venvs/kayobe/bin/activate &&
490+ source src/kayobe-config/kayobe-env --environment ci-builder &&
491+ kayobe control host bootstrap
492+
493+ - name : Configure the seed host (Builder VM)
494+ run : |
495+ source venvs/kayobe/bin/activate &&
496+ source src/kayobe-config/kayobe-env --environment ci-builder &&
497+ kayobe seed host configure -e seed_bootstrap_user=ubuntu --skip-tags network
498+
499+ - name : Install dependencies
500+ run : |
501+ source venvs/kayobe/bin/activate &&
502+ source src/kayobe-config/kayobe-env --environment ci-builder &&
503+ kayobe seed host command run \
504+ --command "sudo apt update && sudo apt -y install gcc git libffi-dev python3-dev python-is-python3 python3-venv containerd docker.io docker-buildx" --show-output
505+ env :
506+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
507+
508+ - name : Create bifrost_httpboot Docker volume
509+ run : |
510+ source venvs/kayobe/bin/activate &&
511+ source src/kayobe-config/kayobe-env --environment ci-builder &&
512+ kayobe seed host command run --command "sudo mkdir -p /var/lib/docker/volumes/bifrost_httpboot/_data" --show-output
513+ env :
514+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
515+
312516 - name : Build an Ubuntu Noble 24.04 overcloud host image
313517 id : build_ubuntu_noble
314518 continue-on-error : true
@@ -340,11 +544,11 @@ jobs:
340544 kayobe playbook run \
341545 src/kayobe-config/etc/kayobe/ansible/pulp-artifact-upload.yml \
342546 -e artifact_path=/opt/kayobe/images/overcloud-ubuntu-noble \
343- -e artifact_tag=${{ steps.host_image_tag .outputs.host_image_tag }} \
547+ -e artifact_tag=${{ needs.create-tag .outputs.host_image_tag }} \
344548 -e artifact_type="kayobe-images" \
345549 -e file_regex="*.qcow2" \
346550 -e os_distribution="ubuntu" \
347- -e os_release="noble"
551+ -e os_release="noble" -vvv
348552 env :
349553 KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
350554 if : inputs.ubuntu-noble && steps.build_ubuntu_noble.outcome == 'success'
@@ -356,7 +560,7 @@ jobs:
356560 kayobe playbook run \
357561 src/kayobe-config/etc/kayobe/ansible/openstack-host-image-upload.yml \
358562 -e local_image_path="/opt/kayobe/images/overcloud-ubuntu-noble/overcloud-ubuntu-noble.qcow2" \
359- -e image_name=overcloud-ubuntu-noble-${{ steps.host_image_tag .outputs.host_image_tag }}
563+ -e image_name=overcloud-ubuntu-noble-${{ needs.create-tag .outputs.host_image_tag }}
360564 env :
361565 CLOUDS_YAML : ${{ secrets.CLOUDS_YAML }}
362566 OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
@@ -370,7 +574,7 @@ jobs:
370574 kayobe playbook run \
371575 src/kayobe-config/etc/kayobe/ansible/openstack-host-image-upload.yml \
372576 -e local_image_path="/opt/kayobe/images/overcloud-ubuntu-noble/overcloud-ubuntu-noble.qcow2" \
373- -e image_name=overcloud-ubuntu-noble-${{ steps.host_image_tag .outputs.host_image_tag }}
577+ -e image_name=overcloud-ubuntu-noble-${{ needs.create-tag .outputs.host_image_tag }}
374578 env :
375579 CLOUDS_YAML : ${{ secrets.CLOUDS_YAML_OTHER_CLOUD }}
376580 OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID_OTHER_CLOUD }}
@@ -395,7 +599,7 @@ jobs:
395599 - name : Upload logs artifact
396600 uses : actions/upload-artifact@v4
397601 with :
398- name : Build logs
602+ name : Build logs Ubuntu
399603 path : ./logs
400604 if : always()
401605
0 commit comments