From c15e39933a10df5cec24089f928043b0393e82b2 Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Thu, 27 Feb 2014 12:06:27 +0100 Subject: added chroot.inc this help provides chroot-install functionality. Only use 'chroot_run ' in your build scripts. Have a look at the comment on how to use. --- remote/includes/chroot.inc | 131 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 remote/includes/chroot.inc (limited to 'remote/includes') diff --git a/remote/includes/chroot.inc b/remote/includes/chroot.inc new file mode 100644 index 00000000..0e95417c --- /dev/null +++ b/remote/includes/chroot.inc @@ -0,0 +1,131 @@ +# ----------------------------------------------------------------------------- +# +# Copyright (c) 2014 - OpenSLX GmbH +# +# This program is free software distributed under the GPL version 2. +# See http://openslx.org/COPYING +# +# If you have any feedback please consult http://openslx.org/feedback and +# send your suggestions, praise, or complaints to feedback@openslx.org +# +# General information about OpenSLX can be found at http://openslx.org/ +# ----------------------------------------------------------------------------- +# +# Common functions for chrooting +# +# ----------------------------------------------------------------------------- + +CHROOT_TEMPDIR="${ROOT_DIR}/remote/chroot.tmp" +CHROOT_MOUNTDIR="${CHROOT_TEMPDIR}/rootmount" +CHROOT_BINDDIR="${CHROOT_TEMPDIR}/rootbind" +CHROOT_LOWERDIR="/" +CHROOT_BINDMOUNTS="/dev /proc /sys /run" + +# Helper function to setup the directory structure +chroot_prepare_dirs() { + # first the dir structure + [ -d "${CHROOT_TEMPDIR}" ] && rm -rf "${CHROOT_TEMPDIR}" + mkdir -p "${CHROOT_TEMPDIR}" || perror "Could not create base directory for mount directories $CHROOT_TEMPDIR." + for DIR in "${CHROOT_BINDDIR}" "${CHROOT_MOUNTDIR}"; do + mkdir -p "${DIR}" || perror "Could not create directory for mount directory $DIR." + done +} + +# Helper to mount the overlay structure: +# - bind mount system / to CHROOT_BINDDIR and make it read-only +# - make an overlay from CHROOT_LOWERDIR CHROOT_UPPERDIR +# - bind mount additional pseudo-fs (as given in CHROOT_BINDMOUNTS) +chroot_prepare_mounts() { + # now the mounts + mount -o bind "${CHROOT_LOWERDIR}" "${CHROOT_BINDDIR}" || perror "Could not bind-mount '$CHROOT_LOWERDIR' to '$CHROOT_BINDDIR'." + mount -o remount,ro "${CHROOT_BINDDIR}" || perror "Could not remount '$CHROOT_BINDDIR' read-only." + mount -t overlayfs overlayfs -o lowerdir="${CHROOT_BINDDIR}",upperdir="${CHROOT_UPPERDIR}" "${CHROOT_MOUNTDIR}" \ + || perror "Could not mount (overlayfs) $CHROOT_LOWERDIR, $CHROOT_UPPERDIR to $CHROOT_BINDDIR." + for DIR in $CHROOT_BINDMOUNTS; do + mount -o bind "${DIR}" "${CHROOT_MOUNTDIR}/${DIR}" \ + || perror "Could not bind mount '$DIR' into '$CHROOT_MOUNTDIR/$DIR'." + done +} + +# Helper to cleanup the temporary mounts +chroot_cleanup_mounts() { + for DIR in $CHROOT_BINDMOUNTS; do + umount -l "${CHROOT_MOUNTDIR}/${DIR}" || pwarning "Could not unmount '$CHROOT_MOUNTDIR/$DIR'!" + done + umount -l "${CHROOT_MOUNTDIR}" || pwarning "Could not unmount '$CHROOT_MOUNTDIR'!" + umount -l "${CHROOT_BINDDIR}" || pwarning "Could not unmount '$CHROOT_BINDDIR'!" +} + +# Helper to clean the temporary directories +chroot_cleanup_dirs() { + rm -rf "${CHROOT_TEMPDIR}" || perror "Could not clean/delete temp directory '$CHROOT_TEMPDIR'." +} + +# Helper to generate the mighty autoexec.bat +chroot_gen_autoexec() { + # create the script to be automatically executed. + cat >"${CHROOT_MOUNTDIR}/autoexec.bat"<<-EOF + #!/bin/bash + echo "chroot success." + EOF + + # dump the piped input to it + cat >> "${CHROOT_MOUNTDIR}/autoexec.bat" + + # finish with an exit + echo "exit 0" >> "${CHROOT_MOUNTDIR}/autoexec.bat" + chmod +x "${CHROOT_MOUNTDIR}/autoexec.bat" +} + +chroot_handle_whiteouts() { + local WHITEOUT_LIST="${CHROOT_UPPERDIR}/overlay.whiteout.list" + rm -f -- "$WHITEOUT_LIST=" + #mkdir -p "$(dirname "$WHITEOUT_LIST")" || perror "Could not create $(dirname "$WHITEOUT_LIST")" + pdebug "Searching for overlayfs-whiteouts ..." + for WHITEOUT in $(find "$CHROOT_UPPERDIR" -lname "(overlay-whiteout)"); do + pdebug "Whiteout found: $WHITEOUT" + echo "/./${WHITEOUT#$CHROOT_UPPERDIR}" >> "$WHITEOUT_LIST" + rm -f -- "$WHITEOUT" || perror "Could not delete whiteout $WHITEOUT!" + done + pinfo "Whitelist dumped to '${CHROOT_UPPERDIR}/overlay.whiteout.list'" +} + +# Main function to be called from the outside +# Usage: +# chroot_run +# +# It will run: +# - chroot_prepare +# - chroot $CHROOT_TEMPDIR/rootmount +# - executes $CHROOT_TEMPDIR/rootmount/autoexec.bat +# - chroot_cleanup +chroot_run() { + # check args + [ $# -eq 1 ] || perror "'chroot_run' requires exactly 1 parameter. Given $#. Use 'chroot_run '" + + local CHROOT_UPPERDIR="$1" + mkdir -p "$1" + + # first prepare the dir structure + chroot_prepare_dirs || perror "'chroot_prepare_dirs' failed with $?." + chroot_prepare_mounts || perror "'chroot_prepare_mounts' failed with $?." + + # generate the code to be executed when chroot'ing + chroot_gen_autoexec || perror "'chroot_gen_autoexec' failed with $?." + + # do the chroot + chroot --userspec root:root "${CHROOT_MOUNTDIR}" /autoexec.bat + local RET=$? + if [ "$RET" -eq 0 ]; then + pinfo "chroot executed '${CHROOT_MOUNTDIR}/autoexec.bat' succeeded." + else + perror "Failed to chroot to '$CHROOT_MOUNTDIR' with error code: $RET" + fi + + # handle whiteouts + chroot_handle_whiteouts || perror "'chroot_handle_whiteouts' failed with error code: $?" + + # finally cleanup all the stuff we did previously + chroot_cleanup_mounts || perror "'chroot_cleanup_mounts' failed with $?." + chroot_cleanup_dirs || perror "'chroot_cleanup_dir' failed with $?." +} -- cgit v1.2.3-55-g7522