From 3189de3d013a6f7c4dfe22ff4c36c01cdbc516a4 Mon Sep 17 00:00:00 2001 From: binujp <1309368+binujp@users.noreply.github.com> Date: Fri, 21 Aug 2026 13:26:49 -0700 Subject: [PATCH 1/2] refactor(images): compose AZL4 images from hierarchical KIWI profiles Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f65ba2f2-0893-43c2-8276-a692c8d1514f --- .github/instructions/kiwi.instructions.md | 35 +-- .../20-wired-dhcp.network | 0 base/images/AzureLinux.kiwi | 19 ++ .../anaconda-launcher.sh | 0 .../azl-install-encrypted.ks.in | 0 .../{vm-iso-installer => }/azl-install.ks.in | 0 .../{vm-iso-installer => }/azurelinux.conf | 0 base/images/components/boot.xml | 23 ++ base/images/components/common.xml | 65 +++++ .../config.sh => config-container-base.sh} | 0 .../config.sh => config-vm-iso-installer.sh} | 21 +- base/images/config.sh | 12 + .../images/container-base/container-base.kiwi | 181 ------------- .../{vm-iso-installer => }/grub_template.cfg | 0 base/images/images.toml | 246 ++++++++++-------- ...st-bootloader.sh => post-bootloader.ks.sh} | 0 .../post-install.sh => post-install.ks.sh} | 0 base/images/repositories/core.xml | 6 + base/images/teams/cloud/marketplace.xml | 216 +++++++++++++++ base/images/teams/cloud/onep.xml | 128 +++++++++ base/images/teams/cloud/vm-base.xml | 81 ++++++ base/images/teams/container.xml | 85 ++++++ base/images/teams/installer.xml | 71 +++++ base/images/teams/minimal-os.xml | 51 ++++ base/images/teams/wsl.xml | 87 +++++++ base/images/tests/README.md | 16 +- base/images/tests/utils/pytest_plugin.py | 4 +- base/images/vm-base/vm-base.kiwi | 200 -------------- .../vm-iso-installer/vm-iso-installer.kiwi | 157 ----------- base/images/wsl/wsl.kiwi | 112 -------- 30 files changed, 1006 insertions(+), 810 deletions(-) rename base/images/{vm-iso-installer => }/20-wired-dhcp.network (100%) create mode 100755 base/images/AzureLinux.kiwi rename base/images/{vm-iso-installer => }/anaconda-launcher.sh (100%) mode change 100644 => 100755 rename base/images/{vm-iso-installer => }/azl-install-encrypted.ks.in (100%) rename base/images/{vm-iso-installer => }/azl-install.ks.in (100%) rename base/images/{vm-iso-installer => }/azurelinux.conf (100%) create mode 100644 base/images/components/boot.xml create mode 100644 base/images/components/common.xml rename base/images/{container-base/config.sh => config-container-base.sh} (100%) mode change 100644 => 100755 rename base/images/{vm-iso-installer/config.sh => config-vm-iso-installer.sh} (91%) mode change 100644 => 100755 create mode 100755 base/images/config.sh delete mode 100644 base/images/container-base/container-base.kiwi rename base/images/{vm-iso-installer => }/grub_template.cfg (100%) rename base/images/{vm-iso-installer/post-bootloader.sh => post-bootloader.ks.sh} (100%) mode change 100644 => 100755 rename base/images/{vm-iso-installer/post-install.sh => post-install.ks.sh} (100%) mode change 100644 => 100755 create mode 100644 base/images/repositories/core.xml create mode 100644 base/images/teams/cloud/marketplace.xml create mode 100644 base/images/teams/cloud/onep.xml create mode 100644 base/images/teams/cloud/vm-base.xml create mode 100644 base/images/teams/container.xml create mode 100644 base/images/teams/installer.xml create mode 100644 base/images/teams/minimal-os.xml create mode 100644 base/images/teams/wsl.xml delete mode 100644 base/images/vm-base/vm-base.kiwi delete mode 100644 base/images/vm-iso-installer/vm-iso-installer.kiwi delete mode 100644 base/images/wsl/wsl.kiwi diff --git a/.github/instructions/kiwi.instructions.md b/.github/instructions/kiwi.instructions.md index e7af54a5cd6..4d11b800728 100644 --- a/.github/instructions/kiwi.instructions.md +++ b/.github/instructions/kiwi.instructions.md @@ -8,38 +8,29 @@ Kiwi files define Azure Linux image builds. They use the [KIWI NG](https://osins ## How images are registered -Images are defined in `base/images/images.toml`. Each image is -declared as a canonical (unsuffixed) entry plus a `-dev` variant, -each selecting the matching kiwi `profile`: +Images are defined in `base/images/images.toml`. Each image selects a leaf +profile from the shared `base/images/AzureLinux.kiwi` description: ```toml [images.container-base] description = "Container Base Image" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "core" } - -[images.container-base-dev] -description = "Container Base Image (dev)" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "core-dev" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "core" } ``` -The two variants share the same kiwi description; they differ only -in which `azurelinux-repos*` package is shipped (controlling where -the resulting OS points at runtime), and — for the `core` container -specifically — the OCI tag (`:4.0` + `:latest` for canonical, -`:4.0-dev` for the dev variant). Both variants build their RPMs -from the same source (the kiwi ``); koji overrides this -during distro builds. - -Distroless container images strip the package manager entirely, so -they ship no `-repos` package and have only a single (canonical) -entry — there's no `-dev` sibling because it would be byte-identical. +`AzureLinux.kiwi` includes reusable fragments from `repositories/`, +`components/`, and `teams/`. Includes remain flat in the root description; +profile requirements express inheritance between fragments. -Each image has its own directory under `base/images/` containing the -`.kiwi` file. +KIWI hook scripts, bootloader templates, and `` sources live directly +under `base/images/`, because that directory is the shared description root. +The root `config.sh` dispatches profile-specific behavior using +`kiwi_profiles`, following Fedora's shared-description model. `` entries +remain scoped to the owning profile so their payloads do not leak into other +images. ## Image types -- **Container** (`image="docker"`): OCI container images with `` for name, tag, entrypoint +- **Container** (`image="oci"`): OCI container images with `` for name, tag, entrypoint - **VM** (`image="oem"`): Virtual machine images with disk format (`vhdx`, `qcow2`), filesystem, bootloader, and partition config ## Key elements diff --git a/base/images/vm-iso-installer/20-wired-dhcp.network b/base/images/20-wired-dhcp.network similarity index 100% rename from base/images/vm-iso-installer/20-wired-dhcp.network rename to base/images/20-wired-dhcp.network diff --git a/base/images/AzureLinux.kiwi b/base/images/AzureLinux.kiwi new file mode 100755 index 00000000000..fd7fa95156a --- /dev/null +++ b/base/images/AzureLinux.kiwi @@ -0,0 +1,19 @@ + + + + + Azure Linux + azurelinux@microsoft.com + Azure Linux 4 image hierarchy + + + + + + + + + + + + diff --git a/base/images/vm-iso-installer/anaconda-launcher.sh b/base/images/anaconda-launcher.sh old mode 100644 new mode 100755 similarity index 100% rename from base/images/vm-iso-installer/anaconda-launcher.sh rename to base/images/anaconda-launcher.sh diff --git a/base/images/vm-iso-installer/azl-install-encrypted.ks.in b/base/images/azl-install-encrypted.ks.in similarity index 100% rename from base/images/vm-iso-installer/azl-install-encrypted.ks.in rename to base/images/azl-install-encrypted.ks.in diff --git a/base/images/vm-iso-installer/azl-install.ks.in b/base/images/azl-install.ks.in similarity index 100% rename from base/images/vm-iso-installer/azl-install.ks.in rename to base/images/azl-install.ks.in diff --git a/base/images/vm-iso-installer/azurelinux.conf b/base/images/azurelinux.conf similarity index 100% rename from base/images/vm-iso-installer/azurelinux.conf rename to base/images/azurelinux.conf diff --git a/base/images/components/boot.xml b/base/images/components/boot.xml new file mode 100644 index 00000000000..aa8094cb9f3 --- /dev/null +++ b/base/images/components/boot.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/components/common.xml b/base/images/components/common.xml new file mode 100644 index 00000000000..7b16b205376 --- /dev/null +++ b/base/images/components/common.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/container-base/config.sh b/base/images/config-container-base.sh old mode 100644 new mode 100755 similarity index 100% rename from base/images/container-base/config.sh rename to base/images/config-container-base.sh diff --git a/base/images/vm-iso-installer/config.sh b/base/images/config-vm-iso-installer.sh old mode 100644 new mode 100755 similarity index 91% rename from base/images/vm-iso-installer/config.sh rename to base/images/config-vm-iso-installer.sh index c13bfc2c0d1..8519c2db66e --- a/base/images/vm-iso-installer/config.sh +++ b/base/images/config-vm-iso-installer.sh @@ -33,24 +33,9 @@ echo " GRUB EFI package: $GRUB_EFI_PKG" echo " Shim EFI binary: $SHIM_EFI" #---------------------------------------------------------------------- -# Variant detection +# Repository package selection #---------------------------------------------------------------------- -# kiwi sets `kiwi_profiles` to a comma-separated list of active profiles -# (one per build, set by --profile). The variant decides which -# `azurelinux-repos*` package goes into the image and the kickstart, -# which in turn controls the runtime repo of the installed system. -# -# OFFLINE_REPO_BLOCKLIST lists packages that must NOT appear in the -# offline repo. The opposite-variant repos package goes here: -# `azurelinux-repos` and `-dev` Conflict: with each other, and -# `azurelinux-release-common` has `Recommends: azurelinux-repos`, which -# would otherwise drag the canonical package into the dev offline repo -# via --resolve --alldeps and risk dnf picking the wrong one. case ",${kiwi_profiles:-}," in - *,vm-iso-installer-dev,*) - AZL_REPOS_PKG="azurelinux-repos-dev" - OFFLINE_REPO_BLOCKLIST=( "azurelinux-repos" ) - ;; *,vm-iso-installer,*) AZL_REPOS_PKG="azurelinux-repos" OFFLINE_REPO_BLOCKLIST=( "azurelinux-repos-dev" ) @@ -130,9 +115,9 @@ echo "=== Downloading target-install packages + dependencies ===" # Kiwi removes repo configs after package installation, so repos from the .kiwi # file are NOT available during config.sh. Use --repofrompath with the CDN URL # directly. Keep this URL in sync with the `azurelinux-base` repo in -# vm-iso-installer.kiwi. +# repositories/core.xml. -AZL_BASE_URL="https://stcontroltowerdevjwisitg.blob.core.windows.net/azl4-dev/base/$ARCH" +AZL_BASE_URL="https://packages.microsoft.com/azurelinux/4.0/beta/base/$ARCH" EXCLUDE_ARGS=() for pkg in "${OFFLINE_REPO_BLOCKLIST[@]}"; do diff --git a/base/images/config.sh b/base/images/config.sh new file mode 100755 index 00000000000..68e874b4256 --- /dev/null +++ b/base/images/config.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +case ",${kiwi_profiles:-}," in + *,vm-iso-installer,*) + exec /image/config-vm-iso-installer.sh + ;; + *,distroless-minimal,*|*,distroless-base,*|*,distroless-debug,*) + exec /image/config-container-base.sh + ;; +esac diff --git a/base/images/container-base/container-base.kiwi b/base/images/container-base/container-base.kiwi deleted file mode 100644 index f81c9f76080..00000000000 --- a/base/images/container-base/container-base.kiwi +++ /dev/null @@ -1,181 +0,0 @@ - - - - - Azure Linux - azurelinux@microsoft.com - Azure Linux Container Base Image - - - - - - - - - - - 0.1 - dnf5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/base/images/vm-iso-installer/grub_template.cfg b/base/images/grub_template.cfg similarity index 100% rename from base/images/vm-iso-installer/grub_template.cfg rename to base/images/grub_template.cfg diff --git a/base/images/images.toml b/base/images/images.toml index 8a3ccf643c8..e95240dcfaf 100644 --- a/base/images/images.toml +++ b/base/images/images.toml @@ -2,36 +2,19 @@ # Image registry # ============================================================================ # -# Most images come in two variants — a canonical (unsuffixed) build and -# a `-dev` build — each backed by a kiwi profile inside the matching -# `*.kiwi` file: +# Every image selects one leaf profile from the shared AzureLinux.kiwi +# hierarchy. Images with runtime package management ship azurelinux-repos. +# Distroless images intentionally omit repository packages. # -# : ships `azurelinux-repos` so the resulting OS points -# at packages.microsoft.com/azurelinux/4.0/beta at runtime. -# (For the `core` container, this is also the variant -# published with the `:4.0` + `:latest` OCI tags.) -# -dev : ships `azurelinux-repos-dev` so the resulting OS points -# at the azl4-dev blob at runtime. (For the `core` -# container, the OCI image is tagged `:4.0-dev` only.) -# -# Distroless container images strip the package manager entirely, so -# they ship no `-repos` package and are not built per-variant — only -# the canonical (unsuffixed) entries exist for those. -# -# Both variants build their RPMs from the same source (the kiwi -# `` points at azl4-dev for local builds; koji overrides -# this for distro builds). -# -# Capabilities and test-suites are identical between a canonical / `-dev` -# pair (the variants only differ in what `-repos` package ships and, -# for `core`, the OCI tag). +# The kiwi repositories are build-time sources. Koji overrides them for +# distro builds. # ============================================================================ # ---- vm-base ----------------------------------------------------------- [images.vm-base] description = "VM Base Image" -definition = { type = "kiwi", path = "vm-base/vm-base.kiwi", profile = "vm-base" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "vm-base" } tests.test-suites = [ { name = "static-image-checks" }, { name = "lisa-main" }, @@ -47,56 +30,9 @@ container = false systemd = true runtime-package-management = true -[images.vm-base-dev] -description = "VM Base Image (dev)" -definition = { type = "kiwi", path = "vm-base/vm-base.kiwi", profile = "vm-base-dev" } -tests.test-suites = [ - { name = "static-image-checks" }, - { name = "lisa-main" }, - { name = "lisa-xfs" }, - { name = "lisa-perf" }, - { name = "lisa-smoke" }, - { name = "lisa-kernel-ltp" }, -] - -[images.vm-base-dev.capabilities] -machine-bootable = true -container = false -systemd = true -runtime-package-management = true - -# ---- minimal-os -------------------------------------------------------- - -[images.minimal-os] -description = "Minimal OS Image" -definition = { type = "kiwi", path = "minimal-os/minimal-os.kiwi", profile = "minimal-os" } -tests.test-suites = [ - { name = "static-image-checks" }, -] - -[images.minimal-os.capabilities] -machine-bootable = true -container = false -systemd = true -runtime-package-management = true - -[images.minimal-os-dev] -description = "Minimal OS Image (dev)" -definition = { type = "kiwi", path = "minimal-os/minimal-os.kiwi", profile = "minimal-os-dev" } -tests.test-suites = [ - { name = "static-image-checks" }, -] - -[images.minimal-os-dev.capabilities] -machine-bootable = true -container = false -systemd = true -runtime-package-management = true - -# ---- container-base (core profile) ------------------------------------- [images.container-base] description = "Container Base Image" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "core" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "core" } tests.test-suites = [ { name = "static-image-checks" }, { name = "runtime-container-tests" }, @@ -108,27 +44,9 @@ container = true systemd = false runtime-package-management = true -[images.container-base-dev] -description = "Container Base Image (dev)" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "core-dev" } -tests.test-suites = [ - { name = "static-image-checks" }, - { name = "runtime-container-tests" }, -] - -[images.container-base-dev.capabilities] -machine-bootable = false -container = true -systemd = false -runtime-package-management = true - -# ---- distroless containers (single-variant only) ----------------------- -# No -dev sibling: with a single build-time repo and no runtime package -# management, a -dev distroless build would be byte-identical. - [images.container-distroless-minimal] description = "Container Distroless Minimal Image" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "distroless-minimal" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "distroless-minimal" } tests.test-suites = [{ name = "static-image-checks" }] [images.container-distroless-minimal.capabilities] @@ -139,7 +57,7 @@ runtime-package-management = false [images.container-distroless-base] description = "Container Distroless Base Image" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "distroless-base" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "distroless-base" } tests.test-suites = [{ name = "static-image-checks" }] [images.container-distroless-base.capabilities] @@ -150,7 +68,7 @@ runtime-package-management = false [images.container-distroless-debug] description = "Container Distroless Debug Image" -definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "distroless-debug" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "distroless-debug" } tests.test-suites = [{ name = "static-image-checks" }] [images.container-distroless-debug.capabilities] @@ -163,7 +81,7 @@ runtime-package-management = false [images.wsl] description = "WSL Image" -definition = { type = "kiwi", path = "wsl/wsl.kiwi", profile = "wsl" } +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "wsl" } tests.test-suites = [{ name = "static-image-checks" }] [images.wsl.capabilities] @@ -172,30 +90,138 @@ container = false systemd = true runtime-package-management = true -[images.wsl-dev] -description = "WSL Image (dev)" -definition = { type = "kiwi", path = "wsl/wsl.kiwi", profile = "wsl-dev" } +[images.vm-iso-installer] +description = "VM ISO Installer" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "vm-iso-installer" } + +[images.vm-iso-installer.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true + +[images.minimal-os] +description = "Minimal OS Image" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "minimal-os" } tests.test-suites = [{ name = "static-image-checks" }] -[images.wsl-dev.capabilities] -machine-bootable = false +[images.minimal-os.capabilities] +machine-bootable = true container = false systemd = true runtime-package-management = true -# ---- vm-iso-installer -------------------------------------------------- +[images.1p-vm-base-gen1] +description = "1P VM Base Gen1 Image (BIOS)" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "1p-vm-base-gen1" } +tests.test-suites = [ + { name = "static-image-checks" }, + { name = "lisa-main" }, + { name = "lisa-xfs" }, + { name = "lisa-perf" }, + { name = "lisa-smoke" }, + { name = "lisa-kernel-ltp" }, +] -[images.vm-iso-installer] -description = "VM ISO Installer" -definition = { type = "kiwi", path = "vm-iso-installer/vm-iso-installer.kiwi", profile = "vm-iso-installer" } +[images.1p-vm-base-gen1.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true -[images.vm-iso-installer-dev] -description = "VM ISO Installer (dev)" -definition = { type = "kiwi", path = "vm-iso-installer/vm-iso-installer.kiwi", profile = "vm-iso-installer-dev" } +[images.1p-vm-base-gen1-fips] +description = "1P VM Base Gen1 FIPS Image (BIOS)" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "1p-vm-base-gen1-fips" } +tests.test-suites = [ + { name = "static-image-checks" }, + { name = "lisa-main" }, + { name = "lisa-xfs" }, + { name = "lisa-perf" }, + { name = "lisa-smoke" }, + { name = "lisa-kernel-ltp" }, + { name = "lisa-fips" }, +] -# ============================================================================ -# Test suites -# ============================================================================ +[images.1p-vm-base-gen1-fips.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true + +[images.1p-vm-base-gen2-fips] +description = "1P VM Base Gen2 FIPS Image (UEFI)" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "1p-vm-base-gen2-fips" } +tests.test-suites = [ + { name = "static-image-checks" }, + { name = "lisa-main" }, + { name = "lisa-xfs" }, + { name = "lisa-perf" }, + { name = "lisa-smoke" }, + { name = "lisa-kernel-ltp" }, + { name = "lisa-fips" }, +] + +[images.1p-vm-base-gen2-fips.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true + +[images.marketplace-gen2] +description = "Marketplace Gen2 Image" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "marketplace-gen2" } +tests.test-suites = [ + { name = "static-image-checks" }, + { name = "lisa-main" }, + { name = "lisa-xfs" }, + { name = "lisa-perf" }, + { name = "lisa-smoke" }, + { name = "lisa-kernel-ltp" }, +] + +[images.marketplace-gen2.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true + +[images.marketplace-gen2-cvm] +description = "Marketplace Gen2 Confidential VM Image" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "marketplace-gen2-cvm" } +tests.test-suites = [ + { name = "static-image-checks" }, + { name = "lisa-main" }, + { name = "lisa-xfs" }, + { name = "lisa-perf" }, + { name = "lisa-smoke" }, + { name = "lisa-cvm" }, + { name = "lisa-kernel-ltp" }, +] + +[images.marketplace-gen2-cvm.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true + +[images.marketplace-gen2-fips] +description = "Marketplace Gen2 FIPS Image" +definition = { type = "kiwi", path = "AzureLinux.kiwi", profile = "marketplace-gen2-fips" } +tests.test-suites = [ + { name = "static-image-checks" }, + { name = "lisa-main" }, + { name = "lisa-xfs" }, + { name = "lisa-perf" }, + { name = "lisa-smoke" }, + { name = "lisa-kernel-ltp" }, + { name = "lisa-fips" }, +] + +[images.marketplace-gen2-fips.capabilities] +machine-bootable = true +container = false +systemd = true +runtime-package-management = true [test-suites.lisa-main] type = "lisa" @@ -221,6 +247,10 @@ description = "Lisa cvm tests" type = "lisa" description = "Lisa kernel LTP tests" +[test-suites.lisa-fips] +type = "lisa" +description = "Lisa FIPS tests" + # Single shared pytest suite for static (offline) image validation. [test-suites.static-image-checks] type = "pytest" diff --git a/base/images/vm-iso-installer/post-bootloader.sh b/base/images/post-bootloader.ks.sh old mode 100644 new mode 100755 similarity index 100% rename from base/images/vm-iso-installer/post-bootloader.sh rename to base/images/post-bootloader.ks.sh diff --git a/base/images/vm-iso-installer/post-install.sh b/base/images/post-install.ks.sh old mode 100644 new mode 100755 similarity index 100% rename from base/images/vm-iso-installer/post-install.sh rename to base/images/post-install.ks.sh diff --git a/base/images/repositories/core.xml b/base/images/repositories/core.xml new file mode 100644 index 00000000000..2b45fb1185e --- /dev/null +++ b/base/images/repositories/core.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/base/images/teams/cloud/marketplace.xml b/base/images/teams/cloud/marketplace.xml new file mode 100644 index 00000000000..dc570560b6c --- /dev/null +++ b/base/images/teams/cloud/marketplace.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/teams/cloud/onep.xml b/base/images/teams/cloud/onep.xml new file mode 100644 index 00000000000..f5b6a040c7a --- /dev/null +++ b/base/images/teams/cloud/onep.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/teams/cloud/vm-base.xml b/base/images/teams/cloud/vm-base.xml new file mode 100644 index 00000000000..5d8b693478f --- /dev/null +++ b/base/images/teams/cloud/vm-base.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + 5 + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/teams/container.xml b/base/images/teams/container.xml new file mode 100644 index 00000000000..3570b1c5691 --- /dev/null +++ b/base/images/teams/container.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 0.1 + dnf5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/teams/installer.xml b/base/images/teams/installer.xml new file mode 100644 index 00000000000..95ae9df21e7 --- /dev/null +++ b/base/images/teams/installer.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + + + + 0.1 + dnf5 + en_US + us + UTC + 4.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/teams/minimal-os.xml b/base/images/teams/minimal-os.xml new file mode 100644 index 00000000000..f35280ef582 --- /dev/null +++ b/base/images/teams/minimal-os.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + 0.1 + dnf5 + C + us + UTC + 4.0 + + + 1 + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/teams/wsl.xml b/base/images/teams/wsl.xml new file mode 100644 index 00000000000..5da1e857d20 --- /dev/null +++ b/base/images/teams/wsl.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + 0.1 + dnf5 + en_US + UTC + 4.0 + + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/images/tests/README.md b/base/images/tests/README.md index 8ce78e38bc5..9edf7a2b730 100644 --- a/base/images/tests/README.md +++ b/base/images/tests/README.md @@ -21,13 +21,10 @@ azldev image build wsl azldev image test wsl ``` -(Most images come in two variants. The canonical/unsuffixed name -ships `azurelinux-repos` so the resulting OS points at PMC's -`azurelinux/4.0/beta` repo at runtime; the `-dev` variant ships -`azurelinux-repos-dev` so the OS points at the azl4-dev blob. -Distroless container images strip the package manager entirely and -have only the canonical entry. Append `-dev` to the image name — -where present — to validate the dev variant.) +Images with runtime package management ship `azurelinux-repos`, so the +resulting OS points at PMC's `azurelinux/4.0/beta` repository. Distroless +container images strip the package manager and do not ship a repository +package. `azldev` creates a per-suite Python venv, installs this directory's `pyproject.toml`, and invokes pytest with the right `--image-path`, @@ -179,9 +176,8 @@ base/images/ image family (the plugin applies `@pytest.mark.image("")` during collection — no boilerplate per file or per subdir). The directory name is treated as a *family*: an `--image-name` matches - the family if it equals the family exactly OR has the form - `-` (so `cases/static/vm-base/` runs for both - `vm-base` and `vm-base-dev`). + the family if it equals the family exactly or has the form + `-`. - **Shared runtime (every container):** add a `cases/runtime/test_.py`. Use `container_exec_shell("...")` for normal runtime tests. Use `container_exec([...])` only when the test must avoid a shell, such as diff --git a/base/images/tests/utils/pytest_plugin.py b/base/images/tests/utils/pytest_plugin.py index f3ab066227a..8c10ad48e27 100644 --- a/base/images/tests/utils/pytest_plugin.py +++ b/base/images/tests/utils/pytest_plugin.py @@ -182,8 +182,8 @@ def pytest_runtest_setup(item: pytest.Item) -> None: # image: skip if --image-name doesn't match the marker's family. # Family matching: the marker's value is treated as a family name that # matches an image-name exactly OR matches a `-` name - # (e.g. ``image("vm-base")`` matches both ``vm-base`` and - # ``vm-base-dev``). This lets tests under ``cases//`` apply + # (e.g. ``image("marketplace-gen2")`` matches both ``marketplace-gen2`` + # and ``marketplace-gen2-fips``). This lets tests under ``cases//`` apply # to every variant of an image without per-variant duplication. image_name = item.config.getoption("--image-name", default=None) for marker in item.iter_markers("image"): diff --git a/base/images/vm-base/vm-base.kiwi b/base/images/vm-base/vm-base.kiwi deleted file mode 100644 index 8c870852e71..00000000000 --- a/base/images/vm-base/vm-base.kiwi +++ /dev/null @@ -1,200 +0,0 @@ - - - - - Azure Linux - azurelinux@microsoft.com - Azure Linux VM Base Image - - - - - - - - 0.1 - dnf5 - en_US - us - UTC - 4.0 - - - 5 - - false - - - - - - 0.1 - dnf5 - en_US - us - UTC - 4.0 - - - 5 - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/base/images/vm-iso-installer/vm-iso-installer.kiwi b/base/images/vm-iso-installer/vm-iso-installer.kiwi deleted file mode 100644 index 562befc142f..00000000000 --- a/base/images/vm-iso-installer/vm-iso-installer.kiwi +++ /dev/null @@ -1,157 +0,0 @@ - - - - - Azure Linux - azurelinux@microsoft.com - Azure Linux 4.0 ISO Installer - - - - - - - - 0.1 - dnf5 - en_US - us - UTC - 4.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/base/images/wsl/wsl.kiwi b/base/images/wsl/wsl.kiwi deleted file mode 100644 index f8d5f56b3f7..00000000000 --- a/base/images/wsl/wsl.kiwi +++ /dev/null @@ -1,112 +0,0 @@ - - - - - Azure Linux - azurelinux@microsoft.com - Azure Linux WSL Image - - - - - - - - 0.1 - dnf5 - en_US - UTC - 4.0 - - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 520cc7dff6196e6043ebfe58a159ec347cf17459 Mon Sep 17 00:00:00 2001 From: binujp <1309368+binujp@users.noreply.github.com> Date: Fri, 21 Aug 2026 17:44:44 -0700 Subject: [PATCH 2/2] fix(images): make installer console architecture-aware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f65ba2f2-0893-43c2-8276-a692c8d1514f --- base/images/azl-install-encrypted.ks.in | 2 +- base/images/azl-install.ks.in | 2 +- base/images/config-vm-iso-installer.sh | 17 +++++++++----- base/images/post-bootloader.ks.sh | 31 ++++++++++++++++++------- base/images/post-install.ks.sh | 13 +++++++++-- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/base/images/azl-install-encrypted.ks.in b/base/images/azl-install-encrypted.ks.in index 0ca1ad74087..88039bde6b8 100644 --- a/base/images/azl-install-encrypted.ks.in +++ b/base/images/azl-install-encrypted.ks.in @@ -16,7 +16,7 @@ network --hostname=azurelinux services --enabled=sshd,systemd-networkd,systemd-resolved # Bootloader -bootloader --location=mbr --append="console=ttyS0,115200 console=tty0" +bootloader --location=mbr --append="console=@@SERIAL_TTY@@,115200 console=tty0" # Eject installation media and reboot automatically after install reboot --eject diff --git a/base/images/azl-install.ks.in b/base/images/azl-install.ks.in index c542607e9aa..80c728fdd3b 100644 --- a/base/images/azl-install.ks.in +++ b/base/images/azl-install.ks.in @@ -16,7 +16,7 @@ network --hostname=azurelinux services --enabled=sshd,systemd-networkd,systemd-resolved # Bootloader -bootloader --location=mbr --append="console=ttyS0,115200 console=tty0" +bootloader --location=mbr --append="console=@@SERIAL_TTY@@,115200 console=tty0" # Eject installation media and reboot automatically after install reboot --eject diff --git a/base/images/config-vm-iso-installer.sh b/base/images/config-vm-iso-installer.sh index 8519c2db66e..f10d6f45333 100755 --- a/base/images/config-vm-iso-installer.sh +++ b/base/images/config-vm-iso-installer.sh @@ -14,6 +14,7 @@ case "$ARCH" in SHIM_EFI="shimx64.efi" GRUB_EFI="grubx64.efi" BOOT_EFI="BOOTX64.EFI" + SERIAL_TTY="ttyS0" ;; aarch64) GRUB_EFI_PKG="grub2-efi-aa64" @@ -22,6 +23,7 @@ case "$ARCH" in SHIM_EFI="shimaa64.efi" GRUB_EFI="grubaa64.efi" BOOT_EFI="BOOTAA64.EFI" + SERIAL_TTY="ttyAMA0" ;; *) echo "ERROR: Unsupported architecture: $ARCH" >&2 @@ -31,6 +33,7 @@ esac echo "=== Architecture: $ARCH ===" echo " GRUB EFI package: $GRUB_EFI_PKG" echo " Shim EFI binary: $SHIM_EFI" +echo " Serial console: $SERIAL_TTY" #---------------------------------------------------------------------- # Repository package selection @@ -207,7 +210,7 @@ cat > /root/.bash_profile << 'PROFILEEOF' # # Console selection logic: # - Hyper-V (systemd-detect-virt = "microsoft") → user is on VGA (tty1) -# - QEMU/KVM/bare-metal with serial in cmdline → user is on serial (ttyS0) +# - QEMU/KVM/bare-metal with serial in cmdline → user is on the architecture's serial TTY # - QEMU/KVM/bare-metal without serial → user is on VGA (tty1) # This prevents the invisible tty1 from stealing the installer on QEMU -nographic. if grep -q 'azl\.autoinstall' /proc/cmdline 2>/dev/null; then @@ -220,13 +223,13 @@ if grep -q 'azl\.autoinstall' /proc/cmdline 2>/dev/null; then else # QEMU/KVM/bare-metal case "$MY_TTY" in - /dev/ttyS0) + /dev/@@SERIAL_TTY@@) LAUNCH=true ;; /dev/tty1|/dev/hvc0) # Only autoinstall on VGA if serial is NOT in kernel cmdline - # (otherwise ttyS0 will handle it) - if ! grep -q 'console=ttyS' /proc/cmdline 2>/dev/null; then + # (otherwise the serial TTY will handle it) + if ! grep -q 'console=@@SERIAL_TTY@@' /proc/cmdline 2>/dev/null; then LAUNCH=true fi ;; @@ -255,6 +258,7 @@ echo "" echo "========================================" echo "" PROFILEEOF +sed -i "s/@@SERIAL_TTY@@/$SERIAL_TTY/g" /root/.bash_profile cat > /root/.bashrc << 'RCEOF' if [[ $- == *i* ]] && [ ! -f /tmp/.azl-banner-shown ]; then @@ -267,8 +271,8 @@ RCEOF # Autologin on serial and VGA consoles #---------------------------------------------------------------------- -mkdir -p /etc/systemd/system/serial-getty@ttyS0.service.d -cat > /etc/systemd/system/serial-getty@ttyS0.service.d/autologin.conf << 'AUTOEOF' +mkdir -p "/etc/systemd/system/serial-getty@${SERIAL_TTY}.service.d" +cat > "/etc/systemd/system/serial-getty@${SERIAL_TTY}.service.d/autologin.conf" << 'AUTOEOF' [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear %I 115200 linux @@ -299,6 +303,7 @@ generate_packages_section() { # Expand @@PACKAGES@@ placeholder in each template for ks_in in /root/azl-install.ks.in /root/azl-install-encrypted.ks.in; do ks_out="${ks_in%.in}" + sed -i "s/@@SERIAL_TTY@@/$SERIAL_TTY/g" "$ks_in" { sed '/@@PACKAGES@@/,$d' "$ks_in" generate_packages_section diff --git a/base/images/post-bootloader.ks.sh b/base/images/post-bootloader.ks.sh index e7e3c061a4f..0f6e5e6890a 100755 --- a/base/images/post-bootloader.ks.sh +++ b/base/images/post-bootloader.ks.sh @@ -5,6 +5,26 @@ set -x SYSROOT=/mnt/sysroot +ARCH=$(uname -m) +case "$ARCH" in + x86_64) + SERIAL_TTY="ttyS0" + SHIM_EFI="shimx64.efi" + GRUB_EFI="grubx64.efi" + BOOT_EFI="BOOTX64.EFI" + ;; + aarch64) + SERIAL_TTY="ttyAMA0" + SHIM_EFI="shimaa64.efi" + GRUB_EFI="grubaa64.efi" + BOOT_EFI="BOOTAA64.EFI" + ;; + *) + echo "ERROR: Unsupported architecture: $ARCH" >&2 + exit 1 + ;; +esac + echo "=== Target mounts ===" findmnt -R "$SYSROOT" 2>/dev/null || mount | grep sysroot @@ -84,13 +104,13 @@ terminal_input console serial menuentry "Azure Linux" { search --no-floppy --fs-uuid --set=root ${BOOT_UUID} - linux /${KERNEL_NAME} root=UUID=${ROOT_UUID} ${LUKS_PARAMS} console=ttyS0,115200 console=tty0 ro + linux /${KERNEL_NAME} root=UUID=${ROOT_UUID} ${LUKS_PARAMS} console=${SERIAL_TTY},115200 console=tty0 ro initrd /${INITRD_NAME} } menuentry "Azure Linux (rescue)" { search --no-floppy --fs-uuid --set=root ${BOOT_UUID} - linux /${KERNEL_NAME} root=UUID=${ROOT_UUID} ${LUKS_PARAMS} console=ttyS0,115200 console=tty0 ro systemd.unit=rescue.target + linux /${KERNEL_NAME} root=UUID=${ROOT_UUID} ${LUKS_PARAMS} console=${SERIAL_TTY},115200 console=tty0 ro systemd.unit=rescue.target initrd /${INITRD_NAME} } @@ -111,13 +131,6 @@ configfile \$prefix/grub.cfg STUBCFG fi -# --- Detect architecture for EFI binary names --- -EFI_ARCH=$(uname -m) -case "$EFI_ARCH" in - x86_64) SHIM_EFI="shimx64.efi"; GRUB_EFI="grubx64.efi"; BOOT_EFI="BOOTX64.EFI" ;; - aarch64) SHIM_EFI="shimaa64.efi"; GRUB_EFI="grubaa64.efi"; BOOT_EFI="BOOTAA64.EFI" ;; -esac - # --- Copy EFI binaries + grub.cfg to fallback boot path --- mkdir -p "$SYSROOT/boot/efi/EFI/BOOT" if [ -f "$EFI_VENDOR/$SHIM_EFI" ]; then diff --git a/base/images/post-install.ks.sh b/base/images/post-install.ks.sh index 396d2c87d4f..ddd2106ef81 100755 --- a/base/images/post-install.ks.sh +++ b/base/images/post-install.ks.sh @@ -3,6 +3,15 @@ # Called from within the installed chroot during anaconda %post. set -x +case "$(uname -m)" in + x86_64) SERIAL_TTY="ttyS0" ;; + aarch64) SERIAL_TTY="ttyAMA0" ;; + *) + echo "ERROR: Unsupported architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + # --- Network configuration --- cat > /etc/systemd/network/20-wired-dhcp.network << 'NET' [Match] @@ -16,14 +25,14 @@ UseDNS=yes NET # --- GRUB defaults --- -cat > /etc/default/grub << 'GRUBDEF' +cat > /etc/default/grub << GRUBDEF GRUB_TIMEOUT=2 GRUB_DISTRIBUTOR="Azure Linux" GRUB_DEFAULT=0 GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console serial" GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" -GRUB_CMDLINE_LINUX="console=ttyS0,115200 console=tty0" +GRUB_CMDLINE_LINUX="console=${SERIAL_TTY},115200 console=tty0" GRUB_DISABLE_RECOVERY=true GRUBDEF