parent
64ec967711
commit
1e31ec7ab0
2 changed files with 135 additions and 101 deletions
@ -0,0 +1,113 @@ |
|||||||
|
error_handler() { |
||||||
|
echo failed at ${BASH_LINENO[0]} |
||||||
|
} |
||||||
|
trap error_handler ERR |
||||||
|
|
||||||
|
create_rootfs_diff() { |
||||||
|
sudo rm -f "$CACHE_ROOTFS_TARBALL_PATH" # remove the old diff tarball from previous run, if exists |
||||||
|
cd /upper |
||||||
|
sudo tar -cf "$CACHE_ROOTFS_TARBALL_PATH" . |
||||||
|
cd |
||||||
|
} |
||||||
|
|
||||||
|
apply_rootfs_diff() { |
||||||
|
cd / |
||||||
|
sudo tar -xf "$CACHE_ROOTFS_TARBALL_PATH" 2>/dev/null || true |
||||||
|
cd |
||||||
|
} |
||||||
|
|
||||||
|
prepare_build() { |
||||||
|
# create and mount the required volumes where they're expected |
||||||
|
mkdir -p /tmp/openpilot /tmp/scons_cache /tmp/comma_download_cache /tmp/openpilot_cache |
||||||
|
sudo mount --bind "$REPO" /tmp/openpilot |
||||||
|
|
||||||
|
sudo mount --bind "$REPO/.ci_cache/scons_cache" /tmp/scons_cache || true |
||||||
|
sudo mount --bind "$REPO/.ci_cache/comma_download_cache" /tmp/comma_download_cache || true |
||||||
|
sudo mount --bind "$REPO/.ci_cache/openpilot_cache" /tmp/openpilot_cache || true |
||||||
|
|
||||||
|
# needed for the unit tests not to fail |
||||||
|
sudo chmod 755 /sys/fs/pstore |
||||||
|
} |
||||||
|
|
||||||
|
post_commit_root() { |
||||||
|
# we have the diff tarball, now let's remove the folder too |
||||||
|
sudo rm -rf /upper |
||||||
|
|
||||||
|
# now we apply it straight away |
||||||
|
apply_rootfs_diff |
||||||
|
|
||||||
|
# before the next tasks are run, finalize the environment for them |
||||||
|
prepare_build |
||||||
|
} |
||||||
|
|
||||||
|
# warning: this function initiates a somewhat complicated program flow, follow carefully |
||||||
|
# (even despite this part was made sure to not be too relevant for the rest of the job) |
||||||
|
commit_root() { |
||||||
|
# if that's a first execution |
||||||
|
if ! [ -e /root_committed ] |
||||||
|
then |
||||||
|
# prepare directories |
||||||
|
sudo mkdir -p /base /newroot /upper /work |
||||||
|
|
||||||
|
# re-execute the main script (causing it to go straight to `build_inside_namespace`), but |
||||||
|
# inside the newly created namespace, in a way which would cause all mounts |
||||||
|
# created to automatically umount before it exits |
||||||
|
sudo unshare -f --kill-child -m "$SELF_PATH" build_inside_namespace |
||||||
|
ec=$? |
||||||
|
|
||||||
|
# after it exited, remove the created directories (except the one containing created diff) |
||||||
|
sudo rm -rf /base /newroot /work |
||||||
|
|
||||||
|
# finally, create the rootfs diff tarball (to be pushed into the CI native cache) |
||||||
|
create_rootfs_diff |
||||||
|
|
||||||
|
# after creating the rootfs diff, bring the system into a state as if it was restored from cache |
||||||
|
post_commit_root |
||||||
|
|
||||||
|
exit $ec |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
reexecute() { |
||||||
|
touch /root_committed |
||||||
|
sudo -u runner "$SELF_PATH" |
||||||
|
ec=$? |
||||||
|
exit $ec |
||||||
|
} |
||||||
|
|
||||||
|
# that's where the script goes after being re-executed for the first time |
||||||
|
build_inside_namespace() { |
||||||
|
# initialize the mounts namespace on overlayfs to be able to prepare the rootfs diff |
||||||
|
mount --bind / /base |
||||||
|
mount -t overlay overlay -o lowerdir=/base,upperdir=/upper,workdir=/work /newroot |
||||||
|
|
||||||
|
# apply the current DNS config (beware: systemd often symlinks /etc/resolv.conf, that's why it's needed) |
||||||
|
rm -f /newroot/etc/resolv.conf |
||||||
|
touch /newroot/etc/resolv.conf |
||||||
|
cat /etc/resolv.conf > /newroot/etc/resolv.conf |
||||||
|
|
||||||
|
# switch the namespace's root mount to the newly created one |
||||||
|
mkdir -p /newroot/old |
||||||
|
cd /newroot |
||||||
|
pivot_root . old |
||||||
|
|
||||||
|
# initialize basic required POSIX-standard additional mounts |
||||||
|
mount -t proc proc /proc |
||||||
|
mount -t devtmpfs devtmpfs /dev |
||||||
|
mkdir -p /dev/pts |
||||||
|
mount -t devpts devpts /dev/pts |
||||||
|
mount -t proc proc /proc |
||||||
|
mount -t sysfs sysfs /sys |
||||||
|
|
||||||
|
# re-execute the main script for the 2nd time, causing it to go back to the main flow |
||||||
|
# (but this time already inside the newly created namespace) |
||||||
|
reexecute |
||||||
|
|
||||||
|
# after the main flow terminates and the namespace exist, post_commit_root is executed - be sure to look at it |
||||||
|
} |
||||||
|
|
||||||
|
if [ "$1" = "build_inside_namespace" ] |
||||||
|
then |
||||||
|
build_inside_namespace |
||||||
|
exit |
||||||
|
fi |
Loading…
Reference in new issue