Added cdz check parameter for use in multicd (normal cd, squash cd and cdz).
Consolidated all squash functionality into a binary (squasher) Updated the 'cd' alias (multicd). Added -e to ldrc (to edit the user scripts)
This commit is contained in:
parent
83324dd0f7
commit
10d81b7e5b
8 changed files with 288 additions and 271 deletions
14
README.md
14
README.md
|
|
@ -45,11 +45,13 @@ These are the included binaries and utilities:
|
|||
NO_ARCHIVEMOUNT=1. The standard script supports zip,
|
||||
tarballs, and rar archives. We recommend relying on
|
||||
archivemount` if you have it installed.
|
||||
- SquashFS tools (mount/umount/make/destroy-squash-image):
|
||||
Use "--check" to only check if a file is an archive.
|
||||
It returns 0 if it is, 1 otherwise.
|
||||
- SquashFS tools (squasher):
|
||||
These convenient set of tools allow you to easily create
|
||||
XZ-compressed SquashFS images from existing folders to save
|
||||
disk space. The resulting folder is still writable since it is
|
||||
mounted using an 'overlay' system. You can use 'make-squash-image'
|
||||
mounted using an 'overlay' system. You can use 'squasher make'
|
||||
to compresses an existing folder. These folders are automatically
|
||||
mounted when you use 'cd' to navigate to them (via an alias).
|
||||
When using 'make-squash-image' on an already mounted folder, it will
|
||||
|
|
@ -57,12 +59,12 @@ These are the included binaries and utilities:
|
|||
SystemD service to auto-mount, however, you cam easily add auto-mount
|
||||
as a cron job. Here is a list of tools, they all take the same
|
||||
folder argument:
|
||||
> make-squash-image: Converts the folder into a hidden image
|
||||
> squasher make: Converts the folder into a hidden image
|
||||
on the same disk as the folder.
|
||||
> mount-squash-image: Sets up a mount for the XZ image alongside
|
||||
> squasher mount: Sets up a mount for the XZ image alongside
|
||||
directories for changes
|
||||
> umount-squash-image: Self-explanatory.
|
||||
> destroy-squash-image: Extracts the image and essentially reverts
|
||||
> squasher umount: Self-explanatory.
|
||||
> squasher destroy: Extracts the image and essentially reverts
|
||||
everything. File changes are kept, however.
|
||||
- editx:
|
||||
Uses your standard CLI editor to create/modify a
|
||||
|
|
|
|||
94
cdz
94
cdz
|
|
@ -1,57 +1,122 @@
|
|||
#!/usr/bin/env bash
|
||||
# Usage: cdz <archive>
|
||||
# Usage: cdz [--check] <archive>
|
||||
|
||||
if [[ $LD_INTERNAL -ne 1 ]]; then
|
||||
if [[ $LD_INTERNAL -ne 1 ]]
|
||||
then
|
||||
LD_INTERNAL=1
|
||||
. $(dirname $(realpath $0))/daisy.source
|
||||
fi
|
||||
|
||||
is_archive()
|
||||
{
|
||||
local file="$1"
|
||||
local mime_type=$(file --mime-type -b "$file")
|
||||
|
||||
if [[ $mime_type == *"tar"* || $file == *.tar* || $mime_type == "application/zip" || $mime_type == "application/x-rar" ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v archivemount >/dev/null 2>&1
|
||||
then
|
||||
local test_dir=$(mktemp -d /tmp/cdz_check.XXXXXXXX)
|
||||
local result=1
|
||||
if archivemount -o readonly "$file" "$test_dir" >/dev/null 2>&1
|
||||
then
|
||||
result=0
|
||||
umount "$test_dir"
|
||||
fi
|
||||
rmdir "$test_dir"
|
||||
return $result
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
check_mode=0
|
||||
if [[ "$1" == "--check" ]]
|
||||
then
|
||||
check_mode=1
|
||||
shift
|
||||
fi
|
||||
|
||||
target=$1
|
||||
if [[ -z "$target" ]]; then
|
||||
if [[ -z "$target" ]]
|
||||
then
|
||||
if [[ $check_mode -eq 0 ]]
|
||||
then
|
||||
echo "No target specified."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$target" ]]; then
|
||||
if [[ ! -f "$target" ]]
|
||||
then
|
||||
if [[ $check_mode -eq 0 ]]
|
||||
then
|
||||
echo "File not found: \"$target\""
|
||||
fi
|
||||
exit 2
|
||||
fi
|
||||
|
||||
target_abs=$(realpath "$target")
|
||||
name=$(basename "$target")
|
||||
|
||||
if is_archive "$target_abs"
|
||||
then
|
||||
if [[ $check_mode -eq 1 ]]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
if [[ $check_mode -eq 1 ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
mime_type=$(file --mime-type -b "$target_abs")
|
||||
echo "Unsupported archive type: $mime_type"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Proceed with extraction
|
||||
has_archivemount=$(command -v archivemount >/dev/null 2>&1; echo $?)
|
||||
|
||||
if [[ $has_archivemount -eq 0 && $NO_ARCHIVEMOUNT -ne 1 ]]; then
|
||||
if [[ $has_archivemount -eq 0 && $NO_ARCHIVEMOUNT -ne 1 ]]
|
||||
then
|
||||
use_mounter=1
|
||||
else
|
||||
use_mounter=0
|
||||
fi
|
||||
|
||||
mime_type=$(file --mime-type -b "$target")
|
||||
|
||||
mime_type=$(file --mime-type -b "$target_abs")
|
||||
comm1=(:)
|
||||
comm2=(echo "Unsupported archive type: $mime_type")
|
||||
comm3=(:)
|
||||
comm4=(:)
|
||||
comm5=(:)
|
||||
|
||||
if [[ $use_mounter -eq 1 ]]; then
|
||||
if [[ $use_mounter -eq 1 ]]
|
||||
then
|
||||
echo "Using archivemount..."
|
||||
comm2=(archivemount -o allow_root,use_ino "$target_abs")
|
||||
comm4=(cd ..)
|
||||
comm5=(umount)
|
||||
elif [[ $mime_type == *"tar"* || $target == *.tar* ]]; then
|
||||
elif [[ $mime_type == *"tar"* || $target_abs == *.tar* ]]
|
||||
then
|
||||
comm2=(tar xvf "$target_abs" -C)
|
||||
elif [[ $mime_type == "application/zip" ]]; then
|
||||
if command -v unzip >/dev/null 2>&1; then
|
||||
elif [[ $mime_type == "application/zip" ]]
|
||||
then
|
||||
if command -v unzip >/dev/null 2>&1
|
||||
then
|
||||
comm2=(unzip -q "$target_abs" -d)
|
||||
else
|
||||
comm1=(echo "unzip is missing")
|
||||
comm3=(exit 1)
|
||||
fi
|
||||
elif [[ $mime_type == "application/x-rar" ]]; then
|
||||
if command -v unrar >/dev/null 2>&1; then
|
||||
elif [[ $mime_type == "application/x-rar" ]]
|
||||
then
|
||||
if command -v unrar >/dev/null 2>&1
|
||||
then
|
||||
# unrar needs the directory as the last argument
|
||||
comm2=(unrar x -idq "$target_abs")
|
||||
else
|
||||
|
|
@ -63,7 +128,8 @@ fi
|
|||
dir=$(mktemp -d /tmp/extracted.XXXXXXXX)
|
||||
|
||||
"${comm1[@]}"
|
||||
if [[ ${comm2[0]} == "unrar" ]]; then
|
||||
if [[ ${comm2[0]} == "unrar" ]]
|
||||
then
|
||||
"${comm2[@]}" "$dir"
|
||||
else
|
||||
"${comm2[@]}" "$dir"
|
||||
|
|
|
|||
29
daisy.source
29
daisy.source
|
|
@ -80,10 +80,12 @@ LD_EDITORFILE="$LD_CONFIG_FOLDER/editor.src"
|
|||
LD_ESOURCEFILE="$LD_CONFIG_FOLDER/extra.src"
|
||||
touch $LD_ALIASFILE
|
||||
touch $LD_EDITORFILE
|
||||
touch $LD_ESOURCEFILE
|
||||
|
||||
ld_dbg echo "Sourced config contents:"
|
||||
ld_dbg cat $LD_ALIASFILE
|
||||
ld_dbg cat $LD_EDITORFILE
|
||||
ld_dbg cat $LD_ESOURCEFILE
|
||||
|
||||
# Source everything in the config folder
|
||||
function _daisy_source_configs
|
||||
|
|
@ -132,21 +134,29 @@ function daisy_wait_for_editor
|
|||
done
|
||||
}
|
||||
|
||||
function mountcd
|
||||
function multicd
|
||||
{
|
||||
cdpath="$@"
|
||||
if [[ $cdpath == '' ]];
|
||||
if [[ $cdpath == '' ]]
|
||||
then
|
||||
\cd
|
||||
return
|
||||
fi
|
||||
if [[ -f "$cdpath/.needs_mount" ]];
|
||||
|
||||
if cdz --check "$cdpath" >/dev/null 2>&1
|
||||
then
|
||||
mount-squash-image "$cdpath"
|
||||
cdz "$cdpath"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -f "$cdpath/.needs_mount" ]]
|
||||
then
|
||||
squasher mount "$cdpath"
|
||||
fi
|
||||
\cd "$cdpath"
|
||||
}
|
||||
|
||||
alias cd=mountcd
|
||||
alias cd=multicd
|
||||
|
||||
# Undocumented but internally used
|
||||
function daisy_editor
|
||||
|
|
@ -154,6 +164,7 @@ function daisy_editor
|
|||
editor=${LD_EDITOR:-$EDITOR};
|
||||
ld_dbg echo Opening $editor to edit file: $1
|
||||
$editor "$1"
|
||||
sleep 1
|
||||
daisy_wait_for_editor $editor "$1"
|
||||
}
|
||||
|
||||
|
|
@ -315,8 +326,12 @@ function daisy_reload
|
|||
|
||||
function ldrc
|
||||
{
|
||||
daisy_editor "$LD_SOURCE_FILE"
|
||||
LD_INTERNAL=0 source "$LD_SOURCE_FILE"
|
||||
ARG=$1
|
||||
SOURCE="$LD_SOURCE_FILE"
|
||||
[[ "$ARG" == "-e" ]] && SOURCE="$LD_ESOURCEFILE"
|
||||
|
||||
daisy_editor "$SOURCE"
|
||||
LD_INTERNAL=0 source "$SOURCE"
|
||||
}
|
||||
|
||||
enc_is_folder=0
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Lackadaisical squashfs tools - Destroy
|
||||
|
||||
DIR="$1"
|
||||
if [[ -z "$DIR" ]]; then
|
||||
echo "Usage: $0 <directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIR=$(readlink -f "$DIR")
|
||||
DIR_SHORT=$(basename "$DIR")
|
||||
BIN_DIR=$(dirname "$(readlink -f "$0")")
|
||||
|
||||
if [[ ! -f "$DIR/.needs_mount" ]]; then
|
||||
if ! mountpoint -q "$DIR"; then
|
||||
echo "Error: $DIR is not a SquashFS directory."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stop systemd service
|
||||
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
|
||||
|
||||
# Ensure it is mounted to copy merged data
|
||||
echo "Ensuring image is mounted to preserve data..."
|
||||
"$BIN_DIR/mount-squash-image" "$DIR" 1>/dev/null 2>/dev/null
|
||||
|
||||
echo "Destroying image and restoring data..."
|
||||
|
||||
# Atomic copy-out
|
||||
TEMP_DIR=$(mktemp -d /tmp/squash-dest.XXXXXXXX)
|
||||
sudo rsync -aX "$DIR/" "$TEMP_DIR/" || { echo "Error: Failed to copy data."; exit 1; }
|
||||
|
||||
# Unmount
|
||||
"$BIN_DIR/umount-squash-image" "$DIR"
|
||||
|
||||
# Restore original directory structure
|
||||
OVERLAY_ROOT="$(dirname "$DIR")/.squashfs/$DIR_SHORT"
|
||||
sudo rm -rf "$DIR"
|
||||
sudo mv "$TEMP_DIR" "$DIR"
|
||||
|
||||
# Final cleanup
|
||||
sudo rm -rf "$OVERLAY_ROOT" "${OVERLAY_ROOT}.img"
|
||||
|
||||
echo "Success: SquashFS image destroyed and data restored to \"$DIR\"."
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Lackadaisical squashfs tools
|
||||
# Allows you to create a modifiable squashfs-backed image for a folder
|
||||
|
||||
BIN_DIR=$(dirname "$(readlink -f "$0")")
|
||||
DIR="$1"
|
||||
|
||||
if [[ -z "$DIR" ]]; then
|
||||
echo "Usage: $0 <directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
DIR=$(readlink -f "$DIR")
|
||||
DIR_SHORT=$(basename "$DIR")
|
||||
DIRSIZE=$(du -sh "$DIR" | cut -f1)
|
||||
|
||||
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"
|
||||
RECREATE=false
|
||||
|
||||
mkdir -p "$OVERLAY_ROOT"
|
||||
|
||||
if [[ -f "${OVERLAY_ROOT}.img" ]]; then
|
||||
echo "Existing image found, updating..."
|
||||
"$BIN_DIR/mount-squash-image" "$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..."
|
||||
"$BIN_DIR/umount-squash-image" "$DIR"
|
||||
# Safety check before destructive RM
|
||||
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"
|
||||
|
||||
# Prepare overlay structure
|
||||
mkdir -p "$OVERLAY_UPPER" "$OVERLAY_LOWER" "$OVERLAY_WORK" "$OVERLAY_TARG"
|
||||
|
||||
# Reset original directory to mountpoint
|
||||
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 "-------------------------------------------------------------------------"
|
||||
|
||||
# SystemD Service Setup
|
||||
SERVICE_CONTENT="[Unit]
|
||||
Description=SquashFS Mount for %I
|
||||
After=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=${BIN_DIR}/mount-squash-image %I
|
||||
ExecStop=${BIN_DIR}/umount-squash-image %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 "Do you want to auto-enable the mount service ($SERVICE_NAME)? [y/N] " yn
|
||||
case $yn in
|
||||
[Yy]* )
|
||||
echo "Enabling and starting service..."
|
||||
sudo systemctl enable --now "$SERVICE_NAME"
|
||||
sudo systemctl stop "$SERVICE_NAME"
|
||||
sudo systemctl start "$SERVICE_NAME"
|
||||
;;
|
||||
* )
|
||||
echo "To enable the service manually, run: sudo systemctl enable --now $SERVICE_NAME"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "Your SquashFS-backed folder is ready for use."
|
||||
echo "To mount it manually, either cd into it or use mount-squash-image."
|
||||
echo ""
|
||||
echo "Should you wish to update the contents of the image with your changes made"
|
||||
echo "inside of the folder, simply run make-squash-image again on the same"
|
||||
echo "folder to update the image."
|
||||
echo
|
||||
echo "To disable auto-mounting upon cd, please remove the"
|
||||
echo ".needs_mount file to prevent that."
|
||||
echo
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Lackadaisical squashfs tools - Mount
|
||||
|
||||
DIR="$1"
|
||||
if [[ -z "$DIR" ]]; then
|
||||
echo "Usage: $0 <directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIR=$(readlink -f "$DIR")
|
||||
DIR_SHORT=$(basename "$DIR")
|
||||
BIN_DIR=$(dirname "$(readlink -f "$0")")
|
||||
|
||||
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"
|
||||
|
||||
if [[ ! -f "${OVERLAY_ROOT}.img" ]]; then
|
||||
echo "Error: SquashFS image \"${OVERLAY_ROOT}.img\" not found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Unmount existing first
|
||||
"$BIN_DIR/umount-squash-image" "$DIR" 2>/dev/null
|
||||
|
||||
# Mount lower squashfs image via loopback
|
||||
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
|
||||
|
||||
# Mount overlay
|
||||
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."
|
||||
175
squasher
Executable file
175
squasher
Executable file
|
|
@ -0,0 +1,175 @@
|
|||
#!/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
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Lackadaisical squashfs tools - Unmount
|
||||
|
||||
DIR="$1"
|
||||
if [[ -z "$DIR" ]]; then
|
||||
echo "Usage: $0 <directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIR=$(readlink -f "$DIR")
|
||||
DIR_SHORT=$(basename "$DIR")
|
||||
|
||||
OVERLAY_ROOT="$(dirname "$DIR")/.squashfs/$DIR_SHORT"
|
||||
OVERLAY_LOWER="$OVERLAY_ROOT/lower"
|
||||
OVERLAY_TARG="$DIR"
|
||||
|
||||
# Forcefully unmount both layers recursively
|
||||
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."
|
||||
exit 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue