aboutsummaryrefslogtreecommitdiffstats
path: root/isocomp.sh
diff options
context:
space:
mode:
author Eric Hameleers <alien@slackware.com>2023-09-10 17:14:47 +0200
committer Eric Hameleers <alien@slackware.com>2023-09-10 17:14:47 +0200
commit672a9e4e7f160a65d1bdae49a65b734a2627a5f1 (patch)
tree3d57adf2cf43db2e55d0bf25cb4cb4a62a46b070 /isocomp.sh
parentfad898a736db76ea3159b668a5979a8efc8ef80a (diff)
downloadliveslak-672a9e4e7f160a65d1bdae49a65b734a2627a5f1.tar.gz
liveslak-672a9e4e7f160a65d1bdae49a65b734a2627a5f1.tar.xz
Several enhancements to LUKS containers and their support scripts
To name the most important: - The filesystem inside the containers is no longer limited to ext4 and can now be btrfs, ext2, ext4, f2fs, jfs or xfs. The scripts 'iso2usb.sh' and 'isocomp.sh' now support this filesystem choice via a new '-F' switch. - The 'upslak.sh' script can now extend the size of your home and persistence container files, in case you run out of storage there. - The internal functions used in 'iso2usb.sh' 'isocomp.sh' and 'upslak.sh' are mostly unified now, and I intend to split all functions off into a separate file which makes maintenance as well as adding new functionaliy easier. - The 'upslak.sh' script will now create a 'kernelmodules' squashfs module and copies it to liveslak's 'addons' directory after updating the boot kernel on the USB stick and the kernel-modules inside the initrd image. This way, you no longer end up with a broken Live OS if you forgot to install a Slackware kernel-modules package inside the persistent Live OS prior to running 'upslak.sh' with the '-k' and '-m' parameters. In addition, the README.txt was updated with these enhancements so that the liveslak documentation is again completely up to date.
Diffstat (limited to 'isocomp.sh')
-rw-r--r--isocomp.sh252
1 files changed, 198 insertions, 54 deletions
diff --git a/isocomp.sh b/isocomp.sh
index 7b361d5..ddb431b 100644
--- a/isocomp.sh
+++ b/isocomp.sh
@@ -50,6 +50,10 @@ VERSION=""
DEFEXT=".icc"
CNTEXT="${DEFEXT}"
+# Default filesystem for devices/containers:
+DEF_FS="ext4"
+FSYS="${DEF_FS}"
+
# Default mount point for a LUKS container if not specified:
DEFMNT="/home"
LUKSMNT=""
@@ -71,8 +75,10 @@ LIVESLAKROOT=""
# Define ahead of time, so that cleanup knows about them:
IMGDIR=""
ISOMNT=""
+CNTDEV=""
CNTMNT=""
EXTENSION=""
+LODEV=""
PERSISTENCE=""
# Minimim free space (in MB) we want to have left in any partition
@@ -85,14 +91,14 @@ MINFREE=${MINFREE:-10}
COMPR="xz --check=crc32"
# These tools are required by the script, we will check for their existence:
-REQTOOLS="cpio cryptsetup fsck gzip isoinfo lsblk resize2fs unsquashfs xz zstd"
+REQTOOLS="cpio cryptsetup fsck gzip isoinfo lsblk unsquashfs xz zstd"
#
# -- function definitions --
#
# Clean up in case of failure:
-cleanup() {
+function cleanup() {
# Clean up by unmounting our loopmounts, deleting tempfiles:
echo "--- Cleaning up the staging area..."
# During cleanup, do not abort due to non-zero exit code:
@@ -103,7 +109,7 @@ cleanup() {
# In case of failure, only most recent LUKS mapped device is still open:
if mount | grep -q ${CNTDEV} ; then
umount -f ${CNTDEV}
- cryptsetup luksClose $(basename ${CNTFILE} ${CNTEXT})
+ cryptsetup luksClose $(basename ${CNTDEV})
losetup -d ${LODEV}
fi
fi
@@ -116,7 +122,7 @@ cleanup() {
trap 'echo "*** $0 FAILED at line $LINENO ***"; cleanup; exit 1' ERR INT TERM
# Show the help text for this script:
-showhelp() {
+function showhelp() {
cat <<EOT
#
# Purpose: enhance the functionality when booting a Slackware Live ISO file.
@@ -146,10 +152,14 @@ cat <<EOT
# (filename extension must be '${CNTEXT}'!).
# -x|--extend <fullpath> Full path to existing (encrypted) container
# file that you want to extend in size
-# (filename needs to end in '${CNTEXT}'!).
# Limitations:
-# - container needs to be LUKS encrypted, and
-# - internal filesystem needs to be ext{2,3,4}.
+# - container needs to be LUKS encrypted.
+# - filename extension needs to be '${CNTEXT}'.
+# Supported filesystems inside container:
+# - $(resizefs).
+# -F|--filesystem <fs> Specify filesystem to create when formatting
+# devices/containers. Defaults to '${DEF_FS}',
+# Choices are $(createfs).
# -L|--lcsize <size|perc> Size of LUKS encrypted /home ; value is the
# requested size of the container in kB, MB, GB,
# or as a percentage of free space
@@ -170,7 +180,7 @@ EOT
} # End of showhelp()
# Show some common usage examples:
-showexamples() {
+function showexamples() {
cat <<EOT
#
# Some common usage examples for $(basename $0)
@@ -182,8 +192,8 @@ cat <<EOT
# Create a 1GB encrypted persistence container:
# ./$(basename $0) -p /run/media/<user>/Ventoy/myfiles/persistence.icc -P 1G
#
-# Create a 4GB encrypted home:
-# ./$(basename $0) -l /run/media/<user>/Ventoy/somedir/lukscontainers.icc -L 4000M -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+# Create a 4GB encrypted home with btrfs filesystem:
+# ./$(basename $0) -l /run/media/<user>/Ventoy/somedir/lukscontainers.icc -L 4000M -F btrfs -i /run/media/<user>/Ventoy/slackware64-live-current.iso
#
# Increase the size of that encrypted home container with another 2GB:
# ./$(basename $0) -x /run/media/<user>/Ventoy/somedir/lukscontainers.icc -X 2G -i /run/media/<user>/Ventoy/slackware64-live-current.iso
@@ -197,8 +207,110 @@ cat <<EOT
EOT
} # End of showexamples()
+# Create a filesystem on a partition with optional label:
+function createfs () {
+ MYDEV="${1}"
+ MYFS="${2:-'ext4'}"
+ MYLABEL="${3}"
+
+ if [ -n "${MYLABEL}" ]; then
+ case "${MYFS}" in
+ fs2s) MYLABEL="-l ${MYLABEL}" ;;
+ *) MYLABEL="-L ${MYLABEL}" ;;
+ esac
+ fi
+
+ if [ -z "${MYDEV}" ]; then
+ # Without arguments given, reply with list of supported fs'es:
+ echo "btrfs,ext2,ext4,f2fs,jfs,xfs"
+ return
+ fi
+ case "${MYFS}" in
+ btrfs) mkfs.btrfs -f -d single -m single ${MYLABEL} ${MYDEV}
+ ;;
+ ext2) mkfs.ext2 -F -F ${MYLABEL} ${MYDEV}
+ # Tune the ext2 filesystem:
+ tune2fs -m 0 -c 0 -i 0 ${MYDEV}
+ ;;
+ ext4) mkfs.ext4 -F -F ${MYLABEL} ${MYDEV}
+ # Tune the ext4 filesystem:
+ tune2fs -m 0 -c 0 -i 0 ${MYDEV}
+ ;;
+ f2fs) mkfs.f2fs ${MYLABEL} -f ${MYDEV}
+ ;;
+ jfs) mkfs.jfs -q ${MYDEV}
+ ;;
+ xfs) mkfs.xfs -f ${MYDEV}
+ ;;
+ *) echo "*** Unsupported filesystem '${MYFS}'!"
+ cleanup
+ exit 1
+ ;;
+ esac
+} # End of createfs()
+
+# Resize the filesystem on a block device:
+function resizefs() {
+ local MYDEV="${1}"
+
+ if [ -z "${MYDEV}" ]; then
+ # Without arguments given, reply with list of supported fs'es:
+ echo "btrfs,ext2,ext4,f2fs,jfs,xfs"
+ return
+ fi
+
+ # Determine the current filesystem for the block device:
+ local MYFS=$(lsblk -n -o FSTYPE ${MYDEV})
+ if [ -z "${MYFS}" ]; then
+ echo "*** Failed to resize filesystem on device '${MYDEV}'!"
+ echo "*** No filesystem found."
+ cleanup
+ exit 1
+ fi
+
+ local TMPMNT=$(mktemp -d -p /tmp -t alienres.XXXXXX)
+ if [ ! -d $TMPMNT ]; then
+ echo "*** Failed to create temporary mount for the filesystem resize!"
+ cleanup
+ exit 1
+ else
+ chmod 711 ${TMPMNT}
+ fi
+
+ # Mount the block device prior to the resize
+ # (btrfs, jfs and xfs do not support offline resize):
+ mount -o rw -t ${MYFS} ${MYDEV} ${TMPMNT}
+
+ # Resize the filesystem to occupy the full new device capacity:
+ case "${MYFS}" in
+ btrfs) btrfs filesystem resize max ${TMPMNT}
+ ;;
+ ext*) resize2fs ${MYDEV}
+ ;;
+ f2fs) resize.f2fs ${MYDEV}
+ ;;
+ jfs) mount -o remount,resize,rw ${TMPMNT}
+ ;;
+ xfs) xfs_growfs -d ${TMPMNT}
+ ;;
+ *) echo "*** Unsupported filesystem '${MYFS}'!"; exit 1
+ ;;
+ esac
+
+ if [ ! $? ]; then
+ echo "*** Failed to resize '${MYFS}'filesystem on device '${MYDEV}'!"
+ cleanup
+ exit 1
+ else
+ # Un-mount the device again:
+ sync
+ umount ${TMPMNT}
+ rmdir ${TMPMNT}
+ fi
+} # End of checkfs()
+
# Uncompress the initrd based on the compression algorithm used:
-uncompressfs () {
+function uncompressfs () {
if $(file "${1}" | grep -qi ": gzip"); then
gzip -cd "${1}"
elif $(file "${1}" | grep -qi ": XZ"); then
@@ -206,19 +318,21 @@ uncompressfs () {
fi
} # End of uncompressfs()
-# Read configuration data from the initrd inside the ISO:
-read_initrd() {
+# Read configuration data from the initrd inside the ISO,
+# after it has been extracted into a directory:
+function read_initrddir() {
local IMGDIR="$1"
+ local INITVARS="$2"
cd ${IMGDIR}
# Read the values of liveslak template variables in the init script:
- for TEMPLATEVAR in DISTRO LIVEMAIN MARKER MEDIALABEL ; do
+ for TEMPLATEVAR in ${INITVARS} ; do
eval $(grep "^ *${TEMPLATEVAR}=" ./init |head -1)
done
-} # End read_initrd()
+} # End of read_initrddir()
# Extract the initrd:
-extract_initrd() {
+function extract_initrd() {
local IMGFILE="$1"
local IMGDIR=$(mktemp -d -p /tmp -t alienimg.XXXXXX)
if [ ! -d $IMGDIR ]; then
@@ -236,21 +350,21 @@ extract_initrd() {
} # End of extract_initrd()
# Determine size of a mounted partition (in MB):
-get_part_mb_size() {
+function get_part_mb_size() {
local MYSIZE
MYSIZE=$(df -P -BM ${1} |tail -n -1 |tr -s '\t' ' ' |cut -d' ' -f2)
echo "${MYSIZE%M}"
} # End of get_part_mb_size()
# Determine free space of a mounted partition (in MB):
-get_part_mb_free() {
+function get_part_mb_free() {
local MYSIZE
MYSIZE=$(df -P -BM ${1} |tail -n -1 |tr -s '\t' ' ' |cut -d' ' -f4)
echo "${MYSIZE%M}"
} # End of get_part_mb_free()
# Determine requested container size in MB (allow for '%|k|K|m|M|g|G' suffix):
-cont_mb() {
+function cont_mb() {
local MYSIZE="$1"
case "${MYSIZE: -1}" in
"%") MYSIZE="$(( $PARTFREE * ${MYSIZE%\%} / 100 ))" ;;
@@ -266,7 +380,7 @@ cont_mb() {
} # End of cont_mb()
# Expand existing encrypted container file:
-expand_container() {
+function expand_container() {
local MYPART="$1" # disk partition
local MYINC="$2" # requested increase ('%|k|K|m|M|g|G' suffix)
local MYFILE="$3" # full path to ${CNTEXT} containerfile
@@ -289,29 +403,47 @@ expand_container() {
# Append random bytes to the end of the container file:
dd if=/dev/urandom of=${MYFILE} bs=1M count=${MYINC} oflag=append conv=notrunc 2>/dev/null
- # Unlock the LUKS encrypted container:
- MYMAP=$(basename ${MYFILE} ${CNTEXT})
- echo "--- Unlocking the LUKS container requires your passphrase..."
- until cryptsetup luksOpen ${MYFILE} ${MYMAP} ; do
- echo ">>> Did you type an incorrect passphrases?"
- read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
- done
+ # Setup a loopback device that we can use with or without cryptsetup:
+ LODEV=$(losetup -f)
+ losetup $LODEV ${MYFILE}
+
+ if cryptsetup isLuks ${LODEV} ; then
+ # Unlock LUKS encrypted container first:
+ MYMAP=$(basename ${MYFILE} ${CNTEXT})
+ CNTDEV=/dev/mapper/${MYMAP}
+ echo "--- Unlocking the LUKS container requires your passphrase..."
+ until cryptsetup luksOpen ${LODEV} ${MYMAP} ; do
+ echo ">>> Did you type an incorrect passphrases?"
+ read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
+ done
+ else
+ # The loopmounted block device for the un-encrypted container:
+ CNTDEV=${LODEV}
+ fi
# Run fsck so the filesystem is clean before we resize it:
- fsck -fvy /dev/mapper/${MYMAP}
+ fsck -fvy ${CNTDEV}
# Resize the filesystem to occupy the full new size:
- resize2fs /dev/mapper/${MYMAP}
+ resizefs ${CNTDEV}
# Just to be safe:
- fsck -fvy /dev/mapper/${MYMAP}
+ fsck -fvy ${CNTDEV}
+
+ # Don't forget to clean up after ourselves:
+ if cryptsetup isLuks ${LODEV} ; then
+ cryptsetup luksClose ${MYMAP}
+ fi
+ losetup -d ${LODEV} || true
+
} # End of expand_container()
# Create container file in the empty space of the partition
-create_container() {
- CNTPART=$1 # partition containing the ISO
- CNTSIZE=$2 # size of the container file to create
- CNTFILE=$3 # ${CNTEXT} filename with full path
- CNTENCR=$4 # 'none' or 'luks'
- CNTUSED=$5 # 'persistence', '/home' or custom mountpoint
+function create_container() {
+ local CNTPART=$1 # partition containing the ISO
+ local CNTSIZE=$2 # size of the container file to create
+ local CNTFILE=$3 # ${CNTEXT} filename with full path
+ local CNTENCR=$4 # 'none' or 'luks'
+ local CNTUSED=$5 # 'persistence', '/home' or custom mountpoint
+ local MYMAP
# Create a container file or re-use previously created one:
if [ -f ${CNTFILE} ]; then
@@ -346,14 +478,21 @@ create_container() {
exit 1
fi
- echo "--- Creating ${CNTSIZE} MB container file using 'dd if=/dev/urandom', patience please..."
+ echo "--- Creating ${CNTSIZE} MB container file '$(basename =${CNTFILE})' using 'dd if=/dev/urandom', patience please..."
mkdir -p $(dirname "${CNTFILE}")
- # Create a sparse file (not allocating any space yet):
- dd of=${CNTFILE} bs=1M count=0 seek=$CNTSIZE 2>/dev/null
+ if [ $? ]; then
+ # Create a sparse file (not allocating any space yet):
+ dd of=${CNTFILE} bs=1M count=0 seek=$CNTSIZE 2>/dev/null
+ else
+ echo "*** Failed to create directory for the container file!"
+ cleanup
+ exit 1
+ fi
# Setup a loopback device that we can use with cryptsetup:
LODEV=$(losetup -f)
losetup $LODEV ${CNTFILE}
+ MYMAP=$(basename ${CNTFILE} ${CNTEXT})
if [ "${CNTENCR}" = "luks" ]; then
# Format the loop device with LUKS:
echo "--- Encrypting the container file with LUKS; takes SOME time..."
@@ -364,26 +503,24 @@ create_container() {
done
# Unlock the LUKS encrypted container:
echo "--- Unlocking the LUKS container requires your passphrase again..."
- until cryptsetup luksOpen $LODEV $(basename ${CNTFILE} ${CNTEXT}) ; do
+ until cryptsetup luksOpen $LODEV ${MYMAP} ; do
echo ">>> Did you type an incorrect passphrases?"
read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
done
- CNTDEV=/dev/mapper/$(basename ${CNTFILE} ${CNTEXT})
+ CNTDEV=/dev/mapper/${MYMAP}
# Now we allocate blocks for the LUKS device. We write encrypted zeroes,
# so that the file looks randomly filled from the outside.
# Take care not to write more bytes than the internal size of the container:
- echo "--- Writing random data to encrypted container; takes LONG time..."
+ echo "--- Writing ${CNTSIZE} MB of random data to encrypted container; takes LONG time..."
CNTIS=$(( $(lsblk -b -n -o SIZE $(readlink -f ${CNTDEV})) / 512))
- dd if=/dev/zero of=${CNTDEV} bs=512 count=${CNTIS} 2>/dev/null || true
+ dd if=/dev/zero of=${CNTDEV} bs=512 count=${CNTIS} status=progress || true
else
- CNTDEV=$LODEV
# Un-encrypted container files remain sparse.
+ CNTDEV=$LODEV
fi
# Format the now available block device with a linux fs:
- mkfs.ext4 ${CNTDEV}
- # Tune the ext4 filesystem:
- tune2fs -m 0 -c 0 -i 0 ${CNTDEV}
+ createfs ${CNTDEV} ${FSYS}
if [ "${CNTUSED}" == "${DEFMNT}" ]; then
# Copy the original /home content into the container.
@@ -415,7 +552,7 @@ create_container() {
} # End of create_container()
-read_config() {
+function read_isoconfig() {
local MYISO="${1}"
# Read ISO customization from the .cfg file if it exists:
if [ -f "${MYISO%.iso}.cfg" ]; then
@@ -429,9 +566,9 @@ read_config() {
fi
done
fi
-} # End of read_config()
+} # End of read_isoconfig()
-write_config() {
+function write_isoconfig() {
local MYISO="${1}"
# Write updated customization into the ISO .cfg:
echo "# Liveslak ISO configuration file for ${VERSION}" > ${MYISO%.iso}.cfg 2>/dev/null
@@ -448,7 +585,7 @@ write_config() {
fi
done
fi
-} # End of write_config()
+} # End of write_isoconfig()
#
# -- end of function definitions --
@@ -500,6 +637,10 @@ while [ ! -z "$1" ]; do
EXTENSION="$(cd "$(dirname "$2")"; pwd)/$(basename "$2")"
shift 2
;;
+ -F|--filesystem)
+ FSYS="$2"
+ shift 2
+ ;;
-L|--lcsize)
LUKSSIZE="$2"
shift 2
@@ -528,6 +669,9 @@ if [ "$(id -u)" != "0" ]; then
exit 1
fi
+# Add required filesystem tools:
+REQTOOLS="${REQTOOLS} mkfs.${FSYS}"
+
# Are all the required tools present?
PROG_MISSING=""
for PROGN in ${REQTOOLS} ; do
@@ -670,10 +814,10 @@ fi
# Collect data from the USB initrd:
IMGDIR=$(extract_initrd ${ISOMNT}/boot/initrd.img)
-read_initrd ${IMGDIR}
+read_initrddir ${IMGDIR} "DISTRO LIVEMAIN MARKER MEDIALABEL"
# Collect customization parameters for the ISO:
-read_config ${SLISO}
+read_isoconfig ${SLISO}
# Determine where in LUKSVOL the /home is defined.
# The LUKSVOL value looks like:
@@ -763,7 +907,7 @@ if [ ${#CONTAINERS[@]} -gt 0 ]; then
fi
# Write customization parameters for the ISO to disk:
-write_config ${SLISO}
+write_isoconfig ${SLISO}
# Write ISO version to the liveslak rootdir if that exists:
if [ -d "${USBMNT}/${LIVESLAKROOT}" ]; then