Compare commits

..

No commits in common. "ubuntu/master" and "26.04.22" have entirely different histories.

21 changed files with 60 additions and 722 deletions

28
debian/changelog vendored
View File

@ -1,31 +1,3 @@
livecd-rootfs (26.04.25) resolute; urgency=medium
* bake LIVECD_ROOTFS_ROOT into config/functions, fixing some build failures
(for at least ubuntu and some ubuntu-cpc configurations).
-- Michael Hudson-Doyle <michael.hudson@ubuntu.com> Fri, 20 Mar 2026 06:47:44 +1300
livecd-rootfs (26.04.24) resolute; urgency=medium
[ Allen Abraham ]
* Added a hook to produce a working minimal Ubuntu image using imagecraft
[ Michael Hudson-Doyle ]
* Various quality of life improvements for hacking on livecd-rootfs:
- Add a "ubuntu-test-iso" project that builds a not very useful ISO in 2-5 minutes.
- Add a build-livefs script that takes care of copying the auto scripts and
invoking lb clean/config/build with the right environment.
- Add a build-livefs-lxd script to run the above script in a lxd vm.
-- Michael Hudson-Doyle <michael.hudson@ubuntu.com> Mon, 16 Mar 2026 11:05:13 +1300
livecd-rootfs (26.04.23) resolute; urgency=medium
[ Tobias Heider ]
* Fix ISO builds when KERNEL_FLAVOUR != generic.
-- Michael Hudson-Doyle <michael.hudson@ubuntu.com> Mon, 02 Mar 2026 10:51:47 +1300
livecd-rootfs (26.04.22) resolute; urgency=medium
[ Oliver Gayot ]

View File

@ -1 +0,0 @@
usr/share/livecd-rootfs/live-build/build-livefs usr/bin/build-livefs

View File

@ -375,7 +375,7 @@ EOF
(cd chroot && find usr/share/doc -maxdepth 1 -type d | xargs du -s | sort -nr)
echo END docdirs
${LIVECD_ROOTFS_ROOT}/minimize-manual chroot
/usr/share/livecd-rootfs/minimize-manual chroot
clean_debian_chroot
fi

View File

@ -1,8 +1,6 @@
#!/bin/bash
set -e
LIVECD_ROOTFS_ROOT=${LIVECD_ROOTFS_ROOT:-/usr/share/livecd-rootfs}
case $ARCH:$SUBARCH in
amd64:|amd64:generic|amd64:intel-iot|\
arm64:|arm64:generic|arm64:raspi|arm64:snapdragon|arm64:nvidia|\
@ -49,14 +47,12 @@ if [ -z "$MIRROR" ]; then
fi
mkdir -p config
echo "LIVECD_ROOTFS_ROOT=\"$LIVECD_ROOTFS_ROOT\"" > config/functions
chmod --reference=${LIVECD_ROOTFS_ROOT}/live-build/functions config/functions
cat ${LIVECD_ROOTFS_ROOT}/live-build/functions >> config/functions
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/lb_*_layered config/
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/snap-seed-parse.py config/snap-seed-parse
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/snap-seed-missing-providers.py config/snap-seed-missing-providers
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/expand-task config/expand-task
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/squashfs-exclude-files config/
cp -af /usr/share/livecd-rootfs/live-build/functions config/functions
cp -af /usr/share/livecd-rootfs/live-build/lb_*_layered config/
cp -af /usr/share/livecd-rootfs/live-build/snap-seed-parse.py config/snap-seed-parse
cp -af /usr/share/livecd-rootfs/live-build/snap-seed-missing-providers.py config/snap-seed-missing-providers
cp -af /usr/share/livecd-rootfs/live-build/expand-task config/expand-task
cp -af /usr/share/livecd-rootfs/live-build/squashfs-exclude-files config/
mkdir -p config/package-lists
@ -394,7 +390,7 @@ if [ -z "${IMAGEFORMAT:-}" ]; then
;;
esac
;;
ubuntu-server:live|ubuntu-mini-iso:|ubuntu-test-iso:|ubuntu-core-installer:*)
ubuntu-server:live|ubuntu-mini-iso:|ubuntu-core-installer:*)
IMAGEFORMAT=plain
;;
esac
@ -430,7 +426,7 @@ case $IMAGEFORMAT in
ubuntu-server:live|ubuntu-core-installer:*)
touch config/universe-enabled
;;
ubuntu-mini-iso:|ubuntu-test-iso:)
ubuntu-mini-iso:)
fs=none
;;
*)
@ -640,7 +636,7 @@ case $PROJECT in
esac
case $PROJECT in
ubuntu-mini-iso|ubuntu-test-iso)
ubuntu-mini-iso)
COMPONENTS='main'
;;
edubuntu|ubuntu-budgie|ubuntucinnamon|ubuntukylin)
@ -657,13 +653,6 @@ case $SUBPROJECT in
;;
esac
case $PROJECT in
ubuntu-test-iso)
# ubuntu-test-iso uses only add_package (not add_task) and has no
# pool, so germinate output is never needed.
touch config/germinate-output/structure
;;
*)
if ! [ -e config/germinate-output/structure ]; then
echo "Running germinate..."
if [ -n "$COMPONENTS" ]; then
@ -673,8 +662,6 @@ case $PROJECT in
-S $SEEDMIRROR -m $MIRROR -d $SUITE,$SUITE-updates \
-s $FLAVOUR.$SUITE $GERMINATE_ARG -a ${ARCH_VARIANT:-$ARCH})
fi
;;
esac
# ISO build configuration. These defaults are overridden per-project below.
#
@ -687,9 +674,6 @@ MAKE_ISO=no
# - "server-ship-live" for Ubuntu Server (includes server-specific packages)
# - "" (empty) for images without a pool, like Ubuntu Core Installer
POOL_SEED_NAME=ship-live
# SQUASHFS_COMP: compression algorithm for squashfs images. lz4 is ~10x
# faster than xz and useful for test builds that don't need small images.
SQUASHFS_COMP=xz
# Common functionality for layered desktop images
common_layered_desktop_image() {
@ -820,7 +804,7 @@ do_layered_desktop_image() {
DEFAULT_KERNEL="linux-$KERNEL_FLAVOURS"
if [ "$LOCALE_SUPPORT" != none ]; then
${LIVECD_ROOTFS_ROOT}/checkout-translations-branch \
/usr/share/livecd-rootfs/checkout-translations-branch \
https://git.launchpad.net/subiquity po \
config/catalog-translations
fi
@ -1140,7 +1124,7 @@ case $PROJECT in
NO_SQUASHFS_PASSES=ubuntu-server-minimal.ubuntu-server.installer.$flavor.netboot
DEFAULT_KERNEL="$kernel_metapkg"
${LIVECD_ROOTFS_ROOT}/checkout-translations-branch \
/usr/share/livecd-rootfs/checkout-translations-branch \
https://git.launchpad.net/subiquity po config/catalog-translations
;;
*)
@ -1158,7 +1142,7 @@ case $PROJECT in
# created in ubuntu-core-installer/hooks/05-prepare-image.binary, which
# subiquity knows how to install.
if [ ${SUBPROJECT} == "desktop" ]; then
cp ${LIVECD_ROOTFS_ROOT}/live-build/${PROJECT}/ubuntu-core-desktop-24-amd64.model-assertion config/
cp /usr/share/livecd-rootfs/live-build/${PROJECT}/ubuntu-core-desktop-24-amd64.model-assertion config/
fi
OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal"
PASSES_TO_LAYERS=true
@ -1172,7 +1156,7 @@ case $PROJECT in
USE_BRIDGE_KERNEL=false
DEFAULT_KERNEL="snap:pc-kernel"
${LIVECD_ROOTFS_ROOT}/checkout-translations-branch \
/usr/share/livecd-rootfs/checkout-translations-branch \
https://git.launchpad.net/subiquity po config/catalog-translations
;;
@ -1195,22 +1179,6 @@ case $PROJECT in
esac
;;
ubuntu-test-iso)
OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal"
KERNEL_FLAVOURS=virtual
BINARY_REMOVE_LINUX=false
MAKE_ISO=yes
POOL_SEED_NAME=
SQUASHFS_COMP=lz4
PASSES_TO_LAYERS=true
add_package base linux-$KERNEL_FLAVOURS
add_package base.live casper
case $ARCH in
amd64) ;;
*) echo "ubuntu-test-iso only supports amd64"; exit 1 ;;
esac
;;
ubuntu-base|ubuntu-oci)
OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal"
;;
@ -1310,7 +1278,7 @@ case $SUBPROJECT in
# and a variety of things fail without it.
add_package install tzdata
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/make-lxd-metadata.py config/make-lxd-metadata
cp -af /usr/share/livecd-rootfs/live-build/make-lxd-metadata.py config/make-lxd-metadata
;;
esac
@ -1435,13 +1403,11 @@ echo "LB_CHROOT_HOOKS=\"$CHROOT_HOOKS\"" >> config/chroot
echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/chroot
echo "LB_DISTRIBUTION=\"$SUITE\"" >> config/chroot
echo "IMAGEFORMAT=\"$IMAGEFORMAT\"" >> config/chroot
echo "LIVECD_ROOTFS_ROOT=\"$LIVECD_ROOTFS_ROOT\"" >> config/common
if [ -n "$PASSES" ]; then
echo "PASSES=\"$PASSES\"" >> config/common
fi
echo "MAKE_ISO=\"$MAKE_ISO\"" >> config/common
echo "POOL_SEED_NAME=\"$POOL_SEED_NAME\"" >> config/common
echo "SQUASHFS_COMP=\"$SQUASHFS_COMP\"" >> config/common
if [ -n "$NO_SQUASHFS_PASSES" ]; then
echo "NO_SQUASHFS_PASSES=\"$NO_SQUASHFS_PASSES\"" >> config/common
fi
@ -1477,7 +1443,7 @@ rm -fv /etc/ssl/private/ssl-cert-snakeoil.key \
EOF
case $PROJECT in
ubuntu-cpc|ubuntu-core|ubuntu-base|ubuntu-oci|ubuntu-wsl|ubuntu-mini-iso|ubuntu-test-iso)
ubuntu-cpc|ubuntu-core|ubuntu-base|ubuntu-oci|ubuntu-wsl|ubuntu-mini-iso)
# ubuntu-cpc gets this added in 025-create-groups.chroot, and we do
# not want this group in projects that are effectively just chroots
;;
@ -1565,11 +1531,11 @@ fi
case $PROJECT:${SUBPROJECT:-} in
ubuntu-cpc:*|ubuntu-server:live|ubuntu:desktop-preinstalled| \
ubuntu-wsl:*|ubuntu-mini-iso:*|ubuntu-test-iso:*|ubuntu:|ubuntu:dangerous|ubuntu-oem:*| \
ubuntu-wsl:*|ubuntu-mini-iso:*|ubuntu:|ubuntu:dangerous|ubuntu-oem:*| \
ubuntustudio:*|edubuntu:*|ubuntu-budgie:*|ubuntucinnamon:*|xubuntu:*| \
ubuntukylin:*|ubuntu-mate:*|ubuntu-core-installer:*|lubuntu:*)
# Ensure that most things e.g. includes.chroot are copied as is
for entry in ${LIVECD_ROOTFS_ROOT}/live-build/${PROJECT}/*; do
for entry in /usr/share/livecd-rootfs/live-build/${PROJECT}/*; do
case $entry in
*hooks*)
# But hooks are shared across the projects with symlinks
@ -1604,11 +1570,11 @@ esac
case $PROJECT in
ubuntu-oem|ubuntustudio|edubuntu|ubuntu-budgie|ubuntucinnamon| \
xubuntu|ubuntukylin|ubuntu-mate|lubuntu)
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/ubuntu/includes.chroot \
cp -af /usr/share/livecd-rootfs/live-build/ubuntu/includes.chroot \
config/includes.chroot
LIVE_LAYER=${LIVE_PREFIX}live
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/ubuntu/includes.chroot.minimal.standard.live \
cp -af /usr/share/livecd-rootfs/live-build/ubuntu/includes.chroot.minimal.standard.live \
config/includes.chroot.$LIVE_LAYER
if [ $PROJECT != ubuntu-oem ]; then
@ -1624,7 +1590,7 @@ esac
case $SUBPROJECT in
buildd)
cp -af ${LIVECD_ROOTFS_ROOT}/live-build/buildd/* config/
cp -af /usr/share/livecd-rootfs/live-build/buildd/* config/
;;
esac
@ -1648,7 +1614,7 @@ if [ "$EXTRA_PPAS" ]; then
extra_ppa=${extra_ppa%:*}
;;
esac
extra_ppa_fingerprint="$(${LIVECD_ROOTFS_ROOT}/get-ppa-fingerprint "$extra_ppa")"
extra_ppa_fingerprint="$(/usr/share/livecd-rootfs/get-ppa-fingerprint "$extra_ppa")"
cat >> config/archives/extra-ppas.list.chroot <<EOF
deb https://ppa.launchpadcontent.net/$extra_ppa/ubuntu @DISTRIBUTION@ main
@ -1738,19 +1704,8 @@ fi
if [ "${MAKE_ISO}" = "yes" ]; then
# XXX should pass --build-type here.
${LIVECD_ROOTFS_ROOT}/live-build/gen-iso-ids \
/usr/share/livecd-rootfs/live-build/gen-iso-ids \
--project $PROJECT ${SUBPROJECT:+--subproject $SUBPROJECT} \
--arch $ARCH ${SUBARCH:+--subarch $SUBARCH} ${NOW+--serial $NOW} \
--output-dir config/iso-ids/
fi
if [ -n "$http_proxy" ]; then
mkdir -p /etc/systemd/system/snapd.service.d/
cat > /etc/systemd/system/snapd.service.d/snap_proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=${http_proxy}"
Environment="HTTPS_PROXY=${http_proxy}"
EOF
systemctl daemon-reload
systemctl restart snapd.service
fi

View File

@ -1,218 +0,0 @@
#!/usr/bin/python3
import configparser
import os
import pathlib
import platform
import subprocess
import click
_CONFIG_FILE = pathlib.Path.home() / ".config" / "livecd-rootfs" / "build-livefs.conf"
def _read_config() -> dict[str, str]:
"""Read default values from the user config file if it exists.
The config file uses INI format with a [defaults] section, e.g.:
[defaults]
http-proxy = http://squid.internal:3128/
mirror = http://ftpmaster.internal/ubuntu/
"""
cp = configparser.ConfigParser()
cp.read(_CONFIG_FILE)
return dict(cp["defaults"]) if "defaults" in cp else {}
_MACHINE_TO_ARCH = {
"x86_64": "amd64",
"aarch64": "arm64",
"ppc64le": "ppc64el",
"s390x": "s390x",
"riscv64": "riscv64",
"armv7l": "armhf",
}
def _default_arch():
machine = platform.machine()
try:
return _MACHINE_TO_ARCH[machine]
except KeyError:
raise click.UsageError(
f"Cannot determine default arch for machine {machine!r}; use --arch"
)
@click.command()
@click.option(
"--work-dir",
default=".",
type=click.Path(file_okay=False, path_type=pathlib.Path),
help="Working directory for the build (default: current directory)",
)
@click.option("--project", required=True, help="Project name (e.g. ubuntu, ubuntu-cpc)")
@click.option("--suite", required=True, help="Ubuntu suite/series (e.g. noble)")
@click.option("--arch", default=None, help="Target architecture (default: host arch)")
@click.option("--arch-variant", default=None, help="Architecture variant")
@click.option("--subproject", default=None, help="Subproject")
@click.option("--subarch", default=None, help="Sub-architecture")
@click.option("--channel", default=None, help="Channel")
@click.option(
"--image-target",
"image_targets",
multiple=True,
help="Image target (may be repeated)",
)
@click.option("--repo-snapshot-stamp", default=None, help="Repository snapshot stamp")
@click.option(
"--snapshot-service-timestamp", default=None, help="Snapshot service timestamp"
)
@click.option("--cohort-key", default=None, help="Cohort key")
@click.option("--datestamp", default=None, help="Datestamp (sets NOW)")
@click.option("--image-format", default=None, help="Image format (sets IMAGEFORMAT)")
@click.option(
"--proposed",
is_flag=True,
default=False,
help="Enable proposed pocket (sets PROPOSED=1)",
)
@click.option(
"--extra-ppa", "extra_ppas", multiple=True, help="Extra PPA (may be repeated)"
)
@click.option(
"--extra-snap", "extra_snaps", multiple=True, help="Extra snap (may be repeated)"
)
@click.option("--build-type", default=None, help="Build type")
@click.option(
"--http-proxy",
default=None,
help="HTTP proxy (sets http_proxy, HTTP_PROXY, LB_APT_HTTP_PROXY)",
)
@click.option(
"--mirror",
default=None,
help="Ubuntu archive mirror URL (sets MIRROR)",
)
@click.option(
"--debug", is_flag=True, default=False, help="Enable debug mode (set -x in lb scripts)"
)
def main(
work_dir,
project,
suite,
arch,
arch_variant,
subproject,
subarch,
channel,
image_targets,
repo_snapshot_stamp,
snapshot_service_timestamp,
cohort_key,
datestamp,
image_format,
proposed,
extra_ppas,
extra_snaps,
build_type,
http_proxy,
mirror,
debug,
):
cfg = _read_config()
if http_proxy is None:
http_proxy = cfg.get("http-proxy")
if mirror is None:
mirror = cfg.get("mirror")
if arch is None:
arch = _default_arch()
# Locate auto/ scripts relative to this script, following symlinks.
# Works for: git checkout, installed deb, and /usr/bin/build-livefs symlink.
live_build_dir = pathlib.Path(__file__).resolve().parent
auto_source = live_build_dir / "auto"
# base_env is passed to both lb config and lb build
base_env = {
"PROJECT": project,
"ARCH": arch,
"LIVECD_ROOTFS_ROOT": str(live_build_dir.parent),
}
if arch_variant is not None:
base_env["ARCH_VARIANT"] = arch_variant
if subproject is not None:
base_env["SUBPROJECT"] = subproject
if subarch is not None:
base_env["SUBARCH"] = subarch
if channel is not None:
base_env["CHANNEL"] = channel
if image_targets:
base_env["IMAGE_TARGETS"] = " ".join(image_targets)
if repo_snapshot_stamp is not None:
base_env["REPO_SNAPSHOT_STAMP"] = repo_snapshot_stamp
if snapshot_service_timestamp is not None:
base_env["SNAPSHOT_SERVICE_TIMESTAMP"] = snapshot_service_timestamp
if cohort_key is not None:
base_env["COHORT_KEY"] = cohort_key
if http_proxy is not None:
base_env["http_proxy"] = http_proxy
base_env["HTTP_PROXY"] = http_proxy
base_env["LB_APT_HTTP_PROXY"] = http_proxy
# config_env adds lb-config-only vars on top of base_env
config_env = {
**base_env,
"SUITE": suite,
}
if datestamp is not None:
config_env["NOW"] = datestamp
if image_format is not None:
config_env["IMAGEFORMAT"] = image_format
if proposed:
config_env["PROPOSED"] = "1"
if extra_ppas:
config_env["EXTRA_PPAS"] = " ".join(extra_ppas)
if extra_snaps:
config_env["EXTRA_SNAPS"] = " ".join(extra_snaps)
if build_type is not None:
config_env["BUILD_TYPE"] = build_type
if mirror is not None:
config_env["MIRROR"] = mirror
work_dir = work_dir.resolve()
work_dir.mkdir(parents=True, exist_ok=True)
# Create/replace auto/ symlinks
auto_dir = work_dir / "auto"
auto_dir.mkdir(exist_ok=True)
for script in ("config", "build", "clean"):
link = auto_dir / script
if link.is_symlink() or link.exists():
link.unlink()
link.symlink_to(auto_source / script)
# Write debug.sh if requested
if debug:
debug_dir = work_dir / "local" / "functions"
debug_dir.mkdir(parents=True, exist_ok=True)
(debug_dir / "debug.sh").write_text("set -x\n")
def run(cmd, env_extra):
env = os.environ.copy()
env.update(env_extra)
if os.getuid() != 0:
env_args = [f"{k}={v}" for k, v in env_extra.items()]
cmd = ["sudo", "env"] + env_args + cmd
subprocess.run(cmd, cwd=work_dir, env=env, check=True)
run(["lb", "clean", "--purge"], base_env)
run(["lb", "config"], config_env)
run(["lb", "build"], base_env)
if __name__ == "__main__":
main()

View File

@ -1,150 +0,0 @@
#!/usr/bin/env python3
import configparser
import pathlib
import subprocess
import time
import click
_CONFIG_FILE = pathlib.Path.home() / ".config" / "livecd-rootfs" / "build-livefs.conf"
def _read_config() -> dict[str, str]:
cp = configparser.ConfigParser()
cp.read(_CONFIG_FILE)
return dict(cp["defaults"]) if "defaults" in cp else {}
@click.command(
context_settings={"ignore_unknown_options": True, "allow_extra_args": True}
)
@click.option("--suite", required=True, help="Ubuntu suite/series (e.g. noble)")
@click.option(
"--vm-name",
default=None,
help="LXD VM name (default: livefs-builder-{suite})",
)
@click.option(
"--http-proxy",
default=None,
help="HTTP proxy URL for apt inside the VM (also read from build-livefs.conf)",
)
@click.argument("extra_args", nargs=-1, type=click.UNPROCESSED)
def main(suite, vm_name, http_proxy, extra_args):
livecd_rootfs_root = pathlib.Path(__file__).resolve().parent.parent
vm_name = vm_name or f"livefs-builder-{suite}"
host_conf = (
pathlib.Path.home() / ".config" / "livecd-rootfs" / "build-livefs.conf"
)
if http_proxy is None:
http_proxy = _read_config().get("http-proxy")
result = subprocess.run(["lxc", "info", vm_name], capture_output=True)
if result.returncode != 0:
launch_cmd = [
"lxc", "launch", f"ubuntu-daily:{suite}", vm_name, "--vm",
"--config", "limits.cpu=4",
"--config", "limits.memory=8GiB",
"--device", "root,size=100GiB",
]
user_data = "#cloud-config\npackage_update: true\n"
if http_proxy is not None:
user_data += (
"apt:\n"
f" http_proxy: {http_proxy}\n"
f" https_proxy: {http_proxy}\n"
)
launch_cmd += ["--config", f"user.user-data={user_data}"]
subprocess.run(launch_cmd, check=True)
device_info = subprocess.run(
["lxc", "config", "device", "show", vm_name],
capture_output=True,
text=True,
check=True,
).stdout
if "livecd-rootfs" not in device_info:
subprocess.run(
[
"lxc",
"config",
"device",
"add",
vm_name,
"livecd-rootfs",
"disk",
f"source={livecd_rootfs_root}",
"path=/srv/livecd-rootfs",
],
check=True,
)
info = subprocess.run(
["lxc", "info", vm_name], capture_output=True, text=True, check=True
).stdout
if "Status: STOPPED" in info:
subprocess.run(["lxc", "start", vm_name], check=True)
for _ in range(30):
result = subprocess.run(
["lxc", "exec", vm_name, "--", "true"], capture_output=True
)
if result.returncode == 0:
break
time.sleep(2)
else:
raise click.ClickException(f"VM {vm_name!r} did not become ready in time")
subprocess.run(
["lxc", "exec", vm_name, "--", "cloud-init", "status", "--wait"], check=True
)
subprocess.run(
["lxc", "exec", vm_name, "--", "apt-get", "install", "-y", "livecd-rootfs"],
check=True,
)
if host_conf.exists():
subprocess.run(
[
"lxc",
"exec",
vm_name,
"--",
"mkdir",
"-p",
"/root/.config/livecd-rootfs",
],
check=True,
)
subprocess.run(
[
"lxc",
"file",
"push",
str(host_conf),
f"{vm_name}/root/.config/livecd-rootfs/build-livefs.conf",
],
check=True,
)
subprocess.run(
[
"lxc",
"exec",
vm_name,
"--",
"/srv/livecd-rootfs/live-build/build-livefs",
"--suite",
suite,
*extra_args,
],
check=True,
)
if __name__ == "__main__":
main()

View File

@ -188,8 +188,8 @@ setup_mountpoint() {
mount sysfs-live -t sysfs "$mountpoint/sys"
mount securityfs -t securityfs "$mountpoint/sys/kernel/security"
# Provide more up to date apparmor features, matching target kernel
mount -o bind ${LIVECD_ROOTFS_ROOT}/live-build/apparmor/generic "$mountpoint/sys/kernel/security/apparmor/features/"
mount -o bind ${LIVECD_ROOTFS_ROOT}/live-build/seccomp/generic.actions_avail "$mountpoint/proc/sys/kernel/seccomp/actions_avail"
mount -o bind /usr/share/livecd-rootfs/live-build/apparmor/generic "$mountpoint/sys/kernel/security/apparmor/features/"
mount -o bind /usr/share/livecd-rootfs/live-build/seccomp/generic.actions_avail "$mountpoint/proc/sys/kernel/seccomp/actions_avail"
# cgroup2 mount for LP: 1944004
mount -t cgroup2 none "$mountpoint/sys/fs/cgroup"
mount -t tmpfs none "$mountpoint/tmp"
@ -408,7 +408,7 @@ create_squashfs() {
squashfs_file="$2"
config_dir="$PWD/config"
(cd $rootfs_dir &&
mksquashfs . $squashfs_file -no-progress -xattrs -comp "${SQUASHFS_COMP:-xz}" \
mksquashfs . $squashfs_file -no-progress -xattrs -comp xz \
-ef "$config_dir/squashfs-exclude-files")
}
@ -860,7 +860,7 @@ snap_validate_seed() {
fi
if [ ${boot_filename} != undefined ]; then # we have a known boot file so we can proceed with checking for features to mount
kern_major_min=$(readlink --canonicalize --no-newline ${CHROOT_ROOT}/boot/${boot_filename} | grep --extended-regexp --only-matching --max-count 1 '[0-9]+\.[0-9]+')
if [ -d ${LIVECD_ROOTFS_ROOT}/live-build/apparmor/${kern_major_min} ]; then
if [ -d /usr/share/livecd-rootfs/live-build/apparmor/${kern_major_min} ]; then
# if an Ubuntu version has different kernel apparmor features between LTS and HWE kernels
# a snap pre-seeding issue can occur, where the incorrect apparmor features are reported
# basic copy of a directory structure overriding the "generic" feature set
@ -868,7 +868,7 @@ snap_validate_seed() {
# Bind kernel apparmor directory to feature directory for snap preseeding
umount "${CHROOT_ROOT}/sys/kernel/security/apparmor/features/"
mount --bind ${LIVECD_ROOTFS_ROOT}/live-build/apparmor/${kern_major_min} "${CHROOT_ROOT}/sys/kernel/security/apparmor/features/"
mount --bind /usr/share/livecd-rootfs/live-build/apparmor/${kern_major_min} "${CHROOT_ROOT}/sys/kernel/security/apparmor/features/"
fi
fi
@ -894,7 +894,7 @@ snap_validate_seed() {
# mount generic apparmor feature again (cleanup)
if [ -d /build/config/hooks.d/extra/apparmor/${kern_major_min} ]; then
umount "${CHROOT_ROOT}/sys/kernel/security/apparmor/features/"
mount -o bind ${LIVECD_ROOTFS_ROOT}/live-build/apparmor/generic "${CHROOT_ROOT}/sys/kernel/security/apparmor/features/"
mount -o bind /usr/share/livecd-rootfs/live-build/apparmor/generic "${CHROOT_ROOT}/sys/kernel/security/apparmor/features/"
fi
}
@ -1254,7 +1254,7 @@ setup_cidata() {
local mountpoint=$(mktemp -d)
mkfs.vfat -F 32 -n CIDATA ${cidata_dev}
mount ${cidata_dev} ${mountpoint}
cp ${LIVECD_ROOTFS_ROOT}/live-build/cidata/* ${mountpoint}
cp /usr/share/livecd-rootfs/live-build/cidata/* ${mountpoint}
cat >>${mountpoint}/meta-data.sample <<END
#instance-id: iid-$(openssl rand -hex 8)
@ -1454,5 +1454,5 @@ gpt_root_partition_uuid() {
# is importable, and uses config/iso-dir as the standard working directory
# for ISO metadata and intermediate files.
isobuild () {
PYTHONPATH=${LIVECD_ROOTFS_ROOT}/live-build/ ${LIVECD_ROOTFS_ROOT}/live-build/isobuild --workdir config/iso-dir "$@"
PYTHONPATH=/usr/share/livecd-rootfs/live-build/ /usr/share/livecd-rootfs/live-build/isobuild --workdir config/iso-dir "$@"
}

View File

@ -42,7 +42,6 @@ project_to_capproject_map = {
"ubuntu-core-installer": "Ubuntu-Core-Installer",
"ubuntu-mate": "Ubuntu-MATE",
"ubuntu-mini-iso": "Ubuntu-Mini-ISO",
"ubuntu-test-iso": "Ubuntu-Test-ISO",
"ubuntu-oem": "Ubuntu OEM",
"ubuntu-server": "Ubuntu-Server",
"ubuntu-unity": "Ubuntu-Unity",

View File

@ -278,10 +278,11 @@ class ISOBuilder:
for path in artifact_dir.glob(f"{filename_prefix}*.{ext}"):
newname = path.name[len(filename_prefix) :]
link(path, newname)
for kernel_path in artifact_dir.glob(f"{filename_prefix}kernel*"):
suffix = kernel_path.name[len(filename_prefix) + len("kernel") :]
prefix = "hwe-" if suffix.endswith("-hwe") else ""
for suffix, prefix in (
("-generic", ""),
("-generic-hwe", "hwe-"),
):
if artifact_dir.joinpath(f"{filename_prefix}kernel{suffix}").exists():
link(
artifact_dir.joinpath(f"{filename_prefix}kernel{suffix}"),
f"{prefix}{kernel_name}",

View File

@ -180,7 +180,7 @@ build_layered_squashfs () {
# Operate on the upperdir directly, so that we are only
# modifying mtime on files that are actually changed in
# this layer. LP: #2107332
${LIVECD_ROOTFS_ROOT}/sync-mtime chroot "$overlay_dir"
/usr/share/livecd-rootfs/sync-mtime chroot "$overlay_dir"
fi
create_squashfs "${overlay_dir}" ${squashfs_f}
@ -206,7 +206,7 @@ build_layered_squashfs () {
if [ -f config/seeded-languages ]; then
usc_opts="$usc_opts --langs $(cat config/seeded-languages)"
fi
${LIVECD_ROOTFS_ROOT}/update-source-catalog source $usc_opts
/usr/share/livecd-rootfs/update-source-catalog source $usc_opts
else
echo "No catalog entry template for $pass"
fi
@ -227,7 +227,7 @@ done
if [ -n "$DEFAULT_KERNEL" -a -f livecd.${PROJECT_FULL}.install-sources.yaml ]; then
write_kernel_yaml "$DEFAULT_KERNEL" "$BRIDGE_KERNEL_REASONS"
${LIVECD_ROOTFS_ROOT}/update-source-catalog merge \
/usr/share/livecd-rootfs/update-source-catalog merge \
--output livecd.${PROJECT_FULL}.install-sources.yaml \
--template config/kernel.yaml
fi

View File

@ -237,7 +237,7 @@ create_chroot_pass () {
lb chroot_interactive ${*}
# Misc ubuntu cleanup and post-layer configuration
${LIVECD_ROOTFS_ROOT}/minimize-manual chroot
/usr/share/livecd-rootfs/minimize-manual chroot
clean_debian_chroot
Chroot chroot "dpkg-query -W" > chroot.packages.${pass}

View File

@ -11,7 +11,6 @@ case ${PASS:-} in
esac
. config/binary
. config/common
. config/functions
case ${SUBPROJECT} in
@ -57,4 +56,4 @@ PROJECT_FULL=$PROJECT${SUBARCH:+-$SUBARCH}
usc_opts="--output livecd.${PROJECT_FULL}.install-sources.yaml \
--template config/edge.catalog-in.yaml \
--size 0"
${LIVECD_ROOTFS_ROOT}/update-source-catalog source $usc_opts
/usr/share/livecd-rootfs/update-source-catalog source $usc_opts

View File

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

View File

@ -1,104 +0,0 @@
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
partition-number: 14
# 2. EFI System Partition
- name: efi
type: C12A7328-F81F-11D2-BA4B-00A0C93EC93B
filesystem: vfat
filesystem-label: UEFI
role: system-boot
size: 106M
partition-number: 15
# 3. Linux Extended Boot
- name: boot
type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
filesystem: ext4
filesystem-label: BOOT
role: system-data
size: 1G
partition-number: 13
# 4. Root Filesystem
- name: rootfs
type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
filesystem: ext4
filesystem-label: cloudimg-rootfs
role: system-data
size: 3G
partition-number: 1
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

@ -1,81 +0,0 @@
#!/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 "imagecraft build is currently not implemented for ARCH=${ARCH:-unset}."
exit 0
;;
esac
case ${SUBPROJECT} in
minimized)
;;
*)
echo "imagecraft build is currently not implemented for SUBPROJECT=${SUBPROJECT:-unset}."
exit 0
;;
esac
_src_d=$(dirname $(readlink -f ${0}))
snap install imagecraft --classic --channel latest/edge
cp -r "$_src_d"/imagecraft-configs/* .
CRAFT_BUILD_ENVIRONMENT=host imagecraft --verbosity debug pack
# We are using this function instead of mount_disk_image from functions
# because imagecraft doesn't currently support XBOOTLDR's GUID and
# mount_disk_image has an explicit check for the XBOOTLDR GUID
# TODO: Use mount_disk_image once imagecraft supports XBOOTLDR's GUID
mount_image_partitions() {
mount_image "${disk_image}" "$ROOT_PARTITION"
# Making sure that the loop device is ready
partprobe "${loop_device}"
udevadm settle
mount_partition "${rootfs_dev_mapper}" "$mountpoint"
mount "${loop_device}p13" "$mountpoint/boot"
mount "${loop_device}p15" "$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 for BIOS boot installed successfully."
}
unmount_image_partitions() {
umount "$mountpoint/boot/efi"
umount "$mountpoint/boot"
umount_partition "$mountpoint"
rmdir "$mountpoint"
}
disk_image="pc.img"
ROOT_PARTITION=1
mountpoint=$(mktemp -d)
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,4 +6,3 @@ depends qcow2
depends vmdk
depends vagrant
depends wsl
depends imagecraft-image

View File

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

View File

@ -1,8 +0,0 @@
#!/bin/sh
set -eu
mkdir -p "etc/initramfs-tools/conf.d"
cat > etc/initramfs-tools/conf.d/casperize.conf <<EOF
export CASPER_GENERATE_UUID=1
EOF

View File

@ -1,15 +0,0 @@
#!/bin/sh
# Copy kernel/initrd artifacts for isobuilder to consume.
# The MAKE_ISO flow in auto/build expects ${PREFIX}.kernel-* and
# ${PREFIX}.initrd-* files. With --linux-packages=none live-build won't
# create them, so we do it here (mirroring ubuntu-mini-iso's approach).
# This hook runs for every pass; exit early when the kernel isn't present.
set -eu
[ -e chroot/boot/vmlinuz ] || exit 0
[ -e chroot/boot/initrd.img ] || exit 0
PREFIX="livecd.${PROJECT}"
cp chroot/boot/vmlinuz "${PREFIX}.kernel-generic"
cp chroot/boot/initrd.img "${PREFIX}.initrd-generic"

View File

@ -7,12 +7,10 @@
set -e
. config/common
chroot_directory=$1
auto_packages=$(${LIVECD_ROOTFS_ROOT}/auto-markable-pkgs $chroot_directory)
auto_packages=$(/usr/share/livecd-rootfs/auto-markable-pkgs $chroot_directory)
if [ -n "$auto_packages" ]; then
chroot $chroot_directory apt-mark auto $auto_packages
fi
[ -z "$(${LIVECD_ROOTFS_ROOT}/auto-markable-pkgs $chroot_directory 2> /dev/null)" ]
[ -z "$(/usr/share/livecd-rootfs/auto-markable-pkgs $chroot_directory 2> /dev/null)" ]