feat: Produce a working minimal image using imagecraft in a livcd-rootfs hook

- Added manifest and filelist generation
- Currently, we only produce minimal images for amd64
- Tested the changes by booting an instance on OVH
- Hook was also tested to be run in a local CPC Jenkins pipeline
This commit is contained in:
Allen Abraham 2026-03-03 10:56:48 -05:00
parent dad4a04751
commit f45429018c
7 changed files with 201 additions and 0 deletions

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
livecd-rootfs (26.04.24) resolute; urgency=medium
* Added a hook to produce a working minimal Ubuntu image using imagecraft
-- Allen Abraham <allen.abraham@canonical.com> Tue, 03 Mar 2026 10:54:22 -0500
livecd-rootfs (26.04.23) resolute; urgency=medium
[ Tobias Heider ]

View File

@ -0,0 +1 @@
datasource_list: [ OpenStack, None ]

View File

@ -0,0 +1,2 @@
dsmode: local
instance_id: ubuntu-server

View File

@ -0,0 +1,100 @@
name: ubuntu-minimal
version: "0.1"
base: bare
build-base: devel
summary: Minimal Ubuntu image for CPC
description: A minimal Ubuntu image to be built using livecd-rootfs by CPC
platforms:
amd64:
volumes:
pc:
schema: gpt
structure:
# 1. BIOS Boot
- name: bios-boot
type: 21686148-6449-6E6F-744E-656564454649
role: system-boot
filesystem: vfat
size: 4M
# 2. EFI System Partition
- name: efi
type: C12A7328-F81F-11D2-BA4B-00A0C93EC93B
filesystem: vfat
filesystem-label: UEFI
role: system-boot
size: 106M
# 3. Linux Extended Boot
- name: boot
type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
filesystem: ext4
filesystem-label: BOOT
role: system-data
size: 913M
# 4. Root Filesystem
- name: rootfs
type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
filesystem: ext4
filesystem-label: cloudimg-rootfs
role: system-data
size: 3G
filesystems:
default:
- mount: "/"
device: "(volume/pc/rootfs)"
- mount: "/boot"
device: "(volume/pc/boot)"
- mount: "/boot/efi"
device: "(volume/pc/efi)"
parts:
rootfs:
plugin: nil
build-packages: ["mmdebstrap"]
override-build: |
mmdebstrap --arch $CRAFT_ARCH_BUILD_FOR \
--mode=sudo \
--format=dir \
--variant=minbase \
--include=apt \
resolute \
$CRAFT_PART_INSTALL/ \
http://archive.ubuntu.com/ubuntu/
rm -r $CRAFT_PART_INSTALL/dev/*
mkdir $CRAFT_PART_INSTALL/boot/efi
organize:
'*': (overlay)/
packages:
plugin: nil
overlay-packages:
- ubuntu-server-minimal
- grub2-common
- grub-pc
- shim-signed
- linux-image-generic
overlay-script: |
rm $CRAFT_OVERLAY/etc/cloud/cloud.cfg.d/90_dpkg.cfg
snaps:
plugin: nil
after: [packages]
overlay-script: |
env SNAPPY_STORE_NO_CDN=1 snap prepare-image --classic \
--arch=amd64 --snap snapd --snap core24 "" $CRAFT_OVERLAY
fstab:
plugin: nil
after: [snaps]
overlay-script: |
cat << EOF > $CRAFT_OVERLAY/etc/fstab
LABEL=cloudimg-rootfs / ext4 discard,errors=remount-ro 0 1
LABEL=BOOT /boot ext4 defaults 0 2
LABEL=UEFI /boot/efi vfat umask=0077 0 1
EOF
cloud-init:
plugin: dump
source: cloud-init/

View File

@ -0,0 +1,86 @@
#!/bin/bash -eux
. config/functions
ARCH="${ARCH:-}"
SUBPROJECT="${SUBPROJECT:-}"
# We want to start off imagecraft builds with just amd64 support right now
case $ARCH in
amd64)
;;
*)
echo "$ARCH builds for imagecraft is currently not implemented."
exit 0
;;
esac
case ${SUBPROJECT} in
minimized)
;;
*)
echo "$SUBPROJECT builds for imagecraft is currently not implemented"
exit 0
;;
esac
_src_d=$(dirname $(readlink -f ${0}))
snap install imagecraft --classic --channel latest/edge
apt install -y qemu-utils parted locales
locale-gen C.UTF-8
export LANG=C.UTF-8
export LC_ALL=C.UTF-8
cp -r "$_src_d"/imagecraft-configs/* .
CRAFT_BUILD_ENVIRONMENT=host imagecraft --verbosity debug pack
mount_image_partitions() {
mount_image "${disk_image}" "$ROOT_PARTITION"
# Making sure that the loop device is ready
partprobe "${loop_device}"
udevadm settle
ls -l "${loop_device}"*
mkdir -p "$mountpoint"
mount_partition "${rootfs_dev_mapper}" "$mountpoint"
mount "${loop_device}p3" "$mountpoint/boot"
mount "${loop_device}p2" "$mountpoint/boot/efi"
}
install_grub_on_image() {
divert_grub "$mountpoint"
chroot "$mountpoint" grub-install --target=i386-pc "${loop_device}"
chroot "$mountpoint" update-grub
undivert_grub "$mountpoint"
echo "GRUB installed successfully."
}
unmount_image_partitions() {
umount "$mountpoint/boot/efi"
umount "$mountpoint/boot"
umount_partition "$mountpoint"
rmdir "$mountpoint"
}
disk_image="pc.img"
ROOT_PARTITION=4
mountpoint="mountpoint"
mount_image_partitions
install_grub_on_image
create_manifest "$mountpoint/" "$PWD/livecd.ubuntu-cpc.imagecraft.manifest" "$PWD/livecd.ubuntu-cpc.imagecraft.spdx" "cloud-image-$ARCH-$(date +%Y%m%dT%H:%M:%S)" "false"
unmount_image_partitions
clean_loops
trap - EXIT
qemu-img convert -f raw -O qcow2 "${disk_image}" livecd.ubuntu-cpc.imagecraft.img

View File

@ -6,3 +6,4 @@ depends qcow2
depends vmdk
depends vagrant
depends wsl
depends imagecraft-image

View File

@ -0,0 +1,5 @@
base/imagecraft-image.binary
provides livecd.ubuntu-cpc.imagecraft.img
provides livecd.ubuntu-cpc.imagecraft.manifest
provides livecd.ubuntu-cpc.imagecraft.filelist