# lib/cinder
# Install and start Cinder volume service

# Dependencies:
# - functions
# - KEYSTONE_AUTH_* must be defined
# SERVICE_{TENANT_NAME|PASSWORD} must be defined

# stack.sh
# ---------
# install_XXX
# configure_XXX
# init_XXX
# start_XXX
# stop_XXX
# cleanup_XXX

# Print the commands being run so that we can see the command that triggers
# an error.  It is also useful for following along as the install occurs.
set -o xtrace


# Defaults
# --------

# set up default directories
CINDER_DIR=$DEST/cinder
CINDERCLIENT_DIR=$DEST/python-cinderclient
CINDER_CONF_DIR=/etc/cinder
CINDER_CONF=$CINDER_CONF_DIR/cinder.conf

# Name of the lvm volume group to use/create for iscsi volumes
VOLUME_GROUP=${VOLUME_GROUP:-stack-volumes}
VOLUME_NAME_PREFIX=${VOLUME_NAME_PREFIX:-volume-}

# cleanup_cinder() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_cinder() {
    # This function intentionally left blank
    :
}

# configure_cinder() - Set config files, create data dirs, etc
function configure_cinder() {
    setup_develop $CINDER_DIR
    setup_develop $CINDERCLIENT_DIR

    if [[ ! -d $CINDER_CONF_DIR ]]; then
        sudo mkdir -p $CINDER_CONF_DIR
    fi
    sudo chown `whoami` $CINDER_CONF_DIR

    cp -p $CINDER_DIR/etc/cinder/policy.json $CINDER_CONF_DIR

    CINDER_API_PASTE_INI=$CINDER_CONF_DIR/api-paste.ini
    cp $CINDER_DIR/etc/cinder/api-paste.ini $CINDER_API_PASTE_INI
    iniset $CINDER_API_PASTE_INI filter:authtoken auth_host $KEYSTONE_AUTH_HOST
    iniset $CINDER_API_PASTE_INI filter:authtoken auth_port $KEYSTONE_AUTH_PORT
    iniset $CINDER_API_PASTE_INI filter:authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
    iniset $CINDER_API_PASTE_INI filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
    iniset $CINDER_API_PASTE_INI filter:authtoken admin_user cinder
    iniset $CINDER_API_PASTE_INI filter:authtoken admin_password $SERVICE_PASSWORD

    cp $CINDER_DIR/etc/cinder/cinder.conf.sample $CINDER_CONF
    iniset $CINDER_CONF DEFAULT auth_strategy keystone
    iniset $CINDER_CONF DEFAULT verbose True
    iniset $CINDER_CONF DEFAULT volume_group $VOLUME_GROUP
    iniset $CINDER_CONF DEFAULT volume_name_template ${VOLUME_NAME_PREFIX}%s
    iniset $CINDER_CONF DEFAULT iscsi_helper tgtadm
    iniset $CINDER_CONF DEFAULT sql_connection $BASE_SQL_CONN/cinder?charset=utf8
    iniset $CINDER_CONF DEFAULT rabbit_host $RABBIT_HOST
    iniset $CINDER_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
    iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
}

# init_cinder() - Initialize database and volume group
function init_cinder() {
    # Force nova volumes off
    NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/osapi_volume,//")

    if is_service_enabled mysql; then
        # (re)create cinder database
        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS cinder;'
        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE cinder;'

        # (re)create cinder database
        $CINDER_DIR/bin/cinder-manage db sync
    fi

    if is_service_enabled c-vol; then
        # Configure a default volume group called '`stack-volumes`' for the volume
        # service if it does not yet exist.  If you don't wish to use a file backed
        # volume group, create your own volume group called ``stack-volumes`` before
        # invoking ``stack.sh``.
        #
        # By default, the backing file is 2G in size, and is stored in ``/opt/stack/data``.

        if ! sudo vgs $VOLUME_GROUP; then
            VOLUME_BACKING_FILE=${VOLUME_BACKING_FILE:-$DATA_DIR/${VOLUME_GROUP}-backing-file}
            VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-2052M}
            # Only create if the file doesn't already exists
            [[ -f $VOLUME_BACKING_FILE ]] || truncate -s $VOLUME_BACKING_FILE_SIZE $VOLUME_BACKING_FILE
            DEV=`sudo losetup -f --show $VOLUME_BACKING_FILE`
            # Only create if the loopback device doesn't contain $VOLUME_GROUP
            if ! sudo vgs $VOLUME_GROUP; then sudo vgcreate $VOLUME_GROUP $DEV; fi
        fi

        if sudo vgs $VOLUME_GROUP; then
            if [[ "$os_PACKAGE" = "rpm" ]]; then
                # RPM doesn't start the service
                start_service tgtd
            fi

            # Remove iscsi targets
            sudo tgtadm --op show --mode target | grep $VOLUME_NAME_PREFIX | grep Target | cut -f3 -d ' ' | sudo xargs -n1 tgt-admin --delete || true
            # Clean out existing volumes
            for lv in `sudo lvs --noheadings -o lv_name $VOLUME_GROUP`; do
                # VOLUME_NAME_PREFIX prefixes the LVs we want
                if [[ "${lv#$VOLUME_NAME_PREFIX}" != "$lv" ]]; then
                    sudo lvremove -f $VOLUME_GROUP/$lv
                fi
            done
        fi
    fi
}

# install_cinder() - Collect source and prepare
function install_cinder() {
    git_clone $CINDER_REPO $CINDER_DIR $CINDER_BRANCH
    git_clone $CINDERCLIENT_REPO $CINDERCLIENT_DIR $CINDERCLIENT_BRANCH
}

# start_cinder() - Start running processes, including screen
function start_cinder() {
    if is_service_enabled c-vol; then
        if [[ "$os_PACKAGE" = "deb" ]]; then
            # tgt in oneiric doesn't restart properly if tgtd isn't running
            # do it in two steps
            sudo stop tgt || true
            sudo start tgt
        else
            # bypass redirection to systemctl during restart
            sudo /sbin/service --skip-redirect tgtd restart
        fi
    fi

    screen_it c-api "cd $CINDER_DIR && $CINDER_DIR/bin/cinder-api --config-file $CINDER_CONF"
    screen_it c-vol "cd $CINDER_DIR && $CINDER_DIR/bin/cinder-volume --config-file $CINDER_CONF"
    screen_it c-sch "cd $CINDER_DIR && $CINDER_DIR/bin/cinder-scheduler --config-file $CINDER_CONF"
}

# stop_cinder() - Stop running processes (non-screen)
function stop_cinder() {
    # FIXME(dtroyer): stop only the cinder screen window?

    if is_service_enabled c-vol; then
        stop_service tgt
    fi
}
