summaryrefslogtreecommitdiffstats
path: root/iso2usb.sh
diff options
context:
space:
mode:
Diffstat (limited to 'iso2usb.sh')
-rw-r--r--iso2usb.sh142
1 files changed, 107 insertions, 35 deletions
diff --git a/iso2usb.sh b/iso2usb.sh
index 4228c56..ed6fec4 100644
--- a/iso2usb.sh
+++ b/iso2usb.sh
@@ -26,9 +26,14 @@ set -e
# Set to '1' if you want to ignore all warnings:
FORCE=0
+# By default, we use 'slhome.img' as the name of the LUKS home containerfile.
+DEF_SLHOME="slhome"
+SLHOME="${DEF_SLHOME}"
+
# By default, we use 'persistence' as the name of the persistence directory,
# or 'persistence.img' as the name of the persistence container:
-PERSISTENCE="persistence"
+DEF_PERSISTENCE="persistence"
+PERSISTENCE="${DEF_PERSISTENCE}"
# Default persistence type is a directory:
PERSISTTYPE="dir"
@@ -40,6 +45,7 @@ UNATTENDED=0
VERBOSE=0
# Variables to store content from an initrd we are going to refresh:
+OLDPERSISTENCE=""
OLDWAIT=""
OLDLUKS=""
@@ -52,10 +58,14 @@ DOLUKS=0
# We are NOT refreshing existing Live content by default:
REFRESH=0
+# These tools are required by the script, we will check for their existence:
+REQTOOLS="blkid cpio extlinux fdisk gdisk isoinfo mkdosfs sgdisk"
+
# Initialize more variables:
CNTBASE=""
CNTDEV=""
CNTFILE=""
+HLUKSSIZE=""
LUKSHOME=""
LODEV=""
@@ -64,6 +74,7 @@ IMGDIR=""
ISOMNT=""
CNTMNT=""
USBMNT=""
+US2MNT=""
# Compressor used on the initrd ("gzip" or "xz --check=crc32");
# Note that the kernel's XZ decompressor does not understand CRC64:
@@ -84,13 +95,14 @@ cleanup() {
# In case of failure, only the most recent device should still be open:
if mount |grep -q ${CNTDEV} ; then
umount -f ${CNTDEV}
- cryptsetup luksClose ${CNTBASE}
+ cryptsetup luksClose $(basename ${CNTBASE})
losetup -d ${LODEV}
fi
fi
[ -n "${ISOMNT}" ] && ( /sbin/umount -f ${ISOMNT} 2>/dev/null; rmdir $ISOMNT )
[ -n "${CNTMNT}" ] && ( /sbin/umount -f ${CNTMNT} 2>/dev/null; rmdir $CNTMNT )
[ -n "${USBMNT}" ] && ( /sbin/umount -f ${USBMNT} 2>/dev/null; rmdir $USBMNT )
+ [ -n "${US2MNT}" ] && ( /sbin/umount -f ${US2MNT} 2>/dev/null; rmdir $US2MNT )
[ -n "${IMGDIR}" ] && ( rm -rf $IMGDIR )
set -e
}
@@ -114,8 +126,11 @@ cat <<EOT
# -f|--force Ignore most warnings (except the back-out).
# -h|--help This help.
# -i|--infile <filename> Full path to the ISO image file.
+# -l|--lukshome <name> Custom path to the containerfile for your LUKS
+# encrypted /home ($SLHOME by default).
# -o|--outdev <filename> The device name of your USB drive.
-# -p|--persistence <dirname> Custom name of the 'persistence' directory.
+# -p|--persistence <name> Custom path to the 'persistence' directory
+# or containerfile ($PERSISTENCE by default).
# -r|--refresh Refresh the USB stick with the ISO content.
# No formatting, do not touch user content.
# -u|--unattended Do not ask any questions.
@@ -148,6 +163,7 @@ uncompressfs () {
read_initrd() {
IMGFILE="$1"
+ OLDPERSISTENCE=$(uncompressfs ${IMGFILE} |cpio -i --to-stdout init |grep "^PERSISTENCE" |cut -d '"' -f2 2>/dev/null)
OLDWAIT=$(uncompressfs ${IMGFILE} |cpio -i --to-stdout wait-for-root 2>/dev/null)
OLDLUKS=$(uncompressfs ${IMGFILE} |cpio -i --to-stdout luksdev 2>/dev/null)
}
@@ -181,11 +197,30 @@ update_initrd() {
if [ $REFRESH -eq 1 ]; then
echo "--- Refreshing Slackware initrd..."
WAIT="$OLDWAIT"
+ if [ -n "$OLDLUKS" ]; then
+ echo "--- Detected LUKS container configuration:"
+ echo "$OLDLUKS" | sed 's/^/ /'
+ fi
echo "$OLDLUKS" >> luksdev
+ if [ "${PERSISTENCE}" != "${DEF_PERSISTENCE}" ]; then
+ # If the user specified a nonstandard persistence, use that:
+ echo "--- Updating persistence from '$OLDPERSISTENCE' to '$PERSISTENCE'"
+ sed -i -e "s,^PERSISTENCE=.*,PERSISTENCE=\"${PERSISTENCE}\"," init
+ elif [ "${PERSISTENCE}" != "${OLDPERSISTENCE}" ]; then
+ # The user did not specify persistence, re-use the retrieved value:
+ sed -i -e "s,^PERSISTENCE=.*,PERSISTENCE=\"${OLDPERSISTENCE}\"," init
+ echo "--- Re-use previous '$OLDPERSISTENCE' for persistence"
+ PERSISTENCE="${OLDPERSISTENCE}"
+ fi
else
- echo "--- Updating 'waitforroot' time from '$OLDWAIT' to '$WAIT':"
+ if [ "${PERSISTENCE}" != "${DEF_PERSISTENCE}" ]; then
+ # If the user specified a nonstandard persistence, use that:
+ echo "--- Updating persistence from '$DEF_PERSISTENCE' to '$PERSISTENCE'"
+ sed -i -e "s,^PERSISTENCE=.*,PERSISTENCE=\"${PERSISTENCE}\"," init
+ fi
fi
+ echo "--- Updating 'waitforroot' time from '$OLDWAIT' to '$WAIT'"
echo ${WAIT} > wait-for-root
if [ $DOLUKS -eq 1 -a -n "${LUKSHOME}" ]; then
@@ -198,7 +233,7 @@ update_initrd() {
echo "--- Compressing the initrd image again:"
chmod 0755 ${IMGDIR}
find . |cpio -o -H newc |$COMPR > ${IMGFILE}
- cd - 2>/dev/null
+ cd - 1>/dev/null
rm -rf $IMGDIR/*
} # End of update_initrd()
@@ -213,7 +248,7 @@ create_container() {
# Create a container file or re-use previously created one:
if [ -f $USBMNT/${CNTBASE}.img ]; then
CNTFILE="${CNTBASE}.img"
- CNTSIZE=$(( $(du -sk ${CNTFILE}) / 1024 ))
+ CNTSIZE=$(( $(du -sk $USBMNT/${CNTFILE} |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
echo "--- Keeping existing '${CNTFILE}' (size ${CNTSIZE} MB)."
return
fi
@@ -225,8 +260,8 @@ create_container() {
PARTFREE=${PARTFREE%M}
if [ $PARTFREE -lt 10 ]; then
- echo "** Free space on USB partition is less than 10 MB;"
- echo "** Not creating a container file!"
+ echo "*** Free space on USB partition is less than 10 MB;"
+ echo "*** Not creating a container file!"
exit 1
fi
@@ -243,16 +278,17 @@ create_container() {
esac
if [ $CNTSIZE -le 0 ]; then
- echo "** Container size must be larger than ZERO!"
- echo "** Check your '-c' commandline parameter."
+ echo "*** Container size must be larger than ZERO!"
+ echo "*** Check your '-c' commandline parameter."
exit 1
elif [ $CNTSIZE -ge $PARTFREE ]; then
- echo "** Not enough free space for container file!"
- echo "** Check your '-c' commandline parameter."
+ echo "*** Not enough free space for container file!"
+ echo "*** Check your '-c' commandline parameter."
exit 1
fi
echo "--- Creating ${CNTSIZE} MB container file using 'dd if=/dev/urandom', patience please..."
+ mkdir -p $USBMNT/$(dirname "${CNTBASE}")
CNTFILE="${CNTBASE}.img"
# Create a sparse file (not allocating any space yet):
dd of=$USBMNT/${CNTFILE} bs=1M count=0 seek=$CNTSIZE
@@ -263,11 +299,17 @@ create_container() {
if [ "${CNTENCR}" = "luks" ]; then
# Format the loop device with LUKS:
echo "--- Encrypting the container file with LUKS; enter 'YES' and a passphrase..."
- cryptsetup -y luksFormat $LODEV
+ until cryptsetup -y luksFormat $LODEV ; do
+ echo ">>> Did you type two different passphrases?"
+ read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
+ done
# Unlock the LUKS encrypted container:
echo "--- Unlocking the LUKS container requires your passphrase again..."
- cryptsetup luksOpen $LODEV ${CNTBASE}
- CNTDEV=/dev/mapper/${CNTBASE}
+ until cryptsetup luksOpen $LODEV $(basename ${CNTBASE}) ; 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 ${CNTBASE})
# 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:
@@ -305,7 +347,7 @@ create_container() {
# Don't forget to clean up after ourselves:
if [ "${CNTENCR}" = "luks" ]; then
- cryptsetup luksClose ${CNTBASE}
+ cryptsetup luksClose $(basename ${CNTBASE})
fi
losetup -d ${LODEV} || true
@@ -325,6 +367,8 @@ while [ ! -z "$1" ]; do
-c|--crypt)
HLUKSSIZE="$2"
DOLUKS=1
+ # Needs unsquashfs to extract the /home
+ REQTOOLS="${REQTOOLS} unsquashfs"
shift 2
;;
-f|--force)
@@ -339,6 +383,10 @@ while [ ! -z "$1" ]; do
SLISO="$(cd $(dirname $2); pwd)/$(basename $2)"
shift 2
;;
+ -l|--lukshome)
+ SLHOME="$2"
+ shift 2
+ ;;
-o|--outdev)
TARGET="$2"
shift 2
@@ -408,7 +456,7 @@ fi
# Are all the required not-so-common add-on tools present?
PROG_MISSING=""
-for PROGN in blkid cpio extlinux fdisk gdisk isoinfo mkdosfs sgdisk unsquashfs ; do
+for PROGN in ${REQTOOLS} ; do
if ! PATH="/sbin:$PATH" which $PROGN 1>/dev/null 2>/dev/null ; then
PROG_MISSING="${PROG_MISSING}-- $PROGN\n"
fi
@@ -508,7 +556,7 @@ if [ ! -d $ISOMNT ]; then
else
chmod 711 $ISOMNT
fi
-# USB mount:
+# USB mounts:
USBMNT=$(mktemp -d -p /mnt -t alienusb.XXXXXX)
if [ ! -d $USBMNT ]; then
echo "*** Failed to create a temporary mount point for the USB device!"
@@ -517,6 +565,14 @@ if [ ! -d $USBMNT ]; then
else
chmod 711 $USBMNT
fi
+US2MNT=$(mktemp -d -p /mnt -t alienus2.XXXXXX)
+if [ ! -d $US2MNT ]; then
+ echo "*** Failed to create a temporary mount point for the USB device!"
+ cleanup
+ exit 1
+else
+ chmod 711 $US2MNT
+fi
# Mount the Linux partition:
/sbin/mount -t auto ${TARGET}3 ${USBMNT}
@@ -561,7 +617,9 @@ if [ $REFRESH -eq 1 ]; then
LIVEMAIN="$(echo $(find ${ISOMNT} -name "0099*") |rev |cut -d/ -f3 |rev)"
rsync -rlptD --delete \
${ISOMNT}/${LIVEMAIN}/system/ ${USBMNT}/${LIVEMAIN}/system/
- chattr -i ${USBMNT}/boot/extlinux/ldlinux.sys 2>/dev/null
+ if [ -f ${USBMNT}/boot/extlinux/ldlinux.sys ]; then
+ chattr -i ${USBMNT}/boot/extlinux/ldlinux.sys 2>/dev/null
+ fi
rsync -rlptD --delete \
${ISOMNT}/boot/ ${USBMNT}/boot/
fi
@@ -572,20 +630,35 @@ if [ -n "$VERSION" ]; then
echo "$VERSION" > ${USBMNT}/.isoversion
fi
-if [ $DOLUKS -eq 1 ]; then
- # Create LUKS container file:
- create_container ${TARGET}3 ${HLUKSSIZE} slhome luks /home
+if [ -n "${HLUKSSIZE}" ]; then
+ # Create LUKS container file for /home:
+ create_container ${TARGET}3 ${HLUKSSIZE} ${SLHOME} luks /home
LUKSHOME=${CNTFILE}
fi
-# Update the initrd with longer USB wait time and LUKS /home info:
+# Update the initrd with regard to USB wait time, persistence and LUKS.
+# If this is a refresh and anything changed to persistence, then the
+# variable $PERSISTENCE will have the correct value when exing this function:
+# If you want to move your LUKS home containerfile you'll have to do that
+# manually - not a supported option for now.
update_initrd ${USBMNT}/boot/initrd.img
if [ $REFRESH -eq 1 ]; then
# Determine what we need to do with persistence if this is a refresh.
+ if [ "${PERSISTENCE}" != "${OLDPERSISTENCE}" ]; then
+ # The user specified a nonstandard persistence, so move the old one first;
+ # hide any errors if it did not *yet* exist:
+ mkdir -p ${USBMNT}/$(dirname ${PERSISTENCE})
+ mv ${USBMNT}/${OLDPERSISTENCE}.img ${USBMNT}/${PERSISTENCE}.img 2>/dev/null
+ mv ${USBMNT}/${OLDPERSISTENCE} ${USBMNT}/${PERSISTENCE} 2>/dev/null
+ fi
if [ -f ${USBMNT}/${PERSISTENCE}.img ]; then
# If a persistence container exists, we re-use it:
PERSISTTYPE="file"
+ if cryptsetup isLuks ${USBMNT}/${PERSISTENCE}.img ; then
+ # If the persistence file is LUKS encrypted we need to record its size:
+ PLUKSSIZE=$(( $(du -sk $USBMNT/${PERSISTENCE}.img |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
+ fi
elif [ -d ${USBMNT}/${PERSISTENCE} -a "${PERSISTTYPE}" = "file" ]; then
# A persistence directory exists but the user wants a container now;
# so we will delete the persistence directory and create a container file
@@ -623,35 +696,34 @@ mv ${USBMNT}/boot/extlinux/isolinux.cfg ${USBMNT}/boot/extlinux/extlinux.conf
rm -f ${USBMNT}/boot/extlinux/isolinux.*
/sbin/extlinux --install ${USBMNT}/boot/extlinux
-# No longer needed:
-if /sbin/mount |grep -qw ${USBMNT} ; then /sbin/umount ${USBMNT} ; fi
-
if [ $EFIBOOT -eq 1 ]; then
# Mount the EFI partition and copy /EFI as well as /boot directories into it:
- /sbin/mount -t vfat -o shortname=mixed ${TARGET}2 ${USBMNT}
- mkdir -p ${USBMNT}/EFI/BOOT
- rsync -rlptD ${ISOMNT}/EFI/BOOT/* ${USBMNT}/EFI/BOOT/
+ /sbin/mount -t vfat -o shortname=mixed ${TARGET}2 ${US2MNT}
+ mkdir -p ${US2MNT}/EFI/BOOT
+ rsync -rlptD ${ISOMNT}/EFI/BOOT/* ${US2MNT}/EFI/BOOT/
mkdir -p ${USBMNT}/boot
echo "--- Copying EFI boot files from ISO to USB."
if [ $VERBOSE -eq 1 ]; then
- rsync -rlptD -v ${ISOMNT}/boot/* ${USBMNT}/boot/
+ rsync -rlptD -v ${ISOMNT}/boot/* ${US2MNT}/boot/
else
- rsync -rlptD ${ISOMNT}/boot/* ${USBMNT}/boot/
+ rsync -rlptD ${ISOMNT}/boot/* ${US2MNT}/boot/
fi
if [ $REFRESH -eq 1 ]; then
# Clean out old Live system data:
echo "--- Cleaning out old Live system data."
rsync -rlptD --delete \
- ${ISOMNT}/EFI/BOOT/ ${USBMNT}/EFI/BOOT/
+ ${ISOMNT}/EFI/BOOT/ ${US2MNT}/EFI/BOOT/
rsync -rlptD --delete \
- ${ISOMNT}/boot/ ${USBMNT}/boot/
+ ${ISOMNT}/boot/ ${US2MNT}/boot/
fi
- # Update the initrd with longer USB wait time and LUKS container info:
- update_initrd ${USBMNT}/boot/initrd.img
+ # Copy the modified initrd over from the Linux partition:
+ cat ${USBMNT}/boot/initrd.img > ${US2MNT}/boot/initrd.img
+ sync
fi
# No longer needed:
if /sbin/mount |grep -qw ${USBMNT} ; then /sbin/umount ${USBMNT} ; fi
+if /sbin/mount |grep -qw ${US2MNT} ; then /sbin/umount ${US2MNT} ; fi
# Unmount/remove stuff:
cleanup