Skip to content

feat(convert): support Ubuntu cloud images - #167

Merged
imlk0 merged 5 commits into
masterfrom
convert-ubuntu-guest
Oct 30, 2026
Merged

imlk0 merged 5 commits into
masterfrom
convert-ubuntu-guest

Conversation

@imlk0

@imlk0 imlk0 commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Ubuntu 24.04 LTS (Noble) cloud images as conversion guests, for cryptpilot-convert and cryptpilot-enhance. Clean-room implementation on current master (supersedes the closed #166; test/CI coverage follows in a separate PR stacked on this one).

  • cryptpilot-enhance.sh: DEB guests take apt branches for cloud-init/openssh removal and the aliyun-assist purge; everything the script runs inside the guest is POSIX sh (the guest's /bin/sh is dash on Ubuntu, where the old bash-only script breaks); the sshd hardening also covers /etc/ssh/sshd_config.d/*.conf drop-ins, which Ubuntu reads after the main file.
  • cryptpilot-convert.sh, DEB guest install path: dependencies (dracut, dracut-network, lvm2, cryptsetup) are resolved via apt before dpkg -i runs; host-side version detection of cryptpilot-fde-host can no longer capture an error message as the version string; the zram module install no longer aborts conversions on kernels it cannot resolve.
  • cryptpilot-convert.sh, GRUB: Noble images boot the first menuentry by default and ship no grubenv; after conversion the guest has a GRUB environment block created with the guest's own grub-editenv (fatal if absent: the block's fixed 1024-byte layout is easy to corrupt when hand-crafted), with saved_entry primed from the freshly generated grub.cfg (submenu path form supported), and GRUB_DEFAULT=saved set in every file that defines it. The ESP stub grub.cfg sync no longer overwrites the ESP's early grub configuration.
  • cryptpilot-convert.sh, UKI: when the output ESP is too small for the UKI (~100M on Noble), it is grown to 512M: an awk rewrite of the sfdisk dump shifts the partitions behind the ESP (starts aligned, partition numbers/types/PARTUUIDs unchanged, only the last partition absorbs the size change), and the ESP is re-created with mkfs.vfat at the full size before its files are copied in. No change to the plain-copy path when the ESP is already large enough.
  • READMEs list Ubuntu 24.04 LTS as supported.

Test plan

  • Guest DEB built in an ubuntu:noble container (dpkg-buildpackage).
  • GRUB-mode conversion of the Noble test image in an alinux4 container: rc=0 (567 s); boot partition carries the fresh initrd.img-6.8.0-117-generic; ESP has shim/grub with the search.fs_uuid stub intact; grub.cfg has menuentries; 1024-byte grubenv with saved_entry=Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-117-generic; all PARTUUIDs preserved.
  • UKI-mode conversion (--uki --uki-stub-version 258): rc=0 (167 s); output ESP is 512M with the FAT spanning the partition and the UKI at EFI/BOOT/BOOTX64.EFI (stub 258.3, compact layout); every other partition's PARTUUID unchanged.
  • cryptpilot-enhance smoke against a Noble image with libguestfs (LIBGUESTFS_BACKEND=direct): cloud-init purged with its directories gone, sshd hardened to key-only, root account locked.
  • Host version detection yields an empty version (never an error string) on both an RPM host without the package and a DEB host without it.
  • bash -n, shellcheck (both scripts), cargo fmt --check clean.
  • CI on this PR.
  • Convert+boot CI legs against Ubuntu (follow-up PR).

Notes

  • Inputs need free space behind the last partition (a stock 2.2 GiB Noble image cannot absorb the 512M ESP growth plus LUKS/verity; the 10 GiB test image fits).
  • cryptpilot-enhance still cannot run on alinux4 hosts (supermin detects no package manager driver there); pre-existing documented behavior, verified on alinux3 instead.

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。

imlk0 added 5 commits October 30, 2026 20:50
virt-customize runs every --run-command through the guest's /bin/sh,
which is dash on Ubuntu, so the guest-side blocks drop their bashisms
(arrays, [[ ]], the #!/bin/bash marker) and are plain POSIX sh now.

Package operations dispatch on the guest's package manager: DEB guests
purge cloud-init and openssh-server with apt, RPM guests keep yum. The
Alibaba-agent steps are guarded no-ops on images that never carried
those agents, and each systemctl/rpm step that can only target missing
components tolerates absence instead of failing the whole run.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>

Assisted-by: Claude Code:glm-5.3
Installing user-provided .debs now goes through "apt-get install" with
the copied file paths, so the guest package's dependencies (dracut,
dracut-network, lvm2, cryptsetup) are resolved from the repositories
in one step instead of a dpkg -i plus an "apt-get -f install" whose
failures were swallowed by "|| true". A failed install is now fatal
with the real error visible: a half-installed guest package produces
an image that cannot decrypt its rootfs at boot.

Host-side version detection of cryptpilot-fde-host moves into
pkg::host_fde_version, shared by the RPM and DEB installers, and
validates the captured string: the query tools print "package ... is
not installed" style errors when the host lacks the package, and a
message that leaks into the version slot later fails as a baffling
"unable to locate package" inside the chroot. Anything that does not
start with a digit is discarded and the latest guest package is
requested instead.

The zram kernel-module step no longer aborts the conversion: the
linux-modules-extra package for a custom kernel flavor is often not in
any repo, and its absence only rules out the "ram" delta location,
which the configuration in use may not need. Both failure paths
downgrade to a warning.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>

Assisted-by: Claude Code:glm-5.3
Ubuntu cloud images default to GRUB_DEFAULT=0 and ship no grubenv, so
the guest boots whichever menuentry grub-mkconfig happens to list
first. The conversion only rebuilds the initramfs for the newest
kernel, so the default now goes through the saved-entry mechanism:
GRUB_DEFAULT=saved is written to /etc/default/grub and to every
/etc/default/grub.d drop-in that defines the variable (drop-ins are
sourced last and would otherwise win), and after grub.cfg is
regenerated the environment block is created with the guest's own
grub-editenv (grub2-editenv fallback; neither present is a fatal
error, since hand-crafting the fixed 1024-byte block corrupts it).
The saved_entry is taken verbatim from the generated grub.cfg: the
menuentry title of the newest non-rescue kernel, prefixed with the
submenu title path form when it is nested, which is the exact
identifier GRUB resolves.

The ESP grub.cfg sync no longer overwrites stub configs. Ubuntu keeps
a tiny search.fs_uuid + configfile stub on the ESP that redirects to
the real grub.cfg on the boot partition; the raw partition copy
preserves that partition verbatim, UUID included, so the stub stays
valid, while clobbering it with the full grub.cfg would break the
redirect and the $prefix-relative grubenv. Full ESP copies (the layout
the sync was built for) are still refreshed; a stub has no menuentry
line, so that is the discriminator.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>

Assisted-by: Claude Code:glm-5.3
Ubuntu cloud images ship a ~100M ESP, far too small for the unified
kernel image UKI mode writes there. When the source ESP is smaller
than 512M, the output partition table is rewritten before it is
applied: the ESP entry covers 512M and the partitions behind it on
the disk are relocated (aligned starts), with the last partition
absorbing the size change. Numbers, types and PARTUUIDs ride along on
the untouched part of each sfdisk line, so every partition keeps its
identity.

The grown partition gets a fresh FAT32 filesystem spanning the whole
partition plus a copy of the original ESP's files (FAT label kept so
the guest's LABEL= fstab entry still resolves). Growing the partition
without regrowing the filesystem leaves the old, smaller FAT inside,
and the UKI write later fails with ENOSPC. A source ESP that already
fits keeps the byte-identical raw copy of today.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>

Assisted-by: Claude Code:glm-5.3
Signed-off-by: Kun Lai <laikun@linux.alibaba.com>

Assisted-by: Claude Code:glm-5.3
@imlk0
imlk0 force-pushed the convert-ubuntu-guest branch from d199ecf to c215318 Compare October 30, 2026 12:50
@imlk0
imlk0 merged commit c215318 into master Oct 30, 2026
@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。

@imlk0
imlk0 deleted the convert-ubuntu-guest branch October 30, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants