#!/bin/bash -e

# Turn an ubuntu Hardy Heron or Intrepid Ibex live cd into one for Debathena
# See https://help.ubuntu.com/community/LiveCDCustomization
# Running this script itself on a similar machine helps.

if [[ $# -ne 2 && $# -ne 3 ]] ; then
    echo "Usage: $0 ubuntu-8.04-desktop-i386.iso debathena-i386.iso [/tmp/workdir]" > /dev/stderr
    exit
fi

# Set vars
if [[ $# -eq 3 ]] ; then
    TMP="$3"
    dontrmtmp=1
else
    TMP=$(mktemp -dt debathena-livecd-XXXXXX)
fi
MNT="$TMP/mnt"
EXCD="$TMP/extract-cd"
SQFS="$TMP/squashfs"
EDIT="$TMP/edit"

CDNAME="Debathena"

# Having this mounted by accident is /very bad/ (you end up removing files
# from the real /dev/), so double check.
umount -l "$EDIT/dev" 2> /dev/null || :

function cleanup {
    echo "Cleaning up..."
    umount -l "$EDIT/dev" || :
    umount -dl "$SQFS" || :
    umount -dl "$MNT" || :
    # These shouldn't be necessary (and shouldn't break a busy loop device),
    # but seem to be for some reason.
    # The -d switch to umount should be sufficient, but it's not
    losetup -d /dev/loop7 || :
    losetup -d /dev/loop6 || :
    losetup -d /dev/loop5 || :
    losetup -d /dev/loop4 || :
    losetup -d /dev/loop3 || :
    losetup -d /dev/loop2 || :
    losetup -d /dev/loop1 || :
    losetup -d /dev/loop0 || :
    
    # Clean intermediate files
    # If an explicit tempdir was given, don't remove it for debugging
    if [[ -z "$dontrmtmp" ]] ; then
	rm -Rf "$TMP"
    else
	echo "Not removing $TMP."
    fi
}
trap cleanup EXIT SIGINT SIGTERM

# Simple rsync equivalent that shows progress based on file count
# Don't include switches that affect output or w/e
# The -pte options to pv prevent it from printing the total number of
# lines (i.e., files) and the number of lines/files per second, because
# those look too much like byte counts.
function rsync_p {
    set -e
    l=`rsync "$@" -n --out-format='%n' | wc -l`
    rsync "$@" --out-format='%n' | pv -lpte -s $l > /dev/null
}

# Make sure we have necessary packages -- these are now dependencies
#apt-get install squashfs-tools genisoimage pv syslinux netpbm

# Make sure the module is loaded
if ! grep -q squashfs /proc/filesystems ; then
    echo "Filesystem 'squashfs' not found in /proc/filesystems." >/dev/stderr
    echo "Try 'modprobe squashfs'?" > /dev/stderr
    exit 1
fi

# Mount CD image
echo "Mounting CD image."
mkdir -p "$MNT"
mount -o loop "$1" "$MNT"

# Extract CD contents for modification
echo "Extracting CD contents for modification."
mkdir -p "$EXCD"
rsync_p --exclude=/casper/filesystem.squashfs -a --delete "$MNT/" "$EXCD/"

# Mount squashfs
echo "Mounting squashfs."
mkdir -p "$SQFS"
mount -t squashfs -o loop "$MNT/casper/filesystem.squashfs" "$SQFS"

# Extract squashfs for mods
echo "Copying squashfs for modification."
mkdir -p "$EDIT"
rsync_p -a --delete "$SQFS/"* "$EDIT/"

# Modifying boot scripts
echo "Modifying boot scripts..."
rm -f "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/02timezone"
rm -f "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/15autologin"
cp "/usr/share/debathena-livecd-tools/casper-bottom/"*[!~] "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/"

# Mod boot screen
if [[ -e "$EXCD/isolinux/isolinux.txt" ]] ; then
    menu="$EXCD/isolinux/isolinux.txt"
else
    menu="$EXCD/isolinux/text.cfg"
fi
sed -ri "s/Ubuntu/$CDNAME/g" "$menu" "$EXCD/isolinux/isolinux.cfg"
pngtopnm < "/usr/share/debathena-livecd-tools/splash/splash1.png" | ppmquant 256 | ppmtopcx > "$EXCD/isolinux/splash.pcx"
# Force this one to no more than 16 colors
pngtopnm < "/usr/share/debathena-livecd-tools/splash/splash2.png" | ppmquant 16 | ppmtolss16 "#000000=0" "#ffffff=7" > "$EXCD/isolinux/splash.rle"

# Mod language
echo 'en' > "$EXCD/isolinux/lang"

# Mod README.diskdefines
sed -ri 's/^(\#define DISKNAME\s+)(.+)$/\1'"$CDNAME"' Custom \2/' "$EXCD/README.diskdefines"

# Put static ubiquity files in to place
cp -a "/usr/lib/debathena-livecd-tools/ubiquity/target/"* "$EDIT/usr/lib/ubiquity/"
cp -a "/usr/share/debathena-livecd-tools/ubiquity/"* "$EDIT/usr/share/ubiquity/"
# We need this for our aptitude 
# success_cmd to not fail horribly, because ubiquity
# gets rid of its version too soon.
cp "/usr/lib/debathena-livecd-tools/bin/policy-rc.d" "$EDIT/usr/share/ubiquity/"

# Also, for some reason success commands aren't always run as root, so do
# this hack
sed -ri "s/^(\s+subprocess\.call\(\[)('sh', *'-c')/\1'sudo', \2/g" "$EDIT/usr/lib/ubiquity/ubiquity/frontend/base.py"

# And do the gtk_ui.py mods
sed -ri -f "/usr/lib/debathena-livecd-tools/ubiquity/gtk_ui-mods.sed" "$EDIT/usr/lib/ubiquity/ubiquity/frontend/gtk_ui.py"

# Prep chroot
echo "Preparing for chroot..."
# We'll need network
cp /etc/resolv.conf "$EDIT/etc/"
cp /etc/hosts "$EDIT/etc/"
# Put a script named /usr/sbin/policy-rc.d that exits with code 101
# This prevents init scripts from being run by installed software
cp "/usr/lib/debathena-livecd-tools/bin/policy-rc.d" "$EDIT/usr/sbin/"

# Debathena key
cp "/usr/share/keyrings/debathena-archive-keyring.gpg" "$EDIT/tmp/"

mount --rbind /dev "$EDIT/dev"
# Set up the chroot script
cp "/usr/lib/debathena-livecd-tools/bin/part2" "$EDIT/tmp/"

# Chroot
echo "Chroot!"
chroot "$EDIT" /tmp/part2
echo "End Chroot."

# Back from the chroot

# Keep regenerated boot image
mv "$EDIT/initrd.img" "$EXCD/casper/initrd.gz"
# And use the upgraded kernel
cp "$EDIT/vmlinuz" "$EXCD/casper/"

# Clean up
rm -Rf "$EDIT/tmp/"* # This includes part2
rm "$EDIT/etc/resolv.conf"
rm "$EDIT/etc/hosts"
rm "$EDIT/usr/sbin/policy-rc.d"

# Regenerate manifest
echo "Generating manifest."
chroot "$EDIT" dpkg-query -W --showformat='${Package} ${Version}\n' > "$EXCD/casper/filesystem.manifest"
cp "$EXCD/casper/filesystem.manifest" "$EXCD/casper/filesystem.manifest-desktop"
sed -i '/ubiquity/d' "$EXCD/casper/filesystem.manifest-desktop"

# Compress filesystem
echo "Compressing filesystem."
rm -f "$EXCD/casper/filesystem.squashfs"
mksquashfs "$EDIT" "$EXCD/casper/filesystem.squashfs" -nolzma

# Calc md5sums
echo "Calcualting checksums."
rm "$EXCD/md5sum.txt"
(cd "$EXCD" && find . -type f -print0 | xargs -0 md5sum > md5sum.txt)

# Create ISO
echo "Building ISO."
genisoimage -r -V "$CDNAME LiveCD" -cache-inodes -J -l -b "isolinux/isolinux.bin" -c "isolinux/boot.cat" -no-emul-boot -boot-load-size 4 -boot-info-table -o "$2" "$EXCD"

# Now test it with VMware or something
echo "Done!"
