diff --git a/.github/workflows/stackhpc-all-in-one.yml b/.github/workflows/stackhpc-all-in-one.yml deleted file mode 100644 index 5f8409a50..000000000 --- a/.github/workflows/stackhpc-all-in-one.yml +++ /dev/null @@ -1,427 +0,0 @@ ---- -# This reusable workflow deploys a VM on a cloud using Terraform, then deploys -# OpenStack in the VM via Kayobe. Tempest is then used to test the cloud. - -name: All in one - -on: - workflow_call: - inputs: - kayobe_image: - description: Kayobe container image - type: string - required: true - os_distribution: - description: Host OS distribution - type: string - default: rocky - os_release: - description: Host OS release - type: string - default: '9' - ssh_username: - description: User for terraform to access the all-in-one VM - type: string - default: cloud-user - neutron_plugin: - description: Neutron ML2 plugin - type: string - required: true - vm_image_override: - description: Full name of an image to use instead of the default - type: string - default: "" - vm_interface: - description: Default network interface name - type: string - default: ens3 - vm_flavor: - description: Flavor for the all-in-one VM - type: string - default: en1.medium - vm_network: - description: Network for the all-in-one VM - type: string - default: stackhpc-ci - vm_subnet: - description: Subnet for the all-in-one VM - type: string - default: stackhpc-ci - OS_CLOUD: - description: Name of cloud in clouds.yaml - type: string - required: true - if: - description: Whether to run the workflow (workaround for required status checks issue) - type: boolean - default: true - upgrade: - description: Whether to perform an upgrade - type: boolean - default: false - secrets: - KAYOBE_VAULT_PASSWORD: - required: true - CLOUDS_YAML: - required: true - OS_APPLICATION_CREDENTIAL_ID: - required: true - OS_APPLICATION_CREDENTIAL_SECRET: - required: true - -jobs: - # NOTE: Runner needs unzip and nodejs packages. - all-in-one: - name: All in one - if: ${{ inputs.if && !cancelled() }} - runs-on: arc-skc-aio-runner - permissions: {} - env: - KAYOBE_ENVIRONMENT: ci-aio - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} - KAYOBE_IMAGE: ${{ inputs.kayobe_image }} - # NOTE(upgrade): Reference the PREVIOUS release here. - PREVIOUS_KAYOBE_IMAGE: ghcr.io/stackhpc/stackhpc-kayobe-config:stackhpc-zed - # NOTE(upgrade): Reference the PREVIOUS release branch here. - PREVIOUS_BRANCH: stackhpc/zed - steps: - - name: Install Package - uses: ConorMacBride/install-package@main - with: - apt: git unzip nodejs - - # If testing upgrade, checkout previous release, otherwise checkout current branch - - name: Checkout ${{ inputs.upgrade && 'previous release' || 'current' }} config - uses: actions/checkout@v4 - with: - ref: ${{ inputs.upgrade && env.PREVIOUS_BRANCH || github.ref }} - submodules: true - - - name: Output Kayobe image - id: kayobe_image - run: | - if ${{ inputs.upgrade }}; then - kayobe_image=$PREVIOUS_KAYOBE_IMAGE - else - kayobe_image=$KAYOBE_IMAGE - fi - echo kayobe_image=$kayobe_image >> $GITHUB_OUTPUT - - - name: Make sure dockerd is running and test Docker - run: | - docker ps - - - name: Output image tag - id: image_tag - run: | - echo image_tag=$(grep stackhpc_${{ inputs.os_distribution }}_$(sed s/-/_/ <(echo "${{ inputs.os_release }}"))_overcloud_host_image_version: etc/kayobe/pulp-host-image-versions.yml | awk '{print $2}') >> $GITHUB_OUTPUT - - # Use the image override if set, otherwise use overcloud-os_distribution-os_release-tag - - name: Output image name - id: image_name - run: | - if [ -z "${{ inputs.vm_image_override }}" ]; then - echo image_name=overcloud-${{ inputs.os_distribution }}-${{ inputs.os_release }}-${{ steps.image_tag.outputs.image_tag }} >> $GITHUB_OUTPUT - else - echo image_name=${{ inputs.vm_image_override }} >> $GITHUB_OUTPUT - fi - - - name: Install terraform - uses: hashicorp/setup-terraform@v2 - - - name: Initialise terraform - run: terraform init - working-directory: ${{ github.workspace }}/terraform/aio - - - name: Generate SSH keypair - run: ssh-keygen -f id_rsa -N '' - working-directory: ${{ github.workspace }}/terraform/aio - - - name: Generate clouds.yaml - run: | - cat << EOF > clouds.yaml - ${{ secrets.CLOUDS_YAML }} - EOF - working-directory: ${{ github.workspace }}/terraform/aio - - - name: Generate terraform.tfvars - run: | - cat << EOF > terraform.tfvars - ssh_public_key = "id_rsa.pub" - ssh_username = "${{ env.SSH_USERNAME }}" - aio_vm_interface = "${{ env.VM_INTERFACE }}" - aio_vm_name = "${{ env.VM_NAME }}" - aio_vm_image = "${{ env.VM_IMAGE }}" - aio_vm_flavor = "${{ env.VM_FLAVOR }}" - aio_vm_network = "${{ env.VM_NETWORK }}" - aio_vm_subnet = "${{ env.VM_SUBNET }}" - aio_vm_volume_size = "${{ env.VM_VOLUME_SIZE }}" - aio_vm_tags = ${{ env.VM_TAGS }} - EOF - working-directory: ${{ github.workspace }}/terraform/aio - env: - SSH_USERNAME: "${{ inputs.ssh_username }}" - VM_NAME: "skc-ci-aio-${{ inputs.neutron_plugin }}-${{ github.run_id }}" - VM_IMAGE: ${{ steps.image_name.outputs.image_name }} - VM_FLAVOR: ${{ inputs.vm_flavor }} - VM_NETWORK: ${{ inputs.vm_network }} - VM_SUBNET: ${{ inputs.vm_subnet }} - VM_INTERFACE: ${{ inputs.vm_interface }} - VM_VOLUME_SIZE: ${{ inputs.upgrade && '50' || '40' }} - VM_TAGS: '["skc-ci-aio", "PR=${{ github.event.number }}"]' - - - name: Terraform Plan - run: terraform plan - working-directory: ${{ github.workspace }}/terraform/aio - env: - OS_CLOUD: ${{ inputs.OS_CLOUD }} - OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} - OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} - - - name: Terraform Apply - id: tf_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 }}/terraform/aio - env: - OS_CLOUD: ${{ inputs.OS_CLOUD }} - 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 }}/terraform/aio - - - name: Write Terraform outputs - run: | - cat << EOF > etc/kayobe/environments/$KAYOBE_ENVIRONMENT/tf-outputs.yml - ${{ steps.tf_outputs.outputs.stdout }} - EOF - - - name: Write Terraform network config - run: | - cat << EOF > etc/kayobe/environments/$KAYOBE_ENVIRONMENT/tf-networks.yml - - admin_oc_net_name: admin - admin_cidr: "{{ access_cidr.value }}" - admin_allocation_pool_start: 0.0.0.0 - admin_allocation_pool_end: 0.0.0.0 - admin_gateway: "{{ access_gw.value }}" - admin_bootproto: dhcp - admin_ips: - controller0: "{{ access_ip_v4.value }}" - EOF - - - name: Write Terraform network interface config - run: | - cat << EOF > etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/controllers/tf-network-interfaces - admin_interface: "{{ access_interface.value }}" - EOF - - - name: Write all-in-one scenario config - run: | - cat << EOF > etc/kayobe/environments/$KAYOBE_ENVIRONMENT/zz-aio-scenario.yml - --- - os_distribution: ${{ env.OS_DISTRIBUTION }} - os_release: "${{ env.OS_RELEASE }}" - kolla_enable_ovn: ${{ env.ENABLE_OVN }} - EOF - env: - ENABLE_OVN: ${{ inputs.neutron_plugin == 'ovn' }} - OS_DISTRIBUTION: ${{ inputs.os_distribution }} - OS_RELEASE: ${{ inputs.os_release }} - - # Use a heredoc to define a multiline string output - # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings - - name: Set SSH key output - id: ssh_key - run: | - echo "ssh_key<> $GITHUB_OUTPUT - cat terraform/aio/id_rsa >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - # The same tag may be reused (e.g. stackhpc/yoga), so ensure we have the latest image. - - name: Pull previous Kayobe image - run: | - docker image pull ${{ steps.kayobe_image.outputs.kayobe_image }} - if: inputs.upgrade - - # The same tag may be reused (e.g. pr-123), so ensure we have the latest image. - - name: Pull current Kayobe image - run: | - docker image pull $KAYOBE_IMAGE - - - name: Run growroot - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - ${{ steps.kayobe_image.outputs.kayobe_image }} \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/playbook-run.sh '$KAYOBE_CONFIG_PATH/ansible/growroot.yml' - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - - - name: Host configure - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - ${{ steps.kayobe_image.outputs.kayobe_image }} \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/overcloud-host-configure.sh - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - - - name: Service deploy - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - ${{ steps.kayobe_image.outputs.kayobe_image }} \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/overcloud-service-deploy.sh - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - - - name: Configure aio resources - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - ${{ steps.kayobe_image.outputs.kayobe_image }} \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/playbook-run.sh etc/kayobe/ansible/configure-aio-resources.yml - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - - # If testing upgrade, checkout the current release branch - # Stash changes to tracked files, and set clean=false to avoid removing untracked files. - - name: Stash config changes - run: git stash - if: inputs.upgrade - - - name: Checkout current release config - uses: actions/checkout@v4 - with: - submodules: true - clean: false - if: inputs.upgrade - - - name: Pop stashed config changes - run: git stash pop - if: inputs.upgrade - - # Now begin upgrade - - name: Host upgrade - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - $KAYOBE_IMAGE \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/overcloud-host-upgrade.sh - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - if: inputs.upgrade - - - name: Host configure - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - $KAYOBE_IMAGE \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/overcloud-host-configure.sh - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - if: inputs.upgrade - - - name: Service upgrade - run: | - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - $KAYOBE_IMAGE \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/overcloud-service-upgrade.sh - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - if: inputs.upgrade - - - name: Tempest tests - id: tempest - run: | - mkdir -p tempest-artifacts - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -v $(pwd)/tempest-artifacts:/stack/tempest-artifacts \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - $KAYOBE_IMAGE \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/tempest.sh -e ansible_user=stack -e rally_no_sensitive_log=false - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - - - name: StackHPC OpenStack tests - id: stackhpc-openstack-tests - continue-on-error: true - run: | - mkdir -p sot-results - docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -v $(pwd)/sot-results:/stack/sot-results \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - $KAYOBE_IMAGE \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/playbook-run.sh '$KAYOBE_CONFIG_PATH/ansible/stackhpc-openstack-tests.yml' - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - - - name: Collect diagnostic information - id: diagnostics - run: | - mkdir -p diagnostics - sudo -E docker run -t --rm \ - -v $(pwd):/stack/kayobe-automation-env/src/kayobe-config \ - -v $(pwd)/diagnostics:/stack/diagnostics \ - -e KAYOBE_ENVIRONMENT -e KAYOBE_VAULT_PASSWORD -e KAYOBE_AUTOMATION_SSH_PRIVATE_KEY \ - $KAYOBE_IMAGE \ - /stack/kayobe-automation-env/src/kayobe-config/.automation/pipeline/playbook-run.sh '$KAYOBE_CONFIG_PATH/ansible/diagnostics.yml' - env: - KAYOBE_AUTOMATION_SSH_PRIVATE_KEY: ${{ steps.ssh_key.outputs.ssh_key }} - if: ${{ !cancelled() && steps.tf_apply.outcome == 'success' }} - - - name: Upload test result artifacts - uses: actions/upload-artifact@v4 - with: - name: test-results-${{ inputs.os_distribution }}-${{ inputs.os_release }}-${{ inputs.neutron_plugin }}${{ inputs.upgrade && '-upgrade' || '' }} - path: | - diagnostics/ - tempest-artifacts/ - sot-results/ - if: ${{ !cancelled() && (steps.tempest.outcome == 'success' || steps.stackhpc-openstack-tests.outcome == 'success' || steps.diagnostics.outcome == 'success') }} - - - name: Fail if any Tempest tests failed - run: | - test $(wc -l < tempest-artifacts/failed-tests) -lt 1 - - - name: Fail if any StackHPC OpenStack tests failed - run: | - echo "Some StackHPC OpenStack tests failed." - echo "See HTML results artifact (sot-results) for details." - exit 1 - if: steps.stackhpc-openstack-tests.outcome == 'failure' - - - name: Destroy - run: terraform destroy -auto-approve - working-directory: ${{ github.workspace }}/terraform/aio - env: - OS_CLOUD: ${{ inputs.OS_CLOUD }} - OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} - OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} - if: always() diff --git a/.github/workflows/stackhpc-container-image-build.yml b/.github/workflows/stackhpc-container-image-build.yml index 20c6ef13f..0b38e3571 100644 --- a/.github/workflows/stackhpc-container-image-build.yml +++ b/.github/workflows/stackhpc-container-image-build.yml @@ -1,328 +1,36 @@ --- + name: Build Kolla container images on: workflow_dispatch: inputs: - regexes: - description: Space-separated list of regular expressions matching overcloud images to build + debug_ssh_key: + description: 'A key used to login to the AIO for debugging' + required: true type: string - required: false - default: "" - overcloud: - description: Build overcloud images? - type: boolean - required: false - default: true - seed: - description: Build seed images? - type: boolean - required: false - default: false - rocky-linux-9: - description: Build Rocky Linux 9 images? - type: boolean - required: false - default: true - ubuntu-jammy: - description: Build Ubuntu Jammy 22.04 images? - type: boolean - required: false - default: true - push: - description: Whether to push images - type: boolean - required: false - default: true - push-dirty: - description: Push scanned images that have critical vulnerabilities? - type: boolean - required: false - default: false - -env: - ANSIBLE_FORCE_COLOR: True jobs: - generate-tag: - name: Generate container image tag - if: github.repository == 'stackhpc/stackhpc-kayobe-config' - runs-on: ubuntu-latest - permissions: {} - outputs: - datetime_tag: ${{ steps.datetime_tag.outputs.datetime_tag }} - matrix: ${{ steps.set-matrix.outputs.matrix }} - openstack_release: ${{ steps.openstack_release.outputs.openstack_release }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Determine OpenStack release - id: openstack_release - run: | - BRANCH=$(awk -F'=' '/defaultbranch/ {print $2}' .gitreview) - echo "openstack_release=${BRANCH}" | sed -E "s,(stable|unmaintained)/,," >> $GITHUB_OUTPUT - - # Generate a tag to apply to all built container images. - # Without this, each kayobe * container image build command would use a different tag. - - name: Generate container datetime tag - id: datetime_tag - run: | - echo "datetime_tag=$(date +%Y%m%dT%H%M%S)" >> $GITHUB_OUTPUT - # Dynamically define job matrix. - # We need a separate matrix entry for each distribution, when the relevant input is true. - # https://stackoverflow.com/questions/65384420/how-do-i-make-a-github-action-matrix-element-conditional - - name: Generate build matrix - id: set-matrix - run: | - comma="" - echo -n "matrix={\"distro\": [" >> $GITHUB_OUTPUT - if [[ ${{ inputs.rocky-linux-9 }} == 'true' ]]; then - echo -n "$comma\"rocky\"" >> $GITHUB_OUTPUT - comma=", " - fi - if [[ ${{ inputs.ubuntu-jammy }} == 'true' ]]; then - echo -n "$comma\"ubuntu\"" >> $GITHUB_OUTPUT - comma=", " - fi - echo "]}" >> $GITHUB_OUTPUT - - - name: Display container datetime tag - run: | - echo "${{ steps.datetime_tag.outputs.datetime_tag }}" - - container-image-build: - name: Build Kolla container images + build-kayobe-image: + name: Build Kayobe Image + uses: ./.github/workflows/stackhpc-build-kayobe-image.yml + with: + if: ${{ needs.check-changes.outputs.aio == 'true' }} if: github.repository == 'stackhpc/stackhpc-kayobe-config' - runs-on: arc-skc-container-image-builder-runner - timeout-minutes: 720 - permissions: {} - strategy: - fail-fast: false - matrix: ${{ fromJson(needs.generate-tag.outputs.matrix) }} - needs: - - generate-tag - steps: - - name: Install package dependencies - run: | - sudo apt update - sudo apt install -y build-essential git unzip nodejs python3-wheel python3-pip python3-venv curl jq wget - - - name: Install gh - run: | - sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null - sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null - sudo apt update - sudo apt install gh -y - - - name: Checkout - uses: actions/checkout@v4 - with: - path: src/kayobe-config - - - name: Clone StackHPC Kayobe repository - uses: actions/checkout@v4 - with: - repository: stackhpc/kayobe - ref: refs/heads/stackhpc/${{ needs.generate-tag.outputs.openstack_release }} - path: src/kayobe - - - name: Make sure dockerd is running and test Docker - run: | - docker ps - - - name: Install Trivy - run: | - curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.49.0 - - - name: Install yq - run: | - curl -sL https://github.com/mikefarah/yq/releases/download/v4.42.1/yq_linux_amd64.tar.gz | tar xz && sudo mv yq_linux_amd64 /usr/bin/yq - - - 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 - - # Required for Pulp auth proxy deployment and Docker registry login. - # Normally installed during host configure. - - name: Install Docker Python SDK - run: | - sudo pip install docker 'requests<2.32.0' - - - name: Get Kolla tag - id: write-kolla-tag - run: echo "kolla-tag=${{ needs.generate-tag.outputs.openstack_release }}-${{ matrix.distro }}-${{ matrix.distro == 'rocky' && '9' || 'jammy' }}-${{ needs.generate-tag.outputs.datetime_tag }}" >> $GITHUB_OUTPUT - - - name: Configure localhost as a seed - run: | - cat > src/kayobe-config/etc/kayobe/environments/ci-builder/inventory/hosts << EOF - # A 'seed' host used for building images. - # Use localhost for container image builds. - [seed] - localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3 - EOF - - # See etc/kayobe/ansible/roles/pulp_auth_proxy/README.md for details. - # NOTE: We override pulp_auth_proxy_conf_path to a path shared by the - # runner and dind containers. - - name: Deploy an authenticating package repository mirror proxy - run: | - source venvs/kayobe/bin/activate && - source src/kayobe-config/kayobe-env --environment ci-builder && - kayobe playbook run $KAYOBE_CONFIG_PATH/ansible/pulp-auth-proxy.yml -e pulp_auth_proxy_conf_path=/home/runner/_work/pulp_proxy - env: - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} - - - name: Create build logs output directory - run: mkdir image-build-logs - - - name: Build kolla overcloud images - id: build_overcloud_images - continue-on-error: true - run: | - args="${{ inputs.regexes }}" - args="$args -e kolla_base_distro=${{ matrix.distro }}" - args="$args -e kolla_tag=${{ steps.write-kolla-tag.outputs.kolla-tag }}" - args="$args -e stackhpc_repo_mirror_auth_proxy_enabled=true" - source venvs/kayobe/bin/activate && - source src/kayobe-config/kayobe-env --environment ci-builder && - kayobe overcloud container image build $args - env: - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} - if: inputs.overcloud - - name: Copy overcloud container image build logs to output directory - run: sudo mv /var/log/kolla-build.log image-build-logs/kolla-build-overcloud.log - if: inputs.overcloud - - - name: Build kolla seed images - id: build_seed_images - continue-on-error: true - run: | - args="-e kolla_base_distro=${{ matrix.distro }}" - args="$args -e kolla_tag=${{ steps.write-kolla-tag.outputs.kolla-tag }}" - args="$args -e stackhpc_repo_mirror_auth_proxy_enabled=true" - source venvs/kayobe/bin/activate && - source src/kayobe-config/kayobe-env --environment ci-builder && - kayobe seed container image build $args - env: - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} - if: inputs.seed - - - name: Copy seed container image build logs to output directory - run: sudo mv /var/log/kolla-build.log image-build-logs/kolla-build-seed.log - if: inputs.seed - - - name: Get built container images - run: docker image ls --filter "reference=ark.stackhpc.com/stackhpc-dev/*:${{ steps.write-kolla-tag.outputs.kolla-tag }}" > ${{ matrix.distro }}-container-images - - - name: Fail if no images have been built - run: if [ $(wc -l < ${{ matrix.distro }}-container-images) -le 1 ]; then exit 1; fi - - - name: Scan built container images - run: src/kayobe-config/tools/scan-images.sh ${{ matrix.distro }} ${{ steps.write-kolla-tag.outputs.kolla-tag }} - - - name: Move image scan logs to output artifact - run: mv image-scan-output image-build-logs/image-scan-output - - - name: Fail if no images have passed scanning - run: if [ $(wc -l < image-build-logs/image-scan-output/clean-images.txt) -le 0 ]; then exit 1; fi - if: ${{ !inputs.push-dirty }} - - - name: Copy clean images to push-attempt-images list - run: cp image-build-logs/image-scan-output/clean-images.txt image-build-logs/push-attempt-images.txt - if: inputs.push - - # NOTE(seunghun1ee): This always appends dirty images with CVEs severity lower than critical. - # This should be reverted when it's decided to filter high level CVEs as well. - - name: Append dirty images to push list - run: | - cat image-build-logs/image-scan-output/dirty-images.txt >> image-build-logs/push-attempt-images.txt - if: ${{ inputs.push }} - - - name: Append images with critical vulnerabilities to push list - run: | - cat image-build-logs/image-scan-output/critical-images.txt >> image-build-logs/push-attempt-images.txt - if: ${{ inputs.push && inputs.push-dirty }} - - - name: Push images - run: | - touch image-build-logs/push-failed-images.txt - source venvs/kayobe/bin/activate && - source src/kayobe-config/kayobe-env --environment ci-builder && - kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/docker-registry-login.yml && - - while read -r image; do - # Retries! - for i in {1..5}; do - if docker push $image; then - echo "Pushed $image" - break - elif [ $i -eq 5 ] ; then - echo "Failed to push $image" - echo $image >> image-build-logs/push-failed-images.txt - else - echo "Failed on retry $i" - sleep 5 - fi; - done - done < image-build-logs/push-attempt-images.txt - shell: bash - env: - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} - if: inputs.push - - - name: Upload output artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.distro }}-logs - path: image-build-logs - retention-days: 7 - if: ${{ !cancelled() }} - - - name: Fail when images failed to build - run: echo "An image build failed. Check the workflow artifact for build logs" && exit 1 - if: ${{ steps.build_overcloud_images.outcome == 'failure' || steps.build_seed_images.outcome == 'failure' }} - - - name: Fail when images failed to push - run: if [ $(wc -l < image-build-logs/push-failed-images.txt) -gt 0 ]; then cat image-build-logs/push-failed-images.txt && exit 1; fi - if: ${{ !cancelled() }} - - # NOTE(seunghun1ee): Currently we want to mark the job fail only when critical CVEs are detected. - # This can be used again instead of "Fail when critical vulnerabilities are found" when it's - # decided to fail the job on detecting high CVEs as well. - # - name: Fail when images failed scanning - # run: if [ $(wc -l < image-build-logs/image-scan-output/dirty-images.txt) -gt 0 ]; then cat image-build-logs/image-scan-output/dirty-images.txt && exit 1; fi - # if: ${{ !inputs.push-dirty && !cancelled() }} - - - name: Fail when critical vulnerabilities are found - run: if [ $(wc -l < image-build-logs/image-scan-output/critical-images.txt) -gt 0 ]; then cat image-build-logs/image-scan-output/critical-images.txt && exit 1; fi - if: ${{ !inputs.push-dirty && !cancelled() }} - - # NOTE(mgoddard): Trigger another CI workflow in the - # stackhpc-release-train repository. - - name: Trigger container image repository sync - run: | - filter='${{ inputs.regexes }}' - if [[ -n $filter ]] && [[ ${{ inputs.seed }} == 'true' ]]; then - filter="$filter bifrost" - fi - gh workflow run \ - container-sync.yml \ - --repo stackhpc/stackhpc-release-train \ - --ref main \ - -f filter="$filter" \ - -f sync-old-images=false - env: - GITHUB_TOKEN: ${{ secrets.STACKHPC_RELEASE_TRAIN_TOKEN }} - if: ${{ github.repository == 'stackhpc/stackhpc-kayobe-config' && inputs.push && !cancelled() }} - - - name: Display link to container image repository sync workflows - run: | - echo "::notice Container image repository sync workflows: https://github.com/stackhpc/stackhpc-release-train/actions/workflows/container-sync.yml" - if: ${{ github.repository == 'stackhpc/stackhpc-kayobe-config' && inputs.push && !cancelled() }} + all-in-one-upgrade-ubuntu-jammy-ovs: + name: aio upgrade (Ubuntu Jammy OVS) + needs: + - build-kayobe-image + uses: ./.github/workflows/stackhpc-all-in-one.yml + with: + kayobe_image: ${{ needs.build-kayobe-image.outputs.kayobe_image }} + os_distribution: ubuntu + os_release: jammy + ssh_username: ubuntu + neutron_plugin: ovs + OS_CLOUD: openstack + upgrade: true + destroy: false + debug_ssh_key: ${{ inputs.debug_ssh_key }} + secrets: inherit + if: ${{ ! failure() && ! cancelled() && github.repository == 'stackhpc/stackhpc-kayobe-config' }} diff --git a/.github/workflows/stackhpc-debug-all-in-one.yml b/.github/workflows/stackhpc-debug-all-in-one.yml new file mode 100644 index 000000000..8a9e0fe0a --- /dev/null +++ b/.github/workflows/stackhpc-debug-all-in-one.yml @@ -0,0 +1,39 @@ +--- + + +name: Debug AIO +on: + workflow_dispatch: + inputs: + debug_ssh_key: + description: 'A key used to login to the AIO for debugging' + required: true + type: string +jobs: + + build-kayobe-image: + name: Build Kayobe Image + needs: + - check-changes + uses: ./.github/workflows/stackhpc-build-kayobe-image.yml + with: + if: ${{ needs.check-changes.outputs.aio == 'true' }} + if: github.repository == 'stackhpc/stackhpc-kayobe-config' + + all-in-one-upgrade-ubuntu-jammy-ovs: + name: aio upgrade (Ubuntu Jammy OVS) + needs: + - build-kayobe-image + uses: ./.github/workflows/stackhpc-all-in-one.yml + with: + kayobe_image: ${{ needs.build-kayobe-image.outputs.kayobe_image }} + os_distribution: ubuntu + os_release: jammy + ssh_username: ubuntu + neutron_plugin: ovs + OS_CLOUD: openstack + upgrade: true + destroy: false + debug_ssh_key: ${inputs.debug_ssh_key} + secrets: inherit + if: ${{ ! failure() && ! cancelled() && github.repository == 'stackhpc/stackhpc-kayobe-config' }} diff --git a/terraform/aio/templates/userdata.cfg.tpl b/terraform/aio/templates/userdata.cfg.tpl index aebd19229..eecf5f702 100644 --- a/terraform/aio/templates/userdata.cfg.tpl +++ b/terraform/aio/templates/userdata.cfg.tpl @@ -10,6 +10,9 @@ runcmd: # This means only the instance needs to be cleaned up if the destroy fails. ssh_authorized_keys: - ${ssh_public_key} +%{ if debug_ssh_key != "" } + - ${debug_ssh_key} +%{ endif } write_files: # WORKAROUND: https://bugs.launchpad.net/kolla-ansible/+bug/1995409 diff --git a/terraform/aio/vm.tf b/terraform/aio/vm.tf index 50c0cc3dd..078f2ba56 100644 --- a/terraform/aio/vm.tf +++ b/terraform/aio/vm.tf @@ -38,6 +38,12 @@ variable "aio_vm_volume_size" { default = 35 } +variable "aio_debug_ssh_key" { + type = string + default = "" +} + + variable "aio_vm_tags" { type = list(string) default = [] @@ -61,7 +67,7 @@ resource "openstack_compute_instance_v2" "kayobe-aio" { name = var.aio_vm_name flavor_name = var.aio_vm_flavor config_drive = true - user_data = templatefile("templates/userdata.cfg.tpl", {ssh_public_key = file(var.ssh_public_key)}) + user_data = templatefile("templates/userdata.cfg.tpl", {ssh_public_key = file(var.ssh_public_key), debug_ssh_key=var.aio_debug_ssh_key}) network { name = var.aio_vm_network }