#!/bin/bash
#Copyright (c) 2009  Eucalyptus Systems, 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, only version 3 of the License.  
# 
#This file 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, see <http://www.gnu.org/licenses/>.
# 
#Please contact Eucalyptus Systems, Inc., 130 Castilian
#Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/> 
#if you need additional information or have any questions.
#
#This file may incorporate work covered under the following copyright and
#permission notice:
#
#  Software License Agreement (BSD License)
#
#  Copyright (c) 2008, Regents of the University of California
#  
#
#  Redistribution and use of this software in source and binary forms, with
#  or without modification, are permitted provided that the following
#  conditions are met:
#
#    Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#
#    Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
#  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
#  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
#  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
#  THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
#  LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
#  SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
#  IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
#  BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
#  THE REGENTS’ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
#  OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
#  WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
#  ANY SUCH LICENSES OR RIGHTS.
#
#
#FAKEREG="yes"

FILE="//etc/eucalyptus/eucalyptus.conf"
IMPORTFILE=""
EUCALYPTUS=""
CC_PORT=""
NC_PORT=""
CLOUD_PORT=""
CLOUD_SSL_PORT=""
NAME=""
INSTANCE=""
EUCA_USER=""
HYPERVISOR=""
DHCPD=""
DHCP_USER=""
BRIDGE=""
NEWNODES=""
NODEMODE=""
WALRUS_MODE=""
SYNC=""
WALRUS=""
WALRUS_MODE=""
CLUSNAME=""
NEWCLUS=""
CLUSMODE=""
UPGRADE_CONF=""
SETUP=""
VERSION=""
CHECK=""
TOSYNC=""
TO_BACKUP="Y"
CREDENTIALZIPFILE=""
SCP="`which scp 2> /dev/null`"
RSYNC="`which rsync 2> /dev/null`"
WGET="`which wget 2> /dev/null`"
VERBOSE="N"
LIST=""
ENABLED=""
DISABLED=""
TO_START=""


usage () {
	echo "$0 [options] [<file>]"
	echo
	echo "where <file> is the configuration file ($FILE by default)"
	echo "   --help                           this message"
	echo "   -d <dir>                         point EUCALYPTUS to <dir>"
	echo "   --no-rsync                       don't use rsync"
	echo "   --no-scp                         don't use scp"
	echo "   --skip-scp-hostcheck             skip scp interactive host keycheck"
	echo "   --get-credentials <zipfile>      download credentials to <zipfile>"
	echo "   --register-nodes \"host host ...\" add new nodes to EUCALYPTUS"
	echo "   --deregister-nodes \"host host ...\"   remove nodes from EUCALYPTUS"
	echo "   --register-cluster <clustername> <host> add new cluster to EUCALYPTUS"
	echo "   --deregister-cluster <clustername>      remove cluster from EUCALYPTUS"
	echo "   --register-walrus <host>         add walrus to EUCALYPTUS"
	echo "   --deregister-walrus <host>       remove walrus from EUCALYPTUS"
	echo "   --register-sc <clustername> <host>      add storage controller"
	echo "   --deregister-sc <clustername>    remove storage controller from EUCALYPTUS"
	echo "   --list-walruses                  list registered walrus(es)"
	echo "   --list-clusters                  list registered CCs"
	echo "   --list-nodes                     list registered NCs"
	echo "   --list-scs                       list registered SCs"
	echo "   --no-sync                        used only with --register-* to skip syncing keys"
	echo "   --cc-port <port>                 set CC port"
	echo "   --nc-port <port>                 set NC port"
	echo "   --instances <path>               set the INSTANCE path"
#	echo "   --cloud-port <port1> <port2>     set the 2 cloud ports"
	echo "   --hypervisor <kvm|xen>           set hypervisor to use"
	echo "   --user <euca_user>               set the user to use"
	echo "   --dhcpd <dhcpd>                  set the dhcpd binary to <name>"
	echo "   --dhcp_user <user>               set the username to run dhcpd as"
	echo "   --name <var>                     returns the value or <name>"
	echo "   --import-conf <file>             import variables from <file> into eucalyptus.conf"
	echo "   --setup                          perform initial setup"
	echo "   --enable {cloud|walrus|sc}       enable service at next start"
	echo "   --disable {cloud|walrus|sc}      disable service at next start"
	echo "   --check {nc|cc|cloud|sc|walrus}  pre-flight checks"
#	echo "   --sync {nc|cc|cloud|sc|walrus}   pre-flight checks"
	echo "   --version                        eucalyptus version"
	echo
}

# utility function to make a copy of the conf file
check_and_backup () {
	# can we write to the configuration file?
	if [ ! -w $1 ]; then
		echo "Cannot write to $1!"
		exit 1
	fi

	# let's see if we need a copy
	if [ "$TO_BACKUP" = "Y" ]; then
		cp $1 $1.bak
		TO_BACKUP="N"
	fi
}

# 3 paramenter: the file, the variable name, the new value
change_var_value () {
	check_and_backup $1
	sed -i "s<^[[:blank:]#]*\(${2}\).*<\1=\"${3}\"<" $1
}
# comment lines matching $2 ($1 is the file)
comment () {
	check_and_backup $1
	sed -i "s<^[[:blank:]]*\(${2}.*\)<#\1<" $1
}
# comment lines matching $2 ($1 is the file)
uncomment () {
	check_and_backup $1
	sed -i "s<^[#[:blank:]]*\(${2}.*\)<\1<" $1
}

check_heartbeat() {
	local __host="$1"
	local __service="$2"
	local ret=""

	# checks
	if [ -z "$__host" -o -z "$__service" ]; then
		echo "check_heartbeat: need a host and a service!"
		return 1
	fi
	if [ -z "$WGET" -o ! -x "$WGET" ]; then
		echo "ERROR: wget is missing, cannot continue."
		return 1
	fi

	# let's talk to the host and check if something is running
	ret="`$WGET -q -T 10 -t 1 -O - http://${__host}:8773/services/Heartbeat`"
	if [ "$?" != "0" -o -z "$ret" ]; then
		return 1
	fi

	# we need both ehabled and local to be true
	if ! echo $ret |grep "enabled=true" > /dev/null  ; then
		return 1
	elif ! echo $ret |grep "local=true"  > /dev/null ; then
		return 1
	fi

	return 0
}

check_ws() {
	local URL="$1"
	local ret=""
	local soap_error=""

	if [ -z "$URL" ]; then
		echo "check_ws: need a URL!"
		return 1
	fi
	
	if [ -n "${FAKEREG}" ]; then
		ret=""
	elif [ "$2" != "" ]; then
		if [ "$VERBOSE" = "Y" ]; then
			echo   "$WGET -q -T 10 -t 1 -O - \"$URL\"" "|sed 's/<euca:registered>\\(.*\\)<\\/euca:registered>/\\n\\1\\n/g;s/<euca:name>/\\n>/g;s/<\\/*euca:item>//g;s/<\\/*euca:[^>]*>/ /g'|awk -F\">\" '/>/{print \"   \"$2}')"
		fi
		E=$($WGET -q -T 10 -t 1 -O - "$URL"|\
			sed 's/<euca:registered>\(.*\)<\/euca:registered>/\n\1\n/g;s/<euca:name>/\n>/g;s/<\/*euca:item>//g;s/<\/*euca:[^>]*>/ /g'|\
			awk -F">" '/>/{print "   "$2}')
		eval "$2=\"${E}\""
	else
		if [ "$VERBOSE" = "Y" ]; then
			echo "$WGET -q -T 10 -t 1 -O - \"$URL\" |grep faultstring | sed 's:.*<faultstring>\(.*\)</faultstring>.*:\1:'"
		fi
		soap_error="`$WGET -q -T 10 -t 1 -O - \"$URL\"`"
		ret="$?"
		soap_error="`echo $soap_error |grep faultstring | sed 's:.*<faultstring>\(.*\)</faultstring>.*:\1:'`"
		if test -n "$soap_error" ; then
			echo $soap_error
			ret="1"
		fi
	fi
	return $ret
}

component_sync_keys() {
    local COMPONENT=""
    local NAME=""
    
    if [ "$SYNC" = "N" ]; then
	return 0
    fi
    
    if [ $# -lt 1 ]; then
	return 1
    fi
    
    COMPONENT="$1"
    shift
    NAME="$2"
    shift

    if [ "$COMPONENT" = "walrus" ]; then
	echo "syncing walrus"
    elif [ "$COMPONENT" = "cc" ]; then
	echo "syncing cc($NAME)"
    elif [ "$COMPONENT" = "sc" ]; then
	echo "syncing sc($NAME)"
    elif [ "$COMPONENT" = "nc" ]; then
	echo "syncing nc"
    fi


}

# copy files over.
sync_keys() {
        local SOURCEDIR=""
	local DESTDIR=""
	local REMOTE=""
	local FILES=""
	local FILE=""

	if [ "$SYNC" = "N" ]; then
	    return 0
	fi

	if [ $# -lt 4 ]; then
		return 1
	fi

	SOURCEDIRS="$1"
	shift
	DESTDIR="$1"
	shift
	REMOTE="$1"
	shift
	while [ $# -ge 1 ]; do 
	    FILE=""
	    for sd in `echo $SOURCEDIRS | sed "s/,/ /g"`
	    do
		if [ -e "${sd}/${1}" ]; then
		    FILE="${sd}/${1}"
		fi
	    done
	    if [ "$FILE" = "" ]; then
		echo "Warning: cannot file file ${1} in ${SOURCEDIRS}"
	    else
		FILES="$FILES $FILE"
	    fi

	    shift
	done

	# is REMOTE actually localhost?
	if [ ${REMOTE} = "127.0.0.1" -o ${REMOTE} = localhost -o ${REMOTE} = "`hostname -s`" -o ${REMOTE} = "`hostname -f`" ]; then
	    # machine is localhost, not need for remote syncing
	    for i in $FILES
	    do
		if [ ! -e $i ]; then
		    echo "ERROR: cannot find cluster credentials."
		    exit 1
		else
		    if ! rsync -a $i $DESTDIR ; then
			echo "ERROR: cannot copy file (${i}) to destination (${DESTDIR})"
			return 1
		    fi
		fi
	    done		    
	    return 0
	fi

	# try rsync first 
	if [ -n "$RSYNC" ]; then
	    echo
	    echo  -n "Trying rsync to sync keys with \"${REMOTE}\"..."
	    if $RSYNC -az ${FILES} ${REMOTE}:${DESTDIR}/ > /dev/null ; then
		echo "done."
		return 0
	    else
		echo "failed."
	    fi
	fi

	# scp next
	if [ -n "$SCP" ]; then
	    echo
	    if [ "$EUCA_USER" = "" ]; then
		if getent passwd eucalyptus > /dev/null ; then
		    echo "Using 'eucalyptus' as EUCA_USER"
		    EUCA_USER="eucalyptus"
		else
		    echo "EUCA_USER is not defined!"
		    return 1
		fi
	    fi
	    echo
	    echo "Trying scp to sync keys with \"${1}\" (user \"${EUCA_USER}\")..."
	    if sudo -u ${EUCA_USER} $SCP ${FILES} ${EUCA_USER}@${REMOTE}:${DESTDIR} > /dev/null ; then
		echo "done."
		return 0
	    else
		echo "failed."
	    fi
	fi
	
	return 1
}

if [ $# -eq 0 ]; then
	usage
	exit 1
fi

# let's parse the command line
while [ $# -gt 0 ]; do
	if [ "$1" = "-h" -o "$1" = "-help" -o "$1" = "?" -o "$1" = "--help" ]; then
		usage
		exit 1
	fi

	if [ "$1" = "-synckeys" -o "$1" = "-synckey" ]; then 
	    NODEMODE="SYNC"
	    shift
	    continue
	fi
	if [ "$1" = "-norsync" -o "$1" = "--no-rsync" ]; then 
	    RSYNC=""
	    shift
	    continue
	fi
	if [ "$1" = "--list-scs" ]; then 
	    LIST="$LIST storages"
	    shift
	    continue
	fi
	if [ "$1" = "--list-walruses" ]; then 
	    LIST="$LIST walruses"
	    shift
	    continue
	fi
	if [ "$1" = "--list-clusters" ]; then 
	    LIST="$LIST clusters"
	    shift
	    continue
	fi
	if [ "$1" = "--list-nodes" ]; then 
	    LIST="$LIST nodes"
	    shift
	    continue
	fi
	if [ "$1" = "--verbose" ]; then 
	    VERBOSE="Y"
	    shift
	    continue
	fi
	if [ "$1" = "-noscp" -o "$1" = "--no-scp" ]; then 
	    SCP=""
	    shift
	    continue
	fi
	if [ "$1" = "--skip-scp-hostcheck" ]; then 
	    SCP_OPT="-oStrictHostKeyChecking=no"
	    shift
	    continue
	fi
	if [ "$1" = "-version" -o "$1" = "--version" ]; then 
	    VERSION="Y"
	    shift
	    continue
	fi
	if [ "$1" = "-setup" -o "$1" = "--setup" ]; then 
	    SETUP="Y"
	    shift
	    continue
	fi
	if [ "$1" = "--no-sync" ]; then 
	    SYNC="N"
	    shift
	    continue
	fi
	if [ "$1" = "--deregister-walrus" ]; then
	    WALRUS_MODE="DEL"
	    shift
	    continue
	fi
	if [ $# -eq 1 ]; then
		# we dont have options with no argument, so it has to be
		# the file
		FILE="$1"
		if [ "${FILE:0:1}" = '-' ]; then
			usage
			exit 1
		fi
		break
	fi

	# all other parameters requires at least 1 argument
	if [ $# -lt 2 ]; then
		usage
		exit 1
	fi

	# old command line options not used anylonger
	if [ "$1" = "-cc" -o "$1" = "-nc" -o "$1" = "-cloud" ]; then
		echo "-cc, -nc and -cloud are not used anymore"
		shift; shift;
		continue
	fi

	if [ "$1" = "-d" ]; then
		if [ ! -d "${2}" ]; then
			echo "Is $2 where Eucalyptus is installed?"
			exit 1
		fi
		EUCALYPTUS="${2}"
		shift; shift
		continue
	fi
	if [ "$1" = "-name" -o "$1" = "--name" ]; then
		NAME="$NAME $2"
		shift; shift
		continue
	fi		
	if [ "$1" = "-bridge" ]; then
		BRIDGE="$2"
		shift; shift
		continue
	fi		
	if [ "$1" = "-upgrade-conf" -o "$1" = "--upgrade-conf" ]; then
		# hidden options to upgrade from an older version
		UPGRADE_CONF="$2"
		if [ ! -e "$UPGRADE_CONF" ]; then
			echo "Cannot read $UPGRADE_CONF"
			exit 1
		fi
		shift; shift
		continue
	fi		
	if [ "$1" = "-import-conf" -o "$1" = "--import-conf" ]; then
	        IMPORTFILE="$2"
		if [ ! -e "$IMPORTFILE" ]; then
			echo "Cannot read $IMPORTFILE"
			exit 1
		fi
		shift; shift
		continue
	fi
	if [ "$1" = "-dhcpd" -o "$1" = "--dhcpd" ]; then
		DHCPD="$2"
		shift; shift
		continue
	fi		
	if [ "$1" = "-dhcp_user" -o "$1" = "--dhcp_user" ]; then
		DHCPC_USER="$2"
		shift; shift
		continue
	fi		
	if [ "$1" = "-nodes" ]; then
		NODES="${2}"
		shift; shift
		continue
	fi		
	if [ "$1" = "-ccp" -o "$1" = "--cc-port" ]; then
		CC_PORT="$2"
		shift; shift
		continue
	fi		
	if [ "$1" = "-ncp" -o "$1" = "--nc-port" ]; then
		NC_PORT="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "-instances" -o "$1" = "--instances" ]; then
		INSTANCE="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "-user" -o "$1" = "--user" ]; then
		EUCA_USER="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "-hypervisor" -o "$1" = "--hypervisor" ]; then
		if [ "$2" != "xen" -a "$2" != "kvm" ]; then
			echo "Only kvm or xen are supported at the moment"
			exit 1
		fi
		HYPERVISOR="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "-cloudp" ]; then
		if [ $# -lt 3 ]; then
			echo "We need 2 ports for cloud controller"
			exit 1
		fi
# doesn't work right now
#		CLOUD_PORT="$2"
#		CLOUD_SSL_PORT="$3"
		shift; shift; shift
		continue
	fi
	if [ "$1" = "--get-credentials" ]; then
	        CREDENTIALZIPFILE="${2}"
		shift; shift;
		continue
	fi
	if [ "$1" = "-addnode" -o "$1" = "--register-nodes" ]; then 
		NEWNODES="${2}"
		NODEMODE="ADD"
		shift; shift
		continue
	fi
	if [ "$1" = "-delnode" -o "$1" = "--deregister-nodes" ]; then 
		NEWNODES="${2}"
		NODEMODE="REM"
		shift; shift
		continue
	fi
	if [ "$1" = "--register-walrus" ]; then
		WALRUS_MODE="ADD"
		WALRUS="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "--deregister-sc" ]; then
		SC_MODE="DEL"
		SCNAME="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "--register-sc" ]; then
		if [ $# -lt 3 ]; then
			echo "--register-sc requires a CC and a hostname"
			exit 1
		fi
		SC_MODE="ADD"
		SCNAME="$2"
		SCHOST="$3"
		shift; shift; shift
		continue
	fi
	if [ "$1" = "-addcluster" -o "$1" = "--register-cluster" ]; then
		if [ $# -lt 3 ]; then
			echo "--register-cluster requires a user assigned name and CC hostname"
			exit 1
		fi
		CLUSNAME="$2"
		NEWCLUS="$3"
		CLUSMODE="ADD"
		shift; shift; shift
		continue
	fi
	if [ "$1" = "--deregister-cluster" ]; then
		CLUSNAME="$2"
		CLUSMODE="DEL"
		shift; shift
		continue
	fi
	if [ "$1" = "-check" -o "$1" = "--check" ]; then 
		if [ "$2" != "cc" -a "$2" != "cloud" -a "$2" != "nc" -a "$2" != "sc" -a "$2" != "walrus" ]; then
			echo "-check requires cc, nc, sc, walrus or cloud"
			exit 1
		fi
		CHECK="$2"
		shift; shift
		continue
	fi
	if [ "$1" = "--enable" ]; then 
		if [ "$2" != "cloud" -a "$2" != "sc" -a "$2" != "walrus" ]; then
			echo "--enable requires cloud, sc or walrus"
			exit 1
		fi
		ENABLED="$ENABLED $2"
		shift; shift
		continue
	fi
	if [ "$1" = "--disable" ]; then 
		if [ "$2" != "cloud" -a "$2" != "sc" -a "$2" != "walrus" ]; then
			echo "--disable requires cloud, sc or walrus"
			exit 1
		fi
		DISABLED="$DISABLED $2"
		shift; shift
		continue
	fi
	if [ "$1" = "-sync" -o "$1" = "--sync" ]; then 
		if [ "$2" != "cc" -a "$2" != "cloud" -a "$2" != "nc" -a "$2" != "sc" -a "$2" != "walrus" ]; then
			echo "-sync requires cc, nc, sc, walrus or cloud"
			exit 1
		fi
		TOSYNC="$2"
		shift; shift
		continue
	fi
	usage 
	exit 1
done

if [ -z "${FILE}" -o ! -f "${FILE}" ]; then
	echo "$FILE is not a valid eucalyptus configuration file"
	exit  1
fi

# if asked to print the version that's all we do
if [ "$VERSION" = "Y" ]; then
	. $FILE

	if [ -e $EUCALYPTUS/etc/eucalyptus/eucalyptus-version ]; then
		VERSION="$EUCALYPTUS/etc/eucalyptus/eucalyptus-version"
	elif [ -e //etc/eucalyptus/eucalyptus-version ]; then
		VERSION="//etc/eucalyptus/eucalyptus-version"
	fi
	if [ -n "$VERSION" ]; then
		echo -n "Eucalyptus version: "
		cat $VERSION 
	else
		echo "Cannot find eucalyptus installation!"
		exit 1
	fi
	exit 0
fi

# let's change the value
if [ -n "$EUCALYPTUS" ]; then
	change_var_value $FILE EUCALYPTUS "${EUCALYPTUS}"
fi
if [ -n "$CC_PORT" ]; then
	change_var_value $FILE CC_PORT "${CC_PORT}"
fi
if [ -n "$NC_PORT" ]; then
	change_var_value $FILE NC_PORT "${NC_PORT}"
fi
if [ -n "$CLOUD_PORT" ]; then
	change_var_value $FILE CLOUD_PORT "${CLOUD_PORT}"
fi
if [ -n "$CLOUD_SSL_PORT" ]; then
	change_var_value $FILE CLOUD_SSL_PORT "${CLOUD_SSL_PORT}"
fi
if [ -n "$INSTANCE" ]; then
	change_var_value $FILE INSTANCE_PATH "${INSTANCE}"
fi
if [ -n "$DHCPD" ]; then
	change_var_value $FILE VNET_DHCPDAEMON "${DHCPD}"
fi
if [ -n "$DHCPC_USER" ]; then
	change_var_value $FILE VNET_DHCPUSER "${DHCPC_USER}"
	uncomment $FILE VNET_DHCPUSER
fi
if [ -n "$NODES" ]; then
	change_var_value $FILE NODES "${NODES}"
fi
if [ -n "$HYPERVISOR" ]; then
	change_var_value $FILE HYPERVISOR "${HYPERVISOR}"
	uncomment $FILE HYPERVISOR
fi
if [ -n "$BRIDGE" ]; then
	change_var_value $FILE VNET_BRIDGE "${BRIDGE}"
	uncomment $FILE VNET_BRIDGE
fi
if [ -n "$EUCA_USER" ]; then
	ID="`which id 2> /dev/null`"
	if [ -n "$ID" ]; then
		if ! $ID $EUCA_USER > /dev/null 2> /dev/null ; then
			echo "WARNING: $EUCA_USER doesn't exists!"
		fi
	fi
	change_var_value $FILE EUCA_USER "${EUCA_USER}"
fi
for x in $NAME ; do
	VALUE=`cat $FILE |grep $x|cut -f 2 -d =|tr  '"' ' '`
	echo "$x=$VALUE"
done

# modify the current conf file based on an older configuration, or from import file
if [ -n "$UPGRADE_CONF" -o -n "$IMPORTFILE" ]; then
	VARS="EUCA_USER ENABLE_WS_SECURITY DISABLE_EBS HYPERVISOR LOGLEVEL SWAP_SIZE CC_PORT MANUAL_INSTANCES_CLEANUP NC_CACHE_SIZE SCHEDPOLICY NODES NC_SERVICE NC_PORT MAX_MEM MAX_CORES INSTANCE_PATH VNET_BRIDGE VNET_DHCPDAEMON VNET_DHCPUSER"
	VNET_VARS="VNET_MODE VNET_SUBNET VNET_NETMASK VNET_DNS VNET_ADDRSPERNET VNET_PUBLICIPS VNET_BROADCAST VNET_ROUTER VNET_MACMAP VNET_INTERFACE VNET_CLOUDIP VNET_LOCALIP"
	
	if [ -n "$UPGRADE_CONF" ]; then
	# source the old config
	    VARS_TO_DO=$VARS
	    VNET_VARS_TO_DO=$VNET_VARS
	    . $UPGRADE_CONF
	elif [ -n "$IMPORTFILE" ]; then
	    VARS_TO_DO=""
	    VNET_VARS_TO_DO=""
	    . $IMPORTFILE
	    for i in $VNET_VARS
	    do
		VAL="$(echo \$${i})"
		eval VAL=$VAL
		if [ -n "$VAL" ]; then
		    VNET_VARS_TO_DO="$VNET_VARS_TO_DO $i"
		fi
	    done
	fi

	# let's start from no network
	for x in $VNET_VARS_TO_DO ; do
	    comment $FILE $x
	done
	
	# modified the defined variables
	for x in $VARS_TO_DO ; do
	    y="$(echo \$${x})"
	    eval y="$y"
	    if [ -z "$y" ]; then
			# we just leave NODES uncommented even if it's empty
		    if [ "$x" != "NODES" ]; then
			comment $FILE $x
		    fi
	    else
		uncomment $FILE $x
		change_var_value $FILE $x "${y}"
	    fi
	done
	# and add the network variables
	echo >> $FILE
	echo "# network configuration from the input configuration file" >> $FILE
	for x in $VNET_VARS_TO_DO ; do
	    y="$(echo \$${x})"
	    eval y="$y"
	    if [ -n "$y" ]; then
		if [ "$x" = "VNET_INTERFACE" ]; then
			change_var_value $FILE VNET_PRIVINTERFACE "${y}"
			change_var_value $FILE VNET_PUBINTERFACE "${y}"
		else
			echo "$x=\"${y}\"" >> $FILE
		fi
	    fi
	done
fi

# we may need the location of the ssh key for eucalyptus
EUCA_HOME="`getent passwd eucalyptus|cut -f 6 -d ':'`"
if [ -f "${EUCA_HOME}/.ssh/id_rsa.pub" ]; then
	SSHKEY=`cat ${EUCA_HOME}/.ssh/id_rsa.pub`
else
	SSHKEY=""
fi

# we need defaults in eucalyptus.conf
. $FILE

# first time setup
if [ -n "$SETUP" ]; then
	ROOTWRAP="$EUCALYPTUS/usr/lib/eucalyptus/euca_rootwrap"
	
	# first of all setup euca_rootwrap
	if [ ! -x "$ROOTWRAP" ]; then
		echo "Cannot find $ROOTWRAP (or not readable)!"
		exit 1
	fi
	# get EUCA group
	if [ -z "$EUCA_USER" ]; then
		echo "Is EUCA_USER defined?"
		exit 1
	fi
	# if running as root no need to do anything
	if [ "$EUCA_USER" != "root" ]; then
		ID="`which id 2> /dev/null`"
		if [ -z "$ID" ]; then
			echo "Cannot find command $ID"
			exit 1
		fi
		if ! $ID $EUCA_USER > /dev/null 2> /dev/null ; then
			echo "User $EUCA_USER doesn't exists!"
			exit 1
		fi
		EUCA_GROUP="`$ID -ng $EUCA_USER 2>/dev/null`"
		if [ -z "$EUCA_GROUP" ]; then
			echo "Cannot detect $EUCA_USER group"
			exit 1
		fi
		if ! chown root:$EUCA_GROUP $ROOTWRAP ; then
			exit 1
		fi
		if ! chmod 4750 $ROOTWRAP ; then
			exit 1
		fi
	fi
	
	# let's create the instance path
	if [ -n "$INSTANCE_PATH" -a "$INSTANCE_PATH" != "not_configured" -a ! -d "$INSTANCE_PATH" ]; then
		if ! mkdir -p $INSTANCE_PATH ; then
			echo "Failed to create instance path!"
			exit 1
		fi
		if ! chown $EUCA_USER:$EUCA_GROUP $INSTANCE_PATH ; then
			exit 1
		fi
	fi

	chown -R $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/lib/eucalyptus
	ret=$?
	chown -R $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/log/eucalyptus
	let $((ret += $?))
	chown -R $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/run/eucalyptus
	let $((ret += $?))
	chown $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/etc/eucalyptus/eucalyptus.conf
	let $((ret += $?))

	# let's create more needed directory with the right permissions
	mkdir -p $EUCALYPTUS/var/lib/eucalyptus/db
	let $((ret += $?))
	chown $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/lib/eucalyptus/db
	let $((ret += $?))
	chmod 700 $EUCALYPTUS/var/lib/eucalyptus/db
	let $((ret += $?))
	mkdir -p $EUCALYPTUS/var/lib/eucalyptus/keys
	let $((ret += $?))
	chown $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/lib/eucalyptus/keys
	let $((ret += $?))
	chmod 700 $EUCALYPTUS/var/lib/eucalyptus/keys
	let $((ret += $?))
	mkdir -p $EUCALYPTUS/var/lib/eucalyptus/CC
	let $((ret += $?))
	chown $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/lib/eucalyptus/CC
	let $((ret += $?))
	chmod 700 $EUCALYPTUS/var/lib/eucalyptus/CC
	let $((ret += $?))

	exit $ret
fi

if [ -n "$TOSYNC" ]; then
    echo "not implemented"
fi

# pre-flight checks
if [ -n "$CHECK" ]; then
	ROOTWRAP="$EUCALYPTUS/usr/lib/eucalyptus/euca_rootwrap"

	# vblade and aoe may be needed
	if [ "$DISABLE_EBS" != "Y" -a "$DISABLE_EBS" != "y" ]; then
		if [ "$CHECK" = "sc" ]; then
			VBLADE="`which vblade 2> /dev/null`"
			if [ -z "$VBLADE" ]; then
				echo
				echo "ERROR: EBS is enabled and vblade was not found"
				exit 1
			fi
		fi
	fi
	
	# first of all check euca_rootwrap
	if [ ! -x $ROOTWRAP ]; then
		echo "Cannot find euca_rootwrap!"
		exit 1
	fi
	# get EUCA group
	if [ -z "$EUCA_USER" ]; then
		echo "Running eucalyptus as root"
		EUCA_USER="root"
		EUCA_GROUP="root"
	fi
	# if running as root no need to do anything
	if [ "$EUCA_USER" != "root" ]; then
		ID="`which id 2> /dev/null`"
		if [ -z "$ID" ]; then
			echo "Cannot find command id"
			exit 1
		fi
		if ! $ID $EUCA_USER > /dev/null 2> /dev/null ; then
			echo "User $EUCA_USER doesn't exists!"
			exit 1
		fi
		EUCA_GROUP="`$ID -ng $EUCA_USER 2>/dev/null`"
		if [ -z "$EUCA_GROUP" ]; then
			echo "Cannot detect $EUCA_USER group: using $EUCA_USER"
			exit 1
		fi
		# need to check if euca_rootwrap can run as EUCA_USER
                TEST_EUID="`sudo -u $EUCA_USER $ROOTWRAP $ID -u`"
		if [ "$?" != "0" -o "$TEST_EUID" != "0" ]; then
			echo "Problem running $ROOTWRAP! Did you run euca_conf -setup?"
			exit 1
		fi
	fi

	# let's be sure we have the INSTANCE_PATH
	if [ "$CHECK" = "nc" ]; then
		if [ -z "$INSTANCE_PATH" ]; then
			echo "INSTANCE_PATH is not defined"
			exit 1
		fi
		if [ ! -d "$INSTANCE_PATH" ]; then
			echo "$INSTANCE_PATH doesn't exist: did you run euca_conf -setup?"
			exit 1
		fi
	fi

	# let's set up directories which could disappears if /var/run is
	# in memory
	if [ ! -d $EUCALYPTUS/var/run/eucalyptus ]; then
		if ! mkdir -p $EUCALYPTUS/var/run/eucalyptus ; then
			# error should come from mkdir
			exit 1
		fi
	fi
	if ! chown $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/run/eucalyptus ; then
	    # error should come from chown
	    exit 1
	fi


	if [ "$CHECK" = "cc" ]; then
	    if [ ! -d $EUCALYPTUS/var/run/eucalyptus/net ]; then
		if ! mkdir -p $EUCALYPTUS/var/run/eucalyptus/net ; then
			# error should come from mkdir
		    exit 1
		fi
	    fi
	    if ! chown $EUCA_USER:$EUCA_GROUP $EUCALYPTUS/var/run/eucalyptus/net ; then
			# error should come from chown
		exit 1
	    fi
	fi
	# good to go
	exit 0
fi

createCloudURL () {
    if ! getSecretKey; then
	echo "ERROR: cannot get credentials"
	return 1
    fi
    ARGS="AWSAccessKeyId=$AKEY"
    KEY=$1
    shift
    VAL=$1
    shift
    while ( test -n "$KEY" -a -n "$VAL")
    do
	ARGS="${ARGS}&${KEY}=${VAL}"
	KEY=$1
	shift
	VAL=$1
	shift
    done
    if [ -z "$SKEY" ]; then
	echo "ERROR: SKEY parameter is not set."
	export URL=""
	return 1
    fi
    ARGS="${ARGS}&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=$(date -u '+%Y-%m-%dT%H%%3A%M%%3A%S.000Z')&Version=eucalyptus"
    SIGNATURE=$(echo -en "GET\n127.0.0.1\n/services/Configuration\n${ARGS}" | openssl dgst -sha256 -hmac ${SKEY} -binary | openssl base64)
    export URL="http://127.0.0.1:8773/services/Configuration?${ARGS}&Signature=${SIGNATURE}"
	if [ "$VERBOSE" = "Y" ]; then
		echo $URL
	fi
    return 0
}

getSecretKey() {
    if [ -d "$EUCALYPTUS/var/lib/eucalyptus/db/" ]; then
	DBDIR="$EUCALYPTUS/var/lib/eucalyptus/db/"
    else
	echo "ERROR: cannot locate eucalyptus database, try logging in through the admin web interface."
	exit 1
    fi

    FIELD=`grep -i "CREATE .*TABLE AUTH_USERS" ${DBDIR}/*auth* | sed 's/,/\n/g' | awk '/[Uu][Ss][Ee][Rr]_[Ss][Ee][Cc][Rr][Ee][Tt][Kk][Ee][Yy]/ {print NR}'`
    if [ "$FIELD" = "" ]; then
	echo "ERROR: cannot locate entry in eucalyptus database, try logging in through the admin web interface"
	export SKEY=""
	return 1
    fi
    SKEY=$(eval echo $(awk -v field=${FIELD} -F, '/INSERT INTO AUTH_USERS.*admin/ {print $field}' ${DBDIR}/*auth* | head -n 1))

   FIELD=`grep -i "CREATE .*TABLE AUTH_USERS" ${DBDIR}/*auth* | sed 's/,/\n/g' | awk '/[Uu][Ss][Ee][Rr]_[Qq][Uu][Ee][Rr][Yy]_[Ii][Dd]/ {print NR}'`
   if [ "$FIELD" = "" ]; then
     echo "ERROR: cannot locate entry in eucalyptus database, try logging in through the admin web interface"
     export AKEY=""
     return 1
   fi
   AKEY=$(eval echo $(awk -v field=${FIELD} -F, '/INSERT INTO AUTH_USERS.*admin/ {print $field}' ${DBDIR}/*auth* | head -n 1))

    return 0
}

checkLocalService() {
    local SERVICE=""
    
    if [ -z "$WGET" -o ! -x "$WGET" ]; then
	echo "ERROR: wget is missing, cannot continue."
	return 1
    fi

    SERVICE="$1"
    if [ -z "$SERVICE" ]; then
	echo "ERROR: must pass in service name (CLC, CC)"
	return 1
    elif [ "$SERVICE" = "CLC" ]; then
	if [ -n "$FAKEREG" ]; then
	    local SOURCEDIR="$EUCALYPTUS/var/lib/eucalyptus/keys/"
	    for i in cloud
	    do 
		if [ ! -e "$SOURCEDIR/${i}-cert.pem" -o ! -e "$SOURCEDIR/${i}-pk.pem" ]; then
		    openssl req -new -nodes -x509 -out $SOURCEDIR/${i}-cert.pem -keyout $SOURCEDIR/${i}-pk.pem -days 365 -subj "/C=US/ST=CA/L=City/CN=localhost/emailAddress=root@localhost"
		fi
	    done
	fi
	
	CMD="$WGET -T 10 -t 1 -O - -q --no-check-certificate https://127.0.0.1:8443/register | grep CloudVersion >/dev/null"
    elif [ "$SERVICE" = "CC" ]; then
	CMD="$WGET -T 10 -t 1 -O - -q http://127.0.0.1:8774/axis2/services/ | grep EucalyptusCC >/dev/null"
    fi
    
    if [ -n "${FAKEREG}" ]; then
	CMD="echo"
    fi
    if ! eval $CMD ; then
	echo "ERROR: you need to be on the $SERVICE host and the $SERVICE needs to be running."
	return 1
    fi  
    return 0
}

if [ -n "$CREDENTIALZIPFILE" ]; then
    if [ -f "$CREDENTIALZIPFILE" ]; then
	echo "file '$CREDENTIALZIPFILE' already exists, please remove and try again"
	exit 1
    fi
    if ! checkLocalService "CLC" ; then
	exit 1
    fi

    if [ -d "$EUCALYPTUS/var/lib/eucalyptus/db/" ]; then
	DBDIR="$EUCALYPTUS/var/lib/eucalyptus/db/"
    else
	echo "ERROR: cannot locate eucalyptus database, try logging in through the admin web interface."
        exit 1
    fi
    FIELD=`grep -i "CREATE .*TABLE USERS" ${DBDIR}/* | sed 's/,/\n/g' | awk '/[Uu][Ss][Ee][Rr]_[Cc][Ee][Rr][Tt][Ii][Ff][Ii][Cc][Aa][Tt][Ee]_[Cc][Oo][Dd][Ee]/ {print NR}'`
    if [ -z "$FIELD" ]; then
	echo "cannot find code field in database, please go to the Eucalyptus web UI to obtain credentials."
	exit 1
    fi
    KEY=$(eval echo $(awk -v field=${FIELD} -F, '/INSERT INTO USERS.*admin/ {print $field}' ${DBDIR}/* | head -n 1))
    if [ -z "$KEY" ]; then
	echo "cannot find code in database, please go to the Eucalyptus web UI to obtain credentials."
	exit 1
    fi
    CMD="$WGET --no-check-certificate \"https://localhost:8443/getX509?user=admin&code=$KEY\" -O $CREDENTIALZIPFILE"
    if ! eval $CMD ; then
	echo "failed to obtain credentals, please try again or go to the Eucalyptus web UI."
	exit 1
    fi
fi

# adding a new cluster
if [ -n "$CLUSNAME" ]; then
    if ! checkLocalService "CLC" ; then
	exit 1
    fi

    if [ "$CLUSMODE" = "ADD" ]; then
	if [ -d "${EUCALYPTUS}/var/lib/eucalyptus/keys/" ]; then
	    SOURCEDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/${CLUSNAME}/
	    DESTDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	else
	    echo "ERROR: cannot find key directory ($EUCALYPTUS/var/lib/eucalyptus/keys), check that your installation was successful!"
	    exit 1
	fi
	
	URL=""
	if ! createCloudURL "Action" "RegisterCluster" "Host" "${NEWCLUS}" "Name" "${CLUSNAME}" "Port" "${CC_PORT}"; then
	    exit 1
	fi
	
	if ! check_ws "$URL" ; then
		echo "ERROR: failed to register new cluster, please log in to the admin interface and check cloud status."
		exit 1
	fi
	
	if [ -n "${FAKEREG}" ]; then
	    mkdir -p $SOURCEDIR
	    if [ -n "${FAKEREG}" ]; then
		mkdir -p $SOURCEDIR
		for i in cluster node
		do 
		    if [ ! -e "$SOURCEDIR/${i}-cert.pem" -o ! -e "$SOURCEDIR/${i}-pk.pem" ]; then
			openssl req -new -nodes -x509 -out $SOURCEDIR/${i}-cert.pem -keyout $SOURCEDIR/${i}-pk.pem -days 365 -subj "/C=US/ST=CA/L=City/CN=localhost/emailAddress=root@localhost"
		    fi
		done
	    fi
	fi
	
        # sync the keys
	if ! sync_keys "${DESTDIR},${SOURCEDIR}" ${DESTDIR} ${NEWCLUS} node-cert.pem cluster-cert.pem cluster-pk.pem node-pk.pem vtunpass cloud-cert.pem; then
	    echo "ERROR: failed to sync keys with ${NEWCLUS}; registration will not be complete until keys can be synced, please try again."
	    exit 1
	fi
	echo
	echo "SUCCESS: new cluster '${CLUSNAME}' on host '${NEWCLUS}' successfully registered."
    elif [ "$CLUSMODE" = "DEL" ]; then
	URL=""
	# let's see if we have such a cluster
	LIST_RES=""
	if ! createCloudURL "Action" "DescribeClusters" ; then
		exit 1
	fi
	if ! check_ws "$URL" LIST_RES ; then
		echo "ERROR: cannot talk with CLC"
		exit 1
	fi
	FOUND="N"
	for x in $LIST_RES ; do
		if [ "$x" = "${CLUSNAME}" ]; then
			FOUND="Y"
			break
		fi
	done
	if [ "$FOUND" = "N" ]; then
		echo "No registered cluster $CLUSNAME was found"
		exit 1
	fi

	# now let's deregister
	URL=""
	if ! createCloudURL "Action" "DeregisterCluster" "Name" "${CLUSNAME}"; then
	    exit 1
	fi
	
	if ! check_ws "$URL" ; then
		echo "ERROR: failed to deregister new cluster, please log in to the admin interface and check cloud status."
		exit 1
	fi	
	echo
	echo "SUCCESS: cluster '${CLUSNAME}' successfully deregistered."
    fi
fi

# walrus
if [ -n "$WALRUS" -o -n "$WALRUS_MODE" ]; then
    if ! checkLocalService "CLC" ; then
	exit 1
    fi
    
    if [ "$WALRUS_MODE" = "ADD" ]; then
	echo "Adding WALRUS host $WALRUS"
	if [ -d "${EUCALYPTUS}/var/lib/eucalyptus/keys/" ]; then
	    SOURCEDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	    DESTDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	else
	    echo "ERROR: cannot find key directory ($EUCALYPTUS/var/lib/eucalyptus/keys), check that your installation was successful!"
	    exit 1
	fi
	
	URL=""
	if ! createCloudURL "Action" "RegisterWalrus" "Host" "${WALRUS}" "Name" "walrus" "Port" "8773"; then
	    exit 1
	fi

	if ! check_ws "$URL" ; then
	    echo "ERROR: failed to register Walrus, please log in to the admin interface and check cloud status."
	    exit 1
	fi
	
	# check that walrus is at least running on the remote host
	sleep 3
	if ! check_heartbeat ${WALRUS} walrus ; then
		echo "WARNING: Walrus is not up on host ${WALRUS};  registration will not be complete until walrus is running."
	fi
	
	# sync the keys
	if ! sync_keys ${SOURCEDIR} ${DESTDIR} ${WALRUS} euca.p12 ; then
	    echo "ERROR: failed to sync keys with ${WALRUS}; registration will not be complete until keys can be synced, please try again."
            exit 1
	fi
	echo
	echo "SUCCESS: new walrus on host '${WALRUS}' successfully registered."
	
    elif [ "$WALRUS_MODE" = "DEL" ]; then
	URL=""
	if ! createCloudURL "Action" "DeregisterWalrus" "Name" "walrus"; then
	    exit 1
	fi
	if ! check_ws "$URL" ; then
	    echo "ERROR: failed to deregister Walrus, please log in to the admin interface and check cloud status."
	    exit 1
	fi
        echo
        echo "SUCCESS: Walrus successfully deregistered."
    fi
fi

# sc
if [ -n "$SCNAME" ]; then
    if ! checkLocalService "CLC" ; then
	exit 1
    fi
    
    if [ "$SC_MODE" = "ADD" ]; then
	echo "Adding SC $SCHOST to cluster $SCNAME"
	if [ -d "${EUCALYPTUS}/var/lib/eucalyptus/keys/" ]; then
	    SOURCEDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	    DESTDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	else
	    echo "ERROR: cannot find key directory ($EUCALYPTUS/var/lib/eucalyptus/keys), check that your installation was successful!"
	    exit 1
	fi
	
	URL=""
	if ! createCloudURL "Action" "RegisterStorageController" "Host" "${SCHOST}" "Name" "${SCNAME}" "Port" "8773"; then
	    exit 1
	fi
	if ! check_ws "$URL"; then
	    echo "ERROR: failed to register storage controller, please log in to the admin interface and check cloud status."
	    exit 1
	fi
	if [ -n "${FAKEREG}" ]; then
	    mkdir -p $SOURCEDIR
	    for i in sc
	    do 
		if [ ! -e "$SOURCEDIR/${i}-cert.pem" -o ! -e "$SOURCEDIR/${i}-pk.pem" ]; then
		    openssl req -new -nodes -x509 -out $SOURCEDIR/${i}-cert.pem -keyout $SOURCEDIR/${i}-pk.pem -days 365 -subj "/C=US/ST=CA/L=City/CN=localhost/emailAddress=root@localhost"
		fi
	    done
	fi
    
    # sync the keys
	if ! sync_keys ${SOURCEDIR} ${DESTDIR} ${SCHOST} euca.p12; then
	    echo "ERROR: failed to sync keys with ${SCHOST}; registration will not be complete until keys can be synced, please try again."
	    exit 1
	fi
	echo
	echo "SUCCESS: new SC for cluster '${SCNAME}' on host '${SCHOST}' successfully registered."

    elif [ "$SC_MODE" = "DEL" ]; then
	# let's see if we have such a storage controller
	LIST_RES=""
	if ! createCloudURL "Action" "DescribeStorageControllers" ; then
		exit 1
	fi
	if ! check_ws "$URL" LIST_RES ; then
		echo "ERROR: cannot talk with CLC"
		exit 1
	fi
	FOUND="N"
	for x in $LIST_RES ; do
		if [ "$x" = "${SCNAME}" ]; then
			FOUND="Y"
			break
		fi
	done
	if [ "$FOUND" = "N" ]; then
		echo "No registered storage controller $SCNAME was found"
		exit 1
	fi

	# now let's deregister
	URL=""
	if ! createCloudURL "Action" "DeregisterStorageController" "Name" "${SCNAME}"; then
	    exit 1
	fi
	if ! check_ws "$URL" ; then
	    echo "ERROR: failed to deregister StorageController, please log in to the admin interface and check cloud status."
	    exit 1
	fi
	echo
	echo "SUCCESS: Storage controller for cluster '${SCNAME}' successfully deregistered."
    fi
fi

# operations on the nodes
if [ -n "$NODEMODE" ]; then
	# for synckey we fake addnodes
	if [ "$NODEMODE" = "SYNC" ]; then
		if [ -z "$NODES" ]; then
			echo "Warning: there are no NODES configured"
		else
			NEWNODES="${NODES}"
			NODEMODE="ADD"
		fi
	fi

	# check we have a valid command
	if [ "$NODEMODE" != "ADD" -a "$NODEMODE" != "REM" ]; then
		echo "ERROR: unknown mode '$NODEMODE', don't know what to do"
		exit 1
	fi

	if [ -d "${EUCALYPTUS}/var/lib/eucalyptus/keys/" ]; then
	    SOURCEDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	    DESTDIR=${EUCALYPTUS}/var/lib/eucalyptus/keys/
	else
	    echo "ERROR: cannot find key directory ($EUCALYPTUS/var/lib/eucalyptus/keys), check that your installation was successful and that this cluster is already registered!"
	    exit 1
	fi
	
	# CC needs to be running 
	if ! checkLocalService "CC" ; then
	    exit 1
	fi

	# warn the user on where we expect the keys to be
	if [ "$NODEMODE" = "ADD" ]; then 
		echo
		echo "INFO: We expect all nodes to have eucalyptus installed in $EUCALYPTUS for key synchronization."
	fi

	# adding (or removing) nodes
	for NEWNODE in ${NEWNODES} ; do
		# remove is simpler: just remove the node name
		if [ "$NODEMODE" = "REM" ]; then
			if ! echo "$NODES"|grep "${NEWNODE}" > /dev/null ; then
				echo "Node ${NEWNODE} is not known"
				continue
			fi
			NODES="`echo $NODES|sed \"s/${NEWNODE}//\"|tr -s ' '`"
			change_var_value $FILE NODES "${NODES}"
			echo "SUCCESS: removed node '${NEWNODE}' from '$FILE'"
			continue
		fi

		# let's sync keys with the nodes
		if ! sync_keys ${SOURCEDIR} ${DESTDIR} ${NEWNODE} node-cert.pem cluster-cert.pem node-pk.pem cloud-cert.pem; then
			echo
			echo "ERROR: could not synchronize keys with $NEWNODE!"
			echo "The configuration will not have this node."
			if [ "$SSHKEY" = "" ]; then
				echo "User $EUCA_USER may have to run ssh-keygen!"
			else
				echo "Hint: to setup passwordless login to the nodes as user $EUCA_USER, you can"
				echo "run the following commands on node $NEWNODE:"
				echo "sudo -u $EUCA_USER mkdir -p ~${EUCA_USER}/.ssh"
				echo "sudo -u $EUCA_USER tee ~${EUCA_USER}/.ssh/authorized_keys > /dev/null <<EOT"
				echo "$SSHKEY"
				echo "EOT"
				echo ""
				echo "Be sure that authorized_keys is not group/world readable or writable"
			fi
			continue
		fi
 
		# NODES list
		if ! echo "${NODES}"|grep "${NEWNODE}" > /dev/null ; then
			# node is not present: we need to add it
			NODES="${NODES} $NEWNODE"
			change_var_value $FILE NODES "${NODES}"
		fi
	done
fi


for x in $LIST ; do
	LIST_RES=""

	if [ "$x" = "walruses" ]; then
		if ! createCloudURL "Action" "DescribeWalruses" ; then
			exit 1
		fi
		if ! check_ws "$URL" LIST_RES ; then
			exit 1
		fi
		if [ -n "$LIST_RES" ]; then
			echo "registered walruses:"
		fi
		echo "$LIST_RES"
	fi
	if [ "$x" = "storages" ]; then
		if ! createCloudURL "Action" "DescribeStorageControllers" ; then
			exit 1
		fi
		if ! check_ws "$URL" LIST_RES ; then
			exit 1
		fi
		if [ -n "$LIST_RES" ]; then
			echo "registered storage controllers:"
		fi
		echo "$LIST_RES"
	fi
	if [ "$x" = "clusters" ]; then
		if ! createCloudURL "Action" "DescribeClusters" ; then
			exit 1
		fi
		if ! check_ws "$URL" LIST_RES ; then
			exit 1
		fi
		if [ -n "$LIST_RES" ]; then
			echo "registered clusters:"
		fi
		echo "$LIST_RES"
	fi
	if [ "$x" = "nodes" ]; then
		if ! createCloudURL "Action" "DescribeNodes" ; then
			exit 1
		fi
		if ! check_ws "$URL" LIST_RES ; then
			exit 1
		fi
		if [ -n "$LIST_RES" ]; then
			echo "registered nodes:"
		fi
		echo "$LIST_RES"
	fi
done


# enable/disable services
if [ -r $EUCALYPTUS/var/lib/eucalyptus/services ]; then
	for x in `cat $EUCALYPTUS/var/lib/eucalyptus/services` ; do
		TO_START="$TO_START $x"
	done
fi
if [ -n "$DISABLED" -o -n "$ENABLED" ]; then
	for x in $TO_START $ENABLED ; do
		to_start="Y"
		for y in $DISABLED ; do
			if [ "$x" = "$y" ]; then
				to_start="N"
			fi
		done
		[ $to_start = "Y" ] && echo $x
	done | sort | uniq > $EUCALYPTUS/var/lib/eucalyptus/services
fi
