Consolidated all squash functionality into a binary (squasher) Updated the 'cd' alias (multicd). Added -e to ldrc (to edit the user scripts)
175 lines
5.4 KiB
Bash
Executable file
175 lines
5.4 KiB
Bash
Executable file
#!/bin/bash
|
|
# Lackadaisical squashfs tools - Squasher
|
|
# Combined utility for make, mount, umount, and destroy operations.
|
|
|
|
BIN_DIR=$(dirname "$(readlink -f "$0")")
|
|
COMMAND="$1"
|
|
DIR="$2"
|
|
|
|
usage() {
|
|
echo "Usage: $0 {make|mount|umount|destroy} <directory>"
|
|
exit 1
|
|
}
|
|
|
|
if [[ -z "$COMMAND" || -z "$DIR" ]]; then
|
|
usage
|
|
fi
|
|
|
|
DIR=$(readlink -f "$DIR")
|
|
DIR_SHORT=$(basename "$DIR")
|
|
OVERLAY_ROOT="$(dirname "$DIR")/.squashfs/$DIR_SHORT"
|
|
OVERLAY_UPPER="$OVERLAY_ROOT/upper"
|
|
OVERLAY_LOWER="$OVERLAY_ROOT/lower"
|
|
OVERLAY_WORK="$OVERLAY_ROOT/work"
|
|
OVERLAY_TARG="$DIR"
|
|
|
|
case "$COMMAND" in
|
|
make)
|
|
if [[ ! -d "$DIR" ]]; then
|
|
echo "Error: Directory \"$DIR\" does not exist!"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Checking system requirements (FUSE, SquashFS, OverlayFS)..."
|
|
for fs in fuse squashfs overlay; do
|
|
if ! grep -q "$fs" /proc/filesystems; then
|
|
echo "Attempting to load $fs module..."
|
|
sudo modprobe "$fs" || { echo "Error: $fs is not supported."; exit 1; }
|
|
fi
|
|
done
|
|
|
|
DIRSIZE=$(du -sh "$DIR" | cut -f1)
|
|
RECREATE=false
|
|
mkdir -p "$OVERLAY_ROOT"
|
|
|
|
if [[ -f "${OVERLAY_ROOT}.img" ]]; then
|
|
echo "Existing image found, updating..."
|
|
"$0" mount "$DIR"
|
|
DIRSIZE=$(du -sh "$DIR" | cut -f1)
|
|
RECREATE=true
|
|
fi
|
|
|
|
echo "Compressing \"$DIR\"..."
|
|
sudo mksquashfs "$DIR" "${OVERLAY_ROOT}.img.1" -noappend -comp xz || exit 1
|
|
|
|
if [[ "$RECREATE" == "true" ]]; then
|
|
echo "Cleaning up old layers..."
|
|
"$0" umount "$DIR"
|
|
if [[ -n "$OVERLAY_ROOT" && "$OVERLAY_ROOT" != "/" ]]; then
|
|
sudo rm -rf "$OVERLAY_UPPER" "$OVERLAY_LOWER" "$OVERLAY_WORK"
|
|
rm -f "${OVERLAY_ROOT}.img"
|
|
fi
|
|
fi
|
|
|
|
mv "${OVERLAY_ROOT}.img.1" "${OVERLAY_ROOT}.img"
|
|
mkdir -p "$OVERLAY_UPPER" "$OVERLAY_LOWER" "$OVERLAY_WORK" "$OVERLAY_TARG"
|
|
|
|
sudo rm -rf "$DIR"
|
|
mkdir -p "$DIR"
|
|
touch "$DIR/.needs_mount"
|
|
|
|
echo "-------------------------------------------------------------------------"
|
|
echo "Storage Stats:"
|
|
echo " Original size: $DIRSIZE"
|
|
echo " Compressed: $(du -sh "${OVERLAY_ROOT}.img" | cut -f1)"
|
|
echo "-------------------------------------------------------------------------"
|
|
|
|
SERVICE_CONTENT="[Unit]
|
|
Description=SquashFS Mount for %I
|
|
After=local-fs.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
RemainAfterExit=yes
|
|
ExecStart=${BIN_DIR}/squasher mount %I
|
|
ExecStop=${BIN_DIR}/squasher umount %I
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target"
|
|
|
|
echo "$SERVICE_CONTENT" | sudo tee /etc/systemd/system/squash-mount@.service > /dev/null
|
|
sudo systemctl daemon-reload
|
|
|
|
ESC_PATH=$(systemd-escape -p "$DIR")
|
|
SERVICE_NAME="squash-mount@$ESC_PATH.service"
|
|
|
|
read -p "Enable auto-mount service ($SERVICE_NAME)? [y/N] " yn
|
|
if [[ "$yn" =~ ^[Yy]$ ]]; then
|
|
sudo systemctl enable --now "$SERVICE_NAME"
|
|
sudo systemctl stop "$SERVICE_NAME"
|
|
sudo systemctl start "$SERVICE_NAME"
|
|
else
|
|
echo "Manual mount command: sudo systemctl start $SERVICE_NAME"
|
|
fi
|
|
;;
|
|
|
|
mount)
|
|
if [[ ! -f "${OVERLAY_ROOT}.img" ]]; then
|
|
echo "Error: SquashFS image \"${OVERLAY_ROOT}.img\" not found." >&2
|
|
exit 1
|
|
fi
|
|
|
|
"$0" umount "$DIR" 2>/dev/null
|
|
mkdir -p "$OVERLAY_LOWER"
|
|
sudo mount "${OVERLAY_ROOT}.img" "$OVERLAY_LOWER" -t squashfs -o loop
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "Error: Failed to mount squashfs image." >&2
|
|
exit 1
|
|
fi
|
|
|
|
sudo mount -t overlay none "$OVERLAY_TARG" \
|
|
-o lowerdir="$OVERLAY_LOWER",upperdir="$OVERLAY_UPPER",workdir="$OVERLAY_WORK"
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "Error: Failed to mount overlay." >&2
|
|
sudo umount "$OVERLAY_LOWER" 2>/dev/null
|
|
exit 1
|
|
fi
|
|
echo "SquashFS filesystem is mounted and ready."
|
|
;;
|
|
|
|
umount)
|
|
sudo umount -l -R "$OVERLAY_TARG" 2>/dev/null
|
|
sudo umount -l -R "$OVERLAY_LOWER" 2>/dev/null
|
|
|
|
if mountpoint -q "$OVERLAY_TARG" || mountpoint -q "$OVERLAY_LOWER"; then
|
|
echo "Warning: Filesystem is still mounted. Check for open processes."
|
|
exit 1
|
|
fi
|
|
echo "SquashFS filesystem has been unmounted."
|
|
;;
|
|
|
|
destroy)
|
|
if [[ ! -f "$DIR/.needs_mount" ]]; then
|
|
if ! mountpoint -q "$DIR"; then
|
|
echo "Error: $DIR is not a SquashFS directory."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
ESC_PATH=$(systemd-escape -p "$DIR")
|
|
SERVICE_NAME="squash-mount@$ESC_PATH.service"
|
|
|
|
echo "Disabling service ($SERVICE_NAME)..."
|
|
sudo systemctl stop "$SERVICE_NAME" 2>/dev/null
|
|
sudo systemctl disable "$SERVICE_NAME" 2>/dev/null
|
|
|
|
echo "Ensuring image is mounted to preserve data..."
|
|
"$0" mount "$DIR" 1>/dev/null 2>/dev/null
|
|
|
|
echo "Destroying image and restoring data..."
|
|
TEMP_DIR=$(mktemp -d /tmp/squash-dest.XXXXXXXX)
|
|
sudo rsync -aX "$DIR/" "$TEMP_DIR/" || { echo "Error: Failed to copy data."; exit 1; }
|
|
|
|
"$0" umount "$DIR"
|
|
sudo rm -rf "$DIR"
|
|
sudo mv "$TEMP_DIR" "$DIR"
|
|
sudo rm -rf "$OVERLAY_ROOT" "${OVERLAY_ROOT}.img"
|
|
|
|
echo "Success: SquashFS image destroyed and data restored to \"$DIR\"."
|
|
;;
|
|
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|