From a4efa4ac7530aad83c0da2a1daa2a17564aee41b Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Thu, 10 Sep 2026 19:51:00 -0700 Subject: [PATCH 01/16] ci: add cloud agent runner smoke probe Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .gitattributes | 2 + .../workflows/cloud-agent-runner-smoke.yml | 64 +++++++++ scripts/cloud-agent/runner-smoke.sh | 132 ++++++++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/cloud-agent-runner-smoke.yml create mode 100644 scripts/cloud-agent/runner-smoke.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..d8b6212c90 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +scripts/cloud-agent/runner-smoke.sh text eol=lf +.github/workflows/cloud-agent-runner-smoke.yml text eol=lf diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml new file mode 100644 index 0000000000..ecd0fbb36f --- /dev/null +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -0,0 +1,64 @@ +name: Cloud agent runner smoke + +permissions: {} + +on: + workflow_dispatch: + push: + branches: + - user/britel/cloud-agent-runner-smoke + paths: + - .github/workflows/cloud-agent-runner-smoke.yml + - scripts/cloud-agent/runner-smoke.sh + +jobs: + runner-smoke: + name: Validate 1ES KVM runner + runs-on: + - self-hosted + - 1ES.Pool=maritimus-github-runner-ubuntu2404-amd64 + - JobId=trident-cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} + timeout-minutes: 20 + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Install virtualization prerequisites + run: | + set -eux + + sudo mkdir -p /etc/apt/apt.conf.d + echo 'DPkg::Lock::Timeout "600";' | sudo tee -a /etc/apt/apt.conf.d/99lock-timeout + + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + libvirt-clients \ + libvirt-daemon-system \ + ovmf \ + qemu-kvm \ + qemu-utils + + sudo systemctl restart libvirtd + sudo systemctl status --no-pager libvirtd + + - name: Run KVM and libvirt smoke test + run: | + set -o pipefail + log_dir="$RUNNER_TEMP/trident-cloud-agent-runner-smoke" + mkdir -p "$log_dir" + + bash scripts/cloud-agent/runner-smoke.sh "$log_dir" \ + 2>&1 | tee "$log_dir/runner-smoke.log" + + - name: Upload runner diagnostics + if: ${{ !cancelled() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} + path: ${{ runner.temp }}/trident-cloud-agent-runner-smoke + if-no-files-found: error diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh new file mode 100644 index 0000000000..77114246b8 --- /dev/null +++ b/scripts/cloud-agent/runner-smoke.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "usage: $0 " >&2 + exit 2 +fi + +log_dir="$1" +mkdir -p "$log_dir" + +run_id="${GITHUB_RUN_ID:-local}" +run_attempt="${GITHUB_RUN_ATTEMPT:-0}" +domain_name="trident-cloud-agent-smoke-${run_id}-${run_attempt}" +domain_xml="$log_dir/domain.xml" +qemu_connection="qemu:///system" + +cleanup() { + if sudo virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then + sudo virsh --connect "$qemu_connection" destroy "$domain_name" >/dev/null + fi +} +trap cleanup EXIT + +{ + echo "Timestamp: $(date --iso-8601=seconds)" + echo "Runner: ${RUNNER_NAME:-unknown}" + echo "Runner OS: ${RUNNER_OS:-unknown}" + echo "Runner architecture: ${RUNNER_ARCH:-unknown}" + echo "GitHub run: $run_id" + echo "GitHub attempt: $run_attempt" + echo "User: $(id)" + echo "Kernel: $(uname -a)" +} | tee "$log_dir/environment.txt" + +lscpu | tee "$log_dir/lscpu.txt" +free -h | tee "$log_dir/memory.txt" +df -hT | tee "$log_dir/filesystems.txt" +ls -l /dev/kvm | tee "$log_dir/kvm-device.txt" + +if [[ ! -c /dev/kvm ]]; then + echo "/dev/kvm is not a character device" >&2 + exit 1 +fi + +sudo test -r /dev/kvm +sudo test -w /dev/kvm + +if [[ -r /sys/module/kvm_intel/parameters/nested ]]; then + cat /sys/module/kvm_intel/parameters/nested | tee "$log_dir/nested-virtualization.txt" +elif [[ -r /sys/module/kvm_amd/parameters/nested ]]; then + cat /sys/module/kvm_amd/parameters/nested | tee "$log_dir/nested-virtualization.txt" +else + echo "No nested virtualization module parameter found" | tee "$log_dir/nested-virtualization.txt" +fi + +qemu_bin="$(command -v qemu-system-x86_64)" +"$qemu_bin" --version | tee "$log_dir/qemu-version.txt" +sudo virsh --connect "$qemu_connection" version | tee "$log_dir/virsh-version.txt" +sudo virsh --connect "$qemu_connection" nodeinfo | tee "$log_dir/libvirt-nodeinfo.txt" + +set +e +sudo virt-host-validate qemu 2>&1 | tee "$log_dir/virt-host-validate.txt" +virt_validate_status=${PIPESTATUS[0]} +set -e +echo "$virt_validate_status" > "$log_dir/virt-host-validate.exit-code" + +set +e +sudo timeout 5s "$qemu_bin" \ + -machine q35,accel=kvm \ + -cpu host \ + -m 256 \ + -display none \ + -monitor none \ + -serial none \ + -nodefaults \ + -S \ + >"$log_dir/qemu-kvm-probe.txt" 2>&1 +qemu_status=$? +set -e + +echo "$qemu_status" > "$log_dir/qemu-kvm-probe.exit-code" +if [[ $qemu_status -ne 124 && $qemu_status -ne 143 ]]; then + cat "$log_dir/qemu-kvm-probe.txt" >&2 + echo "QEMU did not remain running with KVM acceleration" >&2 + exit 1 +fi + +cat > "$domain_xml" < + ${domain_name} + 256 + 256 + 1 + + hvm + + + + + + + + destroy + destroy + destroy + + ${qemu_bin} + + + + +EOF + +sudo virsh --connect "$qemu_connection" create --paused "$domain_xml" +sudo virsh --connect "$qemu_connection" dominfo "$domain_name" | tee "$log_dir/domain-info.txt" +sudo virsh --connect "$qemu_connection" destroy "$domain_name" + +if sudo virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then + echo "Transient smoke domain still exists after destroy" >&2 + exit 1 +fi + +cat > "$log_dir/result.txt" < Date: Thu, 10 Sep 2026 22:06:44 -0700 Subject: [PATCH 02/16] ci: target Trident cloud agent runner pool Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index ecd0fbb36f..fe4bb94b8e 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -16,7 +16,7 @@ jobs: name: Validate 1ES KVM runner runs-on: - self-hosted - - 1ES.Pool=maritimus-github-runner-ubuntu2404-amd64 + - 1ES.Pool=trident-github-runner-ubuntu2204-amd64 - JobId=trident-cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} timeout-minutes: 20 permissions: From 1266b3f9d85ed4cd8fcb63e97c8113a414bedada Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 07:41:44 -0700 Subject: [PATCH 03/16] ci: retrigger runner smoke after pool onboarding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index fe4bb94b8e..ed920c3720 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -16,6 +16,7 @@ jobs: name: Validate 1ES KVM runner runs-on: - self-hosted + # Dedicated stateless pool scoped to microsoft/trident. - 1ES.Pool=trident-github-runner-ubuntu2204-amd64 - JobId=trident-cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} timeout-minutes: 20 From 56ed413e581282a4187d005857fc7f44bd7fde5c Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 07:48:46 -0700 Subject: [PATCH 04/16] ci: use complete 1ES runner job identifier Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index ed920c3720..5cd7be3281 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -18,7 +18,7 @@ jobs: - self-hosted # Dedicated stateless pool scoped to microsoft/trident. - 1ES.Pool=trident-github-runner-ubuntu2204-amd64 - - JobId=trident-cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} + - JobId=trident-cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }} timeout-minutes: 20 permissions: contents: read From fe5aad61f7bceb9f0c9373a890acc89ea030e925 Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 07:53:52 -0700 Subject: [PATCH 05/16] ci: use 1ES scale-set runner integration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index 5cd7be3281..d9ef61f91a 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -14,11 +14,7 @@ on: jobs: runner-smoke: name: Validate 1ES KVM runner - runs-on: - - self-hosted - # Dedicated stateless pool scoped to microsoft/trident. - - 1ES.Pool=trident-github-runner-ubuntu2204-amd64 - - JobId=trident-cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }} + runs-on: trident-github-runner-ubuntu2204-amd64 timeout-minutes: 20 permissions: contents: read From 19f0448b09f2bee4ad47a0a700927b8cf8faf41b Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 10:03:54 -0700 Subject: [PATCH 06/16] ci: bootstrap Copilot cloud agent Configure the proven 1ES runner for Copilot setup, install Trident's documented toolchain, and validate the unit suite on the same ephemeral pool. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .gitattributes | 3 +- .../workflows/cloud-agent-runner-smoke.yml | 28 +++++++++ .github/workflows/copilot-setup-steps.yml | 37 +++++++++++ scripts/cloud-agent/setup.sh | 62 +++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/copilot-setup-steps.yml create mode 100644 scripts/cloud-agent/setup.sh diff --git a/.gitattributes b/.gitattributes index d8b6212c90..f914b17bbe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ -scripts/cloud-agent/runner-smoke.sh text eol=lf +scripts/cloud-agent/*.sh text eol=lf .github/workflows/cloud-agent-runner-smoke.yml text eol=lf +.github/workflows/copilot-setup-steps.yml text eol=lf diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index d9ef61f91a..ef5ea42c5c 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -9,6 +9,8 @@ on: - user/britel/cloud-agent-runner-smoke paths: - .github/workflows/cloud-agent-runner-smoke.yml + - .github/workflows/copilot-setup-steps.yml + - scripts/cloud-agent/setup.sh - scripts/cloud-agent/runner-smoke.sh jobs: @@ -59,3 +61,29 @@ jobs: name: cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ runner.temp }}/trident-cloud-agent-runner-smoke if-no-files-found: error + + unit-tests: + name: Validate Trident unit tests + needs: runner-smoke + runs-on: trident-github-runner-ubuntu2204-amd64 + timeout-minutes: 90 + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: "1.25.x" + cache: false + + - name: Set up Trident dependencies + run: scripts/cloud-agent/setup.sh + + - name: Run unit tests + run: make test diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 0000000000..b369d8ce39 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,37 @@ +name: Copilot Setup Steps + +permissions: {} + +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + - scripts/cloud-agent/setup.sh + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + - scripts/cloud-agent/setup.sh + +jobs: + # This job name is required by GitHub Copilot coding agent. + copilot-setup-steps: + runs-on: trident-github-runner-ubuntu2204-amd64 + timeout-minutes: 59 + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: "1.25.x" + cache: false + + - name: Set up Trident dependencies + run: scripts/cloud-agent/setup.sh diff --git a/scripts/cloud-agent/setup.sh b/scripts/cloud-agent/setup.sh new file mode 100644 index 0000000000..97160c6f63 --- /dev/null +++ b/scripts/cloud-agent/setup.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +readonly RUST_TOOLCHAIN="1.93.0" +readonly PROTOC_VERSION="33.2" +readonly PROTOC_SHA256="b24b53f87c151bfd48b112fe4c3a6e6574e5198874f38036aff41df3456b8caf" +readonly CARGO_TARGET_DIR="/mnt/trident-cloud-agent/cargo-target" + +sudo mkdir -p /etc/apt/apt.conf.d +echo 'DPkg::Lock::Timeout "600";' | sudo tee /etc/apt/apt.conf.d/99lock-timeout + +sudo apt-get update +sudo apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + clang \ + curl \ + libclang-dev \ + libssl-dev \ + pkg-config \ + unzip + +protoc_archive="protoc-${PROTOC_VERSION}-linux-x86_64.zip" +curl --fail --location --retry 3 \ + --output "$RUNNER_TEMP/$protoc_archive" \ + "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${protoc_archive}" +echo "$PROTOC_SHA256 $RUNNER_TEMP/$protoc_archive" | sha256sum --check +sudo unzip -o "$RUNNER_TEMP/$protoc_archive" -d /usr/local +rm -f "$RUNNER_TEMP/$protoc_archive" + +if ! command -v rustup >/dev/null 2>&1; then + curl --proto '=https' --tlsv1.2 --fail --silent --show-error \ + https://sh.rustup.rs | + sh -s -- -y --profile minimal --default-toolchain none +fi + +export PATH="$HOME/.cargo/bin:$PATH" +echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + +rustup toolchain install "$RUST_TOOLCHAIN" \ + --profile minimal \ + --component clippy,rustfmt +rustup default "$RUST_TOOLCHAIN" + +sudo install -d -o "$(id -u)" -g "$(id -g)" "$CARGO_TARGET_DIR" + +make .cargo/config +if ! grep -q '^\[build\]$' .cargo/config; then + cat >> .cargo/config < Date: Fri, 11 Sep 2026 10:27:17 -0700 Subject: [PATCH 07/16] ci: make cloud agent setup executable Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- scripts/cloud-agent/setup.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/cloud-agent/setup.sh diff --git a/scripts/cloud-agent/setup.sh b/scripts/cloud-agent/setup.sh old mode 100644 new mode 100755 From d28ed4bed33c0741d3b80829072b6ea26f0905be Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 11:03:02 -0700 Subject: [PATCH 08/16] ci: keep runner validation manual Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index ef5ea42c5c..acf135067f 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -4,14 +4,6 @@ permissions: {} on: workflow_dispatch: - push: - branches: - - user/britel/cloud-agent-runner-smoke - paths: - - .github/workflows/cloud-agent-runner-smoke.yml - - .github/workflows/copilot-setup-steps.yml - - scripts/cloud-agent/setup.sh - - scripts/cloud-agent/runner-smoke.sh jobs: runner-smoke: From 16580abe7e8524a89040ca87e118aaca4d5b1ca6 Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 11:25:58 -0700 Subject: [PATCH 09/16] ci: harden cloud agent validation Prevent fork pull requests from executing privileged setup on the self-hosted runner, require the configured data-disk mount, and fail when virt-host-validate reports an error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/copilot-setup-steps.yml | 4 ---- scripts/cloud-agent/runner-smoke.sh | 4 ++++ scripts/cloud-agent/setup.sh | 9 ++++++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index b369d8ce39..dd897c8ed0 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -8,10 +8,6 @@ on: paths: - .github/workflows/copilot-setup-steps.yml - scripts/cloud-agent/setup.sh - pull_request: - paths: - - .github/workflows/copilot-setup-steps.yml - - scripts/cloud-agent/setup.sh jobs: # This job name is required by GitHub Copilot coding agent. diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh index 77114246b8..d6ac3b92fe 100644 --- a/scripts/cloud-agent/runner-smoke.sh +++ b/scripts/cloud-agent/runner-smoke.sh @@ -65,6 +65,10 @@ sudo virt-host-validate qemu 2>&1 | tee "$log_dir/virt-host-validate.txt" virt_validate_status=${PIPESTATUS[0]} set -e echo "$virt_validate_status" > "$log_dir/virt-host-validate.exit-code" +if [[ $virt_validate_status -ne 0 ]]; then + echo "virt-host-validate reported a host validation failure" >&2 + exit "$virt_validate_status" +fi set +e sudo timeout 5s "$qemu_bin" \ diff --git a/scripts/cloud-agent/setup.sh b/scripts/cloud-agent/setup.sh index 97160c6f63..9277bc1d37 100755 --- a/scripts/cloud-agent/setup.sh +++ b/scripts/cloud-agent/setup.sh @@ -5,7 +5,8 @@ set -euxo pipefail readonly RUST_TOOLCHAIN="1.93.0" readonly PROTOC_VERSION="33.2" readonly PROTOC_SHA256="b24b53f87c151bfd48b112fe4c3a6e6574e5198874f38036aff41df3456b8caf" -readonly CARGO_TARGET_DIR="/mnt/trident-cloud-agent/cargo-target" +readonly DATA_DISK_MOUNT="/mnt/storage" +readonly CARGO_TARGET_DIR="$DATA_DISK_MOUNT/trident-cloud-agent/cargo-target" sudo mkdir -p /etc/apt/apt.conf.d echo 'DPkg::Lock::Timeout "600";' | sudo tee /etc/apt/apt.conf.d/99lock-timeout @@ -43,6 +44,12 @@ rustup toolchain install "$RUST_TOOLCHAIN" \ --component clippy,rustfmt rustup default "$RUST_TOOLCHAIN" +if ! mountpoint --quiet "$DATA_DISK_MOUNT"; then + echo "Expected runner data disk is not mounted at $DATA_DISK_MOUNT" >&2 + exit 1 +fi +findmnt --mountpoint "$DATA_DISK_MOUNT" + sudo install -d -o "$(id -u)" -g "$(id -g)" "$CARGO_TARGET_DIR" make .cargo/config From 084e14f0d91270c8fcef7ce6a0b3dc4623dcd855 Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 11:52:11 -0700 Subject: [PATCH 10/16] ci: complete cloud agent prerequisites Install the pinned Go protobuf generators and require nested virtualization to be enabled before the runner smoke succeeds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- scripts/cloud-agent/runner-smoke.sh | 18 +++++++++++++++--- scripts/cloud-agent/setup.sh | 10 ++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh index d6ac3b92fe..f753382c36 100644 --- a/scripts/cloud-agent/runner-smoke.sh +++ b/scripts/cloud-agent/runner-smoke.sh @@ -48,13 +48,25 @@ sudo test -r /dev/kvm sudo test -w /dev/kvm if [[ -r /sys/module/kvm_intel/parameters/nested ]]; then - cat /sys/module/kvm_intel/parameters/nested | tee "$log_dir/nested-virtualization.txt" + nested_parameter="/sys/module/kvm_intel/parameters/nested" elif [[ -r /sys/module/kvm_amd/parameters/nested ]]; then - cat /sys/module/kvm_amd/parameters/nested | tee "$log_dir/nested-virtualization.txt" + nested_parameter="/sys/module/kvm_amd/parameters/nested" else - echo "No nested virtualization module parameter found" | tee "$log_dir/nested-virtualization.txt" + echo "No nested virtualization module parameter found" | + tee "$log_dir/nested-virtualization.txt" >&2 + exit 1 fi +nested_value="$(cat "$nested_parameter")" +printf '%s\n' "$nested_value" | tee "$log_dir/nested-virtualization.txt" +case "$nested_value" in + 1 | Y | y) ;; + *) + echo "Nested virtualization is not enabled: $nested_value" >&2 + exit 1 + ;; +esac + qemu_bin="$(command -v qemu-system-x86_64)" "$qemu_bin" --version | tee "$log_dir/qemu-version.txt" sudo virsh --connect "$qemu_connection" version | tee "$log_dir/virsh-version.txt" diff --git a/scripts/cloud-agent/setup.sh b/scripts/cloud-agent/setup.sh index 9277bc1d37..c92fefe2bb 100755 --- a/scripts/cloud-agent/setup.sh +++ b/scripts/cloud-agent/setup.sh @@ -5,6 +5,8 @@ set -euxo pipefail readonly RUST_TOOLCHAIN="1.93.0" readonly PROTOC_VERSION="33.2" readonly PROTOC_SHA256="b24b53f87c151bfd48b112fe4c3a6e6574e5198874f38036aff41df3456b8caf" +readonly PROTOC_GEN_GO_VERSION="v1.36.11" +readonly PROTOC_GEN_GO_GRPC_VERSION="v1.6.2" readonly DATA_DISK_MOUNT="/mnt/storage" readonly CARGO_TARGET_DIR="$DATA_DISK_MOUNT/trident-cloud-agent/cargo-target" @@ -30,6 +32,12 @@ echo "$PROTOC_SHA256 $RUNNER_TEMP/$protoc_archive" | sha256sum --check sudo unzip -o "$RUNNER_TEMP/$protoc_archive" -d /usr/local rm -f "$RUNNER_TEMP/$protoc_archive" +go_bin_dir="$(go env GOPATH)/bin" +export PATH="$go_bin_dir:$PATH" +echo "$go_bin_dir" >> "$GITHUB_PATH" +go install "google.golang.org/protobuf/cmd/protoc-gen-go@${PROTOC_GEN_GO_VERSION}" +go install "google.golang.org/grpc/cmd/protoc-gen-go-grpc@${PROTOC_GEN_GO_GRPC_VERSION}" + if ! command -v rustup >/dev/null 2>&1; then curl --proto '=https' --tlsv1.2 --fail --silent --show-error \ https://sh.rustup.rs | @@ -67,3 +75,5 @@ rustc --version cargo --version go version protoc --version +protoc-gen-go --version +protoc-gen-go-grpc --version From 4096aada7148db85c8f5637ecdebb0d872757bdc Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 12:06:11 -0700 Subject: [PATCH 11/16] ci: validate runner access without sudo Require the trusted runner image to provide rustup, grant the job user precise KVM and libvirt ACLs, and run the virtualization probe as that user. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .../workflows/cloud-agent-runner-smoke.yml | 2 ++ scripts/cloud-agent/runner-smoke.sh | 24 +++++++++---------- scripts/cloud-agent/setup.sh | 5 ++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index acf135067f..4337d08aab 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -28,6 +28,7 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends \ + acl \ libvirt-clients \ libvirt-daemon-system \ ovmf \ @@ -36,6 +37,7 @@ jobs: sudo systemctl restart libvirtd sudo systemctl status --no-pager libvirtd + sudo setfacl -m "u:$(id -un):rw" /dev/kvm /run/libvirt/libvirt-sock - name: Run KVM and libvirt smoke test run: | diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh index f753382c36..b3a607971f 100644 --- a/scripts/cloud-agent/runner-smoke.sh +++ b/scripts/cloud-agent/runner-smoke.sh @@ -17,8 +17,8 @@ domain_xml="$log_dir/domain.xml" qemu_connection="qemu:///system" cleanup() { - if sudo virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then - sudo virsh --connect "$qemu_connection" destroy "$domain_name" >/dev/null + if virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then + virsh --connect "$qemu_connection" destroy "$domain_name" >/dev/null fi } trap cleanup EXIT @@ -44,8 +44,8 @@ if [[ ! -c /dev/kvm ]]; then exit 1 fi -sudo test -r /dev/kvm -sudo test -w /dev/kvm +test -r /dev/kvm +test -w /dev/kvm if [[ -r /sys/module/kvm_intel/parameters/nested ]]; then nested_parameter="/sys/module/kvm_intel/parameters/nested" @@ -69,11 +69,11 @@ esac qemu_bin="$(command -v qemu-system-x86_64)" "$qemu_bin" --version | tee "$log_dir/qemu-version.txt" -sudo virsh --connect "$qemu_connection" version | tee "$log_dir/virsh-version.txt" -sudo virsh --connect "$qemu_connection" nodeinfo | tee "$log_dir/libvirt-nodeinfo.txt" +virsh --connect "$qemu_connection" version | tee "$log_dir/virsh-version.txt" +virsh --connect "$qemu_connection" nodeinfo | tee "$log_dir/libvirt-nodeinfo.txt" set +e -sudo virt-host-validate qemu 2>&1 | tee "$log_dir/virt-host-validate.txt" +virt-host-validate qemu 2>&1 | tee "$log_dir/virt-host-validate.txt" virt_validate_status=${PIPESTATUS[0]} set -e echo "$virt_validate_status" > "$log_dir/virt-host-validate.exit-code" @@ -83,7 +83,7 @@ if [[ $virt_validate_status -ne 0 ]]; then fi set +e -sudo timeout 5s "$qemu_bin" \ +timeout 5s "$qemu_bin" \ -machine q35,accel=kvm \ -cpu host \ -m 256 \ @@ -129,11 +129,11 @@ cat > "$domain_xml" < EOF -sudo virsh --connect "$qemu_connection" create --paused "$domain_xml" -sudo virsh --connect "$qemu_connection" dominfo "$domain_name" | tee "$log_dir/domain-info.txt" -sudo virsh --connect "$qemu_connection" destroy "$domain_name" +virsh --connect "$qemu_connection" create --paused "$domain_xml" +virsh --connect "$qemu_connection" dominfo "$domain_name" | tee "$log_dir/domain-info.txt" +virsh --connect "$qemu_connection" destroy "$domain_name" -if sudo virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then +if virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then echo "Transient smoke domain still exists after destroy" >&2 exit 1 fi diff --git a/scripts/cloud-agent/setup.sh b/scripts/cloud-agent/setup.sh index c92fefe2bb..f44c680349 100755 --- a/scripts/cloud-agent/setup.sh +++ b/scripts/cloud-agent/setup.sh @@ -39,9 +39,8 @@ go install "google.golang.org/protobuf/cmd/protoc-gen-go@${PROTOC_GEN_GO_VERSION go install "google.golang.org/grpc/cmd/protoc-gen-go-grpc@${PROTOC_GEN_GO_GRPC_VERSION}" if ! command -v rustup >/dev/null 2>&1; then - curl --proto '=https' --tlsv1.2 --fail --silent --show-error \ - https://sh.rustup.rs | - sh -s -- -y --profile minimal --default-toolchain none + echo "The Trident runner image must provide rustup" >&2 + exit 1 fi export PATH="$HOME/.cargo/bin:$PATH" From f475b3a15bbb4e9f595541bbb7e47fc88a288698 Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 12:13:10 -0700 Subject: [PATCH 12/16] ci: preserve primary smoke failures Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index 4337d08aab..2c92c6640d 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -54,7 +54,7 @@ jobs: with: name: cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ runner.temp }}/trident-cloud-agent-runner-smoke - if-no-files-found: error + if-no-files-found: warn unit-tests: name: Validate Trident unit tests From abe5be8e8b9d3559cf9a971e737186a5627e3676 Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 12:25:07 -0700 Subject: [PATCH 13/16] ci: make host validation diagnostic Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- scripts/cloud-agent/runner-smoke.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh index b3a607971f..dfedc19e51 100644 --- a/scripts/cloud-agent/runner-smoke.sh +++ b/scripts/cloud-agent/runner-smoke.sh @@ -78,8 +78,7 @@ virt_validate_status=${PIPESTATUS[0]} set -e echo "$virt_validate_status" > "$log_dir/virt-host-validate.exit-code" if [[ $virt_validate_status -ne 0 ]]; then - echo "virt-host-validate reported a host validation failure" >&2 - exit "$virt_validate_status" + echo "virt-host-validate returned $virt_validate_status; direct QEMU and libvirt probes determine the result" >&2 fi set +e @@ -142,7 +141,7 @@ cat > "$log_dir/result.txt" < Date: Fri, 11 Sep 2026 12:34:13 -0700 Subject: [PATCH 14/16] ci: validate runner libvirt access Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .../workflows/cloud-agent-runner-smoke.yml | 2 +- scripts/cloud-agent/runner-smoke.sh | 30 ++----------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index 2c92c6640d..89f4b43ba1 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -37,7 +37,7 @@ jobs: sudo systemctl restart libvirtd sudo systemctl status --no-pager libvirtd - sudo setfacl -m "u:$(id -un):rw" /dev/kvm /run/libvirt/libvirt-sock + sudo setfacl -m "u:$(id -un):rw" /run/libvirt/libvirt-sock - name: Run KVM and libvirt smoke test run: | diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh index dfedc19e51..23aba3b0b3 100644 --- a/scripts/cloud-agent/runner-smoke.sh +++ b/scripts/cloud-agent/runner-smoke.sh @@ -37,16 +37,14 @@ trap cleanup EXIT lscpu | tee "$log_dir/lscpu.txt" free -h | tee "$log_dir/memory.txt" df -hT | tee "$log_dir/filesystems.txt" -ls -l /dev/kvm | tee "$log_dir/kvm-device.txt" +ls -l /dev/kvm /run/libvirt/libvirt-sock | tee "$log_dir/device-permissions.txt" +getfacl -p /dev/kvm /run/libvirt/libvirt-sock | tee "$log_dir/device-acls.txt" if [[ ! -c /dev/kvm ]]; then echo "/dev/kvm is not a character device" >&2 exit 1 fi -test -r /dev/kvm -test -w /dev/kvm - if [[ -r /sys/module/kvm_intel/parameters/nested ]]; then nested_parameter="/sys/module/kvm_intel/parameters/nested" elif [[ -r /sys/module/kvm_amd/parameters/nested ]]; then @@ -81,27 +79,6 @@ if [[ $virt_validate_status -ne 0 ]]; then echo "virt-host-validate returned $virt_validate_status; direct QEMU and libvirt probes determine the result" >&2 fi -set +e -timeout 5s "$qemu_bin" \ - -machine q35,accel=kvm \ - -cpu host \ - -m 256 \ - -display none \ - -monitor none \ - -serial none \ - -nodefaults \ - -S \ - >"$log_dir/qemu-kvm-probe.txt" 2>&1 -qemu_status=$? -set -e - -echo "$qemu_status" > "$log_dir/qemu-kvm-probe.exit-code" -if [[ $qemu_status -ne 124 && $qemu_status -ne 143 ]]; then - cat "$log_dir/qemu-kvm-probe.txt" >&2 - echo "QEMU did not remain running with KVM acceleration" >&2 - exit 1 -fi - cat > "$domain_xml" < ${domain_name} @@ -139,8 +116,7 @@ fi cat > "$log_dir/result.txt" < Date: Fri, 11 Sep 2026 12:47:33 -0700 Subject: [PATCH 15/16] ci: preserve Trident build paths Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .github/workflows/cloud-agent-runner-smoke.yml | 3 +++ .github/workflows/copilot-setup-steps.yml | 2 ++ scripts/cloud-agent/setup.sh | 18 ++++++++++-------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml index 89f4b43ba1..51c74143a9 100644 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ b/.github/workflows/cloud-agent-runner-smoke.yml @@ -79,5 +79,8 @@ jobs: - name: Set up Trident dependencies run: scripts/cloud-agent/setup.sh + - name: Build Trident + run: make build + - name: Run unit tests run: make test diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index dd897c8ed0..50689ec8d5 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -5,6 +5,8 @@ permissions: {} on: workflow_dispatch: push: + branches: + - main paths: - .github/workflows/copilot-setup-steps.yml - scripts/cloud-agent/setup.sh diff --git a/scripts/cloud-agent/setup.sh b/scripts/cloud-agent/setup.sh index f44c680349..180f65edc7 100755 --- a/scripts/cloud-agent/setup.sh +++ b/scripts/cloud-agent/setup.sh @@ -8,7 +8,7 @@ readonly PROTOC_SHA256="b24b53f87c151bfd48b112fe4c3a6e6574e5198874f38036aff41df3 readonly PROTOC_GEN_GO_VERSION="v1.36.11" readonly PROTOC_GEN_GO_GRPC_VERSION="v1.6.2" readonly DATA_DISK_MOUNT="/mnt/storage" -readonly CARGO_TARGET_DIR="$DATA_DISK_MOUNT/trident-cloud-agent/cargo-target" +readonly CARGO_TARGET_PATH="$DATA_DISK_MOUNT/trident-cloud-agent/cargo-target" sudo mkdir -p /etc/apt/apt.conf.d echo 'DPkg::Lock::Timeout "600";' | sudo tee /etc/apt/apt.conf.d/99lock-timeout @@ -57,16 +57,18 @@ if ! mountpoint --quiet "$DATA_DISK_MOUNT"; then fi findmnt --mountpoint "$DATA_DISK_MOUNT" -sudo install -d -o "$(id -u)" -g "$(id -g)" "$CARGO_TARGET_DIR" +sudo install -d -o "$(id -u)" -g "$(id -g)" "$CARGO_TARGET_PATH" make .cargo/config -if ! grep -q '^\[build\]$' .cargo/config; then - cat >> .cargo/config <&2 + exit 1 + fi + rmdir target fi +ln -sfn "$CARGO_TARGET_PATH" target +test "$(readlink -f target)" = "$CARGO_TARGET_PATH" cargo fetch --locked From d73e08a95b445fc57c32a91fecd256d051a7315b Mon Sep 17 00:00:00 2001 From: Brian Telfer Date: Fri, 11 Sep 2026 13:26:27 -0700 Subject: [PATCH 16/16] ci: remove temporary runner smoke harness Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 937dfad0-bd6e-454f-9046-bd773f4a3347 --- .gitattributes | 1 - .../workflows/cloud-agent-runner-smoke.yml | 86 ------------ scripts/cloud-agent/runner-smoke.sh | 123 ------------------ 3 files changed, 210 deletions(-) delete mode 100644 .github/workflows/cloud-agent-runner-smoke.yml delete mode 100644 scripts/cloud-agent/runner-smoke.sh diff --git a/.gitattributes b/.gitattributes index f914b17bbe..0b2da510e1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ scripts/cloud-agent/*.sh text eol=lf -.github/workflows/cloud-agent-runner-smoke.yml text eol=lf .github/workflows/copilot-setup-steps.yml text eol=lf diff --git a/.github/workflows/cloud-agent-runner-smoke.yml b/.github/workflows/cloud-agent-runner-smoke.yml deleted file mode 100644 index 51c74143a9..0000000000 --- a/.github/workflows/cloud-agent-runner-smoke.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Cloud agent runner smoke - -permissions: {} - -on: - workflow_dispatch: - -jobs: - runner-smoke: - name: Validate 1ES KVM runner - runs-on: trident-github-runner-ubuntu2204-amd64 - timeout-minutes: 20 - permissions: - contents: read - - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - name: Install virtualization prerequisites - run: | - set -eux - - sudo mkdir -p /etc/apt/apt.conf.d - echo 'DPkg::Lock::Timeout "600";' | sudo tee -a /etc/apt/apt.conf.d/99lock-timeout - - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - acl \ - libvirt-clients \ - libvirt-daemon-system \ - ovmf \ - qemu-kvm \ - qemu-utils - - sudo systemctl restart libvirtd - sudo systemctl status --no-pager libvirtd - sudo setfacl -m "u:$(id -un):rw" /run/libvirt/libvirt-sock - - - name: Run KVM and libvirt smoke test - run: | - set -o pipefail - log_dir="$RUNNER_TEMP/trident-cloud-agent-runner-smoke" - mkdir -p "$log_dir" - - bash scripts/cloud-agent/runner-smoke.sh "$log_dir" \ - 2>&1 | tee "$log_dir/runner-smoke.log" - - - name: Upload runner diagnostics - if: ${{ !cancelled() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: cloud-agent-runner-smoke-${{ github.run_id }}-${{ github.run_attempt }} - path: ${{ runner.temp }}/trident-cloud-agent-runner-smoke - if-no-files-found: warn - - unit-tests: - name: Validate Trident unit tests - needs: runner-smoke - runs-on: trident-github-runner-ubuntu2204-amd64 - timeout-minutes: 90 - permissions: - contents: read - - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - name: Set up Go - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 - with: - go-version: "1.25.x" - cache: false - - - name: Set up Trident dependencies - run: scripts/cloud-agent/setup.sh - - - name: Build Trident - run: make build - - - name: Run unit tests - run: make test diff --git a/scripts/cloud-agent/runner-smoke.sh b/scripts/cloud-agent/runner-smoke.sh deleted file mode 100644 index 23aba3b0b3..0000000000 --- a/scripts/cloud-agent/runner-smoke.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [[ $# -ne 1 ]]; then - echo "usage: $0 " >&2 - exit 2 -fi - -log_dir="$1" -mkdir -p "$log_dir" - -run_id="${GITHUB_RUN_ID:-local}" -run_attempt="${GITHUB_RUN_ATTEMPT:-0}" -domain_name="trident-cloud-agent-smoke-${run_id}-${run_attempt}" -domain_xml="$log_dir/domain.xml" -qemu_connection="qemu:///system" - -cleanup() { - if virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then - virsh --connect "$qemu_connection" destroy "$domain_name" >/dev/null - fi -} -trap cleanup EXIT - -{ - echo "Timestamp: $(date --iso-8601=seconds)" - echo "Runner: ${RUNNER_NAME:-unknown}" - echo "Runner OS: ${RUNNER_OS:-unknown}" - echo "Runner architecture: ${RUNNER_ARCH:-unknown}" - echo "GitHub run: $run_id" - echo "GitHub attempt: $run_attempt" - echo "User: $(id)" - echo "Kernel: $(uname -a)" -} | tee "$log_dir/environment.txt" - -lscpu | tee "$log_dir/lscpu.txt" -free -h | tee "$log_dir/memory.txt" -df -hT | tee "$log_dir/filesystems.txt" -ls -l /dev/kvm /run/libvirt/libvirt-sock | tee "$log_dir/device-permissions.txt" -getfacl -p /dev/kvm /run/libvirt/libvirt-sock | tee "$log_dir/device-acls.txt" - -if [[ ! -c /dev/kvm ]]; then - echo "/dev/kvm is not a character device" >&2 - exit 1 -fi - -if [[ -r /sys/module/kvm_intel/parameters/nested ]]; then - nested_parameter="/sys/module/kvm_intel/parameters/nested" -elif [[ -r /sys/module/kvm_amd/parameters/nested ]]; then - nested_parameter="/sys/module/kvm_amd/parameters/nested" -else - echo "No nested virtualization module parameter found" | - tee "$log_dir/nested-virtualization.txt" >&2 - exit 1 -fi - -nested_value="$(cat "$nested_parameter")" -printf '%s\n' "$nested_value" | tee "$log_dir/nested-virtualization.txt" -case "$nested_value" in - 1 | Y | y) ;; - *) - echo "Nested virtualization is not enabled: $nested_value" >&2 - exit 1 - ;; -esac - -qemu_bin="$(command -v qemu-system-x86_64)" -"$qemu_bin" --version | tee "$log_dir/qemu-version.txt" -virsh --connect "$qemu_connection" version | tee "$log_dir/virsh-version.txt" -virsh --connect "$qemu_connection" nodeinfo | tee "$log_dir/libvirt-nodeinfo.txt" - -set +e -virt-host-validate qemu 2>&1 | tee "$log_dir/virt-host-validate.txt" -virt_validate_status=${PIPESTATUS[0]} -set -e -echo "$virt_validate_status" > "$log_dir/virt-host-validate.exit-code" -if [[ $virt_validate_status -ne 0 ]]; then - echo "virt-host-validate returned $virt_validate_status; direct QEMU and libvirt probes determine the result" >&2 -fi - -cat > "$domain_xml" < - ${domain_name} - 256 - 256 - 1 - - hvm - - - - - - - - destroy - destroy - destroy - - ${qemu_bin} - - - - -EOF - -virsh --connect "$qemu_connection" create --paused "$domain_xml" -virsh --connect "$qemu_connection" dominfo "$domain_name" | tee "$log_dir/domain-info.txt" -virsh --connect "$qemu_connection" destroy "$domain_name" - -if virsh --connect "$qemu_connection" dominfo "$domain_name" >/dev/null 2>&1; then - echo "Transient smoke domain still exists after destroy" >&2 - exit 1 -fi - -cat > "$log_dir/result.txt" <