-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathprepare-testmachine-chroot
More file actions
executable file
·128 lines (108 loc) · 4.65 KB
/
prepare-testmachine-chroot
File metadata and controls
executable file
·128 lines (108 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/bin/sh -x
. "$(dirname "$0")"/functions
. detect-environment
. compile-options
#
# This script sets up chroot environment for testing.
# It creates the directory structure and populates it with a minimal set of system files.
#
# The script can be run as follows:
# $ ./buildscripts/build-scripts/prepare-testmachine-chroot
#
# Path to file that will contain file-filtering rules for rsync.
TRANSFER_SCRIPT=$BASEDIR/prepare-testmachine-chroot-transfer-script.rsync
# Create the directory where the chroot environment is to be created.
# Don't lose the trailing slash!
CHROOT_ROOT=$HOME/testmachine-chroot/
sudo mkdir -p "$CHROOT_ROOT"
# Clean up previous chroot state by killing any processes that are using the CHROOT_ROOT directory.
sudo "$FUSER" -k "$CHROOT_ROOT" >/dev/null 2>&1 || true
# Unmount the /proc filesystem if it was previously mounted inside the chroot.
sudo umount "${CHROOT_ROOT}proc" >/dev/null 2>&1 || true
# Tell rsync not to touch the BASEDIR and PREFIX directories
echo "P $BASEDIR" >"$TRANSFER_SCRIPT"
echo "P $PREFIX" >>"$TRANSFER_SCRIPT"
# Generate the file-filter for rsync (see functions script)
generate_chroot_transfer_script >>"$TRANSFER_SCRIPT"
# Run a process in the background to print "Keep alive" every 60 seconds until the .keepalive-echo file exists.
# This is to prevent the session from timing out on a remote machine.
touch .keepalive-echo
(while test -e .keepalive-echo; do
sleep 60
echo Keep alive
done) &
RETURN_CODE=0
# Core file transfer command.
# -D is for copying device files as well.
# --delete to remove files in destination that are not present in source
# --delete-excluded to remove excluded files in destination
sudo rsync --filter=". $TRANSFER_SCRIPT" -Da --delete --delete-excluded / "$CHROOT_ROOT" || RETURN_CODE=$?
# Now we can stop the keep alive process
rm .keepalive-echo
# Return code 24 means "some files vanished before they could be transferred",
# which we don't care about, since a running system might experience this
# without it being an error.
if [ $RETURN_CODE -ne 0 ] && [ $RETURN_CODE -ne 24 ]; then
exit $RETURN_CODE
fi
# Create and set permissions for essential directories inside chroot
for d in tmp var/tmp run root; do
sudo mkdir -p "${CHROOT_ROOT}${d}"
done
sudo chmod 1777 "${CHROOT_ROOT}tmp"
sudo chmod 1777 "${CHROOT_ROOT}var/tmp"
# Safeguard to terminate operation if we have somehow ended up outside the
# chroot, so we don't start running unsafe tests there.
sudo touch "${CHROOT_ROOT}inside-chroot.txt"
# Trick in order to get a login command that starts out in the home dir instead of the root.
# See the login command for chroot in test-on-testmachine
sudo bash -c "cat > ${CHROOT_ROOT}run-in-home-dir.sh" <<EOF
#!/bin/sh -x
if [ ! -f /inside-chroot.txt ]; then
echo Something is wrong. We should be inside the chroot now. Bailing...
exit 2
fi
cd $HOME
EOF
# Include entire environment in chroot, and make sure everything is exported,
# and added to the existing environment.
# Split on newlines, not on spaces.
IFS='
'
for entry in $(export); do
name=$(echo "$entry" | sed -e 's/^[^=]* //; s/^\([^=]*\)=.*/\1/')
if [ "$name" = "PATH" ]; then
# Skip the PATH variable as it's handled below
continue
fi
value="$(echo "$entry" | sed -e 's/^[^=]*=//')"
printf "%s=%s\nexport %s\n" "$name" "$value" "$name"
done | sudo sh -c "cat >> ${CHROOT_ROOT}run-in-home-dir.sh"
# Restore normal splitting semantics.
unset IFS
# Treat PATH specifically, and add to existing path.
# shellcheck disable=SC2016
printf 'PATH="%s:$PATH"\nexport PATH\n' "$PATH" | sudo sh -c "cat >> ${CHROOT_ROOT}run-in-home-dir.sh"
# Note different quote style on Here document.
sudo bash -c "cat >> ${CHROOT_ROOT}run-in-home-dir.sh" <<'EOF'
exec "$@"
EOF
# Make the run-in-home-dir.sh script executable
sudo chmod ugo+x "${CHROOT_ROOT}run-in-home-dir.sh"
# Creates the /proc mount point inside the chroot.
# This is done after the rsync because /proc is explicitly excluded in the filter rules.
# The /proc filesystem is typically mounted, not copied.
sudo mkdir -p "${CHROOT_ROOT}proc"
# Create a dummy /dev/random & /dev/urandom.
# For a fully functional chroot, these devices should be mounted.
if [ ! -e "${CHROOT_ROOT}dev" ]; then
sudo mkdir -p "${CHROOT_ROOT}dev"
sudo dd if=/dev/urandom of="${CHROOT_ROOT}dev/urandom" bs=1048576 count=10
sudo dd if=/dev/urandom of="${CHROOT_ROOT}dev/random" bs=1048576 count=10
if [ "$OS_FAMILY" = aix ]; then
# This device is needed for the lscfg command to work on AIX.
# We use that command to get number of cores in the detect-environment script.
sudo mkdir -p "$CHROOT_ROOT"dev
sudo cp -R /dev/nvram "$CHROOT_ROOT"dev/nvram
fi
fi