diff --git a/live-build/auto/build b/live-build/auto/build index 2e4292ca..5e2eeef4 100755 --- a/live-build/auto/build +++ b/live-build/auto/build @@ -17,81 +17,23 @@ fi . config/functions -# New nf_tables-based versions of iptables don't work well on old kernels. -# We aren't sure exactly how old is a problem: 4.15 works, but with 4.4 new -# rules are added to all chains in the requested table rather than just one, -# and the new rules seem to have no useful effect. In such cases, -# iptables-legacy works better. -# -# We can simplify this once livecd-rootfs no longer needs to support running -# on Ubuntu 16.04 (that is, once Launchpad's build VMs are upgraded to -# Ubuntu 18.04). -run_iptables () { - local kver kver_major kver_minor - - kver="$(uname -r)" - kver="${kver%%-*}" - kver_major="${kver%%.*}" - kver="${kver#*.}" - kver_minor="${kver%%.*}" - - - # LP: #1917920 - # I'm seeing issues after iptables got upgraded from 1.8.5 to - # 1.8.7 Somehow installing our nat rule doesn't get activated, and - # no networking is happening at all. - - # But somehow calling both iptables -S makes things start working. - # Maybe no default chains are installed in our network namespace?! - # Or 1.8.7 is somehow broken? - iptables -v -t nat -S - iptables-legacy -v -t nat -S - - if [ "$kver_major" -lt 4 ] || \ - ([ "$kver_major" = 4 ] && [ "$kver_minor" -lt 15 ]); then - iptables-legacy "$@" - else - iptables "$@" - fi -} - -if [ -n "$REPO_SNAPSHOT_STAMP" ]; then - if [ "`whoami`" != "root" ]; then - echo "Magic repo snapshots only work when running as root." >&2 - exit 1 - fi - - apt-get -qyy install iptables - - # Redirect all outgoing traffic to port 80 to proxy instead. - run_iptables -v -t nat -A OUTPUT -p tcp --dport 80 \ - -m owner ! --uid-owner daemon -j REDIRECT --to 8080 - - # Run proxy as "daemon" to avoid infinite loop. - LB_PARENT_MIRROR_BOOTSTRAP=$LB_PARENT_MIRROR_BOOTSTRAP \ - /usr/share/livecd-rootfs/magic-proxy \ - --address="127.0.0.1" \ - --port=8080 \ - --run-as=daemon \ - --cutoff-time="$REPO_SNAPSHOT_STAMP" \ - --log-file=/build/livecd.magic-proxy.log \ - --pid-file=config/magic-proxy.pid \ - --background \ - --setsid - - # Quick check that magic proxy & iptables chains are working - timeout 3m apt-get update -fi - # Link output files somewhere launchpad-buildd will be able to find them. PREFIX="livecd.$PROJECT${SUBARCH:+-$SUBARCH}" if [ "${IMAGEFORMAT:-}" = "ubuntu-image" ]; then # Use ubuntu-image instead of live-build + export SNAPPY_STORE_NO_CDN=1 + LB_UBUNTU_IMAGE_CHANNEL="${LB_UBUNTU_IMAGE_CHANNEL:-candidate}" + snap install \ + --classic --channel="$LB_UBUNTU_IMAGE_CHANNEL" ubuntu-image + + # TODO: eventually, this should be handled by a single ubuntu-image + # call without having to do a conditional on ubuntu-core/classic. + # We could already do that, but then we'd still have to do the + # compressing for the core images. if [ "$PROJECT" = "ubuntu-core" ]; then - env SNAPPY_STORE_NO_CDN=1 \ - ubuntu-image snap $UBUNTU_IMAGE_ARGS \ + /snap/bin/ubuntu-image snap $UBUNTU_IMAGE_ARGS \ -O output "$PREFIX".model-assertion # XXX: currently we only have one image generated, but really # we should be supporting more than one for models that @@ -100,20 +42,23 @@ if [ "${IMAGEFORMAT:-}" = "ubuntu-image" ]; then xz -0 -T4 "$PREFIX".img mv output/seed.manifest "$PREFIX".manifest else - # First we need to build the gadget tree - make -C "config/$PREFIX-gadget" \ - ARCH=$ARCH SERIES=$SUITE $GADGET_TARGET - ubuntu-image classic $UBUNTU_IMAGE_ARGS \ - -s $SUITE -p $PROJECT -a $ARCH --subarch $SUBARCH \ - -O output config/$PREFIX-gadget/install - # XXX: currently we only have one image generated, but really - # we should be supporting more than one for models that - # define those. - mv output/*.img "$PREFIX".img - xz -0 -T4 "$PREFIX".img - # Also link the output image to a filename that cdimage expects - ln "$PREFIX".img.xz livecd.ubuntu-cpc.disk1.img.xz - mv output/filesystem.manifest "$PREFIX".manifest + /snap/bin/ubuntu-image classic --debug $UBUNTU_IMAGE_ARGS \ + -O output "$IMAGE_DEFINITION" + # Since the output of the ubuntu-image call can vary based on what + # kind of an image we build, the safest bet is to 'export' all the + # artifacts from the output directory. The image definition file + # should be what defines what is expected, so that we don't have + # to tweak livecd-rootfs everytime a different type of artifact + # is needed. + for artifact in output/*; do + # We want to be dynamic, and want to support even + # two-part extensions. + filename=$(basename $artifact) + noversion=$(echo $filename | sed 's/[0-9][0-9]\.[0-9][0-9]//') + extension=${noversion#*.} + mv $artifact "$PREFIX".$extension + done + [ -f $PREFIX.img ] && xz -0 -T4 "$PREFIX".img fi exit 0 @@ -154,15 +99,8 @@ Expire-Date: 0 lb bootstrap "$@" - case $PROJECT:${SUBPROJECT:-} in - ubuntu-server:*|ubuntu-cpc:*|ubuntu:desktop-preinstalled|ubuntu-wsl:*) - # Set locale to C.UTF-8 by default. We should - # probably do this for all images early in the - # 18.10 cycle but for now just do it for - # server and cpc products. - echo "LANG=C.UTF-8" > chroot/etc/default/locale - ;; - esac + # Set locale to C.UTF-8 by default. This may be overridden later. + echo "LANG=C.UTF-8" > chroot/etc/default/locale if [ "${SUBPROJECT:-}" = minimized ] \ && ! Chroot chroot dpkg -l tzdata 2>&1 |grep -q ^ii; then @@ -281,6 +219,24 @@ if dpkg-query --show --showformat='${db:Status-Status}\n' ubuntu-server 2> /dev/ DEBIAN_FRONTEND=noninteractive apt-get install -y landscape-common fi EOF + fi + + if [ "$PROJECT" = "ubuntu-cpc" ]; then + # we'd like to transform a minimized image to a base image + # when unminimize is run. + cat >> chroot/usr/local/sbin/unminimize <<'EOF' + +# even if ubuntu-server is installed, we should re-install it with --fix-policy --install-recommends +# to ensure all the Recommends of dependencies of ubuntu-server are installed, which aids in transforming +# this minimized image to an equivalent base image. +DEBIAN_FRONTEND=noninteractive apt-get --reinstall --fix-policy --install-recommends install -y ubuntu-server + +if dpkg-query --show --showformat='${db:Status-Status}\n' linux-image-virtual 2> /dev/null | grep -q '^installed$'; then + echo "Installing linux-virtual for installing the headers which were stripped in a minimized image" + DEBIAN_FRONTEND=noninteractive apt-get install -y linux-virtual +fi +EOF + fi if [ "$PROJECT" = "ubuntu-cpc" ] || [ "$PROJECT" = "ubuntu-server" ]; then cat >> chroot/usr/local/sbin/unminimize <<'EOF' @@ -329,6 +285,16 @@ EOF chmod +x chroot/usr/bin/man fi + if [ "${SUBPROJECT:-}" != minimized ] \ + && [ "${PROJECT}" != "ubuntu-server" ] + then + # debootstrap doesn't handle Recommends and fixing this is + # non-trivial, so install missing Recommends here + echo "Installing any missing recommends" + Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ + apt-get -y --fix-policy install" + fi + if [ -n "${PASSES}" ]; then PATH="config/:$PATH" lb chroot_layered "$@" else @@ -340,7 +306,7 @@ EOF fi if [ -d chroot/etc/apt/preferences.d.save ]; then - # https://twitter.com/infinite_scream + # https://mastodon.social/@scream@botsin.space mv chroot/etc/apt/preferences.d.save/* chroot/etc/apt/preferences.d/ rmdir chroot/etc/apt/preferences.d.save fi @@ -350,21 +316,24 @@ EOF # done in chroot hooks. if [ -z "$PASSES" ]; then if [ "${SUBPROJECT:-}" = minimized ]; then - # force removal of initramfs-tools, which we assert is not - # required for any minimized images but is still pulled in by - # default - # also remove landscape-common, which is heavyweight and - # in the server seed only to provide /etc/motd content which - # would only be seen by humans - Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ - apt-get -y purge initramfs-tools busybox-initramfs \ - landscape-common" - # and if initramfs-tools was configured before our kernel, - # /etc/kernel/postinst.d/initramfs-tools will have created - # an initramfs despite the generic dpkg-divert; so remove it - # here. - rm -f chroot/boot/initrd.img-* - + # ubuntu-cpc has moved to using ubuntu-cloud-minimal seed + # for minimized images, so don't need these purges anymore. + if [ "$PROJECT" != ubuntu-cpc ]; then + # force removal of initramfs-tools, which we assert is not + # required for any minimized images but is still pulled in by + # default + # also remove landscape-common, which is heavyweight and + # in the server seed only to provide /etc/motd content which + # would only be seen by humans + Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ + apt-get -y purge initramfs-tools busybox-initramfs \ + landscape-common" + # and if initramfs-tools was configured before our kernel, + # /etc/kernel/postinst.d/initramfs-tools will have created + # an initramfs despite the generic dpkg-divert; so remove it + # here. + rm -f chroot/boot/initrd.img-* + fi # temporary workaround: don't remove linux-base which # may have no other reverse-depends currently Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ @@ -397,7 +366,7 @@ EOF mkdir -p chroot/var/lib/preinstalled-pool/dists/$LB_DISTRIBUTION/$component/binary-$LB_ARCHITECTURES done apt-ftparchive generate config/indices/apt.conf - cat << @@EOF > chroot/etc/apt/sources.list.preinstall + cat << @@EOF > chroot/etc/apt/sources.list.d/preinstalled-pool.sources # This is a sources.list entry for a small pool of packages # provided on your preinstalled filesystem for your convenience. # @@ -405,12 +374,13 @@ EOF # it references, should you want to save disk space and fetch the # packages remotely instead. # -deb file:/var/lib/preinstalled-pool/ $LB_DISTRIBUTION $LB_PARENT_ARCHIVE_AREAS -# +Types: deb +URIs: file:/var/lib/preinstalled-pool/ +Suites: $LB_DISTRIBUTION +Components: $LB_PARENT_ARCHIVE_AREAS +Signed-By: /etc/apt/keyrings/preinstalled-pool.gpg @@EOF - cp chroot/etc/apt/sources.list chroot/etc/apt/sources.list.orig - cp chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list echo "Waiting on gnupg ("$GPG_PROCESS") to finish generating a key." wait $GPG_PROCESS @@ -434,13 +404,10 @@ deb file:/var/lib/preinstalled-pool/ $LB_DISTRIBUTION $LB_PARENT_ARCHIVE_AREAS chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/Release mv config/gnupg/Release.asc \ chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/Release.gpg - apt-key --keyring chroot/etc/apt/trusted.gpg add config/gnupg/pubring.gpg + cp config/gnupg/pubring.gpg chroot/etc/apt/keyrings/preinstalled-pool.gpg find chroot/var/lib/preinstalled-pool/ -name Packages | xargs rm - - Chroot chroot "apt-get update" - cat chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list.orig \ - > chroot/etc/apt/sources.list - rm chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list.orig + # We only want to have a cache for the pre-installed pool at this point + Chroot chroot "apt-get update -o Dir::Etc::SourceParts=/dev/null -oDir::Etc::SourceList=etc/apt/sources.list.d/preinstalled-pool.sources" fi case $PROJECT:$SUBPROJECT in *) @@ -463,9 +430,16 @@ serial: $BUILDSTAMP EOF fi - if [ "$PROJECT" = "ubuntu-oci" ]; then + if [ "${PROJECT}" = ubuntu-base ] || [ "${PROJECT}" = "ubuntu-oci" ]; then if [ -n "$BUILDSTAMP" ]; then - configure_oci chroot "$BUILDSTAMP" + mkdir -p chroot/etc/cloud + cat > chroot/etc/cloud/build.info << EOF +build_name: $PROJECT:${SUBPROJECT:-} +serial: $BUILDSTAMP +EOF + if [ "${PROJECT}" = "ubuntu-oci" ]; then + configure_oci chroot + fi else echo "The \$BUILDSTAMP variable is empty" exit 1 @@ -491,7 +465,7 @@ EOF # affected by this, we manually clear out the archive-related Packages # files in the cache. case $PROJECT in - ubuntu|xubuntu|kubuntu|ubuntu-budgie|ubuntukylin|ubuntu-mate) + ubuntu|xubuntu|kubuntu|ubuntu-budgie|ubuntukylin|ubuntu-mate|ubuntucinnamon|ubuntu-unity|edubuntu) rm -f chroot/var/lib/apt/lists/*ubuntu.com*_Packages ;; esac @@ -511,12 +485,6 @@ EOF if [ -e binary.success ]; then rm -f binary.success else - # Dump the magic-proxy log to stdout on failure to aid debugging - if [ -f /build/livecd.magic-proxy.log ] ; then - echo "================= Magic proxy log (start) =================" - cat /build/livecd.magic-proxy.log - echo "================== Magic proxy log (end) ==================" - fi exit 1 fi @@ -541,10 +509,13 @@ for OUTPUT in ext2 ext3 ext4 manifest manifest-remove size squashfs; do done # we don't need a manifest-remove for a layered-aware installer -if [ "$PROJECT" = "ubuntu" ] && [ "$SUBPROJECT" = "canary" ]; then - rm -f livecd.${PROJECT}-manifest-remove - rm -f config/manifest-minimal-remove -fi +# here we have a list of all new-installer flavors +case $PROJECT in + ubuntu|ubuntu-budgie) + rm -f livecd.${PROJECT}-manifest-remove + rm -f config/manifest-minimal-remove + ;; +esac if [ -e config/manifest-minimal-remove ]; then cp config/manifest-minimal-remove "$PREFIX.manifest-minimal-remove" @@ -570,6 +541,14 @@ if [ -e "binary/$INITFS/filesystem.packages" ]; then ln "binary/$INITFS/filesystem.packages" "$PREFIX.manifest" chmod 644 "$PREFIX.manifest" fi + +# If a .filelist is present, use it as the filelist for the image by +# symlinking with expected name and updating permissions +if [ -e "binary/$INITFS/filesystem.filelist" ]; then + ln "binary/$INITFS/filesystem.filelist" "$PREFIX.filelist" + chmod 644 "$PREFIX.filelist" +fi + if [ -e "binary/$INITFS/filesystem.packages-remove" ]; then # Not a typo, empty manifest-remove has a single LF in it. :/ if [ $(cat binary/$INITFS/filesystem.packages-remove | wc -c) -gt 1 ]; then @@ -593,12 +572,12 @@ for FLAVOUR in $LB_LINUX_FLAVOURS; do allwinner|virtual|generic-hwe-*) FLAVOUR="generic" ;; - lowlatency-hwe-*) - FLAVOUR="lowlatency" - ;; oem-*) FLAVOUR="oem" ;; + laptop-*) + FLAVOUR="laptop" + ;; image-intel) FLAVOUR="intel" ;; @@ -650,7 +629,7 @@ if [ "$NUMFLAVOURS" = 1 ] && [ "$LB_LINUX_FLAVOURS" != "none" ]; then fi case $SUBARCH in - raspi|raspi2) + raspi) # copy the kernel and initrd to a predictable directory for # ubuntu-image consumption. In some cases, like in pi2/3 # u-boot, the bootloader needs to contain the kernel and initrd, @@ -666,35 +645,6 @@ case $SUBARCH in ;; esac -# LTSP chroot building (only in 32bit and for Edubuntu (DVD)) -case $PROJECT in - edubuntu-dvd) - if [ "$ARCH" = i386 ]; then - echo "Building LTSP chroot" - ltsp-build-client --base $(pwd) --mirror $LB_PARENT_MIRROR_BOOTSTRAP --arch $ARCH --dist $LB_PARENT_DISTRIBUTION --chroot ltsp-live --late-packages ldm-edubuntu-theme,plymouth-theme-edubuntu --purge-chroot --skipimage - mkdir -p images - mksquashfs ltsp-live images/ltsp-live.img -e cdrom - rm -Rf ltsp-live - if [ -f images/ltsp-live.img ]; then - mv images/ltsp-live.img livecd.$PROJECT-ltsp.squashfs - chmod 0644 livecd.$PROJECT-ltsp.squashfs - rmdir --ignore-fail-on-non-empty images - else - echo "LTSP: Unable to build the chroot, see above for details." - fi - fi - ;; -esac - -if [ -f "config/magic-proxy.pid" ]; then - kill -TERM $(cat config/magic-proxy.pid) - rm -f config/magic-proxy.pid - - # Remove previously-inserted iptables rule. - run_iptables -t nat -D OUTPUT -p tcp --dport 80 \ - -m owner ! --uid-owner daemon -j REDIRECT --to 8080 -fi - case $PROJECT in ubuntu-cpc) config/hooks.d/remove-implicit-artifacts diff --git a/live-build/auto/config b/live-build/auto/config index 58990208..d42e0b09 100755 --- a/live-build/auto/config +++ b/live-build/auto/config @@ -1,23 +1,44 @@ #! /bin/sh set -e -rm -rf config +case $ARCH:$SUBARCH in + amd64:|amd64:generic|amd64:intel-iot|\ + arm64:|arm64:generic|arm64:raspi|arm64:snapdragon|\ + arm64:tegra|arm64:tegra-igx|arm64:x13s|arm64:largemem|\ + armhf:|\ + i386:|\ + ppc64el:|\ + riscv64:|riscv64:generic|riscv64:icicle|riscv64:licheerv|\ + riscv64:nezha|riscv64:unmatched|riscv64:visionfive|riscv64:visionfive2|\ + s390x:|\ + *appliance*) + ;; + *) + echo "Unknown architecture target $ARCH:$SUBARCH" + exit 1 + ;; +esac + +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)" -SEEDMIRROR=http://people.canonical.com/~ubuntu-archive/seeds/ +SEEDMIRROR=https://ubuntu-archive-team.ubuntu.com/seeds/ if [ -z "$MIRROR" ]; then case $(hostname --fqdn) in - *.ubuntu.com) MIRROR=http://ftpmaster.internal/ubuntu/ - SEEDMIRROR=http://archive-team.internal/seeds/ - ;; - *.buildd) MIRROR=http://ftpmaster.internal/ubuntu/ - SEEDMIRROR=http://archive-team.internal/seeds/ - ;; - *.ppa|*.scalingstack) MIRROR=http://ftpmaster.internal/ubuntu/ - SEEDMIRROR=http://archive-team.internal/seeds/ - ;; - *) case $ARCH in + *.ubuntu.com|*.buildd|*.ppa|*.scalingstack) + MIRROR=http://ftpmaster.internal/ubuntu/ + SEEDMIRROR=http://archive-team.internal/seeds/ + ;; + *) + case $ARCH in i386|amd64) MIRROR=http://archive.ubuntu.com/ubuntu/ ;; *) MIRROR=http://ports.ubuntu.com/ubuntu-ports/ ;; esac @@ -29,6 +50,7 @@ mkdir -p 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/expand-task config/expand-task cp -af /usr/share/livecd-rootfs/live-build/squashfs-exclude-files config/ mkdir -p config/package-lists @@ -85,62 +107,75 @@ _register_pass () { # $1 Name of the pass [ "$PASSES_TO_LAYERS" != "true" ] && return + case "$PASSES" in + *$1*) + # The pass is already registered in the list of layers. + # If PASSES_TO_LAYERS is true, then the above if statement's error + # code will be non-zero and a return statement with no argument + # will return the error code of the if statement, non-zero, thus + # exiting the script and build. This is not our intent. So we need + # to return 0 here. + return 0 + ;; + esac + + # live-build/ubuntu/hooks/020-ubuntu-live.chroot_early assumes the + # layer ending in '.live' is THE live layer to use, so ensure that + # we only define a single layer ending in '.live'. It principle it + # is not invalid to have multiple layers with .live in the name but + # we should not let this happen accidentally. + case "$PASSES $1" in + *.live\ *.live) + echo "ERROR: only one 'live' layer allowed" + exit 1 + ;; + *) + ;; + esac PASSES="$PASSES $1" } +add_pass () +{ + local pass="$1" + _check_immutable_passes_to_layers + _register_pass "$pass" +} + add_task () { local pass="$1" shift - local task - local snap_list_file - local snap_list_files - local curseed + local file pkg_file snap_file task _check_immutable_passes_to_layers _register_pass "$pass" - # The removal of direct task installation support from live-build - # poses some problems. If the chroot has multiarch configured - for - # example, if we're building for amd64 - then dumpavail will show - # foreign-architecture packages which will have their own Task - # lines, but which we don't want to install. (Compare - # PackageContainerInterface::FromTask in apt, which restricts task - # expansion to the native architecture.) We therefore restrict our - # search to stanzas with Architecture: $ARCH or all. - # - # However, even this may not be accurate enough. At the moment I - # have no idea what happens if an Architecture: all package has - # different Task fields on different architectures. This is - # probably a lurking timebomb that we need to fix. In the meantime, - # the Architecture restriction at least saves us from abject - # failure. - # - # We want as well to grab the snap list for each PASS. Resolve for all - # given task, and deduplicate them to generate snaps for the PASS. + if [ ! -e config/germinate-output/structure ]; then + echo "add_task too soon" >&2 + exit 1 + fi + + pkg_file="config/package-lists/livecd-rootfs.list.chroot_$pass" + + if [ $PASSES_TO_LAYERS = "true" ]; then + snap_file="config/package-lists/livecd-rootfs.snaplist.chroot_$pass.full" + else + snap_file="config/seeded-snaps" + fi for task; do - # We need a ridiculous number of backslashes to protect - # parentheses from eval. - echo "!chroot chroot apt-cache dumpavail | grep-dctrl -nsPackage \\\\\\( -XFArchitecture $ARCH -o -XFArchitecture all \\\\\\) -a -wFTask $task" >> "config/package-lists/livecd-rootfs.list.chroot_$pass" - - curseed=$(seed_from_task ${task}) - if [ -z "${curseed}" ]; then - echo "W: No seed matching task ${task}" - continue - fi - snap_list_file="config/package-lists/seed.${curseed}.snaplist.full" - snap_from_seed "${curseed}" $snap_list_file - if [ -e "$snap_list_file" ]; then - snap_list_files="${snap_list_files} $snap_list_file" + ./config/expand-task config/germinate-output $FLAVOUR $task packages >> "$pkg_file" + ./config/expand-task config/germinate-output $FLAVOUR $task snaps >> "$snap_file" + done + + for file in $pkg_file $snap_file; do + if [ -s $file ]; then + sort -u -o $file $file + else + rm -f $file fi done - # The snap list is one line, and could be duplicated between seeds via inheritance. - # Uniquely sort them and store them back in one line. - if [ -n "${snap_list_files}" ]; then - cat ${snap_list_files}|xargs -n1|sort -u > "config/package-lists/livecd-rootfs.snaplist.chroot_${pass}.full" - rm ${snap_list_files} - fi } add_package () @@ -193,8 +228,13 @@ add_snap () _check_immutable_passes_to_layers _register_pass "$pass" + local channel="" + if [ -n "$CHANNEL" ] ; then + channel="=$CHANNEL" + fi + for pkg; do - echo "$pkg" >> "config/package-lists/livecd-rootfs.snaplist.chroot_$pass.full" + echo "$pkg$channel" >> "config/package-lists/livecd-rootfs.snaplist.chroot_$pass.full" done } @@ -298,7 +338,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 @@ -326,8 +366,14 @@ _get_live_passes () if [ -z "${IMAGEFORMAT:-}" ]; then case $PROJECT:${SUBPROJECT:-} in ubuntu-cpc:*|ubuntu:desktop-preinstalled|ubuntu-wsl:*) - case $SUBARCH in - raspi|intel-iot) + case $ARCH+${SUBARCH:-} in + arm64+raspi|amd64+intel-iot) + # All raspi images use ubuntu-image. + IMAGEFORMAT=ubuntu-image + ;; + arm64+tegra|arm64+tegra-igx) + # Pre-installed Tegra images use + # ubuntu-image IMAGEFORMAT=ubuntu-image ;; *) @@ -335,7 +381,7 @@ if [ -z "${IMAGEFORMAT:-}" ]; then ;; esac ;; - ubuntu-server:live) + ubuntu-server:live|ubuntu-mini-iso:) IMAGEFORMAT=plain ;; esac @@ -345,10 +391,16 @@ fi # one also must request disk1-img-xz image format if [ "$IMAGEFORMAT" = "ext4" ] && [ "$PROJECT" = "ubuntu-cpc" ]; then case $ARCH:$SUBARCH in - armhf:raspi2|riscv64:sifive_*|riscv64:nezha|riscv64:visionfive|riscv64:licheerv|riscv64:icicle|*:generic) + riscv64:icicle | \ + riscv64:nezha | \ + riscv64:licheerv | \ + riscv64:unmatched | \ + riscv64:visionfive | \ + riscv64:visionfive2 | \ + *:generic) IMAGE_HAS_HARDCODED_PASSWORD=1 if [ -z "${IMAGE_TARGETS:-}" ]; then - export IMAGE_TARGETS="disk1-img-xz" + export IMAGE_TARGETS="disk-image-non-cloud" fi ;; esac @@ -370,6 +422,8 @@ case $IMAGEFORMAT in ubuntu-server:live) touch config/universe-enabled ;; + ubuntu-mini-iso:) + ;; *) PREINSTALLED=true ;; @@ -384,22 +438,16 @@ case $IMAGEFORMAT in MODEL=intel-iot ;; amd64+*) MODEL=pc-amd64 ;; - i386+*) - MODEL=pc-i386 ;; arm64+snapdragon) MODEL=dragonboard ;; - armhf+raspi) - MODEL=pi ;; - armhf+raspi2) - MODEL=pi2 ;; - armhf+raspi3) - MODEL=pi3 ;; arm64+raspi) MODEL=pi-arm64 ;; arm64+raspi3) MODEL=pi3-arm64 ;; - armhf+cm3) - MODEL=cm3 ;; + arm64+tegra) + MODEL=tegra ;; + arm64+tegra-igx) + MODEL=tegra-igx ;; arm64+*) MODEL=pc-arm64 ;; *) @@ -420,7 +468,7 @@ case $IMAGEFORMAT in CHANNEL="${CHANNEL:-edge}" case $MODEL in - pc-amd64|pc-i386|pc-arm64) + pc-amd64|pc-arm64) if [ -z "${SUBARCH:-}" ]; then # This is to make sure there's enough writable space UBUNTU_IMAGE_ARGS="$UBUNTU_IMAGE_ARGS --image-size 3700M" @@ -444,9 +492,6 @@ case $IMAGEFORMAT in else CORE_MAJOR=22 fi - if [ "${MODEL}" = "pi" ]; then - MODEL=pi-armhf - fi # Ubuntu Core 2x # Currently uc2x assertions do not support global # channel overrides, instead we have per-channel models @@ -493,42 +538,23 @@ case $IMAGEFORMAT in else # classic images - # Certain models have different names but are built from the same source gadget tree - BRANCH="classic" - case $MODEL in - pi|pi-arm64|pi3-arm64) - MODEL=pi - BRANCH="classic-22.04" - ;; - intel-iot) - MODEL=pc - ;; - esac - - GADGET_TARGET="server" - if [ "$SUBPROJECT" = "desktop-preinstalled" ]; then - GADGET_TARGET="desktop" - fi - - UBUNTU_IMAGE_ARGS="$UBUNTU_IMAGE_ARGS${SUBPROJECT:+ --subproject \"$SUBPROJECT\"}" - UBUNTU_IMAGE_ARGS="$UBUNTU_IMAGE_ARGS${PROPOSED:+ --with-proposed}" - UBUNTU_IMAGE_ARGS="$UBUNTU_IMAGE_ARGS${EXTRA_PPAS:+ --extra-ppas \"$EXTRA_PPAS\"}" - - # We need to look in two places for the gadget tree: - # - Launchpad hosted gadgets will be in the snap-gadget repo - # - Github hosted gadgets are mirrored into a github-mirror repo - git clone git://git.launchpad.net/~canonical-foundations/snap-$MODEL/+git/snap-$MODEL -b $BRANCH config/$PREFIX-gadget || git clone git://git.launchpad.net/~canonical-foundations/snap-$MODEL/+git/github-mirror -b $BRANCH config/$PREFIX-gadget || git clone git://git.launchpad.net/~canonical-foundations/snap-$MODEL/+git/github-mirror-$ARCH -b $BRANCH config/$PREFIX-gadget - - echo "IMAGEFORMAT=$IMAGEFORMAT" >> config/common - echo "SUITE=$SUITE" >> config/common - echo "GADGET_TARGET=$GADGET_TARGET" >> config/common - echo "UBUNTU_IMAGE_ARGS=\"$UBUNTU_IMAGE_ARGS\"" >> config/common - - echo "Configured ubuntu-image for the following gadget model: $MODEL" + IMAGE_PROJECT=$PROJECT + [ "$IMAGE_PROJECT" = "ubuntu-cpc" ] && IMAGE_PROJECT="ubuntu-server" + + LB_UBUNTU_IMAGES_REPO="${LB_UBUNTU_IMAGES_REPO:-git://git.launchpad.net/ubuntu-images}" + # LB_UBUNTU_IMAGES_BRANCH="${LB_UBUNTU_IMAGES_BRANCH:-$SUITE}" + LB_UBUNTU_IMAGES_BRANCH=intel-iot-test + git clone "$LB_UBUNTU_IMAGES_REPO" -b "$LB_UBUNTU_IMAGES_BRANCH" image-definitions + IMAGE_DEFINITION="image-definitions/$IMAGE_PROJECT-$MODEL.yaml" + echo "IMAGE_DEFINITION=$IMAGE_DEFINITION" >> config/common + echo "Configured ubuntu-image to use image definition file $IMAGE_DEFINITION which has the following contents:" + cat "$IMAGE_DEFINITION" + echo "----------------------------------------------------------" fi # Save the model name used for building, mostly for any model-specific hook execution echo "MODEL=$MODEL" >> config/common + echo "IMAGEFORMAT=$IMAGEFORMAT" >> config/common # Fake finished configuration for lb build mkdir -p .build touch .build/config @@ -543,14 +569,9 @@ case $IMAGEFORMAT in ;; *) case $PROJECT in - ubuntu-server) - ;; - ubuntu-wsl) - ;; - ubuntu) - if [ "$SUBPROJECT" != "canary" ]; then - add_package live casper - fi + ubuntu-server|ubuntu-wsl|ubuntu-oem|ubuntu|\ + ubuntu-budgie|ubuntustudio-dvd|edubuntu|ubuntucinnamon|xubuntu|\ + ubuntukylin|ubuntu-mate) ;; *) add_package live casper @@ -560,43 +581,8 @@ case $IMAGEFORMAT in esac if [ "$PREINSTALLED" = "true" ]; then - # Touch a random file that we can refer back to during build, - # cause that's wildly hackish + # LP Bug: 2044154 Enable universe on pre-installed images touch config/universe-enabled - case $PROJECT in - kubuntu*) - add_package live oem-config-kde ubiquity-frontend-kde - add_package live ubiquity-slideshow-kubuntu - ;; - lubuntu*) - add_package live oem-config-gtk ubiquity-frontend-gtk - add_package live ubiquity-slideshow-lubuntu - ;; - xubuntu*) - add_package live oem-config-gtk ubiquity-frontend-gtk - add_package live ubiquity-slideshow-xubuntu - ;; - ubuntu-mate) - add_package live oem-config-gtk ubiquity-frontend-gtk - add_package live ubiquity-slideshow-ubuntu-mate - ;; - ubuntu-server) - add_package live oem-config-debconf ubiquity-frontend-debconf - ;; - ubuntu-base|ubuntu-oci|ubuntu-cpc|ubuntu-wsl) - ;; - ubuntu) - add_package live oem-config-gtk ubiquity-frontend-gtk - add_package live ubiquity-slideshow-ubuntu - if [ "$SUBPROJECT" = "desktop-preinstalled" ]; then - add_package live language-pack-en-base oem-config-slideshow-ubuntu - fi - ;; - *) - add_package live oem-config-gtk ubiquity-frontend-gtk - add_package live ubiquity-slideshow-ubuntu - ;; - esac fi case $BINARYFORMAT in @@ -614,84 +600,72 @@ fi mkdir -p config/germinate-output case $PROJECT in - kubuntu-active*) - SEED=kubuntu-active.$SUITE + edubuntu*) + FLAVOUR=edubuntu ;; kubuntu*) - SEED=kubuntu.$SUITE + FLAVOUR=kubuntu ;; xubuntu*) - SEED=xubuntu.$SUITE + FLAVOUR=xubuntu ;; ubuntu-mate*) - SEED=ubuntu-mate.$SUITE + FLAVOUR=ubuntu-mate + ;; + ubuntu-unity*) + FLAVOUR=ubuntu-unity ;; lubuntu*) - SEED=lubuntu.$SUITE + FLAVOUR=lubuntu ;; ubuntu-budgie*) - SEED=ubuntu-budgie.$SUITE + FLAVOUR=ubuntu-budgie ;; ubuntukylin*) - SEED=ubuntukylin.$SUITE + FLAVOUR=ubuntukylin ;; ubuntustudio*) - SEED=ubuntustudio.$SUITE + FLAVOUR=ubuntustudio + ;; + ubuntucinnamon*) + FLAVOUR=ubuntucinnamon ;; *) - SEED=ubuntu.$SUITE + FLAVOUR=ubuntu ;; esac +case $PROJECT in + ubuntu-server|ubuntu-mini-iso) + COMPONENTS='main' + ;; + edubuntu|kubuntu|ubuntu-budgie|ubuntucinnamon|ubuntukylin) + COMPONENTS='main restricted universe' + ;; + lubuntu|ubuntu-mate|ubuntu-unity|ubuntustudio-dvd|xubuntu) + COMPONENTS='main restricted universe multiverse' + ;; +esac + +case $SUBPROJECT in + buildd) + COMPONENTS='main restricted universe multiverse' + ;; +esac + if ! [ -e config/germinate-output/structure ]; then echo "Running germinate..." + if [ -n "$COMPONENTS" ]; then + GERMINATE_ARG="-c $(echo $COMPONENTS | sed -e's/ \+/,/g')" + fi (cd config/germinate-output && germinate --no-rdepends --no-installer \ - -S $SEEDMIRROR -m $MIRROR -d $SUITE -s $SEED \ - ${COMPONENTS:+-c "$COMPONENTS"} -a $ARCH) + -S $SEEDMIRROR -m $MIRROR -d $SUITE,$SUITE-updates \ + -s $FLAVOUR.$SUITE $GERMINATE_ARG -a $ARCH) fi case $PROJECT in - ubuntu|ubuntu-dvd) - + ubuntu) case ${SUBPROJECT:-} in - canary) - touch config/universe-enabled - PASSES_TO_LAYERS="true" - KERNEL_FLAVOURS='generic-hwe-22.04' - add_task minimal minimal standard ubuntu-desktop-minimal ubuntu-desktop-minimal-default-languages - add_task minimal.standard ubuntu-desktop ubuntu-desktop-default-languages - add_task minimal.standard.live ubuntu-live - add_package minimal cloud-init - remove_package minimal.standard.live ubiquity-frontend-gtk - add_snap minimal.standard.live ubuntu-desktop-installer/classic - - seeded_langs="$(get_seeded_languages desktop-minimal desktop)" - echo "$seeded_langs" | tr ' ' ',' > config/seeded-languages - derive_language_layers minimal desktop-minimal desktop-minimal-default-languages "$seeded_langs" - derive_language_layers minimal.standard desktop desktop-default-languages "$seeded_langs" - cat <<-EOF > config/minimal.catalog-in.yaml - name: "Ubuntu Desktop (minimized)" - description: >- - A minimal but usable Ubuntu Desktop. - id: ubuntu-desktop-minimal - type: fsimage-layered - variant: desktop - locale_support: langpack - EOF - cat <<-EOF > config/minimal.standard.catalog-in.yaml - name: "Ubuntu Desktop" - description: >- - A full featured Ubuntu Desktop. - id: ubuntu-desktop - type: fsimage-layered - variant: desktop - locale_support: langpack - default: yes - EOF - /usr/share/livecd-rootfs/checkout-translations-branch \ - https://git.launchpad.net/subiquity po config/catalog-translations - ;; - desktop-preinstalled) add_task install minimal standard ubuntu-desktop case $SUBARCH in @@ -708,7 +682,6 @@ case $PROJECT in ;; intel-iot) KERNEL_FLAVOURS='intel-iotg' - COMPONENTS='main restricted' OPTS="${OPTS:+$OPTS }--initramfs=none" OPTS="${OPTS:+$OPTS }--system=normal" OPTS="${OPTS:+$OPTS }--hdd-label=cloudimg-rootfs" @@ -721,116 +694,358 @@ case $PROJECT in esac ;; *) - LIVE_TASK='ubuntu-live' - add_task install minimal standard ubuntu-desktop - add_task live ubuntu-desktop-minimal-default-languages ubuntu-desktop-default-languages + touch config/universe-enabled KERNEL_FLAVOURS='generic-hwe-22.04' - if [ "$SUBARCH" = "intel-iot" ]; then - KERNEL_FLAVOURS='intel-iotg' - COMPONENTS='main restricted' + if [ "$SUBARCH" = "x13s" ]; then + KERNEL_FLAVOURS='laptop-23.10' fi + PASSES_TO_LAYERS="true" + # the minimal layer, for minimal installs + add_task minimal minimal standard ubuntu-desktop-minimal ubuntu-desktop-minimal-default-languages + add_package minimal cloud-init + # the standard layer, contains all base common packages for later layers + add_task minimal.standard ubuntu-desktop ubuntu-desktop-default-languages + # the live layer, contains all packages for the live session installer + add_task minimal.standard.live ubuntu-live + add_package minimal.standard.live linux-$KERNEL_FLAVOURS casper + # language support + seeded_langs="$(get_seeded_languages desktop)" + echo "$seeded_langs" | tr ' ' ',' > config/seeded-languages + derive_language_layers minimal desktop-minimal desktop-minimal-default-languages "$seeded_langs" + derive_language_layers minimal.standard desktop desktop-default-languages "$seeded_langs" + + # Enchanced secureboot stuff + case "$ARCH" in + amd64) + # the enhanced-secureboot layer, contains all packages for the enhanced secureboot install + add_package minimal.enhanced-secureboot cryptsetup boot-managed-by-snapd + add_package minimal.standard.enhanced-secureboot cryptsetup boot-managed-by-snapd + derive_language_layers minimal.enhanced-secureboot desktop-minimal desktop-default-languages "$seeded_langs" + derive_language_layers minimal.standard.enhanced-secureboot desktop desktop-default-languages "$seeded_langs" + cat <<-EOF > config/minimal.enhanced-secureboot.catalog-in.yaml + id: ubuntu-desktop-minimal + variations: + minimal-enhanced-secureboot: + path: minimal.enhanced-secureboot.squashfs + snapd_system_label: enhanced-secureboot-desktop + EOF + cat <<-EOF > config/minimal.standard.enhanced-secureboot.catalog-in.yaml + id: ubuntu-desktop + variations: + enhanced-secureboot: + path: minimal.standard.enhanced-secureboot.squashfs + snapd_system_label: enhanced-secureboot-desktop + EOF + ;; + esac + + # now let's create the neccessary catalog files + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Ubuntu Desktop (minimized)" + description: >- + A minimal but usable Ubuntu Desktop. + id: ubuntu-desktop-minimal + type: fsimage-layered + default: yes + variant: desktop + locale_support: langpack + variations: + minimal: + path: minimal.squashfs + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Ubuntu Desktop" + description: >- + A full featured Ubuntu Desktop. + id: ubuntu-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + variations: + standard: + path: minimal.standard.squashfs + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; esac ;; - kubuntu|kubuntu-dvd) - add_task install minimal standard - add_task install kubuntu-desktop - LIVE_TASK='kubuntu-live' - COMPONENTS='main restricted universe' - add_chroot_hook remove-gnome-icon-cache + ubuntu-oem) + touch config/universe-enabled + PASSES_TO_LAYERS="true" + #KERNEL_FLAVOURS='oem-22.04' KERNEL_FLAVOURS='generic-hwe-22.04' + add_task minimal minimal standard ubuntu-desktop-minimal ubuntu-desktop-minimal-default-languages + add_package minimal cloud-init + add_task minimal.standard ubuntu-desktop ubuntu-desktop-default-languages + add_task minimal.standard.live ubuntu-live + remove_package minimal.standard.live ubiquity-frontend-gtk + add_snap minimal.standard.live ubuntu-desktop-bootstrap/classic + add_package minimal.standard.live linux-$KERNEL_FLAVOURS casper + + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Ubuntu Desktop for OEM (minimal)" + description: >- + Ubuntu Desktop (minimal) for OEM preinstallation. + id: ubuntu-desktop-oem-minimal + type: fsimage-layered + variant: desktop + locale_support: none + default: yes + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Ubuntu Desktop for OEM" + description: >- + Ubuntu Desktop for OEM preinstallation. + id: ubuntu-desktop-oem + type: fsimage-layered + variant: desktop + locale_support: none + EOF ;; - kubuntu-active) - add_task install minimal standard kubuntu-active - LIVE_TASK='kubuntu-active-live' - COMPONENTS='main restricted universe' - add_chroot_hook remove-gnome-icon-cache - ;; - - kubuntu-plasma5) + kubuntu) add_task install minimal standard - add_package install kubuntu-plasma5-desktop - # Technically cheating, but PPAs don't have tasks and the - # live seed doesn't have a corresponding metapackage. We'll - # get away with this as long as kubuntu-desktop and - # kubuntu-plasma5-desktop don't grow too far apart. + add_task install kubuntu-desktop LIVE_TASK='kubuntu-live' - COMPONENTS='main restricted universe' add_chroot_hook remove-gnome-icon-cache ;; - edubuntu|edubuntu-dvd) - add_task install minimal standard ubuntu-desktop edubuntu-desktop-gnome - LIVE_TASK='edubuntu-live' - COMPONENTS='main restricted universe' + edubuntu) + # Edubuntu now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" + KERNEL_FLAVOURS=generic + add_task minimal minimal standard edubuntu-desktop-gnome-minimal + add_task minimal.standard edubuntu-desktop-gnome + add_task minimal.standard.live edubuntu-live + add_package minimal.standard.live linux-$KERNEL_FLAVOURS casper + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Edubuntu Desktop (minimized)" + description: >- + A minimal installation of the Edubuntu Desktop. + id: edubuntu-desktop-minimal + type: fsimage-layered + variant: desktop + locale_support: langpack + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Edubuntu Desktop" + description: >- + A full featured Edubuntu Desktop. + id: edubuntu-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; - - xubuntu) - add_task install minimal standard xubuntu-desktop - add_package install xterm - LIVE_TASK='xubuntu-live' - COMPONENTS='main restricted universe multiverse' - case $ARCH in - amd64|i386) KERNEL_FLAVOURS='generic-hwe-22.04' ;; - esac + + ubuntucinnamon) + # Ubuntu Cinnamon now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" + KERNEL_FLAVOURS=generic + add_task minimal minimal standard ubuntucinnamon-desktop-minimal + add_task minimal.standard ubuntucinnamon-desktop + add_task minimal.standard.live ubuntucinnamon-live + add_package minimal.standard.live linux-$KERNEL_FLAVOURS + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Ubuntu Cinnamon Desktop (minimized)" + description: >- + A minimal installation of the Ubuntu Cinnamon Desktop. + id: ubuntucinnamon-desktop-minimal + type: fsimage-layered + variant: desktop + locale_support: langpack + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Ubuntu Cinnamon Desktop" + description: >- + A full featured Ubuntu Cinnamon Desktop. + id: ubuntucinnamon-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; - ubuntu-netbook) - add_task install minimal standard ubuntu-netbook - LIVE_TASK='netbook-live' + lubuntu|ubuntu-unity) + add_task install minimal standard ${PROJECT}-desktop + LIVE_TASK=${PROJECT}-live ;; - - mythbuntu) - add_task install minimal standard mythbuntu-desktop - LIVE_TASK='mythbuntu-live' - COMPONENTS='main restricted universe multiverse' + ubuntukylin) + # Ubuntu Kylin now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" + KERNEL_FLAVOURS=generic + add_task minimal minimal standard ubuntukylin-desktop-minimal + add_task minimal.standard ubuntukylin-desktop + add_task minimal.standard.live ubuntukylin-live + add_package minimal.standard.live linux-$KERNEL_FLAVOURS + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Ubuntu Kylin Desktop (minimized)" + description: >- + A minimal installation of the Ubuntu Kylin Desktop. + id: ubuntukylin-desktop-minimal + type: fsimage-layered + variant: desktop + locale_support: langpack + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Ubuntu Kylin Desktop" + description: >- + A full featured Ubuntu Kylin Desktop. + id: ubuntukylin-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; - lubuntu) - add_task install minimal standard lubuntu-desktop - LIVE_TASK='lubuntu-live' - COMPONENTS='main restricted universe multiverse' - case $ARCH in - amd64|i386) KERNEL_FLAVOURS='generic-hwe-22.04' ;; + xubuntu) + # Xubuntu now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" + KERNEL_FLAVOURS=generic + # the minimal layer, for minimal installs (minimal and desktop iso) + add_task minimal minimal standard xubuntu-minimal + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Xubuntu Minimal" + description: >- + A minimal installation of the Xubuntu Desktop. + id: xubuntu-minimal + type: fsimage-layered + variant: desktop + locale_support: langpack + EOF + case ${SUBPROJECT:-} in + minimal) + LIVE_LAYER_PARENT=minimal + ;; + *) + # the standard layer, for standard installs (desktop iso) + LIVE_LAYER_PARENT=minimal.standard + add_task minimal.standard xubuntu-desktop + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Xubuntu Desktop" + description: >- + A full featured Xubuntu Desktop. + id: xubuntu-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + ;; esac - ;; - - ubuntu-gnome) - add_task install minimal standard ubuntu-gnome-desktop - LIVE_TASK='ubuntu-gnome-live' - COMPONENTS='main restricted universe' + add_task ${LIVE_LAYER_PARENT}.live xubuntu-live + add_package ${LIVE_LAYER_PARENT}.live linux-$KERNEL_FLAVOURS + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; ubuntu-budgie) - add_task install minimal standard ubuntu-budgie-desktop - LIVE_TASK='ubuntu-budgie-live' - COMPONENTS='main restricted universe' + # By default Ubuntu Budgie now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" KERNEL_FLAVOURS='generic-hwe-22.04' + add_task minimal minimal standard ubuntu-budgie-desktop-minimal ubuntu-budgie-desktop-minimal-default-languages + add_task minimal.standard ubuntu-budgie-desktop ubuntu-budgie-desktop-default-languages + add_task minimal.standard.live ubuntu-budgie-live + add_package minimal cloud-init + remove_package minimal.standard.live ubiquity-frontend-gtk + add_snap minimal.standard.live ubuntu-budgie-installer/classic + add_package minimal.standard.live linux-$KERNEL_FLAVOURS casper + seeded_langs="$(get_seeded_languages budgie-desktop-minimal budgie-desktop)" + echo "$seeded_langs" | tr ' ' ',' > config/seeded-languages + derive_language_layers minimal budgie-desktop-minimal budgie-desktop-minimal-default-languages "$seeded_langs" + derive_language_layers minimal.standard budgie-desktop budgie-desktop-default-languages "$seeded_langs" + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Ubuntu Budgie Desktop (minimized)" + description: >- + A minimal but usable Ubuntu Budgie Desktop. + id: ubuntu-budgie-desktop-minimal + type: fsimage-layered + variant: desktop + locale_support: langpack + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Ubuntu Budgie Desktop" + description: >- + A full featured Ubuntu Budgie Desktop. + id: ubuntu-budgie-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; ubuntu-mate) - add_task install minimal standard ubuntu-mate-core ubuntu-mate-desktop - LIVE_TASK='ubuntu-mate-live' - COMPONENTS='main restricted universe multiverse' - KERNEL_FLAVOURS='generic-hwe-22.04' + # Ubuntu MATE now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" + KERNEL_FLAVOURS=generic + add_task minimal minimal standard ubuntu-mate-core + add_task minimal.standard ubuntu-mate-desktop + add_task minimal.standard.live ubuntu-mate-live + add_package minimal.standard.live linux-$KERNEL_FLAVOURS + cat <<-EOF > config/minimal.catalog-in.yaml + name: "Ubuntu MATE Desktop (minimized)" + description: >- + A minimal installation of the Ubuntu MATE Desktop. + id: ubuntu-mate-desktop-minimal + type: fsimage-layered + variant: desktop + locale_support: langpack + EOF + cat <<-EOF > config/minimal.standard.catalog-in.yaml + name: "Ubuntu MATE Desktop" + description: >- + A full featured Ubuntu MATE Desktop. + id: ubuntu-mate-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; ubuntustudio-dvd) - add_task install minimal standard ubuntustudio-desktop ubuntustudio-audio ubuntustudio-graphics ubuntustudio-video ubuntustudio-photography - COMPONENTS='main restricted universe multiverse' - case $ARCH in - amd64|i386) KERNEL_FLAVOURS='lowlatency-hwe-22.04' ;; - esac - ;; - - ubuntukylin) - add_task install minimal standard ubuntukylin-desktop - add_package install ubuntukylin-default-settings - LIVE_TASK='ubuntukylin-live' - COMPONENTS='main restricted universe' - KERNEL_FLAVOURS='generic-hwe-22.04' + # By default Ubuntu Studio now ships the new installer. + touch config/universe-enabled + PASSES_TO_LAYERS="true" + KERNEL_FLAVOURS=lowlatency + LIVE_LAYER_PARENT=standard + add_task standard minimal standard ubuntustudio-desktop ubuntustudio-audio ubuntustudio-graphics ubuntustudio-video ubuntustudio-photography + add_task standard.live ubuntustudio-dvd-live + add_package standard.live linux-$KERNEL_FLAVOURS + cat <<-EOF > config/standard.catalog-in.yaml + name: "Ubuntu Studio Desktop" + description: >- + A full featured Ubuntu Studio Desktop. + id: ubuntustudio-desktop + type: fsimage-layered + variant: desktop + locale_support: langpack + default: yes + EOF + /usr/share/livecd-rootfs/checkout-translations-branch \ + https://git.launchpad.net/subiquity po config/catalog-translations ;; ubuntu-server) @@ -841,37 +1056,31 @@ case $PROJECT in add_task ubuntu-server-minimal server-minimal add_package ubuntu-server-minimal lxd-installer add_task ubuntu-server-minimal.ubuntu-server minimal standard server - # add_task really should do this itself but for now... - snap_from_seed server config/package-lists/livecd-rootfs.snaplist.chroot_ubuntu-server-minimal.ubuntu-server.full add_package ubuntu-server-minimal.ubuntu-server cloud-init - add_package ubuntu-server-minimal.ubuntu-server.installer linux-firmware casper openssh-server - add_snap ubuntu-server-minimal.ubuntu-server.installer subiquity/classic - if [ $ARCH = s390x ]; then - add_package ubuntu-server-minimal.ubuntu-server.installer s390-tools-zkey - fi + add_task ubuntu-server-minimal.ubuntu-server.installer server-live # Live server ISOs for LTS point releases past .2 offer both # the GA and HWE kernels (in separate layers) so this code is # written generically to support both even though a lot of the # time only one kernel is offered. - - case "$ARCH+${SUBARCH:-}" in - amd64+intel-iot) + case ${SUBARCH:-} in + intel-iot) variants='intel' ;; - arm64+tegra) + tegra) variants='tegra' ;; - riscv64*) - # However, for RISC-V we only offer one kernel - variants='ga' + tegra-igx) + variants='tegra-igx' ;; - arm64+largemem) - variants='ga-64k hwe-64k' + largemem) + # variants='ga-64k hwe-64k' + variants='ga-64k' ;; *) - variants='ga hwe' + # variants='ga hwe' + variants='ga' ;; esac @@ -894,6 +1103,9 @@ case $PROJECT in elif [ "$variant" = "tegra" ]; then kernel_metapkg=linux-nvidia-tegra flavor=nvidia-tegra + elif [ "$variant" = "tegra-igx" ]; then + kernel_metapkg=linux-nvidia-tegra-igx + flavor=nvidia-tegra-igx else echo "bogus variant: $variant" exit 1 @@ -902,6 +1114,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.$flavor.netboot grub-pc shim-signed pxelinux + ;; + arm64) + add_package ubuntu-server-minimal.ubuntu-server.installer.$flavor.netboot shim-signed + ;; + *) + add_package ubuntu-server-minimal.ubuntu-server.installer.$flavor.netboot + ;; + esac + NO_SQUASHFS_PASSES=ubuntu-server-minimal.ubuntu-server.installer.$flavor.netboot /usr/share/livecd-rootfs/checkout-translations-branch \ https://git.launchpad.net/subiquity po config/catalog-translations @@ -911,20 +1135,34 @@ case $PROJECT in exit 1 ;; esac - COMPONENTS='main' PREINSTALL_POOL_SEEDS='server-ship' ;; - ubuntu-base) + ubuntu-mini-iso) OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal" + + OPTS="${OPTS:+$OPTS }--linux-packages=none --initramfs=none" + KERNEL_FLAVOURS=none + BINARY_REMOVE_LINUX=false + + add_package install mini-iso-tools linux-generic + case $ARCH in + amd64) + add_package install cd-boot-images-amd64 + ;; + *) + echo "unexpected architecture for $PROJECT: '$ARCH'" + exit 1 + ;; + esac ;; - ubuntu-oci) + ubuntu-base|ubuntu-oci) OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal" ;; ubuntu-wsl) - add_task install minimal standard ubuntu-wsl + add_task install minimal ubuntu-wsl OPTS="${OPTS:+$OPTS }--linux-packages=none --initramfs=none" KERNEL_FLAVOURS=none BINARY_REMOVE_LINUX=false @@ -934,8 +1172,13 @@ case $PROJECT in KERNEL_FLAVOURS=virtual if [ "${SUBPROJECT:-}" = minimized ]; then - add_task install cloud-image - add_package install sudo lxd-installer + # For minimized images we do not want to install any recommended packages. + # We can do this by setting APT::Install-Recommends to false in apt config + # or by passing --no-install-recommends to apt-get install. + # Apt config is set using `APT_OPTIONS` variable in this script. + # This fixes LP: #2031640 + APT_OPTIONS="${APT_OPTIONS:+$APT_OPTIONS }--no-install-recommends" + add_package install ubuntu-cloud-minimal else add_task install minimal standard cloud-image add_package install ubuntu-minimal @@ -949,15 +1192,10 @@ case $PROJECT in BINARY_REMOVE_LINUX=false OPTS="${OPTS:+$OPTS }--initramfs=none" case "$ARCH+${SUBARCH:-}" in - *+raspi) + arm64+raspi) add_task install ubuntu-server-raspi ;; - armhf*) - KERNEL_FLAVOURS=generic-lpae - add_package install flash-kernel - ;; arm64*) - add_package install flash-kernel if [ "${SUBARCH:-}" = "generic" ]; then KERNEL_FLAVOURS=generic fi @@ -967,7 +1205,6 @@ case $PROJECT in KERNEL_FLAVOURS=generic elif [ "${SUBARCH:-}" = "intel-iot" ]; then KERNEL_FLAVOURS=intel-iotg - COMPONENTS='main restricted' OPTS="${OPTS:+$OPTS }--initramfs=none" fi ;; @@ -1002,7 +1239,6 @@ esac case $SUBPROJECT in buildd) OPTS="${OPTS:+$OPTS }--archive-areas main" - COMPONENTS='main restricted universe multiverse' OPTS="${OPTS:+$OPTS }--apt-recommends false" OPTS="${OPTS:+$OPTS }--apt-secure false" OPTS="${OPTS:+$OPTS }--parent-mirror-binary ${MIRROR}" @@ -1023,6 +1259,9 @@ case $SUBPROJECT in add_package install build-essential # Needed for LXD-based builds. add_package install init + # Needed for bootable buildd systems which don't get injected + # nameserver configuration. (LP: 2007419) + add_package install systemd-resolved # Not strictly build-essential, but traditionally present # and a variety of things fail without it. add_package install tzdata @@ -1031,49 +1270,30 @@ case $SUBPROJECT in ;; esac -# we'll expand the base seed given here according to the STRUCTURE file, and -# then look in all of the seeds found to see which snaps are seeded -case $PROJECT:${SUBPROJECT:-} in - ubuntu:*|kubuntu*:*|lubuntu*:*|xubuntu*:*|ubuntu-mate*:*|ubuntustudio*:*|ubuntukylin*:*|ubuntu-budgie*:*) - BASE_SEED='desktop' - ;; - ubuntu-wsl:*) - BASE_SEED='wsl' - ;; - ubuntu-cpc:*) - BASE_SEED='server' - ;; - ubuntu-server:live) - BASE_SEED='server' - ;; -esac - -if [ "$PASSES_TO_LAYERS" != "true" ] && [ -n "${BASE_SEED}" ]; then - snap_from_seed "${BASE_SEED}" config/seeded-snaps -fi if [ "$PROJECT:${SUBPROJECT:-}" = ubuntu-cpc:minimized ]; then - # We install a lxc script that installs the snap when invoked. We don't - # want any other snaps to come in without due consideration, so fail the - # build if we see such a snap. - for snap in `cat config/seeded-snaps`; do - case $snap in - lxd | lxd=*) - ;; - *) - echo "Unexpected seeded snap for ubuntu-cpc:minimized build: $snap" - exit 1 - ;; - esac - done + # We install a lxc script that installs the snap when invoked and + # don't want any other snaps. + if [ -s config/seeded-snaps ]; then + echo "Unexpected seeded snaps for ubuntu-cpc:minimized build:" + cat config/seeded-snaps + exit 1 + fi - # Truncate but don't delete to a) prevent any snaps from being seeded, - # while at the same time b) triggering initialization of assertions. + # Create an empty file to trigger initialization of assertions. truncate --size 0 config/seeded-snaps fi # grab a list of packags to remove for a "minimal" installation from the seed # mirror for this project -if [ -n "${BASE_SEED}" ] && [ -n "${BASE_SEED}" ]; then +case $PROJECT in + kubuntu|ubuntu-mate|ubuntu-unity|ubuntukylin) + # only used now for the 'minimal-remove' functionality, + # which is not used at all in layered images + BASE_SEED='desktop' + ;; +esac + +if [ -n "${BASE_SEED}" ]; then minimal_packages_url=${SEEDMIRROR}/${SEED}/${BASE_SEED}.minimal-remove echo -n "Checking ${minimal_packages_url} for a minimal installation list... " minimal_packages_remove=$(wget -q -O- ${minimal_packages_url} | sed -e '/\s*#.*$/d' -e '/^\s*$/d') @@ -1091,35 +1311,28 @@ if [ "$PREINSTALLED" != "true" ] && [ "$PASSES_TO_LAYERS" != "true" ] && [ "$LIV add_task live "$LIVE_TASK" fi -case $PROJECT in - ubuntu-dvd) - add_task install ubuntu-usb - add_task live ubuntu-usb-live - ;; - - *-dvd) - add_task live "$PROJECT-live" - ;; -esac - case "$ARCH${SUBARCH:++$SUBARCH}" in - arm*+raspi) + arm64+raspi) # Common configuration for all Raspberry Pi image variants (server, # desktop etc.) KERNEL_FLAVOURS="$SUBARCH" - COMPONENTS='main restricted universe multiverse' # Most Pi-specific package installation is handled via the seeds in the # per-project/subproject cases above - add_package install linux-firmware-raspi2 pi-bluetooth u-boot-rpi u-boot-tools + add_package install linux-firmware-raspi pi-bluetooth u-boot-rpi u-boot-tools BINARY_REMOVE_LINUX=false ;; - arm64+tegra) - # Common configuration for all NVIDIA Tegra image variants (server, - # desktop etc.) + arm64+tegra|arm64+tegra-igx) + # Common configuration for all NVIDIA Tegra image variants + # (server, desktop etc.) KERNEL_FLAVOURS="nvidia-$SUBARCH" - COMPONENTS='main restricted universe multiverse' ;; riscv*+*) + if [ "${SUBARCH:-}" = "licheerv" ]; then + # The wifi driver of the licheerv is an out-of-tree driver packaged + # in universe for now, so to ease its installation for those without + # network, install its dependencies. + add_package install dkms + fi # We'll add wpasupplicant to the seeds when we work on RISC-V seeds. add_package install wpasupplicant ;; @@ -1145,15 +1358,6 @@ case $PROJECT in _) add_chroot_hook remove-python-py ;; - amd64) - KERNEL_FLAVOURS="${SUBARCH:-$KERNEL_FLAVOURS}" - case $SUBARCH in - intel-iot) - COMPONENTS='main restricted' - KERNEL_FLAVOURS='intel-iotg' - ;; - esac - ;; esac lb config noauto \ @@ -1203,6 +1407,7 @@ echo "LB_BINARY_HOOKS=\"$BINARY_HOOKS\"" >> config/binary echo "BUILDSTAMP=\"$NOW\"" >> config/binary echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/binary echo "LB_DISTRIBUTION=\"$SUITE\"" >> config/binary +echo "CHANNEL=\"${CHANNEL:-}\"" >> config/binary if [ "${IMAGE_HAS_HARDCODED_PASSWORD:-}" = "1" ]; then echo IMAGE_HAS_HARDCODED_PASSWORD=1 >> config/binary @@ -1211,8 +1416,20 @@ if [ "${IMAGE_HAS_HARDCODED_PASSWORD:-}" = "1" ]; then fi fi +# apply this hook unconditionally to remove files from the chroot that +# are supposed to be install-specific secrets and therefore must never +# be shipped in any image. +# this hook should be extended if we discover any more files that are +# supposed to be private but aren't. +cat > config/hooks/100-too-many-secrets.chroot < config/hooks/01-firmware-directory.chroot_early < config/hooks/999-raspi2-fixes.chroot < config/hooks/999-raspi-fixes.chroot <> /etc/fstab << EOM LABEL=system-boot /boot/firmware vfat defaults 0 1 -EOM - -cat > /boot/firmware/cmdline.txt << EOM -net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait -EOM - -cat > /boot/firmware/config.txt << EOM -# For more options and information see -# http://www.raspberrypi.org/documentation/configuration/config-txt.md -# Some settings may impact device functionality. See link above for details - -kernel=uboot.bin -device_tree_address=0x02000000 - -# enable i2c -dtparam=i2c_arm=on -dtparam=spi=on - -# uncomment if you get no picture on HDMI for a default "safe" mode -#hdmi_safe=1 - -# uncomment this if your display has a black border of unused pixels visible -# and your display can output without overscan -#disable_overscan=1 - -# uncomment the following to adjust overscan. Use positive numbers if console -# goes off screen, and negative if there is too much border -#overscan_left=16 -#overscan_right=16 -#overscan_top=16 -#overscan_bottom=16 - -# uncomment to force a console size. By default it will be display's size minus -# overscan. -#framebuffer_width=1280 -#framebuffer_height=720 - -# uncomment if hdmi display is not detected and composite is being output -#hdmi_force_hotplug=1 - -# uncomment to force a specific HDMI mode (this will force VGA) -#hdmi_group=1 -#hdmi_mode=1 - -# uncomment to force a HDMI mode rather than DVI. This can make audio work in -# DMT (computer monitor) modes -#hdmi_drive=2 - -# uncomment to increase signal to HDMI, if you have interference, blanking, or -# no display -#config_hdmi_boost=4 - -# uncomment for composite PAL -#sdtv_mode=2 - -#uncomment to overclock the arm. 700 MHz is the default. -#arm_freq=800 - EOM EOF ;; @@ -1306,13 +1465,6 @@ EOF ;; esac -if [ $PROJECT = ubuntu-server ] && [ "${SUBPROJECT:-}" != live ]; then - cat > config/hooks/100-remove-fstab.chroot < config/hooks/100-preserve-apt-prefs.chroot <<\EOF #! /bin/sh -ex @@ -1338,18 +1490,6 @@ exit 0 EOF fi -if [ "$PROJECT" = "ubuntustudio-dvd" ]; then - cat > config/hooks/100-ubuntustudio-dkms.chroot < config/binary_rootfs/excludes << EOF boot/vmlinu?-* @@ -1365,6 +1505,14 @@ deb $LB_PARENT_MIRROR_BINARY_VOLATILE $SUITE-proposed $LB_PARENT_ARCHIVE_AREAS EOF cp -a config/archives/proposed.list.chroot \ config/archives/proposed.list.binary + + mkdir -p config/chroot_apt/ + cat > config/chroot_apt/proposed.pref < "${target_filelist}" + (cd "${chroot_root}" && find -xdev) | sort > "${target_filelist}" fi echo "create_manifest finished" } @@ -60,6 +62,7 @@ mount_image() { trap clean_loops EXIT backing_img="$1" local rootpart="$2" + loop_device=$(losetup --show -f -P -v ${backing_img}) if [ ! -b ${loop_device} ]; then @@ -98,15 +101,27 @@ use_lp_archives_in_sourceslist(){ # recover_sourceslist mountpoint="${1}" - MOUNTPOINT_BACKUP_SOURCES_LIST="sources.list.tmp" . config/bootstrap # For the LB_MIRROR_* variables - cp -a "${mountpoint}/etc/apt/sources.list" "${MOUNTPOINT_BACKUP_SOURCES_LIST}" - sed -i "s#http://archive.ubuntu.com/ubuntu#${LB_PARENT_MIRROR_CHROOT}#g" \ - "${mountpoint}/etc/apt/sources.list" - sed -i "s#http://security.ubuntu.com/ubuntu#${LB_PARENT_MIRROR_CHROOT}#g" \ - "${mountpoint}/etc/apt/sources.list" - - sha256sum "${mountpoint}/etc/apt/sources.list" > sources.list.sha + if [ -e "${mountpoint}/etc/apt/sources.list.d/ubuntu.sources" ]; then + MOUNTPOINT_BACKUP_UBUNTU_SOURCES="ubuntu.sources.tmp" + cp -a "${mountpoint}/etc/apt/sources.list.d/ubuntu.sources" "${MOUNTPOINT_BACKUP_UBUNTU_SOURCES}" + sed -i "s#http://archive.ubuntu.com/ubuntu#${LB_PARENT_MIRROR_CHROOT}#g" \ + "${mountpoint}/etc/apt/sources.list.d/ubuntu.sources" + sed -i "s#http://security.ubuntu.com/ubuntu#${LB_PARENT_MIRROR_CHROOT}#g" \ + "${mountpoint}/etc/apt/sources.list.d/ubuntu.sources" + + sha256sum "${mountpoint}/etc/apt/sources.list.d/ubuntu.sources" > ubuntu.sources.sha + fi + if [ -e "${mountpoint}/etc/apt/sources.list" ]; then + MOUNTPOINT_BACKUP_SOURCES_LIST="sources.list.tmp" + cp -a "${mountpoint}/etc/apt/sources.list" "${MOUNTPOINT_BACKUP_SOURCES_LIST}" + sed -i "s#http://archive.ubuntu.com/ubuntu#${LB_PARENT_MIRROR_CHROOT}#g" \ + "${mountpoint}/etc/apt/sources.list" + sed -i "s#http://security.ubuntu.com/ubuntu#${LB_PARENT_MIRROR_CHROOT}#g" \ + "${mountpoint}/etc/apt/sources.list" + + sha256sum "${mountpoint}/etc/apt/sources.list" > sources.list.sha + fi } recover_sourceslist(){ @@ -118,10 +133,18 @@ recover_sourceslist(){ # sources.list.sha mountpoint="${1}" - sha256sum --check sources.list.sha + if [ -e "${MOUNTPOINT_BACKUP_UBUNTU_SOURCES:-/doesnotexist}" ]; then + sha256sum --check ubuntu.sources.sha - mv "${MOUNTPOINT_BACKUP_SOURCES_LIST}" "${mountpoint}/etc/apt/sources.list" - unset MOUNTPOINT_BACKUP_SOURCES_LIST + mv "${MOUNTPOINT_BACKUP_UBUNTU_SOURCES}" "${mountpoint}/etc/apt/sources.list.d/ubuntu.sources" + unset MOUNTPOINT_BACKUP_UBUNTU_SOURCES + fi + if [ -e "${MOUNTPOINT_BACKUP_SOURCES_LIST:-/doesnotexist}" ]; then + sha256sum --check sources.list.sha + + mv "${MOUNTPOINT_BACKUP_SOURCES_LIST}" "${mountpoint}/etc/apt/sources.list" + unset MOUNTPOINT_BACKUP_SOURCES_LIST + fi } setup_mountpoint() { @@ -132,7 +155,8 @@ setup_mountpoint() { chown root:kmem /dev/mem fi - mount --rbind /dev "$mountpoint/dev" + mount dev-live -t devtmpfs "$mountpoint/dev" + mount devpts-live -t devpts -o nodev,nosuid "$mountpoint/dev/pts" mount proc-live -t proc "$mountpoint/proc" mount sysfs-live -t sysfs "$mountpoint/sys" mount securityfs -t securityfs "$mountpoint/sys/kernel/security" @@ -209,18 +233,24 @@ get_lowerdirs_for_pass () { mount_disk_image() { local disk_image=${1} local mountpoint=${2} - mount_image ${disk_image} 1 + local rootpart=${3:-1} + mount_image ${disk_image} "${rootpart}" mount_partition "${rootfs_dev_mapper}" $mountpoint - local uefi_dev="${loop_device}p15" + local boot_dev="${loop_device}p16" if flock -x ${loop_device} \ - [ -b ${uefi_dev} -a -e $mountpoint/boot/efi ]; then - flock -x ${loop_device} mount "${uefi_dev}" $mountpoint/boot/efi + [ -b ${boot_dev} -a -e $mountpoint/boot ]; then + flock -x ${loop_device} mount "${boot_dev}" $mountpoint/boot fi # Having one partition mounted should avoid udev-triggered partition # rescans on that device, so we no longer need to flock. + local uefi_dev="${loop_device}p15" + if [ -b ${uefi_dev} -a -e $mountpoint/boot/efi ]; then + mount "${uefi_dev}" $mountpoint/boot/efi + fi + # This is needed to allow for certain operations # such as updating grub and installing software cat > $mountpoint/usr/sbin/policy-rc.d << EOF @@ -375,7 +405,7 @@ create_derivative() { convert_to_qcow2() { src="$1" destination="$2" - qemu-img convert -c -O qcow2 -o compat=0.10 "$src" "$destination" + qemu-img convert -c -O qcow2 "$src" "$destination" qemu-img info "$destination" } @@ -717,6 +747,12 @@ snap_preseed() { SNAP=${SNAP%=*} # strip /classic confinement local SNAP_NAME=${SNAP%/*} + + # For snap preseed to work, we need to ensure that fuse3 is installed in the chroot. + # fuse3 is a recommends of snapd but if this is a minimized image then recommends are not installed + # and preseeding will fail. + chroot "${CHROOT_ROOT}" apt-get install --assume-yes --no-install-recommends fuse3 + # Seed from the specified channel (e.g. core18 latest/stable) # Or Channel endcoded in the snap name (e.g. lxd=4.0/stable/ubuntu-20.04) # Or Ubuntu policy default channel latest/stable/ubuntu-$(release_ver) @@ -805,56 +841,6 @@ snap_validate_seed() { } -snap_from_seed() { - local base_seed=$1 - local out=$2 - local all_snaps - local seeds_expanded - - seeds_expanded=$(inheritance ${base_seed}) - for seed in ${seeds_expanded}; do - echo "snap: considering ${seed}" - file=config/germinate-output/${seed}.snaps - [ -e "${file}" ] || continue - # extract the first column (snap package name) from germinate's output - # translate the human-readable "foo (classic)" into a - # more machine readable "foo/classic" - seed_snaps=$(sed -rn '1,/-----/d;/-----/,$d; s/(.*) \|.*/\1/; s, \(classic\),/classic,; p' "${file}") - for snap in ${seed_snaps}; do - echo "snap: found ${snap}" - all_snaps="${all_snaps:+${all_snaps} }${snap}" - done - done - if [ -n "${all_snaps}" ]; then - echo "${all_snaps}" > $out - fi -} - -seed_from_task () -{ - # Retrieve the name of the seed from a task name - local task=$1 - local seed - local seedfile - local seedfiles - - seedfile="$(grep -lE "^Task-Key: +${task}\$" config/germinate-output/*seedtext|head -1)" - if [ -n "$seedfile" ]; then - basename $seedfile .seedtext - return - fi - - seedfiles="$(grep -lE "^Task-Per-Derivative: *1\$" config/germinate-output/*seedtext)" - if [ -n "$seedfiles" ]; then - for seed in $(echo $seedfiles | xargs basename -s .seedtext); do - if [ ${PROJECT}-${seed} = $task ]; then - echo ${seed} - return - fi - done - fi -} - list_packages_from_seed () { # Store all packages for a given seed, including its seed dependency # $1: Name of the seed to expand to a package list @@ -906,48 +892,58 @@ configure_universe() { # debian-installer's apt-setup: cat > chroot/etc/apt/sources.list << EOF +# Ubuntu sources have moved to the /etc/apt/sources.list.d/ubuntu.sources +# file, which uses the deb822 format. Use deb822-formatted .sources files +# to manage package sources in the /etc/apt/sources.list.d/ directory. +# See the sources.list(5) manual page for details. +EOF + + cat > chroot/etc/apt/sources.list.d/ubuntu.sources << EOF # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to # newer versions of the distribution. -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION main restricted -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION main restricted - -## Major bug fix updates produced after the final release of the -## distribution. -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates main restricted -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates main restricted - -## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu -## team. Also, please note that software in universe WILL NOT receive any -## review or updates from the Ubuntu security team. -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION universe -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION universe -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates universe -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates universe - -## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu -## team, and may not be under a free licence. Please satisfy yourself as to -## your rights to use the software. Also, please note that software in -## multiverse WILL NOT receive any review or updates from the Ubuntu -## security team. -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION multiverse -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION multiverse -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates multiverse -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates multiverse - -## N.B. software from this repository may not have been tested as -## extensively as that contained in the main release, although it includes -## newer versions of some applications which may provide useful features. -## Also, please note that software in backports WILL NOT receive any review -## or updates from the Ubuntu security team. -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-backports main restricted universe multiverse -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-backports main restricted universe multiverse - -deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security main restricted -# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security main restricted -deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security universe -# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security universe -deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security multiverse -# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security multiverse + +## Ubuntu distribution repository +## +## The following settings can be adjusted to configure which packages to use from Ubuntu. +## Mirror your choices (except for URIs and Suites) in the security section below to +## ensure timely security updates. +## +## Types: Append deb-src to enable the fetching of source package. +## URIs: A URL to the repository (you may add multiple URLs) +## Suites: The following additional suites can be configured +## -updates - Major bug fix updates produced after the final release of the +## distribution. +## -backports - software from this repository may not have been tested as +## extensively as that contained in the main release, although it includes +## newer versions of some applications which may provide useful features. +## Also, please note that software in backports WILL NOT receive any review +## or updates from the Ubuntu security team. +## Components: Aside from main, the following components can be added to the list +## restricted - Software that may not be under a free license, or protected by patents. +## universe - Community maintained packages. +## Software from this repository is only maintained and supported by Canonical +## for machines with Ubuntu Pro subscriptions. Without Ubuntu Pro, the Ubuntu +## community provides best-effort security maintenance. +## multiverse - Community maintained of restricted. Software from this repository is +## ENTIRELY UNSUPPORTED by the Ubuntu team, and may not be under a free +## licence. Please satisfy yourself as to your rights to use the software. +## Also, please note that software in multiverse WILL NOT receive any +## review or updates from the Ubuntu security team. +## +## See the sources.list(5) manual page for further settings. +Types: deb +URIs: $LB_PARENT_MIRROR_BINARY +Suites: $LB_DISTRIBUTION $LB_DISTRIBUTION-updates $LB_DISTRIBUTION-backports +Components: main universe restricted multiverse +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg + +## Ubuntu security updates. Aside from URIs and Suites, +## this should mirror your choices in the previous section. +Types: deb +URIs: $LB_PARENT_MIRROR_BINARY_SECURITY +Suites: $LB_DISTRIBUTION-security +Components: main universe restricted multiverse +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg EOF fi @@ -959,7 +955,6 @@ configure_oci() { # at https://github.com/tianon/docker-brew-ubuntu-core/blob/master/update.sh local chroot=$1 - local serial=$2 if [ ! -d "${chroot}" ]; then echo "The chroot does not exist" @@ -974,13 +969,6 @@ configure_oci() { Chroot ${chroot} "chmod +x /usr/sbin/policy-rc.d" - # Inject a build stamp into the image - mkdir -p ${chroot}/etc/cloud - cat > ${chroot}/etc/cloud/build.info << EOF -serial: $serial -EOF - - # https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56 Chroot ${chroot} "dpkg-divert --local --rename --add /sbin/initctl" cp -a ${chroot}/usr/sbin/policy-rc.d ${chroot}/sbin/initctl @@ -1022,7 +1010,10 @@ EOF mkdir -p ${chroot}/run/systemd echo 'docker' > ${chroot}/run/systemd/container + # Create Ubuntu user + Chroot ${chroot} useradd ubuntu -U -u 1000 --comment Ubuntu --groups adm,audio,cdrom,dialout,dip,floppy,plugdev,sudo,video --shell /bin/bash -m rm -rf ${chroot}/var/cache/apt/*.bin + echo "==== Configuring OCI done ====" } @@ -1031,7 +1022,7 @@ configure_network_manager() { # default. Installing NM on an existing system only manages wifi and wwan via # /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf. When setting # the global backend to NM, netplan overrides that file. - if [ -e chroot/usr/sbin/NetworkManager -a ! -f chroot/etc/netplan/01-network-manager-all.yaml ]; then + if [ -e chroot/usr/sbin/NetworkManager -a ! -f chroot/etc/netplan/01-network-manager-all.yaml -a "$SUBPROJECT" != "desktop-preinstalled" ]; then echo "===== Enabling all devices in NetworkManager ====" mkdir -p chroot/etc/netplan cat < chroot/etc/netplan/01-network-manager-all.yaml @@ -1040,6 +1031,74 @@ network: version: 2 renderer: NetworkManager EOF + # Do not limit cloud-init renderers to network-manager as suggested + # in LP: #1982855 because subiquity needs to render full networking + # in ephemeral boot time when autoinstall.network is provided. + # Neither subiquity nor netplan is aware of /etc/NetworkManager config + # artifacts emmitted by cloud-init. It's best if cloud-init reports + # network config directly to /etc/netplan with the configured netplan + # backend: NetworkManager per 01-network-manager-all.yaml above. + + # cloud-init's default renderer discovery will prefer netplan. + # Any time subiquity needs to write and apply network config + # it disables all previous network config in /etc/netplan so + # any previous 50-cloud-init.yaml will be rendered inert. + + # Position cloud-init.service After=NetworkManager.service. + # (LP: #2008952). + # We override the entire cloud-init.service definition because + # systemd drop-in files only allow adding Before/After constraints + # yet we are dropping the Before=sysinit.target from the upstream + # cloud-init.service. + # This override can be dropped when NetworkManager.service can run + # Before=sysinit.target when it drops strict dbus.service dependency. + cat < chroot/lib/systemd/system/cloud-init.service +${AUTOMATION_HEADER} +# Based on cloud-init 23.1 for Desktop LiveCD +[Unit] +Description=Initial cloud-init job (metadata service crawler) +DefaultDependencies=no +Wants=cloud-init-local.service +Wants=sshd-keygen.service +Wants=sshd.service +After=cloud-init-local.service +After=systemd-networkd-wait-online.service +# Installer Added After=NetworkManager* ordering +After=NetworkManager.service +After=NetworkManager-wait-online.service +After=networking.service +Before=network-online.target +Before=sshd-keygen.service +Before=sshd.service +# Before=sysinit.target Installer removed to allow for NM dependency +Before=shutdown.target +Conflicts=shutdown.target +Before=systemd-user-sessions.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/cloud-init init +RemainAfterExit=yes +TimeoutSec=0 + +# Output needs to appear in instance console output +StandardOutput=journal+console + +[Install] +WantedBy=cloud-init.target +EOF + + # Allow cloud-init clean to inform of strict network-manager config + mkdir -p chroot/etc/cloud/clean.d + cat < chroot/etc/cloud/clean.d/99-installer-use-networkmanager +#!/bin/sh +# Inform clone image creators about strict network-manager cfg for cloud-init +if [ -f /etc/cloud/cloud.cfg.d/99-installer-use-networkmanager.cfg ]; then + echo "WARNING: cloud-init network config is limited to using network-manager." + echo "If this is undesirable: rm /etc/cloud/cloud.cfg.d/99-installer-use-networkmanager.cfg" +fi +EOF + chmod +x chroot/etc/cloud/clean.d/99-installer-use-networkmanager else echo "==== NetworkManager not installed ====" fi @@ -1125,7 +1184,7 @@ END } setup_cinocloud() { - if [ "${IMAGE_HAS_HARDCODED_PASSWORD:-}" != "1" ] || [ "${IMAGE_TARGETS:-}" != "disk1-img-xz" ]; then + if [ "${IMAGE_HAS_HARDCODED_PASSWORD:-}" != "1" ] || ( [ "${IMAGE_TARGETS:-}" != "disk1-img-xz" ] && [ "${IMAGE_TARGETS:-}" != "disk-image-non-cloud" ] ); then echo "unexpected attempt to add a hardcoded password to an image" exit 1 fi @@ -1223,3 +1282,15 @@ EOF undivert_grub "${mountpoint}" fi } + +# find all files under /var/lib/snapd in the target directory that aren't +# shipped by the snapd package itself, and remove them +reset_snapd_state() { + rootdir="$1" + + /usr/lib/snapd/snap-preseed --reset $(realpath "$rootdir") || true + rm -rf "$rootdir/var/lib/snapd" + setup_mountpoint "$rootdir" + chroot "$rootdir" apt-get install --reinstall -y snapd + teardown_mountpoint "$rootdir" +}