Skip to content

Instantly share code, notes, and snippets.

@vholer
Created March 15, 2020 15:22
Show Gist options
  • Save vholer/40932c72635f036e1e1742c32c395362 to your computer and use it in GitHub Desktop.
Save vholer/40932c72635f036e1e1742c32c395362 to your computer and use it in GitHub Desktop.
ISO 9660 to ext2 conversion without root privileges
#!/bin/bash
# Simple conversion script of ISO 9660 image into image based
# on ext2/3/4 filesytem. Completely unprivileged, without needing
# to mount both images. Free to use under Apache 2.0 License.
# 2020, Vlastimil Holer <vlastimil.holer@gmail.com>
set -e -o pipefail
TYPE=${TYPE:-ext2}
LABEL=${LABEL:-CONTEXT}
DISK_SRC=$1
DISK_DST=${2:-${DISK_SRC}.${TYPE}}
if [ -z "${DISK_SRC}" ]; then
echo "SYNTAX: $0 <source image> [<dest. image>]" >&2
exit 1
fi
if ! [ -f "${DISK_SRC}" ]; then
echo "ERROR: File '${DISK_SRC}' not found" >&2
exit 1
fi
###
NEW_EXTR=$(mktemp "${DISK_SRC}.XXXXXX" -d)
NEW_DISK=$(mktemp "${DISK_SRC}.XXXXXX")
NEW_DBFS=$(mktemp "${DISK_SRC}.XXXXXX")
chmod go-rwx "${NEW_EXTR}" "${NEW_DISK}" "${NEW_DBFS}"
trap 'rm -rf "${NEW_EXTR}" "${NEW_DISK}" "${NEW_DBFS}"' EXIT TERM INT HUP
debugfs_do()
{
echo "${1}" >> "${NEW_DBFS}"
}
###
# unpack ISO file
bsdtar -xf "${DISK_SRC}" -C "${NEW_EXTR}"
find "${NEW_EXTR}" -mindepth 1 -exec chmod u+w,go+r {} \;
# create image with extX filesystem
NEW_SIZE=$(du -sk "${NEW_EXTR}" 2>/dev/null | cut -f1)
dd if=/dev/zero of="${NEW_DISK}" bs=1024 seek="$((NEW_SIZE + 1000))" count=1 status=none
mkfs -q -t "${TYPE}" -L "${LABEL}" "${NEW_DISK}"
tune2fs -c0 -i0 -r0 -O read-only "${NEW_DISK}" >/dev/null
# generate debugfs script
while IFS= read -r -d $'\0' F; do
REL_F=${F#${NEW_EXTR}/}
DN=$(dirname "${REL_F}")
BN=$(basename "${REL_F}")
debugfs_do "cd /${DN}"
if [ -f "${F}" ]; then
debugfs_do "write ${F} ${BN}"
elif [ -d "${F}" ]; then
debugfs_do "mkdir ${BN}"
else
echo "ERROR: Unsupported file type of '${REL_F}'" >&2
exit 1
fi
done < <(find "${NEW_EXTR}" -mindepth 1 -print0)
# run debugfs and apply prepared script
OUT=$(debugfs -w "${NEW_DISK}" -f "${NEW_DBFS}" 2>&1 >/dev/null)
# error in debugfs run is mainly detected by nearly empty output,
# which has only debugfs welcome banner and no other messages
if [ "$(echo "${OUT}" | wc -l)" -ne 1 ] || ! [[ "${OUT}" =~ ^debugfs ]]; then
echo "ERROR: Failed to convert ISO into ${TYPE} image due to error:" >&2
echo "${OUT}" >&2
exit 1
fi
# success!
mv -f "${NEW_DISK}" "${DISK_DST}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment