11#! /bin/sh -x
22
3- . ` dirname " $0 " ` /functions
3+ . " $( dirname " $0 " ) " /functions
44. detect-environment
55. compile-options
66
7+ #
8+ # This script sets up chroot environment for testing.
9+ # It creates the directory structure and populates it with a minimal set of system files.
10+ #
11+ # The script can be run as follows:
12+ # $ ./buildscripts/build-scripts/prepare-testmachine-chroot
13+ #
14+
15+ # Path to file that will contain file-filtering rules for rsync.
716TRANSFER_SCRIPT=$BASEDIR /prepare-testmachine-chroot-transfer-script.rsync
17+
18+ # Create the directory where the chroot environment is to be created.
819# Don't lose the trailing slash!
920CHROOT_ROOT=$HOME /testmachine-chroot/
21+ sudo mkdir -p " $CHROOT_ROOT "
1022
11- sudo mkdir -p $CHROOT_ROOT
23+ # Clean up previous chroot state by killing any processes that are using the CHROOT_ROOT directory.
24+ sudo " $FUSER " -k " $CHROOT_ROOT " || true
25+ # Unmount the /proc filesystem if it was previously mounted inside the chroot.
26+ sudo umount " ${CHROOT_ROOT} proc" || true
1227
13- sudo $FUSER -k $CHROOT_ROOT || true
14- sudo umount ${CHROOT_ROOT} proc || true
15-
16- echo " P $BASEDIR " > $TRANSFER_SCRIPT
17- echo " P $PREFIX " >> $TRANSFER_SCRIPT
18- generate_chroot_transfer_script >> $TRANSFER_SCRIPT
28+ # Tell rsync not to touch the BASEDIR and PREFIX directories
29+ echo " P $BASEDIR " > " $TRANSFER_SCRIPT "
30+ echo " P $PREFIX " >> " $TRANSFER_SCRIPT "
31+ # Generate the file-filter for rsync (see functions script)
32+ generate_chroot_transfer_script >> " $TRANSFER_SCRIPT "
1933
34+ # Run a process in the background to print "Keep alive" every 60 seconds until the .keepalive-echo file exists.
35+ # This is to prevent the session from timing out on a remote machine.
2036touch .keepalive-echo
2137(while test -e .keepalive-echo; do sleep 60; echo Keep alive; done)&
38+
2239RETURN_CODE=0
23- sudo rsync --filter=" . $TRANSFER_SCRIPT " -Da --delete --delete-excluded / $CHROOT_ROOT || RETURN_CODE=$?
40+ # Core file transfer command.
41+ # -D is for copying device files as well.
42+ # --delete to remove files in destination that are not present in source
43+ # --delete-excluded to remove excluded files in destination
44+ sudo rsync --filter=" . $TRANSFER_SCRIPT " -Da --delete --delete-excluded / " $CHROOT_ROOT " || RETURN_CODE=$?
45+
46+ # Now we can stop the keep alive process
2447rm .keepalive-echo
48+
2549# Return code 24 means "some files vanished before they could be transferred",
2650# which we don't care about, since a running system might experience this
2751# without it being an error.
28- if [ $RETURN_CODE -ne 0 -a $RETURN_CODE -ne 24 ]; then
52+ if [ $RETURN_CODE -ne 0 ] && [ $RETURN_CODE -ne 24 ]; then
2953 exit $RETURN_CODE
3054fi
3155
32- sudo mkdir -p ${CHROOT_ROOT} tmp
33- sudo chmod 1777 ${CHROOT_ROOT} tmp
34- sudo mkdir -p ${CHROOT_ROOT} var/tmp
35- sudo chmod 1777 ${CHROOT_ROOT} var/tmp
36-
37- sudo mkdir -p ${CHROOT_ROOT} run
38-
39- sudo mkdir -p ${CHROOT_ROOT} root
56+ # Create and set permissions for essential directories inside chroot
57+ for d in tmp var/tmp run root; do
58+ sudo mkdir -p $d
59+ done
60+ sudo chmod 1777 " ${CHROOT_ROOT} tmp"
61+ sudo chmod 1777 " ${CHROOT_ROOT} var/tmp"
4062
4163# Safeguard to terminate operation if we have somehow ended up outside the
4264# chroot, so we don't start running unsafe tests there.
43- sudo touch ${CHROOT_ROOT} inside-chroot.txt
65+ sudo touch " ${CHROOT_ROOT} inside-chroot.txt"
4466
4567# Trick in order to get a login command that starts out in the home dir instead of the root.
4668# See the login command for chroot in test-on-testmachine
6385 name=$( echo " $entry " | sed -e ' s/^[^=]* //; s/^\([^=]*\)=.*/\1/' )
6486 if [ " $name " = " PATH" ]
6587 then
88+ # Skip the PATH variable as it's handled below
6689 continue
6790 fi
6891 value=" $( echo " $entry " | sed -e ' s/^[^=]*=//' ) "
@@ -72,19 +95,26 @@ done | sudo sh -c "cat >> ${CHROOT_ROOT}run-in-home-dir.sh"
7295unset IFS
7396
7497# Treat PATH specifically, and add to existing path.
98+ # shellcheck disable=SC2016
7599printf ' PATH="%s:$PATH"\nexport PATH\n' " $PATH " | sudo sh -c " cat >> ${CHROOT_ROOT} run-in-home-dir.sh"
76100
77101# Note different quote style on Here document.
78102sudo bash -c " cat >> ${CHROOT_ROOT} run-in-home-dir.sh" << 'EOF '
79103exec "$@"
80104EOF
81105
82- sudo chmod ugo+x ${CHROOT_ROOT} run-in-home-dir.sh
106+ # Make the run-in-home-dir.sh script executable
107+ sudo chmod ugo+x " ${CHROOT_ROOT} run-in-home-dir.sh"
83108
84- sudo mkdir -p ${CHROOT_ROOT} proc
109+ # Creates the /proc mount point inside the chroot.
110+ # This is done after the rsync because /proc is explicitly excluded in the filter rules.
111+ # The /proc filesystem is typically mounted, not copied.
112+ sudo mkdir -p " ${CHROOT_ROOT} proc"
85113
86- if [ ! -e ${CHROOT_ROOT} dev ]; then
87- sudo mkdir -p ${CHROOT_ROOT} dev
88- sudo dd if=/dev/urandom of=${CHROOT_ROOT} dev/urandom bs=1048576 count=10
89- sudo dd if=/dev/urandom of=${CHROOT_ROOT} dev/random bs=1048576 count=10
114+ # Create a dummy /dev/random & /dev/urandom.
115+ # For a fully functional chroot, these devices should be mounted.
116+ if [ ! -e " ${CHROOT_ROOT} dev" ]; then
117+ sudo mkdir -p " ${CHROOT_ROOT} dev"
118+ sudo dd if=/dev/urandom of=" ${CHROOT_ROOT} dev/urandom bs=1048576 count=10"
119+ sudo dd if=/dev/urandom of=" ${CHROOT_ROOT} dev/random bs=1048576 count=10"
90120fi
0 commit comments