Last active
January 27, 2023 16:03
-
-
Save fortes/03846f4e896e5d86562c527387e82ec3 to your computer and use it in GitHub Desktop.
Mounting a pool of encrypted disks with rclone and mergerfs. See http://fortes.com/2018/rclone-and-mergerfs for details.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euf -o pipefail | |
# Removable drive names go here, separated by spaces | |
DRIVE_NAMES=(drive1 drive2 drive3) | |
# Removable and cloud drives are mounted in this local directory | |
DRIVE_MOUNT_ROOT="/media" | |
# Name of folder for root of encrypted storage on drives | |
ENCRYPTED_DIR_NAME="encrypted" | |
# Rclone remote name for pooled drives | |
RCLONE_POOL_NAME="encrypted_pool" | |
# Local path for mounting decrypted drive pool | |
DECRYPTED_MOUNT_PATH="/media/decrypted_pool" | |
# Helper for joining array items with `:` | |
function semicolon_join { local IFS=':'; echo "$*"; } | |
# Helper for unmounting on exit | |
function finish { | |
echo "Cleaning up and unmounting ..." | |
if mount | grep -q "$DECRYPTED_MOUNT_PATH"; then | |
echo "Unmounting merged rclone at $DECRYPTED_MOUNT_PATH" | |
fusermount -u "$DECRYPTED_MOUNT_PATH" > /dev/null 2>&1 | |
fi | |
if mount | grep -q "$DRIVE_MOUNT_ROOT/merged"; then | |
echo "Unmounting mergerfs at $DRIVE_MOUNT_ROOT/merged" | |
fusermount -u "$DRIVE_MOUNT_ROOT/merged" > /dev/null 2>&1 | |
fi | |
for name in "${CLOUD_DRIVE_NAMES[@]}"; do | |
mount_path="$DRIVE_MOUNT_ROOT/$name" | |
if mount | grep -q "$mount_path"; then | |
echo "Unmounting cloud remote $name" | |
fusermount -u "$mount_path" > /dev/null 2>&1 | |
fi | |
done | |
} | |
trap finish EXIT | |
VALID_MOUNTS=() | |
echo "Checking removable drives" | |
for name in "${DRIVE_NAMES[@]}"; do | |
mount_path="$DRIVE_MOUNT_ROOT/$name/$ENCRYPTED_DIR_NAME" | |
if [ -d "$mount_path" ]; then | |
VALID_MOUNTS+=("$mount_path") | |
fi | |
done | |
# Mount cloud drives, if any | |
CLOUD_DRIVE_NAMES=(gdrive) | |
echo "Checking cloud drives" | |
for name in "${CLOUD_DRIVE_NAMES[@]}"; do | |
mount_path="$DRIVE_MOUNT_ROOT/$name" | |
if ! mount | grep -q "rclone_$name"; then | |
echo "Mounting rclone remote $name ..." | |
rclone mount "$name:/$ENCRYPTED_DIR_NAME" "$mount_path" \ | |
--allow-other --read-only & | |
fi | |
VALID_MOUNTS+=("$mount_path") | |
done | |
echo "Found drives: ${VALID_MOUNTS[*]}" | |
echo "Mounting pool via mergerfs" | |
mergerfs "$(semicolon_join "${VALID_MOUNTS[@]}")" "$DRIVE_MOUNT_ROOT/merged" \ | |
-o defaults,allow_other,moveonenospc=true \ | |
-o fsname=encrypted_merged,category.create=epmfs,func.getattr=newest | |
echo "Mounting decrypted pool" | |
rclone mount "$RCLONE_POOL_NAME:/" "$DECRYPTED_MOUNT_PATH" \ | |
--allow-other --no-modtime & | |
echo "Mounting complete, hit Control-C to unmount and exit" | |
wait |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment