#!/bin/bash
#
# lib/cinder
# Install and start **Cinder** volume service

# Dependencies:
#
# - functions
# - DEST, DATA_DIR, STACK_USER must be defined
# - SERVICE_{TENANT_NAME|PASSWORD} must be defined
# - ``KEYSTONE_TOKEN_FORMAT`` must be defined

# stack.sh
# ---------
# - install_cinder
# - configure_cinder
# - init_cinder
# - start_cinder
# - stop_cinder
# - cleanup_cinder

# Save trace setting
_XTRACE_CINDER=$(set +o | grep xtrace)
set +o xtrace


# Defaults
# --------

# set up default driver
CINDER_DRIVER=${CINDER_DRIVER:-default}
CINDER_PLUGINS=$TOP_DIR/lib/cinder_plugins
CINDER_BACKENDS=$TOP_DIR/lib/cinder_backends
CINDER_BACKUPS=$TOP_DIR/lib/cinder_backups

# grab plugin config if specified via cinder_driver
if [[ -r $CINDER_PLUGINS/$CINDER_DRIVER ]]; then
    source $CINDER_PLUGINS/$CINDER_DRIVER
fi

# set up default directories
GITDIR["python-cinderclient"]=$DEST/python-cinderclient
GITDIR["python-brick-cinderclient-ext"]=$DEST/python-brick-cinderclient-ext
CINDER_DIR=$DEST/cinder

if [[ $SERVICE_IP_VERSION == 6 ]]; then
    CINDER_MY_IP="$HOST_IPV6"
else
    CINDER_MY_IP="$HOST_IP"
fi


# Cinder virtual environment
if [[ ${USE_VENV} = True ]]; then
    PROJECT_VENV["cinder"]=${CINDER_DIR}.venv
    CINDER_BIN_DIR=${PROJECT_VENV["cinder"]}/bin
else
    CINDER_BIN_DIR=$(get_python_exec_prefix)
fi

CINDER_STATE_PATH=${CINDER_STATE_PATH:=$DATA_DIR/cinder}

CINDER_CONF_DIR=/etc/cinder
CINDER_CONF=$CINDER_CONF_DIR/cinder.conf
CINDER_UWSGI=$CINDER_BIN_DIR/cinder-wsgi
CINDER_UWSGI_CONF=$CINDER_CONF_DIR/cinder-api-uwsgi.ini
CINDER_API_PASTE_INI=$CINDER_CONF_DIR/api-paste.ini

# Public facing bits
if is_service_enabled tls-proxy; then
    CINDER_SERVICE_PROTOCOL="https"
fi
CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
CINDER_SERVICE_PORT_INT=${CINDER_SERVICE_PORT_INT:-18776}
CINDER_SERVICE_PROTOCOL=${CINDER_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
CINDER_SERVICE_LISTEN_ADDRESS=${CINDER_SERVICE_LISTEN_ADDRESS:-$(ipv6_unquote $SERVICE_LISTEN_ADDRESS)}

# We do not need to report service status every 10s for devstack-like
# deployments. In the gate this generates extra work for the services and the
# database which are already taxed.
CINDER_SERVICE_REPORT_INTERVAL=120

# What type of LVM device should Cinder use for LVM backend
# Defaults to auto, which will do thin provisioning if it's a fresh
# volume group, otherwise it will do thick. The other valid choices are
# default, which is thick, or thin, which as the name implies utilizes lvm
# thin provisioning.
CINDER_LVM_TYPE=${CINDER_LVM_TYPE:-auto}

# Default backends
# The backend format is type:name where type is one of the supported backend
# types (lvm, nfs, etc) and name is the identifier used in the Cinder
# configuration and for the volume type name.  Multiple backends are
# comma-separated.
# The old ``CINDER_MULTI_LVM_BACKEND=True`` setting had a default of:
# CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:lvmdriver-1,lvm:lvmdriver-2}
CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:lvmdriver-1}

CINDER_VOLUME_CLEAR=${CINDER_VOLUME_CLEAR:-${CINDER_VOLUME_CLEAR_DEFAULT:-zero}}
CINDER_VOLUME_CLEAR=$(echo ${CINDER_VOLUME_CLEAR} | tr '[:upper:]' '[:lower:]')

VOLUME_TYPE_MULTIATTACH=${VOLUME_TYPE_MULTIATTACH:-multiattach}

if [[ -n "$CINDER_ISCSI_HELPER" ]]; then
    if [[ -z "$CINDER_TARGET_HELPER" ]]; then
        deprecated 'Using CINDER_ISCSI_HELPER is deprecated, use CINDER_TARGET_HELPER instead'
        CINDER_TARGET_HELPER="$CINDER_ISCSI_HELPER"
    else
        deprecated 'Deprecated CINDER_ISCSI_HELPER is set, but is being overwritten by CINDER_TARGET_HELPER'
    fi
fi
CINDER_TARGET_HELPER=${CINDER_TARGET_HELPER:-lioadm}

if [[ $CINDER_TARGET_HELPER == 'nvmet' ]]; then
    CINDER_TARGET_PROTOCOL=${CINDER_TARGET_PROTOCOL:-'nvmet_rdma'}
    CINDER_TARGET_PREFIX=${CINDER_TARGET_PREFIX:-'nvme-subsystem-1'}
    CINDER_TARGET_PORT=${CINDER_TARGET_PORT:-4420}
else
    CINDER_TARGET_PROTOCOL=${CINDER_TARGET_PROTOCOL:-'iscsi'}
    CINDER_TARGET_PREFIX=${CINDER_TARGET_PREFIX:-'iqn.2010-10.org.openstack:'}
    CINDER_TARGET_PORT=${CINDER_TARGET_PORT:-3260}
fi


# EL should only use lioadm
if is_fedora; then
    if [[ ${CINDER_TARGET_HELPER} != "lioadm" && ${CINDER_TARGET_HELPER} != 'nvmet' ]]; then
        die "lioadm and nvmet are the only valid Cinder target_helper config on this platform"
    fi
fi

# When Cinder is used as a backend for Glance, it can be configured to clone
# the volume containing image data directly in the backend instead of
# transferring data from volume to volume.  Value is a comma separated list of
# schemes (currently only 'file' and 'cinder' are supported).  The default
# configuration in Cinder is empty (that is, do not use this feature).  NOTE:
# to use this feature you must also enable GLANCE_SHOW_DIRECT_URL and/or
# GLANCE_SHOW_MULTIPLE_LOCATIONS for glance-api.conf.
CINDER_ALLOWED_DIRECT_URL_SCHEMES=${CINDER_ALLOWED_DIRECT_URL_SCHEMES:-}
if [[ -n "$CINDER_ALLOWED_DIRECT_URL_SCHEMES" ]]; then
    if [[ "${GLANCE_SHOW_DIRECT_URL:-False}" != "True" \
            && "${GLANCE_SHOW_MULTIPLE_LOCATIONS:-False}" != "True" ]]; then
        warn $LINENO "CINDER_ALLOWED_DIRECT_URL_SCHEMES is set, but neither \
GLANCE_SHOW_DIRECT_URL nor GLANCE_SHOW_MULTIPLE_LOCATIONS is True"
    fi
fi

# For backward compatibility
# Before CINDER_BACKUP_DRIVER was introduced, ceph backup driver was configured
# along with ceph backend driver.
if [[ -z "${CINDER_BACKUP_DRIVER}" && "$CINDER_ENABLED_BACKENDS" =~ "ceph" ]]; then
    CINDER_BACKUP_DRIVER=ceph
fi

# Supported backup drivers are in lib/cinder_backups
CINDER_BACKUP_DRIVER=${CINDER_BACKUP_DRIVER:-swift}

# Toggle for deploying Cinder under a wsgi server. Legacy mod_wsgi
# reference should be cleaned up to more accurately refer to uwsgi.
CINDER_USE_MOD_WSGI=${CINDER_USE_MOD_WSGI:-True}

# Source the enabled backends
if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
    for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
        be_type=${be%%:*}
        be_name=${be##*:}
        if [[ -r $CINDER_BACKENDS/${be_type} ]]; then
            source $CINDER_BACKENDS/${be_type}
        fi
    done
fi

# Source the backup driver
if is_service_enabled c-bak && [[ -n "$CINDER_BACKUP_DRIVER" ]]; then
    if [[ -r $CINDER_BACKUPS/$CINDER_BACKUP_DRIVER ]]; then
        source $CINDER_BACKUPS/$CINDER_BACKUP_DRIVER
    else
        die "cinder backup driver $CINDER_BACKUP_DRIVER is not supported"
    fi
fi

# Environment variables to configure the image-volume cache
CINDER_IMG_CACHE_ENABLED=${CINDER_IMG_CACHE_ENABLED:-True}

# For limits, if left unset, it will use cinder defaults of 0 for unlimited
CINDER_IMG_CACHE_SIZE_GB=${CINDER_IMG_CACHE_SIZE_GB:-}
CINDER_IMG_CACHE_SIZE_COUNT=${CINDER_IMG_CACHE_SIZE_COUNT:-}

# Configure which cinder backends will have the image-volume cache, this takes the same
# form as the CINDER_ENABLED_BACKENDS config option. By default it will
# enable the cache for all cinder backends.
CINDER_CACHE_ENABLED_FOR_BACKENDS=${CINDER_CACHE_ENABLED_FOR_BACKENDS:-$CINDER_ENABLED_BACKENDS}

# Flag to set the oslo_policy.enforce_scope. This is used to switch
# the  Volume API policies to start checking the scope of token. by default,
# this flag is False.
# For more detail: https://docs.openstack.org/oslo.policy/latest/configuration/index.html#oslo_policy.enforce_scope
CINDER_ENFORCE_SCOPE=$(trueorfalse False CINDER_ENFORCE_SCOPE)

# Functions
# ---------

# Test if any Cinder services are enabled
# is_cinder_enabled
function is_cinder_enabled {
    [[ ,${DISABLED_SERVICES} =~ ,"cinder" ]] && return 1
    [[ ,${ENABLED_SERVICES} =~ ,"c-" ]] && return 0
    return 1
}

# _cinder_cleanup_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cinder_cleanup_apache_wsgi {
    sudo rm -f $(apache_site_config_for osapi-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 {
    # ensure the volume group is cleared up because fails might
    # leave dead volumes in the group
    if [ "$CINDER_TARGET_HELPER" = "tgtadm" ]; then
        local targets
        targets=$(sudo tgtadm --op show --mode target)
        if [ $? -ne 0 ]; then
            # If tgt driver isn't running this won't work obviously
            # So check the response and restart if need be
            echo "tgtd seems to be in a bad state, restarting..."
            if is_ubuntu; then
                restart_service tgt
            else
                restart_service tgtd
            fi
            targets=$(sudo tgtadm --op show --mode target)
        fi

        if [[ -n "$targets" ]]; then
            local iqn_list=( $(grep --no-filename -r iqn $SCSI_PERSIST_DIR | sed 's/<target //' | sed 's/>//') )
            for i in "${iqn_list[@]}"; do
                echo removing iSCSI target: $i
                sudo tgt-admin --delete $i
            done
        fi

        if is_ubuntu; then
            stop_service tgt
        else
            stop_service tgtd
        fi
    elif [ "$CINDER_TARGET_HELPER" = "lioadm" ]; then
        sudo cinder-rtstool get-targets | sudo xargs -rn 1 cinder-rtstool delete
    elif [ "$CINDER_TARGET_HELPER" = "nvmet" ]; then
        # If we don't disconnect everything vgremove will block
        sudo nvme disconnect-all
        sudo nvmetcli clear
    else
        die $LINENO "Unknown value \"$CINDER_TARGET_HELPER\" for CINDER_TARGET_HELPER"
    fi

    if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
        local be be_name be_type
        for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
            be_type=${be%%:*}
            be_name=${be##*:}
            if type cleanup_cinder_backend_${be_type} >/dev/null 2>&1; then
                cleanup_cinder_backend_${be_type} ${be_name}
            fi
        done
    fi

    if is_service_enabled c-bak && [[ -n "$CINDER_BACKUP_DRIVER" ]]; then
        if type cleanup_cinder_backup_$CINDER_BACKUP_DRIVER >/dev/null 2>&1; then
            cleanup_cinder_backup_$CINDER_BACKUP_DRIVER
        fi
    fi

    stop_process "c-api"
    remove_uwsgi_config "$CINDER_UWSGI_CONF" "$CINDER_UWSGI"
}

# configure_cinder() - Set config files, create data dirs, etc
function configure_cinder {
    sudo install -d -o $STACK_USER -m 755 $CINDER_CONF_DIR

    rm -f $CINDER_CONF

    configure_rootwrap cinder

    if [[ -f "$CINDER_DIR/etc/cinder/resource_filters.json" ]]; then
        cp -p "$CINDER_DIR/etc/cinder/resource_filters.json" "$CINDER_CONF_DIR/resource_filters.json"
    fi

    cp $CINDER_DIR/etc/cinder/api-paste.ini $CINDER_API_PASTE_INI

    inicomment $CINDER_API_PASTE_INI filter:authtoken auth_host
    inicomment $CINDER_API_PASTE_INI filter:authtoken auth_port
    inicomment $CINDER_API_PASTE_INI filter:authtoken auth_protocol
    inicomment $CINDER_API_PASTE_INI filter:authtoken cafile
    inicomment $CINDER_API_PASTE_INI filter:authtoken admin_tenant_name
    inicomment $CINDER_API_PASTE_INI filter:authtoken admin_user
    inicomment $CINDER_API_PASTE_INI filter:authtoken admin_password
    inicomment $CINDER_API_PASTE_INI filter:authtoken signing_dir

    configure_keystone_authtoken_middleware $CINDER_CONF cinder

    iniset $CINDER_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL

    iniset $CINDER_CONF DEFAULT target_helper "$CINDER_TARGET_HELPER"
    iniset $CINDER_CONF database connection `database_connection_url cinder`
    iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
    iniset $CINDER_CONF DEFAULT rootwrap_config "$CINDER_CONF_DIR/rootwrap.conf"
    iniset $CINDER_CONF DEFAULT osapi_volume_extension cinder.api.contrib.standard_extensions
    iniset $CINDER_CONF DEFAULT osapi_volume_listen $CINDER_SERVICE_LISTEN_ADDRESS
    iniset $CINDER_CONF DEFAULT state_path $CINDER_STATE_PATH
    iniset $CINDER_CONF oslo_concurrency lock_path $CINDER_STATE_PATH
    iniset $CINDER_CONF DEFAULT my_ip "$CINDER_MY_IP"
    iniset $CINDER_CONF key_manager backend cinder.keymgr.conf_key_mgr.ConfKeyManager
    iniset $CINDER_CONF key_manager fixed_key $(openssl rand -hex 16)
    if [[ -n "$CINDER_ALLOWED_DIRECT_URL_SCHEMES" ]]; then
        iniset $CINDER_CONF DEFAULT allowed_direct_url_schemes $CINDER_ALLOWED_DIRECT_URL_SCHEMES
    fi

    # set default quotas
    iniset $CINDER_CONF DEFAULT quota_volumes ${CINDER_QUOTA_VOLUMES:-10}
    iniset $CINDER_CONF DEFAULT quota_backups ${CINDER_QUOTA_BACKUPS:-10}
    iniset $CINDER_CONF DEFAULT quota_snapshots ${CINDER_QUOTA_SNAPSHOTS:-10}

    # Avoid RPC timeouts in slow CI and test environments by doubling the
    # default response timeout set by RPC clients. See bug #1873234 for more
    # details and example failures.
    iniset $CINDER_CONF DEFAULT rpc_response_timeout 120

    iniset $CINDER_CONF DEFAULT report_interval $CINDER_SERVICE_REPORT_INTERVAL
    iniset $CINDER_CONF DEFAULT service_down_time $(($CINDER_SERVICE_REPORT_INTERVAL * 6))

    if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
        local enabled_backends=""
        local default_name=""
        local be be_name be_type
        for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
            be_type=${be%%:*}
            be_name=${be##*:}
            if type configure_cinder_backend_${be_type} >/dev/null 2>&1; then
                configure_cinder_backend_${be_type} ${be_name}
            fi
            if [[ -z "$default_name" ]]; then
                default_name=$be_name
            fi
            enabled_backends+=$be_name,
        done
        iniset $CINDER_CONF DEFAULT enabled_backends ${enabled_backends%,*}
        if [[ -n "$default_name" ]]; then
            iniset $CINDER_CONF DEFAULT default_volume_type ${default_name}
        fi
        configure_cinder_image_volume_cache
    fi

    if is_service_enabled c-bak && [[ -n "$CINDER_BACKUP_DRIVER" ]]; then
        if type configure_cinder_backup_$CINDER_BACKUP_DRIVER >/dev/null 2>&1; then
            configure_cinder_backup_$CINDER_BACKUP_DRIVER
        else
            die "configure_cinder_backup_$CINDER_BACKUP_DRIVER doesn't exist in $CINDER_BACKUPS/$CINDER_BACKUP_DRIVER"
        fi
    fi

    if is_service_enabled ceilometer; then
        iniset $CINDER_CONF oslo_messaging_notifications driver "messagingv2"
    fi

    if is_service_enabled tls-proxy; then
        if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then
            # Set the service port for a proxy to take the original
            if [ "$CINDER_USE_MOD_WSGI" == "True" ]; then
                iniset $CINDER_CONF DEFAULT osapi_volume_listen_port $CINDER_SERVICE_PORT_INT
                iniset $CINDER_CONF oslo_middleware enable_proxy_headers_parsing True
            else
                iniset $CINDER_CONF DEFAULT osapi_volume_listen_port $CINDER_SERVICE_PORT_INT
                iniset $CINDER_CONF DEFAULT public_endpoint $CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT
                iniset $CINDER_CONF DEFAULT osapi_volume_base_URL $CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT
            fi
        fi
    fi

    if [ "$SYSLOG" != "False" ]; then
        iniset $CINDER_CONF DEFAULT use_syslog True
    fi

    iniset_rpc_backend cinder $CINDER_CONF

    # Format logging
    setup_logging $CINDER_CONF $CINDER_USE_MOD_WSGI

    if is_service_enabled c-api; then
        write_uwsgi_config "$CINDER_UWSGI_CONF" "$CINDER_UWSGI" "/volume"
    fi

    if [[ -r $CINDER_PLUGINS/$CINDER_DRIVER ]]; then
        configure_cinder_driver
    fi

    iniset $CINDER_CONF DEFAULT osapi_volume_workers "$API_WORKERS"

    iniset $CINDER_CONF DEFAULT glance_api_servers "$GLANCE_URL"
    if is_service_enabled tls-proxy; then
        iniset $CINDER_CONF DEFAULT glance_protocol https
        iniset $CINDER_CONF DEFAULT glance_ca_certificates_file $SSL_BUNDLE_FILE
    fi

    # Set nova credentials (used for os-assisted-snapshots)
    configure_keystone_authtoken_middleware $CINDER_CONF nova nova
    iniset $CINDER_CONF nova region_name "$REGION_NAME"
    iniset $CINDER_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"

    if [[ ! -z "$CINDER_COORDINATION_URL" ]]; then
        iniset $CINDER_CONF coordination backend_url "$CINDER_COORDINATION_URL"
    elif is_service_enabled etcd3; then
        iniset $CINDER_CONF coordination backend_url "etcd3+http://${SERVICE_HOST}:$ETCD_PORT"
    fi

    if [[ "$CINDER_ENFORCE_SCOPE" == True || "$ENFORCE_SCOPE" == True ]] ; then
        iniset $CINDER_CONF oslo_policy enforce_scope true
        iniset $CINDER_CONF oslo_policy enforce_new_defaults true
    else
        iniset $CINDER_CONF oslo_policy enforce_scope false
        iniset $CINDER_CONF oslo_policy enforce_new_defaults false
    fi
}

# create_cinder_accounts() - Set up common required cinder accounts

# Project              User       Roles
# ------------------------------------------------------------------
# SERVICE_PROJECT_NAME cinder     service
# SERVICE_PROJECT_NAME cinder     creator (if Barbican is enabled)

# Migrated from keystone_data.sh
function create_cinder_accounts {
    # Cinder
    if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then

        local extra_role=""

        # cinder needs the "creator" role in order to interact with barbican
        if is_service_enabled barbican; then
            extra_role=$(get_or_create_role "creator")
        fi

        create_service_user "cinder" $extra_role

        # block-storage is the official service type
        get_or_create_service "cinder" "block-storage" "Cinder Volume Service"
        if [ "$CINDER_USE_MOD_WSGI" == "False" ]; then
            get_or_create_endpoint \
                "block-storage" \
                "$REGION_NAME" \
                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/\$(project_id)s"

            get_or_create_service "cinderv3" "volumev3" "Cinder Volume Service V3"
            get_or_create_endpoint \
                "volumev3" \
                "$REGION_NAME" \
                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/\$(project_id)s"
        else
            get_or_create_endpoint \
                "block-storage" \
                "$REGION_NAME" \
                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST/volume/v3/\$(project_id)s"

            get_or_create_service "cinderv3" "volumev3" "Cinder Volume Service V3"
            get_or_create_endpoint \
                "volumev3" \
                "$REGION_NAME" \
                "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST/volume/v3/\$(project_id)s"
        fi

        configure_cinder_internal_tenant
    fi
}

# init_cinder() - Initialize database and volume group
function init_cinder {
    if is_service_enabled $DATABASE_BACKENDS; then
        # (Re)create cinder database
        recreate_database cinder

        time_start "dbsync"
        # Migrate cinder database
        $CINDER_BIN_DIR/cinder-manage --config-file $CINDER_CONF db sync
        time_stop "dbsync"
    fi

    if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
        local be be_name be_type
        for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
            be_type=${be%%:*}
            be_name=${be##*:}
            if type init_cinder_backend_${be_type} >/dev/null 2>&1; then
                init_cinder_backend_${be_type} ${be_name}
            fi
        done
    fi

    if is_service_enabled c-bak && [[ -n "$CINDER_BACKUP_DRIVER" ]]; then
        if type init_cinder_backup_$CINDER_BACKUP_DRIVER >/dev/null 2>&1; then
            init_cinder_backup_$CINDER_BACKUP_DRIVER
        fi
    fi

    mkdir -p $CINDER_STATE_PATH/volumes
}

# install_cinder() - Collect source and prepare
function install_cinder {
    git_clone $CINDER_REPO $CINDER_DIR $CINDER_BRANCH
    setup_develop $CINDER_DIR
    if [[ "$CINDER_TARGET_HELPER" == "tgtadm" ]]; then
        install_package tgt
    elif [[ "$CINDER_TARGET_HELPER" == "lioadm" ]]; then
        if is_ubuntu; then
            # TODO(frickler): Workaround for https://launchpad.net/bugs/1819819
            sudo mkdir -p /etc/target

            install_package targetcli-fb
        else
            install_package targetcli
        fi
    elif [[ "$CINDER_TARGET_HELPER" == "nvmet" ]]; then
        install_package nvme-cli

        # TODO: Remove manual installation of the dependency when the
        # requirement is added to nvmetcli:
        # http://lists.infradead.org/pipermail/linux-nvme/2022-July/033576.html
        if is_ubuntu; then
            install_package python3-configshell-fb
        else
            install_package python3-configshell
        fi
        # Install from source because Ubuntu doesn't have the package and some packaged versions didn't work on Python 3
        pip_install git+git://git.infradead.org/users/hch/nvmetcli.git

        sudo modprobe nvmet
        sudo modprobe nvme-fabrics

        if [[ $CINDER_TARGET_PROTOCOL == 'nvmet_rdma' ]]; then
            install_package rdma-core
            sudo modprobe nvme-rdma

            # Create the Soft-RoCE device over the networking interface
            local iface=${HOST_IP_IFACE:-`ip -br -$SERVICE_IP_VERSION a | grep $CINDER_MY_IP | awk '{print $1}'`}
            if [[ -z "$iface" ]]; then
                die $LINENO "Cannot find interface to bind Soft-RoCE"
            fi

            if ! sudo rdma link | grep $iface ; then
                sudo rdma link add rxe_$iface type rxe netdev $iface
            fi

        elif [[ $CINDER_TARGET_PROTOCOL == 'nvmet_tcp' ]]; then
            sudo modprobe nvme-tcp

        else  # 'nvmet_fc'
            sudo modprobe nvme-fc
        fi
    fi
}

# install_cinderclient() - Collect source and prepare
function install_cinderclient {
    if use_library_from_git "python-brick-cinderclient-ext"; then
        git_clone_by_name "python-brick-cinderclient-ext"
        setup_dev_lib "python-brick-cinderclient-ext"
    fi

    if use_library_from_git "python-cinderclient"; then
        git_clone_by_name "python-cinderclient"
        setup_dev_lib "python-cinderclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-cinderclient"]}/tools/,/etc/bash_completion.d/}cinder.bash_completion
    fi
}

# apply config.d approach for cinder volumes directory
function _configure_tgt_for_config_d {
    if [[ ! -d /etc/tgt/stack.d/ ]]; then
        sudo ln -sf $CINDER_STATE_PATH/volumes /etc/tgt/stack.d
    fi
    if ! grep -q "include /etc/tgt/stack.d/*" /etc/tgt/targets.conf; then
        echo "include /etc/tgt/stack.d/*" | sudo tee -a /etc/tgt/targets.conf
    fi
}

# start_cinder() - Start running processes
function start_cinder {
    local service_port=$CINDER_SERVICE_PORT
    local service_protocol=$CINDER_SERVICE_PROTOCOL
    local cinder_url
    if is_service_enabled tls-proxy && [ "$CINDER_USE_MOD_WSGI" == "False" ]; then
        service_port=$CINDER_SERVICE_PORT_INT
        service_protocol="http"
    fi
    if [ "$CINDER_TARGET_HELPER" = "tgtadm" ]; then
        if is_service_enabled c-vol; then
            # Delete any old stack.conf
            sudo rm -f /etc/tgt/conf.d/stack.conf
            _configure_tgt_for_config_d
            if is_ubuntu; then
                sudo service tgt restart
            else
                restart_service tgtd
            fi
            # NOTE(gfidente): ensure tgtd is running in debug mode
            sudo tgtadm --mode system --op update --name debug --value on
        fi
    fi

    if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then
        if [ "$CINDER_USE_MOD_WSGI" == "False" ]; then
            run_process c-api "$CINDER_BIN_DIR/cinder-api --config-file $CINDER_CONF"
            cinder_url=$service_protocol://$SERVICE_HOST:$service_port
            # Start proxy if tls enabled
            if is_service_enabled tls-proxy; then
                start_tls_proxy cinder '*' $CINDER_SERVICE_PORT $CINDER_SERVICE_HOST $CINDER_SERVICE_PORT_INT
            fi
        else
            run_process "c-api" "$(which uwsgi) --procname-prefix cinder-api --ini $CINDER_UWSGI_CONF"
            cinder_url=$service_protocol://$SERVICE_HOST/volume/v3
        fi
    fi

    echo "Waiting for Cinder API to start..."
    if ! wait_for_service $SERVICE_TIMEOUT $cinder_url; then
        die $LINENO "c-api did not start"
    fi

    run_process c-sch "$CINDER_BIN_DIR/cinder-scheduler --config-file $CINDER_CONF"
    # Tune glibc for Python Services using single malloc arena for all threads
    # and disabling dynamic thresholds to reduce memory usage when using native
    # threads directly or via eventlet.tpool
    # https://www.gnu.org/software/libc/manual/html_node/Memory-Allocation-Tunables.html
    malloc_tuning="MALLOC_ARENA_MAX=1 MALLOC_MMAP_THRESHOLD_=131072 MALLOC_TRIM_THRESHOLD_=262144"
    run_process c-bak "$CINDER_BIN_DIR/cinder-backup --config-file $CINDER_CONF" "" "" "$malloc_tuning"
    run_process c-vol "$CINDER_BIN_DIR/cinder-volume --config-file $CINDER_CONF" "" "" "$malloc_tuning"

    # NOTE(jdg): For cinder, startup order matters.  To ensure that repor_capabilities is received
    # by the scheduler start the cinder-volume service last (or restart it) after the scheduler
    # has started.  This is a quick fix for lp bug/1189595
}

# stop_cinder() - Stop running processes
function stop_cinder {
    stop_process c-api
    stop_process c-bak
    stop_process c-sch
    stop_process c-vol
}

function create_one_type {
    type_name=$1
    property_key=$2
    property_value=$3
    # NOTE (e0ne): openstack client doesn't work with cinder in noauth mode
    if is_service_enabled keystone; then
        openstack --os-region-name="$REGION_NAME" volume type create --property $property_key="$property_value" $type_name
    else
        # TODO (e0ne): use openstack client once it will support cinder in noauth mode:
        # https://bugs.launchpad.net/python-cinderclient/+bug/1755279
        local cinder_url
        cinder_url=$CINDER_SERVICE_PROTOCOL://$SERVICE_HOST:$CINDER_SERVICE_PORT/v3
        OS_USER_ID=$OS_USERNAME OS_PROJECT_ID=$OS_PROJECT_NAME cinder --os-auth-type noauth --os-endpoint=$cinder_url type-create $type_name
        OS_USER_ID=$OS_USERNAME OS_PROJECT_ID=$OS_PROJECT_NAME cinder --os-auth-type noauth --os-endpoint=$cinder_url type-key $type_name set $property_key="$property_value"
    fi
}

# create_volume_types() - Create Cinder's configured volume types
function create_volume_types {
    # Create volume types
    if is_service_enabled c-api && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
        local be be_name
        for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
            be_name=${be##*:}
            create_one_type $be_name "volume_backend_name" $be_name
        done

        if [[ $ENABLE_VOLUME_MULTIATTACH == "True" ]]; then
            create_one_type $VOLUME_TYPE_MULTIATTACH $VOLUME_TYPE_MULTIATTACH "<is> True"
        fi

        # Increase quota for the service project if glance is using cinder,
        # since it's likely to occasionally go above the default 10 in parallel
        # test execution.
        if [[ "$USE_CINDER_FOR_GLANCE" == "True" ]]; then
            openstack --os-region-name="$REGION_NAME" \
                      quota set --volumes 50 "$SERVICE_PROJECT_NAME"
        fi
    fi
}

# Compatibility for Grenade

function create_cinder_volume_group {
    # During a transition period Grenade needs to have this function defined
    # It is effectively a no-op in the Grenade 'target' use case
    :
}

function configure_cinder_internal_tenant {
    # Re-use the Cinder service account for simplicity.
    iniset $CINDER_CONF DEFAULT cinder_internal_tenant_project_id $(get_or_create_project $SERVICE_PROJECT_NAME)
    iniset $CINDER_CONF DEFAULT cinder_internal_tenant_user_id $(get_or_create_user "cinder")
}

function configure_cinder_image_volume_cache {
    # Expect CINDER_CACHE_ENABLED_FOR_BACKENDS to be a list of backends
    # similar to CINDER_ENABLED_BACKENDS with NAME:TYPE where NAME will
    # be the backend specific configuration stanza in cinder.conf.
    for be in ${CINDER_CACHE_ENABLED_FOR_BACKENDS//,/ }; do
        local be_name=${be##*:}

        iniset $CINDER_CONF $be_name image_volume_cache_enabled $CINDER_IMG_CACHE_ENABLED

        if [[ -n $CINDER_IMG_CACHE_SIZE_GB ]]; then
            iniset $CINDER_CONF $be_name image_volume_cache_max_size_gb $CINDER_IMG_CACHE_SIZE_GB
        fi

        if [[ -n $CINDER_IMG_CACHE_SIZE_COUNT ]]; then
            iniset $CINDER_CONF $be_name image_volume_cache_max_count $CINDER_IMG_CACHE_SIZE_COUNT
        fi
    done
}


# Restore xtrace
$_XTRACE_CINDER

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
