#! /bin/bash
# $Id: start-build,v 1.3 2003/12/05 01:17:57 ensc Exp $

# Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
#  
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


function showHelp()
{
    echo $"\
Usage: start-build [-s slave] [-bcef] <dist> <url> <md5sum> <gpg-key#> <build-args>*

Options:
   -s <slave>    ... use the specified slave
   -b            ... use batch-mode; do not enter a shell on failures
   -e            ... enter slave only; without <dist> (and further options)
                     the slave will not be wiped
   -c            ... interpret everything behind <dist> as a command which
                     will be executed in the slave after creating the build
		     chroot
   -f            ... build the complete full build-tree from scratch instead
		     of using cached images

<dist> is the target distribution (see /etc/mach/dist in slave for a
complete list), valid values are e.g.
  'f1fs' resp. 'fedora-1-i386-stable' or
  'rh9u' resp. 'redhat-9-i386-updates'
"
    
    exit 0
}

function exitFunc()
{
    set +e
    stopSlave "$slave"
    test ! -f "$slave_lock"     || rm -f  "$slave_lock"
    test ! -d "$harvest_tmpdir" || rm -rf "$harvest_tmpdir"
}

function setEnv()
{
    unset BATCH

    test -z "$do_cmd"       || export MACH_DOCMD=1
    test -z "$batch"        || export MACH_BATCH=1
    test -z "$from_scratch" || export MACH_SCRATCH=1
    export _PS1="${col_bred}${1:+$1@}$slave#${col_rset} "
    #export _PS1="${1:+$1@}$slave#\033[0;0m "
}

# Usage: prepareSlave <slave-name>
function prepareSlave
{
    mount_point="$SLAVE_MOUNTPOINT/$1"

    ## Can fail since the 'chmod 000' barrier could be active...
    /bin/mkdir -p "$mount_point/aux/root" &>/dev/null || :
 
    cd "$mount_point/aux"

    $DJINNI -q new_bslave "$1" "$mount_point"
    slave_started=1

    set -P
    cd root
    set +P
}

# Usage: stopSlave <slave-name>
function stopSlave
{
    test -z "$slave_started" || {
	$DJINNI -q stop_bslave "$1"
	slave_started=
    }
}

function harvestResults
{
    ## Package was built, but slave can have malicious processes running. Since
    ## following checks will render slave area unusable, copy packages into our
    ## area first before proceeding.
    harvest_tmpdir=$(mktemp -d /var/tmp/build-harvest.XXXXXX)
    $EXEC_CD /var/lib/mach/tmp   /bin/cp -a . $harvest_tmpdir/
    
    stopSlave "$2"
    
    harvest_dir=$HARVEST_TOPDIR
    test "$1" = 0 || harvest_dir="$harvest_dir/FAILED"
    
    cp -a $harvest_tmpdir/* "$harvest_dir" || return 1

    local d=${harvest_dir##$HARVEST_TOPDIR}
    for i in $harvest_tmpdir/*/*; do
	test -d "$i" || continue
	harvest_dirs=( "${harvest_dirs[@]}" "$d/${i##$harvest_tmpdir/}" )
    done

    return $1
}

function printHarvestDirs
{
    local dir

    for dir in "${harvest_dirs[@]}"; do
	echo "  $1$dir"
    done
}

function printResults
{
    local rc=$1
    local cmd dir base dist version comp
    local old_IFS=$IFS

    echo
    if test $rc -eq 0; then
	echo -e "Build ${col_bblue}succeeded${col_rset}. Results can be found in"
	printHarvestDirs "$HARVEST_TOPDIR"

	echo
	echo "Possible/suggested commands:"

	for dir in "${harvest_dirs[@]}"; do
	    dir=$(echo "$dir" | tr -d -c /a-zA-Z0-9_=+-.)
	    base=$(dirname "$dir")
	    base=$(basename "$base")
	    
	    IFS='-'
	    set -- $base
	    IFS=$old_IFS

	    case "$1" in
		fedora)	dist=$1; version=$2; comp=$4;;
		redhat) dist=$1; comp=$5
		    case "$2" in
			9)	version=rh90;;
			*)	version=rh$2;;
		    esac
		    ;;
		*)      dist='?'; version='?'; comp='?';;
	    esac
		
	    for cmd in "${SUCCESS_COMMANDS[@]}"; do
		echo "  $cmd" | sed -e "s!@HARVESTDIR@!$dir!g;
				        s!@DIST@!$dist!g;
				        s!@VERSION@!$version!g;
				        s!@COMPONENT@!$comp!g;
				       "
	    done
	done
    else
	echo -ne "Build ${col_bred}failed${col_rset}."
	if test "${#harvest_dirs[@]}" -gt 0; then
	    echo -ne "Possible results can be found in"
	    printHarvestDirs "$HARVEST_TOPDIR"
	else
	    echo
        fi
    fi
    
}

#############################

set -e

slave=
enter_only=
batch=${BATCH:+1}
do_cmd=
from_scratch=
mount_point=

while getopts "fbhes:c" key "$@"; do
    case "$key" in
	h)	showHelp;;
	e)	enter_only=1;;
	s)	slave=$OPTARG;;
	b)      batch=1;;
	c)	do_cmd=1;;
	f)	from_scratch=1;;
	*)	echo "Use '-h' for more information" >&2; exit 1;;
    esac
done


slave_lock=
slave_started=
harvest_tmpdir=
trap exitFunc EXIT

###########################

. /etc/sysconfig/fedora.us-build


slave=$($PKGLIBDIR/get-next-slave "$slave" "$@")
slave_lock=$SLAVE_LOCKDIR/$slave

shift $[ OPTIND - 1 ]

test "$enter_only$do_cmd" || test "$#" -ge 4 || {
    echo "Bad or missing options, use '-h'  for more information."
    exit 1
} >&2


## execute sysconfig-script with autoconfiguration to set e.g. special IPs
DJINNI_VSERVERNAME=$slave
. /etc/sysconfig/fedora.us-build

## Build the jail and go into it...
prepareSlave "$slave"

test "$do_cmd" || {
    case "$2" in
        /*)	## Copy local files into the slave
    		$EXEC_CD /var /bin/cp -a "$2" .
    		dist=$1
    		src=/var/$(basename "$2")
    		shift 2
    		set -- "$dist" "$src" "$@"
    		;;
    esac
}

setEnv

set +e
## Here, the real build starts...
$CHBIND --silent --ip "$IP_SLAVE" --bcast "$BCAST_SLAVE" \
    $CHCONTEXT --secure --flag lock \
    /usr/sbin/chroot "." .$MACH_INIT "$@"
rc=$?
set -e

if test -z "$do_cmd"; then
    harvest_dirs=()

    test   -d var/lib/mach/tmp || rc=1
    test ! -d var/lib/mach/tmp || {
	harvestResults "$rc" "$slave"
	rc=$?
    }

    printResults $rc
fi

exit $rc
