summaryrefslogtreecommitdiffstats
path: root/remote/includes
diff options
context:
space:
mode:
Diffstat (limited to 'remote/includes')
-rw-r--r--remote/includes/chroot.inc131
1 files changed, 131 insertions, 0 deletions
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 <build_dir>
+#
+# 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 <build_dir>'"
+
+ 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 $?."
+}