Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No exit when union_helper not found #99

Merged
merged 8 commits into from
Jul 7, 2023
23 changes: 23 additions & 0 deletions test/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,28 @@ test_dev()
[ -s target ]
}

## This test is checking if try works when mergerfs/unionfs are not present (but also not necessary)
test_echo_no_unionfs_mergerfs()
{
local try_workspace=$1
cd "$try_workspace/"

## Create a new /bin and /usr/bin without mergerfs and unionfs
new_bin_dir=$(mktemp -d)
mkdir "$new_bin_dir/usr"
cp -rs /usr/bin "$new_bin_dir/usr/bin"

## Delete mergerfs and unionfs and set the new PATH to the temporary directory
rm -f "$new_bin_dir/usr/bin/mergerfs" 2>/dev/null
rm -f "$new_bin_dir/usr/bin/unionfs" 2>/dev/null
export PATH="$new_bin_dir/usr/bin"

cd $(mktemp -d)
echo hi >expected
"$try" -y "echo hi" >target 2>/dev/null
diff -q expected target
}

# a test that deliberately fails (for testing CI changes)
test_fail()
{
Expand Down Expand Up @@ -424,6 +446,7 @@ if [ "$#" -eq 0 ]; then
run_test test_mkdir_on_file
run_test test_ignore_flag
run_test test_dev
run_test test_echo_no_unionfs_mergerfs

# uncomment this to force a failure
# run_test test_fail
Expand Down
54 changes: 31 additions & 23 deletions try
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ try() {
export SANDBOX_DIR
mkdir -p "$SANDBOX_DIR/upperdir" "$SANDBOX_DIR/workdir" "$SANDBOX_DIR/temproot"

## Find all the directories and mounts that need to be mounted
export DIRS_AND_MOUNTS=$(mktemp)
ls / | sed -e 's/^/\//' >"$DIRS_AND_MOUNTS"
findmnt --real -r -o target -n >>"$DIRS_AND_MOUNTS"
sort -u -o "$DIRS_AND_MOUNTS" "$DIRS_AND_MOUNTS"

# we will overlay-mount each root directory separately (instead of all at once) because some directories cannot be overlayed
# so we set up the mount points now
#
Expand All @@ -61,7 +67,7 @@ try() {
# -r: raw output
# -o target: only print the mount target
# then we want to exclude the root partition "/"
for mountpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$")
for mountpoint in $(cat "$DIRS_AND_MOUNTS")
do
## Only make the directory if the original is a directory too
if [ -d "$mountpoint" ]
Expand Down Expand Up @@ -118,8 +124,15 @@ autodetect_union_helper() {
fi
}

# Detect if union_helper is set, if not, we try to autodetect them
if [ -z "$union_helper" ]
then
## Try to detect the union_helper (the variable could still be empty afterwards).
union_helper="$(autodetect_union_helper)"
fi

# actually mount the overlays
for mountpoint in /* $(findmnt --real -r -o target -n)
for mountpoint in $(cat "$DIRS_AND_MOUNTS")
do
## We are not interested in mounts that are not directories
if [ ! -d "$mountpoint" ]
Expand All @@ -140,18 +153,6 @@ do
# If mounting everything normally fails, we try using either using mergerfs or unionfs to mount them.
if [ "$?" -ne 0 ]
then
# Detect if union_helper is set, if not, we try to autodetect them
if [ -z ${union_helper+x} ]
then
union_helper="$(autodetect_union_helper)"
if [ -z "$union_helper" ]
then
printf "%s: Failed to mount overlayfs normally, mergerfs or unionfs not found for $mountpoint, see $try_mount_log\n" "$TRY_COMMAND" >&2
exit 1
fi
fi


## If the overlay failed, it means that there is a nested mount inside the target mount, e.g., both `/home` and `/home/user/mnt` are mounts.
## To address this, we use unionfs/mergerfs (they support the same functionality) to show all mounts under the target mount as normal directories.
## Then we can normally make the overlay on the new union directory.
Expand All @@ -162,15 +163,22 @@ do
## We should try to investigate either:
## 1. Not doing another overlay if we have done it for a parent directory (we can keep around a list of overlays and skip if we are in a child)
## 2. Do one unionfs+overlay at the root `/` once and be done with it!
merger_dir=$(mktemp -d)

## Create a union directory
"$union_helper" $mountpoint $merger_dir 2>> "$try_mount_log" ||
printf "%s: Warning: Failed to mount $mountpoint via $union_helper, see \"$try_mount_log\"\n" "$TRY_COMMAND" >&2

## Make the overlay on the union directory which works as a lowerdir for overlay
make_overlay "$SANDBOX_DIR" "$merger_dir" "$mountpoint" 2>> "$try_mount_log" ||
printf "%s: Warning: Failed mounting $mountpoint as an overlay via $union_helper, see \"$try_mount_log\"\n" "$TRY_COMMAND" >&2

if [ -z "$union_helper" ]
then
## We can ignore this mountpoint, if the user program tries to use it, it will crash, but if not we can run normally
printf "%s: Warning: Failed mounting $mountpoint as an overlay and mergerfs or unionfs not set and could not be found, see \"$try_mount_log\"\n" "$TRY_COMMAND" >&2
else
merger_dir=$(mktemp -d)

## Create a union directory
"$union_helper" $mountpoint $merger_dir 2>> "$try_mount_log" ||
printf "%s: Warning: Failed mounting $mountpoint via $union_helper, see \"$try_mount_log\"\n" "$TRY_COMMAND" >&2

## Make the overlay on the union directory which works as a lowerdir for overlay
make_overlay "$SANDBOX_DIR" "$merger_dir" "$mountpoint" 2>> "$try_mount_log" ||
printf "%s: Warning: Failed mounting $mountpoint as an overlay via $union_helper, see \"$try_mount_log\"\n" "$TRY_COMMAND" >&2
fi
fi
done

Expand Down