#!/bin/bash
#
# lib/glance
# Functions to control the configuration and operation of the **Glance** service

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

# ``stack.sh`` calls the entry points in this order:
#
# - install_glance
# - configure_glance
# - init_glance
# - start_glance
# - stop_glance
# - cleanup_glance

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


# Defaults
# --------

# Set up default directories
GITDIR["python-glanceclient"]=$DEST/python-glanceclient
GITDIR["glance_store"]=$DEST/glance_store
GLANCE_DIR=$DEST/glance

# Glance virtual environment
if [[ ${USE_VENV} = True ]]; then
    PROJECT_VENV["glance"]=${GLANCE_DIR}.venv
    GLANCE_BIN_DIR=${PROJECT_VENV["glance"]}/bin
else
    GLANCE_BIN_DIR=$(get_python_exec_prefix)
fi

# Glance multi-store configuration
# Boolean flag to enable multiple store configuration for glance
GLANCE_ENABLE_MULTIPLE_STORES=$(trueorfalse False GLANCE_ENABLE_MULTIPLE_STORES)

# Comma separated list for configuring multiple file stores of glance,
# for example; GLANCE_MULTIPLE_FILE_STORES = fast,cheap,slow
GLANCE_MULTIPLE_FILE_STORES=${GLANCE_MULTIPLE_FILE_STORES:-fast}

# Default store/backend for glance, must be one of the store specified
# in GLANCE_MULTIPLE_FILE_STORES option.
GLANCE_DEFAULT_BACKEND=${GLANCE_DEFAULT_BACKEND:-fast}

GLANCE_CACHE_DIR=${GLANCE_CACHE_DIR:=$DATA_DIR/glance/cache}

# Full Glance functionality requires running in standalone mode. If we are
# not in uwsgi mode, then we are standalone, otherwise allow separate control.
if [[ "$WSGI_MODE" != "uwsgi" ]]; then
    GLANCE_STANDALONE=True
fi
GLANCE_STANDALONE=${GLANCE_STANDALONE:-True}

# File path for each store specified in GLANCE_MULTIPLE_FILE_STORES, the store
# identifier will be appended to this path at runtime. If GLANCE_MULTIPLE_FILE_STORES
# has fast,cheap specified then filepath will be generated like $DATA_DIR/glance/fast
# and $DATA_DIR/glance/cheap.
GLANCE_MULTISTORE_FILE_IMAGE_DIR=${GLANCE_MULTISTORE_FILE_IMAGE_DIR:=$DATA_DIR/glance}
GLANCE_IMAGE_DIR=${GLANCE_IMAGE_DIR:=$DATA_DIR/glance/images}
GLANCE_LOCK_DIR=${GLANCE_LOCK_DIR:=$DATA_DIR/glance/locks}
GLANCE_STAGING_DIR=${GLANCE_MULTISTORE_FILE_IMAGE_DIR:=$DATA_DIR/os_glance_staging_store}
GLANCE_TASKS_DIR=${GLANCE_MULTISTORE_FILE_IMAGE_DIR:=$DATA_DIR/os_glance_tasks_store}

GLANCE_USE_IMPORT_WORKFLOW=$(trueorfalse False GLANCE_USE_IMPORT_WORKFLOW)

GLANCE_CONF_DIR=${GLANCE_CONF_DIR:-/etc/glance}
GLANCE_METADEF_DIR=$GLANCE_CONF_DIR/metadefs
GLANCE_API_CONF=$GLANCE_CONF_DIR/glance-api.conf
GLANCE_API_PASTE_INI=$GLANCE_CONF_DIR/glance-api-paste.ini
GLANCE_CACHE_CONF=$GLANCE_CONF_DIR/glance-cache.conf
GLANCE_SCHEMA_JSON=$GLANCE_CONF_DIR/schema-image.json
GLANCE_SWIFT_STORE_CONF=$GLANCE_CONF_DIR/glance-swift-store.conf
GLANCE_IMAGE_IMPORT_CONF=$GLANCE_CONF_DIR/glance-image-import.conf

if is_service_enabled tls-proxy; then
    GLANCE_SERVICE_PROTOCOL="https"
fi

# Glance connection info.  Note the port must be specified.
GLANCE_SERVICE_HOST=${GLANCE_SERVICE_HOST:-$SERVICE_HOST}
GLANCE_SERVICE_LISTEN_ADDRESS=${GLANCE_SERVICE_LISTEN_ADDRESS:-$(ipv6_unquote $SERVICE_LISTEN_ADDRESS)}
GLANCE_SERVICE_PORT=${GLANCE_SERVICE_PORT:-9292}
GLANCE_SERVICE_PORT_INT=${GLANCE_SERVICE_PORT_INT:-19292}
GLANCE_HOSTPORT=${GLANCE_HOSTPORT:-$GLANCE_SERVICE_HOST:$GLANCE_SERVICE_PORT}
GLANCE_SERVICE_PROTOCOL=${GLANCE_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
GLANCE_UWSGI=$GLANCE_BIN_DIR/glance-wsgi-api
GLANCE_UWSGI_CONF=$GLANCE_CONF_DIR/glance-uwsgi.ini
# If wsgi mode is uwsgi run glance under uwsgi, else default to eventlet
# TODO(mtreinish): Remove the eventlet path here and in all the similar
# conditionals below after the Pike release
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
    GLANCE_URL="$GLANCE_SERVICE_PROTOCOL://$GLANCE_SERVICE_HOST/image"
else
    GLANCE_URL="$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT"
fi

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

# Test if any Glance services are enabled
# is_glance_enabled
function is_glance_enabled {
    [[ ,${DISABLED_SERVICES} =~ ,"glance" ]] && return 1
    [[ ,${ENABLED_SERVICES} =~ ,"g-" ]] && return 0
    return 1
}

# cleanup_glance() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_glance {
    # delete image files (glance)
    sudo rm -rf $GLANCE_CACHE_DIR $GLANCE_IMAGE_DIR

    # Cleanup multiple stores directories
    if [[ "$GLANCE_ENABLE_MULTIPLE_STORES" == "True" ]]; then
        local store file_dir
        for store in $(echo $GLANCE_MULTIPLE_FILE_STORES | tr "," "\n"); do
            file_dir="${GLANCE_MULTISTORE_FILE_IMAGE_DIR}/${store}/"
            sudo rm -rf $file_dir
        done

        # Cleanup reserved stores directories
        sudo rm -rf $GLANCE_STAGING_DIR $GLANCE_TASKS_DIR
    fi
}

# configure_glance() - Set config files, create data dirs, etc
function configure_glance {
    sudo install -d -o $STACK_USER $GLANCE_CONF_DIR $GLANCE_METADEF_DIR

    # Set non-default configuration options for the API server
    local dburl
    dburl=`database_connection_url glance`

    # Configure multiple stores
    if [[ "$GLANCE_ENABLE_MULTIPLE_STORES" == "True" ]]; then
        local store enabled_backends
        enabled_backends=""
        for store in $(echo $GLANCE_MULTIPLE_FILE_STORES | tr "," "\n"); do
            enabled_backends+="${store}:file,"
        done
        iniset $GLANCE_API_CONF DEFAULT enabled_backends ${enabled_backends::-1}
    fi

    iniset $GLANCE_API_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
    iniset $GLANCE_API_CONF database connection $dburl
    iniset $GLANCE_API_CONF DEFAULT use_syslog $SYSLOG
    iniset $GLANCE_API_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
    iniset $GLANCE_API_CONF oslo_concurrency lock_path $GLANCE_LOCK_DIR
    iniset $GLANCE_API_CONF paste_deploy flavor keystone+cachemanagement
    configure_keystone_authtoken_middleware $GLANCE_API_CONF glance
    iniset $GLANCE_API_CONF oslo_messaging_notifications driver messagingv2
    iniset_rpc_backend glance $GLANCE_API_CONF
    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
        iniset $GLANCE_API_CONF DEFAULT container_formats "ami,ari,aki,bare,ovf,tgz"
        iniset $GLANCE_API_CONF DEFAULT disk_formats "ami,ari,aki,vhd,raw,iso"
    fi
    if [ "$VIRT_DRIVER" = 'libvirt' ] && [ "$LIBVIRT_TYPE" = 'parallels' ]; then
        iniset $GLANCE_API_CONF DEFAULT disk_formats "ami,ari,aki,vhd,vmdk,raw,qcow2,vdi,iso,ploop"
    fi

    # Glance multiple store Store specific configs
    if [[ "$GLANCE_ENABLE_MULTIPLE_STORES" == "True" ]]; then
        iniset $GLANCE_API_CONF glance_store default_backend $GLANCE_DEFAULT_BACKEND
        local store
        for store in $(echo $GLANCE_MULTIPLE_FILE_STORES | tr "," "\n"); do
            iniset $GLANCE_API_CONF $store filesystem_store_datadir "${GLANCE_MULTISTORE_FILE_IMAGE_DIR}/${store}/"
        done

        # Glance configure reserved stores
        iniset $GLANCE_API_CONF os_glance_staging_store filesystem_store_datadir "${GLANCE_MULTISTORE_FILE_IMAGE_DIR}/os_glance_staging_store/"
        iniset $GLANCE_API_CONF os_glance_tasks_store filesystem_store_datadir "${GLANCE_MULTISTORE_FILE_IMAGE_DIR}/os_glance_tasks_store/"
    else
        # Store specific configs
        iniset $GLANCE_API_CONF glance_store filesystem_store_datadir $GLANCE_IMAGE_DIR/
    fi

    # CORS feature support - to allow calls from Horizon by default
    if [ -n "$GLANCE_CORS_ALLOWED_ORIGIN" ]; then
        iniset $GLANCE_API_CONF cors allowed_origin "$GLANCE_CORS_ALLOWED_ORIGIN"
    else
        iniset $GLANCE_API_CONF cors allowed_origin "http://$SERVICE_HOST"
    fi

    # No multiple stores for swift yet
    # Store the images in swift if enabled.
    if is_service_enabled s-proxy; then
        iniset $GLANCE_API_CONF glance_store default_store swift
        iniset $GLANCE_API_CONF glance_store swift_store_create_container_on_put True

        iniset $GLANCE_API_CONF glance_store swift_store_config_file $GLANCE_SWIFT_STORE_CONF
        iniset $GLANCE_API_CONF glance_store default_swift_reference ref1
        iniset $GLANCE_API_CONF glance_store stores "file, http, swift"
        if is_service_enabled tls-proxy; then
            iniset $GLANCE_API_CONF glance_store swift_store_cacert $SSL_BUNDLE_FILE
        fi
        iniset $GLANCE_API_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"

        iniset $GLANCE_SWIFT_STORE_CONF ref1 user $SERVICE_PROJECT_NAME:glance-swift

        iniset $GLANCE_SWIFT_STORE_CONF ref1 key $SERVICE_PASSWORD
        iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address $KEYSTONE_SERVICE_URI/v3
        iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_version 3
    fi

    # We need to tell glance what it's public endpoint is so that the version
    # discovery document will be correct
    iniset $GLANCE_API_CONF DEFAULT public_endpoint $GLANCE_URL

    if is_service_enabled tls-proxy; then
        iniset $GLANCE_API_CONF DEFAULT bind_port $GLANCE_SERVICE_PORT_INT
        iniset $GLANCE_API_CONF keystone_authtoken identity_uri $KEYSTONE_SERVICE_URI
    fi

    # Format logging
    setup_logging $GLANCE_API_CONF

    cp -p $GLANCE_DIR/etc/glance-api-paste.ini $GLANCE_API_PASTE_INI

    # Set non-default configuration options for the glance-cache
    iniset $GLANCE_CACHE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
    iniset $GLANCE_CACHE_CONF DEFAULT use_syslog $SYSLOG
    iniset $GLANCE_CACHE_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
    iniset $GLANCE_CACHE_CONF DEFAULT auth_url $KEYSTONE_SERVICE_URI
    iniset $GLANCE_CACHE_CONF DEFAULT admin_tenant_name $SERVICE_PROJECT_NAME
    iniset $GLANCE_CACHE_CONF DEFAULT admin_user glance
    iniset $GLANCE_CACHE_CONF DEFAULT admin_password $SERVICE_PASSWORD

    # Store specific confs
    iniset $GLANCE_CACHE_CONF glance_store filesystem_store_datadir $GLANCE_IMAGE_DIR/

    # Set default configuration options for the glance-image-import
    iniset $GLANCE_IMAGE_IMPORT_CONF image_import_opts image_import_plugins []
    iniset $GLANCE_IMAGE_IMPORT_CONF inject_metadata_properties ignore_user_roles admin
    iniset $GLANCE_IMAGE_IMPORT_CONF inject_metadata_properties inject

    cp -p $GLANCE_DIR/etc/schema-image.json $GLANCE_SCHEMA_JSON

    cp -p $GLANCE_DIR/etc/metadefs/*.json $GLANCE_METADEF_DIR

    if is_service_enabled tls-proxy; then
        CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
        CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}

        iniset $GLANCE_API_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/%(project_id)s"
        iniset $GLANCE_CACHE_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/%(project_id)s"
    fi

    if [[ "$GLANCE_STANDALONE" == False ]]; then
        write_local_uwsgi_http_config "$GLANCE_UWSGI_CONF" "$GLANCE_UWSGI" "/image"
    else
        write_local_proxy_http_config glance "http://$GLANCE_SERVICE_HOST:$GLANCE_SERVICE_PORT_INT" "/image"
        iniset $GLANCE_API_CONF DEFAULT bind_host $GLANCE_SERVICE_LISTEN_ADDRESS
        iniset $GLANCE_API_CONF DEFAULT bind_port $GLANCE_SERVICE_PORT_INT
        iniset $GLANCE_API_CONF DEFAULT workers "$API_WORKERS"
    fi
}

# create_glance_accounts() - Set up common required glance accounts

# Project              User            Roles
# ---------------------------------------------------------------------
# SERVICE_PROJECT_NAME  glance          service
# SERVICE_PROJECT_NAME  glance-swift    ResellerAdmin (if Swift is enabled)
# SERVICE_PROJECT_NAME  glance-search   search (if Search is enabled)

function create_glance_accounts {
    if is_service_enabled g-api; then

        create_service_user "glance"

        # required for swift access
        if is_service_enabled s-proxy; then
            create_service_user "glance-swift" "ResellerAdmin"
        fi

        get_or_create_service "glance" "image" "Glance Image Service"
        get_or_create_endpoint \
            "image" \
            "$REGION_NAME" \
            "$GLANCE_URL"

        # Note(frickler): Crude workaround for https://bugs.launchpad.net/glance-store/+bug/1620999
        service_domain_id=$(get_or_create_domain $SERVICE_DOMAIN_NAME)
        iniset $GLANCE_SWIFT_STORE_CONF ref1 project_domain_id $service_domain_id
        iniset $GLANCE_SWIFT_STORE_CONF ref1 user_domain_id $service_domain_id
    fi
}

# init_glance() - Initialize databases, etc.
function init_glance {
    # Delete existing images
    rm -rf $GLANCE_IMAGE_DIR
    mkdir -p $GLANCE_IMAGE_DIR

    # (Re)create glance database
    recreate_database glance

    time_start "dbsync"
    # Migrate glance database
    $GLANCE_BIN_DIR/glance-manage --config-file $GLANCE_CONF_DIR/glance-api.conf db_sync

    # Load metadata definitions
    $GLANCE_BIN_DIR/glance-manage --config-file $GLANCE_CONF_DIR/glance-api.conf db_load_metadefs
    time_stop "dbsync"
}

# install_glanceclient() - Collect source and prepare
function install_glanceclient {
    if use_library_from_git "python-glanceclient"; then
        git_clone_by_name "python-glanceclient"
        setup_dev_lib "python-glanceclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-glanceclient"]}/tools/,/etc/bash_completion.d/}glance.bash_completion
    fi
}

# install_glance() - Collect source and prepare
function install_glance {
    local glance_store_extras=()

    if is_service_enabled cinder; then
        glance_store_extras=("cinder" "${glance_store_extras[@]}")
    fi

    if is_service_enabled swift; then
        glance_store_extras=("swift" "${glance_store_extras[@]}")
    fi

    # Install glance_store from git so we make sure we're testing
    # the latest code.
    if use_library_from_git "glance_store"; then
        git_clone_by_name "glance_store"
        setup_dev_lib "glance_store" $(join_extras "${glance_store_extras[@]}")
    else
        # we still need to pass extras
        pip_install_gr_extras glance-store $(join_extras "${glance_store_extras[@]}")
    fi

    git_clone $GLANCE_REPO $GLANCE_DIR $GLANCE_BRANCH

    setup_develop $GLANCE_DIR
}

# start_glance() - Start running processes
function start_glance {
    local service_protocol=$GLANCE_SERVICE_PROTOCOL
    if is_service_enabled tls-proxy; then
        if [[ "$WSGI_MODE" != "uwsgi" ]]; then
            start_tls_proxy glance-service '*' $GLANCE_SERVICE_PORT $GLANCE_SERVICE_HOST $GLANCE_SERVICE_PORT_INT
        fi
    fi

    if [[ "$GLANCE_STANDALONE" == False ]]; then
        run_process g-api "$(which uwsgi) --procname-prefix glance-api --ini $GLANCE_UWSGI_CONF"
    else
        run_process g-api "$GLANCE_BIN_DIR/glance-api --config-dir=$GLANCE_CONF_DIR"
    fi

    echo "Waiting for g-api ($GLANCE_SERVICE_HOST) to start..."
    if ! wait_for_service $SERVICE_TIMEOUT $GLANCE_URL; then
        die $LINENO "g-api did not start"
    fi
}

# stop_glance() - Stop running processes
function stop_glance {
    stop_process g-api
}

# Restore xtrace
$_XTRACE_GLANCE

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