#!/bin/bash

# Copyright (C) 2010-2012, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA  02110-1301, USA.  A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.

# Requires: sudo livecd-creator, sudo setenforce, ksflatten

# Based on oVirt's node-creator

# Current fedora data
cur_rawhide=18
cur_devel=19

me=$(basename "$0")
warn() { printf '%s: %s\n' "$me" "$*" >&2; }
die() { warn "$*"; exit 1; }
usage() {
cat <<EOF
usage: $me <options>

Build a virt-p2v bootable image.

OPTIONS:
  -a    Additional yum repository. Can be specified multiple times.
  -c    Yum cache directory.
  -d    Directory containing virt-p2v-image.ks.
  -f    Specific Fedora mirror to use if building a Fedora image.
  -k    Don't run livecd-creator, just write the kickstart file to stdout.
  -l    Boot image label.
  -n    Don't add any repositories to kickstart. Useful in conjunction with -k.
  -r    Primary yum repository.
  -u    Updates yum repository.
  -p    Proxy server (e.g. http://bob:s3cr3t@cache.example.com:3128/)
  -h    Show this message.
EOF
}

onlyonce() {
    warn "-$1 may only be specified once"
    usage
    exit 1
}

norepos=0
ksonly=0
while getopts "a:d:f:hkl:np:r:u:w:" OPTION
do
    case $OPTION in
        a)
            n_elems=${#extra_repos[*]}
            extra_repos[$n_elems]="$OPTARG"
            ;;
        c)
            [ -n "$cachedir" ] && onlyonce $OPTION
            cachedir="$OPTARG"
            ;;
        d)
            [ -n "$datadir" ] && onlyonce $OPTION
            datadir="$OPTARG"
            ;;
        f)
            [ -n "$fedora_url" ] && onlyonce $OPTION
            fedora_url="$OPTARG"
            ;;
        k)
            ksonly=1
            ;;
        l)
            [ -n "$label" ] && onlyonce $OPTION
            label="$OPTARG"
            ;;
        n)
            norepos=1
            ;;
        p)
            [ -n "$proxy" ] && onlyonce $OPTION
            proxy="$OPTARG"
            ;;
        r)
            [ -n "$repo" ] && onlyonce $OPTION
            repo="$OPTARG"
            ;;
        u)
            [ -n "$updates" ] && onlyonce $OPTION
            updates="$OPTARG"
            ;;
        h)
            usage
            exit 0
            ;;
        ?)
            usage
            exit 1
            ;;
    esac
done

# Split out here for simple editing with sed during installation
DEFAULT_DATADIR=/usr/share/virt-p2v-image-builder

# Option defaults
datadir="${datadir:-$DEFAULT_DATADIR}"
cachedir="${cachedir:-/var/tmp/p2v-image-builder.$USER}"
label="${label:-Virt-P2V}"

# We hardcode the arch so it will run on both i386 and x86_64
#arch=$(rpm --eval '%{_arch}')
arch=i386
kstmp=$(mktemp --tmpdir p2v-image-builder.XXXXXXXX)

if pgrep -xl nscd; then
    die "Please stop nscd first"
fi

rm -f "$kstmp"
# combine recipe includes
ksflatten --config "$datadir/virt-p2v-image.ks" --output "$kstmp"
# XXX broken ksflatten leaves %include
sed -i 's/^%include /#&/' "$kstmp"

addrepo() {
    if [ "$norepos" == 0 ]; then
        echo -n "repo --name=$1 $2" >> "$kstmp"
        [ -n "$proxy" -a -z "$3" ] && echo -n " --proxy=$proxy" >> "$kstmp"
        echo >> "$kstmp"
    fi
}

if [ -z "$repo" ]; then
    # Set defaults for Fedora if this is a fedora system
    fedora=$(rpm --eval '%{fedora}' |grep [0-9])

    mirrorlist="http://mirrors.fedoraproject.org/mirrorlist"

    case "$fedora" in
    $curr_rawhide)
        if [ -z "$fedora_url" ]; then
            repo="--mirrorlist=$mirrorlist?repo=rawhide&arch=$arch"
        else
            repo="--baseurl=$fedora_url/development/rawhide/$arch/os"
        fi
        ;;
    $cur_devel)
        if [ -z "$fedora_url" ]; then
            repo="--mirrorlist=$mirrorlist?repo=fedora-$fedora&arch=$arch"
        else
            repo="--baseurl=$fedora_url/development/$fedora/$arch/os"
        fi
        ;;
    ?*)
        if [ -z "$fedora_url" ]; then
            repo="--mirrorlist=$mirrorlist?repo=fedora-$fedora&arch=$arch"
            updates="--mirrorlist=$mirrorlist?repo=updates-released-f${fedora}&arch=$arch"
        else
            repo="--baseurl=$fedora_url/releases/$fedora/Everything/$arch/os"
            updates="--baseurl=$fedora_url/updates/$fedora/$arch"
        fi
    esac
else
    repo="--baseurl=$repo"
    [ -n "$updates" ] && updates="--baseurl=$updates"
fi

if [ -n "$repo" ]; then
    addrepo base $repo
else
    die "No repository specified, and no default available."
fi
if [ -n "$updates" ]; then
    addrepo updates $updates
fi
i=0
for extra in "${extra_repos[@]}"; do
    ((i++))
    if [ -d "$extra" ]; then
        extra="file://$extra"
        noproxy=1
    fi
    addrepo "extra$i" "--baseurl=$extra" $noproxy
done

if [ $ksonly == 0 ]; then
    selinux_enforcing=$(/usr/sbin/getenforce)
    case "$selinux_enforcing" in
        Enforcing) sudo /usr/sbin/setenforce Permissive ;;
        Permissive) ;;
        *) if grep -q '^selinux --disabled' "$kstmp";
               then
                   warn "WARNING: SELinux disabled in kickstart"
               else
                   die "ERROR: SELinux enabled in kickstart, \
                   but disabled on the build machine"
           fi ;;
    esac

    mkdir -p $cachedir
    sudo livecd-creator -c "$kstmp" -f "$label" --cache="$cachedir" \
        --compression-type=gzip

    # Clean up
    if [ "$selinux_enforcing" = Enforcing ]; then
        sudo /usr/sbin/setenforce Enforcing
    fi
else
    cat $kstmp
fi

rm -f $kstmp
