#!/bin/sh ## live-build(7) - System Build Scripts ## Copyright (C) 2006-2012 Daniel Baumann ## ## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING. ## This is free software, and you are welcome to redistribute it ## under certain conditions; see COPYING for details. set -e # Including common functions ( . "${LIVE_BUILD}/scripts/build.sh" > /dev/null 2>&1 || true ) || . /usr/lib/live/build.sh # Automatically populating config tree if [ -x auto/config ] && [ ! -e .build/config ] then Echo_message "Automatically populating config tree." lb config fi # Setting static variables DESCRIPTION="$(Echo 'build binary images')" HELP="" USAGE="${PROGRAM} [--force]" Arguments "${@}" # Reading configuration files Read_conffiles config/all config/common config/bootstrap config/chroot config/binary config/source Set_defaults # Setup cleanup function Setup_cleanup . config/functions lb_binary_includes () { # Copying includes from pass subdirectory local pass="$1" if [ ! -d config/includes.binary.${pass} ]; then return fi cd config/includes.binary.${pass} find . | cpio -dmpu --no-preserve-owner "${OLDPWD}"/chroot cd "${OLDPWD}" } build_layered_squashfs () { local pass=$1 shift 1 # restore ${*} Echo_message "lb_binary_layered: treating pass $pass" # Per convention, we include the subarch name next to the project PROJECT_FULL=$PROJECT${SUBARCH:+-$SUBARCH} # Building squashfs filesystem & manifest local overlay_dir="overlay.${pass}" base="${PWD}/livecd.${PROJECT_FULL}.${pass}" squashfs_f="${base}.squashfs" # We have already treated that pass if [ -f "${squashfs_f}" ]; then return fi rm -f .build/binary_chroot .build/binary_hooks mkdir -p "$overlay_dir/" lowerdirs=$(get_lowerdirs_for_pass $pass) if [ -n "$lowerdirs" ]; then mkdir -p chroot/ mount_overlay "$lowerdirs" "$overlay_dir" chroot/ else ln -s "$overlay_dir/" chroot fi export PASS=${pass} setenv_file PASS "${pass}" config/environment.chroot # Cleanup root filesystem lb binary_chroot ${*} lb_binary_includes $pass ${*} lb binary_hooks ${*} # Copy initrd and vmlinuz outside of chroot and remove them from the layer squashfs if $(is_live_layer "$pass"); then lb binary_linux-image ${*} rm -f chroot/boot/initrd.img-* chroot/boot/vmlinu{x,z}-* fi make_squashfs=yes ppass="${pass}" while :; do for nsp in ${NO_SQUASHFS_PASSES}; do if [ "${ppass}" = "${nsp}" ]; then make_squashfs=no break 2 fi done ppass="$(get_parent_pass "${ppass}")" if [ -z "${ppass}" ]; then break fi done if [ $make_squashfs = yes ]; then # Full manifest until that PASS squashfs_f_manifest="${base}.manifest" create_manifest "chroot" "${squashfs_f_manifest}.full" # Delta manifest diff -NU0 ${PWD}/livecd.${PROJECT_FULL}.$(get_parent_pass $pass).manifest.full ${squashfs_f_manifest}.full|grep -v ^@ > $squashfs_f_manifest || true echo "Delta manifest:" cat $squashfs_f_manifest squashfs_f_size="${base}.size" du -B 1 -s "overlay.${pass}/" | cut -f1 > "${squashfs_f_size}" # We take first live pass for "global" ISO properties (used by installers and checkers): # Prepare initrd + kernel # Main manifest and size files prefix="livecd.$PROJECT_FULL" if [ ! -e "${prefix}.manifest" ] && $(is_live_layer "$pass"); then totalsize=$(cat ${squashfs_f_size}) curpass="$pass" while :; do curpass=$(get_parent_pass $curpass) # We climbed up the tree to the root layer, we are done [ -z "$curpass" ] && break totalsize=$(expr $totalsize + $(cat "${PWD}/livecd.${PROJECT_FULL}.${curpass}.size")) done echo ${totalsize} > "${prefix}.size" cp "${squashfs_f_manifest}.full" "${prefix}.manifest" fi if [ -n "$lowerdirs" ]; then # Although the current chroot was created as an overlay over # the previous layer, many operations can result in redundant # files in the upperdir. Rather than trying to minimize the # overlay by hand, we rsync the chroot into a fresh overlay, # rely on rsyncs ability to avoid redundant file operations, # and take _that_ overlay's upperdir as the content of the # layer. mkdir -p chroot-2 "$overlay_dir-2" mount_overlay "$lowerdirs" "$overlay_dir-2" chroot-2 # rsync takes many, many options. The subset # we pass here is quite important: # -a is standard to operate in the basic way required here. # -X to preserve xattrs # -H to preserve hardlinks # -A to preserve ACLs # -S to preserve sparseness # --checksum to skip copies based on the content of the file # (rather than the default which is to skip copies based # on size + mtime) # --no-times to not copy mtimes from source to dest (we # don't care about mtime in the image and want to # deduplicate files that have indentical contents but # different mtimes) # --del because we want to remove files that have been # deleted in this layer. rsync -aXHAS --checksum --no-times --del chroot/ chroot-2/ umount chroot-2 rmdir chroot-2 overlay_dir="$overlay_dir-2" fi create_squashfs "${overlay_dir}" ${squashfs_f} if [ -f config/$pass.catalog-in.yaml ]; then echo "Expanding catalog entry template for $pass" usc_opts="--output livecd.${PROJECT_FULL}.install-sources.yaml \ --template config/$pass.catalog-in.yaml \ --size $(du -B 1 -s chroot/ | cut -f1) --squashfs ${pass}.squashfs \ --translations config/catalog-translations" if [ -f config/seeded-languages ]; then usc_opts="$usc_opts --langs $(cat config/seeded-languages)" fi /usr/share/livecd-rootfs/update-source-catalog source $usc_opts else echo "No catalog entry template for $pass" fi fi if [ -n "$lowerdirs" ]; then umount chroot rmdir chroot else rm chroot fi } for _PASS in $PASSES do build_layered_squashfs "${_PASS}" ${*} done # Ubiquity-compatible removal manifest for ISO not using a layered-aware installer if [ -n "$(ls livecd.${PROJECT_FULL}.*install.live.manifest.full 2>/dev/null)" ] && \ [ -n "$(ls livecd.${PROJECT_FULL}.*install.manifest.full 2>/dev/null)" ]; then echo "$(diff livecd.${PROJECT_FULL}.*install.live.manifest.full livecd.${PROJECT_FULL}.*install.manifest.full | awk '/^< / { print $2 }')" > livecd.${PROJECT_FULL}-manifest-remove fi chmod 644 *.squashfs *.manifest* *.size