#!/bin/bash

usage() {
    cat <<EOF
Usage: $0 [options]

Options:
   -h                   show this help message and exit
   -r RELEASEVER        Value to use for \$releasever (example: fedora-14,
                        fedora-rawhide)
   -a ARCH              Value used for \$basearch
   -d RESULTDIR         Directory to store results (default: \$PWD)
   -e NVR               RPM to download from koji for use during compose (e.g.
                        '-e anaconda-16.14-1.fc16').
   -p PACKAGES          Override kickstart %packages used to determine which
                        packages are included on generated ISO media
                        (default: $PACKAGES)
   -x EXCLUDE           Specify packages to exclude from kickstart repositories
   -i DVDISO            Optionally build a DVD.iso (default: no)
   -t TMPDIR            Temporary directory to use (default: /tmp)
EOF
    exit 1
}

## Detect the system release and version
detect_releasever() {
    RELEASE="fedora"
    VER="rawhide"
    # Guess releasever based on current system release
    if [ -f /etc/fedora-release ]; then
        RELEASE="fedora"
        VER=$(gawk '{print $3}' /etc/fedora-release)
    elif [ -f /etc/redhat-release -a ! -L /etc/redhat-release ]; then
        RELEASE="epel"
        VER=$(gawk '{print $5}' /etc/redhat-release)
        case $VER in
            4* ) VER=4 ;;
            5* ) VER=5 ;;
            6* ) VER=6 ;;
            * ) VER=6 ;;
        esac
    fi
    echo "$RELEASE-$VER"
}

error() {
    echo "Error: $1"
    exit 1
}

sigterm() {
    cleanup
    exit 1
}

cleanup() {
    test -n "${SETUP}" && rm ${SETUP}

    # only remove MOCKCFG if we own/created it
    test -O "${MOCKDIR}/${MOCKCFG}.cfg" && rm -f "${MOCKDIR}/${MOCKCFG}.cfg"
}

# Default values
BASEARCH=$(uname -i)
RELEASEVER=$(detect_releasever)
RESULTSDIR=${PWD}/results/$(date +%Y%m%d)
TMPDIR=/tmp
PUNGI_ARGS="-G -C -B"
PACKAGES="@core"
EXCLUDE=""
NVR=""
MOCKDIR=/etc/mock

# Process arguments
while getopts "ha:r:d:t:e:p:ix:" option
do
  case ${option} in
    a ) BASEARCH=${OPTARG} ;;
    r ) RELEASEVER=${OPTARG} ;;
    d ) RESULTSDIR=${OPTARG} ;;
    t ) TMPDIR=${OPTARG} ;;
    i ) PUNGI_ARGS="" ;;
    p ) PACKAGES="${PACKAGES} ${OPTARG}" ;;
    x ) EXCLUDE="${EXCLUDE} --exclude ${OPTARG}" ;;
    e ) NVR="${NVR} ${OPTARG}" ;;
    \?|h ) usage ;;
    * ) usage ;;
  esac
done

# Sanitize input arguments
RELEASE=${RELEASEVER%%-*}
VERSION=${RELEASEVER##*-}
test -d $MOCKDIR || error "Directory $MOCKDIR not found.  Is mock installed?"
# FIXME - sanitize basearch
# FIXME - sanitize releasever

# Prepare mock config template
MOCKROOT="${RELEASEVER}-${BASEARCH}"
MOCKROOTDIR="/var/lib/mock/${MOCKROOT}/root"

# If needed/supported, specify additional mock configuration information
# NOTE: This was needed by older versions of mock, and may not be required in
# the future
if [ 1 -eq 1 ]; then
    MOCKCFG="composetree-${MOCKROOT}"
    cat << EOF > ${MOCKDIR}/${MOCKCFG}.cfg
# Enable composes
config_opts['plugin_conf']['bind_mount_enable'] = True
config_opts['plugin_conf']['bind_mount_opts']['dirs'].append(('/dev','/dev/'))
config_opts['plugin_conf']['bind_mount_opts']['dirs'].append(('/dev/pts','/dev/pts/'))
config_opts['plugin_conf']['bind_mount_opts']['dirs'].append(('/dev/shm','/dev/shm/'))

EOF

    if [ ! -w "${MOCKDIR}" ]; then
        error "Unable to create mock configuration in ${MOCKDIR}"
    fi

    cat ${MOCKDIR}/${MOCKROOT}.cfg >> ${MOCKDIR}/${MOCKCFG}.cfg
    if [ "$?" -ne 0 ]; then
        error "Failed while building mock configuration file"
    fi
else
    MOCKCFG="${MOCKROOT}"
fi

# Install new packages for testing
KSCFG=$(mktemp --suffix .ks ${TMPDIR}/compose_tree-ks-XXXXXX)
SETUP=$(mktemp --suffix .sh ${TMPDIR}/compose_tree-setup-XXXXXX)
cat > ${SETUP} << EOF
#!/bin/sh

## Install any requested packages
if [ -n "${NVR}" ]; then
    KOJI_RPMS=\$(mktemp -d /tmp/koji-rpms.XXXXXX)
    mkdir -p \${KOJI_RPMS}
    cd \${KOJI_RPMS}

    ## Use koji to download updated packages
    for E in ${NVR}
    do
        koji download-build \$E
    done

    ## Install updated packages
    yum -y localupdate *.rpm

    ## Create repository
    createrepo \${KOJI_RPMS}
fi

## If specific packages were requested, adjust kickstart as needed
KSTEMPLATE="/usr/share/spin-kickstarts/fedora-install-fedora.ks"
if [ -n "${PACKAGES}" ]; then
    ## Prepare kickstart for boot.iso ...
    ## Use existing spin-kickstart file, but use a smaller %packages
    ## Remove everything between %packages ... %end
    gawk '/^%packages/,/^%end/ {next} {print}' \${KSTEMPLATE} > ${KSCFG}

    # Include requested packages
    echo "%packages --nobase --ignoremissing" >> "${KSCFG}"
    for PKG in ${PACKAGES}; do
        echo "\${PKG}" >> "${KSCFG}"
    done
    echo "%end" >> "${KSCFG}"

## Otherwise, use the default kickstart file
else
    ## Prepare kickstart for DVD.iso ...
    ## Just use the existing kickstart as is
    cp \${KSTEMPLATE} ${KSCFG}
fi

## Make sure the requested packages were installed
if [ -n "${NVR}" ]; then

    # Add custom repo for local koji packages
    echo "repo --name=koji-rpms --baseurl=file://\${KOJI_RPMS}" >> ${KSCFG}

    rpm -q ${NVR}
    echo \$?
fi

## If requested, exclude specific packages
if [ -n "${EXCLUDE}" ]; then
    sed -i -e "s|^\(repo.*\)$|\1 ${EXCLUDE}|" ${KSCFG}
fi

EOF

# Ensure sigterm is called on exit
trap sigterm SIGTERM

MOCK="mock -r ${MOCKCFG}"
let RETVAL=0
${MOCK} --init
let RETVAL+=$?
${MOCK} --install koji pungi spin-kickstarts createrepo
let RETVAL+=$?
${MOCK} --copyin ${SETUP} /tmp/setup.sh
let RETVAL+=$?
${MOCK} --chroot "bash /tmp/setup.sh"
let RETVAL+=$?
${MOCK} --chroot "pungi --force --nosource --nodebuginfo ${PUNGI_ARGS} --force --flavor Fedora --name Fedora --ver ${VERSION} -c ${KSCFG}"
let RETVAL+=$?

# Report the results.  We do all the copies individually in case one of the files doesn't exist.
mkdir -p ${RESULTSDIR}
cp -f ${SETUP} ${RESULTSDIR}/setup.sh
let RETVAL+=$?
cp -f ${MOCKROOTDIR}/${KSCFG} ${RESULTSDIR}/ks.cfg
let RETVAL+=$?
cp -f ${MOCKROOTDIR}/../result/root.log ${RESULTSDIR}/
let RETVAL+=$?

# Save generated installer files
for FNAME in .treeinfo images/boot.iso images/pxeboot/vmlinuz images/pxeboot/initrd.img
do
    cp -f ${MOCKROOTDIR}/${VERSION}/Fedora/${BASEARCH}/os/${FNAME} ${RESULTSDIR}/
    let RETVAL+=$?
done

# Clean up and exit
cleanup
exit ${RETVAL}
