diff --git a/.pipelines/templates/stages/azl_installer/azl-installer.yml b/.pipelines/templates/stages/azl_installer/azl-installer.yml index cc7d807c53..e9e8d93f2d 100644 --- a/.pipelines/templates/stages/azl_installer/azl-installer.yml +++ b/.pipelines/templates/stages/azl_installer/azl-installer.yml @@ -76,15 +76,15 @@ stages: - bash: | set -ex - mkdir -p tests/images/azl-installer/iso/bin - mkdir -p tests/images/azl-installer/iso/images + mkdir -p tests/tailor-images/azl-installer/iso/bin + mkdir -p tests/tailor-images/azl-installer/iso/images # Move liveinstaller to bin directory - mv "$(Build.ArtifactStagingDirectory)/installer-tools/liveinstaller" tests/images/azl-installer/iso/bin/ - chmod +x tests/images/azl-installer/iso/bin/liveinstaller + mv "$(Build.ArtifactStagingDirectory)/installer-tools/liveinstaller" tests/tailor-images/azl-installer/iso/bin/ + chmod +x tests/tailor-images/azl-installer/iso/bin/liveinstaller # Move .cosi file to the ISO directory. When there are clones (multiple .cosi files), we pick the first one. - mv $(ls $(Build.ArtifactStagingDirectory)/testimage/*.cosi | head -n 1) tests/images/azl-installer/iso/images/trident-testimage.cosi + mv $(ls $(Build.ArtifactStagingDirectory)/testimage/*.cosi | head -n 1) tests/tailor-images/azl-installer/iso/images/trident-testimage.cosi displayName: "Prepare installer dependencies" workingDirectory: $(TRIDENT_SOURCE_DIR) diff --git a/.pipelines/templates/stages/build_image/build-image-template.yml b/.pipelines/templates/stages/build_image/build-image-template.yml index 75b3521d6b..249fa5d30d 100644 --- a/.pipelines/templates/stages/build_image/build-image-template.yml +++ b/.pipelines/templates/stages/build_image/build-image-template.yml @@ -62,6 +62,10 @@ parameters: steps: - template: ../common_tasks/avoid-pypi-usage.yml + - template: ../common_tasks/cargo-auth.yml + parameters: + cargoConfigPath: $(TRIDENT_SOURCE_DIR)/.cargo/config.toml + - template: common/sfi-enforce-isolation-with-etc-hosts.yaml@platform-pipelines - script: | @@ -82,8 +86,23 @@ steps: retryCountOnTaskFailure: 3 - bash: | - ./tests/images/testimages.py show-image ${{ parameters.imageName }} base-image --devops-var baseImageType - displayName: "Get Image Info" + set -euo pipefail + + case '${{ parameters.imageName }}' in + azl-installer|trident-container-installer|trident-container-testimage|trident-functest|trident-installer|trident-split-installer|trident-testimage|trident-verity-testimage|trident-usrverity-testimage|trident-container-verity-testimage|trident-container-usrverity-testimage|trident-direct-streaming-installer-amd64) + baseImageType=baremetal + ;; + trident-direct-streaming-installer-arm64|trident-installer-arm64|trident-testimage-arm64) + baseImageType=core_arm64 + ;; + *) + echo "Unsupported imageName for build-image-template: ${{ parameters.imageName }}" + exit 1 + ;; + esac + + echo "##vso[task.setvariable variable=baseImageType]${baseImageType}" + displayName: "Resolve image metadata" workingDirectory: ${{ parameters.tridentSourceDirectory }} - bash: | @@ -117,10 +136,27 @@ steps: azureLinuxVersion: ${{ parameters.azureLinuxVersion }} runtimeBuildType: ${{ parameters.baseimgBuildType }} + - ${{ if eq(parameters.architecture, 'arm64') }}: + - task: DownloadPipelineArtifact@2 + displayName: "Download go-tools for direct-streaming installer" + condition: or(eq('${{ parameters.imageName }}', 'trident-direct-streaming-installer-amd64'), eq('${{ parameters.imageName }}', 'trident-direct-streaming-installer-arm64')) + inputs: + buildType: current + artifactName: go-tools-arm64 + targetPath: "$(Build.ArtifactStagingDirectory)/go-tools" + - ${{ if ne(parameters.architecture, 'arm64') }}: + - task: DownloadPipelineArtifact@2 + displayName: "Download go-tools for direct-streaming installer" + condition: or(eq('${{ parameters.imageName }}', 'trident-direct-streaming-installer-amd64'), eq('${{ parameters.imageName }}', 'trident-direct-streaming-installer-arm64')) + inputs: + buildType: current + artifactName: go-tools + targetPath: "$(Build.ArtifactStagingDirectory)/go-tools" + - bash: | set -ex - # Move base VHDX to artifacts/ (builder expects artifacts/*.vhdx) + # Move base VHDX to artifacts/ (tailor baseImages catalogue points at artifacts/*.vhdx) mkdir -p artifacts if ls "$(Build.ArtifactStagingDirectory)/images" | grep -q ".*\.vhdx$"; then mv $(Build.ArtifactStagingDirectory)/images/*.vhdx artifacts/ @@ -144,28 +180,145 @@ steps: DISTRO=azl4 fi - # Move Trident RPMs to bin/RPMS/ (builder expects bin/RPMS/*.rpm) + # Move Trident RPMs to bin/RPMS/ (tailor rpmSources point at bin/RPMS/) if [ -d "$(Build.ArtifactStagingDirectory)/trident" ]; then mkdir -p bin/RPMS find "$(Build.ArtifactStagingDirectory)/trident" -name "*${DISTRO}*.rpm" -exec mv {} bin/RPMS/ \; rm -rf "$(Build.ArtifactStagingDirectory)/trident" fi + + if [[ "${{ parameters.imageName }}" == trident-direct-streaming-installer-* ]]; then + if [ -f "$(Build.ArtifactStagingDirectory)/go-tools/rcp-agent" ]; then + cp "$(Build.ArtifactStagingDirectory)/go-tools/rcp-agent" artifacts/rcp-agent + elif [ -f bin/rcp-agent ]; then + cp bin/rcp-agent artifacts/rcp-agent + else + echo "Missing rcp-agent for direct-streaming installer" + exit 1 + fi + chmod +x artifacts/rcp-agent + cp tools/cmd/rcp-agent/rcp-agent.service artifacts/rcp-agent.service + fi displayName: "Prepare and move requirements" workingDirectory: ${{ parameters.tridentSourceDirectory }} - bash: | - set -ex + set -euo pipefail + + legacy_name='${{ parameters.imageName }}' + export PATH="$HOME/.cargo/bin:$PATH" + export CLICOLOR_FORCE=1 - EXTRA_ARGS="" + selector_args=() + case "$legacy_name" in + azl-installer) + tailor_image=azl-installer + artifact_ext=iso + ;; + trident-functest) + tailor_image=trident-functest + artifact_ext=qcow2 + ;; + trident-installer) + tailor_image=trident-installer + artifact_ext=iso + selector_args=(-s arch=amd64 -s variant=default) + ;; + trident-split-installer) + tailor_image=trident-installer + artifact_ext=iso + selector_args=(-s arch=amd64 -s variant=split) + ;; + trident-installer-arm64) + tailor_image=trident-installer + artifact_ext=iso + selector_args=(-s arch=arm64 -s variant=default) + ;; + trident-direct-streaming-installer-amd64) + tailor_image=trident-installer + artifact_ext=iso + selector_args=(-s arch=amd64 -s variant=direct-streaming) + ;; + trident-direct-streaming-installer-arm64) + tailor_image=trident-installer + artifact_ext=iso + selector_args=(-s arch=arm64 -s variant=direct-streaming) + ;; + trident-container-installer) + tailor_image=trident-container-installer + artifact_ext=iso + ;; + trident-testimage) + tailor_image=trident-testimage + artifact_ext=cosi + selector_args=(-s arch=amd64) + ;; + trident-testimage-arm64) + tailor_image=trident-testimage + artifact_ext=cosi + selector_args=(-s arch=arm64) + ;; + trident-container-testimage) + tailor_image=trident-container-testimage + artifact_ext=cosi + ;; + trident-verity-testimage) + tailor_image=trident-verity-testimage + artifact_ext=cosi + selector_args=(-s deployment=host -s mode=root) + ;; + trident-container-verity-testimage) + tailor_image=trident-verity-testimage + artifact_ext=cosi + selector_args=(-s deployment=container -s mode=root) + ;; + trident-usrverity-testimage) + tailor_image=trident-verity-testimage + artifact_ext=cosi + selector_args=(-s deployment=host -s mode=usr) + ;; + trident-container-usrverity-testimage) + tailor_image=trident-verity-testimage + artifact_ext=cosi + selector_args=(-s deployment=container -s mode=usr) + ;; + *) + echo "Unsupported imageName for build-image-template: ${legacy_name}" + exit 1 + ;; + esac + manifest_path=tests/tailor-images/tailor.yaml if [[ "${{ parameters.micBuildType }}" == "dev" ]]; then - EXTRA_ARGS+=" --container imagecustomizer:dev" + manifest_path=tests/tailor-images/.tailor.pipeline.yaml + python3 - <<'PY' + from pathlib import Path + text = Path('tests/tailor-images/tailor.yaml').read_text() + needle = 'toolchains:\n default: ic\n entries:\n - name: ic\n container: mcr.microsoft.com/azurelinux/imagecustomizer\n tag: latest\n' + replacement = 'toolchains:\n default: ic-dev\n entries:\n - name: ic\n container: mcr.microsoft.com/azurelinux/imagecustomizer\n tag: latest\n - name: ic-dev\n container: imagecustomizer\n tag: dev\n pull: never\n' + Path('tests/tailor-images/.tailor.pipeline.yaml').write_text(text.replace(needle, replacement, 1)) + PY + fi + + rm -f tests/tailor-images/artifacts/ca_cert.pem + cargo run --manifest-path tools/tailor/Cargo.toml --quiet -- \ + --manifest "$manifest_path" \ + build "$tailor_image" \ + "${selector_args[@]}" \ + --output-dir $(ob_outputDirectory) \ + --clones ${{ parameters.clones }} + + if [[ ${{ parameters.clones }} -gt 1 ]]; then + for ((i=0; i<${{ parameters.clones }}; i++)); do + mv "$(ob_outputDirectory)/${legacy_name}_clone${i}.${artifact_ext}" \ + "$(ob_outputDirectory)/${legacy_name}_${i}.${artifact_ext}" + done + fi + + if [ -f tests/tailor-images/artifacts/ca_cert.pem ]; then + cp tests/tailor-images/artifacts/ca_cert.pem "$(ob_outputDirectory)/ca_cert.pem" fi - python3 ./tests/images/testimages.py build \ - "${{ parameters.imageName }}" $EXTRA_ARGS \ - --output-dir $(ob_outputDirectory) \ - --no-download \ - --clones ${{ parameters.clones }} + rm -f tests/tailor-images/.tailor.pipeline.yaml displayName: "Build ${{ parameters.imageName }}" workingDirectory: ${{ parameters.tridentSourceDirectory }} diff --git a/.pipelines/templates/stages/trident_images/build-image-arm64.yml b/.pipelines/templates/stages/trident_images/build-image-arm64.yml index 04be97e2f9..abc4ab9d3e 100644 --- a/.pipelines/templates/stages/trident_images/build-image-arm64.yml +++ b/.pipelines/templates/stages/trident_images/build-image-arm64.yml @@ -52,6 +52,15 @@ jobs: - template: ../common_tasks/checkout_trident.yml - template: ../common_tasks/avoid-pypi-usage.yml + # The Makefile's tailor-backed legacy image targets invoke + # `cargo run --manifest-path tools/tailor/Cargo.toml`, so a Rust + # toolchain and cargo registry auth are required here even though this + # job previously never needed cargo. + - template: ../common_tasks/rustup.yml + - template: ../common_tasks/cargo-auth.yml + parameters: + cargoConfigPath: $(TRIDENT_SOURCE_DIR)/.cargo/config.toml + - task: DownloadPipelineArtifact@2 inputs: buildType: current diff --git a/.pipelines/templates/stages/trident_images/build-image.yml b/.pipelines/templates/stages/trident_images/build-image.yml index 6f70dafdce..c50648e7c4 100644 --- a/.pipelines/templates/stages/trident_images/build-image.yml +++ b/.pipelines/templates/stages/trident_images/build-image.yml @@ -101,6 +101,15 @@ jobs: - template: ../common_tasks/checkout_trident.yml - template: ../common_tasks/avoid-pypi-usage.yml + # The Makefile's tailor-backed legacy image targets invoke + # `cargo run --manifest-path tools/tailor/Cargo.toml`, so a Rust + # toolchain and cargo registry auth are required here even though this + # job previously never needed cargo. + - template: ../common_tasks/rustup.yml + - template: ../common_tasks/cargo-auth.yml + parameters: + cargoConfigPath: $(TRIDENT_SOURCE_DIR)/.cargo/config.toml + - ${{ if parameters.downloadGoTools }}: - task: DownloadPipelineArtifact@2 displayName: "Download $(goToolsArtifactName)" diff --git a/.pipelines/templates/stages/trident_images/trident-testimg-template.yml b/.pipelines/templates/stages/trident_images/trident-testimg-template.yml index c2d53a4694..9b7cce61a1 100644 --- a/.pipelines/templates/stages/trident_images/trident-testimg-template.yml +++ b/.pipelines/templates/stages/trident_images/trident-testimg-template.yml @@ -135,7 +135,7 @@ steps: displayName: Copy SSH Keys - script: | - echo "##[warning]THE PIPELINE TEMPLATE trident-testimg-template.yaml IS DEPRECATED. PLEASE SWITCH TO USING testimages.py TO BUILD TEST IMAGES." + echo "##[warning]THE PIPELINE TEMPLATE trident-testimg-template.yaml IS DEPRECATED. PLEASE SWITCH TO USING the tailor workspace under tests/tailor-images." cat /etc/os-release displayName: "Report Host Info" @@ -264,6 +264,18 @@ steps: rm -rf "$(Build.ArtifactStagingDirectory)/trident" fi + if [[ "${{ parameters.target }}" == artifacts/trident-direct-streaming-installer-* ]]; then + mkdir -p '${{ parameters.tridentSourceDirectory }}/artifacts' + if [ -f "${{ parameters.tridentSourceDirectory }}/bin/rcp-agent" ]; then + cp "${{ parameters.tridentSourceDirectory }}/bin/rcp-agent" '${{ parameters.tridentSourceDirectory }}/artifacts/rcp-agent' + chmod +x '${{ parameters.tridentSourceDirectory }}/artifacts/rcp-agent' + else + echo "Missing rcp-agent in bin/ for direct-streaming installer" + exit 1 + fi + cp '${{ parameters.tridentSourceDirectory }}/tools/cmd/rcp-agent/rcp-agent.service' '${{ parameters.tridentSourceDirectory }}/artifacts/rcp-agent.service' + fi + workingDirectory: ${{ parameters.tridentSourceDirectory }} displayName: "Prepare and move requirements" @@ -280,13 +292,12 @@ steps: export MIC_CONTAINER_IMAGE="imagecustomizer:dev" fi - # Allow cross-platform (i.e. amd64 pipeline creating arm64 images) - if [[ "${{ parameters.micArchitecture }}" != "${{ parameters.pipelineArchitecture }}" ]]; then - # Export variable to tell Makefile and testimages to use `docker --platform` - export MIC_ARCHITECTURE="linux/${{ parameters.micArchitecture }}" - fi + # The Makefile's tailor-backed legacy target helper resolves the cell arch + # from the historical image name, so no extra MIC_ARCHITECTURE export is + # needed here for cross-arch direct-streaming builds. # Compress the full image & delete the uncompressed image + rm -f tests/tailor-images/artifacts/ca_cert.pem make ${{ parameters.target }} workingDirectory: ${{ parameters.tridentSourceDirectory }} displayName: "Build Test Image" @@ -302,5 +313,9 @@ steps: # Everything else is a file sudo mv -v "${{ parameters.target }}" "${{ parameters.outputDirectory }}/" fi + + if [ -f "tests/tailor-images/artifacts/ca_cert.pem" ]; then + sudo cp -v "tests/tailor-images/artifacts/ca_cert.pem" "${{ parameters.outputDirectory }}/ca_cert.pem" + fi workingDirectory: ${{ parameters.tridentSourceDirectory }} displayName: "Copy artifacts to output directory" diff --git a/Makefile b/Makefile index 28ec9dc5d7..998d569742 100644 --- a/Makefile +++ b/Makefile @@ -538,7 +538,7 @@ generate-functional-test-manifest: .cargo/config .PHONY: validate-configs validate-configs: target/release/trident - $(eval DETECTED_HC_FILES := $(shell grep -R '^storage:' . --include '*.yaml' -l | grep -E -v '\./(target|dev|azure-linux-image-tools|crates/docbuilder|tests/images|tests/azl-installer)')) + $(eval DETECTED_HC_FILES := $(shell grep -R '^storage:' . --include '*.yaml' -l | grep -E -v '\./(target|dev|azure-linux-image-tools|crates/docbuilder|tests/tailor-images|tests/azl-installer)')) @for file in $(DETECTED_HC_FILES); do \ echo "Validating $$file"; \ $< validate $$file -v info || exit 1; \ @@ -627,31 +627,13 @@ run-attendedinstaller-simulator: bin/attendedinstaller-simulator # Test image paths ARTIFACTS_TEST_IMAGE_DIR := artifacts/test-image -AZL_INSTALLER_DIR := tests/images/azl-installer +AZL_INSTALLER_DIR := tests/tailor-images/azl-installer AZL_INSTALLER_ISO_DIR := $(AZL_INSTALLER_DIR)/iso # If regular.cosi is not present, download runtime images $(ARTIFACTS_TEST_IMAGE_DIR)/regular.cosi: download-runtime-images -# Build the installer ISO using the builder -$(ARTIFACTS_TEST_IMAGE_DIR)/azl-installer.iso: \ - bin/RPMS \ - bin/liveinstaller \ - artifacts/baremetal.vhdx \ - $(ARTIFACTS_TEST_IMAGE_DIR)/regular.cosi \ - $(AZL_INSTALLER_DIR)/installer-iso.yaml \ - $(shell find $(AZL_INSTALLER_DIR)/ -type f 2>/dev/null) - # Prepare dependencies - # Copy runtime image - rm -rf $(AZL_INSTALLER_ISO_DIR)/images - mkdir -p $(AZL_INSTALLER_ISO_DIR)/images - cp $(ARTIFACTS_TEST_IMAGE_DIR)/regular.cosi $(AZL_INSTALLER_ISO_DIR)/images/trident-testimage.cosi - # Copy installer binary - rm -rf $(AZL_INSTALLER_ISO_DIR)/bin - mkdir -p $(AZL_INSTALLER_ISO_DIR)/bin - cp bin/liveinstaller $(AZL_INSTALLER_ISO_DIR)/bin/ - # Build ISO - ./tests/images/testimages.py build azl-installer --output-dir $(ARTIFACTS_TEST_IMAGE_DIR) +include tests/tailor-images/targets.mk .PHONY: validate validate: $(TRIDENT_CONFIG) target/release/trident @@ -885,184 +867,9 @@ download-trident-container-installer-iso: --path artifacts/ \ --artifact-name 'trident-container-installer' -artifacts/trident-container-installer.iso: - $(MAKE) download-trident-container-installer-iso; \ - ls -l artifacts/trident-container-installer.iso - -# Copies locally built runtime images from ../test-images/build to ./artifacts/test-image. -# Expects that both the regular and verity Trident test images have been built. -.PHONY: copy-runtime-images -copy-runtime-images: $(TEST_IMAGES_PATH)/build/trident-testimage/*.cosi $(TEST_IMAGES_PATH)/build/trident-verity-testimage/*.cosi - @test -d $(TEST_IMAGES_PATH) || { \ - echo "$(TEST_IMAGES_PATH) not found"; \ - exit 1; \ - } - @test -d $(TEST_IMAGES_PATH)/build/trident-testimage || { \ - echo "$(TEST_IMAGES_PATH)/build/trident-testimage not found"; \ - exit 1; \ - } - @test -d $(TEST_IMAGES_PATH)/build/trident-verity-testimage || { \ - echo "$(TEST_IMAGES_PATH)/build/trident-verity-testimage not found"; \ - exit 1; \ - } - - @rm -rf ./artifacts/test-image - @mkdir -p ./artifacts/test-image - -# Copy all COSI images from trident-testimage - @for file in $(TEST_IMAGES_PATH)/build/trident-testimage/*.cosi; do \ - cp $$file ./artifacts/test-image/$$(basename $$file); \ - echo "Copied $$file to ./artifacts/test-image/$$(basename $$file)"; \ - done - -# Copy all COSI images from trident-verity-testimage - @for file in $(TEST_IMAGES_PATH)/build/trident-verity-testimage/*.cosi; do \ - cp $$file ./artifacts/test-image/$$(basename $$file); \ - echo "Copied $$file to ./artifacts/test-image/$$(basename $$file)"; \ - done - -# Uses the simple E2E test to set up a starter Host Configuration -.PHONY: starter-configuration -starter-configuration: - @mkdir -p $$(dirname $(TRIDENT_CONFIG)) - @cp tests/e2e_tests/trident_configurations/simple/trident-config.yaml $(TRIDENT_CONFIG) - @echo "\033[33mCreated \033[36m$(TRIDENT_CONFIG)\033[33m. Please review and modify as needed! :)" - @echo "\033[33mDon't forget to add your SSH public key to the Host Configuration!" - -bin/trident-mos.iso: \ - artifacts/baremetal.vhdx \ - packaging/systemd/trident-install.service \ - tests/images/trident-mos/iso.yaml \ - tests/images/trident-mos/files/* \ - tests/images/trident-mos/post-install.sh \ - packaging/selinux-policy-trident/* \ - tools/cmd/rcp-agent/rcp-agent.service \ - bin/rcp-agent - @echo "Rebuilding Trident MOS ISO: $@ from $< because of: $?" - @mkdir -p bin - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level=debug \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --config-file /repo/tests/images/trident-mos/iso.yaml \ - --output-image-format iso - -.PHONY: recreate-verity-image -recreate-verity-image: bin/trident-rpms.tar.gz - $(MAKE) -C $(TEST_IMAGES_PATH) copy-trident-rpms - $(MAKE) -C $(TEST_IMAGES_PATH) trident-verity-testimage - make copy-runtime-images - -.PHONY: website-clear -website-clear: - cd ./website && \ - rm -rf ./docs && \ - rm -rf ./versioned_* && \ - rm -rf ./versions.json && \ - rm -rf ./node_modules - -.PHONY: website-prereqs -website-prereqs: - cd ./website && npm ci - -DOCS_CONTENTS = $(shell find ./docs -type f) -website/docs: $(DOCS_CONTENTS) - rm -rf ./website/docs && \ - cp -r ./docs ./website - -website/versions.json: - echo '[]' > website/versions.json - -.PHONY: website-build -website-build: website-prereqs website/docs website/versions.json - cd ./website && \ - npm run build - -.PHONY: website-serve -website-serve: website-build - cd ./website && \ - npm run serve -- --port $(SERVER_PORT) - -# Useful if you edit website/docs files in place and want to copy them back to ./docs -.PHONY: website-reverse -website-reverse: website/docs - rm -rf ./docs - cp -r ./website/docs ./ - -.PHONY: validate-pipeline-website-artifact -validate-pipeline-website-artifact: - if ! which gh > /dev/null; then \ - sudo apt install gh; \ - fi - $(eval STAGING_DIR := $(shell mktemp -d)) - cp -r ./website/. $(STAGING_DIR)/ - rm -rf $(STAGING_DIR)/build && \ - mkdir -p $(STAGING_DIR)/build - $(eval RUN_ID ?= $(shell gh run list --workflow 'Deploy to GitHub Pages' --repo microsoft/trident --json conclusion,databaseId --jq '.[] | select(.conclusion == "success") | .databaseId' | sort -n | tail -n 1)) - @echo "Downloading GitHub Pages artifact from $(RUN_ID)" - gh run download $(RUN_ID) --name github-pages --repo microsoft/trident --dir $(STAGING_DIR)/build - cd $(STAGING_DIR)/build && \ - tar -xvf ./artifact.tar && \ - cd $(STAGING_DIR) && \ - npm install && \ - npm run serve -- --port $(SERVER_PORT) - -# -# Generic COSI image build target pattern -# -COSI_TARGETS = $(shell ./tests/images/testimages.py list --filter-type cosi) - -.PHONY: $(COSI_TARGETS) -$(COSI_TARGETS): %: artifacts/%.cosi - -.PHONY: all-cosi -all-cosi: $(COSI_TARGETS) - -# -# Generic ISO image build target pattern -# -ISO_TARGETS = $(shell ./tests/images/testimages.py list --filter-type iso) - -.PHONY: $(ISO_TARGETS) -$(ISO_TARGETS): %: artifacts/%.iso - -.PHONY: all-iso -all-iso: $(ISO_TARGETS) - -# Fun trick to use the stem of the target (%) as a variable ($*) in the -# prerequisites so that we can use find to get all the files in the directory. -# https://www.gnu.org/software/make/manual/make.html#Secondary-Expansion -.SECONDEXPANSION: -artifacts/%.cosi artifacts/%.iso artifacts/%.vhdx: $$(shell ./tests/images/testimages.py dependencies $$*) - @echo "Building '$*' [$@] from $<" - @echo "Prerequisites:" - @echo "$^" | tr ' ' '\n' | sed 's/^/ /' - @echo "Building image..." - sudo ./tests/images/testimages.py build \ - $* \ - --output-dir ./artifacts \ - $(if $(strip $(MIC_CONTAINER_IMAGE)),--container $(MIC_CONTAINER_IMAGE)) \ - $(if $(strip $(MIC_ARCHITECTURE)),--image-architecture $(MIC_ARCHITECTURE)) - -MIC_CONTAINER_IMAGE ?= $(shell ./tests/images/testimages.py show-artifact customizer-container-full) -artifacts/trident-functest.qcow2: $$(shell ./tests/images/testimages.py dependencies $$(basename $$(notdir $$@))) - @echo "Building '$*' [$@] from $<" - @echo "Prerequisites:" - @echo "$^" | tr ' ' '\n' | sed 's/^/ /' - @echo "Building image..." - sudo ./tests/images/testimages.py build \ - $(basename $(notdir $@)) \ - --output-dir ./artifacts \ - $(if $(strip $(MIC_CONTAINER_IMAGE)),--container $(MIC_CONTAINER_IMAGE)) - # TRIDENT VM UPDATE IMAGES -VM_IMAGE_PATH_PREFIX = tests/images/trident-vm-testimage/base +VM_IMAGE_PATH_PREFIX = tests/tailor-images/trident-vm-testimage/base artifacts/rpm-overrides: @mkdir -p artifacts/rpm-overrides @@ -1097,194 +904,30 @@ $(QEMU_GUEST_IMAGE): BAREMETAL_IMAGE = artifacts/baremetal.vhdx $(BAREMETAL_IMAGE): @mkdir -p artifacts - @tests/images/testimages.py download-image baremetal + $(CARGO_TAILOR) run --manifest-path tools/tailor/Cargo.toml --quiet -- --manifest tests/tailor-images/tailor.yaml bases download baremetal CORE_SELINUX_IMAGE = artifacts/core_selinux.vhdx $(CORE_SELINUX_IMAGE): @mkdir -p artifacts - @tests/images/testimages.py download-image core_selinux + $(CARGO_TAILOR) run --manifest-path tools/tailor/Cargo.toml --quiet -- --manifest tests/tailor-images/tailor.yaml bases download core_selinux +CORE_ARM64_IMAGE_NAME ?= core_vhdx-arm64-3.0-stable +CORE_ARM64_IMAGE_VERSION ?= * +CORE_ARM64_IMAGE = artifacts/core_arm64.vhdx +$(CORE_ARM64_IMAGE): + @mkdir -p artifacts + @tempdir=$$(mktemp -d); result=$$(az artifacts universal download --organization "https://dev.azure.com/mariner-org/" --project "36d030d6-1d99-4ebd-878b-09af1f4f722f" --scope project --feed "AzureLinuxArtifacts" --name '$(CORE_ARM64_IMAGE_NAME)' --version '$(CORE_ARM64_IMAGE_VERSION)' --path $$tempdir) && mv $$tempdir/*.vhdx $(CORE_ARM64_IMAGE) && rm -rf $$tempdir && echo $$result | jq > $(CORE_ARM64_IMAGE).metadata.json -MINIMAL_IMAGE = artifacts/minimal.vhdx -$(MINIMAL_IMAGE): +artifacts/rcp-agent: bin/rcp-agent @mkdir -p artifacts - @tests/images/testimages.py download-image minimal + @cp bin/rcp-agent $@ + @chmod +x $@ -MINIMAL_IMAGE_AARCH64 = artifacts/minimal_aarch64.vhdx -$(MINIMAL_IMAGE_AARCH64): +artifacts/rcp-agent.service: tools/cmd/rcp-agent/rcp-agent.service @mkdir -p artifacts - @tests/images/testimages.py download-image minimal_aarch64 - -artifacts/trident-vm-grub-testimage.qcow2: \ - $(QEMU_GUEST_IMAGE) \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-grub.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub \ - artifacts/rpm-overrides - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --rpm-source /repo/artifacts/rpm-overrides \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-grub.yaml - -artifacts/trident-vm-grub-testimage-arm64.qcow2: \ - base/core_arm64.vhdx \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-grub.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-grub-verity.yaml - -artifacts/trident-vm-grub-verity-testimage.qcow2: \ - $(QEMU_GUEST_IMAGE) \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-grub-verity.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/etc-mount.service \ - $(VM_IMAGE_PATH_PREFIX)/files/etc-mount.sh \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub \ - artifacts/rpm-overrides - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --rpm-source /repo/artifacts/rpm-overrides \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-grub-verity.yaml - -artifacts/trident-vm-root-verity-testimage.qcow2: \ - $(QEMU_GUEST_IMAGE) \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-root-verity.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub \ - artifacts/rpm-overrides - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --rpm-source /repo/artifacts/rpm-overrides \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-root-verity.yaml - -artifacts/trident-vm-verity-testimage-arm64.qcow2: \ - base/core_arm64.vhdx \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-verity.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/etc-mount.service \ - $(VM_IMAGE_PATH_PREFIX)/files/etc-mount.sh \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-verity.yaml - -artifacts/trident-vm-usr-verity-testimage.qcow2: \ - $(QEMU_GUEST_IMAGE) \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-usr-verity.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub \ - artifacts/rpm-overrides - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --rpm-source /repo/artifacts/rpm-overrides \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-usr-verity.yaml - -artifacts/trident-vm-acl-agent-testimage.qcow2: \ - $(QEMU_GUEST_IMAGE) \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-acl-agent.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub \ - $(VM_IMAGE_PATH_PREFIX)/files/trident-acl-agent-override.conf \ - artifacts/rpm-overrides - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --rpm-source /repo/artifacts/rpm-overrides \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format qcow2 \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-acl-agent.yaml - -artifacts/trident-vm-grub-verity-azure-testimage.vhd: \ - $(CORE_SELINUX_IMAGE) \ - $(TRIDENT_VM_DEPENDENCIES) \ - $(VM_IMAGE_PATH_PREFIX)/baseimg-grub-verity-azure.yaml \ - $(VM_IMAGE_PATH_PREFIX)/files/etc-mount.service \ - $(VM_IMAGE_PATH_PREFIX)/files/etc-mount.sh \ - $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub \ - artifacts/rpm-overrides - @echo "Building $@ from $<" - docker run --rm \ - --privileged \ - -v ".:/repo:z" \ - -v "/dev:/dev" \ - ${MIC_CONTAINER_IMAGE} \ - --log-level debug \ - --rpm-source /repo/bin/RPMS \ - --rpm-source /repo/artifacts/rpm-overrides \ - --build-dir /build \ - --image-file /repo/$< \ - --output-image-file /repo/$@ \ - --output-image-format vhd-fixed \ - --config-file /repo/$(VM_IMAGE_PATH_PREFIX)/baseimg-grub-verity-azure.yaml + @cp tools/cmd/rcp-agent/rcp-agent.service $@ + + .PHONY: imagecustomizer-dev-amd64 imagecustomizer-dev-amd64: @@ -1315,3 +958,18 @@ artifacts/ubuntu_2404_arm64.vhdx: curl -LO https://cloud-images.ubuntu.com/releases/server/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img qemu-img convert -O vhdx ubuntu-24.04-server-cloudimg-arm64.img artifacts/ubuntu_2404_arm64.vhdx rm -f ubuntu-24.04-server-cloudimg-arm64.img + +# GB200 base image is staged from a private Azure Linux storage account (see +# .pipelines/templates/stages/trident_images/trident-testimg-template.yml, +# "Download Base Image - gb200_2404_arm64"), not a public URL, so this rule +# mirrors the pipeline's az CLI download for local/dev builds that have +# access to the azlinuxbmpstaging storage account. +GB200_BLOB_NAME = gb200/arm64/20260318/image.vhdx +artifacts/gb200_2404_arm64.vhdx: + mkdir -p artifacts + az storage blob download \ + --auth-mode login \ + --account-name azlinuxbmpstaging \ + --container-name os-image-cache \ + --name "$(GB200_BLOB_NAME)" \ + --file artifacts/gb200_2404_arm64.vhdx diff --git a/docs/Development/Testing/E2E-Tests.md b/docs/Development/Testing/E2E-Tests.md index 13169b5e42..509840db27 100644 --- a/docs/Development/Testing/E2E-Tests.md +++ b/docs/Development/Testing/E2E-Tests.md @@ -132,8 +132,8 @@ make bin/rcp-agent # Remote control plane agent ### 4. Build Trident RPMs The **host** test images include Trident packages built from your local tree. -This step builds the RPMs into `bin/RPMS/`, which `testimages.py` passes to -Image Customizer via `--rpm-source`: +This step builds the RPMs into `bin/RPMS/`, which the `tests/tailor-images` tailor +workspace passes to Image Customizer via `rpmSources:`: ```bash make bin/trident-rpms.tar.gz @@ -168,8 +168,7 @@ make artifacts/id_rsa ### 7. Download Base Image ```bash -# Downloads baremetal.vhdx from MCR -./tests/images/testimages.py download-image baremetal +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml bases download baremetal ``` ### 8. Build COSI Images @@ -184,29 +183,27 @@ then rename them into `artifacts/test-image/`. ```bash mkdir -p artifacts/test-image -# Build two clones (produces trident-testimage_0.cosi and trident-testimage_1.cosi) -sudo ./tests/images/testimages.py build trident-testimage \ - --output-dir ./artifacts/test-image --clones 2 +# Build two clones (produces trident-testimage_amd64_cosi_clone0.cosi and +# trident-testimage_amd64_cosi_clone1.cosi) +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-testimage -s arch=amd64 --output-dir ./artifacts/test-image --clones 2 # Rename clones to the filenames referenced by Host Configurations -mv artifacts/test-image/trident-testimage_0.cosi artifacts/test-image/regular.cosi -mv artifacts/test-image/trident-testimage_1.cosi artifacts/test-image/regular_v2.cosi +mv artifacts/test-image/trident-testimage_amd64_cosi_clone0.cosi artifacts/test-image/regular.cosi +mv artifacts/test-image/trident-testimage_amd64_cosi_clone1.cosi artifacts/test-image/regular_v2.cosi ``` Repeat for other image types as needed: ```bash # Verity image (for root-verity configuration) -sudo ./tests/images/testimages.py build trident-verity-testimage \ - --output-dir ./artifacts/test-image --clones 2 -mv artifacts/test-image/trident-verity-testimage_0.cosi artifacts/test-image/verity.cosi -mv artifacts/test-image/trident-verity-testimage_1.cosi artifacts/test-image/verity_v2.cosi +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-verity-testimage -s deployment=host -s mode=root --output-dir ./artifacts/test-image --clones 2 +mv artifacts/test-image/trident-verity-testimage_host_root_amd64_cosi_clone0.cosi artifacts/test-image/verity.cosi +mv artifacts/test-image/trident-verity-testimage_host_root_amd64_cosi_clone1.cosi artifacts/test-image/verity_v2.cosi # UKI/usr-verity image (for usr-verity, combined configurations) -sudo ./tests/images/testimages.py build trident-usrverity-testimage \ - --output-dir ./artifacts/test-image --clones 2 -mv artifacts/test-image/trident-usrverity-testimage_0.cosi artifacts/test-image/usrverity.cosi -mv artifacts/test-image/trident-usrverity-testimage_1.cosi artifacts/test-image/usrverity_v2.cosi +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-verity-testimage -s deployment=host -s mode=usr --output-dir ./artifacts/test-image --clones 2 +mv artifacts/test-image/trident-verity-testimage_host_usr_amd64_cosi_clone0.cosi artifacts/test-image/usrverity.cosi +mv artifacts/test-image/trident-verity-testimage_host_usr_amd64_cosi_clone1.cosi artifacts/test-image/usrverity_v2.cosi ``` #### Container Runtime Images @@ -220,26 +217,23 @@ URLs work unchanged: mkdir -p artifacts/test-image # Regular container image -sudo ./tests/images/testimages.py build trident-container-testimage \ - --output-dir ./artifacts/test-image --clones 2 -mv artifacts/test-image/trident-container-testimage_0.cosi artifacts/test-image/regular.cosi -mv artifacts/test-image/trident-container-testimage_1.cosi artifacts/test-image/regular_v2.cosi +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-container-testimage --output-dir ./artifacts/test-image --clones 2 +mv artifacts/test-image/trident-container-testimage_amd64_cosi_clone0.cosi artifacts/test-image/regular.cosi +mv artifacts/test-image/trident-container-testimage_amd64_cosi_clone1.cosi artifacts/test-image/regular_v2.cosi # Verity container image (for root-verity configuration) -sudo ./tests/images/testimages.py build trident-container-verity-testimage \ - --output-dir ./artifacts/test-image --clones 2 -mv artifacts/test-image/trident-container-verity-testimage_0.cosi artifacts/test-image/verity.cosi -mv artifacts/test-image/trident-container-verity-testimage_1.cosi artifacts/test-image/verity_v2.cosi +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-verity-testimage -s deployment=container -s mode=root --output-dir ./artifacts/test-image --clones 2 +mv artifacts/test-image/trident-verity-testimage_container_root_amd64_cosi_clone0.cosi artifacts/test-image/verity.cosi +mv artifacts/test-image/trident-verity-testimage_container_root_amd64_cosi_clone1.cosi artifacts/test-image/verity_v2.cosi # UKI/usr-verity container image (for usr-verity, combined configurations) -sudo ./tests/images/testimages.py build trident-container-usrverity-testimage \ - --output-dir ./artifacts/test-image --clones 2 -mv artifacts/test-image/trident-container-usrverity-testimage_0.cosi artifacts/test-image/usrverity.cosi -mv artifacts/test-image/trident-container-usrverity-testimage_1.cosi artifacts/test-image/usrverity_v2.cosi +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-verity-testimage -s deployment=container -s mode=usr --output-dir ./artifacts/test-image --clones 2 +mv artifacts/test-image/trident-verity-testimage_container_usr_amd64_cosi_clone0.cosi artifacts/test-image/usrverity.cosi +mv artifacts/test-image/trident-verity-testimage_container_usr_amd64_cosi_clone1.cosi artifacts/test-image/usrverity_v2.cosi ``` -The images use the Image Customizer container from -`mcr.microsoft.com/azurelinux/imagecustomizer:latest`. +The workspace defaults to the Image Customizer container declared in +`tests/tailor-images/tailor.yaml` (`mcr.microsoft.com/azurelinux/imagecustomizer:latest`). ### 9. Build the Installer ISO @@ -255,8 +249,9 @@ make bin/trident-mos.iso **Container runtime:** ```bash -sudo ./tests/images/testimages.py build trident-container-installer \ - --output-dir ./artifacts +cargo run --manifest-path tools/tailor/Cargo.toml -- \ + --manifest tests/tailor-images/tailor.yaml \ + build trident-container-installer --output-dir ./artifacts ``` This builds `artifacts/trident-container-installer.iso` using Image Customizer. diff --git a/docs/Development/Testing/Functional-Tests.md b/docs/Development/Testing/Functional-Tests.md index 2a4d79b99f..a59aecc3e1 100644 --- a/docs/Development/Testing/Functional-Tests.md +++ b/docs/Development/Testing/Functional-Tests.md @@ -47,18 +47,17 @@ and a base image also from MCR. 1. **Download the base image:** ```bash - # Downloads baremetal.vhdx from mcr.microsoft.com/azurelinux/3.0/image/baremetal:latest - ./tests/images/testimages.py download-image baremetal + cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml bases download baremetal ``` 2. **Build the functional test image:** ```bash - sudo ./tests/images/testimages.py build trident-functest --output-dir ./artifacts + cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-functest --output-dir ./artifacts ``` - This produces `artifacts/trident-functest.qcow2`. The image configuration is - defined in `tests/images/trident-functest/base/baseimg.yaml`. + This produces `artifacts/trident-functest.qcow2`. The image is selected from + the `trident-functest` family in `tests/tailor-images/tailor.yaml`. ## Building Test Dependencies diff --git a/docs/Development/Testing/Rollback-Tests.md b/docs/Development/Testing/Rollback-Tests.md index 385fd77ee2..cf918beaea 100644 --- a/docs/Development/Testing/Rollback-Tests.md +++ b/docs/Development/Testing/Rollback-Tests.md @@ -7,7 +7,7 @@ sidebar_position: 8 Rollback tests validate manual rollback and runtime update workflows using `storm-trident run rollback`. Like [servicing tests](Servicing-Tests.md), they start from a pre-built VM image defined in -`tests/images/trident-vm-testimage/`, but focus specifically on the rollback +`tests/tailor-images/trident-vm-testimage/`, but focus specifically on the rollback chain: A/B updates, runtime updates (sysexts and netplan), and rolling each back in sequence. @@ -21,7 +21,7 @@ extensions: | `trident-vm-usr-verity-testimage` | systemd-boot | `/usr` verity | Yes | Sysexts supported | Required | | `trident-vm-grub-verity-testimage` | grub2 | Root verity | No | Not supported | Not needed | -All image configs live under `tests/images/trident-vm-testimage/base/`. The +All image configs live under `tests/tailor-images/trident-vm-testimage/base/`. The base image is `qemu_guest` (see [Servicing Tests — Download the qemu\_guest Base Image](Servicing-Tests.md#4-download-the-qemu_guest-base-image) for how to download it from the publicly available `minimal-os` image on MCR). @@ -128,7 +128,7 @@ TEST_IMAGE_NAME="trident-vm-usr-verity-testimage" sudo rm -f artifacts/trident-vm-*-testimage.qcow2 artifacts/trident-vm-*-testimage.cosi # Build the COSI and QCOW2 -sudo ./tests/images/testimages.py build $TEST_IMAGE_NAME --output-dir ./artifacts +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-vm-testimage -s arch=amd64 -s scenario=usr-verity --output-dir ./artifacts make artifacts/$TEST_IMAGE_NAME.qcow2 ``` diff --git a/docs/Development/Testing/Servicing-Tests.md b/docs/Development/Testing/Servicing-Tests.md index af1eb33b92..fe7ce9e4f0 100644 --- a/docs/Development/Testing/Servicing-Tests.md +++ b/docs/Development/Testing/Servicing-Tests.md @@ -10,7 +10,7 @@ Servicing tests validate multi-update workflows on pre-built VM images using from a QCOW2 image that already has Trident and an OS installed, then run repeated A/B updates with optional rollback testing. -The VM images are defined in `tests/images/trident-vm-testimage/` and built +The VM images are defined in `tests/tailor-images/trident-vm-testimage/` and built with Image Customizer from a `qemu_guest` base image downloaded from MCR. ## VM Image Types @@ -24,7 +24,7 @@ image types are: | `trident-vm-grub-verity-testimage` | grub2 | Root verity | No | `updateimg-grub-verity.yaml` | | `trident-vm-usr-verity-testimage` | systemd-boot | `/usr` verity | Yes | `baseimg-usr-verity.yaml` | -All image configs live under `tests/images/trident-vm-testimage/base/`. The +All image configs live under `tests/tailor-images/trident-vm-testimage/base/`. The base image is `qemu_guest` (see [step 4](#4-download-the-qemu_guest-base-image) for how to obtain it). @@ -105,7 +105,7 @@ step, so the base image's pre-installed package set does not matter. :::tip Internal shortcut If you have access to the internal Azure DevOps artifacts feed, the Makefile downloads `qemu_guest` automatically (requires `az login`). You can also -download it directly: `./tests/images/testimages.py download-image qemu_guest` +download it directly: `cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml bases download qemu_guest` ::: ### 5. Build the VM Image @@ -131,15 +131,12 @@ the same filename in each directory (the update loop picks the filename from ```bash mkdir -p artifacts/update-a artifacts/update-b -# Build two clones of the COSI image (produces _0 and _1 suffixed files) -sudo ./tests/images/testimages.py build trident-vm-grub-verity-testimage \ - --output-dir ./artifacts --clones 2 +# Build two clones of the COSI image +cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/tailor-images/tailor.yaml build trident-vm-testimage -s arch=amd64 -s scenario=grub-verity --output-dir ./artifacts --clones 2 # Move the clones into the update directories with the same filename -mv artifacts/trident-vm-grub-verity-testimage_0.cosi \ - artifacts/update-a/trident-vm-grub-verity-testimage.cosi -mv artifacts/trident-vm-grub-verity-testimage_1.cosi \ - artifacts/update-b/trident-vm-grub-verity-testimage.cosi +mv artifacts/trident-vm-testimage_amd64_grub-verity_cosi_clone0.cosi artifacts/update-a/trident-vm-grub-verity-testimage.cosi +mv artifacts/trident-vm-testimage_amd64_grub-verity_cosi_clone1.cosi artifacts/update-b/trident-vm-grub-verity-testimage.cosi ``` :::note diff --git a/tests/tailor-images/README.md b/tests/tailor-images/README.md index bb9666b62d..e3d7201ab0 100644 --- a/tests/tailor-images/README.md +++ b/tests/tailor-images/README.md @@ -48,9 +48,11 @@ remote source. ## Legacy name mapping -Pipelines still accept the historical image names. `tests/tailor-images/legacy-map.json` -maps each legacy name to the tailor image family, selectors, expected base slot, -and published artifact extension. +Pipelines and Make targets still accept the historical image names, but the +mapping is now declarative: each image family emits the legacy basename via +`outputs[].name`, while the remaining glue for aliases, clone suffixes, and +raw-to-`.cosi` compatibility lives directly in the Makefile / pipeline +templates. The current families are: diff --git a/tests/tailor-images/targets.mk b/tests/tailor-images/targets.mk new file mode 100644 index 0000000000..f7e3ea708c --- /dev/null +++ b/tests/tailor-images/targets.mk @@ -0,0 +1,113 @@ +CARGO_TAILOR ?= $(if $(shell command -v cargo 2>/dev/null),cargo,$(HOME)/.cargo/bin/cargo) +TAILOR_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) +TAILOR_WORKSPACE := $(TAILOR_DIR)/tailor.yaml +TAILOR_RPM_DEPS := bin/RPMS $(shell find bin/RPMS -name '*.rpm' 2>/dev/null) +VM_IMAGE_PATH_PREFIX := $(TAILOR_DIR)/trident-vm-testimage/base + +TRIDENT_INSTALLER_DEPS := $(shell find $(TAILOR_DIR)/trident-installer -type f 2>/dev/null) +TRIDENT_TESTIMAGE_DEPS := $(shell find $(TAILOR_DIR)/trident-testimage -type f 2>/dev/null) +TRIDENT_VERITY_TESTIMAGE_DEPS := $(shell find $(TAILOR_DIR)/trident-verity-testimage -type f 2>/dev/null) +TRIDENT_CONTAINER_INSTALLER_DEPS := $(shell find $(TAILOR_DIR)/trident-container-installer -type f 2>/dev/null) +TRIDENT_CONTAINER_TESTIMAGE_DEPS := $(shell find $(TAILOR_DIR)/trident-container-testimage -type f 2>/dev/null) +TRIDENT_FUNCTEST_DEPS := $(shell find $(TAILOR_DIR)/trident-functest -type f 2>/dev/null) +AZL_INSTALLER_TAILOR_DEPS := $(shell find $(AZL_INSTALLER_DIR) -type f 2>/dev/null) +AZURELINUX_DIRECT_STREAMING_DEPS := $(shell find $(TAILOR_DIR)/azurelinux-direct-streaming-testimage -type f 2>/dev/null) +FOREIGN_DIRECT_STREAMING_DEPS := $(shell find $(TAILOR_DIR)/foreign-direct-streaming-testimage -type f 2>/dev/null) +TRIDENT_VM_TESTIMAGE_DEPS := $(shell find $(TAILOR_DIR)/trident-vm-testimage -type f 2>/dev/null) $(VM_IMAGE_PATH_PREFIX)/files/id_rsa.pub + +COSI_TARGETS = \ + trident-testimage \ + trident-testimage-arm64 \ + trident-verity-testimage \ + trident-usrverity-testimage \ + trident-container-verity-testimage \ + trident-container-usrverity-testimage \ + trident-container-testimage \ + azurelinux-direct-streaming-testimage-amd64 \ + azurelinux-direct-streaming-testimage-arm64 \ + trident-vm-grub-testimage \ + trident-vm-grub-verity-testimage \ + trident-vm-root-verity-testimage \ + trident-vm-usr-verity-testimage \ + trident-vm-acl-agent-update-testimage \ + trident-vm-grub-verity-azure-testimage \ + trident-vm-grub-testimage-arm64 \ + trident-vm-grub-verity-testimage-arm64 \ + ubuntu-direct-streaming-testimage-2204-amd64 \ + ubuntu-direct-streaming-testimage-2204-arm64 \ + ubuntu-direct-streaming-testimage-2404-amd64 \ + ubuntu-direct-streaming-testimage-2404-arm64 \ + gb200-direct-streaming-testimage-2404-arm64 + +ISO_TARGETS = \ + trident-installer \ + trident-split-installer \ + trident-installer-arm64 \ + trident-container-installer \ + trident-direct-streaming-installer-amd64 \ + trident-direct-streaming-installer-arm64 \ + azl-installer + +.PHONY: $(COSI_TARGETS) $(ISO_TARGETS) all-cosi all-iso +$(COSI_TARGETS): %: artifacts/%.cosi +$(filter-out azl-installer,$(ISO_TARGETS)): %: artifacts/%.iso +azl-installer: $(ARTIFACTS_TEST_IMAGE_DIR)/azl-installer.iso + +all-cosi: $(COSI_TARGETS) +all-iso: $(ISO_TARGETS) + +define declare_tailor_target +$1: $(TAILOR_WORKSPACE) $4 + @echo "Building '$$(@F)' [$@]" + @echo "Prerequisites:" + @echo "$$^" | tr ' ' '\n' | sed 's/^/ /' + rm -f $(TAILOR_DIR)/artifacts/ca_cert.pem + $(CARGO_TAILOR) run --manifest-path tools/tailor/Cargo.toml --quiet -- --manifest $(TAILOR_WORKSPACE) build $2 $3 --output-dir $(dir $1) + @if [ -f $(TAILOR_DIR)/artifacts/ca_cert.pem ]; then cp $(TAILOR_DIR)/artifacts/ca_cert.pem "$(dir $1)/ca_cert.pem"; fi + @if [ "$1" != "$5" ]; then cp "$5" "$1"; fi + @$6 +endef + +$(eval $(call declare_tailor_target,artifacts/trident-installer.iso,trident-installer,-s arch=amd64 -s variant=default,$(TRIDENT_INSTALLER_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx,artifacts/trident-installer.iso,:)) +$(eval $(call declare_tailor_target,artifacts/trident-split-installer.iso,trident-installer,-s arch=amd64 -s variant=split,$(TRIDENT_INSTALLER_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx,artifacts/trident-split-installer.iso,:)) +$(eval $(call declare_tailor_target,artifacts/trident-installer-arm64.iso,trident-installer,-s arch=arm64 -s variant=default,$(TRIDENT_INSTALLER_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_arm64.vhdx,artifacts/trident-installer-arm64.iso,:)) +$(eval $(call declare_tailor_target,artifacts/trident-direct-streaming-installer-amd64.iso,trident-installer,-s arch=amd64 -s variant=direct-streaming,$(TRIDENT_INSTALLER_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx artifacts/rcp-agent artifacts/rcp-agent.service,artifacts/trident-direct-streaming-installer-amd64.iso,:)) +$(eval $(call declare_tailor_target,artifacts/trident-direct-streaming-installer-arm64.iso,trident-installer,-s arch=arm64 -s variant=direct-streaming,$(TRIDENT_INSTALLER_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_arm64.vhdx artifacts/rcp-agent artifacts/rcp-agent.service,artifacts/trident-direct-streaming-installer-arm64.iso,:)) +$(eval $(call declare_tailor_target,artifacts/trident-container-installer.iso,trident-container-installer,,$(TRIDENT_CONTAINER_INSTALLER_DEPS) artifacts/baremetal.vhdx,artifacts/trident-container-installer.iso,:)) +$(eval $(call declare_tailor_target,artifacts/trident-functest.qcow2,trident-functest,,$(TRIDENT_FUNCTEST_DEPS) artifacts/baremetal.vhdx,artifacts/trident-functest.qcow2,:)) +$(eval $(call declare_tailor_target,artifacts/trident-testimage.cosi,trident-testimage,-s arch=amd64,$(TRIDENT_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx,artifacts/trident-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-testimage-arm64.cosi,trident-testimage,-s arch=arm64,$(TRIDENT_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_arm64.vhdx,artifacts/trident-testimage-arm64.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-verity-testimage.cosi,trident-verity-testimage,-s deployment=host -s mode=root,$(TRIDENT_VERITY_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx,artifacts/trident-verity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-usrverity-testimage.cosi,trident-verity-testimage,-s deployment=host -s mode=usr,$(TRIDENT_VERITY_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx,artifacts/trident-usrverity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-container-verity-testimage.cosi,trident-verity-testimage,-s deployment=container -s mode=root,$(TRIDENT_VERITY_TESTIMAGE_DEPS) artifacts/baremetal.vhdx,artifacts/trident-container-verity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-container-usrverity-testimage.cosi,trident-verity-testimage,-s deployment=container -s mode=usr,$(TRIDENT_VERITY_TESTIMAGE_DEPS) artifacts/baremetal.vhdx,artifacts/trident-container-usrverity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-container-testimage.cosi,trident-container-testimage,,$(TRIDENT_CONTAINER_TESTIMAGE_DEPS) artifacts/baremetal.vhdx,artifacts/trident-container-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/azurelinux-direct-streaming-testimage-amd64.cosi,azurelinux-direct-streaming-testimage,-s arch=amd64,$(AZURELINUX_DIRECT_STREAMING_DEPS) $(TAILOR_RPM_DEPS) artifacts/baremetal.vhdx,artifacts/azurelinux-direct-streaming-testimage-amd64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/azurelinux-direct-streaming-testimage-arm64.cosi,azurelinux-direct-streaming-testimage,-s arch=arm64,$(AZURELINUX_DIRECT_STREAMING_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_arm64.vhdx,artifacts/azurelinux-direct-streaming-testimage-arm64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/ubuntu-direct-streaming-testimage-2204-amd64.cosi,foreign-direct-streaming-testimage,-s arch=amd64 -s source=ubuntu-2204,$(FOREIGN_DIRECT_STREAMING_DEPS) artifacts/ubuntu_2204_amd64.vhdx,artifacts/ubuntu-direct-streaming-testimage-2204-amd64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/ubuntu-direct-streaming-testimage-2204-arm64.cosi,foreign-direct-streaming-testimage,-s arch=arm64 -s source=ubuntu-2204,$(FOREIGN_DIRECT_STREAMING_DEPS) artifacts/ubuntu_2204_arm64.vhdx,artifacts/ubuntu-direct-streaming-testimage-2204-arm64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/ubuntu-direct-streaming-testimage-2404-amd64.cosi,foreign-direct-streaming-testimage,-s arch=amd64 -s source=ubuntu-2404,$(FOREIGN_DIRECT_STREAMING_DEPS) artifacts/ubuntu_2404_amd64.vhdx,artifacts/ubuntu-direct-streaming-testimage-2404-amd64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/ubuntu-direct-streaming-testimage-2404-arm64.cosi,foreign-direct-streaming-testimage,-s arch=arm64 -s source=ubuntu-2404,$(FOREIGN_DIRECT_STREAMING_DEPS) artifacts/ubuntu_2404_arm64.vhdx,artifacts/ubuntu-direct-streaming-testimage-2404-arm64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/gb200-direct-streaming-testimage-2404-arm64.cosi,foreign-direct-streaming-testimage,-s arch=arm64 -s source=gb200-2404,$(FOREIGN_DIRECT_STREAMING_DEPS) artifacts/gb200_2404_arm64.vhdx,artifacts/gb200-direct-streaming-testimage-2404-arm64.raw,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-testimage.cosi,trident-vm-testimage,-s arch=amd64 -s scenario=grub,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-grub-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-verity-testimage.cosi,trident-vm-testimage,-s arch=amd64 -s scenario=grub-verity,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-grub-verity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-verity-testimage.qcow2,trident-vm-testimage,-s arch=amd64 -s scenario=grub-verity-base,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-grub-verity-testimage.qcow2,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-root-verity-testimage.cosi,trident-vm-testimage,-s arch=amd64 -s scenario=root-verity,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-root-verity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-usr-verity-testimage.cosi,trident-vm-testimage,-s arch=amd64 -s scenario=usr-verity,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-usr-verity-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-usr-verity-testimage.qcow2,trident-vm-testimage,-s arch=amd64 -s scenario=usr-verity,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-usr-verity-testimage.qcow2,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-acl-agent-update-testimage.cosi,trident-vm-testimage,-s arch=amd64 -s scenario=acl-agent,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-acl-agent-update-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-acl-agent-testimage.qcow2,trident-vm-testimage,-s arch=amd64 -s scenario=acl-agent,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/qemu_guest.vhdx,artifacts/trident-vm-acl-agent-testimage.qcow2,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-verity-azure-testimage.cosi,trident-vm-testimage,-s arch=amd64 -s scenario=grub-verity-azure,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_selinux.vhdx,artifacts/trident-vm-grub-verity-azure-testimage.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-verity-azure-testimage.vhd,trident-vm-testimage,-s arch=amd64 -s scenario=grub-verity-azure,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_selinux.vhdx,artifacts/trident-vm-grub-verity-azure-testimage.vhd,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-testimage-arm64.cosi,trident-vm-testimage,-s arch=arm64 -s scenario=grub,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_arm64.vhdx,artifacts/trident-vm-grub-testimage-arm64.cosi,:)) +$(eval $(call declare_tailor_target,artifacts/trident-vm-grub-verity-testimage-arm64.cosi,trident-vm-testimage,-s arch=arm64 -s scenario=grub-verity,$(TRIDENT_VM_TESTIMAGE_DEPS) $(TAILOR_RPM_DEPS) artifacts/core_arm64.vhdx,artifacts/trident-vm-grub-verity-testimage-arm64.cosi,:)) + +$(ARTIFACTS_TEST_IMAGE_DIR)/azl-installer.iso: $(TAILOR_WORKSPACE) $(AZL_INSTALLER_TAILOR_DEPS) $(TAILOR_RPM_DEPS) bin/liveinstaller artifacts/baremetal.vhdx $(ARTIFACTS_TEST_IMAGE_DIR)/regular.cosi + rm -rf $(AZL_INSTALLER_ISO_DIR)/images + mkdir -p $(AZL_INSTALLER_ISO_DIR)/images + cp $(ARTIFACTS_TEST_IMAGE_DIR)/regular.cosi $(AZL_INSTALLER_ISO_DIR)/images/trident-testimage.cosi + rm -rf $(AZL_INSTALLER_ISO_DIR)/bin + mkdir -p $(AZL_INSTALLER_ISO_DIR)/bin + cp bin/liveinstaller $(AZL_INSTALLER_ISO_DIR)/bin/ + rm -f $(TAILOR_DIR)/artifacts/ca_cert.pem + $(CARGO_TAILOR) run --manifest-path tools/tailor/Cargo.toml --quiet -- --manifest $(TAILOR_WORKSPACE) build azl-installer --output-dir $(ARTIFACTS_TEST_IMAGE_DIR)