# $Id: make_inst_disk8,v 1.18 2005/04/11 14:14:34 fabian Exp $
# vim:set sw=4 ts=4:
#
#############################################################################
#
# ALICE
# Automatic Linux Installation and Configuration Environment
#
# Copyright (c) 2000-2002 SuSE Linux Solutions AG, Eschborn, Germany
#               2002-2004 SuSE Linux AG, Eschborn, Germany
#               2005           SUSE GmbH, Nuernberg, Germany
#
# 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; either version 2 of the License, or
# (at your option) any later version.
#
# 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
#
#############################################################################
#
# Author: 
#
# ALICE
# Automatic Linux Installation and Configuration Environment
#
#############################################################################
#
# Copyright (c) 2002-2004 SuSE Linux AG, Eschborn, Germany
# All rights reserved. GPL.
#
# This file is part of ALICE
#
# Author: Fabian Herschel
#
#############################################################################
#
# SHOULD BE CALLED BY make_inst_disk or make_inst_media
#
#############################################################
#
# NOTES:
#
#############################################################
# 

function err_exit
{
    echo $1
    clean_up
    exit 1
}

function last_of
{
    typeset -i last
    if [ $# -gt 0 ]
    then
	last=$(( $# -1 ))
	shift $last
	echo $1
    fi
}

function clean_up
{
    cd /tmp
    cd -
}

function get_file
{
    source="$url_path/$1"
    dest=$2
    # TODO: ggf so umstellen, dass verschiedene URLS verwendbar sind
    case $method in
	HTTP )
	    GET "http://$url_server/$source" > $dest
	    ;;
        NFS )
	    cp $source $dest
	    ;;
        SCP )
	    scp $url_server:$source $dest
	    ;;
        FILE )
	    cp $source $dest
	    ;;
	* )  err_exit "Method $method not implemented yet"
	    ;;
    esac
}

function put_file
{
	#
	return 99
}


create_the_media()
{
	#
	################################## MAIN #######################
	#
	if [ -z "$alice_dir" ]; then
		alice_dir=$(cd $(dirname $0)/..; pwd)
		export alice_dir
	fi

	# definition of some constants:
	#
	#  the_new_dir="/floppy"
	#  the_master="AutoBootImg.Master"
	#boot_image="autodisk"
	cd $ALICE_HOME

	# check if templates exist
	for i in classes/*_linux_*.sys.tcf ; do echo -n ; done
	if test ! -r "templates/sys.tcf" -o ! -r $i ; then
		echo "templates/ or classes/*_linux_*.sys.tcf is missing!!"
		echo "Please copy the complete templates and classes"
		echo "for SuSE-Linux to your ALICE_HOME from /usr/lib/alice/samples";
		sleep 5
	fi

	#
	# have a look on the comamnd line
	#
	while [ $# -gt 0 ]
	do
	   case $1 in
			-? | --? | --help | -h ) 
							   usage
							   exit 1
							   ;;
			-CD | -cd | --CD | --cd        ) 
							   MODE="cd"
							   ;;
			--only_create_disk_image ) 
							   MODE="image"
							   ;;
			--netboot ) 
							   MODE="netboot"
								pxe_or_netboot="$netboot"
								mkdir -p $netboot
							   ;;
			--pxeboot ) 
								MODE="pxeboot"
								pxe_or_netboot="$pxeboot"
								 mkdir -p $pxeboot
								;;
			--only_pxe_cfg )
							    # Do NOT copy kernel (linux) and ramdisk (initrd)
								# use this flag, if your workstation could not mount from the inst server
								only_pxe_cfg=1
								;;
			-URL | -url | --URL | --url    ) 
							   URL=$2      
							   # this sould be an "URL" the root directory of the distribution
							   # from which the boot/module disk should be copied
							   # method:/[/server/]path/..
							   method=${URL%:*}
							   method=$(echo $method | tr '[:lower:]' '[:upper:]')
							   URL=${URL#*:}
							   case $method in
									SCP ) # //server/ follows 
												   URL=${URL#//}
												   url_server=${URL%%/*}
												   url_path="/${URL#*/}"
												   method=SCP
												   ;;
									FILE ) # /path follows
												   URL=${URL#/}
												   url_path="/${URL#*/}"
												   method=FILE
												   ;;
							   esac
							   shift
							   ;;
			--diskimage | --bootimage )
							   boot_image=$2
							   shift
							   ;;
			--modulesimage   ) modules_image=$2
							   shift
							   ;;
			--original_image ) original_image="yes"
							   ;;
			--dhcp )          #
							  # dhcp client installation
							  # we do not know the machines name
							  # special routines are needed
							  #
							  export dhcp_mode=1
							  export dhcp_class=$2
							  shift
							  export fqhn=dhcp
							  ;;
			--debug )         #
							  # let GET_CONFIGURATION print, which files are serached and found
							  #
							  export debug="--debug"
							  ;;
			-v | --verify    ) # verify disk image
							   DISK_VERIFY=1
							   ;;
			--mkinfo         )
							   mk_info="yes"
							   ;;
			--add_module_dir )
								add_module_dir=$2
								shift
								;;
			[a-zA-Z]*        ) fqhn=$1;
							   ;;
			*                )  
							   echo "Unknown command line option: $1"
							   usage
							   exit 1
							   ;;
	   esac
	   shift
	done
	#
	cd $alice_dir/lib
	. $alice_dir/lib/alicerc
	cd $ALICE_HOME
	#

	if [ -z "${tmp_dir}" ] || [ "${tmp_dir:0:5}" != "/tmp/" ]; then
		# TODO: tmp_dir sollte auch unabhaengig in make_info_file gesetzt werden
		tmp_dir="$ALICE_HOME/tmp"
	fi

	export tmp_dir
	rm -rf ${tmp_dir}/disk
	mkdir -p ${tmp_dir}/disk
	new_boot_image="${tmp_dir}/boot"

	if [ "$fqhn" = "" ]
	then
	   usage
	   exit 1
	fi

		#
		###############################################################
		#
		# MAKE XML FILE
		# SL 8x
		#
		# TODO: use the correct path to alice2autoyast.pl
		#	at this moment we need the quick fix for $PATH (see above)
		#
		echo "Calling alice2autoyast.pl"
		cd $alice_dir
		$alice_dir/utils/alice2autoyast.pl --host $SYS_NAME \
			--alice_home=$ALICE_HOME \
			--xml_file=$pxe_or_netboot/$SYS_NAME.xml || err_exit "can't create $pxe_or_netboot/$SYS_NAME.xml"
		cd -


	#
	###############################################################
	#
	# Set some variables
	#
    NFS_SERVER=$(get_inst_server)
    NFS_DIR=$(get_inst_directory)
    nfs_mnt=/tmp/mnt$$.dist
    #
    #
    method=$(echo "$SYS_INST_PROTOCOL" | tr '[:lower:]' '[:upper:]')
    #
    # TODO: HANDLING OF FTP, HTTPS, TFTP(!), ???
    #
    case "$method" in
        HTTP )
            #
            #
            #
            url_server=$NFS_SERVER
            url_path=$NFS_DIR
            ;;
        NFS )
            #
            # create a mout point and mount the dist from the i-server
            #
            url_path=$nfs_mnt
            mkdir -p $nfs_mnt
            if [ "$method" = "NFS" ]
            then
               echo mount ${NFS_SERVER}:${NFS_DIR} $nfs_mnt
               mount ${NFS_SERVER}:${NFS_DIR} $nfs_mnt
            fi
            ;;
    esac

			if [ -z "$NET_INST_DEV" ]
			then
				echo "NET_INST_DEV is not set " >&2
			else
				if [ "$dhcp_mode" -ne 1 ]
				then
					# read the install interface settings
					tmp_var=$( echo "$NET_IP_CONFIG" | grep "$NET_INST_DEV" )
					declare -a NET_CFG
					NET_CFG=($tmp_var)
					net_interface=${NET_CFG[0]}
					net_addr=${NET_CFG[1]}
					net_addr_hex=$(echo $net_addr | awk -F\. '{ printf "%02X%02X%02X%02X\n",$1,$2,$3,$4}')
					net_mask=${NET_CFG[2]}
					net_broadcast=${NET_CFG[3]}
echo NET_INST_DEV $NET_INST_DEV
echo  net_addr $net_addr
echo net_addr_hex $net_addr_hex
				 fi
			  fi
	#
	# set the url parameters
	#
	if [ -z "$url_server" ]
	then
	   url_server=$NFS_SERVER
	fi
	nfs_mnt=/tmp/mnt$$.dist
	if [ -z "$url_path" ]
	then
	   url_path=$nfs_mnt
	fi


	#
	# optionaly copy the kernel and ramdisk
    #
	if [ "$only_pxe_cfg" = "1" ]
	then
		echo "skipping copy of linux and initrd"
	else
		#
		# create a mout point and mount the dist from the i-server
		#
		mkdir -p $nfs_mnt
		if [ "$method" = "NFS" ]
		then
		   echo mount ${NFS_SERVER}:${NFS_DIR} $nfs_mnt
		   mount ${NFS_SERVER}:${NFS_DIR} $nfs_mnt
		fi
		case $MODE in
			netboot | pxeboot )
				echo "Copy initrd (ram disk) and linux (kernel file)"
				get_file $initrd_path $pxe_or_netboot/initrd || err_exit "Getting initrd failed"
				get_file $kernel_path $pxe_or_netboot/linux  || err_exit "Getting linux  failed"
			;;
		esac
		#
		# umount the dist mounted from the i-server
		#
		if [ "$method" = "NFS" ]
		then
			umount $nfs_mnt 
		fi
	fi
	#  
	# message file
	#
	#
	#
	#
		# TODO: set the correct directory for netboot and pxeboot
		# TODO: fhbaust
		message_dest_file=$pxe_or_netboot/message

	if [ -n "$SYS_BOOT_SCREEN" ]
	then
	   #
	   # EDIT THE TEMPLATE OF THE BOOT SCREEN
	   #
	   if [ $dhcp_mode -eq 0 ]
	   then
		  host_message=$(printf "%-59.59s"         "Host:        $SYS_NAME")
		  ipadr_message=$(printf "%-59.59s"        "IP:          $net_addr")
	   else
		  host_message=$(printf "%-59.59s"         "Class:       $dhcp_class")
		  ipadr_message=$(printf "%-59.59s"        "IP:          dhcp")
	   fi
	   bootmode_message=$(printf "%-59.59s"     "Boot:        $SYS_BOOT_MODE") 
	   kernel_message=$(printf "%-59.59s"       "Kernel:      $SYS_INST_KERNEL")

	   if [ "$SYS_BOOT_MODE" = "cdrom" ]
	   then
		   sourceserver_message=$(printf "%-59.59s" "Src:         CDROM or DVD") 
		   sourcedir_message=$(printf "%-59.59s"     "    ")
		else
		   sourceserver_message=$(printf "%-59.59s" "SrcHost:     $NFS_SERVER") 
		   sourcedir_message=$(printf "%-59.59s"     "SrcDir:      $NFS_DIR")
		fi

	   if [ -n "$SYS_ALICE_CFG_URL" ]
	   then
		  cfgurl_message=$(printf "%-59.59s"     "CfgURL:      $SYS_ALICE_CFG_URL")
	   else
		  cfgurl_message=$(printf "%-59.59s"     "CfgURL:      \$I:/alice")
	   fi
	   echo "$SYS_BOOT_SCREEN" | sed -e "s/1--[^-]*--1/$host_message/" \
								 -e "s/2--[^-]*--2/$ipadr_message/" \
								 -e "s/3--[^-]*--3/$bootmode_message/" \
								 -e "s/4--[^-]*--4/$kernel_message/" \
								 -e "s/5--[^-]*--5/$sourceserver_message/" \
								 -e "s|6--[^-]*--6|$sourcedir_message|" \
								 -e "s|7--[^-]*--7|$cfgurl_message|" >${tmp_dir}/disk/message
		cp ${tmp_dir}/disk/message $message_dest_file || err_exit "Copy of file message (boot screen) failed."
	else
	   #
	   # CREATE A MINIMAL MESSAGE FILE, IF NO TEMPLATE IS DEFINED
	   #
	   echo "Creating message file"
	(
	   printf "\014\0171e\014"
	   FMT="%-79.79s\n"
	   printf $FMT "     Welcome to SUSE Linux"
	   printf $FMT "     SUSE Linux by SUSE LINUX AG Nuernberg"
	   printf $FMT "     ALICE2 by SUSE LINUX AG - Professional Services"
	   printf $FMT " "
	   printf $FMT "     This is an automatic installation disk created by make_inst_disk."
	   printf $FMT "     Generation date: $(date)"

	   printf $FMT "     Host:         $SYS_NAME "
	   printf $FMT "     IP-Address:   $net_addr "

	   printf $FMT "     SUSE Version: $SV"
	   printf $FMT "     Bootmode:     $SYS_BOOT_MODE"
	   printf $FMT "     Kernel:       $SYS_INST_KERNEL"

	   if [ "$SYS_BOOT_MODE" = "CD" ]
	   then
		  printf $FMT "     DIST-SERVER:  $NFS_SERVER"
		  printf $FMT "     DIST-DIR:     $NFS_DIR"
	   else
		  printf $FMT "     NFS-SERVER:   $NFS_SERVER"
		  printf $FMT "     NFS-DIR:      $NFS_DIR"
	   fi
	   printf $FMT " "
	   printf $FMT " "
	)> $message_dest_file
	fi
	#
	# optional syslinux.cfg for append parameters
	#
	# TODO: pxeboot und netboot als ziel beachten!
	sys_cfg_dest_file=$pxe_or_netboot/syslinux.cfg
	if [ -f "$sys_file" ]
	then
	   echo "Copying syslinux configuration file"
	   cp $sys_file $sys_cfg_dest_file || err_exit "Copy of syslinux.cfg failed."
	fi
	#
	# last not least place the gererated images
	#
	case $MODE in
		cd )
			cp ${new_boot_image} ${tmp_dir}/auto_boot_image
			echo "Creating of new installation disk was successfull."
			echo "The image file is: tmp/auto_boot_image"
			;;
		floppy )
			# TODO: Maybe we will need an additional info file for some reasons too
			echo "Copy xml file to a dos floppy"
			mcopy cp $pxe_or_netboot/$SYS_NAME.xml a:autoinst.xml
			sleep 3
			;;
		image )
			mkdir -p $pxe_or_netboot/mnt
			dd if=/dev/zero of=$pxe_or_netboot/xml_floppie count=1440 bs=1024
			mkdosfs $pxe_or_netboot/xml_floppie
			# TODO: /mnt has to be changed!
			mount -oloop $pxe_or_netboot/xml_floppie $pxe_or_netboot/mnt
			cp $pxe_or_netboot/$SYS_NAME.xml $pxe_or_netboot/mnt/autoinst.xml
			# TODO: the options of the linuxrc info file should be set by this script...
			echo "autoyast=floppy" >> $pxe_or_netboot/mnt/info
			echo "instmode=cd"     >> $pxe_or_netboot/mnt/info
			umount $pxe_or_netboot/xml_floppie
			echo "The config floppy image is: $pxe_or_netboot/xml_floppie"
			;;
		netboot )
			#
			# etherboot start
			#
			echo "Copying objects for net boot (nbi)"
			xml_file_name="yastxml.$net_addr"
			echo "Copy the xml file $netboot/$SYS_NAME.xml to $tftpboot_url/$SYS_ARCH/yast.cfg/$xml_file_name"
			echo "Creating netboot image $tftpboot_url/$SYS_ARCH/nbi/linux.nbi.$net_addr"
			#
			# TODO: be more flexible with the kernel params?
			# some systems also need initrd=initrd
			# unfortunatly autoyast=tftp.... leads into a linuxrc stop
			#
			appendline="autoyast=$(expand_alice_var $SYS_AUTOYAST_URL) install=$SYS_INST_PROTOCOL://$NFS_SERVER$NFS_DIR"
			echo "setting append line $appendline"
			mknbi-linux -a "$appendline" -r $netboot/initrd $netboot/linux \
				$netboot/linux.nbi.$net_addr
			#
			# TODO: make $tftpboot_url more flexible
			#
			cp $netboot/linux.nbi.$net_addr $tftpboot_url/$SYS_ARCH/nbi/linux.nbi.$net_addr
			cp $netboot/$SYS_NAME.xml 		$tftpboot_url/$SYS_ARCH/yast.cfg/$xml_file_name
			#
			# transfer url1 url2
			;;
		pxeboot )
			#
			# PXE start
			#
			#
			# TODO: make $tftpboot_url more flexible
			#
			mkdir -p $tftpboot_url/$SYS_ARCH/{yast.cfg,pxe/pxelinux.cfg}
			xml_file_name="$net_addr.xml"
			appendline="append autoyast=$(expand_alice_var $SYS_AUTOYAST_URL) install=$SYS_INST_PROTOCOL://$NFS_SERVER$NFS_DIR initrd=initrd${sys_os_short}"
			if [ -n "$net_interface" ]
			then
				appendline="$appendline netdevice=$net_interface"
			fi
			if [  "$SYS_DISPLAY_MODE" = "normal" ]
			then
				appendline="$appendline textmode=1"
			fi
			(
				echo $appendline
				echo timeout 5
				echo prompt 1
				echo label linux
				echo kernel linux${sys_os_short}
			) > $pxeboot/pxelinux.cfg.$net_addr
			echo "Copying objects for pxe boot"
			#
			# TODO: check for /srv/tftp/$SYS_ARCH/pxe/pxelinux.0 and create a link using boot_switch
			#
			echo "Copy the pxe config file to $tftpboot_url/$SYS_ARCH/pxe/pxelinux.cfg/$net_addr_hex"
			cp $pxeboot/pxelinux.cfg.$net_addr 	$tftpboot_url/$SYS_ARCH/pxe/pxelinux.cfg/$net_addr_hex
			echo "Copy the xml file $pxeboot/$SYS_NAME.xml to $tftpboot_url/$SYS_ARCH/yast.cfg/$xml_file_name"
			cp $pxeboot/$SYS_NAME.xml $tftpboot_url/$SYS_ARCH/yast.cfg/$xml_file_name

			# TODO: create a link from $tftpboot_url/$SYS_ARCH/yast.cfg/$xml_file_name
			# to $tftpboot_url/$SYS_ARCH/yast.cfg/%MAC
			#
			if [[ -n "$NET_MAC_ADDRESSES" ]]
			then
				MAC=$(echo "$NET_MAC_ADDRESSES" | awk '$1 == dev { print $2}' dev="$NET_INST_DEV")
				if [[ -n "$MAC" ]]
				then
					echo "Create link for mac address $MAC"
					(cd "$tftpboot_url/$SYS_ARCH/yast.cfg"; ln -s "$xml_file_name" "$MAC")
				fi
			fi

			# optionaly provide the kernel and ramdisk
			#
			if [ ! "$only_pxe_cfg" = "1" ]
			then
				if [ ! -f $tftpboot_url/$SYS_ARCH/pxe/initrd${sys_os_short} ]
				then
					echo "Copy the ramdisk to $tftpboot_url/$SYS_ARCH/pxe/initrd${sys_os_short}"
					cp $pxeboot/initrd 	$tftpboot_url/$SYS_ARCH/pxe/initrd${sys_os_short}
				fi
				if [ ! -f $tftpboot_url/$SYS_ARCH/pxe/linux${sys_os_short} ]
				then
					echo "Copy the kernel to $tftpboot_url/$SYS_ARCH/pxe/linux${sys_os_short}"
					cp $pxeboot/linux 	$tftpboot_url/$SYS_ARCH/pxe/linux${sys_os_short}
				fi
			fi
			;;
	esac

	return 0
}
