#!/bin/bash -e
# Copyright (c) 2009 Alon Swartz <alon@turnkeylinux.org> - all rights reserved

fatal() {
    echo "fatal: $@" 1>&2
    exit 1
}

usage() {
cat<<EOF
Syntax: $(basename $0) rootfs-dir patch-dir|patch.tar.gz
Apply the patch to the extracted root filesystem. 

Patch structure:

    patch-dir/
        debs/       # custom debian packages (installed with dpkg -i *.deb)
        overlay/    # overlay applied to root filesystem
        conf        # configuration script to execute in chroot (rootfs)

This script calls the following sub-scripts:

    1) tklpatch-apply-debs
       Installs custom deb packages into the extracted root filesystem.

    2) tklpatch-apply-overlay
       Applies the overlay into the extracted root filesystem.

    3) tklpatch-apply-conf
       Executes the configuration script chrooted inside the root filesystem.

Advanced usage (configuration hooks):

    The configuration script 'conf' can be replaced with a conf directory
    containing the following configuration script hooks to be executed in
    the chroot (rootfs):

        conf/pre-debs       # executed before apply-debs
        conf/post-debs      # executed after apply-debs
        conf/pre-overlay    # executed before apply-overlay
        conf/post-overlay   # executed after apply-overlay

Environment variables:

    TKLPATCH_DEBUG       Turn on debugging. Increases verbosity.

EOF
    exit 1
}

chopslash() {
    [ "$1" == "/" ] && echo $1
    echo $1 | sed "s|/$||"
}

if [[ "$#" != "2" ]]; then
    usage
fi

[ -n "$TKLPATCH_DEBUG" ] && set -x

rootfs=$1
patch=$2

[ -d $rootfs ] || fatal "no such directory: $rootfs"
[ -e $patch ] || fatal "no such file/directory: $patch"

name="$(basename $patch)"
name="$(echo $name | sed 's/.tar.gz$//')"

if [ -z "$TKLPATCH_ISOLABEL" ]; then
    export TKLPATCH_ISOLABEL=$name
    echo "TKLPATCH_ISOLABEL: $name"
fi

if [ -f $patch ]; then
    patch_tmp=$(mktemp -d)
    echo "# extracting patch $patch to $patch_tmp"
    tar -zxf $patch -C $patch_tmp
    patch_dir=$patch_tmp/$name
else
    patch_dir=$patch
fi

[ -d $patch_dir ] || fatal "no such directory: $patch_dir"

if [ -d $patch_dir/patches ]; then
    for p in $patch_dir/patches/*; do
        tklpatch-apply $rootfs $p
    done
fi

rootfs=$(chopslash $rootfs)
patch_dir=$(chopslash $patch_dir)
conf_dir=$patch_dir/conf

echo "# applying patch $patch_dir"
[ -x $conf_dir/pre-debs ] && tklpatch-apply-conf $rootfs $conf_dir/pre-debs
[ -d $patch_dir/debs ] && tklpatch-apply-debs $rootfs $patch_dir/debs
[ -x $conf_dir/post-debs ] && tklpatch-apply-conf $rootfs $conf_dir/post-debs

[ -x $conf_dir/pre-overlay ] && tklpatch-apply-conf $rootfs $conf_dir/pre-overlay
[ -d $patch_dir/overlay ] && tklpatch-apply-overlay $rootfs $patch_dir/overlay
[ -x $conf_dir/post-overlay ] && tklpatch-apply-conf $rootfs $conf_dir/post-overlay

if [ -f $patch_dir/conf ]; then
    [ -x $patch_dir/conf ] && tklpatch-apply-conf $rootfs $patch_dir/conf
fi

echo "# cleaning up stray files"
tklpatch-apply-cleanup $rootfs

[ -d "$patch_tmp" ] && rm -rf $patch_tmp

exit 0

