Skip to content

Migrate tests/images to tailor - #841

Draft
bfjelds (bfjelds) wants to merge 16 commits into
mainfrom
user/bfjelds/tailor-testimages
Draft

bfjelds (bfjelds) wants to merge 16 commits into
mainfrom
user/bfjelds/tailor-testimages

Conversation

@bfjelds

@bfjelds bfjelds (bfjelds) commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

  • replace tests/images/testimages.py and tests/images/builder/ with a tailor workspace under tests/images/
  • migrate both legacy entry points that previously depended on that Python CLI:
    • the direct/pipeline build_image template path
    • the older root Makefile + trident_images pipeline path used by direct-streaming jobs
  • express the legacy image set as tailor image families plus matrix/fragments and a shared base-image catalogue
  • add tests/images/legacy-map.json and tests/images/legacy_targets.py so existing legacy image names still resolve to the correct tailor cell selectors
  • update local docs and the active pipeline templates to use tailor commands/selectors
  • factor duplicated per-scenario Image Customizer YAML into family-local include/ snippets and smaller delta fragments
  • stage direct-streaming installer inputs under artifacts/ so every IC-referenced file stays within tailor's actual bind-mount set

Workspace structure

  • tests/images/tailor.yaml
    • toolchain: mcr.microsoft.com/azurelinux/imagecustomizer:latest
    • signing preview enabled with a local test CA profile
    • base-image catalogue for Azure Linux, QEMU guest, Ubuntu, and GB200 inputs
  • tests/images/trident-installer/image.yaml
    • matrix: arch x variant
    • cells replace: trident-installer, trident-split-installer, trident-installer-arm64, trident-direct-streaming-installer-{amd64,arm64}
    • shared installer storage/packages/files are now factored under tests/images/trident-installer/include/
    • direct-streaming-only rcp-agent inputs are staged under artifacts/ and scoped only to the direct-streaming variant
  • tests/images/trident-testimage/image.yaml
    • matrix: arch
    • cells replace: trident-testimage, trident-testimage-arm64
  • tests/images/trident-verity-testimage/image.yaml
    • matrix: deployment x mode
    • cells replace: trident-verity-testimage, trident-usrverity-testimage, trident-container-verity-testimage, trident-container-usrverity-testimage
    • shared root/usr blocks now live under tests/images/trident-verity-testimage/include/
  • tests/images/trident-vm-testimage/image.yaml
    • matrix: arch x scenario
    • cells replace: the 8 legacy VM update/test images
    • shared grub / grub-verity / uki-verity blocks now live under tests/images/trident-vm-testimage/include/
  • single-family manifests for azl-installer, trident-container-installer, trident-container-testimage, trident-functest, and azurelinux-direct-streaming-testimage
  • tests/images/foreign-direct-streaming-testimage/image.yaml
    • operation: convert
    • matrix covers the Ubuntu / GB200 direct-streaming images

Validation

Validated with the in-tree tailor CLI:

  • tailor validate on the full workspace: 10 image families / 30 cells valid
  • tailor matrix --format slugs before and after the include refactor: identical slug list
  • representative tailor build --dry-run checks for:
    • azl-installer
    • azurelinux-direct-streaming-testimage arm64
    • foreign-direct-streaming-testimage arm64 Ubuntu 24.04
    • trident-container-installer
    • trident-container-testimage
    • trident-functest
    • trident-installer arm64 direct-streaming
    • trident-testimage arm64
    • trident-verity-testimage container+usr
    • trident-vm-testimage amd64 acl-agent
    • trident-vm-testimage amd64 root-verity
    • trident-vm-testimage amd64 usr-verity
  • rendered-config comparison for trident-vm-testimage root-verity and usr-verity before vs after the include refactor: identical after unwrapping the old top-level $set wrapper in the pre-refactor render
  • old vs new legacy target sets:
    • all-cosi: identical (22 names)
    • all-iso: identical (7 names)
  • make -n checks for the previously failing direct-streaming targets:
    • artifacts/ubuntu-direct-streaming-testimage-2204-amd64.cosi
    • artifacts/ubuntu-direct-streaming-testimage-2404-amd64.cosi
    • artifacts/ubuntu-direct-streaming-testimage-2204-arm64.cosi
    • artifacts/ubuntu-direct-streaming-testimage-2404-arm64.cosi
  • real end-to-end Makefile run: make artifacts/trident-functest.qcow2 succeeded and produced the qcow2 through the new helper + tailor path
  • real direct-streaming installer verification:
    • make artifacts/trident-direct-streaming-installer-amd64.iso succeeded
    • direct-tailor equivalent cargo run --manifest-path tools/tailor/Cargo.toml -- --manifest tests/images/tailor.yaml build trident-installer -s arch=amd64 -s variant=direct-streaming --output-dir artifacts succeeded after staging artifacts/rcp-agent and artifacts/rcp-agent.service
    • arm64 dry-run validated the staged-path fix and rendered config, but a real local arm64 build on this host is blocked by the available local Image Customizer image being amd64-only (toolchain \ic` local image is `amd64` but cell `trident-installer_arm64_direct-streaming_iso` targets `arm64``)

Compatibility and known follow-ups

  • tailor's published filenames are cell slugs, so both the pipeline path and the Makefile path use tests/images/legacy-map.json plus a post-build rename step to preserve the historical artifact names expected by downstream jobs
  • tailor publishes baremetal-image artifacts as .raw; the rename layer preserves the legacy .cosi filenames for the existing direct-streaming jobs. Direct local tailor builds keep tailor's native slug/extension
  • the dev Image Customizer override is preserved by patching the workspace toolchain to imagecustomizer:dev in the migrated pipeline path, and by forwarding MIC_CONTAINER_IMAGE through the migrated Makefile helper path
  • tailor only bind-mounts the workspace root, the output directory, and explicit rpmSources paths. Any IC config file or extraDependencies path that escapes those roots must be staged into a mounted path (now artifacts/ for the direct-streaming installer's rcp-agent inputs)
  • the AZL installer flow still depends on pipeline-staged liveinstaller and trident-testimage.cosi, and the Ubuntu / GB200 direct-streaming bases still depend on externally staged base images

Follow-up #5: per-cell signing regression fix

Root cause found and fixed:

  • tests/images/trident-verity-testimage/by-mode/usr.yaml sets signing: true, but tailor was dropping fragment-level signing during render/planning.
  • tailor-config fragments did not deserialize signing, RenderedCell/Cell did not carry it, and tailor keyed signing by image definition name instead of the selected cell.
  • Result: the failing usr verity cell ran as a plain single-pass customize build instead of the signed 3-pass flow, so no CA cert was published into the image bundle.
  • That matches the failing VM logs: the branch's netlaunch invocation lacked --signing-cert, unlike the known-good baseline, and the deployed target then failed to boot after the installer reboot.

Fix in this push:

  • propagate fragment-level signing through tailor-config render -> tailor-core::Cell -> tailor::run
  • resolve/build signers per selected cell slug, not per image family
  • clean signed CA-cert sidecars per selected cell
  • copy tests/images/artifacts/ca_cert.pem into the published output directory for both pipeline entry paths and the legacy Makefile helper

Local verification:

  • cargo check --manifest-path tools/tailor/Cargo.toml -p tailor -p tailor-core -p tailor-config -p tailor-sign -p tailor-exec
  • dry-run unsigned root cell still shows a single customize pass
  • dry-run failing usr cell now shows:
    • signed 3-pass
    • pass 1/3: customize -> raw intermediate
    • pass 2/3: host-side sign ... publish CA -> ...ca_cert.pem
    • pass 3/3: inject-files -> final cosi
  • real build of trident-verity-testimage -s deployment=host -s mode=usr now regenerates tests/images/artifacts/ca_cert.pem
  • real python3 tests/images/legacy_targets.py build trident-usrverity-testimage --output-path artifacts/legacy-usrverity.cosi now copies artifacts/ca_cert.pem

Follow-up #6: signed build jobs use pesign fallback on AZL

Correction to the earlier analysis: the pre-migration Trident image signer did not use sbsign; main:tests/images/builder/sign.py used efikeygen/certutil/pk12util/pesign, and the AZL build-image jobs already provision pesign (sudo tdnf install -y ... pesign). The regression was therefore not “CI forgot to install an always-required tool”, but a tailor tool-choice mismatch: the new generic signer hardcoded sbsign for PE/UKI signing even though Trident's existing AZL pipeline/tooling standardizes on pesign.

Observed failure text from the restored signing path (reproduced directly by removing sbsign from PATH on the same branch):

error: signing preflight failed — fix every prerequisite below, then rebuild:
  - profile `test-ca` (needed by: trident-verity-testimage_host_usr_amd64_cosi): `sbsign` not found on PATH (required to sign PE/UKI boot artifacts)

Final fix in this push:

  • tailor-sign now signs PE artifacts with sbsign when present, or falls back to pesign when sbsign is absent but pesign + certutil + pk12util are available
  • the pesign path builds a temporary NSS DB, exports the generated PEM key/cert to PKCS#12, imports it into NSS, handles the historical pesign --certficate typo variant, and signs the EFI artifact in place
  • dry-run/help/comments/docs now describe sbsign/pesign instead of only sbsign
  • the temporary Ubuntu-pool / sbsigntool pipeline workaround from the previous push is reverted; the normal AZL build-image jobs remain unchanged

Verification:

  • cargo check --manifest-path tools/tailor/Cargo.toml -p tailor-sign -p tailor-exec -p tailor
  • cargo test --manifest-path tools/tailor/Cargo.toml -p tailor-sign --lib
  • cargo test --manifest-path tools/tailor/Cargo.toml -p tailor --test signing
  • with /usr/bin/sbsign temporarily moved out of PATH, a real signed build still succeeds:
    • cargo run --manifest-path tools/tailor/Cargo.toml --quiet -- --manifest tests/images/tailor.yaml build trident-verity-testimage -s deployment=host -s mode=usr --output-dir artifacts
    • output image produced successfully
    • tests/images/artifacts/ca_cert.pem published successfully
  • sbsign was restored afterward

Replace the tests/images Python builder with a tailor workspace and legacy image-name mapping. Update the image build pipeline and local docs to use tailor commands and selectors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

bfjelds (bfjelds) and others added 14 commits October 9, 2026 22:32
Replace per-scenario full YAML copies with shared include snippets and smaller delta fragments in the installer, verity, and VM image families. Preserve the existing matrix cells and rendered configs while reducing duplicated Image Customizer config.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
….yml

The python3 <<PY heredoc bodies and their terminators/closing parens were
written at column 0 inside bash: | block literals. YAML strips only the
common leading indentation established by the first line of the block, so
any line with less indentation (here, 0 vs the required 6 spaces) ends the
block scalar early and is parsed as a new top-level mapping key, causing:

  While scanning a simple key, could not find expected ':'

Indenting every heredoc body/terminator/closing-paren line to match the
block's 6-space indent keeps them inside the literal block; YAML strips
the shared indent back off before bash/python ever see the text, so the
resulting script is unchanged. Verified by extracting each step's bash
script from the parsed YAML, bash -n syntax-checking it, and tracing
execution of the affected heredocs against the real legacy-map.json.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build-image-template.yml runs `cargo run --manifest-path tools/tailor/Cargo.toml`
to build images, but never ran the CargoAuthenticate@0 task first. Every other
job in this pipeline that invokes cargo (check.yml, functional-testing.yml,
dev-build.yml, etc.) includes `../common_tasks/cargo-auth.yml` before doing so;
this template was missing it, so cargo failed to resolve the crates-io mirror:

  error: failed to get `clap` as a dependency of package `tailor v1.3.0 ...`
  Caused by: authenticated registries require a credential-provider to be
  configured

That caused the bash step to exit 101 before tailor ever ran, which in turn
left $(ob_outputDirectory) (/tmp/output) never created by tailor (tailor
itself does `fs::create_dir_all(output_dir)`, so it would have created it on
a successful run) - hence the secondary "Path does not exist: /tmp/output"
error surfaced by the output-publishing step.

Add the same `cargo-auth.yml` template step used elsewhere in this pipeline,
pointed at $(TRIDENT_SOURCE_DIR)/.cargo/config.toml per the existing
convention (set by common_tasks/checkout_trident.yml).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the root Makefile test image integration with a legacy-name helper that resolves into tailor selectors, updates base-image download rules, and removes the remaining deleted testimages.py call sites used by the older direct-streaming pipeline path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Check amd64 pipeline job's "Check Python Formatting" step runs
`black --check .` over the whole repo and failed because the new
tests/images/legacy_targets.py shim was not Black-formatted. Reformat with
black==24.1.0 (matching the version pinned in CI) to fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…acy_targets.py

dependencies() base_dep_map only listed baremetal/core_selinux/core_arm64/
qemu_guest, so `make artifacts/ubuntu-direct-streaming-testimage-*.cosi`
never pulled in the Ubuntu cloud image as a prerequisite before invoking
tailor build. The Makefile's own curl+qemu-img-convert rules for
artifacts/ubuntu_22{0,4}4_{amd64,arm64}.vhdx were preserved by the earlier
Makefile migration, but nothing wired them in as dependencies anymore,
so tailor failed with "failed to read local base ... No such file or
directory" (reproduced locally).

Add the four ubuntu_*_vhdx entries to base_dep_map, keyed by the same
baseImage values already present in tests/images/legacy-map.json.

Note: gb200_2404_arm64 has no equivalent Makefile download rule on main
either (pre-existing gap, not introduced by this migration) and is gated
off by default in the pipeline (testGB200StreamingImage: false), so it is
not fixed here - flagging as a known follow-up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pendency

GB200 had no existing Makefile rule or legacy_targets.py dependency entry
on main either - the pipeline staged artifacts/gb200_2404_arm64.vhdx purely
via a dedicated az storage blob download step
(.pipelines/templates/stages/trident_images/trident-testimg-template.yml),
bypassing the Makefile entirely. Add a Makefile rule mirroring that same
az CLI download (for local/dev builds with access to the azlinuxbmpstaging
storage account), and register it in legacy_targets.py's base_dep_map so
make correctly tracks it as a prerequisite, consistent with the other base
images.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
.pipelines/templates/stages/trident_images/build-image.yml and
build-image-arm64.yml drive the "Prepare Image <label>" jobs (installer,
direct-streaming, ubuntu/gb200 images) via `make <target>`. These jobs
never needed cargo before, since testimages.py was pure Python. Now that
the Makefile's tailor-backed targets run
`cargo run --manifest-path tools/tailor/Cargo.toml`, a Rust toolchain is
required.

This went unnoticed for amd64 because that host pool happens to already
have cargo preinstalled, but "Prepare Image ubuntu-direct-streaming-
testimage-2404-arm64" runs on azl3-hci-ARM64-1es-pool-westcentralus,
which does not, and failed with "cargo not found" (confirmed from the
build 1221421 log). Add the same ../common_tasks/rustup.yml +
cargo-auth.yml steps used elsewhere in this pipeline to both job
templates.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…fallback

legacy_targets.py's cargo_cmd() had a hardcoded /home/bfjelds/.cargo/bin/cargo
fallback left over from local development - not valid for CI or any other
contributor. Replace with a clear error message pointing at how cargo is
provisioned in CI (../common_tasks/rustup.yml).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…perations

Image Customizer's `convert` subcommand has no --image-cache-dir flag (only
`customize` downloads/caches OCI or azureLinux base images) and rejects
unknown flags outright, printing its own usage and exiting 80. tailor's
resolve_image_cache_dir() unconditionally configures a default cache dir for
every build, and build_ic_args() was emitting --image-cache-dir for every
operation instead of gating it like the adjacent --tools-dir/--rpm-source
block does. This broke every tailor-based convert build (discovered via the
tests/images/foreign-direct-streaming-testimage cells added in this same PR
for the Ubuntu/GB200 direct-streaming test images - confirmed end-to-end
with a real `make artifacts/ubuntu-direct-streaming-testimage-2204-amd64.cosi`
run after this fix, which now runs IC convert successfully).

Gate the --image-cache-dir flag in build_ic_args() behind
operation == Operation::Customize, matching the existing tools-dir/rpm-source
gating. build_signed_customize_args() is unconditionally customize-only by
construction, so it is intentionally left as-is. Extend the existing
builds_convert_args_without_config_or_rpm_sources test to assert
--image-cache-dir is absent from a convert cell's args.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the direct-streaming installer s rcp-agent inputs under artifacts/ so tailors container bind set can see them from both the direct-tailor and Makefile-driven pipeline paths. Also scope the dependency to the direct-streaming variant and align the supporting Makefile/base-image rules.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Propagate fragment-level signing through render/build selection so signed usr-verity cells take the signed three-pass path again. Also publish ca_cert.pem with both image pipeline entry points and the legacy target helper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The usr-verity image builds now trigger tailor's host-side signing path, which requires sbsign. Pin those two build_image jobs to the Ubuntu pool and install sbsigntool there so the signed builds have the required host tooling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use pesign with a temporary NSS database when sbsign is unavailable, so signed usr-verity builds work on AZL/Mariner hosts that already provision pesign tooling. This also drops the temporary Ubuntu-pool workaround from the build-image pipeline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Required test fixtures do not compile, signing is absent from incremental fingerprints, and one migrated pipeline lacks Rust installation.

4 open findings
What changed in this PR

Migrates test-image construction from the legacy Python builder to Tailor, preserving legacy artifact names and pipeline entry points while adding per-cell signing support.

Changes:

  • Defines Tailor image families, matrices, fragments, and compatibility mappings.
  • Updates Makefile, pipelines, and documentation to use Tailor.
  • Adds per-cell signing propagation and pesign fallback support.
File Description
tools/​tailor/​docs/​explanation/​crate-architecture.md Documents pesign support.
tools/​tailor/​crates/​tailor/​src/​run.rs Resolves signing per selected cell.
tools/​tailor/​crates/​tailor-sign/​src/​lib.rs Adds the pesign fallback.
tools/​tailor/​crates/​tailor-exec/​src/​arg_builder.rs Fixes convert arguments and signing output.
tools/​tailor/​crates/​tailor-core/​src/​signing.rs Updates signing documentation.
tools/​tailor/​crates/​tailor-core/​src/​ports.rs Updates signer contract documentation.
tools/​tailor/​crates/​tailor-core/​src/​orchestrator.rs Propagates cell signing metadata.
tools/​tailor/​crates/​tailor-core/​src/​domain.rs Adds signing to Cell.
tools/​tailor/​crates/​tailor-config/​src/​render.rs Merges fragment signing configuration.
tools/​tailor/​crates/​tailor-config/​src/​fragment.rs Deserializes fragment signing fields.
tests/​images/​trident-vm-testimage/​include/​uki-verity-scripts.yaml Factors UKI scripts.
tests/​images/​trident-vm-testimage/​include/​uki-verity-os-common.yaml Factors shared UKI OS configuration.
tests/​images/​trident-vm-testimage/​include/​storage-usr-verity.yaml Defines usr-verity storage.
tests/​images/​trident-vm-testimage/​include/​storage-root-verity.yaml Defines root-verity storage.
tests/​images/​trident-vm-testimage/​include/​storage-grub.yaml Defines GRUB storage.
tests/​images/​trident-vm-testimage/​include/​storage-grub-verity.yaml Defines GRUB-verity storage.
tests/​images/​trident-vm-testimage/​include/​storage-acl-agent.yaml Defines ACL-agent storage.
tests/​images/​trident-vm-testimage/​include/​grub-verity-scripts.yaml Factors GRUB-verity scripts.
tests/​images/​trident-vm-testimage/​include/​grub-verity-os-common.yaml Factors GRUB-verity OS configuration.
tests/​images/​trident-vm-testimage/​include/​grub-scripts.yaml Factors GRUB scripts.
tests/​images/​trident-vm-testimage/​include/​grub-os-common.yaml Factors GRUB OS configuration.
tests/​images/​trident-vm-testimage/​image.yaml Defines the VM image matrix.
tests/​images/​trident-vm-testimage/​by-scenario/​usr-verity.yaml Configures usr-verity cells.
tests/​images/​trident-vm-testimage/​by-scenario/​root-verity+usr-verity+acl-agent.yaml Shares UKI scenario settings.
tests/​images/​trident-vm-testimage/​by-scenario/​root-verity.yaml Configures root-verity cells.
tests/​images/​trident-vm-testimage/​by-scenario/​grub.yaml Configures GRUB cells.
tests/​images/​trident-vm-testimage/​by-scenario/​grub-verity+grub-verity-azure.yaml Shares GRUB-verity settings.
tests/​images/​trident-vm-testimage/​by-scenario/​grub-verity.yaml Configures GRUB-verity cells.
tests/​images/​trident-vm-testimage/​by-scenario/​grub-verity-azure.yaml Configures Azure GRUB-verity cells.
tests/​images/​trident-vm-testimage/​by-scenario/​acl-agent.yaml Configures ACL-agent cells.
tests/​images/​trident-vm-testimage/​by-arch/​arm64.yaml Selects the ARM64 base.
tests/​images/​trident-verity-testimage/​README.md Documents Tailor selectors.
tests/​images/​trident-verity-testimage/​include/​usr-storage.yaml Factors usr storage.
tests/​images/​trident-verity-testimage/​include/​usr-os-common.yaml Factors usr OS settings.
tests/​images/​trident-verity-testimage/​include/​root-storage.yaml Factors root storage.
tests/​images/​trident-verity-testimage/​include/​root-os-common.yaml Factors root OS settings.
tests/​images/​trident-verity-testimage/​image.yaml Defines the verity matrix.
tests/​images/​trident-verity-testimage/​by-mode/​usr.yaml Enables signing for usr cells.
tests/​images/​trident-verity-testimage/​by-mode/​root.yaml Configures root cells.
tests/​images/​trident-verity-testimage/​by-deployment+mode/​host+usr.yaml Configures host usr cells.
tests/​images/​trident-verity-testimage/​by-deployment+mode/​host+root.yaml Configures host root cells.
tests/​images/​trident-verity-testimage/​by-deployment+mode/​container+usr.yaml Configures container usr cells.
tests/​images/​trident-verity-testimage/​by-deployment+mode/​container+root.yaml Configures container root cells.
tests/​images/​trident-verity-testimage/​by-deployment/​host.yaml Adds host RPM sources.
tests/​images/​trident-verity-testimage/​by-deployment/​container.yaml Configures container features.
tests/​images/​trident-testimage/​tailor/​baseimg.yaml Ports the test-image configuration.
tests/​images/​trident-testimage/​README.md Documents Tailor builds.
tests/​images/​trident-testimage/​image.yaml Defines the architecture matrix.
tests/​images/​trident-testimage/​by-arch/​arm64.yaml Selects the ARM64 base.
tests/​images/​trident-installer/​README.md Documents installer selectors.
tests/​images/​trident-installer/​include/​storage.yaml Factors installer storage.
tests/​images/​trident-installer/​include/​kernel-args.yaml Factors installer kernel arguments.
tests/​images/​trident-installer/​include/​common-packages.yaml Factors installer packages.
tests/​images/​trident-installer/​include/​common-files.yaml Factors installer files.
tests/​images/​trident-installer/​image.yaml Defines the installer matrix.
tests/​images/​trident-installer/​by-variant/​split.yaml Configures split installers.
tests/​images/​trident-installer/​by-variant/​direct-streaming.yaml Configures direct-streaming installers.
tests/​images/​trident-installer/​by-arch/​arm64.yaml Selects the ARM64 base.
tests/​images/​trident-installer/​base/​baseimg-direct-streaming.yaml Uses staged RCP inputs.
tests/​images/​trident-functest/​tailor/​baseimg.yaml Ports the functional-test image.
tests/​images/​trident-functest/​image.yaml Defines the functional-test family.
tests/​images/​trident-container-testimage/​tailor/​baseimg.yaml Ports the container test image.
tests/​images/​trident-container-testimage/​README.md Documents Tailor builds.
tests/​images/​trident-container-testimage/​image.yaml Defines the container test family.
tests/​images/​trident-container-installer/​tailor/​baseimg.yaml Ports the container installer.
tests/​images/​trident-container-installer/​README.md Documents Tailor builds.
tests/​images/​trident-container-installer/​image.yaml Defines the container installer family.
tests/​images/​testimages.py Removes the legacy CLI.
tests/​images/​tailor.yaml Defines the Tailor workspace and catalogue.
tests/​images/​README.md Documents the new workspace.
tests/​images/​legacy-map.json Maps legacy names to Tailor cells.
tests/​images/​legacy_targets.py Implements legacy command compatibility.
tests/​images/​foreign-direct-streaming-testimage/​image.yaml Defines foreign conversion cells.
tests/​images/​foreign-direct-streaming-testimage/​by-source/​ubuntu-2404.yaml Selects Ubuntu 24.04.
tests/​images/​foreign-direct-streaming-testimage/​by-source/​gb200-2404.yaml Selects GB200.
tests/​images/​foreign-direct-streaming-testimage/​by-arch+source/​arm64+ubuntu-2404.yaml Selects ARM64 Ubuntu 24.04.
tests/​images/​foreign-direct-streaming-testimage/​by-arch+source/​arm64+ubuntu-2204.yaml Selects ARM64 Ubuntu 22.04.
tests/​images/​builder/​utils.py Removes legacy path utilities.
tests/​images/​builder/​sign.py Removes legacy signing code.
tests/​images/​builder/​run.py Removes legacy orchestration.
tests/​images/​builder/​README.md Removes legacy builder documentation.
tests/​images/​builder/​download.py Removes legacy download support.
tests/​images/​builder/​customize.py Removes the old IC wrapper.
tests/​images/​builder/​convert.py Removes the old conversion wrapper.
tests/​images/​builder/​context_managers.py Removes legacy resource helpers.
tests/​images/​builder/​cli.py Removes the legacy CLI implementation.
tests/​images/​builder/​builder.py Removes the legacy build engine.
tests/​images/​builder/​__init__.py Removes legacy image models.
tests/​images/​azurelinux-direct-streaming-testimage/​tailor/​baseimg.yaml Ports the Azure Linux streaming image.
tests/​images/​azurelinux-direct-streaming-testimage/​image.yaml Defines its architecture matrix.
tests/​images/​azurelinux-direct-streaming-testimage/​by-arch/​arm64.yaml Selects the ARM64 base.
tests/​images/​azl-installer/​image.yaml Defines the AZL installer family.
Makefile Routes legacy targets through Tailor.
docs/​Development/​Testing/​Servicing-Tests.md Updates servicing build instructions.
docs/​Development/​Testing/​Rollback-Tests.md Updates rollback build instructions.
docs/​Development/​Testing/​Functional-Tests.md Updates functional-test instructions.
docs/​Development/​Testing/​E2E-Tests.md Updates E2E image commands.
.pipelines/​templates/​stages/​trident_images/​trident-testimg-template.yml Migrates the legacy pipeline path.
.pipelines/​templates/​stages/​trident_images/​build-image.yml Adds Rust setup for Tailor.
.pipelines/​templates/​stages/​trident_images/​build-image-arm64.yml Adds ARM64 Rust setup.
.pipelines/​templates/​stages/​build_image/​build-image-template.yml Migrates direct image builds to Tailor.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +65 to +67
- template: ../common_tasks/cargo-auth.yml
parameters:
cargoConfigPath: $(TRIDENT_SOURCE_DIR)/.cargo/config.toml
Comment on lines +65 to +66
/// The resolved per-cell `signing:` opt-in after fragment merging.
pub signing: Option<SigningRef>,
base_image: base_image.clone(),
rpm_sources: rc.rpm_sources.clone(),
extra_params: rc.extra_params.clone(),
signing: rc.signing.clone(),
Comment on lines +59 to +60
This produces `artifacts/trident-functest.qcow2`. The image is selected from
the `trident-functest` family in `tests/images/tailor.yaml`.
mint_leaf() embedded the full per-cell leaf_id verbatim in the certificate
subject (/CN=tailor leaf <leaf_id>). X.509 caps CommonName at 64 characters
(RFC 5280 ub-common-name), which OpenSSL's ASN1_mbstring_ncopy enforces by
aborting the whole `req` with "string too long" - and cell slugs (image +
every matrix axis + format, plus a _cloneN suffix tailor always appends
internally even for a single clone) easily exceed the 52 characters left
after the 12-char "tailor leaf " prefix. Confirmed from a real pipeline
failure: trident-verity-testimage's container+usr cell produces leaf_id
"trident-verity-testimage_container_usr_amd64_cosi_clone0" (69 chars
prefixed), while the host+usr cell lands at exactly 64 and happened to
still pass - a landmine for any longer image/cell name.

Add leaf_common_name(), which keeps the full id when it fits and otherwise
truncates to a readable prefix plus a short xxh3-64 hash of the full id, so
two ids sharing a truncated prefix still get distinct, deterministic CNs.
leaf_id itself is untouched everywhere else (file naming, etc.) - only the
certificate CN is bounded.

Added two regression tests (short id unaffected; the exact 69-char
container+usr id truncates/hashes correctly, is deterministic, and two
same-prefix long ids do not collide). Verified end-to-end with a real
--clones 2 build of trident-verity-testimage container+usr (the exact
previously-failing cell) - both clones built successfully.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants