From a734a3374c47c77136cfbdf0351bab9e4739a6b9 Mon Sep 17 00:00:00 2001 From: David Engel Date: Tue, 21 Jul 2026 20:41:14 +0000 Subject: [PATCH 1/9] Retarget x64 CI to the NVMe 1ES pool and images Switch every x64 Windows/Linux job in the Rust CI pipelines from the RUST-1ES-POOL-WUS3 pool (RUST-1ES-UBUSLIM / RUST-Win22-Sql25-1P images) to the NVMe-capable RUST-1ES-POOL-WUS3-NVME pool and the RUST-1ES-UBUSLIM-NVME / RUST-Win22-Sql25-1P-NVME images. The old pool and images are being retired, so the NVMe pool becomes the default everywhere rather than an opt-in override. DRY refactor for the two files with many references: - validation-stages.yml: adds poolName / linuxImage / windowsImage parameters (NVMe defaults) as a single source of truth; every inline x64 pool block now references them. - sync-container-images.yml: adds poolName / imageName pipeline variables; every job pool block now references them. All other pipelines (OneBranch build, benchmark, sync-github-main-to-stable) and the shared templates (sql-host, kerberos, test-matrix, test-matrix-alpine, private-link) are renamed directly to the NVMe names. ARM jobs (RUST-1ES-POOL-ARM-WUS3, RUST-UBUNTU-ARM64, RUST-WINSRV-ARM) are unchanged - no NVMe ARM images exist. --- .pipeline/OneBranch/stages.yml | 8 +-- .pipeline/benchmark-pipeline.yml | 4 +- .pipeline/docs/arm-sql-host-design.md | 4 +- .pipeline/sync-container-images.yml | 48 ++++++++++-------- .pipeline/sync-github-main-to-stable.yml | 4 +- .../templates/kerberos-test-template.yml | 4 +- .../templates/private-link-smoke-template.yml | 4 +- .pipeline/templates/sql-host-template.yml | 4 +- .../templates/test-matrix-template-alpine.yml | 4 +- .pipeline/templates/test-matrix-template.yml | 4 +- .pipeline/templates/validation-stages.yml | 50 ++++++++++++------- mssql-tds-bench/perf-lab/run-benchmarks.ps1 | 2 +- 12 files changed, 79 insertions(+), 61 deletions(-) diff --git a/.pipeline/OneBranch/stages.yml b/.pipeline/OneBranch/stages.yml index 1064f8a6..657b2427 100644 --- a/.pipeline/OneBranch/stages.yml +++ b/.pipeline/OneBranch/stages.yml @@ -48,9 +48,9 @@ stages: pool: type: windows isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-Win22-Sql25-1P + - imageOverride -equals RUST-Win22-Sql25-1P-NVME variables: - ${{ if eq(parameters.isOfficial, true) }}: - group: 'ESRP Federated Creds (AME)' @@ -148,9 +148,9 @@ stages: pool: type: linux isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' ob_artifactSuffix: '_linux_x64' diff --git a/.pipeline/benchmark-pipeline.yml b/.pipeline/benchmark-pipeline.yml index 84b3962c..4067ccaa 100644 --- a/.pipeline/benchmark-pipeline.yml +++ b/.pipeline/benchmark-pipeline.yml @@ -25,9 +25,9 @@ stages: displayName: 'Criterion Benchmark' timeoutInMinutes: 30 pool: - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' diff --git a/.pipeline/docs/arm-sql-host-design.md b/.pipeline/docs/arm-sql-host-design.md index 3da3ed0a..921d7c1f 100644 --- a/.pipeline/docs/arm-sql-host-design.md +++ b/.pipeline/docs/arm-sql-host-design.md @@ -341,7 +341,7 @@ unchanged. ## Open assumptions -- Cross-pool reachability between `RUST-1ES-POOL-WUS3` (x64) and +- Cross-pool reachability between `RUST-1ES-POOL-WUS3-NVME` (x64) and `RUST-1ES-POOL-ARM-WUS3` (ARM) on the SQL host's private IPv4 and the published port. Confirmed at design time; a connectivity regression here would surface as `poll-for-endpoint.sh` succeeds (the test job sees the @@ -349,7 +349,7 @@ unchanged. - `mcr.microsoft.com/mssql/server:` ships `/opt/mssql-tools18/bin/sqlcmd`, which `start.sh` uses for the readiness probe. The current default tag (`2025-latest`) does. -- The ubuntu image used by the x64 SQL host (`RUST-1ES-UBUSLIM`) provides +- The ubuntu image used by the x64 SQL host (`RUST-1ES-UBUSLIM-NVME`) provides `curl` and `docker`. The latter is enforced by `DockerInstaller@0` and `install-ubuntu-dependency.yaml`; the former is standard in the image. - Both ARM and x64 1ES pool agents have `python3` available (used by diff --git a/.pipeline/sync-container-images.yml b/.pipeline/sync-container-images.yml index de87e8eb..23da15c0 100644 --- a/.pipeline/sync-container-images.yml +++ b/.pipeline/sync-container-images.yml @@ -126,6 +126,10 @@ variables: ACR_REGISTRY: 'tdslibrs.azurecr.io' GHCR_REGISTRY: 'ghcr.io' GHCR_NAMESPACE: 'ghcr.io/${{ parameters.ghcrOrg }}' + # 1ES pool + Linux image used by every job in this pipeline. Single source of + # truth: change these two lines to retarget the whole pipeline. + poolName: 'RUST-1ES-POOL-WUS3-NVME' + imageName: 'RUST-1ES-UBUSLIM-NVME' # ============================================================================= # STAGE 1 (Import): Sync base images from public registries (incl. Docker Hub) to ACR @@ -147,9 +151,9 @@ stages: displayName: 'Import manylinux x64 & arm64' condition: eq('${{ parameters.syncManylinux }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -210,9 +214,9 @@ stages: displayName: 'Import musllinux x64 & arm64' condition: eq('${{ parameters.syncMusllinux }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -247,9 +251,9 @@ stages: displayName: 'Import Ubuntu 22.04 & 24.04' condition: eq('${{ parameters.syncUbuntu }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -306,9 +310,9 @@ stages: displayName: 'Import Alpine 3.18 & 3.19' condition: eq('${{ parameters.syncAlpine1 }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -365,9 +369,9 @@ stages: displayName: 'Import Alpine 3.20 & 3.21' condition: eq('${{ parameters.syncAlpine2 }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -483,9 +487,9 @@ stages: displayName: 'Import Debian & RHEL UBI' condition: eq('${{ parameters.syncDebianRHEL }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -629,9 +633,9 @@ stages: displayName: 'Import Oracle Linux 9' condition: eq('${{ parameters.syncOracle }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -735,9 +739,9 @@ stages: displayName: Build x64 Images condition: or(eq('${{ parameters.buildPythonImages }}', 'true'), eq('${{ parameters.buildUbuntuImages }}', 'true')) pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: self displayName: Checkout repository @@ -1071,9 +1075,9 @@ stages: - BuildARM64Images condition: eq('${{ parameters.buildUbuntuImages }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none @@ -1132,9 +1136,9 @@ stages: - CreateMultiArchManifests condition: always() pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none @@ -1268,9 +1272,9 @@ stages: displayName: 'Mirror ACR -> GHCR' timeoutInMinutes: 60 pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none diff --git a/.pipeline/sync-github-main-to-stable.yml b/.pipeline/sync-github-main-to-stable.yml index f37ebd50..0ae06a79 100644 --- a/.pipeline/sync-github-main-to-stable.yml +++ b/.pipeline/sync-github-main-to-stable.yml @@ -35,9 +35,9 @@ resources: ref: refs/heads/stable pool: - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME steps: # GitHub main (self): the source we are syncing from. diff --git a/.pipeline/templates/kerberos-test-template.yml b/.pipeline/templates/kerberos-test-template.yml index 235cd837..8b51fae6 100644 --- a/.pipeline/templates/kerberos-test-template.yml +++ b/.pipeline/templates/kerberos-test-template.yml @@ -33,10 +33,10 @@ parameters: - alpine318 - name: poolName type: string - default: 'RUST-1ES-POOL-WUS3' + default: 'RUST-1ES-POOL-WUS3-NVME' - name: poolImageOverride type: string - default: 'imageOverride -equals RUST-1ES-UBUSLIM' + default: 'imageOverride -equals RUST-1ES-UBUSLIM-NVME' - name: testTimeout type: number default: 60 diff --git a/.pipeline/templates/private-link-smoke-template.yml b/.pipeline/templates/private-link-smoke-template.yml index a3b78b9e..d92b41e5 100644 --- a/.pipeline/templates/private-link-smoke-template.yml +++ b/.pipeline/templates/private-link-smoke-template.yml @@ -70,9 +70,9 @@ jobs: - job: PrivateLink_Smoke displayName: Private Link Smoke Test (ACI) pool: - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME timeoutInMinutes: 30 steps: # --- Login --- diff --git a/.pipeline/templates/sql-host-template.yml b/.pipeline/templates/sql-host-template.yml index af73333c..be2ed4fb 100644 --- a/.pipeline/templates/sql-host-template.yml +++ b/.pipeline/templates/sql-host-template.yml @@ -51,10 +51,10 @@ parameters: default: 120 - name: poolName type: string - default: 'RUST-1ES-POOL-WUS3' + default: 'RUST-1ES-POOL-WUS3-NVME' - name: poolImageOverride type: string - default: 'imageOverride -equals RUST-1ES-UBUSLIM' + default: 'imageOverride -equals RUST-1ES-UBUSLIM-NVME' - name: jobCondition # Job-level condition. Defaults to succeeded(); callers that only need the # SQL host on PRs (e.g. the Build stage) pass a Build.Reason check. diff --git a/.pipeline/templates/test-matrix-template-alpine.yml b/.pipeline/templates/test-matrix-template-alpine.yml index af546ee6..f74041b2 100644 --- a/.pipeline/templates/test-matrix-template-alpine.yml +++ b/.pipeline/templates/test-matrix-template-alpine.yml @@ -2,8 +2,8 @@ parameters: matrix: {} artifactName: 'Build_Linux' - poolName: 'RUST-1ES-POOL-WUS3' - poolImageOverride: 'imageOverride -equals RUST-1ES-UBUSLIM' + poolName: 'RUST-1ES-POOL-WUS3-NVME' + poolImageOverride: 'imageOverride -equals RUST-1ES-UBUSLIM-NVME' jobs: - job: Test_Matrix diff --git a/.pipeline/templates/test-matrix-template.yml b/.pipeline/templates/test-matrix-template.yml index 5d88bc19..494f7cb5 100644 --- a/.pipeline/templates/test-matrix-template.yml +++ b/.pipeline/templates/test-matrix-template.yml @@ -8,9 +8,9 @@ jobs: strategy: matrix: ${{ parameters.matrix }} pool: - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME steps: - template: generate-sql-password-template.yml parameters: diff --git a/.pipeline/templates/validation-stages.yml b/.pipeline/templates/validation-stages.yml index baaa663f..bd5f7d9f 100644 --- a/.pipeline/templates/validation-stages.yml +++ b/.pipeline/templates/validation-stages.yml @@ -39,6 +39,20 @@ parameters: type: string default: '2025-latest' +# 1ES pool + image overrides for the x64 Windows/Linux jobs. Single source of +# truth: change these defaults to retarget every x64 job in this pipeline. +- name: poolName + type: string + default: RUST-1ES-POOL-WUS3-NVME + +- name: linuxImage + type: string + default: RUST-1ES-UBUSLIM-NVME + +- name: windowsImage + type: string + default: RUST-Win22-Sql25-1P-NVME + stages: - stage: EvaluateDuplicate displayName: Evaluate PR duplicate @@ -47,9 +61,9 @@ stages: - job: Evaluate displayName: Check prior successful PR validation pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} steps: - bash: | set -euo pipefail @@ -88,9 +102,9 @@ stages: - job: Build_Windows displayName: Build Windows pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-Win22-Sql25-1P + - imageOverride -equals ${{ parameters.windowsImage }} variables: # For details on this CARGO_TARGET_DIR setting, see https://eng.ms/docs/more/rust/topics/onebranch-workaround CARGO_TARGET_DIR: C:\cargo_target_dir @@ -215,9 +229,9 @@ stages: - job: Build_Linux displayName: Build Linux pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' @@ -413,9 +427,9 @@ stages: - job: Fuzz_TokenStream_Linux displayName: Fuzz Test Token Stream Linux (30 min) pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) steps: @@ -434,9 +448,9 @@ stages: - job: Fuzz_TdsClient_Linux displayName: Fuzz Test TdsClient Linux (30 min) pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) steps: @@ -455,9 +469,9 @@ stages: - job: Fuzz_Additional_Targets_Linux displayName: Fuzz Additional Targets Linux (Serial - 5 min each) pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) steps: @@ -507,9 +521,9 @@ stages: - job: Build_mssql_python_Linux displayName: Build mssql-python (cross-repo) pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) steps: @@ -895,9 +909,9 @@ stages: - job: Merge_Coverage displayName: Merge Rust and Python coverage pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} steps: - checkout: self - task: DownloadPipelineArtifact@2 @@ -1016,9 +1030,9 @@ stages: - job: LongHaul_BCP_Test displayName: Long-Haul BCP Test Ubuntu pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) steps: diff --git a/mssql-tds-bench/perf-lab/run-benchmarks.ps1 b/mssql-tds-bench/perf-lab/run-benchmarks.ps1 index 65b93ca6..c7649599 100644 --- a/mssql-tds-bench/perf-lab/run-benchmarks.ps1 +++ b/mssql-tds-bench/perf-lab/run-benchmarks.ps1 @@ -235,7 +235,7 @@ if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { } # --- git (needed for the baseline worktree) --- -# The Windows Server perf image (RUST-Win22-Sql25-1P) normally ships git, but +# The Windows Server perf image (RUST-Win22-Sql25-1P-NVME) normally ships git, but # install it if absent: winget first, then Chocolatey as a fallback. if (-not (Get-Command git -ErrorAction SilentlyContinue)) { Write-Host '>>> git not found; installing...' From bfc2c7e732ca83af4a0720f1c6636e13ffbff1c8 Mon Sep 17 00:00:00 2001 From: David Engel Date: Tue, 21 Jul 2026 23:17:27 +0000 Subject: [PATCH 2/9] TEMP: hijack PR validation to print agent disk info only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Temporarily reduces .pipeline/validation-pipeline.yml (the PR validation entry, def "mssql-rs Pull request validation") to a single DiskInfo stage with a Linux and a Windows job that print disk hardware/layout and exit — no build/test — to confirm the NVMe disk topology cheaply. Also enriches the reusable diagnostics for when full validation is restored: - print-disk-info.sh: lsblk TRAN/ROTA, /dev/nvme*, per-mount transport. - PrintAgentDebugInfo.ps1: Get-PhysicalDisk BusType, Get-Disk, Get-Volume. - validation-stages.yml Build_Linux: run print-disk-info.sh. REVERT: restore the validation-stages.yml template call in validation-pipeline.yml (kept commented at the bottom) and drop the DiskInfo stage. --- .pipeline/scripts/PrintAgentDebugInfo.ps1 | 23 +++++++ .pipeline/scripts/print-disk-info.sh | 28 +++++++++ .pipeline/templates/validation-stages.yml | 3 + .pipeline/validation-pipeline.yml | 76 ++++++++++++++++++++--- 4 files changed, 120 insertions(+), 10 deletions(-) diff --git a/.pipeline/scripts/PrintAgentDebugInfo.ps1 b/.pipeline/scripts/PrintAgentDebugInfo.ps1 index 22546c1e..1f9907e0 100644 --- a/.pipeline/scripts/PrintAgentDebugInfo.ps1 +++ b/.pipeline/scripts/PrintAgentDebugInfo.ps1 @@ -17,3 +17,26 @@ if (Test-Path $pythonDir) { } else { Write-Host "Directory $pythonDir does NOT exist" } + +Write-Host "" +Write-Host "=== Physical Disks (BusType shows NVMe / SATA / SAS) ===" +try { + Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, MediaType, BusType, + @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}} | + Format-Table -AutoSize | Out-String | Write-Host +} catch { Write-Host "Get-PhysicalDisk failed: $_" } + +Write-Host "=== Disks ===" +try { + Get-Disk | Select-Object Number, FriendlyName, BusType, + @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}, PartitionStyle, OperationalStatus | + Format-Table -AutoSize | Out-String | Write-Host +} catch { Write-Host "Get-Disk failed: $_" } + +Write-Host "=== Volumes (drive letters + free space) ===" +try { + Get-Volume | Where-Object DriveLetter | Select-Object DriveLetter, FileSystemLabel, FileSystem, + @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}, + @{N='FreeGB';E={[math]::Round($_.SizeRemaining/1GB,1)}} | + Format-Table -AutoSize | Out-String | Write-Host +} catch { Write-Host "Get-Volume failed: $_" } diff --git a/.pipeline/scripts/print-disk-info.sh b/.pipeline/scripts/print-disk-info.sh index f0599584..f24f7569 100755 --- a/.pipeline/scripts/print-disk-info.sh +++ b/.pipeline/scripts/print-disk-info.sh @@ -4,6 +4,34 @@ echo "=== Disk Space - All Mount Points ===" df -h +echo "" +echo "=== Block Devices (TYPE / TRAN=transport / ROTA=1 spinning,0 SSD) ===" +# TRAN column shows 'nvme' for NVMe-attached devices; ROTA=0 confirms SSD/NVMe. +lsblk -o NAME,SIZE,TYPE,TRAN,ROTA,FSTYPE,MOUNTPOINT,MODEL 2>/dev/null || lsblk + +echo "" +echo "=== NVMe devices present ===" +if ls /dev/nvme* >/dev/null 2>&1; then + ls -l /dev/nvme* + command -v nvme >/dev/null 2>&1 && nvme list 2>/dev/null || true +else + echo "No /dev/nvme* devices found (agent is NOT on NVMe)." +fi + +echo "" +echo "=== Backing device + transport for key mount points ===" +for m in / /mnt /mnt/vss /mnt/azure_nvme_temp "${AGENT_WORKFOLDER:-/mnt/vss/_work}"; do + [ -e "$m" ] || continue + src=$(findmnt -no SOURCE --target "$m" 2>/dev/null) + fstype=$(findmnt -no FSTYPE --target "$m" 2>/dev/null) + # Resolve the parent block device and read its transport from sysfs. + dev=$(lsblk -no PKNAME "$src" 2>/dev/null | head -1) + [ -z "$dev" ] && dev=$(basename "$src" 2>/dev/null) + tran=$(cat "/sys/class/block/$dev/device/../transport" 2>/dev/null) + case "$src" in *nvme*) tran="${tran:-nvme}";; esac + echo "$m -> ${src:-?} (${fstype:-?}) transport=${tran:-unknown}" +done + echo "" echo "=== Agent Work Folder Disk Space ===" WORK_DIR="${AGENT_WORKFOLDER:-/mnt/vss/_work}" diff --git a/.pipeline/templates/validation-stages.yml b/.pipeline/templates/validation-stages.yml index bd5f7d9f..0a5a2866 100644 --- a/.pipeline/templates/validation-stages.yml +++ b/.pipeline/templates/validation-stages.yml @@ -236,6 +236,9 @@ stages: CARGO_TARGET_DIR: $(Build.SourcesDirectory) ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' steps: + - script: | + .pipeline/scripts/print-disk-info.sh + displayName: 'Print agent disk info' - template: cargo-authenticate-template.yml parameters: osType: Linux diff --git a/.pipeline/validation-pipeline.yml b/.pipeline/validation-pipeline.yml index e768217a..c966593d 100644 --- a/.pipeline/validation-pipeline.yml +++ b/.pipeline/validation-pipeline.yml @@ -36,14 +36,70 @@ parameters: type: string default: '2025-latest' +# ============================================================================ +# TEMPORARY HIJACK: PR validation is reduced to ONLY printing agent disk info +# (Windows + Linux) and exiting, to confirm the NVMe disk layout without burning +# compute on the full build/test matrix. +# TO REVERT: delete the DiskInfo stage below and un-comment the original +# `- template: templates/validation-stages.yml` block at the bottom of this file. +# ============================================================================ stages: -- template: templates/validation-stages.yml - parameters: - buildType: ${{ parameters.buildType }} - RunFuzz: ${{ parameters.RunFuzz }} - RunLongHaul: ${{ parameters.RunLongHaul }} - sqlInstanceMode: ${{ parameters.sqlInstanceMode }} - sqlImageTag: ${{ parameters.sqlImageTag }} - # PR validation for internal ADO and GitHub PRs. GitHub PRs run in the public - # project, which lacks 'Magnitude Test', so exclude the infra stages here. - includeInfraStages: false \ No newline at end of file +- stage: DiskInfo + displayName: Agent disk info (validation temporarily hijacked) + jobs: + - job: DiskInfo_Linux + displayName: Disk info (Linux) + pool: + name: RUST-1ES-POOL-WUS3-NVME + demands: + - imageOverride -equals RUST-1ES-UBUSLIM-NVME + steps: + - checkout: none + - bash: | + set -x + echo "===== LINUX AGENT DISK INFO =====" + uname -a + df -h + echo "--- Block devices (TRAN=nvme + ROTA=0 => NVMe SSD) ---" + lsblk -o NAME,SIZE,TYPE,TRAN,ROTA,FSTYPE,MOUNTPOINT,MODEL || lsblk + echo "--- NVMe devices ---" + ls -l /dev/nvme* 2>/dev/null || echo "no /dev/nvme* devices" + command -v nvme >/dev/null 2>&1 && nvme list 2>/dev/null || true + echo "--- Backing device + transport for key mounts ---" + for m in / /mnt /mnt/vss /mnt/azure_nvme_temp "${AGENT_WORKFOLDER:-/mnt/vss/_work}"; do + [ -e "$m" ] || continue + echo "$m -> $(findmnt -no SOURCE,FSTYPE --target "$m" 2>/dev/null)" + done + displayName: Print Linux disk info + - job: DiskInfo_Windows + displayName: Disk info (Windows) + pool: + name: RUST-1ES-POOL-WUS3-NVME + demands: + - imageOverride -equals RUST-Win22-Sql25-1P-NVME + steps: + - checkout: none + - powershell: | + Write-Host "===== WINDOWS AGENT DISK INFO =====" + Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version | Format-List | Out-String | Write-Host + Write-Host "--- Physical disks (BusType = NVMe / SATA / SAS) ---" + Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, MediaType, BusType, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}} | Format-Table -AutoSize | Out-String | Write-Host + Write-Host "--- Disks ---" + Get-Disk | Select-Object Number, FriendlyName, BusType, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}, PartitionStyle | Format-Table -AutoSize | Out-String | Write-Host + Write-Host "--- Volumes (drive letters + free space) ---" + Get-Volume | Where-Object DriveLetter | Select-Object DriveLetter, FileSystem, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}, @{N='FreeGB';E={[math]::Round($_.SizeRemaining/1GB,1)}} | Format-Table -AutoSize | Out-String | Write-Host + Write-Host "--- Agent work folder ---" + Write-Host "AGENT_WORKFOLDER=$env:AGENT_WORKFOLDER BUILD_SOURCESDIRECTORY=$env:BUILD_SOURCESDIRECTORY" + displayName: Print Windows disk info + +# ORIGINAL PR validation (restore this and delete the DiskInfo stage above to re-enable): +# - template: templates/validation-stages.yml +# parameters: +# buildType: ${{ parameters.buildType }} +# RunFuzz: ${{ parameters.RunFuzz }} +# RunLongHaul: ${{ parameters.RunLongHaul }} +# sqlInstanceMode: ${{ parameters.sqlInstanceMode }} +# sqlImageTag: ${{ parameters.sqlImageTag }} +# # PR validation for internal ADO and GitHub PRs. GitHub PRs run in the public +# # project, which lacks 'Magnitude Test', so exclude the infra stages here. +# includeInfraStages: false \ No newline at end of file From 93ed15c02e537235b365490e0b38dc6ef526ff52 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 22 Jul 2026 17:22:04 +0000 Subject: [PATCH 3/9] ci: re-run disk-info validation to verify 200 GB NVMe root on rebuilt images From 557dbccdc582f0f2a26bfc8667c87ceab69c4d05 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 22 Jul 2026 17:36:26 +0000 Subject: [PATCH 4/9] ci: un-hijack PR validation (restore full validation matrix) Disk fix verified on rebuilt images (Linux root 194G / Windows C: 200G, both local NVMe). Restore the full validation-stages.yml matrix. The reusable disk diagnostics (print-disk-info.sh, PrintAgentDebugInfo.ps1, Build_Linux disk step) are kept. --- .pipeline/validation-pipeline.yml | 76 ++++--------------------------- 1 file changed, 10 insertions(+), 66 deletions(-) diff --git a/.pipeline/validation-pipeline.yml b/.pipeline/validation-pipeline.yml index c966593d..e768217a 100644 --- a/.pipeline/validation-pipeline.yml +++ b/.pipeline/validation-pipeline.yml @@ -36,70 +36,14 @@ parameters: type: string default: '2025-latest' -# ============================================================================ -# TEMPORARY HIJACK: PR validation is reduced to ONLY printing agent disk info -# (Windows + Linux) and exiting, to confirm the NVMe disk layout without burning -# compute on the full build/test matrix. -# TO REVERT: delete the DiskInfo stage below and un-comment the original -# `- template: templates/validation-stages.yml` block at the bottom of this file. -# ============================================================================ stages: -- stage: DiskInfo - displayName: Agent disk info (validation temporarily hijacked) - jobs: - - job: DiskInfo_Linux - displayName: Disk info (Linux) - pool: - name: RUST-1ES-POOL-WUS3-NVME - demands: - - imageOverride -equals RUST-1ES-UBUSLIM-NVME - steps: - - checkout: none - - bash: | - set -x - echo "===== LINUX AGENT DISK INFO =====" - uname -a - df -h - echo "--- Block devices (TRAN=nvme + ROTA=0 => NVMe SSD) ---" - lsblk -o NAME,SIZE,TYPE,TRAN,ROTA,FSTYPE,MOUNTPOINT,MODEL || lsblk - echo "--- NVMe devices ---" - ls -l /dev/nvme* 2>/dev/null || echo "no /dev/nvme* devices" - command -v nvme >/dev/null 2>&1 && nvme list 2>/dev/null || true - echo "--- Backing device + transport for key mounts ---" - for m in / /mnt /mnt/vss /mnt/azure_nvme_temp "${AGENT_WORKFOLDER:-/mnt/vss/_work}"; do - [ -e "$m" ] || continue - echo "$m -> $(findmnt -no SOURCE,FSTYPE --target "$m" 2>/dev/null)" - done - displayName: Print Linux disk info - - job: DiskInfo_Windows - displayName: Disk info (Windows) - pool: - name: RUST-1ES-POOL-WUS3-NVME - demands: - - imageOverride -equals RUST-Win22-Sql25-1P-NVME - steps: - - checkout: none - - powershell: | - Write-Host "===== WINDOWS AGENT DISK INFO =====" - Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version | Format-List | Out-String | Write-Host - Write-Host "--- Physical disks (BusType = NVMe / SATA / SAS) ---" - Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, MediaType, BusType, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}} | Format-Table -AutoSize | Out-String | Write-Host - Write-Host "--- Disks ---" - Get-Disk | Select-Object Number, FriendlyName, BusType, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}, PartitionStyle | Format-Table -AutoSize | Out-String | Write-Host - Write-Host "--- Volumes (drive letters + free space) ---" - Get-Volume | Where-Object DriveLetter | Select-Object DriveLetter, FileSystem, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}, @{N='FreeGB';E={[math]::Round($_.SizeRemaining/1GB,1)}} | Format-Table -AutoSize | Out-String | Write-Host - Write-Host "--- Agent work folder ---" - Write-Host "AGENT_WORKFOLDER=$env:AGENT_WORKFOLDER BUILD_SOURCESDIRECTORY=$env:BUILD_SOURCESDIRECTORY" - displayName: Print Windows disk info - -# ORIGINAL PR validation (restore this and delete the DiskInfo stage above to re-enable): -# - template: templates/validation-stages.yml -# parameters: -# buildType: ${{ parameters.buildType }} -# RunFuzz: ${{ parameters.RunFuzz }} -# RunLongHaul: ${{ parameters.RunLongHaul }} -# sqlInstanceMode: ${{ parameters.sqlInstanceMode }} -# sqlImageTag: ${{ parameters.sqlImageTag }} -# # PR validation for internal ADO and GitHub PRs. GitHub PRs run in the public -# # project, which lacks 'Magnitude Test', so exclude the infra stages here. -# includeInfraStages: false \ No newline at end of file +- template: templates/validation-stages.yml + parameters: + buildType: ${{ parameters.buildType }} + RunFuzz: ${{ parameters.RunFuzz }} + RunLongHaul: ${{ parameters.RunLongHaul }} + sqlInstanceMode: ${{ parameters.sqlInstanceMode }} + sqlImageTag: ${{ parameters.sqlImageTag }} + # PR validation for internal ADO and GitHub PRs. GitHub PRs run in the public + # project, which lacks 'Magnitude Test', so exclude the infra stages here. + includeInfraStages: false \ No newline at end of file From 57a9b68ef38d2b81e84ed0210822bcfb64564827 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 22 Jul 2026 18:44:43 +0000 Subject: [PATCH 5/9] ci: ensure SQLDEV instance is started before configuring its sa login The SSRP named-instance test (test_ssrp_named_instance_resolution) connects to HOST\SQLDEV as sa. sql-setup-template.yml only configured SQLDEV's sa password when the MSSQL$SQLDEV service was already Running, and silently skipped otherwise. On freshly-built images the service can be stopped / manual-start at setup time, so sa was never set and the test failed with 'Login failed for user sa'. Now set the service to Automatic, start it, and wait for Running before configuring, instead of skipping. --- .pipeline/templates/sql-setup-template.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.pipeline/templates/sql-setup-template.yml b/.pipeline/templates/sql-setup-template.yml index acaec9c9..33ce45f2 100644 --- a/.pipeline/templates/sql-setup-template.yml +++ b/.pipeline/templates/sql-setup-template.yml @@ -36,8 +36,23 @@ steps: sqlcmd -Q "ALTER SERVER ROLE sysadmin ADD MEMBER testuser;" sqlcmd -S localhost,1433 -U sa -P $(SQL_PASSWORD) -Q "SELECT @@VERSION" - # Setup the same logins on the SQLDEV named instance (used by SSRP tests) + # Setup the same logins on the SQLDEV named instance (used by SSRP tests). + # Freshly-built images can leave the SQLDEV service stopped / manual-start, + # so ensure it is set to start automatically and is actually running before + # we configure its sa login. Previously this block was skipped whenever the + # service wasn't already running, which left sa unconfigured and broke the + # SSRP named-instance test (login failed for user 'sa' on HOST\SQLDEV). $svc = Get-Service -Name 'MSSQL$SQLDEV' -ErrorAction SilentlyContinue + if ($svc) { + echo "Ensuring SQLDEV instance is running..." + Set-Service -Name 'MSSQL$SQLDEV' -StartupType Automatic -ErrorAction SilentlyContinue + Start-Service -Name 'MSSQL$SQLDEV' -ErrorAction SilentlyContinue + for ($i = 1; $i -le 12; $i++) { + $svc.Refresh() + if ($svc.Status -eq 'Running') { break } + Start-Sleep -Seconds 5 + } + } if ($svc -and $svc.Status -eq 'Running') { echo "Configuring logins on SQLDEV instance..." sqlcmd -S "localhost\SQLDEV" -C -Q "EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'LoginMode', REG_DWORD, 2" From c4abeba7bacad8abae6fc835b16131bb28f63306 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 22 Jul 2026 18:58:25 +0000 Subject: [PATCH 6/9] ci: make SQL cert-step service restart robust on fresh images Generate-SqlCertificates.ps1 used a bare Restart-Service, which fails intermittently on freshly-provisioned ephemeral NVMe images with 'cannot be stopped' (CouldNotStopService) because SQL Server is still in startup/recovery. Wait for a steady state, then stop/start with retries via Restart-SqlServiceSafely. --- .../scripts/Generate-SqlCertificates.ps1 | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/.pipeline/scripts/Generate-SqlCertificates.ps1 b/.pipeline/scripts/Generate-SqlCertificates.ps1 index 812deed6..d6809b60 100644 --- a/.pipeline/scripts/Generate-SqlCertificates.ps1 +++ b/.pipeline/scripts/Generate-SqlCertificates.ps1 @@ -23,6 +23,39 @@ function Copy-To-Root-Store($cert) { } } +function Restart-SqlServiceSafely($serviceName) { + # Freshly-provisioned images can leave SQL Server briefly in a start-pending / + # not-yet-stoppable state (startup database recovery), which makes a plain + # Restart-Service fail intermittently with "cannot be stopped" + # (CouldNotStopService). Wait for a steady state, then stop/start with retries. + $svc = Get-Service -Name $serviceName -ErrorAction Stop + + for ($i = 1; $i -le 30; $i++) { + $svc.Refresh() + if ($svc.Status -eq 'Running' -or $svc.Status -eq 'Stopped') { break } + Write-Host "Waiting for $serviceName to reach a steady state (current: $($svc.Status))..." + Start-Sleep -Seconds 5 + } + + for ($attempt = 1; $attempt -le 5; $attempt++) { + try { + $svc.Refresh() + if ($svc.Status -ne 'Stopped') { + Stop-Service -Name $serviceName -Force -ErrorAction Stop + $svc.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(120)) + } + Start-Service -Name $serviceName -ErrorAction Stop + $svc.WaitForStatus('Running', [TimeSpan]::FromSeconds(120)) + Write-Host "SQL service '$serviceName' restarted (attempt $attempt)." + return + } catch { + Write-Host "Restart attempt $attempt for '$serviceName' failed: $($_.Exception.Message)" + Start-Sleep -Seconds 10 + } + } + throw "Failed to restart SQL service '$serviceName' after multiple attempts." +} + function New-And-Install-Certificates($instanceName) { Write-Output "Instance name received is " + $instanceName $certStorePath = "Cert:\LocalMachine\My" @@ -70,7 +103,7 @@ function New-And-Install-Certificates($instanceName) { Set-ItemProperty -Path $registryPath -Name "Certificate" -Value $thumbprint - Restart-Service -Name "MSSQLSERVER" + Restart-SqlServiceSafely -serviceName $instanceName Copy-To-Root-Store -cert $cert } From 852c20f4f526c059449be26105d48bf42bfe47b5 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 22 Jul 2026 22:23:29 +0000 Subject: [PATCH 7/9] ci: re-run validation to re-measure Windows build timing From 748d0ad222b4d5a2c24879a3641047e7b879f1f6 Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 7 Aug 2026 18:33:00 +0000 Subject: [PATCH 8/9] ci: retarget pool references added to main since the branch was cut Rebase onto main picked up new jobs still pointing at the old x64 pool: ODBC e2e Linux matrix, Long-Haul BCP Arrow, four sync-container-images import jobs, and the new OneBranch PublishFeeds-Sandbox pipeline. Each now follows its file's existing convention (variables/parameters where defined, literal -NVME names otherwise). --- .pipeline/OneBranch/PublishFeeds-Sandbox.yml | 24 +++++++++---------- .pipeline/sync-container-images.yml | 16 ++++++------- .../odbc-e2e-windows-remote-sql-template.yml | 2 +- .../templates/test-matrix-odbc-template.yml | 4 ++-- .pipeline/templates/validation-stages.yml | 4 ++-- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.pipeline/OneBranch/PublishFeeds-Sandbox.yml b/.pipeline/OneBranch/PublishFeeds-Sandbox.yml index 0b08eea1..5363a9b0 100644 --- a/.pipeline/OneBranch/PublishFeeds-Sandbox.yml +++ b/.pipeline/OneBranch/PublishFeeds-Sandbox.yml @@ -110,9 +110,9 @@ extends: pool: type: windows isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-Win22-Sql25-1P + - imageOverride -equals RUST-Win22-Sql25-1P-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' steps: @@ -144,9 +144,9 @@ extends: pool: type: linux isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' ob_artifactSuffix: '_mock_linux_x64' @@ -248,9 +248,9 @@ extends: pool: type: linux isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' ob_artifactSuffix: '_mock_linux_musl_x64' @@ -353,9 +353,9 @@ extends: pool: type: windows isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-Win22-Sql25-1P + - imageOverride -equals RUST-Win22-Sql25-1P-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' ob_artifactSuffix: '_mock_windows_x64' @@ -522,9 +522,9 @@ extends: pool: type: windows isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-Win22-Sql25-1P + - imageOverride -equals RUST-Win22-Sql25-1P-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' steps: @@ -576,9 +576,9 @@ extends: pool: type: windows isCustom: true - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-Win22-Sql25-1P + - imageOverride -equals RUST-Win22-Sql25-1P-NVME variables: ob_outputDirectory: '$(Build.ArtifactStagingDirectory)' CARGO_TARGET_DIR: C:\cargo_target_dir diff --git a/.pipeline/sync-container-images.yml b/.pipeline/sync-container-images.yml index 23da15c0..152005f5 100644 --- a/.pipeline/sync-container-images.yml +++ b/.pipeline/sync-container-images.yml @@ -428,9 +428,9 @@ stages: displayName: 'Import Alpine 3.22 & 3.23' condition: eq('${{ parameters.syncAlpine3 }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -668,9 +668,9 @@ stages: displayName: 'Import CentOS Stream 9' condition: eq('${{ parameters.syncCentOS }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -692,9 +692,9 @@ stages: displayName: 'Import openSUSE Leap 15.6' condition: eq('${{ parameters.syncSUSE }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: none - task: AzureCLI@2 @@ -862,9 +862,9 @@ stages: timeoutInMinutes: 120 condition: eq('${{ parameters.buildKerberosImages }}', 'true') pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ variables.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ variables.imageName }} steps: - checkout: self displayName: Checkout repository diff --git a/.pipeline/templates/odbc-e2e-windows-remote-sql-template.yml b/.pipeline/templates/odbc-e2e-windows-remote-sql-template.yml index 47685171..6af4b426 100644 --- a/.pipeline/templates/odbc-e2e-windows-remote-sql-template.yml +++ b/.pipeline/templates/odbc-e2e-windows-remote-sql-template.yml @@ -3,7 +3,7 @@ # Runs the mssql-odbc C++ gtest e2e suite on a Windows agent that has no local # SQL Server, against the cross-pool x64 SQL host booted by sql-host-template.yml. # -# The Windows ARM agent image ships no SQL Server (unlike RUST-Win22-Sql25-1P used +# The Windows ARM agent image ships no SQL Server (unlike RUST-Win22-Sql25-1P-NVME used # by Build_Windows), so the ARM job joins the same artifact-sentinel rendezvous the # Linux ARM jobs use: derive the shared SA password, poll for the sql-ready # endpoint sentinel, run the suite, then publish a teardown sentinel to release diff --git a/.pipeline/templates/test-matrix-odbc-template.yml b/.pipeline/templates/test-matrix-odbc-template.yml index 2e90c4aa..1f12ba37 100644 --- a/.pipeline/templates/test-matrix-odbc-template.yml +++ b/.pipeline/templates/test-matrix-odbc-template.yml @@ -17,9 +17,9 @@ jobs: strategy: matrix: ${{ parameters.matrix }} pool: - name: RUST-1ES-POOL-WUS3 + name: RUST-1ES-POOL-WUS3-NVME demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals RUST-1ES-UBUSLIM-NVME steps: - template: generate-sql-password-template.yml parameters: diff --git a/.pipeline/templates/validation-stages.yml b/.pipeline/templates/validation-stages.yml index 0a5a2866..5ffb19b1 100644 --- a/.pipeline/templates/validation-stages.yml +++ b/.pipeline/templates/validation-stages.yml @@ -1052,9 +1052,9 @@ stages: - job: LongHaul_BCP_Arrow_Test displayName: Long-Haul BCP Arrow Test Ubuntu pool: - name: RUST-1ES-POOL-WUS3 + name: ${{ parameters.poolName }} demands: - - imageOverride -equals RUST-1ES-UBUSLIM + - imageOverride -equals ${{ parameters.linuxImage }} variables: CARGO_TARGET_DIR: $(Build.SourcesDirectory) steps: From 1ea61aae73bc0e5d2c6a2dd7d934e5dcc539f660 Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 7 Aug 2026 18:39:03 +0000 Subject: [PATCH 9/9] ci: trigger validation after rebase onto main