#!/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}

# 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_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
GLANCE_V1_ENABLED=${GLANCE_V1_ENABLED:-False}

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`

    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

    # NOTE(flaper87): To uncomment as soon as all services consuming Glance are
    # able to consume V2 entirely.
    if [ "$GLANCE_V1_ENABLED" != "True" ]; then
        iniset $GLANCE_API_CONF DEFAULT enable_v1_api False
    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 [[ "$WSGI_MODE" == "uwsgi" ]]; then
        write_local_uwsgi_http_config "$GLANCE_UWSGI_CONF" "$GLANCE_UWSGI" "/image"
    else
        iniset $GLANCE_API_CONF DEFAULT bind_host $GLANCE_SERVICE_LISTEN_ADDRESS
        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 [[ "$WSGI_MODE" == "uwsgi" ]]; 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:
