#!/bin/bash
#
#   ConVirt   -  Copyright (c) 2008 Convirture Corp.
#   ======
#
# ConVirt is a Virtualization management tool with a graphical user
# interface that allows for performing the standard set of VM operations
# (start, stop, pause, kill, shutdown, reboot, snapshot, etc...). It
# also attempts to simplify various aspects of VM lifecycle management.
#
#
# This software is subject to the GNU General Public License, Version 2 (GPLv2)
# and for details, please consult it at:
#
#    http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
# 
#
# author : Jd <jd_jedi@users.sourceforge.net>
#

# Script to do required configuration for the managed server node.
#
# Detect distribution 
# -- Get distro name, distro version, distro major, distro minor, architecture
#
# Detect virtualization platform
# -- XEN or KVM
#
# For Xen
#   -- configure xend to listen on all port
#   -- open corresponding firewall port for 8005/8006 and 8002
#   -- detect bridge name and put it in well known location
#   -- make sure that on reboot, firewall rules are preserved
#
# For KVM (not implemented yet)
#  -- do bridge setup
#  -- put in the /etc/qemu-if script
#  -- put the bridge name at well known location
#  -- check socat is installed.
#


# TODO : Allow user to specify the distro and virtualization platform
#        xen 3.3 ?
#        kvm implementation
#

# TODO : add setup_bridge as separate command. It is bit intertwined with 
#        xend config right now.
# 


prg_name=`readlink -f $0`
base=`dirname $prg_name`
if [ "${base}" == "" ]; then
    base="."
fi
common_scripts=${base}/../../../common/scripts

usage()
{
    cat <<EOF
    usage: $0 [options] [setup | setup_nw_svc]

    commands :
    setup : Do all necessary changes.
    setup_nw_svc : setup convirt serivce to start virtual networks.
    
    options : 
    --detect_only     : do not make changes, detect distro and virtualization platform
    -h                : help 
    --skip_fw_changes : Skip firewall changes
    --xen_skip_config : skip configuring xend server
    --xen_ssl         : configure xend to listen on SSL socket.
    --skip_setup_bridge: skip setup of public bridge for each interface.
    --skip_setup_nw_svc: skip setup of nw service during system boot
EOF
    exit 1

}

# parse the command line parameters
new_opts=`getopt -n$0 -u -a --longoptions="xen_skip_config,xen_ssl,detect_only,skip_fw_changes,skip_setup_bridge,skip_nw_svc_setup" "h" "$@"` || usage
set -- `echo $new_opts`
while [ $# -gt 0 ]
do
    case "$1" in
       --xen_skip_config)   xen_skip_config="true";;
       --xen_ssl)           xen_ssl="true";;
       --skip_fw_chages)    skip_fw_changes="true";;
       --detect_only)       detect_only="true";;
       --skip_setup_bridge) skip_setup_bridge="true";;
       --skip_setup_nw_svc) skip_nw_svc_setup="true";;
       -h)        usage;;
       --)        shift;break;;
       -*)        usage;;
       *)         break;;            
    esac
    shift
done

if [ $# != 1 ]; then 
   usage
fi
if [ "$1" != "setup" ] && [ "$1" != "setup_nw_svc" ];  then
   usage
fi

#echo "detect_only=$detect_only"
#echo "xen_skip_config=$xen_skip_config"
#echo "xen_ssl=$xen_ssl"
#echo "skip_setup_bridge=$skip_setup_bridge"

# We need to be root to do the setup.
if [ `id -u` != 0 ]; then
   echo "Must be root to execute $0 script"
   exit 1
fi

# detect distro
source $common_scripts/utils
source $common_scripts/functions
source $common_scripts/nw_functions
detect_distro

if [ "$?" != "0" ]; then
   echo "Error detecting Linux distribution.Exiting."
   exit 1
fi

# dump information
echo "DISTRO ${DIST}"
echo "VER ${VER}"
echo "CODENAME ${CODE_NAME}"
echo "KERNEL ${KERNEL}"
echo "ARCH ${ARCH}"

# include the distro specific file if it exists.
distro_functions=$common_scripts/${DIST}_functions
if [ -r $distro_functions ]; then
    echo "Info: Sourcing $distro_functions"
    source $distro_functions
else
   echo "Info: $distro_functions not found."
fi


#detect virtualization platform
detect_v_platform
if [ "$?" != "0" ]; then
   echo "Error detecting virtualization platform."
   echo "For Xen, please make sure that you reboot in to a Xen kernel and Xen server is running, while for KVM, the kvm modules are correctly loaded."
   exit 1
fi

echo "Virtualization platform $v_platform Version $v_platform_ver "

if [ "$detect_only" != "" ]; then
   exit 0
fi
if [ "$1" == "setup" ] || [ "$1" == "setup_nw_svc" ]; then
  if [ "$skip_setup_nw_svc" == "" ]; then
     cp $base/convirt-nw /etc/init.d/convirt-nw
     chmod +x /etc/init.d/convirt-nw
     setup_nw_svc
  fi
fi


if [ "$1" != "setup" ]; then
   exit 0
fi

# Xen Setup (may be moved in to functions.)
if [ "$v_platform" == "XEN" ]; then
    echo "Doing xen setup "


    # configure xen using config-xen scripts
    ver=`get_xen_userspace_ver $v_platform_ver`
    if [ "$?" == "0" ]; then
	x_u=$ver
	echo "Xen userspace version : $x_u"
        if [ "$xen_skip_config" == "" ]; then
	    s_dir=$base/xen-${x_u:0:3} # use only major and minor version.
	    echo "s_dir = $s_dir"
	    s_name="configure-xend.sh"
	    if [ -d $s_dir ]; then
		echo $s_dir exists.
		if [ -x $s_dir/$s_name ]; then
                    if [ "$xen_ssl" != "" ]; then
			ssl_opt="SSL"
		    fi
                    # switch skip_setup_bridge to true if num interfaces is < 2
                    if [ `get_num_physical_interfaces` -lt 2 ]; then
                       echo "switching skip_setup_bridge to true"
                       skip_setup_bridge="true"
                    fi
                    #create custom script to setup up a public bridge for each physical interface
                    if [ "${skip_setup_bridge}" != "true" ]; then
                      create_xen_custom_script $x_u 
                    fi
		    $s_dir/$s_name $x_u $ssl_opt ${skip_setup_bridge} 
		    if [ "$?" != "0" ]; then
			echo "Error executing $s_dir/$s_name"
			exit 1
		    else
			echo "$s_dir/$s_name successful."
		    fi
		fi
	    fi
         else
           echo "Skiping xend_config"
	 fi
    else
	echo "Error determining xen version required for xend-config.sh."
	exit 1
    fi

    # Detect bridge name
    bridge=`get_xen_bridge_name`
    if [ "$?" != "0" ]; then
	echo "Error ($bridge). Default bridge name will not be set"
    else
	br_name=$bridge
    fi
    echo "BRIDGE NAME=$br_name"


    # open up fire wall for related ports
    if [ "$skip_fw_changes" == "" ]; then
	if [ "$DIST" == "SLES" ]; then
	    open_ports 8002 8006 ssh
	else
	    open_ports 8002 8006 22
	fi
	if [ "$?" != "0" ]; then
	    echo "Error opening firewall ports. You may experience connection problems via convirt"
	fi
    fi
    

    # for some platforms we need to seed the conf
    seed_config
    if [ "$?" != "0" ]; then
       echo "Error seeding convirt.conf"
       exit 1
    fi

    # fix Debian problem.. :probably should introduce post fix up and 
    # pre fixup functions.
    if [ -L /usr/lib/xen-default ]; then
	if [ ! -L /usr/lib/xen ]; then
	    ln -s `readlink -f /usr/lib/xen-default` /usr/lib/xen
	fi
    fi

elif [ "$v_platform" == "KVM" ]; then
    # make sure socat,tunctl and brctl are installed.

    # Setup up bridge for each network interface in persistent fashion
    setup_public_bridge_for_kvm 

    # Detect bridge name
    bridge=`get_default_bridge`
    if [ $? != 0 ]; then
	echo "Error ($bridge). Default bridge name will not be set"
	echo "NOTE : To allow Virtual Machines to connect to the host network, please do public bridge setup as recommended by KVM platform documentation."
    else
	br_name=$bridge
    fi
    echo "BRIDGE NAME=$br_name"
else
   echo "Error : $0 : Dont know how to setup $v_platform."
   exit 1
fi




# dump discoverd information and brdige name in a well known location
# Also, this will act as a marker that the setup is done.
# save_discoved_info
mkdir -p /var/cache/convirt
cat <<EOF > /var/cache/convirt/server_info
DISTRO="$DIST"
CODE_NAME="$CODE_NAME"
VER="$VER"
KERNEL="$KERNEL"
ARCH="$ARCH"
V_PLATFORM="$v_platform"
V_PLATFORM_VER="$v_platform_ver"
DEFAULT_BRIDGE="$br_name"
EOF
if [ "$?" != 0 ]; then
   echo "Failed to save discoverd information."
   exit 1
fi

echo "Setup successful."



