#!/bin/sh
# (C) Copyright 2013-present, Skylable Ltd. <info-copyright@skylable.com>
# All Rights Reserved.

OPTNUM=1
while [ $OPTNUM -le $# ]; do
    eval "OPTION=\$$OPTNUM"

    if [ "$OPTION" = "--help" -o "$OPTION" = "-h" ]; then
	HELP_GIVEN="yes"
    elif [ "$OPTION" = "--version" -o "$OPTION" = "-V" ]; then
	VERSION_GIVEN="yes"
    elif [ "$OPTION" = "--info" -o "$OPTION" = "-i" ]; then
	INFO_GIVEN="yes"
    elif [ "$OPTION" = "--upgrade" ]; then
	UPGRADE_GIVEN="yes"
    elif [ "$OPTION" = "--config-file" ]; then
	CONFIG_FILE_GIVEN="yes"
	OPTNUM=`expr $OPTNUM + 1`
	eval "CONFIG_FILE=\$$OPTNUM"
	if [ -z "$CONFIG_FILE" ]; then
	    echo "--config-file requires a file argument"
	    exit 1
	fi
	if [ ! -f "$CONFIG_FILE" ]; then
	    echo "--config-file requires a valid config file"
	    exit 1
	fi

    elif [ "$OPTION" = "--advanced" ]; then
	ADVANCED_GIVEN="yes"

    elif [ "$OPTION" = "--no-remote-copy" ]; then
	NO_REMOTE_COPY_GIVEN="yes"

    elif [ "$OPTION" = "--bare" ]; then
	BARE_GIVEN="yes"

    elif [ "$OPTION" = "--force-reinit" ]; then
	FORCE_REINIT_GIVEN="yes"

    elif [ "$OPTION" = "--compact" ]; then
	COMPACT_GIVEN="yes"

    elif [ "$OPTION" = "--deactivate" ]; then
	DEACTIVATE_GIVEN="yes"

    elif [ "$OPTION" = "--wait" ]; then
	WAIT_GIVEN="yes"

    elif [ "$OPTION" = "--debug" ]; then
	DEBUG_GIVEN="yes"
    else
	echo "ERROR: Unknown option '$OPTION'"
	exit 1
    fi
    OPTNUM=`expr $OPTNUM + 1`
done

if [ "$HELP_GIVEN" = "yes" ]; then
    echo "SX Setup Script"
    echo
    echo "sxsetup performs interactive or automated configuration of a node"
    echo "and displays its existing configuration."
    echo
    echo "Usage: $0 [OPTIONS]"
    echo
    echo "-h, --help              Print help and exit"
    echo "-V, --version           Print version and exit"
    echo "-i, --info              Show current node configuration and exit"
    echo "    --upgrade           Upgrade local storage format and cluster databases to the latest version"
    echo "    --config-file FILE  Use config FILE to configure the node automatically"
    echo "    --advanced          Enable advanced configuration"
    echo "    --no-remote-copy    Don't make and use remote copy of sxsetup.conf"
    echo "    --bare              Create a bare (unprogrammed) node"
    echo "    --force-reinit      Overwrite existing configuration"
    echo "    --compact           Compact the local storage of the node"
    echo "    --deactivate        Leave cluster and deactivate the node"
    echo "    --wait              Wait till rebalance finishes after joining the cluster"
    echo "    --debug             Turn on debug mode for the created node"
    echo
    exit 0
fi

if [ "$VERSION_GIVEN" = "yes" ]; then
    echo "sxsetup 2.0"
    exit 0
fi

CFG_VERSION=3
ETCDIR="/etc"
CONFIG="$ETCDIR/sxserver/sxsetup.conf"

if [ "$INFO_GIVEN" = "yes" -o "$UPGRADE_GIVEN" = "yes" -o "$COMPACT_GIVEN" = "yes" ]; then
    if [ ! -f "$CONFIG" ]; then
	echo "Not configured. You have to run sxsetup in configuration mode first."
	exit 1
    fi
    if [ ! -r "$CONFIG" ]; then
	echo "No permission to read $CONFIG"
	exit 1
    fi
    . $CONFIG
    test -z "$SX_NO_ROOT" && OWNERFLAG="--owner=$SX_SERVER_USER:$SX_SERVER_GROUP"
    if [ "$INFO_GIVEN" = "yes" ]; then
	echo "--- SX INFO ---"
	echo "SX Version: `/usr/sbin/sx.fcgi --version | cut -d\  -f2`"
	echo "Cluster name: $SX_CLUSTER_NAME"
	echo "Cluster port: $SX_PORT"
	/usr/sbin/sxadm node $OWNERFLAG --info --human-readable $SX_DATA_DIR | grep -v "HashFS Version"
	echo "Storage location: $SX_DATA_DIR"
	test "$SX_USE_SSL" = "yes" && echo "SSL private key: $SX_SSL_KEY_FILE"
	echo "SX Logfile: $SX_LOG_FILE"
	exit 0

    elif [ "$COMPACT_GIVEN" = "yes" ]; then
	echo "The node will be stopped now and started again when compacting is finished"
	"/usr/sbin/sxserver" stop
	"/usr/sbin/sxadm" node $OWNERFLAG --human-readable --compact $SX_DATA_DIR
	"/usr/sbin/sxserver" start
	exit 0
    else
	# Update config files if needed and possible
	if [ -n "`grep 'children=32' $ETCDIR/sxserver/sxfcgi.conf`" -a -z "`grep reserved-children $ETCDIR/sxserver/sxfcgi.conf`" -a -z "`grep 'location /.s2s/' $ETCDIR/sxserver/sxhttpd.conf`" ]; then
	    echo "Enabling support for reserved workers..."
	    # update sxfcgi.conf
	    sed -i.old -e 's/children=32/children=24/' $ETCDIR/sxserver/sxfcgi.conf
	    echo "reserved-socket=\"$SX_RUN_DIR/sxfcgi-reserved.socket\"" >> $ETCDIR/sxserver/sxfcgi.conf
	    echo "reserved-children=8" >> $ETCDIR/sxserver/sxfcgi.conf

	    # update sxhttpd.conf
	    echo "Updating sxhttpd.conf (s2s)"
	    sed -i.old_s2s -e "s|location / {|location /.s2s/ {\\
                 fastcgi_pass unix:$SX_RUN_DIR/sxfcgi-reserved.socket;\\
                 fastcgi_store off;\\
                 fastcgi_read_timeout 300s;\\
                 fastcgi_max_temp_file_size 0;\\
                 include fastcgi_params;\\
             }\\
	     location / {|" $ETCDIR/sxserver/sxhttpd.conf
	    RESTART_SXSERVER="yes"
	fi

	if [ -n "`/usr/sbin/nginx -V 2>&1 | grep nginx-module-vts`" -a -z "`grep 'location /.s2s/.traffic' $ETCDIR/sxserver/sxhttpd.conf`" ]; then
	    echo "Updating sxhttpd.conf (vts)"
	    test -z "$SX_NODE_INTERNAL_IP" && SX_NODE_INTERNAL_IP=$SX_NODE_IP
	    sed -i.old_vts \
		-e "s|server {|vhost_traffic_status_zone;\\
       server{|"\
		-e "s|location / {|location /.s2s/.traffic {\\
		 vhost_traffic_status_display;\\
		 vhost_traffic_status_display_format json;\\
		 allow $SX_NODE_INTERNAL_IP;\\
		 allow 127.0.0.1;\\
		 deny all;\\
             }\\
	     location / {|" $ETCDIR/sxserver/sxhttpd.conf
	    RESTART_SXSERVER="yes"
	fi

	# Upgrade hashfs
        "/usr/sbin/sxadm" node $OWNERFLAG --info "$SX_DATA_DIR" > /dev/null 2>&1
	if [ $? -ne 0 ]; then
	    HB_DEADTIME="`/usr/sbin/sxadm cluster --get-param hb_deadtime sx://admin@$SX_CLUSTER_NAME 2>/dev/null | grep hb_deadtime | grep -v '=0$'`"
	    if [ -n "$HB_DEADTIME" ]; then
		echo "Temporarily disabling automatic node removal..."
		"/usr/sbin/sxadm" cluster --set-param hb_deadtime=0 "sx://admin@$SX_CLUSTER_NAME"
		if [ $? -ne 0 ]; then
		    echo "ERROR: Failed to update Raft settings (hb_deadtime=0)"
		    exit 1
		fi
	    fi
	    echo "Upgrading local node..."
	    "/usr/sbin/sxserver" stop
	    "/usr/sbin/sxadm" node $OWNERFLAG --upgrade "$SX_DATA_DIR"
	    if [ $? -ne 0 ]; then
		echo "ERROR: Failed to upgrade the local node"
		"/usr/sbin/sxserver" start
		test -n "$HB_DEADTIME" && "/usr/sbin/sxadm" cluster --set-param $HB_DEADTIME "sx://admin@$SX_CLUSTER_NAME" 
		exit 1
	    fi
	    "/usr/sbin/sxserver" start
	    RESTART_SXSERVER=
	else
	    echo "Local node is up-to-date."
	fi

	if [ "$RESTART_SXSERVER" = "yes" ]; then
	    "/usr/sbin/sxserver" restart
	else
	    "/usr/sbin/sxserver" start > /dev/null 2>&1
	fi

	if [ -n "$HB_DEADTIME" ]; then
	    echo "Re-enabling automatic node removal..."
	    "/usr/sbin/sxadm" cluster --set-param $HB_DEADTIME "sx://admin@$SX_CLUSTER_NAME" 
	    if [ $? -ne 0 ]; then
		echo "WARNING: Failed to update Raft settings ($HB_DEADTIME)"
		echo "Please update the settings when the cluster is fully upgraded."
	    fi
	fi

	# move remote sxsetup.conf into settings if needed
	"/usr/bin/sxls" "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
	if [ $? = 0 ]; then
	    XCONF=`cat $CONFIG | xxd -ps 2>/dev/null | tr -d '\n'`
	    if [ -n "$XCONF" ]; then
		echo "Moving remote sxsetup.conf into cluster settings..."
		"/usr/sbin/sxadm" cluster --set-param sxsetup_conf=$XCONF "sx://admin@$SX_CLUSTER_NAME" > /dev/null 2>&1
		if [ $? = 0 ]; then
		    echo "Removing _sxsetup.conf volume..."
		    "/usr/bin/sxrm" -r "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
		    "/usr/bin/sxvol" remove "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
		fi
	    fi
	fi

	# run cluster --upgrade
	OUT=`mktemp /tmp/sxsetupXXXXXXX`
	if [ $? -ne 0 ]; then
	    echo "ERROR: Failed to create temporary file"
	    exit 1
	fi
        "/usr/sbin/sxadm" cluster --upgrade "sx://admin@$SX_CLUSTER_NAME" > $OUT 2>&1
	RET=$?
	if [ $RET -eq 2 ]; then
	    cat $OUT
	    echo
	    echo "All components of the cluster are up-to-date!"
	    rm $OUT
	    exit 0
	elif [ $RET -ne 0 ]; then
	    # 2.0 doesn't require cluster upgrade
	    echo
	    if [ -n "`/usr/sbin/sxadm -V | grep '^sxadm 2.0'`" ]; then
		echo "More nodes in the cluster require upgrading."
	    else
		echo "Could not upgrade the remote cluster data at this point. Please run"
		echo "sxsetup --upgrade again when all other nodes are locally upgraded and"
		echo "online. The cluster should also get upgraded automatically after the"
		echo "last node is locally upgraded."
	    fi
	    rm $OUT
	    exit 0
	fi
	echo
	echo "Upgrading remote cluster data..."
	cat $OUT
	rm $OUT
        "/usr/sbin/sxadm" cluster --info "sx://admin@$SX_CLUSTER_NAME"
	echo
	echo "Remote upgrade started. You can monitor the progress by running:"
	echo "/usr/sbin/sxadm cluster --info sx://admin@$SX_CLUSTER_NAME"
	exit 0
    fi
fi

# Read previous answers, and initialize the defaults with them
LOAD_CONFIG=${CONFIG_FILE:-"$CONFIG"}
if [ -f "$LOAD_CONFIG" ]; then
    if [ ! -r "$LOAD_CONFIG" ]; then
	echo "No permission to read $LOAD_CONFIG"
	exit 1
    fi
    . "$LOAD_CONFIG"
    if [ -f "$SX_DATA_DIR/hashfs.db" ]; then 
	if [ "$FORCE_REINIT_GIVEN" != "yes" -a "$DEACTIVATE_GIVEN" != "yes" ]; then
	    echo "This SX node is already configured. Run sxsetup with --info to display"
	    echo "the current configuration or with --force-reinit to set it up again."
	    echo "See sxsetup --help for more options."
	    exit 1
	fi
    fi
fi

if [ `id -u` -ne 0 -a -z "$SX_NO_ROOT" ] && [ "$ADVANCED_GIVEN" != "yes" ]; then
    echo "You must be root or call sxsetup with --advanced"
    exit 1
fi

test `id -u` -ne 0 && SX_NO_ROOT="yes"

# Set defaults if there are no previous answers
SX_DATA_DIR=${SX_DATA_DIR:-"/var/lib/sxserver/storage"}
if [ -z "$SX_NODE_IP" ]; then
    SX_NODE_IP=`ip route get 8.8.8.8 2>/dev/null | awk 'NR==1 {print $NF}' | grep "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"`
    if [ -z "$SX_NODE_IP" ]; then
        SX_NODE_IP="127.0.0.1"
    fi
fi

if [ "$FORCE_REINIT_GIVEN" = "yes" -a "$CONFIG_FILE_GIVEN" != "yes" ]; then
    SX_CLUSTER_KEY=
    SX_CLUSTER_UUID=
    if [ "$ADVANCED_GIVEN" != "yes" ]; then
	SX_PORT=
	SX_SERVER_USER=
	SX_SERVER_GROUP=
	SX_NODE_INTERNAL_IP=
    fi
fi

SX_SERVER_USER=${SX_SERVER_USER:-"nobody"}
SX_SERVER_GROUP=`id -n -g "$SX_SERVER_USER"`
SX_RUN_DIR=${SX_RUN_DIR:-"/var/run/sxserver"}
SX_LIB_DIR=${SX_LIB_DIR:-"/var/lib/sxserver"}
SX_NODE_SIZE=${SX_NODE_SIZE:-"1T"}
SX_CHILDREN_NUM=${SX_CHILDREN_NUM:-"24"}
SX_RESERVED_CHILDREN_NUM=${SX_RESERVED_CHILDREN_NUM:-"8"}
SX_LOG_FILE=${SX_LOG_FILE:-"/var/log/sxserver/sxfcgi.log"}

# temp files
SXSETUP_TMPDIR="/var/lib/sxserver-tmp"
if [ -d $SXSETUP_TMPDIR ]; then
    echo "Temporary directory $SXSETUP_TMPDIR already exists"
    echo "Make sure there's no other sxsetup running or remove it manually"
    exit 1
fi
mkdir -p $SXSETUP_TMPDIR
if [ $? -ne 0 ]; then
    echo "Can't create temporary directory $SXSETUP_TMPDIR"
    exit 1
fi
chmod 700 $SXSETUP_TMPDIR
test -z "$SX_NO_ROOT" && chown "$SX_SERVER_USER":"$SX_SERVER_GROUP" $SXSETUP_TMPDIR
OUT_TMP=$SXSETUP_TMPDIR/out.tmp
XCONF_TMP=$SXSETUP_TMPDIR/xconf.tmp
SSLKEY_TMP=$SXSETUP_TMPDIR/sslkey.tmp
SSLCERT_TMP=$SXSETUP_TMPDIR/sslcert.tmp
CERTCONF_TMP=$SXSETUP_TMPDIR/certconf.tmp
CLUSTKEY_TMP=$SXSETUP_TMPDIR/clustkey.tmp
ADMINKEY_TMP=$SXSETUP_TMPDIR/adminkey.tmp
touch $ADMINKEY_TMP
chmod 600 $ADMINKEY_TMP
trap "rm -rf $SXSETUP_TMPDIR; exit 1" EXIT INT

ask_yn() {
    while true; do
	printf "$@ "
        read ANSWER
	if [ -z "$ANSWER" ]; then
	    break
	elif [ "$ANSWER" = "n" -o "$ANSWER" = "N" ]; then
	    ANSWER="n"
	    break
	elif [ "$ANSWER" = "y" -o "$ANSWER" = "Y" ]; then
	    ANSWER="y"
	    break
	fi
    done
}

read_ascii()
{
    read $1
    eval "_READVAL=\$$1"
    save_LC_TYPE=$LC_TYPE
    LC_CTYPE=C
    case "$_READVAL" in
	*[![:cntrl:][:print:]]*)
	    ask_yn "WARNING: the input contains non-ASCII characters, do you want to continue with it? (y/N)"
	    if [ "$ANSWER" != "y" ]; then
		printf "Try again: "
		read_ascii $1
	    fi
	    LC_CTYPE=$save_LC_TYPE
	    ;;
    esac
    LC_CTYPE=$save_LC_TYPE
}

check_port() {
    IP=$1
    PORT=$2
    # Can't use -t or -p, not compatible with FreeBSD
    # Linux format: IP:port, or 0.0.0.0:port
    # FreeBSD format: IP.port or *.port
    FLAGS=
    if [ `uname` = "Linux" ]; then
	FLAGS=-p
    fi
    printf "Checking port $PORT on $IP ... "
    if type netstat > /dev/null 2>&1; then
	nstat="`netstat $FLAGS -na 2>/dev/null | 
	grep \"tcp.*\($IP\|0.0.0.0\|::\|*\)[:.]$PORT[ \t].*LISTEN\" |
	sed 's/\/.*//g'`"
	if [ -n "$nstat" ]; then
	    echo
	    echo "ERROR: another service is already running on $IP:$PORT"
	    echo "Please stop that service or provide another IP address."
	    CHECK_PORT_RETVAL=1
	else
	    echo OK
	    CHECK_PORT_RETVAL=0
	fi
    else
	echo "'netstat' not available, assuming OK"
	CHECK_PORT_RETVAL=0
    fi
}

ask_questions() {
    while true; do
	echo "--- SKYLABLE SX CONFIGURATION SCRIPT ---"
	echo
	echo "The script will help you to create or extend a Skylable SX data cluster."
	echo
	echo "--- CLUSTER NAME ---"
	echo
	echo "Clients will access your cluster using a sx://clustername/volume/path URI."
	echo "It is recommended to use a FQDN for clustername, but not required. Refer to the documentation for more info."
	while true; do
	    printf "Enter the cluster name (use the same across all nodes) [$SX_CLUSTER_NAME]: "
	    read_ascii NEWVAL
	    SX_CLUSTER_NAME=${NEWVAL:-$SX_CLUSTER_NAME}
	    test -n "$SX_CLUSTER_NAME" && break
	    echo "Cluster name must be provided!"
	done

	echo
	echo "--- DATA STORAGE ---"
	echo
	echo "Please provide the location where all incoming data will be stored."
	while true; do
	    printf "Path to SX storage [default=$SX_DATA_DIR]: "
	    read_ascii NEWVAL
	    SX_DATA_DIR=${NEWVAL:-$SX_DATA_DIR}
	    if [ -d "$SX_DATA_DIR" ]; then 
		echo
		echo "The data directory $SX_DATA_DIR already exists."
		echo "Provide a different directory or wipe it before proceeding."
	    elif [ -e "$SX_DATA_DIR" -a ! -d "$SX_DATA_DIR" ]; then
		echo
		echo "$SX_DATA_DIR already exists, but is not a directory."
		echo "Provide a different directory or wipe it before proceeding."
	    else
		break
	    fi
	done

	echo
	echo "Please specify the maximum size of the storage for this node. You can"
	echo "use M, G and T suffixes, eg. 100T for 100 terabytes."
	while true; do
	    printf "Maximum size [default=$SX_NODE_SIZE]: "
	    read_ascii NEWVAL
	    SX_NODE_SIZE=${NEWVAL:-$SX_NODE_SIZE}
	    test -z "$SX_NODE_SIZE" && continue
	    if [ -z "`echo $SX_NODE_SIZE | egrep ^[0-9]+[MGT]?$`" ]; then
		echo "Invalid format. Use numerical size optionally followed by modifiers, eg. 20G or 4T"
		SX_NODE_SIZE=
		continue
	    fi
	    break
	done

	echo
	echo "--- NETWORKING ---"
	echo
	if [ -z "$SX_USE_SSL" -o "$SX_USE_SSL" != "no" ]; then
	    DEFAULTFIRST="(Y/n)"
	    DEFAULTANSWER="y"
	else
	    DEFAULTFIRST="(y/N)"
	    DEFAULTANSWER="n"
	fi
	ask_yn "Enable SSL? (use the same setting for all nodes in the cluster) $DEFAULTFIRST"
	ANSWER=${ANSWER:-$DEFAULTANSWER}
	if [ "$ANSWER" != "n" ]; then
	    SX_USE_SSL="yes"
	    DEFAULT_PORT="443"
	    SX_SSL_CERT_FILE=${SX_SSL_CERT_FILE:-"$ETCDIR/ssl/certs/sxcert.pem"}
	    SX_SSL_KEY_FILE=${SX_SSL_KEY_FILE:-"$ETCDIR/ssl/private/sxkey.pem"}
	    HTTPS="https://"
	else
	    SX_USE_SSL="no"
	    DEFAULT_PORT="80"
	fi
	test "$SX_NO_ROOT" = "yes" && DEFAULT_PORT="50$DEFAULT_PORT"
	SX_PORT=${SX_PORT:-"$DEFAULT_PORT"}

	while true; do
	    printf "Enter the IP address of this node [default=$SX_NODE_IP]: "
	    read_ascii NEWVAL
	    SX_NODE_IP=${NEWVAL:-$SX_NODE_IP}
	    test -z "$SX_NODE_IP" && continue
	    if [ -n "$ADVANCED_GIVEN" ]; then
		while true; do
		    printf "Enter the port number (use the same value for all nodes in the cluster) [default=$SX_PORT]: "
		    read_ascii NEWVAL
		    SX_PORT=${NEWVAL:-$SX_PORT}
		    test -n "$SX_PORT" && break
		done
	    fi
	    check_port "$SX_NODE_IP" $SX_PORT
	    test "$CHECK_PORT_RETVAL" = "1" && continue
	    break
	done

	if [ -n "$ADVANCED_GIVEN" ]; then
	    echo
	    if [ -z "$SX_NODE_INTERNAL_IP" -o "$SX_NODE_INTERNAL_IP" = "$SX_NODE_IP" ]; then
		DEFAULTFIRST="(y/N)"
		DEFAULTANSWER="n"
	    else
		DEFAULTFIRST="(Y/n)"
		DEFAULTANSWER="y"
	    fi
	    ask_yn "Use separated network for inter-node communication? $DEFAULTFIRST"
	    ANSWER=${ANSWER:-$DEFAULTANSWER}
	    if [ "$ANSWER" != "n" ]; then
		echo
		while true; do
		    printf "Enter the internal IP address of this node [default=$SX_NODE_INTERNAL_IP]: "
		    read_ascii NEWVAL
		    SX_NODE_INTERNAL_IP=${NEWVAL:-$SX_NODE_INTERNAL_IP}
		    test -z "$SX_NODE_INTERNAL_IP" && continue
		    check_port "$SX_NODE_INTERNAL_IP" $SX_PORT
		    test "$CHECK_PORT_RETVAL" = "1" && continue
		    break
		done
	    fi
	fi

	echo
	echo "--- CLUSTER CONFIGURATION ---"
	echo
	DEFAULTFIRST="(Y/n)"
	DEFAULTANSWER="y"
	if [ -n "$SX_EXISTING_NODE_IP" ]; then
	    DEFAULTFIRST="(y/N)"
	    DEFAULTANSWER="n"
	fi
	ask_yn "Is this ($SX_NODE_IP) the first node of a new cluster? $DEFAULTFIRST"
	ANSWER=${ANSWER:-$DEFAULTANSWER}
	if [ "$ANSWER" = "y" ]; then
	    SX_EXISTING_NODE_IP=
	else
	    echo "Please provide the IP address of a working node in '$SX_CLUSTER_NAME'."
	    while true; do
		if [ -n "$SX_EXISTING_NODE_IP" ]; then
		    printf "IP address [default=$SX_EXISTING_NODE_IP]: "
		else
		    printf "IP address: "
		fi
		read_ascii NEWVAL
		SX_EXISTING_NODE_IP=${NEWVAL:-$SX_EXISTING_NODE_IP}
		if [ "$SX_EXISTING_NODE_IP" = "$SX_NODE_IP" -o "$SX_EXISTING_NODE_IP" = "$SX_NODE_INTERNAL_IP" ]; then
		    echo "$SX_EXISTING_NODE_IP is the IP address of this node."
		    echo "You must provide the IP address of a node that is already part of the cluster!"
		else
		    if type curl > /dev/null 2>&1; then
			if curl -s -k -m 3 $HTTPS$SX_EXISTING_NODE_IP:$SX_PORT > /dev/null 2>&1; then
			    break
			else
			    echo "Cannot contact node $HTTPS$SX_EXISTING_NODE_IP"
			    if [ -f /etc/redhat-release ]; then
				echo "Please check the firewall rules by running 'iptables -L'"
			    fi
			    echo "Make sure the node is running and accessible from this host, then try again."

			    test -n "$HTTPS" && echo "Disable SSL in case the cluster you want to join doesn't use secure connection."
			fi
		    else
			break
		    fi
		fi
	    done
	fi

	if [ -n "$SX_EXISTING_NODE_IP" -a -z "$BARE_GIVEN" ]; then
	    echo
	    echo "The admin key is required to join the existing cluster."
	    echo "If you don't have it, run 'sxsetup --info' on $SX_EXISTING_NODE_IP."
	    echo "Below you can provide the key itself or path to the file containing the key."

	    while true; do
		printf "Admin key or path to key-file [default=$SX_ADMIN_KEY]: "
		read_ascii NEWVAL
		SX_ADMIN_KEY=${NEWVAL:-$SX_ADMIN_KEY}
		if [ -z "$SX_ADMIN_KEY" ]; then
		    echo "Admin key is required to connect to the existing cluster"
		    SX_ADMIN_KEY=
		    continue
		elif [ -r "$SX_ADMIN_KEY" ]; then 
		    if [ -z "`cat $SX_ADMIN_KEY | grep '0DPiKuNIrrVmD8IUCuw1hQxNqZ'`" ]; then
			echo "$SX_ADMIN_KEY doesn't contain a valid admin key"
			SX_ADMIN_KEY=
			continue
		    fi
		    SX_ADMIN_KEY=`cat $SX_ADMIN_KEY`
		elif [ -z "`echo $SX_ADMIN_KEY | grep '0DPiKuNIrrVmD8IUCuw1hQxNqZ'`" ]; then
		    echo "'$SX_ADMIN_KEY' is not a valid admin key"
		    SX_ADMIN_KEY=
		    continue
		fi
		break
	    done
	fi

	if [ -n "$SX_EXISTING_NODE_IP" -a -n "$BARE_GIVEN" ]; then
	    echo
	    echo "The cluster key is required to later join this node to the cluster."
	    echo "If you don't have it, run 'sxsetup --info' on $SX_EXISTING_NODE_IP."
	    echo "Below you can provide the key itself or path to the file containing the key."

	    while true; do
		printf "Cluster key or path to key-file [default=$SX_CLUSTER_KEY]: "
		read_ascii NEWVAL
		SX_CLUSTER_KEY=${NEWVAL:-$SX_CLUSTER_KEY}
		if [ -z "$SX_CLUSTER_KEY" ]; then
		    echo "Cluster key is required to configure the bare node"
		    SX_CLUSTER_KEY=
		    continue
		elif [ -r "$SX_CLUSTER_KEY" ]; then 
		    if [ -z "`cat $SX_CLUSTER_KEY | grep 'CLUSTER/ALLNODE/ROOT/'`" ]; then
			echo "$SX_CLUSTER_KEY doesn't contain a valid cluster key"
			SX_CLUSTER_KEY=
			continue
		    fi
		    SX_CLUSTER_KEY=`cat $SX_CLUSTER_KEY`
		elif [ -z "`echo $SX_CLUSTER_KEY | grep 'CLUSTER/ALLNODE/ROOT/'`" ]; then
		    echo "'$SX_CLUSTER_KEY' is not a valid cluster key"
		    SX_CLUSTER_KEY=
		    continue
		fi
		break
	    done

	    echo
	    echo "Please provide the UUID of the cluster. If you don't have it, run"
	    echo "'sxsetup --info' on $SX_EXISTING_NODE_IP."
	    while true; do
		printf "Cluster UUID [default=$SX_CLUSTER_UUID]: "
		read_ascii NEWVAL
		SX_CLUSTER_UUID=${NEWVAL:-$SX_CLUSTER_UUID}
		if [ -z "$SX_CLUSTER_UUID" ]; then
		    echo "Cluster UUID is required to configure the bare node"
		    continue
		fi
		break
	    done
	fi

	if [ "$SX_USE_SSL" = "yes" ] ; then
	    echo
	    echo "--- SSL CONFIGURATION ---"
	    if [ "$FORCE_REINIT_GIVEN" = "yes" ]; then
		rm -f "$SX_SSL_KEY_FILE" "$SX_SSL_CERT_FILE"
	    fi
	    CREATED=0
	    while [ ! -r "$SX_SSL_KEY_FILE" -o ! -r "$SX_SSL_CERT_FILE" ]; do
		mkdir -p "$ETCDIR/ssl/private" "$ETCDIR/ssl/certs"
		if [ "$ADVANCED_GIVEN" = "yes" ]; then
		    cat > "$CERTCONF_TMP" <<EOF
[ req ]
default_bits	       = 2048
distinguished_name     = req_distinguished_name
encrypt_key            = no
x509_extensions        = v3_ca

[ req_distinguished_name ]
countryName                    = Country Name (2 letter code)
countryName_default            = UK
countryName_min                = 2
countryName_max                = 2

localityName                    = Locality Name (eg, city)
localityName_default            = London

organizationalUnitName         = Organizational Unit Name (eg, section)
organizationalUnitName_default = SX

commonName                     = Common Name (must match SX cluster name)
commonName_default	       = $SX_CLUSTER_NAME

EOF
		else
		    cat > "$CERTCONF_TMP" <<EOF
[ req ]
default_bits		= 2048
distinguished_name	= req_distinguished_name
prompt			= no
encrypt_key		= no
x509_extensions		= v3_ca

[ req_distinguished_name ]
C		       = UK
L		       = London
O		       = SX
CN		       = $SX_CLUSTER_NAME

EOF
		fi
		cat >> "$CERTCONF_TMP" <<EOF
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = critical,CA:true
keyUsage=keyCertSign,cRLSign,digitalSignature,keyEncipherment
EOF

		if [ -z "$SX_EXISTING_NODE_IP" ]; then
		    CREATESSL=1
		    if [ "$ADVANCED_GIVEN" = "yes" ]; then
			echo
			ask_yn "Do you want to generate SSL certificate and key? (Y/n)"
			test "$ANSWER" = "n" && CREATESSL=0
		    fi
		fi

		if [ -z "$SX_EXISTING_NODE_IP" -a "$CREATESSL" = "1" ]; then
		    echo
		    echo "Generating default SSL certificate and key in $SX_SSL_KEY_FILE $SX_SSL_CERT_FILE"
		    openssl req -days 1825 -x509 -config "$CERTCONF_TMP" -new -keyout "$SX_SSL_KEY_FILE" -out "$SX_SSL_CERT_FILE" || exit 1
		    test -z "$SX_NO_ROOT" && chown "$SX_SERVER_USER":"$SX_SERVER_GROUP" "$SX_SSL_KEY_FILE" "$SX_SSL_CERT_FILE"
		    chmod 600 "$SX_SSL_KEY_FILE" "$SX_SSL_CERT_FILE"
		    SX_SSL_KEY="`cat $SX_SSL_KEY_FILE`"
		    SX_SSL_CERT="`cat $SX_SSL_CERT_FILE`"
		    CREATED=1
		else
		    if [ -n "$SX_EXISTING_NODE_IP" -a "$NO_REMOTE_COPY_GIVEN" != "yes" ]; then
			# try to obtain existing node's sxsetup.conf (non-critical)
			echo "$SX_ADMIN_KEY" > $ADMINKEY_TMP
			"/usr/bin/sxinit" --batch-mode --force-reinit --port="$SX_PORT" $NOSSL_FLAG --auth-file="$ADMINKEY_TMP" --host-list="$SX_EXISTING_NODE_IP" "sx://admin@$SX_CLUSTER_NAME" > /dev/null 2>&1
			"/usr/bin/sxcp" "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf/sxsetup.conf.$SX_EXISTING_NODE_IP" $XCONF_TMP > /dev/null 2>&1
			if [ $? = 0 ]; then
			    sed -e "s/SX_/XSX_/g" $XCONF_TMP > $OUT_TMP
			    if [ $? = 0 ]; then
				mv $OUT_TMP $XCONF_TMP
				. $XCONF_TMP
			    fi
			else
			    "/usr/sbin/sxadm" cluster --get-param sxsetup_conf "sx://admin@$SX_CLUSTER_NAME" 2>/dev/null | sed 's/sxsetup_conf=//' | xxd -ps -r > $XCONF_TMP 2>/dev/null
			    if [ -s "$XCONF_TMP" ]; then
				sed -e "s/SX_/XSX_/g" $XCONF_TMP > $OUT_TMP
				if [ $? = 0 ]; then
				    mv $OUT_TMP $XCONF_TMP
				    . $XCONF_TMP
				fi
			    fi
			fi
		    fi

		    GOTSSLKEY=
		    if [ -n "$XSX_SSL_KEY" ]; then
			echo $XSX_SSL_KEY | sed -e 's/[ 	][ 	]*/\
/g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/BEGIN\n/BEGIN /g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/END\n/END /g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/PRIVATE\n/PRIVATE /g' > "$SSLKEY_TMP"
			if [ $? = 0 ]; then
			    echo "Automatically obtained SSL private key from $SX_EXISTING_NODE_IP"
			    mv "$SSLKEY_TMP" "$SX_SSL_KEY_FILE"
			    GOTSSLKEY=1
			fi
		    fi

		    if [ "$GOTSSLKEY" != "1" ]; then
			echo
			echo "Please paste the SSL private key below (and press CTRL+D when done) or provide a path to it."
			echo "SSL private key:"
			# Cannot use read for multi-line input
			cat >$SSLKEY_TMP
			if [ -s "$SSLKEY_TMP" ]; then
			    if grep -q -F -- '-----BEGIN' "$SSLKEY_TMP"; then
				# it was pasted
				if grep -q -F -- 'PRIVATE KEY-----' "$SSLKEY_TMP"; then
				    cp "$SSLKEY_TMP" "$SX_SSL_KEY_FILE"
				else
				    echo
				    echo "*** The data provided is not a private key! ***"
				    continue
				fi
			    else
				cp "`cat \"$SSLKEY_TMP\"`" "$SX_SSL_KEY_FILE"
			    fi
			fi
			rm -f $SSLKEY_TMP
		    fi

		    GOTSRVCERT=
		    if [ -n "$XSX_SSL_CERT" ]; then
			echo $XSX_SSL_CERT | sed -e 's/[ 	][ 	]*/\
/g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/BEGIN\n/BEGIN /g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/END\n/END /g' > "$SSLCERT_TMP"
			test $? = 0 && GOTSRVCERT=1
		    elif [ -n "$SX_EXISTING_NODE_IP" ]; then
			SRVCERT="`echo \"HEAD / HTTP/1.0\n Host: $SX_EXISTING_NODE_IP:$SX_PORT\n\n EOT\n\" | openssl s_client -connect $SX_EXISTING_NODE_IP:$SX_PORT -prexit 2>/dev/null`"
			if [ $? = 0 ]; then
			    echo "$SRVCERT" | openssl x509 > "$SSLCERT_TMP"
			    test $? = 0 && GOTSRVCERT=1
			fi
		    fi

		    echo
		    if [ "$GOTSRVCERT" = "1" ]; then
			echo "Automatically obtained SSL certificate from $SX_EXISTING_NODE_IP"
			mv "$SSLCERT_TMP" "$SX_SSL_CERT_FILE"
		    else
			echo "Please paste the SSL certificate below (and press CTRL+D when done) or provide a path to it"
			echo "SSL certificate: [default=$SX_SSL_CERT_FILE]"
			cat >$SSLCERT_TMP
			if [ -s "$SSLCERT_TMP" ]; then
			    if grep -q -F -- '-----BEGIN' "$SSLCERT_TMP"; then
				# it was pasted
				if grep -q -F -- '-----BEGIN CERTIFICATE-----' "$SSLCERT_TMP"; then
				    cp "$SSLCERT_TMP" "$SX_SSL_CERT_FILE"
				else
				    echo "Not a certificate!"
				    continue
				fi
			    else
				cp "`cat \"$SSLCERT_TMP\"`" "$SX_SSL_CERT_FILE"
			    fi
			fi
			rm -f $SSLCERT_TMP
		    fi
		fi
		test -z "$SX_NO_ROOT" && chown "$SX_SERVER_USER":"$SX_SERVER_GROUP" "$SX_SSL_KEY_FILE" "$SX_SSL_CERT_FILE" 2>/dev/null
		chmod 600 "$SX_SSL_KEY_FILE" "$SX_SSL_CERT_FILE" 2>/dev/null
		SX_SSL_KEY="`cat $SX_SSL_KEY_FILE`"
		SX_SSL_CERT="`cat $SX_SSL_CERT_FILE`"
	    done
	    if [ "$CREATED" = 0 ]; then
		CERTCN=`openssl x509 -in "$SX_SSL_CERT_FILE" -text|grep Subject: | sed -e 's/.*CN=//'`
		if [ "$CERTCN" != "$SX_CLUSTER_NAME" -a -z "`echo $SX_CLUSTER_NAME | grep .$CERTCN`" ]; then
		    echo "ERROR: The certificate's CN ($CERTCN) doesn't match the cluster name: $SX_CLUSTER_NAME"
		    echo "If you changed the cluster name then you must manually remove $SX_SSL_KEY_FILE and $SX_SSL_CERT_FILE!"
		    echo "Run $0 --force-reinit to automatically wipe the old SSL key and certificate."
		    exit 1
		fi
	    fi
	fi

	if [ -n "$ADVANCED_GIVEN" ]; then
	    echo
	    echo "--- SERVER CONFIGURATION ---"
	    if [ -z "$SX_NO_ROOT" ]; then
		while true; do
		    printf "What user should the SX server be running as [default=$SX_SERVER_USER]: "
		    read_ascii NEWVAL
		    test -z "$NEWVAL" && break
		    id $NEWVAL > /dev/null 2>&1 && break
		    echo "User $NEWVAL doesn't exist!"
		done
		SX_SERVER_USER=${NEWVAL:-$SX_SERVER_USER}
		SX_SERVER_GROUP=`id -n -g "$SX_SERVER_USER"`
	    else
		SX_SERVER_USER=`whoami`
		SX_SERVER_GROUP=`id -n -g "$SX_SERVER_USER"`
	    fi
	    echo
	    printf "Number of children processes used to communicate with the clients [default=$SX_CHILDREN_NUM]: "
	    read_ascii NEWVAL
	    SX_CHILDREN_NUM=${NEWVAL:-$SX_CHILDREN_NUM}
	    printf "Number of children processes used to communicate with other nodes [default=$SX_RESERVED_CHILDREN_NUM]: "
	    read_ascii NEWVAL
	    SX_RESERVED_CHILDREN_NUM=${NEWVAL:-$SX_RESERVED_CHILDREN_NUM}
	fi

        TOTAL_MEM=`/usr/sbin/sxreport-server --get-mem`
	if [ "$TOTAL_MEM" -gt 0 ]; then
	    TOTAL_CHILDREN=`expr $SX_CHILDREN_NUM + $SX_RESERVED_CHILDREN_NUM`
	    if [ "$TOTAL_MEM" -lt 2000000000 -a "$TOTAL_CHILDREN" -gt 8 ]; then
		echo
		echo "WARNING: This node has less than 2GB of total memory."
		if [ -n "$ADVANCED_GIVEN" ]; then
		    echo "It is not recommended to use more than 8 children processes."
		else
		    SX_CHILDREN_NUM=6
		    SX_RESERVED_CHILDREN_NUM=2
		    echo "The number of children processes will be limited to 8."
		    echo "Run sxsetup with --advanced to fine-tune the value if needed."
		fi
		printf "[ PRESS ENTER TO CONTINUE ]"
		read FOO
	    fi
	fi

	echo
	echo "--- YOUR CHOICES ---"
	echo
	echo "Cluster: sx://$SX_CLUSTER_NAME"
	if [ -n "$SX_NODE_INTERNAL_IP" ]; then
	    echo "Node: $SX_NODE_IP (internal address: $SX_NODE_INTERNAL_IP)"
	else
	    echo "Node: $SX_NODE_IP"
	fi
	echo "Use SSL: $SX_USE_SSL"
	echo "Storage: $SX_DATA_DIR"
	echo "Run as user: $SX_SERVER_USER"
	echo

	ask_yn "Is this correct? (Y/n)"
	if [ "$ANSWER" != "n" ]; then
	    break
	fi
	rm -f "$SX_SSL_KEY_FILE" "$SX_SSL_CERT_FILE"
    done
} #ask_questions()

cluster_modify() {
    # Commit new cluster config
    LOCKCNT=1
    MODCNT=1
    while true; do
	if [ -n "`/usr/sbin/sxadm cluster --info sx://admin@$SX_CLUSTER_NAME 2>&1 | grep 'activity:'`" ]; then
	    echo "Cluster is busy (another operation in progress)... retrying in 60 seconds (attempt $LOCKCNT of 10)."
	    LOCKCNT=`expr $LOCKCNT + 1`
	    sleep 60
	    continue
	fi
	"/usr/sbin/sxadm" cluster --lock "sx://admin@$SX_CLUSTER_NAME" > $OUT_TMP 2>&1
	if [ $? -ne 0 ]; then
	    if [ -n "`grep 'Cluster is already locked' $OUT_TMP`" -o -n "`grep 'Distribution changes in progress' $OUT_TMP`" ] && [ $LOCKCNT -le 10 ]; then
		echo "Cluster is busy (already locked for changes by another process)... retrying in 60 seconds (attempt $LOCKCNT of 10)."
		LOCKCNT=`expr $LOCKCNT + 1`
		sleep 60
		continue
	    fi
	    echo "Failed to modify the cluster. The error message from 'sxadm cluster --lock' was:"
	    cat $OUT_TMP
	    echo
	    echo "Please check the error and try again later."
	    return 1
	fi

	"/usr/sbin/sxadm" cluster --info "sx://admin@$SX_CLUSTER_NAME" > $OUT_TMP
	if [ $? -ne 0 ]; then
	    echo "Failed to retrieve current configuration of the cluster."
	    "/usr/sbin/sxadm" cluster --unlock "sx://admin@$SX_CLUSTER_NAME" > /dev/null
	    return 1
	fi
	SXDIST=`cat $OUT_TMP | grep "Current configuration" | cut -d: -f 2-`
	if [ -z "$SXDIST" ]; then
	    echo "Failed to obtain the node information."
	    "/usr/sbin/sxadm" cluster --unlock "sx://admin@$SX_CLUSTER_NAME" > /dev/null
	    return 1
	fi

	if [ -n "$NEWNODE" ]; then
	    SXDIST="$NEWNODE $SXDIST"
	elif [ -n "$REMOVENODE" ]; then
	    # FIXME: add support for zones
            SXDIST=`echo $SXDIST | sed "s|$REMOVENODE||g"`
	    if [ -z "$SXDIST" ]; then
		echo "This is the last node in the cluster, no data will be relocated."
		"/usr/sbin/sxserver" stop
		mv "$CONFIG" "$CONFIG.old.$OLDSTAMP"
		echo "The node has been successfully deactivated."
		rm -rf $SXSETUP_TMPDIR
		trap - EXIT INT
		exit 0
	    fi
	else
	    echo "Invalid operation mode."
	    "/usr/sbin/sxadm" cluster --unlock "sx://admin@$SX_CLUSTER_NAME" > /dev/null
	    return 1
	fi

	"/usr/sbin/sxadm" cluster --mod $SXDIST "sx://admin@$SX_CLUSTER_NAME" 2>$OUT_TMP
	if [ $? = 0 ]; then
	    "/usr/sbin/sxadm" cluster --unlock "sx://admin@$SX_CLUSTER_NAME" > /dev/null
	    break
	fi
	"/usr/sbin/sxadm" cluster --unlock "sx://admin@$SX_CLUSTER_NAME" > /dev/null
	if [ -n "`grep -E 'temporarily locked|complex operation|Failed to setup job targets' $OUT_TMP`" -a $MODCNT -le 10 ]; then
	    echo "Cluster busy... retrying in 60 seconds (attempt $MODCNT of 10)."
	    MODCNT=`expr $MODCNT + 1`
	    sleep 60
	else
            cat $OUT_TMP
	    echo "Failed to modify cluster sx://$SX_CLUSTER_NAME"
	    return 1
	fi
    done
    return 0
}

OLDSTAMP="`date +%s`"

if [ "$DEACTIVATE_GIVEN" = "yes" ]; then
    if [ ! -f "$CONFIG" ]; then
	echo "Not configured. You have to run sxsetup in configuration mode first."
	exit 1
    fi
    if [ "$SXSETUP_BATCH_MODE" != "yes" ]; then
	echo "This option will relocate all data stored on this node to other nodes in"
	echo "the cluster and deactivate the node. The procedure can take more time"
	echo "depending on the data size and the network speed. Please do not interrupt"
	echo "it and don't turn off the node until the operation is finished."
	ask_yn "Do you want to continue? (y/N)"
	if [ "$ANSWER" != "y" ]; then
	    exit 0
	fi
    fi

    REMOVENODE=`/usr/sbin/sxadm node $OWNERFLAG --get-definition $SX_DATA_DIR`
    cluster_modify || exit 1

    echo "Waiting for cluster to finish data relocation..."
    while true; do
	"/usr/sbin/sxadm" cluster --info "sx://admin@$SX_CLUSTER_NAME" > $OUT_TMP
	if [ $? -ne 0 ]; then
	    sleep 10
	    continue
	fi
	if [ -n "`cat $OUT_TMP | grep 'activity:'`" ]; then
	    sleep 10
	    continue
	else
	    break
	fi
    done

    "/usr/sbin/sxserver" stop
    mv "$CONFIG" "$CONFIG.old.$OLDSTAMP"

    echo "The node has been successfully deactivated."
    rm -rf $SXSETUP_TMPDIR
    trap - EXIT INT
    exit 0
fi

if [ "$CONFIG_FILE_GIVEN" = "yes" ]; then
    echo "Using config file $CONFIG_FILE"

    if [ -z "$SX_CFG_VERSION" ]; then
	echo "ERROR: Config version not set in the config file (possibly unsupported)."
	echo "Please perform a manual setup to generate a new config file with this"
	echo "sxsetup version."
	exit 1
    fi

    if [ "$SX_CFG_VERSION" != "$CFG_VERSION" ]; then
	echo "ERROR: Config file version $SX_CFG_VERSION while sxsetup requires version $CFG_VERSION"
	echo "Please perform a manual setup to generate a new config file with this"
	echo "sxsetup version."
	exit 1
    fi

    if [ -f "$SX_DATA_DIR/hashfs.db" ]; then 
	echo "ERROR: Cluster is already initialized in $SX_DATA_DIR"
	echo "Please wipe the existing data directory or provide a new one"
	exit 1
    fi

    test -r "$SX_ADMIN_KEY" && SX_ADMIN_KEY=`cat $SX_ADMIN_KEY`
    if [ -n "$SX_ADMIN_KEY" -a -z "`echo $SX_ADMIN_KEY | grep '0DPiKuNIrrVmD8IUCuw1hQxNqZ'`" ]; then
	echo "ERROR: SX_ADMIN_KEY doesn't specify a valid admin key"
	exit 1
    fi

    if [ -z "$SX_NODE_IP" ]; then
	echo "ERROR: SX_NODE_IP is required to setup this node"
	exit 1
    fi

    check_port "$SX_NODE_IP" $SX_PORT
    test "$CHECK_PORT_RETVAL" = "1" && exit 1

    if [ -n "$SX_NODE_INTERNAL_IP" ]; then
	check_port "$SX_NODE_INTERNAL_IP" $SX_PORT
	test "$CHECK_PORT_RETVAL" = "1" && exit 1
    fi

    if [ -n "$SX_EXISTING_NODE_IP" ]; then
	if [ -z "$SX_ADMIN_KEY" ]; then
	    echo "ERROR: SX_ADMIN_KEY is required when joining existing cluster"
	    exit 1
	fi
    fi

    if [ "$SX_USE_SSL" != "no" ]; then
	mkdir -p "$ETCDIR/ssl/private" "$ETCDIR/ssl/certs"

	if [ ! -r "$SX_SSL_CERT_FILE" ]; then
	    if [ -z "$SX_SSL_CERT" ]; then
		echo "ERROR: Please provide SX_SSL_CERT_FILE or SX_SSL_CERT in the config file."
		exit 1
	    fi
	    echo $SX_SSL_CERT | sed -e 's/[ 	][ 	]*/\
/g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/BEGIN\n/BEGIN /g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/END\n/END /g' > "$SX_SSL_CERT_FILE"
	    test -z "$SX_NO_ROOT" && chown "$SX_SERVER_USER":"$SX_SERVER_GROUP" "$SX_SSL_CERT_FILE" 2>/dev/null
	    chmod 600 "$SX_SSL_CERT_FILE" 2>/dev/null
	fi

	if [ ! -r "$SX_SSL_KEY_FILE" ]; then
	    if [ -z "$SX_SSL_KEY" ]; then
		echo "ERROR: Please provide SX_SSL_KEY_FILE or SX_SSL_KEY in the config file."
		exit 1
	    fi
	    echo $SX_SSL_KEY | sed -e 's/[ 	][ 	]*/\
/g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/BEGIN\n/BEGIN /g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/END\n/END /g' | sed -e ':a' -e 'N' -e '$!ba' -e 's/PRIVATE\n/PRIVATE /g' > "$SX_SSL_KEY_FILE"
	    test -z "$SX_NO_ROOT" && chown "$SX_SERVER_USER":"$SX_SERVER_GROUP" "$SX_SSL_KEY_FILE" 2>/dev/null
	    chmod 600 "$SX_SSL_KEY_FILE" 2>/dev/null
	fi
    fi

else
    # Interactive mode
    ask_questions
fi

# Create up-to-date sxsetup.conf

if [ -f "$CONFIG" ]; then
    mv "$CONFIG" "$CONFIG.old.$OLDSTAMP"
fi
touch "$CONFIG"
chmod 600 "$CONFIG"

# REMEMBER: Bump CFG_VERSION after any incompatible changes to the config file!
cat >"$CONFIG" <<EOF
###########################################################################
#                    !!! DO NOT EDIT THIS FILE !!!                        #
#                                                                         #
#    This file was generated during node creation with sxsetup.           #
#    Some of the variables defined below are used by sxserver and other   #
#    scripts, however the main purpose of this file is to provide         #
#    a template for creating new nodes with sxsetup --config-file.        #
#    Changing parameters such as SX_NODE_SIZE directly in this file       #
#    will have no effect *after* the node was created.                    #
#                                                                         #
###########################################################################
SX_CLUSTER_NAME="$SX_CLUSTER_NAME"
SX_DATA_DIR="$SX_DATA_DIR"
SX_RUN_DIR="$SX_RUN_DIR"
SX_LIB_DIR="$SX_LIB_DIR"
SX_LOG_FILE="$SX_LOG_FILE"
SX_NODE_SIZE="$SX_NODE_SIZE"
SX_NODE_IP="$SX_NODE_IP"
SX_NODE_INTERNAL_IP="$SX_NODE_INTERNAL_IP"
SX_EXISTING_NODE_IP="$SX_EXISTING_NODE_IP"
SX_SERVER_USER="$SX_SERVER_USER"
SX_SERVER_GROUP="$SX_SERVER_GROUP"
SX_CHILDREN_NUM="$SX_CHILDREN_NUM"
SX_RESERVED_CHILDREN_NUM="$SX_RESERVED_CHILDREN_NUM"
SX_PORT="$SX_PORT"
SX_USE_SSL="$SX_USE_SSL"
SX_SSL_KEY_FILE="$SX_SSL_KEY_FILE"
SX_SSL_CERT_FILE="$SX_SSL_CERT_FILE"
SX_SSL_KEY="$SX_SSL_KEY"
SX_SSL_CERT="$SX_SSL_CERT"
SX_CFG_VERSION="$CFG_VERSION"
EOF

################
# Actual setup #
################

mkdir -p "$ETCDIR/sxserver"

test "$SX_USE_SSL" = "no" && NOSSL_FLAG="--no-ssl"

# sxfcgi.conf
if [ -f "$ETCDIR/sxserver/sxfcgi.conf" ]; then
    mv "$ETCDIR/sxserver/sxfcgi.conf" "$ETCDIR/sxserver/sxfcgi.conf.old.$OLDSTAMP"
fi
cat >"$ETCDIR/sxserver/sxfcgi.conf" <<EOF
pidfile="$SX_RUN_DIR/sxfcgi.pid"
logfile="$SX_LOG_FILE"
socket="$SX_RUN_DIR/sxfcgi.socket"
reserved-socket="$SX_RUN_DIR/sxfcgi-reserved.socket"
socket-mode=0660
data-dir="$SX_DATA_DIR"
children=$SX_CHILDREN_NUM
reserved-children=$SX_RESERVED_CHILDREN_NUM
EOF

if [ -z "$SX_NO_ROOT" ]; then
    cat >>"$ETCDIR/sxserver/sxfcgi.conf" <<EOF
run-as="$SX_SERVER_USER:$SX_SERVER_GROUP"
EOF
fi

if [ -z "$NOSSL_FLAG" ]; then
    cat >>"$ETCDIR/sxserver/sxfcgi.conf" <<EOF
ssl_ca="$SX_SSL_CERT_FILE"
EOF
fi

if [ "$DEBUG_GIVEN" = "yes" ]; then
    cat >>"$ETCDIR/sxserver/sxfcgi.conf" <<EOF
debug
EOF
fi

if [ -f "$ETCDIR/sxserver/sxhttpd.conf" ]; then
    mv "$ETCDIR/sxserver/sxhttpd.conf" "$ETCDIR/sxserver/sxhttpd.conf.old.$OLDSTAMP"
fi
cp "$ETCDIR/sxserver/sxhttpd.conf.default" "$ETCDIR/sxserver/sxhttpd.conf"

if [ -n "$SX_EXISTING_NODE_IP" -a -n "$SXCLUSTERKEY" ]; then
    if [ -z "`echo $SXCLUSTERKEY | grep 'CLUSTER/ALLNODE/ROOT/'`" ]; then
        # key file
        if [ -r "$SXCLUSTERKEY" ]; then
            # Save only if it is a file
            echo SXCLUSTERKEY="$SXCLUSTERKEY" >>"$DEFAULTS"
            SXCLUSTERKEY=`cat "$SXCLUSTERKEY"`
        else
            echo "Can't read key file $SXCLUSTERKEY"
            exit 1
        fi
        if [ -z "`echo $SXCLUSTERKEY | grep 'CLUSTER/ALLNODE/ROOT/'`" ]; then
            echo "'$SXCLUSTERKEY' is not a valid key or key file"
            exit 1
        fi
    fi
fi

if [ -z "$NOSSL_FLAG" ] ; then
    sed -e "s/^#//g"\
	-e "s|ssl_certificate .*|ssl_certificate $SX_SSL_CERT_FILE;|"\
	-e "s|ssl_certificate_key .*|ssl_certificate_key $SX_SSL_KEY_FILE;|"\
	"$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    cp $OUT_TMP "$ETCDIR/sxserver/sxhttpd.conf"
fi

if [ -z "${SX_NODE_IP##*:*}" ]; then
    SX_NODE_LISTEN_IP="[$SX_NODE_IP]"
else
    SX_NODE_LISTEN_IP="$SX_NODE_IP"
fi
if [ -z "${SX_NODE_INTERNAL_IP##*:*}" ]; then
    SX_NODE_LISTEN_INTERNAL_IP="[$SX_NODE_INTERNAL_IP]"
else
    SX_NODE_LISTEN_INTERNAL_IP="$SX_NODE_INTERNAL_IP"
fi
if [ -n "$SX_NODE_INTERNAL_IP" -a "$SX_NODE_IP" != "$SX_NODE_INTERNAL_IP" ]; then
    if [ -n "`ip addr show 2>/dev/null | grep $SX_NODE_IP`" -o -n "`/sbin/ifconfig 2>/dev/null | grep $SX_NODE_IP`" ]; then
	# bind to both public and internal IPs
	sed -e "s/listen 80/listen $SX_NODE_LISTEN_IP:$SX_PORT default_server;\\
	     listen $SX_NODE_LISTEN_INTERNAL_IP:$SX_PORT/"\
	"$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    else
	# only listen on the internal IP (assume public IP is translated via 1:1 NAT)
	sed -e "s/listen.*80/listen $SX_NODE_LISTEN_INTERNAL_IP:$SX_PORT/"\
	"$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    fi
    if [ -n "`/usr/sbin/nginx -V 2>&1 | grep nginx-module-vts`" ]; then
	cp $OUT_TMP "$ETCDIR/sxserver/sxhttpd.conf"
	sed -e "s/#vhost_traffic_status/vhost_traffic_status/g"\
	    -e "s/allow 127.0.0.1;/allow $SX_NODE_LISTEN_INTERNAL_IP;\\
		 allow 127.0.0.1;/"\
	"$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    fi
else
    # listen on the public IP
    sed -e "s/listen.*80/listen $SX_NODE_LISTEN_IP:$SX_PORT/"\
    "$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    if [ -n "`/usr/sbin/nginx -V 2>&1 | grep nginx-module-vts`" ]; then
	cp $OUT_TMP "$ETCDIR/sxserver/sxhttpd.conf"
	sed -e "s/#vhost_traffic_status/vhost_traffic_status/g"\
	    -e "s/allow 127.0.0.1;/allow $SX_NODE_LISTEN_IP;\\
		 allow 127.0.0.1;/"\
	"$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    fi
fi
cp $OUT_TMP "$ETCDIR/sxserver/sxhttpd.conf"

sed -e "s/^user.*/user $SX_SERVER_USER $SX_SERVER_GROUP;/"\
    "$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
cp $OUT_TMP "$ETCDIR/sxserver/sxhttpd.conf"

if [ "$SX_NO_ROOT" = "yes" ] ; then
    sed -e "s/^user.*/#user $SX_SERVER_USER $SX_SERVER_GROUP;/"\
    "$ETCDIR/sxserver/sxhttpd.conf" >$OUT_TMP
    cp $OUT_TMP "$ETCDIR/sxserver/sxhttpd.conf"
else
    OWNERFLAG="--owner=$SX_SERVER_USER:$SX_SERVER_GROUP"
fi

if [ ! -f "$SX_DATA_DIR/hashfs.db" ]; then
    echo
    echo "--- NODE INITIALIZATION ---"
    echo
    mkdir -p "`dirname $SX_DATA_DIR`"
    test -n "$SX_ADMIN_KEY" && echo "$SX_ADMIN_KEY" > $ADMINKEY_TMP
    test -n "$SX_CLUSTER_UUID" && UUIDFLAG="--cluster-uuid=$SX_CLUSTER_UUID"
    test -n "$SX_CLUSTER_KEY" && echo "$SX_CLUSTER_KEY" > $CLUSTKEY_TMP && KEYFLAG="--cluster-key=$CLUSTKEY_TMP"

    if [ "$BARE_GIVEN" = "yes" ]; then
	if [ "$CONFIG_FILE_GIVEN" = "yes" -a "$SX_CFG_VERSION" = "2" ]; then
	    if [ -z "$UUIDFLAG" ]; then
		echo "SX_CLUSTER_UUID must be set with a valid cluster UUID"
		exit 1
	    fi
	    if [ -z "$SX_CLUSTER_KEY" -o -z "`echo $SX_CLUSTER_KEY | grep 'CLUSTER/ALLNODE/ROOT/'`" ]; then
		echo "SX_CLUSTER_KEY must be set with a valid cluster key"
		exit 1
	    fi
	fi

	# Create node
        "/usr/sbin/sxadm" node --new\
            --batch-mode $OWNERFLAG $UUIDFLAG $KEYFLAG\
            "$SX_DATA_DIR"
	if [ $? -ne 0 ]; then
	    echo "Failed to create the bare node. Please make sure that $SX_SERVER_USER:$SX_SERVER_GROUP"
	    echo "has write access to $SX_DATA_DIR"
	    exit 1
	fi

	# Start the new node
	"/usr/sbin/sxserver" start
	if [ $? -ne 0 ]; then
	    echo "Failed to start the bare node."
	    exit 1
	fi
	if [ -n "$SX_NODE_INTERNAL_IP" -a "$SX_NODE_INTERNAL_IP" != "$SX_NODE_IP" ]; then
	    NEWNODE="$SX_NODE_SIZE/$SX_NODE_IP/$SX_NODE_INTERNAL_IP"
	else
	    NEWNODE="$SX_NODE_SIZE/$SX_NODE_IP"
	fi
	echo "SX_CLUSTER_UUID=`/usr/sbin/sxadm node $OWNERFLAG --info $SX_DATA_DIR | grep 'Cluster UUID' | cut -d\  -f 3`" >> $CONFIG
	echo "SX_CLUSTER_KEY=`/usr/sbin/sxadm node $OWNERFLAG --info $SX_DATA_DIR | grep 'Cluster key' | cut -d\  -f 3`" >> $CONFIG
	echo "SX_ADMIN_KEY=`/usr/sbin/sxadm node $OWNERFLAG --info $SX_DATA_DIR | grep 'Admin key' | cut -d\  -f 3`" >> $CONFIG


	echo "Bare node created. Use 'sxadm cluster --mod' to join it to the cluster"
	echo "or perform another operation."
	echo "Node specification: $NEWNODE"
        rm -rf $SXSETUP_TMPDIR
        trap - EXIT INT
        exit 0

    elif [ -z "$SX_EXISTING_NODE_IP" ]; then
        "/usr/sbin/sxadm" node --new\
            --batch-mode $OWNERFLAG $KEYFLAG\
            $UUIDFLAG "$SX_DATA_DIR"
	if [ $? -ne 0 ]; then
	    echo "Failed to create the first node. Please make sure that $SX_SERVER_USER:$SX_SERVER_GROUP"
	    echo "has write access to $SX_DATA_DIR"
	    exit 1
	fi

	test -z "$NOSSL_FLAG" && SSLCAFILE="--ssl-ca-file=$SX_SSL_CERT_FILE"
	if [ -n "$SX_NODE_INTERNAL_IP" -a "$SX_NODE_INTERNAL_IP" != "$SX_NODE_IP" ]; then
	    NEWNODE="$SX_NODE_SIZE/$SX_NODE_IP/$SX_NODE_INTERNAL_IP"
	else
	    NEWNODE="$SX_NODE_SIZE/$SX_NODE_IP"
	fi

	if [ "$FORCE_REINIT_GIVEN" = "yes" -a "$CONFIG_FILE_GIVEN" != "yes" ]; then
	    SX_ADMIN_KEY=
	fi
	if [ -n "$SX_ADMIN_KEY" ]; then
	    echo $SX_ADMIN_KEY > $ADMINKEY_TMP
	    ADMKEYFILE="--admin-key $ADMINKEY_TMP"
	fi
        "/usr/sbin/sxadm" cluster --new\
            --port="$SX_PORT"\
            --batch-mode\
	    --node-dir="$SX_DATA_DIR"\
	    $ADMKEYFILE \
            $SSLCAFILE \
	    $NEWNODE \
	    "sx://$SX_CLUSTER_NAME"
	if [ $? -ne 0 ]; then
	    echo "Failed to create the initial cluster."
	    exit 1
	fi

	echo "SX_CLUSTER_UUID=`/usr/sbin/sxadm node $OWNERFLAG --info $SX_DATA_DIR | grep 'Cluster UUID' | cut -d\  -f 3`" >> $CONFIG
	echo "SX_CLUSTER_KEY=`/usr/sbin/sxadm node $OWNERFLAG --info $SX_DATA_DIR | grep 'Cluster key' | cut -d\  -f 3`" >> $CONFIG
	SX_ADMIN_KEY="`/usr/sbin/sxadm node $OWNERFLAG --info $SX_DATA_DIR | grep 'Admin key' | cut -d\  -f 3`"
	echo "SX_ADMIN_KEY=$SX_ADMIN_KEY" >> $CONFIG

	"/usr/sbin/sxserver" start
	if [ $? -ne 0 ]; then
	    echo "Failed to start the new node."
	    exit 1
	fi

	# store sxsetup.conf (non-critical)
	if [ "$NO_REMOTE_COPY_GIVEN" != "yes" ]; then
	    echo "$SX_ADMIN_KEY" > $ADMINKEY_TMP
	    "/usr/bin/sxinit" --batch-mode --force-reinit --port="$SX_PORT" $NOSSL_FLAG --auth-file="$ADMINKEY_TMP" --host-list="$SX_NODE_IP" "sx://admin@$SX_CLUSTER_NAME" > /dev/null 2>&1
	    if [ $? = 0 ]; then
		XCONF=`cat $CONFIG | xxd -ps 2>/dev/null | tr -d '\n'`
		if [ -n "$XCONF" ]; then
		    "/usr/sbin/sxadm" cluster --set-param sxsetup_conf=$XCONF "sx://admin@$SX_CLUSTER_NAME" > /dev/null 2>&1
		    if [ $? = 0 ]; then
			"/usr/bin/sxrm" -r "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
			"/usr/bin/sxvol" remove "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
		    fi
		fi
	    fi
	fi

    else
	# Config access to the cluster
	test "$CONFIG_FILE_GIVEN" = "yes" && SXINITFLAGS="--batch-mode"
	"/usr/bin/sxinit" --force-reinit --port="$SX_PORT" $NOSSL_FLAG $SXINITFLAGS --auth-file="$ADMINKEY_TMP" --host-list="$SX_EXISTING_NODE_IP" "sx://admin@$SX_CLUSTER_NAME"
	if [ $? -ne 0 ]; then
	    echo "Failed to connect to the cluster. Please make sure the admin key is correct"
	    echo "and $SX_EXISTING_NODE_IP is a valid and accessible node of the cluster sx://$SX_CLUSTER_NAME"
	    exit 1
	fi
	SXUUID=`cat $HOME/.sx/$SX_CLUSTER_NAME/config | grep ClusterUUID | cut -d= -f2`
	if [ -z "$SXUUID" ]; then
	    echo "Cannot obtain cluster's UUID"
	    exit 1
	fi
	echo "SX_CLUSTER_UUID=\"$SXUUID\"" >> "$CONFIG"

	# Get cluster key
	if [ -z "$SX_CLUSTER_KEY" ]; then
	    "/usr/sbin/sxadm" cluster --get-cluster-key "sx://admin@$SX_CLUSTER_NAME" > $OUT_TMP
	    if [ $? -ne 0 ]; then
		echo "Failed to retrieve current configuration of the cluster."
		exit 1
	    fi
	    SX_CLUSTER_KEY=`cat $OUT_TMP | grep "Cluster key: " | cut -d\  -f3`
	    if [ -z "$SX_CLUSTER_KEY" -o -z "`echo $SX_CLUSTER_KEY | grep 'CLUSTER/ALLNODE/ROOT/'`" ]; then
		echo "Failed to obtain the cluster key."
		exit 1
	    fi
	fi
	echo "$SX_CLUSTER_KEY" > $CLUSTKEY_TMP
	echo "SX_CLUSTER_KEY=\"$SX_CLUSTER_KEY\"" >> "$CONFIG"
	echo "SX_ADMIN_KEY=\"$SX_ADMIN_KEY\"" >> "$CONFIG"

	# Create node
        "/usr/sbin/sxadm" node --new\
            --batch-mode $OWNERFLAG\
	    --cluster-uuid="$SXUUID"\
	    --cluster-key="$CLUSTKEY_TMP"\
            "$SX_DATA_DIR"
	if [ $? -ne 0 ]; then
	    echo "Failed to create the node. Please make sure that $SX_SERVER_USER:$SX_SERVER_GROUP"
	    echo "has write access to $SX_DATA_DIR"
	    exit 1
	fi

	# Start the new node
	"/usr/sbin/sxserver" start
	if [ $? -ne 0 ]; then
	    echo "Failed to start the new node."
	    exit 1
	fi

	if [ -n "$SX_NODE_INTERNAL_IP" -a "$SX_NODE_INTERNAL_IP" != "$SX_NODE_IP" ]; then
	    NEWNODE="$SX_NODE_SIZE/$SX_NODE_IP/$SX_NODE_INTERNAL_IP"
	else
	    NEWNODE="$SX_NODE_SIZE/$SX_NODE_IP"
	fi

	cluster_modify
	if [ $? -ne 0 ]; then
	    "/usr/sbin/sxserver" stop
	    exit 1
	fi

	# store sxsetup.conf (non-critical)
	if [ "$NO_REMOTE_COPY_GIVEN" != "yes" ]; then
	    XCONF=`cat $CONFIG | xxd -ps 2>/dev/null | tr -d '\n'`
	    if [ -n "$XCONF" ]; then
		"/usr/sbin/sxadm" cluster --set-param sxsetup_conf=$XCONF "sx://admin@$SX_CLUSTER_NAME" > /dev/null 2>&1
		if [ $? = 0 ]; then
		    "/usr/bin/sxrm" -r "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
		    "/usr/bin/sxvol" remove "sx://admin@$SX_CLUSTER_NAME/_sxsetup.conf" > /dev/null 2>&1
		fi
	    fi
	fi

	if [ "$WAIT_GIVEN" = "yes" ]; then
	    echo "Waiting for cluster to finish rebalancing..."
	    while true; do
		"/usr/sbin/sxadm" cluster --info "sx://admin@$SX_CLUSTER_NAME" > $OUT_TMP
		if [ $? -ne 0 ]; then
		    sleep 10
		    continue
		fi
		if [ -n "`cat $OUT_TMP | grep 'activity:'`" ]; then
		    sleep 10
		    continue
		else
		    break
		fi
	    done
	fi
    fi

else
    echo "Cluster is already initialized in $SX_DATA_DIR"
    # TODO loopback but remember what I typed
fi

"/usr/sbin/sxadm" node $OWNERFLAG --info --human-readable "$SX_DATA_DIR" | grep -v "HashFS Version"

rm -rf $SXSETUP_TMPDIR
trap - EXIT INT

echo
echo "--- CONFIGURATION SUMMARY ---"
echo
if [ -z "$NOSSL_FLAG" ]; then
    echo "SSL private key ($SX_SSL_KEY_FILE):"
    cat "$SX_SSL_KEY_FILE"
    echo
    echo "SSL certificate ($SX_SSL_CERT_FILE):"
    cat "$SX_SSL_CERT_FILE"
fi

echo
echo "Cluster: sx://$SX_CLUSTER_NAME"

if [ -n "$SX_NODE_INTERNAL_IP" -a "$SX_NODE_IP" != "$SX_NODE_INTERNAL_IP" ]; then
    echo "This node: $SX_NODE_IP (internal address: $SX_NODE_INTERNAL_IP)"
else
    echo "This node: $SX_NODE_IP"
fi
echo "Port number: $SX_PORT"
"/usr/sbin/sxadm" node $OWNERFLAG --info --human-readable "$SX_DATA_DIR" | grep -v "HashFS Version"
echo "Storage location: $SX_DATA_DIR"
echo "Run as user: $SX_SERVER_USER"
echo "Sockets and pidfiles in: $SX_RUN_DIR"
echo "Logs in: $SX_LOG_FILE"
echo
echo "--- END OF SUMMARY ---"
echo
echo "Congratulations, the new node is up and running!"
echo "You can control it with '/usr/sbin/sxserver'"
echo
echo "You can add a new node to the cluster by running 'sxsetup' on another server."
if [ -z "$NOSSL_FLAG" ]; then
    echo "When prompted, enter the 'admin key', 'SSL private key' and"
    echo "'SSL certificate' printed above."
else
    echo "When prompted, enter the 'admin key' printed above."
fi
echo
echo "You can run 'sxacl useradd joe sx://admin@$SX_CLUSTER_NAME' to add a new user."
echo "To create a new volume owned by user 'joe' run:"
echo "'sxvol create --owner joe --replica N --size SIZE sx://admin@$SX_CLUSTER_NAME/VOLNAME'"
echo

exit 0
