Release Notes: Image Composer Tool#
Version 2026.3#
Release Date: TBD
New:
Fixed: the Web UI Artifacts table reported every build output as type
IMAGE, including the SBOM and files that are not build outputs at all. Two causes, both server-side — the table itself always displayed whatever type the API sent. The API’s log parser fell back toimagefor any file it did not recognise, so a chroot’s leftovers in the image build directory (bash.bashrc,debconf.conf,debian_version,UPLOAD-MANIFEST.txt) were listed as images; and its directory scanner, used for history builds and for partial outputs after a failed or cancelled compose, looked for SBOMs ending in.spdx.jsonand so missed thespdx_manifest_<deb|rpm>_<image>_<timestamp>.jsonfile ICT actually writes — dropping the SBOM from those views entirely. Both now share one set of naming rules (internal/utils/artifact), covering every image format the builder emits (raw,img,iso,qcow2,vhd,vhdx,vmdk,vdi,tar, with optionalgz/xz/zstdcompression) and both SBOM naming conventions (the create-mode manifest and the overlay.delta.spdx.json/.complete.spdx.jsonsidecars). An output that matches no rule is now reported asunknownrather than guessed to be an image —unknownis a new value on theArtifact.typeenum in the API contract, so a client that handles onlyimageandsbomshould expect it. Separately, the CLI’s “Generated Artifacts” summary listed every file in the image build directory; it now lists only the images and SBOMs, which is also what the web API parses.Fixed: the Web UI Artifacts table listed outputs in whatever order they came off disk, so the SBOM appeared wherever its filename happened to sort. Images are now listed first and the SBOM last. Ordering is applied when a build is read rather than when its artifact list is built, so it also holds for a past build whose recorded order predates this change, and the live completion view and a reloaded history build agree.
Changed: MBR is no longer selectable in the Advanced tab’s Disk Layout step, and the chip now reads “MBR is not yet enabled.” It is shown locked rather than hidden, so a template that already declares
partitionTableType: mbrstill displays its real value — it can be moved to GPT, but not back. The schema and the builder both still accept MBR, so a hand-authored template is unaffected.Fixed: a template’s
metadatablock was dropped from its resolved output. The AI-searchable discovery text (description,use_cases,keywords) that most curated templates open with — it is optional, and a number of shipped templates declare none — never reachedresolve --fullor the Web UI’s resolved view, because the template struct had no field for it. It now round-trips through load, merge and marshal. It still does not inherit: a child that declares nometadataresolves to none rather than adopting its parent’s, since the block is read per file for discovery and a child is a different image than its parent describes; a child that declares its own replaces the parent’s whole block rather than merging it field by field. Top-level keys are also emitted in the order the curated templates are authored in (metadata→image→target→ … →systemConfig), where previouslysystemConfigwas followed bypackageRepositoriesandmetadatawas absent entirely, so a resolved template now reads like a hand-written one.Intel EdgePack template for Ubuntu 26.04:
image-templates/ubuntu26/ubuntu26-x86_64-edgepack-raw.yml, the resolute counterpart of the existingubuntu24-x86_64-edgepack-raw.yml. It uses the same native building blocks — apackageRepositoriesentry for the signed EdgePack repository, EdgePack metapackages insystemConfig.packages, and the typedsystemConfig.dkmssection that builds the vendor DKMS modules against the image’s target kernel rather than the chroot’s build-host kernel. The EdgePack repository is pinned to theresolutesuite instead ofnoble, and there is a single repository entry rather than two: NPU, IPU and edge-compute-essentials enablement is carried byintel-edge-base-standarditself on both 24.04 and 26.04, so neither template selects a separateintel-edge-npupackage or its prerequisite repository. Both templates take their kernel from the floatinglinux-image-generic-hwe-24.04/-26.04metapackage;systemConfig.dkmsrebuilds the vendor modules against whichever kernel that resolves to, both at image build time and again on-target after a subsequent HWE kernel update. Both templates are schema-validated but not CI-built — build them locally before relying on them; doing so confirms EdgePack’sedge-edac-dkms,edge-gfx-dkms,edge-issei-dkms, andedge-mei-dkmsmodules build and install against the resolved HWE kernel inside the chroot.Minimal Ubuntu server + EdgePack templates for 24.04 and 26.04:
image-templates/ubuntu24/ubuntu24-x86_64-edgepack-server-raw.ymlandimage-templates/ubuntu26/ubuntu26-x86_64-edgepack-server-raw.yml. These are headless counterparts of the two*-edgepack-raw.ymltemplates above — same EdgePack package set (intel-edge-base-standard,intel-edge-media-ffmpeg,intel-edge-media-gst,intel-edge-manageability) and the same floating HWE kernel, but addingubuntu-server-minimalinstead ofubuntu-standard/ubuntu-desktop-minimalon top of theubuntu-minimalraw-image default, with no use-case-specific provisioning. Both are schema-validated; the 24.04 server template has also been built end-to-end and confirmed to produce working DKMS modules.Fixed:
internal/image/imageos/dkms.go’s post-build DKMS verification treated theoriginal_modulepseudo-version directory DKMS creates when it backs up an in-tree driver it displaced (e.g.igen6_edac,xe,virtio-gpu,mei*— all upstream in-tree on current Ubuntu kernels) as if it were a real built source, and failed the whole build looking for a nonexistentdkms.confunder it. Any DKMS-enabled template whose target kernel already ships an in-tree module of the same name — both EdgePack templates included — could hit this.original_moduleis now skipped when walking the DKMS build tree.Fed Aero host-OS blueprints in the Web UI Basic tab. The two generic host-OS templates from
edge-node-infrastructure-blueprintrelease-2026.2.0are now vendored intoimage-templates/ubuntu24/and selectable from the Basic tab:generic-handheld-os-template.yml(handheld/desktop) andgeneric-companion-os-server-template.yml(companion OS server). Both target Panther Lake on Ubuntu 24.04 and build arawimage. Both are wired into the shipped Basic-tab manifest (internal/api/service/data/manifest.yaml) under the Fed Aero vertical, so they are available out of the box with no extra configuration. TheEdge Node Infrastructure Blueprint BKCSKU has been removed from the Fed Aero vertical, so Fed Aero now offers exactly these two blueprints on Ubuntu 24.04 (the grayed-outDrone Image - From BKC Teamplaceholder on Ubuntu 26.04 Server is unchanged). Its template,ubuntu24-x86_64-minimal-ptl-pv-raw.yml, remains inimage-templates/and can still be built directly from the CLI — only the Basic-tab entry is gone. Note thatgeneric-handheld-os-template.ymlwas updated in place to therelease-2026.2.0revision — its swap partition grows from 3073MiB to 5121MiB, and it now installs the 6.18 Intel kernel and media stack from a pinned snapshot of the Intel edge overlay (download.01.org/edge-linux-overlay) instead of the rollingintel-linux-overlaysuite, so images built from it differ from earlier releases. Upstream ships<USERNAME>/<PASSWORD>placeholders in both templates’users:block; these are filled with this repo’s convention (user, empty password, set at deploy time) so the templates validate and build as shipped — set real credentials before deploying. The Advanced tab’s repository picker gains the two repositories these blueprints introduce: the pinned Intel edge overlay snapshot and the Ubuntu MozillaTeam PPA.
Version 2026.2#
Release Date: September 9, 2026
New:
Web UI Advanced tab: editable Disk Layout step. Step 3 of the Advanced wizard was a placeholder; it is now a working editor for the resolved template’s
diskblock — disk name and size, GPT or MBR partition table, and add/remove/reorder/resize of partitions, seeded from the template the current selection resolves to. The partition table showsname,fsLabel,fsType, size,mountPoint,startandendas labelled columns, withid,index,type,typeUUID,mountOptionsandflagsbehind a per-row details toggle — every field the schema defines round-trips, whether or not it is prominent. Partitions can be edited two ways, switchable per disk: size-based (the default) takes one size per partition and lays them out contiguously, calculatingstart/endfor you — the schema stores offsets and has no size field, so this keeps them from drifting out of sync; offset-based takes the offset strings directly, deriving sizes, for layouts that need a deliberate gap or must match an existing table offset-for-offset. Switching converts the layout in place, and an unedited layout emits identical YAML either way. Gaps and overlaps in offset mode are reported as warnings, not blocked — the builder accepts both. The last partition can take the remainder (end: "0") in either mode. The step also editsdisk.artifacts[]— the output-format list (raw,qcow2,vhd,vhdx,vmdk,vdi,tar, with optional compression) — which is where ICT produces QCOW2 and the other container formats;target.imageTypecontrols how the image is built and is a separate axis. Field values are checked against what the builder accepts, not just against the schema — the schema types nearly every Disk and Partition field as an unconstrained string, so the rules live in the implementation. Fields with a closed set are dropdowns (fsType, partitiontype, and the artifact format/compression); free-text fields show the expected format as a placeholder and are validated as you type. Values that would fail the build are errors, values that would degrade quietly are warnings — an unrecognised partitiontype, for instance, leaves the partition at a default type rather than failing, and is flagged as such. Output artifacts now offer only combinations that can actually be produced for the selected image type: RAW and overlay images getraw/qcow2/vhd/vhdx/vmdk/vdiwith optionalgz/xz/zstd; WSL2 requires exactly onetar+gzartifact; ISO and IMG do not run the artifact pipeline at all and say so instead of offering a dead control. Note this is narrower than the schema’s own enums, which includetar,gzipandbz2— none of which the builder implements on the disk path. Constraints the template loader enforces outside the JSON schema are reported inline too (extendLastPartitionToFillDiskis rejected forimageType: iso, and forrawunless the last partition is the rootfs). The edited layout is what gets built. Once you change anything on the step, the disk block is sent asdiskonPOST /templates/composeandPOST /builds, and the backend emits it into the same generatedextendsdelta the image-name and package overrides already use — so the Review step’s “Your changes” and “Resolved” views, and the image the build produces, all come from one file. An untouched layout is not sent: it round-trips to the template’s own disk block, so sending it would generate a delta that changes nothing. Becauseextendsmerging replacesdiskwholesale rather than merging it field by field, the override is always the complete block, never a diff. See ADR: Advanced mode Disk step.Kernel wildcard now installs a single kernel: a
systemConfig.kernel.packagesentry that uses a glob (for examplelinux-image-generic*) previously matched everylinux-image-generic*metapackage in the Ubuntu 24 repositories and silently installed several kernels (6.8 GA plus 6.11/6.14/6.17/7.0 HWE tracks) in the same image. The build now installs only the newest matched kernel and logs a warning listing every match, so a template using a broad glob still boots with a single, up-to-date kernel; pin an exact metapackage insystemConfig.kernel.packagesto install a different one. Explicitly listing multiple exact kernel packages is unchanged — the selection only applies to a single glob pattern that resolves to multiple kernels. The behavior applies to the Debian-family providers (Ubuntu, eLxr, Debian 13).
Overlay kernel replacement (
overlayPolicy.replaceKernel)Overlay builds on a GRUB2 baseline can now swap the kernel rather than only adding one alongside the baseline’s. The functionality depends on the following settings:
overlayPolicy.replaceKernel.package: <kernel-package>installs the named kernel (resolved from the configured repositories, and the value may use the same glob wildcards —*,?,[...]— as an ordinarysystemConfigpackage, e.g.linux-image-*-oem) and removes the baseline kernel family — the bootable image plus its meta-package, modules, and headers (linux-image-*,linux-image-generic,linux-modules-*,linux-headers-*; rpmkernel/kernel-core/kernel-modules) — so the emitted image ships only the new kernel.replaceKernel.additionalPackages(a list, same rules aspackage) installs further kernel-family packages alongside it — typically the matchinglinux-headers-*— following the same resolve/removal path. -replaceKernel.enableExtraModules(space-separated module names, mirroringsystemConfig.kernel.enableExtraModules) forces driver modules into the replacement kernel’s regenerated initramfs (dracut --add-drivers, or aninitramfs-toolsmodules-file entry).replaceKernel.versionis descriptive only, surfaced in the compose API summary.
The removal set is auto-detected from the baseline inventory (userspace packages such as
linux-libc-dev,linux-tools-common, and rpmkernel-headers/kernel-develare kept) and removed as one batch so no kernel package is left orphaned.The GRUB config is then regenerated so the removed kernel’s menu entry is dropped and
GRUB_DEFAULTpoints at the new kernel (auto-pinned to"0"unlessoverlayPolicy.grubDefaultis set). Only the GRUB config on the writable root changes — the ESP and the bootloader binary are never touched (grub-installis never run), preserving the overlay read-only-ESP contract; on a Secure Boot baseline the new kernel may be unsigned (sign it out of band).replaceKernelrequirespackageOperation: additive-and-upgradeand, being self-authorizing for its kernel-family removals, does not requireallowPackageRemoval; it is a hard error — raised at preflight, before any package is installed or removed — on a non-GRUB2 baseline (including a UKI baseline).See
image-templates/ubuntu24/ubuntu24-x86_64-overlay-replace-kernel-raw.ymlfor an example. This supersedes the previous restriction (see 2026.1) that in-place kernel-image replacement was always blocked.Overlay feature
The overlay feature enables composition of a final system image by installing additional packages on top of an existing RAW or QCOW2 base image, rather than building an image entirely from scratch. It is supported for Ubuntu 24.04 and Debian 13 images.
Key benefits:
Significantly reduced build time: Composing a full image from scratch by listing all packages can take approximately 1.5 hours. Using an existing base image and applying only the delta packages reduces composition time to approximately 8 minutes.
Upgrade and additive operations only: Package additions and upgrades are supported. Removing packages from the base image is not supported in this release.
Root filesystem resize: The root filesystem is resized to accommodate newly installed packages based on user inputs for the maximum allowed root filesystem size and maximum disk size.
Base Image Access for Overlay Composition
Base images can be accessed through the following methods:
URL: The base image is fetched directly from a remote location.
Local file path: The base image is referenced from a directory on the host system.
Supported Base Image Types
Base image type
Format
Canonical cloud images
QCOW2
Existing BKC (Best Known Configuration) images
RAW
ICT-composed images
RAW
Additional benefits include:
Significantly reduced overall image composition time by eliminating the need to resolve and install a full package list from scratch.
Simplified template creation by requiring only delta packages instead of a comprehensive list of all packages.
ICT continues to fully support composing minimal images from scratch for all POR (Plan of Record) OS distributions.
Post-boot root filesystem (rootfs) resize
Support has been added to grow the root filesystem after the first boot on the target device. This allows the image to remain at a minimal size during distribution and storage, with the filesystem expanding as needed upon boot.
Template extensions: multi-level support
ICT now supports multi-level template extensions, enabling modular and layered composition of system images.
Benefits include:
Cleaner separation of concerns through layered templates.
Easier collaboration across teams.
Reduced maintenance overhead.
Simplified debugging of template configurations.
Debian 13 with custom initrd and graphical desktop environment
Debian 13 images can now use a customized initrd, providing greater flexibility in early boot configuration. The images can also boot into a graphical desktop environment with GDM over X11.
debian13-x86_64-bb-dracut-raw.ymlalso ships a sample first-boot systemd oneshot unit (first-boot-sample.service): a script that runs once, on the device’s first boot only, gated by a marker file, with its message mirrored to the journal, a log file,dmesg, and the serial console.Full Disk Encryption (FDE) for RAW images
This release supports selectively encrypting disk partitions in RAW images with user-specified passphrases in the user template for encryption and decryption. Sealing encryption keys in a TPM is not supported.
Image composition for WSL environments
The tool can now compose Ubuntu images compatible with WSL environments.
Intel EdgePack platform-enablement template
Adds
ubuntu24-x86_64-edgepack-raw.yml, demonstrating native support for Intel’s EdgePack platform-enablement packages (Panther Lake / Wildcat Lake) viapackageRepositories,systemConfig.packages, and the new typedsystemConfig.dkmssection, which builds and verifies DKMS modules against the installed target kernel rather than the chroot’s build-host kernel.
Validated hardware:
Target platform: Panther Lake (PTL)
Reference Templates:
Feature
Reference template
Overlay and root filesystem resize
ubuntu24-x86_64-overlay-raw.ymlinimage-templates/ubuntu24/Post-boot root filesystem resize
ubuntu24-x86_64-minimal-raw-expand-partition.ymlinimage-templates/ubuntu24/Template extensions
ubuntu24-x86_64-extends-example-raw.ymlandubuntu24-x86_64-minimal-raw.ymlinimage-templates/ubuntu24/Debian 13 custom initrd with overlay
debian13-x86_64-bb-graphics-raw.ymlanddebian13-x86_64-bb-overlay-initrd-raw.ymlinimage-templates/debian13/Debian 13 monolithic robotics
debian13-x86_64-bb-dracut-raw.ymlinimage-templates/debian13/Ubuntu 24 robotics templates
ubuntu24-x86_64-robotics-hw-overlay-qcow2.yml,ubuntu24-x86_64-robotics-jazzy-overlay-extends.yml, andubuntu24-x86_64-robotics-jazzy-iso.ymlinimage-templates/ubuntu24/Intel EdgePack platform enablement
ubuntu24-x86_64-edgepack-raw.ymlinimage-templates/ubuntu24/
Fixed:
fix(imagedisc): bound sfdisk calls and detach stale loop devices before reattach:createPartitionTable’ssfdiskcalls had no execution timeout, so a wedgedsfdisk(e.g. blocked behind a stale loop-device handle from a hard-killed prior build) could hang a build indefinitely. Bothsfdiskinvocations are now bounded to a 30s context so a hang fails fast into the existing retry-with-force path instead of blocking forever. Loop-device attach is also now idempotent: beforelosetup, any existing loop device already bound to the same backing file (including one whose backing file was since deleted) is detached first, removing the actual trigger that could wedge the kernel’s partition-table re-read on a freshly attached device.fix(debutils): support APT repositories that publish only a combinedInReleasefile instead of a detachedRelease/Release.gpgpair. Builds against such repositories (including EdgePack’s public repository) previously failed to fetch metadata; the format is now auto-detected and verified either way, and offline rebuilds correctly keep using the previously detected format instead of reverting to the missing classic files.fix(debutils): correctly resolve dependencies on a versioned virtualProvides:(e.g. Debian’s Qt6 ABI-pinning packages) by comparing against the version the provider actually declares for that capability, not the provider’s own unrelated package version. An unversionedProvides:no longer incorrectly satisfies a versioned dependency either.fix(shell):configurationscommands containing multi-line scripts or shell metacharacters ($(), backticks,$var) now reach the chroot unmodified instead of having their whitespace collapsed or being partially expanded by the outer shell before execution.
Known Issues:
Custom partition layouts with the overlay feature are not supported:
The tool does not support user-specified disk partition layouts in the output image. The base image partitions are passed through to the RAW or QCOW2 output image.
SBOM generation for base images without an embedded SBOM:
If the base image does not contain an embedded Software Bill of Materials (SBOM), the resulting image generates an SBOM only for the additionally installed packages. Packages from the base image are not included in the SBOM output.
Web UI Advanced tab: cross-repository package search and browsing: The Choose Packages to Compose step now lists real packages instead of just the repository catalog. A search box queries every repository the target offers at once (gated to 2+ characters, matching the backend’s own minimum, since an empty query means “browse the whole catalog”), and picking a result auto-enables its source repository. A two-pane browser lets a single repository be explored directly, paginated 25 rows at a time via
GET /packages/search. Each row shows the package’s real version and aLatest/ pinned-version chip, and a running “Selected” rail groups everything added so far by repository, with per-item and clear-all removal; disabling a repository drops whatever was added from it. Selections are scoped to the current target OS — changing it (not just the SKU or platform) resets both the enabled repositories and the selected packages. See the entry below for how those selections reach the template.Web UI Advanced tab: “Show frequently used” curation and “Select all” for the repository browser: The two-pane browser’s page size is raised from 25 to 100, and a new “Show frequently used” checkbox narrows the list to each repository’s hand-picked curated packages — a new optional
curatedPackagesfield inpackage-repos.yaml, withGET /packages/searchgaining a matchingcuratedquery parameter. Curated picks are defined for every repository whose index is reachable: the three base-OS repos (build-essential,ca-certificates,curl,network-manager,openssh-server,python3,sudo,systemd,vim), the ROS 2 Jazzy and Lyrical repos (ros-*-desktop,ros-*-ros-base,ros-*-rviz2,ros-dev-toolsand friends, cutting ~8400 message and driver packages down to the metapackages an image actually starts from), Gazebo, Docker CE, Mozilla, Intel Graphics, Intel Linux Overlay and RealSense. The curated names themselves stay server-side — the browser sendscurated=trueand the server filters — butGET /package-reposnow reports ahasCuratedPackagesflag per repository, and the browser hides the “Show frequently used” checkbox where a repository has no curated picks (the six Intel repositories whose indexes are not currently reachable) instead of offering a toggle that could only empty the list. A “Select all” checkbox above the list adds every currently-shown package to the selection (skipping any already selected, so a manually pinned version is left alone) and removes them again when unchecked.Package search no longer re-downloads indexes it already holds: The picker’s index cache was capped at 24 indexes, but a catalog repository expands to one index per (suite, component, architecture) —
ubuntu-noble-basealone needed 24, and a target’s full repository set around 50. Every cross-repository search therefore evicted the indexes the next browse would ask for. Measured against the real binary, browsing a repository straight after a search re-downloaded 39 MB and took 90 seconds; it now answers from cache in 0.01s. The cap is raised to 128 indexes, with the 600,000-package budget still bounding memory. Alongside it, only the target’s own architecture is fetched: a catalog entry commonly lists one architecture per publishing host (Ubuntu serves x86_64 fromarchive.ubuntu.comand aarch64 fromports.ubuntu.com), and the aarch64 index — 18 MB that an x86_64 target can never install from — was being downloaded on every cold search. Together these take a cold cross-repository search from 30 seconds to 5.7, with the first results shown at 0.4s, and a repeat search to 0.02s.Package search offers every available version of a package, not just one: A Debian-style repository publishes its release,
-updatesand-securitysuites as separate indexes, so a package routinely exists at several versions —curlon Ubuntu 24.04 is available as both8.5.0-2ubuntu10and8.5.0-2ubuntu10.13. Search and browse previously reported these as unrelated rows and the picker showed whichever one happened to load first. Each package is now listed once, with every version it was found at offered as a chip (newest first, the rest behind “+N more”), andGET /packages/searchgained aversionsarray on each result carrying the version and the repository providing it. Choosing a version pins that exact string and also selects the repository it comes from, so a package available from two repositories at different versions resolves unambiguously;Latestinstead follows whatever the repository publishes next. Ordering uses the target’s own version rules rather than string comparison, so8.5.0-2ubuntu10.13correctly outranks8.5.0-2ubuntu10.9and an epoch outranks a higher upstream version.limitandtotalnow count packages rather than versions.Package search returns results as they arrive, instead of waiting for the slowest repository: A cross-repository search fans out over every repository a target offers, so its latency was set by whichever mirror was slowest to answer — an unreachable one took its full TCP dial timeout while packages already found elsewhere sat unsent, leaving the search box showing “Searching…” for around 30 seconds. A new
GET /packages/search/streamendpoint emits each repository’s matches as Server-Sent Events the moment that repository responds, and the search box fills in progressively: first results now appear in about 2-4 seconds. The stream closes after a fixed budget rather than tracking the slowest repository, and the dropdown states plainly when a search could not cover everything (“Searched 14 repositories — 6 of 14 repositories unreachable”), so a partial result is never passed off as the whole answer. Repository fetch failures are now also briefly cached (2 minutes, against 6 hours for a success), so one dead mirror is not redialled on every keystroke — a repeat search over a warm cache completes in well under a second.GET /packages/searchis unchanged and remains the endpoint for paging through one known repository; the stream is not paginated.Optional repository catalog rebalanced across targets:
intel-oneapiandmozilla-aptare distribution-neutral and are now offered to every target (previously ubuntu24 only), and debian13 and ubuntu26-server each gained the Debian/Ubuntu-26.04 equivalents of repositories already offered for ubuntu24 (docker-ce-ubuntu-resolute,gazebo-resolute,ros2-lyrical). Also fixesdocker-ce’s Debian index, which pointed atbookworm(Debian 12) for a debian13 target; it now points attrixie, Debian 13’s own suite.Web UI Advanced tab: selected packages now reach the template and the build: What the Choose Packages to Compose step selects is no longer UI-only state.
POST /templates/composeandPOST /buildsacceptpackagesandrepos, and the Advanced tab’s generatedextendsdelta gains asystemConfig.packagesentry per selected package — using thename_versionform the package resolvers match for a pinned version (curl_8.5.0-2ubuntu10.13), or the bare name to float to whatever the repository publishes — plus apackageRepositoriesentry per enabled repository, so a package picked from a repository the curated template does not already configure still resolves. Base repositories are not re-declared; they already come from the per-OSproviderconfigs/. Each catalog repository now carries the same signing-key URL (pkey) the authored templates use for it, so an Advanced-mode build verifies the repository exactly as a hand-written one would, andGET /package-reposreports ahasSigningKeyflag per repository. The Review step’s package count and YAML update as packages are added, and the build installs them. The Review step now presents the template in three views — Your changes (the generated delta alone), Base template (the pre-authored template it extends) and Resolved (the two merged, which is what the build runs) — served by newdeltaYamlandbaseYamlfields on the compose response; a selection with no changes shows only the resolved template as before. Because template inheritance combines package lists rather than replacing them, pinning a version for a package the pre-authored template already lists unpinned leaves both entries in the resolved template; the compose response reports these onpinConflictsand the Review step names them, rather than presenting an ambiguous package list as settled.
Fixed
Web UI package search no longer accepts a
Releasesigned by an unrecognised key: the picker’s GPG verification (independent of the CLI build path’s owndebutils/rpmutilsverification) treated a signature made by a key absent from the configured keyring as a pass, logging a warning but returning no error — silently accepting a forgedReleasefor the two repositories that carry a local keyring and are otherwise fetched over plaintexthttp://(ubuntu-noble-base,ubuntu-resolute-base). The keyring is now the sole trust anchor: a signature from any key it does not list is rejected, for both the armored (InRelease) and binary (Release.gpg) detached-signature forms.Web UI Advanced tab: base repositories no longer show a false “No signing key is configured” warning:
hasSigningKeychecked only for apkeyURL, which the Ubuntu base repos never carry — enabling one never emits apackageRepositoriesentry in the first place, since base repositories already come from the per-OSproviderconfigs/. It now also reports true when the repository carries a localgpgKeyPath, which is what the picker’s own search already verifies the repository’sReleaseagainst, soubuntu-noble-baseandubuntu-resolute-baseno longer warn about a verification gap they don’t have.Web UI Advanced tab: the repository browser’s rail now lists base (always-enabled) repositories first, ahead of the optional ones, instead of interleaving them by priority.
Version 2026.1#
Release Date: June 17, 2026
New:
Overlay cascade removal of orphaned reverse-dependencies: When
overlayPolicy.allowPackageRemovalis enabled, a conflict-driven removal that orphans an unrelated baseline package (one that onlyDepends:on the removed package — for example the Debian cloud image’scloud-initramfs-growrootdepending oninitramfs-tools) is now resolved automatically instead of failing the build. The post-install dependency audit becomes a bounded cascade: each baseline package that is broken after a removal but was whole before it is itself removed, transitively, until the package manager’s own check (apt-get check/dnf check) reports the dependency tree is whole again. The package manager’s audit is the ground truth, so a dependency that an alternative still satisfies is never mistaken for breakage and nothing is over-removed. The cascade still fails closed: if resolving the breakage would require removing a bootloader/kernel-image package or a package the overlay is installing, the build fails. Cascade removals are folded into the preflight report’s approved removals, surfaced onInstallResult.CascadeRemoved, and reflected in the OVERLAY PACKAGE STATISTICS summary and the complete SBOM. The behavior is entirely gated by the existingallowPackageRemovalflag — there is no new schema field, and with the flag off a removal that would orphan another package still fails the build.Overlay user provisioning with a baseline-conflict guard: Overlay builds now honor
systemConfig.users, provisioning each account onto the baseline using the same implementation as create mode (useradd, password/hashing, groups, sudo, startup script). A requested user that already exists in the baseline image fails the build up front — before any resize or package install mutates the baseline — because an overlay cannot redefine a baseline account. A user’sstartupScriptmust reference a path present when users are created (shipped by the baseline or installed by an overlaypackagesentry), not one delivered viaadditionalFiles, which are copied later in the overlay pipeline.systemConfig.usersis therefore no longer rejected as an unsupported overlay section.Robotics image composed from Canonical’s cloud image via overlay + extends: the hardware base layers Intel oneAPI, Level Zero, NPU, RealSense DKMS, patched systemd/udev, and the ROS 2 Jazzy child layers OpenVINO, Gazebo Harmonic, and collaborative SLAM. The child inherits the base’s baseline, policy, repositories, and disk settings. The overlay is build-verified with a 64 GiB target disk; Debian installation uses size-bounded dependency-ordered batches and retries only failed batches, while repository metadata caches are isolated per concrete package-list URL. The final Jazzy overlay emits a valid QCOW2 artifact. The resize path needs util-linux >= 2.38 because it reads partition start sectors via
lsblk -o PATH,START,TYPE, with apartedfallback.Graceful cancellation on Ctrl+C / SIGTERM: interrupting a build (SIGINT or SIGTERM) now triggers cooperative cleanup before the tool exits. Chroot bind mounts (
/proc,/sys,/dev/{pts,shm},/run, and the cache-repo bind) are torn down in reverse order, loop devices attached to files under the work directory are detached, and every spawned child process (bash, sudo, mmdebstrap, apt, mksquashfs, losetup, mkfs.*, xorriso, dracut, ukify, sbsign, qemu-img, …) runs in its own process group so a single kill reaches the whole subtree. In-flight HTTPS downloads of DEB/RPM packages and repository metadata (Go-levelnet/httprequests) also observe the same cancellation context, so a signal during the download stage aborts within one retry-backoff quantum instead of running to completion. The tool exits with the conventional exit code130after user-initiated cancellation. A second signal during cleanup is a hard exit (also130) so a wedged umount cannot pin the process forever. Internal deadlines (such as the 2-minute PostProcess cleanup budget) that exceed their limit surface as exit1— distinguishable from a user-initiated signal — so operators can tell “aborted by me” from “cleanup timed out”. Any residual mount/loop that could not be reaped is logged with detail so the operator knows exactly what to clean up manually. No user-visible flag changes; the behavior is on by default.Overlay
additionalFilessupport: Overlay builds now honorsystemConfig.additionalFiles, copying each host file into the baseline root at itsfinalpath (mirroring create-mode behavior for the Ubuntu and Debian overlay providers). The copy runs as the last build step — after both initramfs and GRUB regeneration — so a prebuilt boot artifact such as a custom/boot/initrd.img-*lands after regeneration instead of being overwritten byupdate-initramfs. Files that must instead be consumed by regeneration (for example initramfs-tools hooks under/etc/initramfs-tools/) still belong in asystemConfig.configurationscommand that runs the generator, which executes earlier in the pipeline. Unlike create mode, overlay does not auto-inject apt source/preferences/GPG files intoadditionalFiles(overlay installs from prepared artifacts, not live apt repositories), so only user-authored entries are copied.Overlay kernel command line & GRUB2 regeneration: Overlay builds on a GRUB2 baseline now apply
overlayPolicy.kernelCmdline(a full-line replacement ofGRUB_CMDLINE_LINUXin/etc/default/grub) and the optionaloverlayPolicy.grubDefault(a full-line replacement ofGRUB_DEFAULT, to pin the default boot menu entry — e.g. an Ubuntu submenu path for an overlay-added flavored kernel), then regenerate the GRUB configuration with the baseline’s native tool (update-grub/grub-mkconfig) after the initramfs is rebuilt. A kernel added by the overlay gets a boot menu entry automatically. The bootloader binary and the read-only ESP are never modified (grub-installis never run); regeneration failures fail the build so no image is emitted; a best-effort warning is logged when a Secure Boot baseline has no signing material. Bootloader- and kernel-image replacement remain blocked by overlay preflight.Overlay package removal & SBOM sidecars: Overlay builds gain two hardening features.
overlayPolicy.allowPackageRemoval(default off, and only valid withpackageOperation: additive-and-upgrade) permits removing a baseline package that an added package conflicts with (for example removinginitramfs-toolssodracutcan install); bootloader and bootable-kernel packages are never removed, removals are shown in the OVERLAY PACKAGE STATISTICS summary, and a removal that leaves an unrelated baseline package with an unmet dependency fails the build (later relaxed into a bounded cascade — see the cascade-removal note above). Overlay builds also emit SPDX SBOM sidecars next to the image: a delta SBOM (<image>-<version>.delta.spdx.json, always written) listing the overlay-contributed packages, and — when a base SBOM is available (an inherited/usr/share/sbominventory or an externalbaseline.source.sbomPath) — a complete SBOM (<image>-<version>.complete.spdx.json) with the full baseline+overlay inventory. The initramfs generator is selected by what the baseline actually ships (dracut vs update-initramfs) rather than by package-manager family. UnsupportedsystemConfigsections in an overlay template (hostname,network,initramfs,kernel,immutability,fde,bootloader) now fail the build up front instead of being silently ignored, and overlay builds no longer inherit the create-mode OS default configuration (disk size/partitions, bootloader, kernel, and base packages come from the baseline image).Overlay
additionalFiles.stagemarker & inspection CLI change: A new per-fileadditionalFiles.stagefield controls WHEN an overlay copies a file relative to boot/initramfs regeneration. The default (stage: "", or omitted) keeps the historical behavior — the file is copied at the end of the build, after regeneration. Setstage: pre-initramfsto copy the file BEFORE initramfs/boot regeneration so the generator can consume it (e.g. a dracut module or an initramfs-tools hook that must be baked into the initramfs). The marker is overlay-only; create-mode builds ignore it. Separately, the overlay--inspectflag now defaults off (it previously defaulted on): when set, the post-build inspection report is written to a<image>-<version>.inspect.txtsidecar in the build artifacts directory instead of the console, and when unset nothing is written. The now-redundant--no-inspectflag has been removed — inspection is off by default, so scripts that passed--no-inspectto disable it should simply drop the flag.Overlay emits every build-mode output format: Overlay builds now honor
disk.artifactsthe same way create-mode builds do, so requestingqcow2,vhd,vhdx,vmdk,vdi, ortar(with optional compression) produces those formats instead of silently emitting only a.rawfile. The overlay always assembles a RAW image internally, then converts it to the requested formats after the post-build RAW inspection; a template whosedisk.artifactsomitsrawdeletes the intermediate RAW during conversion, and a build withdisk.artifactsempty or listing onlyrawis unchanged (plain RAW, no conversion step).Build from scratch with
--no-cache: Thebuildcommand now accepts a--no-cacheflag that runs the build in fresh, unique cache and workspace directories (ignoring any existing caches) and removes them once the build finishes. The final image is copied into the configuredwork_dirbeforehand.--no-cachecannot be combined with--cache-diror--work-dir.Template
extendsinheritance: User templates now accept an optionalextends:field pointing at a parent template. The parent is resolved relative to the child’s directory, and the chain (root → intermediate levels → leaf, up to 4 recommended levels) is folded together before OS defaults are applied — using the same per-section merge rules the two-layer user↔default merge already uses (packages additive+deduped, users merged byname,additionalFilesmerged byfinalpath,diskreplaced wholesale,kernel/bootloader/networkper-field, and so on). Cycle detection, target-match enforcement, path-containment guards, and symlink rejection all apply, and the resolved chain is logged at info level during builds. Useimage-composer-tool resolve TEMPLATE.ymlto inspect the chain-merged result before building. See Template Extends (Inheritance) for the full reference.resolvesubcommand for template debugging: A newimage-composer-tool resolve <template.yml>command prints the merged image template as YAML to stdout, so contributors can see exactly what the tool sees before running a build. By default the extends chain is folded without OS defaults; passing--fulladditionally merges the OS defaults, producing the exact template that would be built. Sensitive fields (user passwords, hash algorithms, and secure boot key/cert/cer paths) are always redacted in the output, and the merged view is computed on demand and never cached.ARM64/aarch64 cross-architecture image builds: Ubuntu 24, eLxR 12, and AZL3 images can now be composed on an x86_64 host targeting ARM64. The builder validates host-side prerequisites (arch-test, qemu-user-static), normalizes architectures for
mmdebstrapanddpkg, and forces a host-side ukify execution when the host and target architectures differ.Ubuntu 24 ARM64 bootable server image: Added a user template and supporting configuration to produce a bootable Ubuntu 24
aarch64server image.Ubuntu 26.04 LTS (Resolute Raccoon) support: New OS target and associated configuration for Ubuntu 26.04.
eLxR Edge 26.04 / eLxR 13 support: New OS provider, image configuration, and user templates for eLxR 13 (elxr-edge-26.04) raw image builds.
Debian 13 user templates: New raw image template and Desktop Virtualization (IDV) ISO installer template for Debian 13.
ROS 2 Jazzy robotics templates: New AMR raw image template and a companion ISO installer template for ROS 2 Jazzy edge robotics platforms.
PTL PV attended and unattended ISO templates: New attended and unattended ISO installer templates for PTL (Platform Validation Toolkit) PV (Para-Virtual) configurations including cloud-init example configuration files.
Unattended ISO installer with policy-based target disk selection:
live-installernow supports fully automatic installation using aselectionPolicyblock in the disk template section. Supported strategies: first, largest, fastest (prefers NVMe over SSD over HDD), and largest-free (selects the disk with the most unallocated span). Removable and externally attached disks are excluded by default and can be included explicitly withexcludeRemovable: false.Declarative network configuration in image templates: A new
systemConfig.networksection defines network interfaces at image composition time. It supportssystemd-networkdandnetplanbackends, configures DHCP, static IP/CIDR addresses, default gateways (via routes), and DNS nameservers per interface.Network configuration view in attended ISO installer: The attended (interactive) ISO installer now includes a “Configure Network” step that allows selecting an interface and entering DHCP or static IP/gateway/DNS settings before installation.
Local package repository population via
packageRepositoriessection: ThepackageRepositoriesschema now accepts a package list whose entries are HTTPS URLs (downloaded at build time) or local file/directory paths (copied). Archives (.tar, .tar.gz, .tgz, .zip) are extracted for their .deb/.rpm payloads. Thepathfield is optional whenpackagesis set. A temporary directory is auto-created and cleaned up. An optionalinsecureSkipVerifyflag allows skipping TLS certificate verification for downloads from environments with self-signed certificates.Full offline/cache mode for DEB and RPM repositories: DEB Packages.gz metadata is now cached by SHA-256 checksum (
packages.parsed.json) undercache_dir/and reused on rebuilds with no network access. RPMprimary.xmlmetadata andprimary.location.jsonare cached undercache_dir/rpm-metadata/. Debian repository GPG keys are cached incache_dir/gpg-keys/. Repository file-existence check results and package-list URLs are cached in-process per run to eliminate redundant HEAD requests.DKMS module installation: Package resolution now uses a target-name-aware candidate filter (
filterCandidatesByPriorityWithTarget) that prefers exact-name matches over Provides virtual package matches, preventing kernel packages that provide a DKMS module name from being selected instead of the actual DKMS package.
Improved:
RPM package cache:
DownloadPackagesCompletenow checks for a valid local cache before contacting the repository. If all required packages are present, no network request is made. Only the missing packages are re-fetched, preserving existing cached files.DEB package cache:
DownloadPackagesperforms a staleness check against the local.debcache (by name) before downloading. Version-pinned requirements and epoch-prefixed package names are matched correctly.Chroot environment package isolation: The chroot-build tool package cache and the initrd package cache are now stored in dedicated subdirectories (
chrootenv/andinitrd/respectively) to prevent the stale-cache check from evicting image packages when the two sets do not overlap.Chroot cleanup error handling:
CleanupChrootEnvandUmountChrootSysfsnow accumulate all cleanup errors rather than short-circuiting on the first failure. All partial errors are surfaced in the returned error.Mount rollback on failure:
mountDiskToChrootandMountSysfsnow roll back previously mounted paths when a later mount step fails, preventing orphaned bind mounts.Loop device cleanup:
LoopSetupDeletenow detects and disables any SWAP partitions on the loop device before callinglosetup -d, preventing detach failures caused by active swap.Loop device error cleanup on creation failure: If loop device creation fails but a partial loop device path is returned,
BuildRawImagenow detaches it immediately rather than leaking the resource.Disk partition creation reliability:
createPartitionTablenow retries wipe (wipefs) andsfdiskcommands in separate loops with a 30-second timeout each, verifying vialsblk/sfdiskthat the expected state is actually reached before proceeding.Grub command detection in install root:
getGrubVersionandupdateGrubConfignow resolve grub binaries by checking known absolute paths in the install root (/usr/sbin/,/usr/bin/) before falling back to shellcommand -v.update-grubis now also accepted as a valid fallback.apt-getinstall with--no-install-recommends: DEB package installation in the chroot environment now passes--no-install-recommends, reducing unnecessary package pulls.sudo suppressed when already root:
GetFullCmdStrdetects when the process is already running as root (euid == 0) and omits the redundant innersudoprefix from both chroot and host commands. ICT is launched as root (sudo -E image-composer-tool build ..., or the server’ssudo -n ...), so an innersudois a root-to-root no-op that only forks an extra process per command; dropping it also avoids permission-escalation errors in CI environments that run as root. When the process is not root the prefix is kept so the per-command sudo model still elevates.Partition mount-point path resolution:
resolveInstallRootMountPointis now the single canonical function for joining the install root and partition mount points. It handles empty, /-absolute, and relative mount-point strings uniformly.Default installer partitioning mode: The attended ISO installer now starts in manual partitioning mode by default; partition template state is cleared when entering manual mode to avoid stale configuration.
Installer startup scripts hardened:
attendedinstallerandunattendedinstallershell scripts replaced withset -euo pipefail, standardized quote handling, and[[...]]conditionals for more robust error propagation.Dual GPG key per repo for RPM EMT distro: RPM-based EMT repositories now support a second GPG public key (
pkeyslist), enabling repositories that require two signing keys.Boot partition label in EMT-EMF template: Explicit partition labels added to the boot partition.
systemd-resolvedenabled at startup for RCD: RCD image builds now enable and startsystemd-resolvedas part of post-install configuration.intel-dlstreamer / OpenVINOversion alignment for RCD: Fixed version mismatch betweenintel-dlstreamerandopenvinoin RCD templates.intel-dlstreameris pinned to 2025.2.0.ukifylookup paths:shell.gonow searches additional known installation prefixes forukifyso builds on distributions that install it in non-standard locations do not fall back to host-side execution unnecessarily.Progress bar terminal output: A trailing newline is now emitted after progress bars finish (
VerifyDEBs,VerifyAll,FetchPackages) to prevent the next log line from overwriting the progress bar.CopyDirempty-source handling: Fixed glob pattern from/*to/.so that copying an empty source directory does not produce a shell error.RPM dependency graph (
PkgName):GenerateDotnow uses thePkgNamefield for node names in dependency graphs, producing clean package names instead of raw filenames.Network schema validation: IPv4/IPv6 CIDR addresses, gateway addresses, and nameservers in
systemConfig.networkare now validated against typed formats in the JSON schema; DHCP and static addresses cannot be combined on the same interface.Debian 13 graphics template ships a desktop terminal and GUI installer: The
debian13-x86_64-bb-graphics-raw.ymltemplate now addsgnome-terminalandgnome-softwareon top of its GNOME desktop stack (gdm3+gnome-session+gnome-shell). Previously the composed desktop had no terminal application in the Activities overview and no graphical way to browse or install packages, becausegnome-shell/gnome-sessiondo not pull those in (only the largergnome-core/gnomemetapackages do). Both packages merge additively under the template’s inheritedadditive-and-upgradeoverlay policy; the CLIaptis unchanged and already present.Image templates grouped by distribution:
image-templates/is now organized into one subdirectory pertarget.dist(azl3/,debian13/,el10/,elxr12/,elxr13/,emt3/,ubuntu24/,ubuntu26/) instead of a single flat listing of 60 files. Filenames are unchanged, soimage-templates/ubuntu24-x86_64-minimal-raw.ymlbecomesimage-templates/ubuntu24/ubuntu24-x86_64-minimal-raw.yml. If you reference a template by path in a script or automation, add the distribution directory. Templates packaged into the.debunder/usr/share/ict/examples/gain the same subdirectories. Distribution is the grouping used because anextends:chain must be siblings in one directory and must shareos/dist/arch/imageType, so a distribution directory can never split a valid chain. New guides ship alongside the templates:image-templates/README.md(catalog),COMPOSITION.md(extends:and overlay mode) andCONVENTIONS.md(naming), plus aREADME.mdper distribution.Templates composed with
extendsinstead of duplication: Several templates now inherit a base template rather than restating it.emt3-x86_64-emf-raw.ymlandemt3-x86_64-dlstreamer.ymlextendemt3-x86_64-edge-raw.yml, andemt3-x86_64-emf-rt-raw.ymlextendsemt3-x86_64-emf-raw.yml. This removes a 41-package block that had been copied verbatim into four EMT3 templates. Each derived template was verified withresolve --fullto produce the same functional fields as before. Note that because package lists are a union with no removal syntax, a derived template also installs its parent’s packages. And because the three EMT3 templates now inheritemt3-x86_64-edge-raw.yml, they also inherit its three sample repositories (company-internal,dev-tools,intel-openvino), soemf-rawandemf-rt-rawresolve to three repositories where they previously declared none anddlstreamerresolves to six rather than three. Those entries are inert — their URLs are the literal placeholder<URL>, whichrpmutilsskips before fetching, and EMT3 is RPM-based so apt-source generation never runs for it — so the built image is unchanged. Each of the three templates notes this in its header.
Fixed:
fix(debian13): drop stale kernel version pins from Debian 13 OS defaults: Debian 13 repositories no longer provide kernel version6.12.74, so inherited ISO, initrd, and raw configurations (x86_64 and aarch64) failed during package resolution. Removing the pin lets each architecture’s kernel metapackage —linux-image-amd64on x86_64 andlinux-image-arm64on aarch64 — select the current repository kernel.Templates in subdirectories are now discovered: template scanning walked only the top level of the templates directory and skipped subdirectories, which would have hidden every template from the AI/RAG index and the web UI template list once templates were grouped into per-distribution directories. The scan is now recursive, as are the
image-composer-*Copilot skill scripts.elxr-cloud-amd64.ymladditional files were silently dropped: the template referencedfiles/etc/...while the files ship inelxr-cloud-amd64/files/etc/..., so all fouradditionalFilesentries failed to resolve and were skipped with a warning rather than being copied into the image.Drifted RealSense apt pin in the robotics raw template:
ubuntu24-x86_64-robotics-jazzy-raw.ymlpinnedlibrealsense2where its ISO counterpart pinnedlibrealsense2*, leaving the RealSense sub-packages unpinned in raw images. Both templates now use the glob.fix(config): drop stalekernel.versionpin from the ubuntu24 OS defaults: ubuntu24 builds failed in pre-processing withkernel version mismatch: requires kernel version "6.17", but available versions are: [6.8.0-31.31 7.0.0-28.28~24.04.1]. Four default configs underconfig/osv/ubuntu/ubuntu24/imageconfigs/defaultconfigs/pinnedkernel.version: "6.17"alongside the rolling metapackagelinux-image-generic-hwe-24.04, and Ubuntu noble no longer ships 6.17. Any template without its ownkernel.versioninherited the stale pin, soubuntu24-x86_64-minimal-initrd.ymlandubuntu24-x86_64-dkms-demo.ymlfailed even though the templates themselves were already clean. #765 removed this antipattern from the 12 affected user templates but did not cover the OS defaults, which is why the failure recurred;image-templates/robotics-demo-ubuntu24-x86_64.ymlwas also missed there and is fixed here. Dropping the pin letsaptresolve whatever the metapackage currently points to — no pin, nothing to go stale. Templates that pin a concrete kernel package (for examplelinux-image-6.11.0-17-generic,linux-image-6.12-intel) are unaffected.fix(ubuntu):AllowPackagesnot propagated to debutils.Repository (#480): TheallowPackageslist in user-provided package repository configuration was silently dropped instead of being passed through to the DEB package resolver.fix(inspect): ext4 filesystem misdetection in image inspect (#484): The image inspect command was incorrectly classifying some ext4 partitions as a different filesystem type.Fixes for error logs when building UKI (#485): Spurious or incorrect error log entries emitted during UKI image construction were corrected.
fix(templates): pin intel-dlstreamer to 2025.2.0 (#492):intel-dlstreamerineLxR/RCDtemplates was not version-pinned, causing uncontrolled version updates.fix(templates): kernel version metadata 6.14 → 6.17 (#494): Template metadata version field for Ubuntu 24 kernels corrected to match the actual installed kernel series.fix(templates): pin ubuntu24 edge kernel to noble GA (6.8) (#761): Theubuntu24-x86_64-edge-rawandubuntu24-aarch64-edge-rawtemplates pinnedkernel.version: 6.17withlinux-image-generic-hwe-24.04, a combination Ubuntu noble no longer ships — only6.8.0-31.31(GA) and7.0.0-28.28~24.04.1(HWE-edge) are available. Pin the kernel to the noble GA combination (6.8+linux-image-generic) so thebuild-ubuntu24-immutableCI job can complete.fix(templates): drop stalekernel.versionpin across ubuntu24 metapackage templates (#765): Every ubuntu24 template that combined akernel.versionstring with a rolling metapackage (linux-image-generic-hwe-24.04,linux-image-generic,linux-image-generic*) was one HWE roll away from the same class of CI break that #494, #669, and #761 fixed. Drop thekernel.versionline from those templates soaptresolves whatever the metapackage currently points to — no pin, nothing to go stale. Templates with an intentionally-pinned concrete kernel package (e.g.linux-image-6.11.0-17-genericinubuntu24-server-cloud-amd64.yml) are unaffected.RPM DOT file naming bug (#538):
GenerateDotused the raw filename (e.g.,glibc-2.38-16.azl3.x86_64.rpm) as a node label instead of the canonical package name (glibc), producing incorrect dependency graphs.Swap partition cleanup before loop device detach (#568): Building images that include a swap partition would fail at teardown because the loop device was busy. The swap partition is now detected and disabled with
swapoffbeforelosetup -d.Ubuntu 24 ARM64 minimal raw template boot partition type: The
xbootldrpartition inubuntu24-aarch64-minimal-raw.ymlhad an incorrectfsType: vfat. It is now corrected toext4.Local DEB repo path in chroot:
initDebLocalRepoWithinInstallRootused an incorrect path separator for the/cdrom/cache-repomount point inside the chroot, causing package installation failures.Deferred cleanup of local DEB repo: De-initialization of the local Debian repository inside the install root is now performed via a defer statement, ensuring cleanup happens even when package installation fails midway.
fix(scripts): remove Intel-internal proxy from repository configuration (#561): An Intel-internal proxy URL was hardcoded in repository configuration, causing failures in external environments.
Known Issues:
Unattended ISO installer is a first-pass implementation: The unattended installer (
ubuntu24-x86_64-minimal-unattended-iso.yml) does not yet support all advanced partition layouts (e.g.,LVM,LUKS). Complex partition schemes must use the attended installer or a custom startup script.ARM64 cross-architecture builds require host tools: Builds targeting aarch64 from an
x86_64host require arch-test and qemu-user-static installed on the build host. The builder will detect and report missing dependencies but does not install them automatically.Loop devices not destroyed when image building is terminated abruptly: When the image build process is terminated abruptly using
ctrl-C, loop devices created just prior toctrl-Care not removed automatically. The loop devices must be manually removed by the user.
Version 1.0#
Release Date: December 12, 2025
Features:
Support for building OS images with Intel® specific OOT Kernel packages.
Support for building Wind River eLxr 12 images.
Support for adding multiple Debian package repositories, e.g., Intel® and OSV.
Ability to set priority for repositories to manage conflicts.
Ability to prioritize specific packages to manage conflicts.
Caching for consistent and faster composition.
Debian repository GPG keys are now cached in
cache_dir/gpg-keysand reused on rebuilds to avoid re-downloading.RPM repository metadata is now cached in
cache_dir/rpm-metadataand reused on rebuilds to avoid network fetches.Native support for Debian and RPM based distributions.
Support for building immutable OS images with DM-Verity and read-only file system support.
Generation of signed OS images using provided keys for Secure Boot.
Support for Unified Kernel Image (UKI) with systemd over UEFI BIOS or Legacy BIOS.
Verbose and filtered logging based on severity to provide easy troubleshooting.
User-defined OS image configuration.
Seamless support for AI software stacks - Edge AI Libraries in user space of the OS distribution.
Support for composing the OS images to include ECG Sample Apps.
Known Issues/Opens:
Installation from ISO images on NVMe SSD and via USB is not functional on RPL platforms.
Face Detection and Recognition application output video is not displayed locally.
Support for building Ubuntu OS images is being considered.