#! /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 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 "$@" Chroot chroot "dpkg-divert --quiet --add \ --divert /usr/sbin/update-initramfs.REAL --rename \ /usr/sbin/update-initramfs" cat > chroot/usr/sbin/update-initramfs <<'EOF' #! /bin/sh if [ $# != 1 ] || [ "$1" != -u ]; then exec update-initramfs.REAL "$@" fi echo "update-initramfs: diverted by livecd-rootfs (will be called later)" >&2 exit 0 EOF chmod +x chroot/usr/sbin/update-initramfs cat > config/hooks/999-undivert-update-initramfs.chroot <<'EOF' #! /bin/sh rm -f /usr/sbin/update-initramfs dpkg-divert --quiet --remove --rename /usr/sbin/update-initramfs EOF lb chroot "$@" if [ -f config/oem-config-preinstalled ]; then # This is cargo-culted almost verbatim (with some syntax changes for # preinstalled being slightly different in what it doesn't ask) from # debian-installer's apt-setup: codename=$LB_DISTRIBUTION file="chroot/etc/apt/sources.list" dists="main" alldists="main" if echo "$LB_PARENT_ARCHIVE_AREAS" | grep -q restricted; then dists="$dists restricted" alldists="$alldists restricted" fi if echo "$LB_PARENT_ARCHIVE_AREAS" | grep -q universe; then UNIVERSE=true else UNIVERSE=false fi if echo "$LB_PARENT_ARCHIVE_AREAS" | grep -q multiverse; then MULTIVERSE=true else MULTIVERSE=false fi cat > $file <> $file if [ "$UNIVERSE" = true ]; then alldists="$alldists universe" COMMENT= else cat >> $file <> $file <> $file <> $file <> $file <> $file <> $file < 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 if [ "$PROJECT" = "ubuntu-touch" ] && [ "$ARCH" = "armhf" ]; then INFO_DESC="$(lsb_release -d -s)" echo "$INFO_DESC - $ARCH ($BUILDSTAMP)" >chroot/etc/media-info mkdir -p chroot/var/log/installer Chroot chroot "ln -s /etc/media-info /var/log/installer/media-info" fi 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 if which fdupes >/dev/null 2>&1; then echo "===== Checking for duplicate files =====" echo "first line: " echo "data lines: [ ...]" echo BEGIN fdupes (cd chroot \ && fdupes --recurse --noempty --sameline --size --quiet usr \ | awk '/bytes each/ {s=$1} /^usr/ { n+=1; n2+=NF-1; sum+=s*(NF-1); print s*(NF-1), NF-1, s, $0 } END {print sum, n, n2}' \ | sort -nr ) echo END fdupes fi lb binary "$@" 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 exit 1 fi # Link output files somewhere BuildLiveCD will be able to find them. PREFIX="livecd.$PROJECT${SUBARCH:+-$SUBARCH}" 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 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 *) | \ 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 for FLAVOUR in $LB_LINUX_FLAVOURS; do if [ -z "$LB_LINUX_FLAVOURS" ] || [ "$LB_LINUX_FLAVOURS" = "none" ]; then continue fi 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 [ -e "binary/$INITFS/vmlinuz" ]; then ln "binary/$INITFS/vmlinuz" "$PREFIX.kernel" else ln -sf "$PREFIX.kernel-$LB_LINUX_FLAVOURS" "$PREFIX.kernel" fi if [ -e "binary/$INITFS/initrd.lz" ]; then ln "binary/$INITFS/initrd.lz" "$PREFIX.initrd" else ln -sf "$PREFIX.initrd-$LB_LINUX_FLAVOURS" "$PREFIX.initrd" fi fi if [ "$SUBARCH" = "ac100" ] || [ "$SUBARCH" = "nexus7" ]; then # create the md5sum and size files for which we are actually doing all this md5sum $PREFIX.rootfs.tar.gz >chroot/installer.md5 wc -c $PREFIX.rootfs.tar.gz >chroot/installer.size INFO_DESC="$(lsb_release -d -s)" INFO_STAMP=$(date +20%y%m%d-%H:%M) echo "$INFO_DESC - $ARCH ($INFO_STAMP)" >chroot/media-info # make sure update-initramfs feels cosy and warm in the environment lb chroot_proc install "$@" lb chroot_sysfs install "$@" lb chroot_devpts install "$@" # re-create initrd to contain the installer.md5 file Chroot chroot "env FLASH_KERNEL_SKIP=1 update-initramfs -k all -t -u -v" # create boot.img Chroot chroot "abootimg --create /boot/installer-${KVERS}.img -f /boot/bootimg.cfg-$SUBARCH -r /boot/initrd.img-${KVERS} -k /boot/vmlinuz-${KVERS}" if [ "$SUBARCH" = "nexus7" ]; then # roll the android rootfs images mkdir -p userdata mv $PREFIX.rootfs.tar.gz userdata/rootfs.tar.gz make_ext4fs -l 6G -s $PREFIX.ext4-$FLAVOUR userdata/ mv userdata/rootfs.tar.gz $PREFIX.rootfs.tar.gz ln -sf "$PREFIX.ext4-$FLAVOUR" "$PREFIX.ext4" fi # clean up lb chroot_devpts remove "$@" lb chroot_sysfs remove "$@" lb chroot_proc remove "$@" cp "chroot/boot/installer-${KVERS}.img" "$PREFIX.bootimg-$FLAVOUR" ln -sf "$PREFIX.bootimg-$FLAVOUR" "$PREFIX.bootimg" fi if [ "$PROJECT" = "ubuntu-touch" ] && [ "$ARCH" = "armhf" ]; then touchsubarches="maguro manta grouper mako" sourceslist="chroot/etc/apt/sources.list" lb chroot_proc install "$@" lb chroot_sysfs install "$@" lb chroot_devpts install "$@" if [ -e "$PREFIX.manifest" ]; then Chroot chroot "click list" | while read line; do echo "click:$line" >>"$PREFIX.manifest" done fi if [ -e chroot/etc/resolv.conf ]; then mv chroot/etc/resolv.conf chroot/etc/resolv.conf.orig fi if [ -e /etc/resolv.conf ]; then cp /etc/resolv.conf chroot/etc/resolv.conf fi mv "${sourceslist}" "${sourceslist}.orig" mv "${sourceslist}.d" "${sourceslist}.d.orig" echo "deb $LB_PARENT_MIRROR_CHROOT ${LB_DISTRIBUTION} main universe multiverse restricted" >$sourceslist Chroot chroot "apt-get -y update" Chroot chroot "apt-get -y install android" for subarch in $touchsubarches; do cp chroot/usr/share/android/product/*-preinstalled-system-armel+${subarch}.img\ "${PREFIX}.system-armel+${subarch}.img" cp chroot/usr/share/android/product/*-preinstalled-recovery-armel+${subarch}.img\ "${PREFIX}.recovery-armel+${subarch}.img" cp chroot/usr/share/android/product/*-preinstalled-boot-armhf+${subarch}.img\ "${PREFIX}.boot-armhf+${subarch}.img" # drop this following line once cdimage can handle -boot-*.img cp "${PREFIX}.boot-armhf+${subarch}.img" "${PREFIX}.bootimg-${subarch}" cp chroot/usr/share/android/product/*-preinstalled-touch-armel+${subarch}.zip\ "${PREFIX}.armel+${subarch}.zip" done lb chroot_devpts remove "$@" lb chroot_sysfs remove "$@" lb chroot_proc remove "$@" fi # 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