Skip to content

Instantly share code, notes, and snippets.

@mwhudson
Last active May 20, 2022 04:59
Show Gist options
  • Save mwhudson/66d7774fe3df870c8e450aacf7eda4d0 to your computer and use it in GitHub Desktop.
Save mwhudson/66d7774fe3df870c8e450aacf7eda4d0 to your computer and use it in GitHub Desktop.
diff --git a/debian/changelog b/debian/changelog
index e4b6c681..74c7a2e6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+livecd-rootfs (2.765) UNRELEASED; urgency=medium
+
+ * Produce a tarball of artefacts for netbooting during live-server build.
+
+ -- Michael Hudson-Doyle <michael.hudson@ubuntu.com> Mon, 16 May 2022 21:29:39 +1200
+
livecd-rootfs (2.764) jammy; urgency=medium
[ Michał Sawicz ]
diff --git a/live-build/auto/config b/live-build/auto/config
index e223954e..dd9fa173 100755
--- a/live-build/auto/config
+++ b/live-build/auto/config
@@ -1,7 +1,14 @@
#! /bin/sh
set -e
-rm -rf config
+if [ -e config/germinate-output ]; then
+ mv -T config/germinate-output germ-tmp
+ rm -rf config
+ mkdir config
+ mv -T germ-tmp config/germinate-output
+else
+ rm -rf config
+fi
echo "Building on $(hostname --fqdn)"
@@ -298,7 +305,7 @@ _sanitize_passes ()
# if root pass, no parent to find
[ -z "$parent" ] && continue
if [ $(echo "$passes"|grep -cE "^$parent\$") -ne 1 ]; then
- echo "ERROR: '$parent' is required by '$pass' but is missing. Registered passes are:\n$passes"
+ echo "ERROR: '$parent' is required by '$pass' but is missing. Registered passes are:\n$passes" >&2
exit 1
fi
done
@@ -867,6 +874,18 @@ case $PROJECT in
add_package ubuntu-server-minimal.ubuntu-server.installer.$flavor $kernel_metapkg
LIVE_PASSES="${LIVE_PASSES:+$LIVE_PASSES }ubuntu-server-minimal.ubuntu-server.installer.$flavor"
done
+ case $ARCH in
+ amd64)
+ add_package ubuntu-server-minimal.ubuntu-server.installer.generic.netboot grub-pc shim-signed pxelinux
+ ;;
+ arm64)
+ add_package ubuntu-server-minimal.ubuntu-server.installer.generic.netboot shim-signed
+ ;;
+ *)
+ add_package ubuntu-server-minimal.ubuntu-server.installer.generic.netboot
+ ;;
+ esac
+ NO_SQUASHFS_PASSES=ubuntu-server-minimal.ubuntu-server.installer.generic.netboot
/usr/share/livecd-rootfs/checkout-translations-branch \
https://git.launchpad.net/subiquity po config/catalog-translations
diff --git a/live-build/ubuntu-server/hooks/03-kernel-metapkg.chroot_early b/live-build/ubuntu-server/hooks/03-kernel-metapkg.chroot_early
index 864d4c4c..ec02cc3c 100755
--- a/live-build/ubuntu-server/hooks/03-kernel-metapkg.chroot_early
+++ b/live-build/ubuntu-server/hooks/03-kernel-metapkg.chroot_early
@@ -2,6 +2,9 @@
# vi: ts=4 noexpandtab
case $PASS in
+ ubuntu-server-minimal.ubuntu-server.installer.*.*)
+ exit 0
+ ;;
ubuntu-server-minimal.ubuntu-server.installer.*)
flavor=${PASS##*.}
if [ "$flavor" = "generic" ]; then
diff --git a/live-build/ubuntu-server/hooks/04-kernel-bits.binary b/live-build/ubuntu-server/hooks/04-kernel-bits.binary
index c0b2e3d7..a5d64a12 100755
--- a/live-build/ubuntu-server/hooks/04-kernel-bits.binary
+++ b/live-build/ubuntu-server/hooks/04-kernel-bits.binary
@@ -2,6 +2,9 @@
# vi: ts=4 noexpandtab
case $PASS in
+ ubuntu-server-minimal.ubuntu-server.installer.*.*)
+ exit 0
+ ;;
ubuntu-server-minimal.ubuntu-server.installer.*)
flavor=${PASS##*.}
;;
diff --git a/live-build/ubuntu-server/hooks/05-netboot-tarball.binary b/live-build/ubuntu-server/hooks/05-netboot-tarball.binary
new file mode 100755
index 00000000..04d465f7
--- /dev/null
+++ b/live-build/ubuntu-server/hooks/05-netboot-tarball.binary
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+case $PASS in
+ ubuntu-server-minimal.ubuntu-server.installer.generic.netboot)
+ ;;
+ *)
+ exit 0
+ ;;
+esac
+
+set -eux
+
+flavor=generic
+
+KERNEL=${PWD}/livecd.${PROJECT}.kernel-$flavor
+INITRD=${PWD}/livecd.${PROJECT}.initrd-$flavor
+
+mkdir tarball
+mkdir tarball/$ARCH
+
+case $ARCH in
+ s390x)
+ cp $INITRD tarball/$ARCH/initrd.ubuntu
+ cp $KERNEL tarball/$ARCH/kernel.ubuntu
+ ;;
+
+ *)
+ cp $INITRD tarball/$ARCH/initrd
+ cp $KERNEL tarball/$ARCH/kernel
+ ;;
+esac
+
+case $ARCH in
+ amd64)
+ mv chroot/usr/lib/PXELINUX/pxelinux.0 tarball/pxelinux.0
+ mv chroot/usr/lib/syslinux/modules/bios/ldlinux.c32 tarball/ldlinux.c32
+ mv chroot/usr/lib/shim/shimx64.efi tarball/bootx64.efi
+ mv chroot/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed tarball/grubx64.efi
+
+ mkdir tarball/x86_64-efi tarball/pxelinux.cfg
+ cat > tarball/x86_64-efi/grub.cfg.in <<EOF
+menuentry "Install Ubuntu Server" {
+ set gfxpayload=keep
+ linux amd64/linux url=#ISOURL# ip=dhcp ---
+ initrd amd64/initrd
+}
+EOF
+ cat > tarball/pxelinux.cfg/default.in <<EOF
+DEFAULT install
+LABEL install
+ KERNEL amd64/linux
+ INITRD amd64/initrd
+ APPEND root=/dev/ram0 ramdisk_size=1500000 ip=dhcp url=#ISOURL# ---
+EOF
+ ;;
+
+ arm64)
+ mv chroot/usr/lib/shim/shimaa64.efi tarball/bootaa64.efi
+ mv chroot/usr/lib/grub/arm64-efi-signed/grubnetaa64.efi.signed tarball/grubaa64.efi
+
+ mkdir tarball/arm64-efi
+ cat > tarball/arm64-efi/grub.cfg.in <<EOF
+menuentry "Install Ubuntu Server" {
+ set gfxpayload=keep
+ linux arm64/linux url=#ISOURL# ip=dhcp ---
+ initrd arm64/initrd
+}
+EOF
+ ;;
+
+ s390x)
+ cat > tarball/s390x/ubuntu.exec <<EOF
+/* REXX EXEC TO IPL Ubuntu for */
+/* z Systems FROM THE VM READER. */
+/* */
+'CP CLOSE RDR'
+'PURGE RDR ALL'
+'SPOOL PUNCH * RDR'
+'PUNCH KERNEL UBUNTU * (NOHEADER'
+'PUNCH PARMFILE UBUNTU * (NOHEADER'
+'PUNCH INITRD UBUNTU * (NOHEADER'
+'CHANGE RDR ALL KEEP NOHOLD'
+'CP IPL 000C CLEAR'
+EOF
+ cat > tarball/s390x/ubuntu.ins <<EOF
+* Ubuntu for IBM Z (default kernel)
+kernel.ubuntu 0x00000000
+initrd.off 0x0001040c
+initrd.siz 0x00010414
+parmfile.ubuntu 0x00010480
+initrd.ubuntu 0x01000000
+EOF
+ cat > tarball/s390x/parmfile.ubuntu.in <<EOF
+url=#ISOURL# ---
+EOF
+ perl -e "print pack('N', 0x1000000)" > tarball/s390x/initrd.off
+ perl -e "print pack('N', -s 'tarball/s390x/initrd.ubuntu')" > tarball/s390x/initrd.siz
+ cat > tarball/s390x-kvm.cfg.in <<EOF
+DEFAULT install
+LABEL install
+ KERNEL amd64/linux.ubuntu
+ INITRD amd64/initrd.ubuntu
+ APPEND ip=dhcp url=#ISOURL# ---
+EOF
+ cat > tarball/dpm.cfg.in <<EOF
+PROMPT 1
+DEFAULT install
+TIMEOUT 1
+LABEL install
+ kernel=amd64/linux.ubuntu
+ initrd=amd64/initrd.ubuntu
+ append=ip=dhcp url=#ISOURL# ---
+EOF
+ ;;
+esac
+
+tar -C tarball -czf livecd.${PROJECT}.netboot-${ARCH}.tgz .
+rm -rf tarball
diff --git a/lib/cdimage/build.py b/lib/cdimage/build.py
index 97439ae..6d943ee 100644
--- a/lib/cdimage/build.py
+++ b/lib/cdimage/build.py
@@ -738,6 +738,21 @@ def build_image_set_locked(config, options, multipidfile_state):
configure_splash(config)
run_debian_cd(config)
+ # Copy netboot tarballs too. (should be in a function)
+ # mv ../$arch.netboot-$arch.tar.gz debian_cd_dir/$series-netboot-$arch.raw
+ scratch_dir = os.path.join(
+ config.root, "scratch", config.project, config.full_series,
+ config.image_type)
+ for arch in config.arches:
+ netboot_path = os.path.join(
+ live_output_directory(config),
+ '%s.netboot-%s.tar.gz' % (arch, arch))
+ if os.path.exists(netboot_path):
+ output_dir = os.path.join(scratch_dir, "debian-cd", arch)
+ os.rename(
+ netboot_path, os.path.join(
+ output_dir,
+ '%s-netboot-%s.raw' % (config.series, arch)))
fix_permissions(config)
# Temporarily turned off for live builds.
diff --git a/lib/cdimage/livefs.py b/lib/cdimage/livefs.py
index 83ab8a2..c1994d8 100644
--- a/lib/cdimage/livefs.py
+++ b/lib/cdimage/livefs.py
@@ -588,6 +588,11 @@ def live_item_paths(config, arch, item):
if url.endswith("modules.squashfs"):
continue
yield url
+ elif item == "netboot-tarball":
+ for url in urls_for(
+ 'livecd.%s.netboot-%s' % (liveproject_subarch, arch),
+ 'tar.gz'):
+ yield url
elif item in (
"kernel", "initrd", "bootimg", "modules.squashfs"
):
@@ -805,6 +810,7 @@ def download_live_filesystems(config):
elif download_live_items(config, arch, "squashfs"):
download_live_items(config, arch, "modules.squashfs")
download_live_items(config, arch, "yaml")
+ download_live_items(config, arch, "netboot-tarball")
got_image = True
elif download_live_items(config, arch, "rootfs.tar.gz"):
got_image = True
diff --git a/lib/cdimage/tree.py b/lib/cdimage/tree.py
index 11ce9dc..501920c 100644
--- a/lib/cdimage/tree.py
+++ b/lib/cdimage/tree.py
@@ -487,6 +487,8 @@ class Publisher:
return "classroom server %s" % cd
else:
return "server install %s" % cd
+ elif publish_type == "netboot":
+ return "netboot tarball"
elif publish_type == "legacy-server":
return "legacy server install %s" % cd
elif publish_type == "serveraddon":
@@ -579,6 +581,10 @@ class Publisher:
sentences.append(
"The install %s allows you to install %s permanently on a "
"computer." % (cd, capproject))
+ elif publish_type == "netboot":
+ sentences.append(
+ "The netboot tarball contains files needed to boot the %s "
+ "installer over the network." % (capproject,))
elif publish_type == "alternate":
sentences.append(
"The alternate install %s allows you to perform certain "
@@ -1089,6 +1095,9 @@ class Publisher:
elif publish_type == "wubi" and entry.endswith(".tar.xz"):
# Wubi images are just "ARCH.tar.xz", with no prefix.
images.append(entry)
+ elif publish_type == "netboot":
+ if entry.startswith('netboot') and entry.endswith(".tar.gz"):
+ images.append(entry)
elif entry.startswith("%s-" % prefix_type):
if (entry.endswith(".list") or
entry.endswith(".img.gz") or
@@ -1121,6 +1130,7 @@ class Publisher:
all_publish_types = (
"live", "desktop",
"live-server",
+ "netboot",
"legacy-server",
"server", "install", "alternate",
"serveraddon", "addon",
@@ -2023,10 +2033,19 @@ class DailyTreePublisher(Publisher):
logger.info("Publishing %s ..." % arch)
osextras.ensuredir(target_dir)
- extension = self.detect_image_extension(source_prefix)
- shutil.move(
- "%s.%s" % (source_prefix, self.source_extension),
- "%s.%s" % (target_prefix, extension))
+ if publish_type == "netboot":
+ # here we should repack the tarball and rewrite the .in files to
+ # have the full URL to the ISO we're about to publish but for
+ # now...
+ extension = 'tar.gz'
+ shutil.move(
+ "%s.%s" % (source_prefix, self.source_extension),
+ "%s.%s" % (target_prefix, extension))
+ else:
+ extension = self.detect_image_extension(source_prefix)
+ shutil.move(
+ "%s.%s" % (source_prefix, self.source_extension),
+ "%s.%s" % (target_prefix, extension))
if os.path.exists("%s.list" % source_prefix):
shutil.move("%s.list" % source_prefix, "%s.list" % target_prefix)
self.checksum_dirs.append(source_dir)
@@ -2633,6 +2652,11 @@ class DailyTreePublisher(Publisher):
for arch in self.config.arches:
published.extend(
list(self.publish_binary("serveraddon", arch, date)))
+ if self.project == "ubuntu-server":
+ if self.publish_type == "live-server":
+ for arch in self.config.arches:
+ published.extend(
+ list(self.publish_binary("netboot", arch, date)))
published.extend(list(self.publish_source(date)))
if not published:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment