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

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

# ``stack.sh`` calls the entry points in this order:
#
# - install_nova
# - configure_nova
# - create_nova_conf
# - init_nova
# - start_nova
# - stop_nova
# - cleanup_nova

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

# Defaults
# --------

# Set up default directories
GITDIR["python-novaclient"]=$DEST/python-novaclient
GITDIR["os-vif"]=$DEST/os-vif
NOVA_DIR=$DEST/nova

# Nova virtual environment
if [[ ${USE_VENV} = True ]]; then
    PROJECT_VENV["nova"]=${NOVA_DIR}.venv
    NOVA_BIN_DIR=${PROJECT_VENV["nova"]}/bin
else
    NOVA_BIN_DIR=$(get_python_exec_prefix)
fi

NOVA_STATE_PATH=${NOVA_STATE_PATH:=$DATA_DIR/nova}
# INSTANCES_PATH is the previous name for this
NOVA_INSTANCES_PATH=${NOVA_INSTANCES_PATH:=${INSTANCES_PATH:=$NOVA_STATE_PATH/instances}}
NOVA_AUTH_CACHE_DIR=${NOVA_AUTH_CACHE_DIR:-/var/cache/nova}

NOVA_CONF_DIR=/etc/nova
NOVA_CONF=$NOVA_CONF_DIR/nova.conf
NOVA_COND_CONF=$NOVA_CONF_DIR/nova.conf
NOVA_CPU_CONF=$NOVA_CONF_DIR/nova-cpu.conf
NOVA_FAKE_CONF=$NOVA_CONF_DIR/nova-fake.conf
NOVA_API_DB=${NOVA_API_DB:-nova_api}
NOVA_UWSGI=$NOVA_BIN_DIR/nova-api-wsgi
NOVA_METADATA_UWSGI=$NOVA_BIN_DIR/nova-metadata-wsgi
NOVA_UWSGI_CONF=$NOVA_CONF_DIR/nova-api-uwsgi.ini
NOVA_METADATA_UWSGI_CONF=$NOVA_CONF_DIR/nova-metadata-uwsgi.ini

# The total number of cells we expect. Must be greater than one and doesn't
# count cell0.
NOVA_NUM_CELLS=${NOVA_NUM_CELLS:-1}
# Our cell index, so we know what rabbit vhost to connect to.
# This should be in the range of 1-$NOVA_NUM_CELLS
NOVA_CPU_CELL=${NOVA_CPU_CELL:-1}

NOVA_API_PASTE_INI=${NOVA_API_PASTE_INI:-$NOVA_CONF_DIR/api-paste.ini}

# Toggle for deploying Nova-API under a wsgi server. We default to
# true to use UWSGI, but allow False so that fall back to the
# eventlet server can happen for grenade runs.
# NOTE(cdent): We can adjust to remove the eventlet-base api service
# after pike, at which time we can stop using NOVA_USE_MOD_WSGI to
# mean "use uwsgi" because we'll be always using uwsgi.
NOVA_USE_MOD_WSGI=${NOVA_USE_MOD_WSGI:-True}

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

# Whether to use TLS for comms between the VNC/SPICE/serial proxy
# services and the compute node
NOVA_CONSOLE_PROXY_COMPUTE_TLS=${NOVA_CONSOLE_PROXY_COMPUTE_TLS:-False}

# Public facing bits
NOVA_SERVICE_HOST=${NOVA_SERVICE_HOST:-$SERVICE_HOST}
NOVA_SERVICE_PORT=${NOVA_SERVICE_PORT:-8774}
NOVA_SERVICE_PORT_INT=${NOVA_SERVICE_PORT_INT:-18774}
NOVA_SERVICE_PROTOCOL=${NOVA_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
NOVA_SERVICE_LOCAL_HOST=${NOVA_SERVICE_LOCAL_HOST:-$SERVICE_LOCAL_HOST}
NOVA_SERVICE_LISTEN_ADDRESS=${NOVA_SERVICE_LISTEN_ADDRESS:-$(ipv6_unquote $SERVICE_LISTEN_ADDRESS)}
METADATA_SERVICE_PORT=${METADATA_SERVICE_PORT:-8775}

# Option to enable/disable config drive
# NOTE: Set ``FORCE_CONFIG_DRIVE="False"`` to turn OFF config drive
FORCE_CONFIG_DRIVE=${FORCE_CONFIG_DRIVE:-"False"}

# Nova supports pluggable schedulers.  The default ``FilterScheduler``
# should work in most cases.
SCHEDULER=${SCHEDULER:-filter_scheduler}

# The following NOVA_FILTERS contains SameHostFilter and DifferentHostFilter with
# the default filters.
NOVA_FILTERS="RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,SameHostFilter,DifferentHostFilter"

QEMU_CONF=/etc/libvirt/qemu.conf

# Set default defaults here as some hypervisor drivers override these
PUBLIC_INTERFACE_DEFAULT=br100
# Set ``GUEST_INTERFACE_DEFAULT`` to some interface on the box so that
# the default isn't completely crazy. This will match ``eth*``, ``em*``, or
# the new ``p*`` interfaces, then basically picks the first
# alphabetically. It's probably wrong, however it's less wrong than
# always using ``eth0`` which doesn't exist on new Linux distros at all.
GUEST_INTERFACE_DEFAULT=$(ip link \
    | grep 'state UP' \
    | awk '{print $2}' \
    | sed 's/://' \
    | grep ^[ep] \
    | head -1)

# ``NOVA_VNC_ENABLED`` can be used to forcibly enable VNC configuration.
# In multi-node setups allows compute hosts to not run ``n-novnc``.
NOVA_VNC_ENABLED=$(trueorfalse False NOVA_VNC_ENABLED)

# Get hypervisor configuration
# ----------------------------

NOVA_PLUGINS=$TOP_DIR/lib/nova_plugins
if is_service_enabled nova && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
    # Load plugin
    source $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER
fi

# Other Nova configurations
# ----------------------------

# ``NOVA_USE_SERVICE_TOKEN`` is a mode where service token is passed along with
# user token while communicating to external RESP API's like Neutron, Cinder
# and Glance.
NOVA_USE_SERVICE_TOKEN=$(trueorfalse False NOVA_USE_SERVICE_TOKEN)

# ``NOVA_ALLOW_MOVE_TO_SAME_HOST`` can be set to False in multi node DevStack,
# where there are at least two nova-computes.
NOVA_ALLOW_MOVE_TO_SAME_HOST=$(trueorfalse True NOVA_ALLOW_MOVE_TO_SAME_HOST)

# Enable debugging levels for iscsid service (goes from 0-8)
ISCSID_DEBUG=$(trueorfalse False ISCSID_DEBUG)
ISCSID_DEBUG_LEVEL=${ISCSID_DEBUG_LEVEL:-4}

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

# Test if any Nova services are enabled
# is_nova_enabled
function is_nova_enabled {
    [[ ,${DISABLED_SERVICES} =~ ,"nova" ]] && return 1
    [[ ,${ENABLED_SERVICES} =~ ,"n-" ]] && return 0
    return 1
}

# is_nova_console_proxy_compute_tls_enabled() - Test if the Nova Console Proxy
# service has TLS enabled
function is_nova_console_proxy_compute_tls_enabled {
    [[ ${NOVA_CONSOLE_PROXY_COMPUTE_TLS} = "True" ]] && return 0
    return 1
}

# Helper to clean iptables rules
function clean_iptables {
    # Delete rules
    sudo iptables -S -v | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-A" |  sed "s/-A/-D/g" | awk '{print "sudo iptables",$0}' | bash
    # Delete nat rules
    sudo iptables -S -v -t nat | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" |  grep "\-A" | sed "s/-A/-D/g" | awk '{print "sudo iptables -t nat",$0}' | bash
    # Delete chains
    sudo iptables -S -v | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" | grep "\-N" |  sed "s/-N/-X/g" | awk '{print "sudo iptables",$0}' | bash
    # Delete nat chains
    sudo iptables -S -v -t nat | sed "s/-c [0-9]* [0-9]* //g" | grep "nova" |  grep "\-N" | sed "s/-N/-X/g" | awk '{print "sudo iptables -t nat",$0}' | bash
}

# cleanup_nova() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_nova {
    if is_service_enabled n-cpu; then
        # Clean iptables from previous runs
        clean_iptables

        # Destroy old instances
        local instances
        instances=`sudo virsh list --all | grep $INSTANCE_NAME_PREFIX | sed "s/.*\($INSTANCE_NAME_PREFIX[0-9a-fA-F]*\).*/\1/g"`
        if [ ! "$instances" = "" ]; then
            echo $instances | xargs -n1 sudo virsh destroy || true
            if ! xargs -n1 sudo virsh undefine --managed-save --nvram <<< $instances; then
                # Can't delete with nvram flags, then just try without this flag
                xargs -n1 sudo virsh undefine --managed-save <<< $instances
            fi
        fi

        # Logout and delete iscsi sessions
        local tgts
        tgts=$(sudo iscsiadm --mode node | grep $VOLUME_NAME_PREFIX | cut -d ' ' -f2)
        local target
        for target in $tgts; do
            sudo iscsiadm --mode node -T $target --logout || true
        done
        sudo iscsiadm --mode node --op delete || true

        # Clean out the instances directory.
        sudo rm -rf $NOVA_INSTANCES_PATH/*
    fi

    sudo rm -rf $NOVA_STATE_PATH $NOVA_AUTH_CACHE_DIR

    # NOTE(dtroyer): This really should be called from here but due to the way
    #                nova abuses the _cleanup() function we're moving it
    #                directly into cleanup.sh until this can be fixed.
    #if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
    #    cleanup_nova_hypervisor
    #fi

    stop_process "n-api"
    stop_process "n-api-meta"
    remove_uwsgi_config "$NOVA_UWSGI_CONF" "$NOVA_UWSGI"
    remove_uwsgi_config "$NOVA_METADATA_UWSGI_CONF" "$NOVA_METADATA_UWSGI"
}

# configure_nova() - Set config files, create data dirs, etc
function configure_nova {
    # Put config files in ``/etc/nova`` for everyone to find
    sudo install -d -o $STACK_USER $NOVA_CONF_DIR

    configure_rootwrap nova

    if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
        # Get the sample configuration file in place
        cp $NOVA_DIR/etc/nova/api-paste.ini $NOVA_CONF_DIR
    fi

    if is_service_enabled n-cpu; then
        # Force IP forwarding on, just on case
        sudo sysctl -w net.ipv4.ip_forward=1

        if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
            # Check for kvm (hardware based virtualization).  If unable to initialize
            # kvm, we drop back to the slower emulation mode (qemu).  Note: many systems
            # come with hardware virtualization disabled in BIOS.
            if [[ "$LIBVIRT_TYPE" == "kvm" ]]; then
                sudo modprobe kvm || true
                if [ ! -e /dev/kvm ]; then
                    echo "WARNING: Switching to QEMU"
                    LIBVIRT_TYPE=qemu
                    if which selinuxenabled >/dev/null 2>&1 && selinuxenabled; then
                        # https://bugzilla.redhat.com/show_bug.cgi?id=753589
                        sudo setsebool virt_use_execmem on
                    fi
                fi
            fi

            # Install and configure **LXC** if specified.  LXC is another approach to
            # splitting a system into many smaller parts.  LXC uses cgroups and chroot
            # to simulate multiple systems.
            if [[ "$LIBVIRT_TYPE" == "lxc" ]]; then
                if is_ubuntu; then
                    # enable nbd for lxc unless you're using an lvm backend
                    # otherwise you can't boot instances
                    if [[ "$NOVA_BACKEND" != "LVM" ]]; then
                        sudo modprobe nbd
                    fi
                fi
            fi
        fi

        # Instance Storage
        # ----------------

        # Nova stores each instance in its own directory.
        sudo install -d -o $STACK_USER $NOVA_INSTANCES_PATH

        # You can specify a different disk to be mounted and used for backing the
        # virtual machines.  If there is a partition labeled nova-instances we
        # mount it (ext filesystems can be labeled via e2label).
        if [ -L /dev/disk/by-label/nova-instances ]; then
            if ! mount -n | grep -q $NOVA_INSTANCES_PATH; then
                sudo mount -L nova-instances $NOVA_INSTANCES_PATH
                sudo chown -R $STACK_USER $NOVA_INSTANCES_PATH
            fi
        fi

        if [[ ${ISCSID_DEBUG} == "True" ]]; then
            # Install an override that starts iscsid with debugging
            # enabled.
            cat > /tmp/iscsid.override <<EOF
[Service]
ExecStart=
ExecStart=/usr/sbin/iscsid -d${ISCSID_DEBUG_LEVEL}
EOF
            sudo mkdir -p /etc/systemd/system/iscsid.service.d
            sudo mv /tmp/iscsid.override /etc/systemd/system/iscsid.service.d/override.conf
            sudo systemctl daemon-reload
        fi

        # ensure that iscsid is started, even when disabled by default
        restart_service iscsid
    fi

    # Rebuild the config file from scratch
    create_nova_conf

    if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
        # Configure hypervisor plugin
        configure_nova_hypervisor
    fi
}

# create_nova_accounts() - Set up common required nova accounts
#
# Project              User         Roles
# ------------------------------------------------------------------
# SERVICE_PROJECT_NAME  nova         admin
# SERVICE_PROJECT_NAME  nova         ResellerAdmin (if Swift is enabled)
function create_nova_accounts {

    # Nova
    if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then

        # NOTE(jamielennox): Nova doesn't need the admin role here, however neutron uses
        # this service user when notifying nova of changes and that requires the admin role.
        create_service_user "nova" "admin"

        local nova_api_url
        if [[ "$NOVA_USE_MOD_WSGI" == "False" ]]; then
            nova_api_url="$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT"
        else
            nova_api_url="$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST/compute"
        fi

        get_or_create_service "nova_legacy" "compute_legacy" "Nova Compute Service (Legacy 2.0)"
        get_or_create_endpoint \
            "compute_legacy" \
            "$REGION_NAME" \
            "$nova_api_url/v2/\$(project_id)s"

        get_or_create_service "nova" "compute" "Nova Compute Service"
        get_or_create_endpoint \
            "compute" \
            "$REGION_NAME" \
            "$nova_api_url/v2.1"
    fi

    if is_service_enabled n-api; then
        # Swift
        if is_service_enabled swift; then
            # Nova needs ResellerAdmin role to download images when accessing
            # swift through the s3 api.
            get_or_add_user_project_role ResellerAdmin nova $SERVICE_PROJECT_NAME $SERVICE_DOMAIN_NAME $SERVICE_DOMAIN_NAME
        fi
    fi

    # S3
    if is_service_enabled s3api; then
        get_or_create_service "s3" "s3" "S3"
        get_or_create_endpoint \
            "s3" \
            "$REGION_NAME" \
            "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
            "http://$SERVICE_HOST:$S3_SERVICE_PORT" \
            "http://$SERVICE_HOST:$S3_SERVICE_PORT"
    fi
}

# create_nova_conf() - Create a new nova.conf file
function create_nova_conf {
    # Remove legacy ``nova.conf``
    rm -f $NOVA_DIR/bin/nova.conf

    # (Re)create ``nova.conf``
    rm -f $NOVA_CONF
    iniset $NOVA_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
    if [ "$NOVA_ALLOW_MOVE_TO_SAME_HOST" == "True" ]; then
        iniset $NOVA_CONF DEFAULT allow_resize_to_same_host "True"
    fi
    iniset $NOVA_CONF wsgi api_paste_config "$NOVA_API_PASTE_INI"
    iniset $NOVA_CONF DEFAULT rootwrap_config "$NOVA_CONF_DIR/rootwrap.conf"
    iniset $NOVA_CONF scheduler driver "$SCHEDULER"
    iniset $NOVA_CONF filter_scheduler enabled_filters "$NOVA_FILTERS"
    if [[ $SCHEDULER == "filter_scheduler" ]]; then
        iniset $NOVA_CONF scheduler workers "$API_WORKERS"
    fi
    iniset $NOVA_CONF DEFAULT default_floating_pool "$PUBLIC_NETWORK_NAME"
    if [[ $SERVICE_IP_VERSION == 6 ]]; then
        iniset $NOVA_CONF DEFAULT my_ip "$HOST_IPV6"
        iniset $NOVA_CONF DEFAULT use_ipv6 "True"
    else
        iniset $NOVA_CONF DEFAULT my_ip "$HOST_IP"
    fi
    iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
    iniset $NOVA_CONF DEFAULT osapi_compute_listen "$NOVA_SERVICE_LISTEN_ADDRESS"
    iniset $NOVA_CONF DEFAULT metadata_listen "$NOVA_SERVICE_LISTEN_ADDRESS"

    iniset $NOVA_CONF key_manager backend nova.keymgr.conf_key_mgr.ConfKeyManager

    if is_fedora || is_suse; then
        # nova defaults to /usr/local/bin, but fedora and suse pip like to
        # install things in /usr/bin
        iniset $NOVA_CONF DEFAULT bindir "/usr/bin"
    fi

    # only setup database connections if there are services that
    # require them running on the host. The ensures that n-cpu doesn't
    # leak a need to use the db in a multinode scenario.
    if is_service_enabled n-api n-cond n-sched; then
        # If we're in multi-tier cells mode, we want our control services pointing
        # at cell0 instead of cell1 to ensure isolation. If not, we point everything
        # at the main database like normal.
        if [[ "$CELLSV2_SETUP" == "singleconductor" ]]; then
            local db="nova_cell1"
        else
            local db="nova_cell0"
            # When in superconductor mode, nova-compute can't send instance
            # info updates to the scheduler, so just disable it.
            iniset $NOVA_CONF filter_scheduler track_instance_changes False
        fi

        iniset $NOVA_CONF database connection `database_connection_url $db`
        iniset $NOVA_CONF api_database connection `database_connection_url nova_api`
    fi

    if is_service_enabled n-api; then
        if is_service_enabled n-api-meta; then
            # If running n-api-meta as a separate service
            NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/,metadata//")
        fi
        iniset $NOVA_CONF DEFAULT enabled_apis "$NOVA_ENABLED_APIS"
        if is_service_enabled tls-proxy && [ "$NOVA_USE_MOD_WSGI" == "False" ]; then
            # Set the service port for a proxy to take the original
            iniset $NOVA_CONF DEFAULT osapi_compute_listen_port "$NOVA_SERVICE_PORT_INT"
            iniset $NOVA_CONF DEFAULT osapi_compute_link_prefix $NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT
        fi

        configure_auth_token_middleware $NOVA_CONF nova $NOVA_AUTH_CACHE_DIR
    fi

    if is_service_enabled cinder; then
        if is_service_enabled tls-proxy; then
            CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
            CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
            iniset $NOVA_CONF cinder cafile $SSL_BUNDLE_FILE
        fi
    fi

    if [ -n "$NOVA_STATE_PATH" ]; then
        iniset $NOVA_CONF DEFAULT state_path "$NOVA_STATE_PATH"
        iniset $NOVA_CONF oslo_concurrency lock_path "$NOVA_STATE_PATH"
    fi
    if [ -n "$NOVA_INSTANCES_PATH" ]; then
        iniset $NOVA_CONF DEFAULT instances_path "$NOVA_INSTANCES_PATH"
    fi
    if [ "$SYSLOG" != "False" ]; then
        iniset $NOVA_CONF DEFAULT use_syslog "True"
    fi
    if [ "$FORCE_CONFIG_DRIVE" != "False" ]; then
        iniset $NOVA_CONF DEFAULT force_config_drive "$FORCE_CONFIG_DRIVE"
    fi

    # nova defaults to genisoimage but only mkisofs is available for 15.0+
    if is_suse; then
        iniset $NOVA_CONF DEFAULT mkisofs_cmd /usr/bin/mkisofs
    fi

    # Format logging
    setup_logging $NOVA_CONF

    iniset $NOVA_CONF upgrade_levels compute "auto"

    write_uwsgi_config "$NOVA_UWSGI_CONF" "$NOVA_UWSGI" "/compute"
    write_uwsgi_config "$NOVA_METADATA_UWSGI_CONF" "$NOVA_METADATA_UWSGI" "" "$SERVICE_LISTEN_ADDRESS:${METADATA_SERVICE_PORT}"

    if is_service_enabled ceilometer; then
        iniset $NOVA_CONF DEFAULT instance_usage_audit "True"
        iniset $NOVA_CONF DEFAULT instance_usage_audit_period "hour"
        iniset $NOVA_CONF DEFAULT notify_on_state_change "vm_and_task_state"
    fi

    # Set the oslo messaging driver to the typical default. This does not
    # enable notifications, but it will allow them to function when enabled.
    iniset $NOVA_CONF oslo_messaging_notifications driver "messagingv2"
    iniset $NOVA_CONF oslo_messaging_notifications transport_url $(get_notification_url)
    iniset_rpc_backend nova $NOVA_CONF

    iniset $NOVA_CONF DEFAULT osapi_compute_workers "$API_WORKERS"
    iniset $NOVA_CONF DEFAULT metadata_workers "$API_WORKERS"
    # don't let the conductor get out of control now that we're using a pure python db driver
    iniset $NOVA_CONF conductor workers "$API_WORKERS"

    iniset $NOVA_CONF cinder os_region_name "$REGION_NAME"

    if is_service_enabled tls-proxy; then
        iniset $NOVA_CONF DEFAULT glance_protocol https
        iniset $NOVA_CONF oslo_middleware enable_proxy_headers_parsing True
    fi

    iniset $NOVA_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"

    if [ "$NOVA_USE_SERVICE_TOKEN" == "True" ]; then
        init_nova_service_user_conf
    fi

    if is_service_enabled n-cond; then
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            local conf
            local vhost
            conf=$(conductor_conf $i)
            vhost="nova_cell${i}"
            # clean old conductor conf
            rm -f $conf
            iniset $conf database connection `database_connection_url nova_cell${i}`
            iniset $conf conductor workers "$API_WORKERS"
            iniset $conf DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
            # if we have a singleconductor, we don't have per host message queues.
            if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
                iniset_rpc_backend nova $conf DEFAULT
            else
                rpc_backend_add_vhost $vhost
                iniset_rpc_backend nova $conf DEFAULT $vhost
                # When running in superconductor mode, the cell conductor
                # must be configured to talk to the placement service for
                # reschedules to work.
                if is_service_enabled placement placement-client; then
                    configure_placement_nova_compute $conf
                fi
            fi
            # Format logging
            setup_logging $conf
        done
    fi

    # Console proxy configuration has to go after conductor configuration
    # because the per cell config file nova_cellN.conf is cleared out as part
    # of conductor configuration.
    if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
        configure_console_proxies
    else
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            local conf
            local offset
            conf=$(conductor_conf $i)
            offset=$((i - 1))
            configure_console_proxies $conf $offset
        done
    fi
}

# Configure access to placement from a nova service, usually
# compute, but sometimes conductor.
function configure_placement_nova_compute {
    # Use the provided config file path or default to $NOVA_CONF.
    local conf=${1:-$NOVA_CONF}
    iniset $conf placement auth_type "password"
    iniset $conf placement auth_url "$KEYSTONE_SERVICE_URI"
    iniset $conf placement username placement
    iniset $conf placement password "$SERVICE_PASSWORD"
    iniset $conf placement user_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $conf placement project_name "$SERVICE_TENANT_NAME"
    iniset $conf placement project_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $conf placement region_name "$REGION_NAME"
}

function configure_console_compute {
    # All nova-compute workers need to know the vnc configuration options
    # These settings don't hurt anything if n-xvnc and n-novnc are disabled
    if is_service_enabled n-cpu; then
        if [ "$NOVNC_FROM_PACKAGE" == "True" ]; then
            # Use the old URL when installing novnc packages.
            NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_auto.html"}
        elif vercmp ${NOVNC_BRANCH} "<" "1.0.0"; then
             # Use the old URL when installing older novnc source.
            NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_auto.html"}
        else
            # Use the new URL when building >=v1.0.0 from source.
            NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_lite.html"}
        fi
        iniset $NOVA_CPU_CONF vnc novncproxy_base_url "$NOVNCPROXY_URL"
        XVPVNCPROXY_URL=${XVPVNCPROXY_URL:-"http://$SERVICE_HOST:6081/console"}
        iniset $NOVA_CPU_CONF vnc xvpvncproxy_base_url "$XVPVNCPROXY_URL"
        SPICEHTML5PROXY_URL=${SPICEHTML5PROXY_URL:-"http://$SERVICE_HOST:6082/spice_auto.html"}
        iniset $NOVA_CPU_CONF spice html5proxy_base_url "$SPICEHTML5PROXY_URL"
    fi

    if is_service_enabled n-novnc || is_service_enabled n-xvnc || [ "$NOVA_VNC_ENABLED" != False ]; then
        # Address on which instance vncservers will listen on compute hosts.
        # For multi-host, this should be the management ip of the compute host.
        VNCSERVER_LISTEN=${VNCSERVER_LISTEN=$NOVA_SERVICE_LOCAL_HOST}
        VNCSERVER_PROXYCLIENT_ADDRESS=${VNCSERVER_PROXYCLIENT_ADDRESS=$NOVA_SERVICE_LOCAL_HOST}
        iniset $NOVA_CPU_CONF vnc server_listen "$VNCSERVER_LISTEN"
        iniset $NOVA_CPU_CONF vnc server_proxyclient_address "$VNCSERVER_PROXYCLIENT_ADDRESS"
    else
        iniset $NOVA_CPU_CONF vnc enabled false
    fi

    if is_service_enabled n-spice; then
        # Address on which instance spiceservers will listen on compute hosts.
        # For multi-host, this should be the management ip of the compute host.
        SPICESERVER_PROXYCLIENT_ADDRESS=${SPICESERVER_PROXYCLIENT_ADDRESS=$NOVA_SERVICE_LOCAL_HOST}
        SPICESERVER_LISTEN=${SPICESERVER_LISTEN=$NOVA_SERVICE_LOCAL_HOST}
        iniset $NOVA_CPU_CONF spice enabled true
        iniset $NOVA_CPU_CONF spice server_listen "$SPICESERVER_LISTEN"
        iniset $NOVA_CPU_CONF spice server_proxyclient_address "$SPICESERVER_PROXYCLIENT_ADDRESS"
    fi

    if is_service_enabled n-sproxy; then
        iniset $NOVA_CPU_CONF serial_console enabled True
    fi
}

function configure_console_proxies {
    # Use the provided config file path or default to $NOVA_CONF.
    local conf=${1:-$NOVA_CONF}
    local offset=${2:-0}
    # Stagger the offset based on the total number of possible console proxies
    # (novnc, xvpvnc, spice, serial) so that their ports will not collide if
    # all are enabled.
    offset=$((offset * 4))

    if is_service_enabled n-novnc || is_service_enabled n-xvnc || [ "$NOVA_VNC_ENABLED" != False ]; then
        iniset $conf vnc novncproxy_host "$NOVA_SERVICE_LISTEN_ADDRESS"
        iniset $conf vnc novncproxy_port $((6080 + offset))
        iniset $conf vnc xvpvncproxy_host "$NOVA_SERVICE_LISTEN_ADDRESS"
        iniset $conf vnc xvpvncproxy_port $((6081 + offset))

        if is_nova_console_proxy_compute_tls_enabled ; then
            iniset $conf vnc auth_schemes "vencrypt"
            iniset $conf vnc vencrypt_client_key "/etc/pki/nova-novnc/client-key.pem"
            iniset $conf vnc vencrypt_client_cert "/etc/pki/nova-novnc/client-cert.pem"
            iniset $conf vnc vencrypt_ca_certs "/etc/pki/nova-novnc/ca-cert.pem"

            sudo mkdir -p /etc/pki/nova-novnc
            deploy_int_CA /etc/pki/nova-novnc/ca-cert.pem
            deploy_int_cert /etc/pki/nova-novnc/client-cert.pem /etc/pki/nova-novnc/client-key.pem
            # OpenSSL 1.1.0 generates the key file with permissions: 600, by
            # default, and the deploy_int* methods use 'sudo cp' to copy the
            # files, making them owned by root:root.
            # Change ownership of everything under /etc/pki/nova-novnc to
            # $STACK_USER:$(id -g ${STACK_USER}) so that $STACK_USER can read
            # the key file.
            sudo chown -R $STACK_USER:$(id -g ${STACK_USER}) /etc/pki/nova-novnc
            # This is needed to enable TLS in the proxy itself, example log:
            # WebSocket server settings:
            #   - Listen on 0.0.0.0:6080
            #   - Flash security policy server
            #   - Web server (no directory listings). Web root: /usr/share/novnc
            #   - SSL/TLS support
            #   - proxying from 0.0.0.0:6080 to None:None
            iniset $conf DEFAULT key "/etc/pki/nova-novnc/client-key.pem"
            iniset $conf DEFAULT cert "/etc/pki/nova-novnc/client-cert.pem"
        fi
    fi

    if is_service_enabled n-spice; then
        iniset $conf spice html5proxy_host "$NOVA_SERVICE_LISTEN_ADDRESS"
        iniset $conf spice html5proxy_port $((6082 + offset))
    fi

    if is_service_enabled n-sproxy; then
        iniset $conf serial_console serialproxy_host "$NOVA_SERVICE_LISTEN_ADDRESS"
        iniset $conf serial_console serialproxy_port $((6083 + offset))
    fi
}

function init_nova_service_user_conf {
    iniset $NOVA_CONF service_user send_service_user_token True
    iniset $NOVA_CONF service_user auth_type password
    iniset $NOVA_CONF service_user auth_url "$KEYSTONE_SERVICE_URI"
    iniset $NOVA_CONF service_user username nova
    iniset $NOVA_CONF service_user password "$SERVICE_PASSWORD"
    iniset $NOVA_CONF service_user user_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $NOVA_CONF service_user project_name "$SERVICE_PROJECT_NAME"
    iniset $NOVA_CONF service_user project_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $NOVA_CONF service_user auth_strategy keystone
}

function conductor_conf {
    local cell="$1"
    echo "${NOVA_CONF_DIR}/nova_cell${cell}.conf"
}

# create_nova_cache_dir() - Part of the init_nova() process
function create_nova_cache_dir {
    # Create cache dir
    sudo install -d -o $STACK_USER $NOVA_AUTH_CACHE_DIR
    rm -f $NOVA_AUTH_CACHE_DIR/*
}

# create_nova_keys_dir() - Part of the init_nova() process
function create_nova_keys_dir {
    # Create keys dir
    sudo install -d -o $STACK_USER ${NOVA_STATE_PATH} ${NOVA_STATE_PATH}/keys
}

# init_nova() - Initialize databases, etc.
function init_nova {
    # All nova components talk to a central database.
    # Only do this step once on the API node for an entire cluster.
    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled n-api; then
        recreate_database $NOVA_API_DB
        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF api_db sync

        recreate_database nova_cell0

        # map_cell0 will create the cell mapping record in the nova_api DB so
        # this needs to come after the api_db sync happens. We also want to run
        # this before the db sync below since that will migrate both the nova
        # and nova_cell0 databases.
        $NOVA_BIN_DIR/nova-manage cell_v2 map_cell0 --database_connection `database_connection_url nova_cell0`

        # (Re)create nova databases
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            recreate_database nova_cell${i}
            $NOVA_BIN_DIR/nova-manage --config-file $(conductor_conf $i) db sync --local_cell
        done

        # Migrate nova and nova_cell0 databases.
        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF db sync

        # Run online migrations on the new databases
        # Needed for flavor conversion
        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF db online_data_migrations

        # create the cell1 cell for the main nova db where the hosts live
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF --config-file $(conductor_conf $i) cell_v2 create_cell --name "cell$i"
        done
    fi

    create_nova_cache_dir
    create_nova_keys_dir

    if [[ "$NOVA_BACKEND" == "LVM" ]]; then
        init_default_lvm_volume_group
    fi
}

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

# install_nova() - Collect source and prepare
function install_nova {

    # Install os-vif
    if use_library_from_git "os-vif"; then
        git_clone_by_name "os-vif"
        setup_dev_lib "os-vif"
    fi

    if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
        install_nova_hypervisor
    fi

    if is_service_enabled n-novnc; then
        # a websockets/html5 or flash powered VNC console for vm instances
        NOVNC_FROM_PACKAGE=$(trueorfalse False NOVNC_FROM_PACKAGE)
        if [ "$NOVNC_FROM_PACKAGE" = "True" ]; then
            NOVNC_WEB_DIR=/usr/share/novnc
            install_package novnc
        else
            NOVNC_WEB_DIR=$DEST/noVNC
            git_clone $NOVNC_REPO $NOVNC_WEB_DIR $NOVNC_BRANCH
        fi
    fi

    if is_service_enabled n-spice; then
        # a websockets/html5 or flash powered SPICE console for vm instances
        SPICE_FROM_PACKAGE=$(trueorfalse True SPICE_FROM_PACKAGE)
        if [ "$SPICE_FROM_PACKAGE" = "True" ]; then
            SPICE_WEB_DIR=/usr/share/spice-html5
            install_package spice-html5
        else
            SPICE_WEB_DIR=$DEST/spice-html5
            git_clone $SPICE_REPO $SPICE_WEB_DIR $SPICE_BRANCH
        fi
    fi

    git_clone $NOVA_REPO $NOVA_DIR $NOVA_BRANCH
    setup_develop $NOVA_DIR
    sudo install -D -m 0644 -o $STACK_USER {$NOVA_DIR/tools/,/etc/bash_completion.d/}nova-manage.bash_completion
}

# start_nova_api() - Start the API process ahead of other things
function start_nova_api {
    # Get right service port for testing
    local service_port=$NOVA_SERVICE_PORT
    local service_protocol=$NOVA_SERVICE_PROTOCOL
    local nova_url
    if is_service_enabled tls-proxy; then
        service_port=$NOVA_SERVICE_PORT_INT
        service_protocol="http"
    fi

    # Hack to set the path for rootwrap
    local old_path=$PATH
    export PATH=$NOVA_BIN_DIR:$PATH

    if [ "$NOVA_USE_MOD_WSGI" == "False" ]; then
        run_process n-api "$NOVA_BIN_DIR/nova-api"
        nova_url=$service_protocol://$SERVICE_HOST:$service_port
        # Start proxy if tsl enabled
        if is_service_enabled tls-proxy; then
            start_tls_proxy nova '*' $NOVA_SERVICE_PORT $NOVA_SERVICE_HOST $NOVA_SERVICE_PORT_INT
        fi
    else
        run_process "n-api" "$NOVA_BIN_DIR/uwsgi --procname-prefix nova-api --ini $NOVA_UWSGI_CONF"
        nova_url=$service_protocol://$SERVICE_HOST/compute/v2.1/
    fi

    echo "Waiting for nova-api to start..."
    if ! wait_for_service $SERVICE_TIMEOUT $nova_url; then
        die $LINENO "nova-api did not start"
    fi

    export PATH=$old_path
}


# start_nova_compute() - Start the compute process
function start_nova_compute {
    # Hack to set the path for rootwrap
    local old_path=$PATH
    export PATH=$NOVA_BIN_DIR:$PATH

    local compute_cell_conf=$NOVA_CONF

    cp $compute_cell_conf $NOVA_CPU_CONF

    if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
        # NOTE(danms): Grenade doesn't setup multi-cell rabbit, so
        # skip these bits and use the normal config.
        echo "Skipping multi-cell conductor fleet setup"
    else
        # "${CELLSV2_SETUP}" is "superconductor"
        # FIXME(danms): Should this be configurable?
        iniset $NOVA_CPU_CONF workarounds disable_group_policy_check_upcall True
        # Since the nova-compute service cannot reach nova-scheduler over
        # RPC, we also disable track_instance_changes.
        iniset $NOVA_CPU_CONF filter_scheduler track_instance_changes False
        iniset_rpc_backend nova $NOVA_CPU_CONF DEFAULT "nova_cell${NOVA_CPU_CELL}"
    fi

    # Make sure we nuke any database config
    inidelete $NOVA_CPU_CONF database connection
    inidelete $NOVA_CPU_CONF api_database connection

    # Console proxies were configured earlier in create_nova_conf. Now that the
    # nova-cpu.conf has been created, configure the console settings required
    # by the compute process.
    configure_console_compute

    if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
        # The group **$LIBVIRT_GROUP** is added to the current user in this script.
        # ``sg`` is used in run_process to execute nova-compute as a member of the
        # **$LIBVIRT_GROUP** group.
        run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $NOVA_CPU_CONF" $LIBVIRT_GROUP
    elif [[ "$VIRT_DRIVER" = 'lxd' ]]; then
        run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $NOVA_CPU_CONF" $LXD_GROUP
    elif [[ "$VIRT_DRIVER" = 'docker' || "$VIRT_DRIVER" = 'zun' ]]; then
        run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $NOVA_CPU_CONF" $DOCKER_GROUP
    elif [[ "$VIRT_DRIVER" = 'fake' ]]; then
        local i
        for i in `seq 1 $NUMBER_FAKE_NOVA_COMPUTE`; do
            # Avoid process redirection of fake host configurations by
            # creating or modifying real configurations. Each fake
            # gets its own configuration and own log file.
            local fake_conf="${NOVA_FAKE_CONF}-${i}"
            iniset $fake_conf DEFAULT host "${HOSTNAME}${i}"
            run_process "n-cpu-${i}" "$NOVA_BIN_DIR/nova-compute --config-file $NOVA_CPU_CONF --config-file $fake_conf"
        done
    else
        if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
            start_nova_hypervisor
        fi
        run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $NOVA_CPU_CONF"
    fi

    export PATH=$old_path
}

# start_nova() - Start running processes
function start_nova_rest {
    # Hack to set the path for rootwrap
    local old_path=$PATH
    export PATH=$NOVA_BIN_DIR:$PATH

    local api_cell_conf=$NOVA_CONF
    local compute_cell_conf=$NOVA_CONF

    run_process n-sch "$NOVA_BIN_DIR/nova-scheduler --config-file $compute_cell_conf"
    if [ "$NOVA_USE_MOD_WSGI" == "False" ]; then
        run_process n-api-meta "$NOVA_BIN_DIR/nova-api-metadata --config-file $compute_cell_conf"
    else
        run_process n-api-meta "$NOVA_BIN_DIR/uwsgi --procname-prefix nova-api-meta --ini $NOVA_METADATA_UWSGI_CONF"
    fi

    export PATH=$old_path
}

function enable_nova_console_proxies {
    for i in $(seq 1 $NOVA_NUM_CELLS); do
        for srv in n-novnc n-xvnc n-spice n-sproxy; do
            if is_service_enabled $srv; then
                enable_service ${srv}-cell${i}
            fi
        done
    done
}

function start_nova_console_proxies {
    # Hack to set the path for rootwrap
    local old_path=$PATH
    # This is needed to find the nova conf
    export PATH=$NOVA_BIN_DIR:$PATH

    local api_cell_conf=$NOVA_CONF
    # console proxies run globally for singleconductor, else they run per cell
    if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
        run_process n-novnc "$NOVA_BIN_DIR/nova-novncproxy --config-file $api_cell_conf --web $NOVNC_WEB_DIR"
        run_process n-xvnc "$NOVA_BIN_DIR/nova-xvpvncproxy --config-file $api_cell_conf"
        run_process n-spice "$NOVA_BIN_DIR/nova-spicehtml5proxy --config-file $api_cell_conf --web $SPICE_WEB_DIR"
        run_process n-sproxy "$NOVA_BIN_DIR/nova-serialproxy --config-file $api_cell_conf"
    else
        enable_nova_console_proxies
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            local conf
            conf=$(conductor_conf $i)
            run_process n-novnc-cell${i} "$NOVA_BIN_DIR/nova-novncproxy --config-file $conf --web $NOVNC_WEB_DIR"
            run_process n-xvnc-cell${i} "$NOVA_BIN_DIR/nova-xvpvncproxy --config-file $conf"
            run_process n-spice-cell${i} "$NOVA_BIN_DIR/nova-spicehtml5proxy --config-file $conf --web $SPICE_WEB_DIR"
            run_process n-sproxy-cell${i} "$NOVA_BIN_DIR/nova-serialproxy --config-file $conf"
        done
    fi

    export PATH=$old_path
}

function enable_nova_fleet {
    if is_service_enabled n-cond; then
        enable_service n-super-cond
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            enable_service n-cond-cell${i}
        done
    fi
}

function start_nova_conductor {
    if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
        echo "Starting nova-conductor in a cellsv1-compatible way"
        run_process n-cond "$NOVA_BIN_DIR/nova-conductor --config-file $NOVA_COND_CONF"
        return
    fi

    enable_nova_fleet
    if is_service_enabled n-super-cond; then
        run_process n-super-cond "$NOVA_BIN_DIR/nova-conductor --config-file $NOVA_COND_CONF"
    fi
    for i in $(seq 1 $NOVA_NUM_CELLS); do
        if is_service_enabled n-cond-cell${i}; then
            local conf
            conf=$(conductor_conf $i)
            run_process n-cond-cell${i} "$NOVA_BIN_DIR/nova-conductor --config-file $conf"
        fi
    done
}

function is_nova_ready {
    # NOTE(sdague): with cells v2 all the compute services must be up
    # and checked into the database before discover_hosts is run. This
    # happens in all in one installs by accident, because > 30 seconds
    # happen between here and the script ending. However, in multinode
    # tests this can very often not be the case. So ensure that the
    # compute is up before we move on.

    # TODO(sdague): honestly, this probably should be a plug point for
    # an external system.
    if [[ "$VIRT_DRIVER" == 'xenserver' ]]; then
        # xenserver encodes information in the hostname of the compute
        # because of the dom0/domU split. Just ignore for now.
        return
    fi
    wait_for_compute $NOVA_READY_TIMEOUT
}

function start_nova {
    start_nova_rest
    start_nova_console_proxies
    start_nova_conductor
    start_nova_compute
    if is_service_enabled n-api; then
        # dump the cell mapping to ensure life is good
        echo "Dumping cells_v2 mapping"
        $NOVA_BIN_DIR/nova-manage cell_v2 list_cells --verbose
    fi
}

function stop_nova_compute {
    if [ "$VIRT_DRIVER" == "fake" ]; then
        local i
        for i in `seq 1 $NUMBER_FAKE_NOVA_COMPUTE`; do
            stop_process n-cpu-${i}
        done
    else
        stop_process n-cpu
    fi
    if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
        stop_nova_hypervisor
    fi
}

function stop_nova_rest {
    # Kill the non-compute nova processes
    for serv in n-api n-api-meta n-sch; do
        stop_process $serv
    done
}

function stop_nova_console_proxies {
    if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
        for srv in n-novnc n-xvnc n-spice n-sproxy; do
            stop_process $srv
        done
    else
        enable_nova_console_proxies
        for i in $(seq 1 $NOVA_NUM_CELLS); do
            for srv in n-novnc n-xvnc n-spice n-sproxy; do
                stop_process ${srv}-cell${i}
            done
        done
    fi
}

function stop_nova_conductor {
    if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
        stop_process n-cond
        return
    fi

    enable_nova_fleet
    for srv in n-super-cond $(seq -f n-cond-cell%0.f 1 $NOVA_NUM_CELLS); do
        if is_service_enabled $srv; then
            stop_process $srv
        fi
    done
}

# stop_nova() - Stop running processes
function stop_nova {
    stop_nova_rest
    stop_nova_console_proxies
    stop_nova_conductor
    stop_nova_compute
}

# create_instance_types(): Create default flavors
function create_flavors {
    if is_service_enabled n-api; then
        if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q ds512M; then
            # Note that danms hates these flavors and apologizes for sdague
            openstack --os-region-name="$REGION_NAME" flavor create --id c1 --ram 256 --disk 1 --vcpus 1 cirros256
            openstack --os-region-name="$REGION_NAME" flavor create --id d1 --ram 512 --disk 5 --vcpus 1 ds512M
            openstack --os-region-name="$REGION_NAME" flavor create --id d2 --ram 1024 --disk 10 --vcpus 1 ds1G
            openstack --os-region-name="$REGION_NAME" flavor create --id d3 --ram 2048 --disk 10 --vcpus 2 ds2G
            openstack --os-region-name="$REGION_NAME" flavor create --id d4 --ram 4096 --disk 20 --vcpus 4 ds4G
        fi

        if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q m1.tiny; then
            openstack --os-region-name="$REGION_NAME" flavor create --id 1 --ram 512 --disk 1 --vcpus 1 m1.tiny
            openstack --os-region-name="$REGION_NAME" flavor create --id 2 --ram 2048 --disk 20 --vcpus 1 m1.small
            openstack --os-region-name="$REGION_NAME" flavor create --id 3 --ram 4096 --disk 40 --vcpus 2 m1.medium
            openstack --os-region-name="$REGION_NAME" flavor create --id 4 --ram 8192 --disk 80 --vcpus 4 m1.large
            openstack --os-region-name="$REGION_NAME" flavor create --id 5 --ram 16384 --disk 160 --vcpus 8 m1.xlarge
        fi
    fi
}

# Restore xtrace
$_XTRACE_LIB_NOVA

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