Skip to content

azl4: build target and test image definitions#697

Draft
bfjelds wants to merge 14 commits into
user/bfjelds/azl4-1-runtimefrom
user/bfjelds/azl4-2-images
Draft

azl4: build target and test image definitions#697
bfjelds wants to merge 14 commits into
user/bfjelds/azl4-1-runtimefrom
user/bfjelds/azl4-2-images

Conversation

@bfjelds

@bfjelds bfjelds commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

Part 2 of the stacked azl4 series. Builds on the runtime PR. Adds the Makefile output targets and azl4 grub test image definitions.

  • Makefile output targets for the azl4 images.
  • base/updateimg-grub-azl4 test image definitions and the testimages.py / builder plumbing to produce them.
  • First-boot support scripts and units: initrd rebuild, SSH host-key move/regeneration, hostname shim, SELinux xattr stripping.

Review note: base this on PR #1; only the second commit is new here.

@bfjelds bfjelds force-pushed the user/bfjelds/azl4-2-images branch from 084346c to b76b575 Compare June 24, 2026 23:47
Add the Makefile output targets and the azl4 grub test image definitions
(base/update) plus the supporting first-boot scripts and units used to build
Azure Linux 4 test images: initrd rebuild, SSH host-key move/regeneration,
hostname shim, SELinux xattr stripping, and the testimages.py / builder
plumbing to produce them.

Stacked on the azl4 runtime PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bfjelds bfjelds force-pushed the user/bfjelds/azl4-1-runtime branch from fd80756 to 3ac0bb5 Compare June 25, 2026 00:25
@bfjelds bfjelds force-pushed the user/bfjelds/azl4-2-images branch from b76b575 to 490d136 Compare June 25, 2026 00:25
@bfjelds bfjelds requested a review from Copilot June 26, 2026 21:20

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.

Pull request overview

Adds Azure Linux 4 (AZL4) VM GRUB test-image definitions and extends the test-image builder plumbing so images can expose multiple output targets (e.g., .cosi + .qcow2) and fetch AZL4 base images from blob storage when needed.

Changes:

  • Add AZL4 GRUB base/update image YAML configs plus first-boot/post-customization scripts and a oneshot systemd unit for SSH host-key generation.
  • Refactor the Python image builder to support per-image output_and_config mappings, a --output-type selector, and blob-sourced base images (BlobImageManifest + downloader).
  • Simplify Makefile image build rules into a generalized output-suffix-driven pattern; update pipeline template to stage the SSH public key into the image tree.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/images/trident-vm-testimage/base/updateimg-grub-azl4.yaml New AZL4 update-image (COSI) definition for GRUB-based VM testing.
tests/images/trident-vm-testimage/base/baseimg-grub-azl4.yaml New AZL4 bootable base qcow2 definition used by rollback tests.
tests/images/trident-vm-testimage/base/scripts/strip-selinux-xattrs.sh New post-customization script to strip security.selinux xattrs during image build.
tests/images/trident-vm-testimage/base/scripts/ssh-move-host-keys-azl4.sh New AZL4-specific sshd HostKey drop-in configuration script.
tests/images/trident-vm-testimage/base/scripts/rebuild-initrd-azl4.sh New initramfs rebuild script to ensure non-hostonly storage drivers are included.
tests/images/trident-vm-testimage/base/scripts/enable-trident-service-azl4.sh New defensive systemd enablement script for trident units on AZL4 builds.
tests/images/trident-vm-testimage/base/scripts/enable-regen-sshd-keys.sh New script enabling the SSH host-key regeneration oneshot unit.
tests/images/trident-vm-testimage/base/files/regen-sshd-keys.service New systemd oneshot unit to generate SSH host keys under /var/srv on first boot.
tests/images/trident-vm-testimage/base/files/hostname-shim.sh New hostname shim for AZL4 images where the binary is not present.
tests/images/testimages.py Update image definitions to use multi-output configs; add AZL4 VM test image and blob base-image manifest.
tests/images/builder/init.py Introduce Distro, BlobImageManifest, multi-output config mapping, and runtime output selection.
tests/images/builder/run.py Add output-type selection at build time; route blob manifests to blob downloader.
tests/images/builder/download.py Add blob-based base-image downloader; extend MCR download URL selection by distro.
tests/images/builder/cli.py Add --output-type and blob download CLI flags/env defaults.
tests/images/builder/builder.py Update build calls to use the selected output format dynamically.
Makefile Generalize artifacts build pattern to include .qcow2/.vhd and pass output type through to the builder.
.pipelines/templates/stages/trident_images/trident-testimg-template.yml Stage SSH public key into the testimage tree before building.

Comment thread tests/images/builder/__init__.py Outdated
Comment thread tests/images/builder/download.py
…st images

The netplan-main generate/configure split defers virtual-device creation
to netplan-configure.service (Fedora ships it preset-disabled), and the
grub-azl4 base image needs the socket-activated tridentd unit enabled.
Enable both in the grub-azl4 base and update test images.

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.

Comment thread tests/images/builder/__init__.py Outdated
Comment thread tests/images/builder/download.py
- builder/__init__.py: pass Distro.OTHER via distro= keyword so it maps
  to the distro field instead of mcr_name for Ubuntu/GB200 entries
- builder/download.py: move docstring to first statement so it is a real
  docstring rather than a no-op expression
- rebuild-initrd-azl4.sh: enable nullglob so an empty modules dir yields
  an empty array and the 0-kernels error arm is reachable
- enable-regen-sshd-keys.sh: add set -euo pipefail and mkdir -p the wants
  directory so enabling fails loudly and works on minimal images
- regen-sshd-keys.service: condition on all host key types via OR-negated
  ConditionPathExists so partial key state still triggers regeneration

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread tests/images/builder/__init__.py
The pattern rule passes the file extension as --output-type, so a .cosi
target always resolves to OutputFormat.COSI even for configs that intend
OutputFormat.BAREMETAL_IMAGE (both use extension cosi). Echo a note on
.cosi builds pointing users who want a baremetal-image COSI to invoke
testimages.py directly with --output-type baremetal-image.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bfjelds bfjelds force-pushed the user/bfjelds/azl4-2-images branch from 9fdf734 to 9e50bd5 Compare June 26, 2026 22:16
@bfjelds bfjelds requested a review from Copilot June 26, 2026 22:20

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread tests/images/builder/__init__.py Outdated
@bfjelds bfjelds force-pushed the user/bfjelds/azl4-2-images branch from 898a664 to e0ce882 Compare June 26, 2026 22:46
The config_file field on ImageConfig is no longer read; full_yaml_path()
derives the YAML from config_path()/output_and_config. Left in place it
made show-image <name> config-file return a stale default, so remove it.

- show_image: render dict fields one entry per line so
  show-image <name> output-and-config prints a readable
  outputtype: yaml mapping instead of a raw dict repr.
- README: document show-image <name> base-image with the download step
  (it identifies which base image to fetch, as the build pipeline does)
  and show-image <name> output-and-config with the config-edit step
  (it lists the YAML used for each output type).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bfjelds bfjelds force-pushed the user/bfjelds/azl4-2-images branch from e0ce882 to 8559e3d Compare June 26, 2026 22:49
@bfjelds bfjelds requested a review from Copilot June 26, 2026 22:53

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comment thread tests/images/trident-vm-testimage/base/baseimg-grub-azl4.yaml

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.

Comment thread Makefile
Comment thread tests/images/builder/__init__.py Outdated
Comment thread tests/images/builder/__init__.py Outdated
Comment thread tests/images/trident-vm-testimage/base/baseimg-grub-azl4.yaml Outdated
bfjelds and others added 2 commits June 27, 2026 00:01
- Annotate output_and_config values and config_path() return as Path to
  match __post_init__ normalization.
- Drop stale baseimg-grub-azl4.yaml TODO about trident additionalFiles /
  inline binary; the config installs the trident-service RPM.
- Update enable-trident-service-azl4.sh header: AZL4 now installs the
  trident-service RPM (units ship with the RPM, not additionalFiles).

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.

Comment thread tests/images/builder/__init__.py Outdated
Comment thread tests/images/builder/__init__.py Outdated
Comment thread tests/images/builder/run.py Outdated
Comment thread tests/images/builder/__init__.py
- Drop module-level logging.basicConfig from the builder library module;
  cli.py already configures root logging.
- Fix set_output_type warning to point at the valid 'baremetal-image'
  output type (was 'baremetal-cosi', which is not an OutputFormat).
- Log the resolved output_format() instead of the raw runtime value so
  vhd->vhd-fixed / cosi->baremetal-image resolution is visible.
- Set distro=Distro.AZL4 on BaseImage.AZL4_QEMU_GUEST.

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

tests/images/builder/run.py:36

  • list-files currently prints exactly one output file per image config via config.file_name(), which now only reflects the default output type (first key in output_and_config). For configs that declare multiple outputs (e.g. VM images that produce both .cosi and .qcow2), list-files will omit valid artifacts and can mislead callers.

Consider listing one target per declared output format instead of only the default.

def list_files(*, configs: List[ImageConfig], output_dir: Path) -> None:
    for config in configs:
        print(output_dir / config.file_name())

Comment thread tests/images/builder/__init__.py Outdated
output_format() previously fell back to the first declared output format
when --output-type matched no declared format, so make artifacts/<name>.<ext>
could complete without producing the requested artifact. It now raises a
ValueError listing the supported output extensions for the image.

Also simplify config_path() to index output_and_config by the resolved
output_format() key, since that key is guaranteed present.

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Comment thread tests/images/builder/__init__.py
Comment thread tests/images/testimages.py
Comment thread tests/images/builder/download.py
- output_and_config default_factory now returns a Path value to match
  the dict[OutputFormat, Path] annotation.
- Remove unused Distro import from testimages.py (only referenced in
  commented-out code).
- Annotate download_blob_image storage_account/container as Optional[str]
  to match the None defaults passed from the run layer.

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

tests/images/builder/download.py:35

  • download_base_image() always pulls the amd64 artifact (--platform linux/amd64), which will download the wrong base image when the manifest refers to an ARM64 base image (e.g. BaseImage.CORE_ARM64 in tests/images/testimages.py). This makes ./testimages.py download-image core_arm64 unusable and can silently produce a mismatched VHDX.

Pick the ORAS platform based on the base image name (arm64/aarch64 vs amd64), and pass that into --platform.

                "--platform",
                "linux/amd64",
            ],

Comment thread tests/images/builder/cli.py Outdated
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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comment thread tests/images/builder/__init__.py
output_format() resolved a requested --output-type purely by file
extension. Because ext() collapses baremetal-image->cosi and
vhd-fixed->vhd, an explicit request for baremetal-image or vhd-fixed
could silently downgrade to a same-extension format (COSI/VHD), and two
declared formats sharing an extension could not be selected reliably.

Now, when the requested format is baremetal-image or vhd-fixed and that
exact format is declared in output_and_config, return it directly;
otherwise fall back to extension-based matching to preserve the
Makefile's extension-driven selection (--output-type cosi / vhd).

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comment thread tests/images/builder/__init__.py
set_output_type() warned on every --output-type cosi/vhd, even when the
image config does not declare the same-extension alternative
(BAREMETAL_IMAGE/VHD_FIXED). Gate each warning on the alternative being
present in output_and_config so the hint only appears when the ambiguity
is real.

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.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comment thread tests/images/trident-vm-testimage/base/updateimg-grub-azl4.yaml
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