mirror of
				https://git.launchpad.net/livecd-rootfs
				synced 2025-10-26 14:34:06 +00:00 
			
		
		
		
	Debian changelog.Debian.* files are already keept for minimized builds. But those changelogs are from non-native .deb packages (see man dh_installchangelogs). Native .deb packages name their changelog just changelog.* . So keep them in a minimized build, too. LP: #1943114
		
			
				
	
	
		
			673 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			673 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #! /bin/sh
 | |
| set -e
 | |
| 
 | |
| export LC_ALL=C
 | |
| 
 | |
| ( . "${LIVE_BUILD}/scripts/build.sh" > /dev/null 2>&1 || true ) || . /usr/lib/live/build.sh
 | |
| 
 | |
| Arguments "${@}"
 | |
| 
 | |
| Read_conffiles config/all config/common config/bootstrap config/chroot config/binary config/source
 | |
| Set_defaults
 | |
| 
 | |
| if [ -z "${PROJECT:-}" ]; then
 | |
|     echo "PROJECT environment variable has to be set" >&2
 | |
|     exit 1
 | |
| 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
 | |
| 
 | |
| 	if [ "$PROJECT" = "ubuntu-core" ]; then
 | |
| 		env SNAPPY_STORE_NO_CDN=1 \
 | |
| 		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
 | |
| 		#  define those.
 | |
| 		mv output/*.img "$PREFIX".img
 | |
| 		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
 | |
| 		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
 | |
| 	fi
 | |
| 
 | |
| 	exit 0
 | |
| fi
 | |
| 
 | |
| # Setup cleanup function
 | |
| Setup_cleanup
 | |
| 
 | |
| preinstall_snaps() {
 | |
| 	setup_mountpoint chroot
 | |
| 
 | |
| 	snap_prepare chroot
 | |
| 
 | |
| 	for snap in "$@"; do
 | |
| 		SNAP_NO_VALIDATE_SEED=1 snap_preseed chroot "${snap}"
 | |
| 	done
 | |
| 
 | |
| 	snap_validate_seed chroot
 | |
| 
 | |
| 	teardown_mountpoint chroot
 | |
| }
 | |
| 
 | |
| rm -f binary.success
 | |
| (
 | |
| 	if [ -d config/gnupg ]; then
 | |
| 		cat << @@EOF > config/gnupg/NEWKEY
 | |
| Key-Type: DSA
 | |
| Key-Length: 1024
 | |
| Key-Usage: sign
 | |
| Name-Real: Ubuntu Local Archive One-Time Signing Key
 | |
| Name-Email: cdimage@ubuntu.com
 | |
| Expire-Date: 0
 | |
| @@EOF
 | |
| 		gpg --home config/gnupg --gen-key --batch < config/gnupg/NEWKEY \
 | |
| 			> config/gnupg/generate.log 2>&1 &
 | |
| 		GPG_PROCESS=$!
 | |
| 	fi
 | |
| 
 | |
| 	lb bootstrap "$@"
 | |
| 
 | |
|         case $PROJECT:${SUBPROJECT:-} in
 | |
| 		ubuntu-server:*|ubuntu-cpc:*|ubuntu:desktop-preinstalled)
 | |
| 			# 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
 | |
| 
 | |
| 	if [ "${SUBPROJECT:-}" = minimized ] \
 | |
| 	   && ! Chroot chroot dpkg -l tzdata 2>&1 |grep -q ^ii; then
 | |
| 		# workaround for tzdata purge not removing these files
 | |
| 		rm -f chroot/etc/localtime chroot/etc/timezone
 | |
| 	fi
 | |
| 
 | |
| 	if [ "${SUBPROJECT:-}" = minimized ] || [ "${PROJECT}" = "ubuntu-server" ]; then
 | |
| 		# ubuntu-server has a minimized base layer so needs
 | |
| 		# minimizations applied to the chroot
 | |
| 
 | |
| 		# set up dpkg filters to skip installing docs on minimized system
 | |
| 		mkdir -p chroot/etc/dpkg/dpkg.cfg.d
 | |
| 		cat > chroot/etc/dpkg/dpkg.cfg.d/excludes <<EOF
 | |
| # Drop all man pages
 | |
| path-exclude=/usr/share/man/*
 | |
| 
 | |
| # Drop all translations
 | |
| path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo
 | |
| 
 | |
| # Drop all documentation ...
 | |
| path-exclude=/usr/share/doc/*
 | |
| 
 | |
| # ... except copyright files ...
 | |
| path-include=/usr/share/doc/*/copyright
 | |
| 
 | |
| # ... and Debian changelogs for native & non-native packages
 | |
| path-include=/usr/share/doc/*/changelog.*
 | |
| EOF
 | |
| 
 | |
| 		# Remove docs installed by bootstrap
 | |
| 		Chroot chroot dpkg-query -f '${binary:Package}\n' -W | Chroot chroot xargs -L1 apt-get install --reinstall
 | |
| 
 | |
|                 # Add unminimizer script which restores default image behavior
 | |
|                 mkdir -p chroot/usr/local/sbin
 | |
|                 cat > chroot/usr/local/sbin/unminimize <<'EOF'
 | |
| #!/bin/sh
 | |
| 
 | |
| set -e
 | |
| 
 | |
| echo "This system has been minimized by removing packages and content that are"
 | |
| echo "not required on a system that users do not log into."
 | |
| echo ""
 | |
| echo "This script restores content and packages that are found on a default"
 | |
| echo "Ubuntu server system in order to make this system more suitable for"
 | |
| echo "interactive use."
 | |
| echo ""
 | |
| echo "Reinstallation of packages may fail due to changes to the system"
 | |
| echo "configuration, the presence of third-party packages, or for other"
 | |
| echo "reasons."
 | |
| echo ""
 | |
| echo "This operation may take some time."
 | |
| echo ""
 | |
| read -p "Would you like to continue? [y/N] " REPLY
 | |
| echo    # (optional) move to a new line
 | |
| if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]
 | |
| then
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| if [ -f /etc/dpkg/dpkg.cfg.d/excludes ] || [ -f /etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp ]; then
 | |
|     echo "Re-enabling installation of all documentation in dpkg..."
 | |
|     if [ -f /etc/dpkg/dpkg.cfg.d/excludes ]; then
 | |
|         mv /etc/dpkg/dpkg.cfg.d/excludes /etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp
 | |
|     fi
 | |
|     echo "Updating package list and upgrading packages..."
 | |
|     apt-get update
 | |
|     # apt-get upgrade asks for confirmation before upgrading packages to let the user stop here
 | |
|     apt-get upgrade
 | |
|     echo "Restoring system documentation..."
 | |
|     echo "Reinstalling packages with files in /usr/share/man/ ..."
 | |
|     # Reinstallation takes place in two steps because a single dpkg --verified
 | |
|     # command generates very long parameter list for "xargs dpkg -S" and may go
 | |
|     # over ARG_MAX. Since many packages have man pages the second download
 | |
|     # handles a much smaller amount of packages.
 | |
|     dpkg -S /usr/share/man/ |sed 's|, |\n|g;s|: [^:]*$||' | DEBIAN_FRONTEND=noninteractive xargs apt-get install --reinstall -y
 | |
|     echo "Reinstalling packages with system documentation in /usr/share/doc/ .."
 | |
|     # This step processes the packages which still have missing documentation
 | |
|     dpkg --verify --verify-format rpm | awk '/..5......   \/usr\/share\/doc/ {print $2}' | sed 's|/[^/]*$||' | sort |uniq \
 | |
|          | xargs dpkg -S | sed 's|, |\n|g;s|: [^:]*$||' | uniq | DEBIAN_FRONTEND=noninteractive xargs apt-get install --reinstall -y
 | |
|     echo "Restoring system translations..."
 | |
|     # This step processes the packages which still have missing translations
 | |
|     dpkg --verify --verify-format rpm | awk '/..5......   \/usr\/share\/locale/ {print $2}' | sed 's|/[^/]*$||' | sort |uniq \
 | |
|          | xargs dpkg -S | sed 's|, |\n|g;s|: [^:]*$||' | uniq | DEBIAN_FRONTEND=noninteractive xargs apt-get install --reinstall -y
 | |
|     if dpkg --verify --verify-format rpm | awk '/..5......   \/usr\/share\/doc/ {exit 1}'; then
 | |
|         echo "Documentation has been restored successfully."
 | |
|         rm /etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp
 | |
|     else
 | |
|         echo "There are still files missing from /usr/share/doc/:"
 | |
|         dpkg --verify --verify-format rpm | awk '/..5......   \/usr\/share\/doc/ {print " " $2}'
 | |
|         echo "You may want to try running this script again or you can remove"
 | |
|         echo "/etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp and restore the files manually."
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| if  [ "$(dpkg-divert --truename /usr/bin/man)" = "/usr/bin/man.REAL" ]; then
 | |
|     # Remove diverted man binary
 | |
|     rm -f /usr/bin/man
 | |
|     dpkg-divert --quiet --remove --rename /usr/bin/man
 | |
| fi
 | |
| EOF
 | |
| 
 | |
|                 if [ "$PROJECT" != "ubuntu-base" ] && [ "$PROJECT" != "ubuntu-oci" ]; then
 | |
|                     	# ubuntu-minimal is too much for a docker container (it contains
 | |
|                     	# systemd and other things)
 | |
| 	                cat >> chroot/usr/local/sbin/unminimize <<'EOF'
 | |
| 
 | |
| if ! dpkg-query --show --showformat='${db:Status-Status}\n' ubuntu-minimal 2> /dev/null | grep -q '^installed$'; then
 | |
|     echo "Installing ubuntu-minimal package to provide the familiar Ubuntu minimal system..."
 | |
|     DEBIAN_FRONTEND=noninteractive apt-get install -y ubuntu-minimal ubuntu-standard
 | |
| fi
 | |
| 
 | |
| if dpkg-query --show --showformat='${db:Status-Status}\n' ubuntu-server 2> /dev/null | grep -q '^installed$' \
 | |
|    && ! dpkg-query --show --showformat='${db:Status-Status}\n' landscape-common 2> /dev/null | grep -q '^installed$'; then
 | |
|     echo "Installing ubuntu-server recommends..."
 | |
|     DEBIAN_FRONTEND=noninteractive apt-get install -y landscape-common
 | |
| fi
 | |
| EOF
 | |
| fi
 | |
| 		if [ "$PROJECT" = "ubuntu-cpc" ] || [ "$PROJECT" = "ubuntu-server" ]; then
 | |
| 			cat >> chroot/usr/local/sbin/unminimize <<'EOF'
 | |
| 
 | |
| echo "Removing lxd installer package..."
 | |
| apt-get purge -y lxd-installer
 | |
| 
 | |
| echo "Installing lxd from snap..."
 | |
| snap install lxd
 | |
| EOF
 | |
| 		fi
 | |
| 		cat >> chroot/usr/local/sbin/unminimize <<'EOF'
 | |
| 
 | |
| # unminimization succeeded, there is no need to mention it in motd
 | |
| rm -f /etc/update-motd.d/60-unminimize
 | |
| EOF
 | |
|                 chmod +x chroot/usr/local/sbin/unminimize
 | |
| 
 | |
| 		# inform users about the unminimize script
 | |
| 		cat > "chroot/etc/update-motd.d/60-unminimize" << EOF
 | |
| #!/bin/sh
 | |
| #
 | |
| # This file is not managed by a package.  If you no longer want to
 | |
| # see this message you can safely remove the file.
 | |
| echo ""
 | |
| echo "This system has been minimized by removing packages and content that are"
 | |
| echo "not required on a system that users do not log into."
 | |
| echo ""
 | |
| echo "To restore this content, you can run the 'unminimize' command."
 | |
| EOF
 | |
| 
 | |
| 		chmod +x chroot/etc/update-motd.d/60-unminimize
 | |
| 		Chroot chroot "dpkg-divert --quiet --add \
 | |
| 			--divert /usr/bin/man.REAL --rename \
 | |
| 			/usr/bin/man"
 | |
| 		cat > chroot/usr/bin/man << EOF
 | |
| #!/bin/sh
 | |
| echo "This system has been minimized by removing packages and content that are"
 | |
| echo "not required on a system that users do not log into."
 | |
| echo ""
 | |
| echo "To restore this content, including manpages, you can run the 'unminimize'"
 | |
| echo "command. You will still need to ensure the 'man-db' package is installed."
 | |
| EOF
 | |
|                 chmod +x chroot/usr/bin/man
 | |
| 	fi
 | |
| 
 | |
| 	if [ -n "${PASSES}" ]; then
 | |
| 		PATH="config/:$PATH" lb chroot_layered "$@"
 | |
| 	else
 | |
| 		divert_grub chroot
 | |
| 		divert_update_initramfs
 | |
| 		lb chroot "$@"
 | |
| 		undivert_update_initramfs
 | |
| 		undivert_grub chroot
 | |
| 	fi
 | |
| 
 | |
| 	if [ -d chroot/etc/apt/preferences.d.save ]; then
 | |
| 		# https://twitter.com/infinite_scream
 | |
| 		mv chroot/etc/apt/preferences.d.save/* chroot/etc/apt/preferences.d/
 | |
| 		rmdir chroot/etc/apt/preferences.d.save
 | |
| 	fi
 | |
| 
 | |
| 	# Let all configuration non multi-layered project here.
 | |
| 	# If those are moving to a multi-layer layout, this needs to be
 | |
| 	# 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-*
 | |
| 
 | |
| 			# temporary workaround: don't remove linux-base which
 | |
| 			# may have no other reverse-depends currently
 | |
| 			Chroot chroot "env DEBIAN_FRONTEND=noninteractive \
 | |
| 				apt-mark manual linux-base"
 | |
| 			Chroot chroot "env DEBIAN_FRONTEND=noninteractive \
 | |
| 				apt-get -y --purge autoremove"
 | |
| 		fi
 | |
| 
 | |
| 		configure_universe
 | |
| 
 | |
| 		if [ -d chroot/var/lib/preinstalled-pool ]; then
 | |
| 			cat > config/indices/apt.conf <<-EOF
 | |
| Dir {
 | |
|  ArchiveDir "chroot/var/lib/preinstalled-pool";
 | |
|  OverrideDir "config/indices";
 | |
|  CacheDir "config/indices";
 | |
| }
 | |
| Default { Packages::Compress ". bzip2"; }
 | |
| TreeDefault { Directory "pool"; }
 | |
| Tree "dists/$LB_DISTRIBUTION"
 | |
| {
 | |
|  Sections "$LB_PARENT_ARCHIVE_AREAS";
 | |
|  Architectures "$LB_ARCHITECTURES";
 | |
|  BinOverride "override.$LB_DISTRIBUTION.\$(SECTION)";
 | |
|  ExtraOverride "override.$LB_DISTRIBUTION.extra.\$(SECTION)";
 | |
|  Contents " ";
 | |
| }
 | |
| EOF
 | |
| 			for component in $LB_PARENT_ARCHIVE_AREAS; do
 | |
| 				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
 | |
| # This is a sources.list entry for a small pool of packages
 | |
| # provided on your preinstalled filesystem for your convenience.
 | |
| #
 | |
| # It is perfectly safe to delete both this entry and the directory
 | |
| # 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
 | |
| #
 | |
| @@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
 | |
| 
 | |
| 			R_ORIGIN=$(lsb_release -i -s)
 | |
| 			R_CODENAME=$(lsb_release -c -s)
 | |
| 			R_VERSION=$(lsb_release -r -s)
 | |
| 			R_PRETTYNAME=$(echo $R_CODENAME | sed -e 's/^\(.\)/\U\1/')
 | |
| 
 | |
| 			apt-ftparchive -o APT::FTPArchive::Release::Origin=$R_ORIGIN \
 | |
| 				-o APT::FTPArchive::Release::Label=$R_ORIGIN \
 | |
| 				-o APT::FTPArchive::Release::Suite=$R_CODENAME-local \
 | |
| 				-o APT::FTPArchive::Release::Version=$R_VERSION \
 | |
| 				-o APT::FTPArchive::Release::Codename=$R_CODENAME \
 | |
| 				-o APT::FTPArchive::Release::Description="$R_ORIGIN $R_PRETTYNAME Local" \
 | |
| 				release chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/ \
 | |
| 					> config/gnupg/Release
 | |
| 
 | |
| 			gpg --home config/gnupg --detach-sign --armor config/gnupg/Release
 | |
| 			mv config/gnupg/Release \
 | |
| 				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
 | |
| 			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
 | |
| 		fi
 | |
| 		case $PROJECT:$SUBPROJECT in
 | |
| 			*)
 | |
| 				if [ -e "config/seeded-snaps" ]; then
 | |
| 					snap_list=$(cat config/seeded-snaps)
 | |
| 					preinstall_snaps $snap_list
 | |
| 				fi
 | |
| 				;;
 | |
| 		esac
 | |
| 
 | |
| 		if [ "$PROJECT" = "ubuntu-cpc" ]; then
 | |
| 			if [ "${SUBPROJECT:-}" = minimized ]; then
 | |
| 				BUILD_NAME=minimal
 | |
| 			else
 | |
| 				BUILD_NAME=server
 | |
| 			fi
 | |
| 			cat > chroot/etc/cloud/build.info << EOF
 | |
| build_name: $BUILD_NAME
 | |
| serial: $BUILDSTAMP
 | |
| EOF
 | |
| 		fi
 | |
| 
 | |
| 		if [ "$PROJECT" = "ubuntu-oci" ]; then
 | |
| 		    configure_oci chroot
 | |
| 		fi
 | |
| 
 | |
| 		configure_network_manager
 | |
| 
 | |
| 		echo "===== Checking size of /usr/share/doc ====="
 | |
| 		echo BEGIN docdirs
 | |
| 		(cd chroot && find usr/share/doc -maxdepth 1 -type d | xargs du -s | sort -nr)
 | |
| 		echo END docdirs
 | |
| 
 | |
| 		/usr/share/livecd-rootfs/minimize-manual chroot
 | |
| 
 | |
| 		clean_debian_chroot
 | |
| 	fi
 | |
| 
 | |
| 	if [ -n "${PASSES}" ]; then
 | |
| 		PATH="config/:$PATH" lb binary_layered "$@"
 | |
| 	else
 | |
| 		lb binary "$@"
 | |
| 	fi
 | |
| 
 | |
| 	touch binary.success
 | |
| ) 2>&1 | tee binary.log
 | |
| 
 | |
| # bash has trouble with the build.sh sourcing arrangement at the top of this
 | |
| # file, so we use this cheap-and-cheerful approach rather than the more
 | |
| # correct 'set -o pipefail'.
 | |
| 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
 | |
| 
 | |
| case $LB_INITRAMFS in
 | |
| 	casper)
 | |
| 		INITFS="casper"
 | |
| 		;;
 | |
| 
 | |
| 	live-boot)
 | |
| 		INITFS="live"
 | |
| 		;;
 | |
| 
 | |
| 	*)
 | |
| 		INITFS="boot"
 | |
| 		;;
 | |
| esac
 | |
| 
 | |
| for OUTPUT in ext2 ext3 ext4 manifest manifest-remove size squashfs; do
 | |
| 	[ -e "binary/$INITFS/filesystem.$OUTPUT" ] || continue
 | |
| 	ln "binary/$INITFS/filesystem.$OUTPUT" "$PREFIX.$OUTPUT"
 | |
| 	chmod 644 "$PREFIX.$OUTPUT"
 | |
| 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
 | |
| 
 | |
| if [ -e config/manifest-minimal-remove ]; then
 | |
|         cp config/manifest-minimal-remove  "$PREFIX.manifest-minimal-remove"
 | |
| fi
 | |
| 
 | |
| for ISO in binary.iso binary.hybrid.iso; do
 | |
| 	[ -e "$ISO" ] || continue
 | |
| 	ln "$ISO" "$PREFIX.iso"
 | |
| 	chmod 644 "$PREFIX.iso"
 | |
| 	break
 | |
| done
 | |
| 
 | |
| if [ -e "binary/$INITFS/filesystem.dir" ]; then
 | |
| 	(cd "binary/$INITFS/filesystem.dir/" && tar -c --sort=name --xattrs *) | \
 | |
| 		gzip -9 --rsyncable > "$PREFIX.rootfs.tar.gz"
 | |
| 	chmod 644 "$PREFIX.rootfs.tar.gz"
 | |
| elif [ -e binary-tar.tar.gz ]; then
 | |
| 	cp -a binary-tar.tar.gz "$PREFIX.rootfs.tar.gz"
 | |
| fi
 | |
| 
 | |
| # '--initramfs none' produces different manifest names.
 | |
| if [ -e "binary/$INITFS/filesystem.packages" ]; then
 | |
| 	ln "binary/$INITFS/filesystem.packages" "$PREFIX.manifest"
 | |
| 	chmod 644 "$PREFIX.manifest"
 | |
| 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
 | |
| 		ln "binary/$INITFS/filesystem.packages-remove" "$PREFIX.manifest-remove"
 | |
| 		chmod 644 "$PREFIX.manifest-remove"
 | |
| 	fi
 | |
| fi
 | |
| 
 | |
| # Since snaps are now Ubuntu first-class citizen, so always try fetching the
 | |
| # list of seeded snaps into the manifest.  In case of layered images we skip
 | |
| # this step, as we assume they're doing it on their own at some earlier stage.
 | |
| if [ -z "$PASSES" ] && [ -e "$PREFIX.manifest" ]; then
 | |
| 	./config/snap-seed-parse "chroot/" "$PREFIX.manifest"
 | |
| fi
 | |
| 
 | |
| for FLAVOUR in $LB_LINUX_FLAVOURS; do
 | |
| 	if [ -z "$LB_LINUX_FLAVOURS" ] || [ "$LB_LINUX_FLAVOURS" = "none" ]; then
 | |
| 		continue
 | |
| 	fi
 | |
| 	case $FLAVOUR in
 | |
| 		virtual|generic-hwe-*)
 | |
| 			FLAVOUR="generic"
 | |
| 			;;
 | |
| 		oem-*)
 | |
| 			FLAVOUR="oem"
 | |
| 			;;
 | |
| 	esac
 | |
| 	KVERS="$( (cd "binary/$INITFS"; ls vmlinu?-* 2>/dev/null || true) | (fgrep -v .efi || true) | sed -n "s/^vmlinu.-\\([^-]*-[^-]*-$FLAVOUR\\)$/\\1/p" )"
 | |
| 	if [ -z "$KVERS" ]; then
 | |
| 		if [ -e "binary/$INITFS/vmlinuz" ]; then
 | |
| 			# already renamed by ubuntu-defaults-image
 | |
| 			break
 | |
| 		fi
 | |
| 		echo "No kernel output for $FLAVOUR!" >&2
 | |
| 		exit 1
 | |
| 	fi
 | |
| 	NUMKVERS="$(set -- $KVERS; echo $#)"
 | |
| 	if [ "$NUMKVERS" -gt 1 ]; then
 | |
| 		echo "Cannot handle more than one kernel for $FLAVOUR ($KVERS)!" >&2
 | |
| 		exit 1
 | |
| 	fi
 | |
| 	ln "binary/$INITFS/"vmlinu?-"$KVERS" "$PREFIX.kernel-$FLAVOUR"
 | |
| 	if [ -e "binary/$INITFS/"vmlinu?-"$KVERS.efi.signed" ]; then
 | |
| 		ln "binary/$INITFS/"vmlinu?-"$KVERS.efi.signed" "$PREFIX.kernel-$FLAVOUR.efi.signed"
 | |
| 		chmod 644 "$PREFIX.kernel-$FLAVOUR.efi.signed"
 | |
| 	fi
 | |
| 	chmod 644 "$PREFIX.kernel-$FLAVOUR"
 | |
| 	if [ -e "binary/$INITFS/initrd.img-$KVERS" ]; then
 | |
| 		ln "binary/$INITFS/initrd.img-$KVERS" "$PREFIX.initrd-$FLAVOUR"
 | |
| 		chmod 644 "$PREFIX.initrd-$FLAVOUR"
 | |
| 	fi
 | |
| done
 | |
| 
 | |
| NUMFLAVOURS="$(set -- $LB_LINUX_FLAVOURS; echo $#)"
 | |
| if [ "$NUMFLAVOURS" = 1 ] && [ "$LB_LINUX_FLAVOURS" != "none" ]; then
 | |
| 	# only one kernel flavour
 | |
| 	if [ -f "binary/$INITFS/vmlinuz" ] && ! [ -h "binary/$INITFS/vmlinuz" ]; then
 | |
| 		ln "binary/$INITFS/vmlinuz" "$PREFIX.kernel"
 | |
| 		chmod 644 "$PREFIX.kernel"
 | |
| 	else
 | |
| 		ln -sf "$PREFIX.kernel-$LB_LINUX_FLAVOURS" "$PREFIX.kernel"
 | |
| 	fi
 | |
| 	if [ -f "binary/$INITFS/initrd.lz" ] && ! [ -h "binary/$INITFS/initrd.lz" ]; then
 | |
| 		ln "binary/$INITFS/initrd.lz" "$PREFIX.initrd"
 | |
| 		chmod 644 "$PREFIX.initrd"
 | |
| 	else
 | |
| 		ln -sf "$PREFIX.initrd-$LB_LINUX_FLAVOURS" "$PREFIX.initrd"
 | |
| 	fi
 | |
| fi
 | |
| 
 | |
| case $SUBARCH in
 | |
| 	raspi|raspi2)
 | |
| 		# 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,
 | |
| 		# so during rootfs build we copy it over to a directory that
 | |
| 		# ubuntu-image looks for and shoves into the bootloader
 | |
| 		# partition.
 | |
| 		UBOOT_BOOT="image/boot/uboot"
 | |
| 
 | |
| 		mkdir -p $UBOOT_BOOT
 | |
| 
 | |
| 		cp $PREFIX.initrd $UBOOT_BOOT/initrd.img || true
 | |
| 		cp $PREFIX.kernel $UBOOT_BOOT/vmlinuz || true
 | |
| 		;;
 | |
| 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
 | |
| esac
 |