#!/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. ## This is a fork of lb_chroot for layered live system. ## We don't want leaking host configuratino in each layer, and so, ## we clean and setup the chroot each time. ## In addition, we create the squashfs for each layer, but top one (live) ## which still can be configured after lb chroot call. 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 'customize the Debian system')" 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_chroot_remove_packages() { # Remove packages from the chroot specific to this layer # # $1: Name of the pass* local pass=$1 Expand_packagelist "$(basename config/package-lists/*.removal-list.chroot_${pass})" "config/package-lists" \ >> chroot/root/packages.chroot.removal Chroot chroot "xargs --arg-file=/root/packages.chroot.removal apt-get ${APT_OPTIONS} autoremove --purge" rm -f chroot/root/packages.chroot.removal } # Create the snap list specific to this layer lb_chroot_snap_lists() { local pass=$1 local prevpass=$2 # This assumes that the prefix is unique for a given project local snap_for_pass=$(ls config/package-lists/*.snaplist.chroot_${pass}.full 2>/dev/null || true) local snap_for_prevpass=$(ls config/package-lists/*.snaplist.chroot_${prevpass}.full 2>/dev/null || true) if [ -z "${snap_for_pass}" ]; then return fi if [ -z "${snap_for_prevpass}" ]; then cp ${snap_for_pass} ${snap_for_pass%.full} return fi # Generate a list of snaps added to a layer. diff -NU0 ${snap_for_prevpass} ${snap_for_pass}|grep -Ev '^(---|\+\+\+|@@)'|cut -c2- > ${snap_for_pass%.full} } lb_chroot_install_snaps() { # Prepare the snap environment and install snaps into a chroot # # $1: Name of the pass local snaplist_file=$(ls config/package-lists/*.snaplist.chroot_${1} 2>/dev/null || true) if [ -z "${snaplist_file}" ]; then return fi snap_prepare chroot while read snap; do snap_preseed chroot "${snap}" done < $snaplist_file } create_chroot_pass() { local pass=$1 local prevpass=$2 local lowerlayers=$3 local passtype=$4 # "first"|"last"|"" empty string shift 4 # restore ${*} # We have already treated that pass if [ -d "chroot.${pass}/" ]; then return fi export PASS=${pass} if [ "${passtype}" != "first" ]; then mkdir chroot.${pass} mount_overlay ${lowerlayers} "chroot.${pass}/" chroot/ fi # Configuring chroot lb chroot_cache restore ${*} lb chroot_devpts install ${*} lb chroot_proc install ${*} lb chroot_selinuxfs install ${*} lb chroot_sysfs install ${*} lb chroot_debianchroot install ${*} lb chroot_dpkg install ${*} lb chroot_tmpfs install ${*} lb chroot_sysv-rc install ${*} lb chroot_upstart install ${*} lb chroot_hosts install ${*} lb chroot_resolv install ${*} lb chroot_hostname install ${*} lb chroot_apt install ${*} lb chroot_archives chroot install ${*} # Customizing chroot lb chroot_linux-image ${*} lb chroot_preseed ${*} lb chroot_early_hooks ${*} lb chroot_package-lists ${pass} ${*} lb chroot_install-packages ${pass} ${*} lb_chroot_remove_packages ${pass} ${*} # Snap management lb_chroot_snap_lists ${pass} ${prevpass} lb_chroot_install_snaps ${pass} ${*} # Kernel should be in first layer if [ "${passtype}" = "first" ]; then Chroot chroot "dpkg -l linux-headers-3* linux-headers-4*" 2>/dev/null \ | awk '/^i/ {print $2}' > chroot.headers for i in $(cat chroot.headers); do Chroot chroot "apt-mark auto $i" done fi Chroot chroot "apt-get --purge -y autoremove" # Add live packages to top layer if [ "${passtype}" = "last" ]; then lb chroot_live-packages ${*} fi lb chroot_includes ${*} lb chroot_hooks ${*} lb chroot_hacks ${*} lb chroot_interactive ${*} Chroot chroot "dpkg-query -W" > chroot.packages.${pass} # Deconfiguring chroot lb chroot_archives chroot remove ${*} lb chroot_apt remove ${*} lb chroot_hostname remove ${*} lb chroot_resolv remove ${*} lb chroot_hosts remove ${*} lb chroot_sysv-rc remove ${*} lb chroot_upstart remove ${*} lb chroot_tmpfs remove ${*} lb chroot_dpkg remove ${*} lb chroot_debianchroot remove ${*} lb chroot_sysfs remove ${*} lb chroot_selinuxfs remove ${*} lb chroot_proc remove ${*} lb chroot_devpts remove ${*} lb chroot_cache save ${*} if [ "${passtype}" = "first" ]; then mv chroot chroot.${pass} mkdir chroot else umount chroot fi # Handle direct sublayer of current one # Extract the name of the pass corresponding to the sublayer for subpass in $(ls config/package-lists/*list.chroot_${pass}_* 2>/dev/null | sed -e "s/.*list\.chroot_\(${pass}_[^_]\+\).*/\1/"); do lowerlayers_for_subpass="chroot.${pass}:${lowerlayers}" lowerlayers_for_subpass="${lowerlayers_for_subpass%:}" create_chroot_pass "${subpass}" "${pass}" "${lowerlayers_for_subpass}" "" ${*} done } PASSES="${PASSES:-install live}" CURPASS=1 PREVPASS="" LASTPASS=$(echo $PASSES|wc -w) LOWER_LAYERS="" for _PASS in $PASSES do PASSTYPE="" if [ $CURPASS -eq 1 ]; then PASSTYPE="first" elif [ $CURPASS -eq $LASTPASS ]; then PASSTYPE="last" fi create_chroot_pass "$_PASS" "$PREVPASS" "$LOWER_LAYERS" "$PASSTYPE" ${*} LOWER_LAYERS="chroot.${_PASS}:$LOWER_LAYERS" LOWER_LAYERS="${LOWER_LAYERS%:}" PREVPASS=${_PASS} CURPASS=$(( CURPASS + 1 )) done # remount last pass on chroot for lb binary mount_overlay "${LOWER_LAYERS}" "chroot.${_PASS}/" chroot/ # Remove unused chroot binary corresponding to bottom layer (once everything is unmount) TEARDOWNPATH="config/teardown_chroot_layered" cat > $TEARDOWNPATH << EOF #!/bin/sh set -e umount chroot rm -rf chroot/ EOF chmod +x $TEARDOWNPATH