# 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=$(set +o | grep xtrace)
set +o xtrace


# Defaults
# --------

# Set up default directories
GLANCE_DIR=$DEST/glance
GLANCE_STORE_DIR=$DEST/glance_store
GLANCECLIENT_DIR=$DEST/python-glanceclient
GLANCE_CACHE_DIR=${GLANCE_CACHE_DIR:=$DATA_DIR/glance/cache}
GLANCE_IMAGE_DIR=${GLANCE_IMAGE_DIR:=$DATA_DIR/glance/images}
GLANCE_AUTH_CACHE_DIR=${GLANCE_AUTH_CACHE_DIR:-/var/cache/glance}

GLANCE_CONF_DIR=${GLANCE_CONF_DIR:-/etc/glance}
GLANCE_METADEF_DIR=$GLANCE_CONF_DIR/metadefs
GLANCE_REGISTRY_CONF=$GLANCE_CONF_DIR/glance-registry.conf
GLANCE_API_CONF=$GLANCE_CONF_DIR/glance-api.conf
GLANCE_REGISTRY_PASTE_INI=$GLANCE_CONF_DIR/glance-registry-paste.ini
GLANCE_API_PASTE_INI=$GLANCE_CONF_DIR/glance-api-paste.ini
GLANCE_CACHE_CONF=$GLANCE_CONF_DIR/glance-cache.conf
GLANCE_POLICY_JSON=$GLANCE_CONF_DIR/policy.json
GLANCE_SCHEMA_JSON=$GLANCE_CONF_DIR/schema-image.json

# Support entry points installation of console scripts
if [[ -d $GLANCE_DIR/bin ]]; then
    GLANCE_BIN_DIR=$GLANCE_DIR/bin
else
    GLANCE_BIN_DIR=$(get_python_exec_prefix)
fi

if is_ssl_enabled_service "glance" || 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_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_REGISTRY_PORT=${GLANCE_REGISTRY_PORT:-9191}
GLANCE_REGISTRY_PORT_INT=${GLANCE_REGISTRY_PORT_INT:-19191}

# Tell Tempest this project is present
TEMPEST_SERVICES+=,glance


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

# Test if any Glance services are enabled
# is_glance_enabled
function is_glance_enabled {
    [[ ,${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 {
    # kill instances (nova)
    # delete image files (glance)
    sudo rm -rf $GLANCE_CACHE_DIR $GLANCE_IMAGE_DIR $GLANCE_AUTH_CACHE_DIR
}

# configure_glance() - Set config files, create data dirs, etc
function configure_glance {
    if [[ ! -d $GLANCE_CONF_DIR ]]; then
        sudo mkdir -p $GLANCE_CONF_DIR
    fi
    sudo chown $STACK_USER $GLANCE_CONF_DIR

    if [[ ! -d $GLANCE_METADEF_DIR ]]; then
        sudo mkdir -p $GLANCE_METADEF_DIR
    fi
    sudo chown $STACK_USER $GLANCE_METADEF_DIR

    # Copy over our glance configurations and update them
    cp $GLANCE_DIR/etc/glance-registry.conf $GLANCE_REGISTRY_CONF
    iniset $GLANCE_REGISTRY_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
    inicomment $GLANCE_REGISTRY_CONF DEFAULT log_file
    local dburl=`database_connection_url glance`
    iniset $GLANCE_REGISTRY_CONF DEFAULT sql_connection $dburl
    iniset $GLANCE_REGISTRY_CONF DEFAULT use_syslog $SYSLOG
    iniset $GLANCE_REGISTRY_CONF paste_deploy flavor keystone
    configure_auth_token_middleware $GLANCE_REGISTRY_CONF glance $GLANCE_AUTH_CACHE_DIR/registry
    if is_service_enabled qpid || [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; then
        iniset $GLANCE_REGISTRY_CONF DEFAULT notification_driver messaging
    fi
    iniset_rpc_backend glance $GLANCE_REGISTRY_CONF DEFAULT

    cp $GLANCE_DIR/etc/glance-api.conf $GLANCE_API_CONF
    iniset $GLANCE_API_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
    inicomment $GLANCE_API_CONF DEFAULT log_file
    iniset $GLANCE_API_CONF DEFAULT sql_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 paste_deploy flavor keystone+cachemanagement
    configure_auth_token_middleware $GLANCE_API_CONF glance $GLANCE_AUTH_CACHE_DIR/api
    if is_service_enabled qpid || [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; then
        iniset $GLANCE_API_CONF DEFAULT notification_driver messaging
    fi
    iniset_rpc_backend glance $GLANCE_API_CONF DEFAULT
    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

    # Store specific configs
    iniset $GLANCE_API_CONF DEFAULT filesystem_store_datadir $GLANCE_IMAGE_DIR/

    # NOTE(flaper87): Until Glance is fully migrated, set these configs in both
    # sections.
    iniset $GLANCE_API_CONF glance_store filesystem_store_datadir $GLANCE_IMAGE_DIR/

    iniset $GLANCE_API_CONF DEFAULT workers "$API_WORKERS"

    # Store the images in swift if enabled.
    if is_service_enabled s-proxy; then
        iniset $GLANCE_API_CONF DEFAULT default_store swift
        iniset $GLANCE_API_CONF DEFAULT swift_store_auth_address $KEYSTONE_SERVICE_URI/v2.0/
        iniset $GLANCE_API_CONF DEFAULT swift_store_user $SERVICE_TENANT_NAME:glance-swift
        iniset $GLANCE_API_CONF DEFAULT swift_store_key $SERVICE_PASSWORD
        iniset $GLANCE_API_CONF DEFAULT swift_store_create_container_on_put True

        iniset $GLANCE_API_CONF DEFAULT known_stores "glance.store.filesystem.Store, glance.store.http.Store, glance.store.swift.Store"

        # NOTE(flaper87): Until Glance is fully migrated, set these configs in both
        # sections.
        iniset $GLANCE_API_CONF glance_store default_store swift
        iniset $GLANCE_API_CONF glance_store swift_store_auth_address $KEYSTONE_SERVICE_URI/v2.0/
        iniset $GLANCE_API_CONF glance_store swift_store_user $SERVICE_TENANT_NAME:glance-swift
        iniset $GLANCE_API_CONF glance_store swift_store_key $SERVICE_PASSWORD
        iniset $GLANCE_API_CONF glance_store swift_store_create_container_on_put True
        iniset $GLANCE_API_CONF glance_store stores "file, http, swift"
    fi

    if is_service_enabled tls-proxy; then
        iniset $GLANCE_API_CONF DEFAULT bind_port $GLANCE_SERVICE_PORT_INT
        iniset $GLANCE_REGISTRY_CONF DEFAULT bind_port $GLANCE_REGISTRY_PORT_INT
    fi

    # Register SSL certificates if provided
    if is_ssl_enabled_service glance; then
        ensure_certificates GLANCE

        iniset $GLANCE_API_CONF DEFAULT cert_file "$GLANCE_SSL_CERT"
        iniset $GLANCE_API_CONF DEFAULT key_file "$GLANCE_SSL_KEY"

        iniset $GLANCE_REGISTRY_CONF DEFAULT cert_file "$GLANCE_SSL_CERT"
        iniset $GLANCE_REGISTRY_CONF DEFAULT key_file "$GLANCE_SSL_KEY"
    fi

    if is_ssl_enabled_service glance || is_service_enabled tls-proxy; then
        iniset $GLANCE_API_CONF DEFAULT registry_client_protocol https
    fi

    cp -p $GLANCE_DIR/etc/glance-registry-paste.ini $GLANCE_REGISTRY_PASTE_INI

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

    cp $GLANCE_DIR/etc/glance-cache.conf $GLANCE_CACHE_CONF
    iniset $GLANCE_CACHE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
    inicomment $GLANCE_CACHE_CONF DEFAULT log_file
    iniset $GLANCE_CACHE_CONF DEFAULT use_syslog $SYSLOG
    iniset $GLANCE_CACHE_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
    iniuncomment $GLANCE_CACHE_CONF DEFAULT auth_url
    iniset $GLANCE_CACHE_CONF DEFAULT auth_url $KEYSTONE_AUTH_URI/v2.0
    iniuncomment $GLANCE_CACHE_CONF DEFAULT auth_tenant_name
    iniset $GLANCE_CACHE_CONF DEFAULT admin_tenant_name $SERVICE_TENANT_NAME
    iniuncomment $GLANCE_CACHE_CONF DEFAULT auth_user
    iniset $GLANCE_CACHE_CONF DEFAULT admin_user glance
    iniuncomment $GLANCE_CACHE_CONF DEFAULT auth_password
    iniset $GLANCE_CACHE_CONF DEFAULT admin_password $SERVICE_PASSWORD

    # Store specific confs
    # NOTE(flaper87): Until Glance is fully migrated, set these configs in both
    # sections.
    iniset $GLANCE_CACHE_CONF DEFAULT filesystem_store_datadir $GLANCE_IMAGE_DIR/
    iniset $GLANCE_CACHE_CONF glance_store filesystem_store_datadir $GLANCE_IMAGE_DIR/

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

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

    if is_ssl_enabled_service "cinder" || 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/v1/%(project_id)s"
        iniset $GLANCE_CACHE_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/%(project_id)s"
    fi
}

# create_glance_accounts() - Set up common required glance accounts

# Project              User         Roles
# ------------------------------------------------------------------
# SERVICE_TENANT_NAME  glance       service
# SERVICE_TENANT_NAME  glance-swift ResellerAdmin (if Swift is enabled)

function create_glance_accounts {
    if is_service_enabled g-api; then

        local glance_user=$(get_or_create_user "glance" \
            "$SERVICE_PASSWORD" $SERVICE_TENANT_NAME)
        get_or_add_user_role service $glance_user $SERVICE_TENANT_NAME

        # required for swift access
        if is_service_enabled s-proxy; then

            local glance_swift_user=$(get_or_create_user "glance-swift" \
                "$SERVICE_PASSWORD" $SERVICE_TENANT_NAME "glance-swift@example.com")
            get_or_add_user_role "ResellerAdmin" $glance_swift_user $SERVICE_TENANT_NAME
        fi

        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then

            local glance_service=$(get_or_create_service "glance" \
                "image" "Glance Image Service")
            get_or_create_endpoint $glance_service \
                "$REGION_NAME" \
                "$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT" \
                "$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT" \
                "$GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT"
        fi
    fi
}

# create_glance_cache_dir() - Part of the init_glance() process
function create_glance_cache_dir {
    # Create cache dir
    sudo mkdir -p $GLANCE_AUTH_CACHE_DIR/api
    sudo chown $STACK_USER $GLANCE_AUTH_CACHE_DIR/api
    rm -f $GLANCE_AUTH_CACHE_DIR/api/*
    sudo mkdir -p $GLANCE_AUTH_CACHE_DIR/registry
    sudo chown $STACK_USER $GLANCE_AUTH_CACHE_DIR/registry
    rm -f $GLANCE_AUTH_CACHE_DIR/registry/*
}

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

    # Delete existing cache
    rm -rf $GLANCE_CACHE_DIR
    mkdir -p $GLANCE_CACHE_DIR

    # (Re)create glance database
    recreate_database glance utf8

    # Migrate glance database
    $GLANCE_BIN_DIR/glance-manage db_sync

    # Load metadata definitions
    $GLANCE_BIN_DIR/glance-manage db_load_metadefs

    create_glance_cache_dir
}

# install_glanceclient() - Collect source and prepare
function install_glanceclient {
    git_clone $GLANCECLIENT_REPO $GLANCECLIENT_DIR $GLANCECLIENT_BRANCH
    setup_develop $GLANCECLIENT_DIR
}

# install_glance() - Collect source and prepare
function install_glance {
    # Install glance_store from git so we make sure we're testing
    # the latest code.
    git_clone $GLANCE_STORE_REPO $GLANCE_STORE_DIR $GLANCE_STORE_BRANCH
    setup_develop $GLANCE_STORE_DIR

    git_clone $GLANCE_REPO $GLANCE_DIR $GLANCE_BRANCH
    setup_develop $GLANCE_DIR
}

# start_glance() - Start running processes, including screen
function start_glance {
    local service_protocol=$GLANCE_SERVICE_PROTOCOL
    if is_service_enabled tls-proxy; then
        start_tls_proxy '*' $GLANCE_SERVICE_PORT $GLANCE_SERVICE_HOST $GLANCE_SERVICE_PORT_INT &
        start_tls_proxy '*' $GLANCE_REGISTRY_PORT $GLANCE_SERVICE_HOST $GLANCE_REGISTRY_PORT_INT &
    fi

    run_process g-reg "$GLANCE_BIN_DIR/glance-registry --config-file=$GLANCE_CONF_DIR/glance-registry.conf"
    run_process g-api "$GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"

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

# stop_glance() - Stop running processes
function stop_glance {
    # Kill the Glance screen windows
    stop_process g-api
    stop_process g-reg
}


# Restore xtrace
$XTRACE

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