-
Notifications
You must be signed in to change notification settings - Fork 16
engineering: Azure Linux 4.0 (AZL4) full enablement stack #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
49b6d9b
cca2a4c
460393c
b1c2363
bb2fd89
2411dd9
d5846c2
5ad0c6a
74ead34
ed333bf
550ff11
afb7a26
75f8095
1796dfc
eae6848
73835d5
9dabb18
f81d73e
28b09d1
c194c4b
4684259
58742b0
b450fca
d8a19c1
a03524a
6dbf7da
caba721
c6d77d3
0a454b0
a90f38f
6412f16
ccc1047
107dffd
e29e0cc
2d770b1
53020d5
3dad740
d026fd4
a6c8df9
acc94e0
c1bd058
532b19f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| * text=auto eol=lf | ||
|
|
||
| # Anything that gets executed inside an image must keep LF endings; CRLF | ||
| # on shebang lines breaks the interpreter lookup with `bad interpreter: | ||
| # /bin/bash^M`. | ||
| *.sh text eol=lf | ||
| *.py text eol=lf | ||
| *.service text eol=lf | ||
| *.network text eol=lf | ||
| *.yaml text eol=lf | ||
| *.yml text eol=lf | ||
|
|
||
| # Binary artifacts — never normalize. | ||
| *.vhdx binary | ||
| *.cosi binary | ||
| *.qcow2 binary | ||
| *.iso binary | ||
| *.raw binary | ||
| *.png binary | ||
| *.jpg binary | ||
| *.zst binary | ||
| *.patch text eol=lf |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # AZL4 variant of build-image.yml. | ||
| # | ||
| # Forked from build-image.yml on 2026-05-13. Calls build-image-template-azl4.yml | ||
| # (which uses MCR MIC container + blob-sourced base VHDX) instead of the | ||
| # external test-images repo template. | ||
| # | ||
| # TODO(azl4-merge-back): Merge this back into build-image.yml with an | ||
| # `azureLinuxVersion` parameter switch once AZL4 base VHDX acquisition | ||
| # and trident-service RPM packaging are resolved. The base VHDX may | ||
| # continue to come from blob storage (not the AzureLinuxArtifacts ADO | ||
| # feed); the RPM will come from an AZL4 package repo, not ADO. | ||
|
|
||
| parameters: | ||
| - name: imageName | ||
| type: string | ||
|
|
||
| - name: clones | ||
| displayName: "Number of clones to generate" | ||
| type: number | ||
| default: 2 | ||
|
|
||
| - name: dependsOnTrident | ||
| type: boolean | ||
| default: true | ||
|
|
||
| - name: dependsOnStage | ||
| type: string | ||
| default: "" | ||
|
|
||
| stages: | ||
| - stage: TridentTestImg_${{ replace(parameters.imageName, '-', '_') }} | ||
| displayName: Build ${{ parameters.imageName }} | ||
| ${{ if parameters.dependsOnTrident }}: | ||
| dependsOn: | ||
| # AZL4 doesn't have RPM publication so we depend on the | ||
| # trident-binaries artifact (which the GetTridentBinaries stage | ||
| # produces and copies to artifacts/binaries/trident). | ||
| - GetTridentBinaries_rpms_amd64 | ||
| # PrepareSSHKeys produces the shared 'ssh-keys' artifact. | ||
| # build-image-template-azl4.yml stages it into the testimage | ||
| # tree so qcow2 + cosi builds share the same SSH keypair, | ||
| # which lets storm-trident SSH into both A/B sides after | ||
| # update. | ||
| - PrepareSSHKeys | ||
| - ${{ if ne(parameters.dependsOnStage, '') }}: | ||
| - ${{ parameters.dependsOnStage }} | ||
| ${{ elseif ne(parameters.dependsOnStage, '') }}: | ||
| dependsOn: | ||
| - PrepareSSHKeys | ||
| - ${{ parameters.dependsOnStage }} | ||
|
|
||
| jobs: | ||
| - job: BuildTridentTestImgAzl4 | ||
| displayName: Build (AZL4 MIC) | ||
| # Pinned MIC container build adds ~5 min cold-cache. Bump the timeout | ||
| # accordingly. TODO(azl4-release): lower back to 20 min once we use a | ||
| # released MIC container. | ||
| timeoutInMinutes: 30 | ||
| pool: | ||
| type: linux | ||
|
|
||
| variables: | ||
| ob_outputDirectory: /tmp/output | ||
| ob_artifactBaseName: ${{ parameters.imageName }} | ||
|
|
||
| steps: | ||
| - template: ../common_tasks/checkout_trident.yml | ||
|
|
||
| - task: DownloadPipelineArtifact@2 | ||
| inputs: | ||
| buildType: current | ||
| artifactName: trident-binaries | ||
| targetPath: "$(Build.ArtifactStagingDirectory)/trident-binaries" | ||
| displayName: Download Trident binaries | ||
| condition: eq('${{ parameters.dependsOnTrident }}', true) | ||
|
|
||
| - template: build-image-template-azl4.yml | ||
| parameters: | ||
| tridentSourceDirectory: $(TRIDENT_SOURCE_DIR) | ||
| imageName: ${{ parameters.imageName }} | ||
| clones: ${{ parameters.clones }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| # AZL4 variant of build-image-template.yml. | ||
| # | ||
| # Forked from build-image-template.yml on 2026-05-13. The AZL3 path pulls the | ||
| # base VHDX from the AzureLinuxArtifacts ADO feed and the Trident RPM from the | ||
| # trident-binaries pipeline artifact, then runs `testimages.py build`. AZL4 | ||
| # uses different acquisition paths: | ||
| # | ||
| # 1. Base VHDX comes from the AZL preview gallery's backing storage | ||
| # (azlpubdev2mruiyvi/images-dev). See the BlobImageManifest | ||
| # registration in tests/images/testimages.py. | ||
| # | ||
| # 2. There is no Trident RPM for AZL4 yet. The binary is baked in via | ||
| # additionalFiles in tests/images/trident-vm-testimage/base/updateimg-grub-azl4.yaml. | ||
| # | ||
| # TODO(azl4-merge-back): Fold this template back into build-image-template.yml | ||
| # once the AZL4 base VHDX and trident-service RPM acquisition paths are | ||
| # standardized. The base VHDX may stay as a blob download; the RPM will | ||
| # come from an AZL4 package repo. | ||
|
|
||
| parameters: | ||
| - name: tridentSourceDirectory | ||
| type: string | ||
|
|
||
| - name: imageName | ||
| type: string | ||
|
|
||
| - name: clones | ||
| type: number | ||
| default: 1 | ||
| displayName: Number of clones to create | ||
|
|
||
| # The AZL4 base VHDX is sourced from the Azure Linux preview gallery's | ||
| # backing storage account. The pipeline service connection at | ||
| # $(BLOB_SERVICE_CONNECTION) must have `Storage Blob Data Reader` on | ||
| # this account. See tests/images/SERVICE-CONNECTION-RUNBOOK.md. | ||
| - name: blobStorageAccount | ||
| type: string | ||
| default: "azlpubdev2mruiyvi" | ||
|
|
||
| - name: blobContainer | ||
| type: string | ||
| default: "images-dev" | ||
|
|
||
| - name: blobSubscription | ||
| type: string | ||
| # Subscription where the storage account lives. The SC's default | ||
| # subscription may differ — we explicitly set context before download. | ||
| default: "e4ab81f8-030f-4593-a8f2-3ea2c7630a19" | ||
|
|
||
| - name: blobServiceConnection | ||
| type: string | ||
| # NB: this must be a service connection that exists in the ADO project. | ||
| # Created manually by trident infra team. | ||
| default: "trident-azl4-blob-reader" | ||
|
|
||
| - name: micContainerTag | ||
| type: string | ||
| default: "imagecustomizer:1.4.0-1" | ||
|
|
||
| steps: | ||
| - template: ../common_tasks/avoid-pypi-usage.yml | ||
|
|
||
| - template: common/sfi-enforce-isolation-with-etc-hosts.yaml@platform-pipelines | ||
|
|
||
| # Stage the Trident binary that gets baked into the COSI via additionalFiles. | ||
| # The trident-binaries artifact comes from the same upstream Trident build | ||
| # stage the AZL3 path uses; we just copy the binary rather than installing | ||
| # an RPM. | ||
| # | ||
| # TODO(azl4-rpm): replace this binary copy with an RPM install once the | ||
| # trident-service RPM is packaged for AZL4 (same TODO as in | ||
| # tests/images/testimages.py registration). | ||
| - bash: | | ||
| set -euxo pipefail | ||
| TRIDENT_BIN_SRC="$(Build.ArtifactStagingDirectory)/trident-binaries" | ||
| TRIDENT_BIN_DEST="${{ parameters.tridentSourceDirectory }}/tests/images/trident-vm-testimage/base/trident-bin" | ||
|
|
||
| if [ ! -f "$TRIDENT_BIN_SRC/trident" ]; then | ||
| echo "trident binary not found at $TRIDENT_BIN_SRC/trident" | ||
| echo "Available artifacts:" | ||
| find "$TRIDENT_BIN_SRC" -type f 2>/dev/null | head -20 || true | ||
| exit 1 | ||
| fi | ||
|
|
||
| mkdir -p "$TRIDENT_BIN_DEST" | ||
| cp "$TRIDENT_BIN_SRC/trident" "$TRIDENT_BIN_DEST/trident" | ||
| chmod +x "$TRIDENT_BIN_DEST/trident" | ||
| file "$TRIDENT_BIN_DEST/trident" | ||
| displayName: "Stage Trident binary into testimage tree" | ||
| workingDirectory: ${{ parameters.tridentSourceDirectory }} | ||
|
|
||
| # Pull the released MIC container from MCR. AZL4 support is included | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the pipeline should use mcr imagecustomizer:latest i think ... not sure we need this.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. testimages.py: |
||
| # in imagecustomizer >= 1.4.0. Tag it locally so testimages.py can | ||
| # reference it by short name. | ||
| - bash: | | ||
| set -euxo pipefail | ||
| docker pull "mcr.microsoft.com/azurelinux/${{ parameters.micContainerTag }}" | ||
| docker tag "mcr.microsoft.com/azurelinux/${{ parameters.micContainerTag }}" "${{ parameters.micContainerTag }}" | ||
| displayName: "Pull MIC container from MCR" | ||
|
|
||
| # Stage the pipeline-wide SSH key into the testimage tree before | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this ssh handling coder seems out of place. we shouldn't need to do this here if we don't for azl3 images. it feels like we are confusing images built for servicing/rollback testing and e2e images. |
||
| # MIC runs. testimages.py's generate_ssh_keys() generates a new | ||
| # keypair UNLESS files/id_rsa.pub already exists at the source path | ||
| # — in which case it reuses it. By dropping the shared key from the | ||
| # PrepareSSHKeys artifact here, both the qcow2 base build and the | ||
| # COSI build end up with the same key baked into testuser's | ||
| # authorized_keys, so storm-trident's A/B update test can SSH into | ||
| # both A-side and B-side after the update reboot. | ||
| # | ||
| # The matching private key lives at ssh-keys/id_rsa from the | ||
| # PrepareSSHKeys stage. storm-trident's rollback stage picks it up | ||
| # the same way for AZL3 builds. | ||
| - task: DownloadPipelineArtifact@2 | ||
| displayName: "Download shared SSH keys" | ||
| inputs: | ||
| buildType: current | ||
| artifactName: "ssh-keys" | ||
| targetPath: "$(Build.ArtifactStagingDirectory)/ssh-keys" | ||
|
|
||
| - bash: | | ||
| set -euxo pipefail | ||
| SSH_PUB_SRC="$(Build.ArtifactStagingDirectory)/ssh-keys/id_rsa.pub" | ||
| SSH_PUB_DEST="${{ parameters.tridentSourceDirectory }}/tests/images/trident-vm-testimage/base/files/id_rsa.pub" | ||
| if [ ! -f "$SSH_PUB_SRC" ]; then | ||
| echo "shared SSH public key not found at $SSH_PUB_SRC" | ||
| find "$(Build.ArtifactStagingDirectory)/ssh-keys" -type f | ||
| exit 1 | ||
| fi | ||
| cp "$SSH_PUB_SRC" "$SSH_PUB_DEST" | ||
| echo "Staged shared SSH public key:" | ||
| cat "$SSH_PUB_DEST" | ||
| displayName: "Stage shared SSH key into testimage tree" | ||
| workingDirectory: ${{ parameters.tridentSourceDirectory }} | ||
|
|
||
| # Download the AZL4 base VHDX from the preview gallery's backing storage. | ||
| # Authenticates via the federated identity attached to the service | ||
| # connection — no storage keys handled here. | ||
| # | ||
| # The SC's default subscription (Polar_ImageTools_Staging) differs from | ||
| # the storage account's subscription (ControlTower_Test). We must switch | ||
| # context so `az storage blob list` resolves the account correctly. | ||
| - task: AzureCLI@2 | ||
| displayName: "Download AZL4 base VHDX from blob" | ||
| inputs: | ||
| azureSubscription: ${{ parameters.blobServiceConnection }} | ||
| scriptType: bash | ||
| scriptLocation: inlineScript | ||
| workingDirectory: ${{ parameters.tridentSourceDirectory }} | ||
| inlineScript: | | ||
| set -euxo pipefail | ||
| az account set --subscription "${{ parameters.blobSubscription }}" | ||
| python3 ./tests/images/testimages.py download-image azl4_qemu_guest \ | ||
| --blob-storage-account "${{ parameters.blobStorageAccount }}" \ | ||
| --blob-container "${{ parameters.blobContainer }}" | ||
| ls -la artifacts/azl4_qemu_guest.vhdx | ||
|
|
||
| - bash: | | ||
| set -euxo pipefail | ||
| python3 ./tests/images/testimages.py build \ | ||
| "${{ parameters.imageName }}" \ | ||
| --container "${{ parameters.micContainerTag }}" \ | ||
| --output-dir "$(ob_outputDirectory)" \ | ||
| --no-download \ | ||
| --clones ${{ parameters.clones }} | ||
| displayName: "Build ${{ parameters.imageName }}" | ||
| workingDirectory: ${{ parameters.tridentSourceDirectory }} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i suspect we could merge these azl4 templates now, maybe using soemthign like : baseimgBuildType=azl4-preview
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or better yet,
azureLinuxVersion=4.0-previewThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is untested, but it is the idea:
user/bfjelds/azl4-pipelines