Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ported the bootable image creation to 24 #76

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions .github/workflows/build-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,24 @@ jobs:
submodules: true
- name: Install build dependencies
run: |
sudo apt install -y make squashfs-tools dosfstools mtools
sudo apt install -y make squashfs-tools dosfstools mtools xorriso grub-common grub-pc-bin
sudo snap refresh --edge snapd
sudo snap install --classic ubuntu-image
- name: Build image
run: |
make
- name: Upload artifacts
- name: Upload image artifact
uses: actions/upload-artifact@v4
with:
name: image
name: bootable-image
path: |
README.md
*.tar.gz
compression-level: 0 # content is already compressed
*.img.xz
compression-level: 0
- name: Upload ISO artifact
uses: actions/upload-artifact@v4
with:
name: bootable-iso
path: |
*.iso
compression-level: 6
55 changes: 46 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@

EXTRA_SNAPS =
ALL_SNAPS = $(EXTRA_SNAPS) firefox
all: pc.tar.gz
all: bootable-iso

bootable-iso: ubuntu-core-desktop-24-amd64.iso
bootable-iso-dangerous: ubuntu-core-desktop-24-dangerous-amd64.iso

define build_img =
rm -rf img${1}
ubuntu-image snap --output-dir img${1} --image-size ${2}G \
$(foreach snap,$(ALL_SNAPS),--snap $(snap)) $<
mv img${1}/${3}.img ./$@
endef

pc.img: ubuntu-core-desktop-24-amd64.model $(EXTRA_SNAPS)
rm -rf img/
ubuntu-image snap --output-dir img --image-size 20G \
$(foreach snap,$(ALL_SNAPS),--snap $(snap)) $<
mv img/pc.img .
$(call build_img,,20,pc)

pc-dangerous.img: ubuntu-core-desktop-24-amd64-dangerous.model $(EXTRA_SNAPS)
rm -rf dangerous/
ubuntu-image snap --output-dir dangerous --image-size 20G \
$(foreach snap,$(ALL_SNAPS),--snap $(snap)) $<
mv dangerous/pc.img pc-dangerous.img
$(call build_img,-dangerous,20,pc)

pi.img: ubuntu-core-desktop-22-pi.model $(EXTRA_SNAPS)
rm -rf dangerous/
Expand All @@ -29,10 +33,43 @@ pi-dangerous.img: ubuntu-core-desktop-22-pi-dangerous.model $(EXTRA_SNAPS)
%.tar.gz: %.img
tar czSf $@ $<

%.img.xz: %.img
xz -k --force --threads=0 -vv $<

.PHONY: all

define build_bootable_img =
rm -rf output/
mkdir -p image
cat image_data/install-sources.yaml.in |sed "s/@FILE@/$</g"|sed "s/@SIZE@/$(shell stat -c%s $<)/g" > image/install-sources.yaml
cat image_data/core-desktop.yaml.in |sed "s/@FILE@/$</g" | sed "s/@OUTPUT@/$@/g" > image/core-desktop.yaml
sudo ubuntu-image classic --debug -O output/ image/core-desktop.yaml
sudo chown -R $(shell id -u):$(shell id -g) output
mv output/$@ .
endef

ubuntu-core-desktop-24-amd64.img: pc.img.xz image_data/core-desktop.yaml.in image_data/install-sources.yaml.in
$(call build_bootable_img)

ubuntu-core-desktop-24-dangerous-amd64.img: pc-dangerous.img.xz image_data/core-desktop.yaml.in image_data/install-sources.yaml.in
$(call build_bootable_img)

ubuntu-core-desktop-24-%.iso: ubuntu-core-desktop-24-%.img
./create_iso.sh $<

clean:
sudo rm -rf img
sudo rm -rf output
sudo rm -rf image
sudo rm -rf image2
sudo rm -rf img-dangerous
sudo rm -rf livecd-rootfs
sudo rm -f pc*.img.xz pc*.img pc*.tar.gz ubuntu-core-desktop-*.img ubuntu-core-desktop-*.img.xz ubuntu-core-desktop-*.iso image/install-sources.yaml

clean-bootable:
sudo rm -rf img
sudo rm -rf output
sudo rm -rf image
sudo rm -rf image2
sudo rm -rf img-dangerous
sudo rm -f ubuntu-core-desktop-*.img ubuntu-core-desktop-*.img.xz ubuntu-core-desktop-*.iso image/install-sources.yaml image/core-desktop.yaml
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# GDM on Ubuntu Core

This directory contains an image of Ubuntu Core 22 with the GDM
display manager loaded into the boot file system. It can be launched
in a Qemu virtual machine by following these instructions:
This directory contains an image of Ubuntu Core 24 with the GDM
display manager loaded into the boot file system, and an ISO image
with an installer for that same image.

The ISO image can be used in any virtual machine. The image, in .zx
compressed format, can be launched in a Qemu virtual machine by
following these instructions:

1. Download and decompress the two image files and place them in the
same directory.
Expand Down
134 changes: 134 additions & 0 deletions create_iso.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/bin/sh

# Process obtained from https://itnext.io/how-to-create-a-custom-ubuntu-live-from-scratch-dd3b3f213f81

# we expect a .xz compressed image (see below where we decompress it)
ORIGINAL_DISK_IMAGE=$1
DISK_IMAGE=$PWD/output/disk.img

# where to mount the disk image
CHROOT=$PWD/output/mnt

cp -a ${ORIGINAL_DISK_IMAGE} ${DISK_IMAGE}

#cd output
# decompress the image
#xz -v -d ${DISK_IMAGE}
#cd ..

mkdir -p $CHROOT
# since we know that the partition with the data is the third one, we use awk to extract the start sector
sudo mount -o loop,offset=$(expr 512 \* $(fdisk -l ${DISK_IMAGE} |grep img3 | awk '{print $2}')) ${DISK_IMAGE} $CHROOT

# we prepare the chroot environment to ensure that everything works inside..
sudo mount -o bind /dev ${CHROOT}/dev
sudo mount -o bind /dev/pts ${CHROOT}/dev/pts
sudo mount -o bind /proc ${CHROOT}/proc
sudo mount -o bind /sys ${CHROOT}/sys
sudo mount -o bind /run ${CHROOT}/run
# install the required packages
sudo chroot ${CHROOT} apt install -y casper
# and, if needed, open a bash shell to do manual checks
# chroot ${CHROOT} /bin/bash
sudo umount ${CHROOT}/run
sudo umount ${CHROOT}/sys/firmware/efi/efivars
sudo umount ${CHROOT}/sys
sudo umount ${CHROOT}/proc
sudo umount ${CHROOT}/dev/pts
sudo umount ${CHROOT}/dev

rm -rf $PWD/image2

mkdir -p $PWD/image2/casper
mkdir -p $PWD/image2/isolinux
mkdir -p $PWD/image2/install

mv $CHROOT/cdrom/casper/* $PWD/image2/casper/

sudo cp $CHROOT/boot/vmlinuz-**-**-generic image2/casper/vmlinuz
sudo cp $CHROOT/boot/initrd.img-**-**-generic image2/casper/initrd

touch image2/ubuntu

cat <<EOF > image2/isolinux/grub.cfg

search --set=root --file /ubuntu

insmod all_video

set default="0"
set timeout=3

menuentry "Install Ubuntu Core Desktop" {
linux /casper/vmlinuz boot=casper quiet splash ---
initrd /casper/initrd
}
EOF

sudo mksquashfs $CHROOT image2/casper/filesystem.squashfs

printf $(sudo du -sx --block-size=1 $CHROOT | cut -f1) > image2/casper/filesystem.size

# we are done with the original disk image
#sudo umount ${CHROOT}/sys/firmware/efi/efivars
#sudo umount ${CHROOT}/sys
sudo umount ${CHROOT}
rmdir ${CHROOT}

cd $PWD/image2

grub-mkstandalone \
--format=x86_64-efi \
--output=isolinux/bootx64.efi \
--locales="" \
--fonts="" \
"boot/grub/grub.cfg=isolinux/grub.cfg"

(
cd isolinux && \
dd if=/dev/zero of=efiboot.img bs=1M count=10 && \
sudo mkfs.vfat efiboot.img && \
LC_CTYPE=C mmd -i efiboot.img efi efi/boot && \
LC_CTYPE=C mcopy -i efiboot.img ./bootx64.efi ::efi/boot/
)

grub-mkstandalone \
--format=i386-pc \
--output=isolinux/core.img \
--install-modules="linux16 linux normal iso9660 biosdisk memdisk search tar ls" \
--modules="linux16 linux normal iso9660 biosdisk search" \
--locales="" \
--fonts="" \
"boot/grub/grub.cfg=isolinux/grub.cfg"

cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img

sudo /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v "\./md5sum.txt" > md5sum.txt)"

sudo xorriso \
-as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-volid "Ubuntu Core Desktop" \
-output ${DISK_IMAGE%.*}.iso \
-eltorito-boot boot/grub/bios.img \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
--eltorito-catalog boot/grub/boot.cat \
--grub2-boot-info \
--grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
-eltorito-alt-boot \
-e EFI/efiboot.img \
-no-emul-boot \
-append_partition 2 0xef isolinux/efiboot.img \
-m "isolinux/efiboot.img" \
-m "isolinux/bios.img" \
-graft-points \
"/EFI/efiboot.img=isolinux/efiboot.img" \
"/boot/grub/bios.img=isolinux/bios.img" \
"."

cd ..
mv ${DISK_IMAGE%.*}.iso ${ORIGINAL_DISK_IMAGE%.*}.iso
rm -rf image2
4 changes: 4 additions & 0 deletions image_data/06_quiet.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output: {all: '>> /var/log/cloud-init-output.log'}
no_ssh_fingerprints: true
ssh:
emit_keys_to_console: false
7 changes: 7 additions & 0 deletions image_data/autoinstall.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 1
source:
id: ubuntu-core-desktop
search_drivers: false
interactive-sections:
- locale
- storage
96 changes: 96 additions & 0 deletions image_data/core-desktop.yaml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: ubuntu-core-desktop-amd64
display-name: Ubuntu Core Desktop amd64
revision: 1
architecture: amd64
series: noble
class: preinstalled
kernel: linux-image-generic
gadget:
url: "https://git.launchpad.net/~canonical-foundations/snap-pc/+git/github-mirror-amd64"
branch: classic
type: "git"
rootfs:
components:
- main
- restricted
seed:
urls:
- "git://git.launchpad.net/~ubuntu-core-dev/ubuntu-seeds/+git/"
branch: noble
names:
- minimal
customization:
cloud-init:
user-data: |
#cloud-config
chpasswd:
expire: false
users:
- name: ubuntu
password: ubuntu
type: text
meta-data: |
#cloud-config
dsmode: local
instance_id: ubuntu-core-desktop
extra-packages:
- name: squashfs-tools
- name: snapd
- name: cloud-init
- name: lshw
- name: bzip2
- name: tar
- name: lvm2
- name: parted
- name: dosfstools
- name: xz-utils
- name: console-setup-linux
- name: whois
- name: mdadm
extra-snaps:
- name: subiquity
- name: core22
- name: snapd
manual:
make-dirs:
- path: /cdrom/casper
permissions: 0755
- path: /etc/systemd/journald.conf.d
permissions: 0755
- path: /etc/systemd/system/systemd-journald.service.d
permissions: 0755
- path: /etc/cloud/cloud.cfg.d
permissions: 0755
copy-file:
- source: install-sources.yaml
destination: /cdrom/casper/install-sources.yaml
- source: ../image_data/autoinstall.yaml
destination: /autoinstall.yaml
- source: ../@FILE@
destination: /cdrom/casper/@FILE@
- source: ../image_data/subiquity-enable
destination: /sbin/subiquity-enable
- source: ../image_data/subiquity-launcher.service
destination: /lib/systemd/system/subiquity-launcher.service
- source: ../image_data/subiquity-launch
destination: /sbin/subiquity-launch
#- source: installer-data.tar.bz2
# destination: /installer-data.tar.bz2
- source: ../image_data/no-rate-limit.conf
destination: /etc/systemd/journald.conf.d/no-rate-limit.conf
- source: ../image_data/no-compact.conf
destination: /etc/systemd/system/systemd-journald.service.d/no-compact.conf
- source: ../image_data/no-hardening.conf
destination: /etc/systemd/system/systemd-journald.service.d/no-hardening.conf
- source: ../image_data/06_quiet.cfg
destination: /etc/cloud/cloud.cfg.d/06_quiet.cfg
execute:
- path: /usr/bin/systemd-machine-id-setup
- path: /sbin/subiquity-enable
artifacts:
img:
-
name: @OUTPUT@
manifest:
name: ubuntu-core-desktop-pc-amd64.manifest

11 changes: 11 additions & 0 deletions image_data/install-sources.yaml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
- default: true
description:
en: Ubuntu Core Desktop.
id: ubuntu-core-desktop
locale_support: locale-only
name:
en: Ubuntu Core Desktop
path: @FILE@
type: dd-xz:file
size: @SIZE@
variant: core
4 changes: 4 additions & 0 deletions image_data/no-compact.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# systemd in 23.04+ uses a newer "compact" format by default which is not
# understood by the systemd libraries from jammy used in the subiquity snap.
[Service]
Environment="SYSTEMD_JOURNAL_COMPACT=0"
4 changes: 4 additions & 0 deletions image_data/no-hardening.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# systemd in 22.04+ uses "hash table hardening" by default which is not
# understood by the systemd libraries from focal used in the subiquity snap.
[Service]
Environment="SYSTEMD_JOURNAL_KEYED_HASH=0"
2 changes: 2 additions & 0 deletions image_data/no-rate-limit.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Journal]
RateLimitIntervalSec=0
Loading