#!/bin/sh 

# if we start up as ./init-ceph, assume everything else is in the
# current directory too.
if [ `dirname $0` = "." ] && [ $PWD != "/etc/init.d" ]; then
    BINDIR=.
    LIBDIR=.
    ETCDIR=.
else
    BINDIR=/usr/bin
    LIBDIR=/usr/lib64/ceph
    # i hate autoconf:
    if [ "/etc" = "/usr/etc" ]; then
	ETCDIR=/etc/ceph
    else
	ETCDIR=/etc/ceph
    fi
fi

usage_exit() {
    echo "usage: $0 -c ceph.conf [--allhosts] [--mkbtrfs] [-k adminkeyring]"
    echo "   ** be careful, this WILL clobber old data; check your ceph.conf carefully **"
    exit
}

. $LIBDIR/ceph_common.sh


allhosts=0
clobber=""
mkbtrfs=0
numosd=
usecrushmapsrc=
usecrushmap=
verbose=0
adminkeyring=""
conf=""

while [ $# -ge 1 ]; do
case $1 in
    -v )
	    verbose=1;
	    ;;
    --allhosts | -a)
	    allhosts=1
	    ;;
    --clobber | --clobber_old_data)
	    clobber="--clobber"
	    ;;
    --mkbtrfs)
	    mkbtrfs=1
	    ;;
    --conf | -c)
	    [ "$2" = "" ] && usage_exit
	    shift
	    conf=$1
	    ;;
    --numosd)
	    [ "$2" = "" ] && usage_exit
	    shift
	    numosd=$1
	    ;;
    --crushmapsrc)
	    [ "$2" = "" ] && usage_exit
	    shift
	    usecrushmapsrc=$1
	    ;;
    --crushmap)
	    [ "$2" = "" ] && usage_exit
	    shift
	    usecrushmap=$1
	    ;;
    -k)
	    [ "$2" = "" ] && usage_exit
	    shift
	    adminkeyring=$1
	    ;;
    *)
	    echo unrecognized option \'$1\'
	    usage_exit
	    ;;
esac
shift
done

[ -z "$conf" ] && usage_exit

verify_conf

get_name_list "$@"

# create the monmap if we're doing mon0
if echo $what | grep -q mon0 ; then
    # first, make a list of monitors
    mons=`$CCONF -c $conf -l mon | egrep -v '^mon$' | sort`
    args=""

    type="mon"
    for name in $mons; do
	id=`echo $name | cut -c 4- | sed 's/\\.//'`
	get_conf addr "" "mon addr"
	args=$args" --add $addr"
    done

    # build monmap
    monmap="/tmp/monmap.$$"
    echo $BINDIR/monmaptool --create --clobber $args --print $monmap || exit 1
    $BINDIR/monmaptool --create --clobber $args --print $monmap || exit 1

    # build osdmap
    osdmap="/tmp/osdmap.$$"
    if [ -z "$numosd" ]; then
	maxosd=`$CCONF -c $conf -l osd | egrep -v '^osd$' | tail -1 | cut -c 4-`
	numosd=$(($maxosd + 1))
	echo max osd in $conf is $maxosd, num osd is $numosd
    fi
    $BINDIR/osdmaptool --clobber --createsimple $numosd $osdmap || exit 1

    # import crush map?
    get_conf crushmapsrc "$usecrushmapsrc" "crush map src" mon0 mon global
    if [ -n "$crushmapsrc" ]; then
	echo Compiling crush map from $crushmapsrc to $crushmap
	crushmap="/tmp/crushmap.$$"
	$BINDIR/crushtool -c $crushmapsrc -o $crushmap
    fi
    get_conf crushmap "$usecrushmap" "crush map" mon0 mon global
    if [ -n "$crushmap" ]; then
	echo Importing crush map from $crushmap
	$BINDIR/osdmaptool --clobber --import-crush $crushmap $osdmap
    fi

    # admin keyring
    [ -z "$adminkeyring" ] && adminkeyring="/tmp/admin.keyring.$$"
    echo Building admin keyring at $adminkeyring
    cat <<EOF > /tmp/admin_caps.$$
; generated by mkcephfs on `date`
	mon = "allow *"
	osd = "allow *"
	mds = "allow"
EOF
    [ -e "$monkeyring" ] && rm -f $monkeyring
    $BINDIR/cauthtool --create-keyring --gen-key --name=client.admin --set-uid=0 --caps=/tmp/admin_caps.$$ $adminkeyring
    rm -f /tmp/admin_caps.$$

    # mon keyring (for monitor)
    echo Building monitor keyring with all service keys
    monkeyring="/tmp/monkeyring.$$"
    $BINDIR/cauthtool --create-keyring --gen-key --name=mon. $monkeyring

    $BINDIR/cauthtool --import-keyring $adminkeyring $monkeyring

    cat <<EOF > /tmp/osd.caps.$$
; generated by mkcephfs on `date`
	mon = "allow rwx"
	osd = "allow *"
EOF
    cat <<EOF > /tmp/mds.caps.$$
; generated by mkcephfs on `date`
	mon = "allow rwx"
	osd = "allow *"
	mds = "allow"
EOF

    for name in $what; do
	type=`echo $name | cut -c 1-3`   # e.g. 'mon', if $name is 'mon1'
	id=`echo $name | cut -c 4- | sed 's/\\.//'`

	if [ "$type" = "osd" ]; then
	    $BINDIR/cauthtool --create-keyring --gen-key --name=osd.$id --caps=/tmp/osd.caps.$$ /tmp/keyring.osd.$id
	    $BINDIR/cauthtool --import-keyring /tmp/keyring.osd.$id $monkeyring
	fi
	if [ "$type" = "mds" ]; then
	    $BINDIR/cauthtool --create-keyring --gen-key --name=mds.$id --caps=/tmp/mds.caps.$$ /tmp/keyring.mds.$id
	    $BINDIR/cauthtool --import-keyring /tmp/keyring.mds.$id $monkeyring
	fi
    done

    tmpkeyring="/tmp/keyring.$$"
fi


# create monitors, osds
for name in $what; do
    type=`echo $name | cut -c 1-3`   # e.g. 'mon', if $name is 'mon1'
    id=`echo $name | cut -c 4- | sed 's/\\.//'`
    num=$id

    check_host || continue

    if [ -n "$ssh" ] && ( echo $pushed_to | grep -v -q " $host " ); then
	scp -q $osdmap $host:$osdmap
	scp -q $monmap $host:$monmap
	pushed_to="$pushed_to $host "
    fi

    if [ "$type" = "mon" ]; then
	if [ -n "$ssh" ]; then
	    if [ -n "$user" ]; then
		scp -q $monkeyring $user@$host:$tmpkeyring
	    else
		scp -q $monkeyring $host:$tmpkeyring
	    fi
	else
	    cp -a $monkeyring $tmpkeyring
	    [ -n "$user" ] && chown $user $tmpkeyring
	fi
	get_conf mon_data "" "mon data"
	do_cmd "$BINDIR/mkmonfs --clobber --mon-data $mon_data -i $num --monmap $monmap --osdmap $osdmap -k $tmpkeyring ; rm -f $tmpkeyring"

	if [ -n "$ssh" ]; then
	    if [ -n "$user" ]; then
		scp -p $adminkeyring $user@$host:$mon_data/admin_keyring.bin
	    else
		scp -p $adminkeyring $host:$mon_data/admin_keyring.bin
	    fi
	else
	    cp -av $adminkeyring $mon_data/admin_keyring.bin
	fi
    fi

    if [ "$type" = "osd" ]; then
	get_conf osd_data "" "osd data"
	get_conf keyring "" "keyring"
	get_conf btrfs_path "$osd_data" "btrfs path"  # mount point defaults so osd data
	get_conf btrfs_devs "" "btrfs devs"
	first_dev=`echo $btrfs_devs | cut '-d ' -f 1`
	get_conf btrfs_opt "noatime" "btrfs options"
	[ -n "$btrfs_opt" ] && btrfs_opt="-o $btrfs_opt"
	
	do_cmd "test -d $osd_data || mkdir -p $osd_data"

	if [ $mkbtrfs -eq 1 ]; then
	    get_conf osd_user "root" "user"
	    do_root_cmd "umount $btrfs_path ; for f in $btrfs_devs ; do umount \$f ; done ; modprobe btrfs ; mkfs.btrfs $btrfs_devs ; modprobe btrfs ; btrfsctl -a ; mount -t btrfs $btrfs_opt $first_dev $btrfs_path ; chown $osd_user $btrfs_path ; chmod +w $btrfs_path "
	fi

	[ -n "$ssh" ] && scp $monmap $host:$monmap
	do_root_cmd "$BINDIR/cosd -c $conf --monmap $monmap -i $num --mkfs --osd-data $osd_data"
	[ -n "$user" ] && do_root_cmd "chown -R $user $osd_data"

	if [ -n "$keyring" ]; then
	    if [ -n "$ssh" ]; then
		if [ -n "$user" ]; then
		    scp /tmp/keyring.osd.$id $user@$host:$keyring
		else
		    scp /tmp/keyring.osd.$id $host:$keyring
		fi
	    else
		cp -v /tmp/keyring.osd.$id $keyring
	    fi
	else
	    echo WARNING: no keyring specified for $name
	fi
	rm -f /tmp/keyring.osd.$id
    fi

    if [ "$type" = "mds" ]; then
	get_conf keyring "" "keyring"
	if [ -n "$keyring" ]; then
	    if [ -n "$ssh" ]; then
		if [ -n "$user" ]; then
		    scp /tmp/keyring.mds.$id $user@$host:$keyring
		else
		    scp /tmp/keyring.mds.$id $host:$keyring
		fi
	    else
		cp -v /tmp/keyring.mds.$id $keyring
	    fi
	else
	    echo WARNING: no keyring specified for $name
	fi
	rm -f /tmp/keyring.mds.$id
    fi

done

rm -f $monkeyring
