openstack-operator/devstack/lib/nova

382 lines
16 KiB
Bash

#!/bin/bash
#
# Copyright 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
NOVA_STATE_PATH=/var/lib/nova
# INSTANCES_PATH is the previous name for this
NOVA_INSTANCES_PATH=$NOVA_STATE_PATH/instances
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 filter_scheduler enabled_filters "$NOVA_FILTERS"
iniset $NOVA_CONF scheduler workers "$API_WORKERS"
iniset $NOVA_CONF neutron default_floating_pool "$PUBLIC_NETWORK_NAME"
if [[ $SERVICE_IP_VERSION == 6 ]]; then
iniset $NOVA_CONF DEFAULT my_ip "$HOST_IPV6"
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 DEFAULT shutdown_timeout $NOVA_SHUTDOWN_TIMEOUT
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
kubernetes_ensure_resource secret/nova-cell1-mysql
NOVA_CELL1_DATABASE_USER=$(get_data_from_secret nova-cell1-mysql openstack USER)
NOVA_CELL1_DATABASE_PASSWORD=$(get_data_from_secret nova-cell1-mysql openstack PASSWORD)
NOVA_CELL1_DATABASE_NAME=$(get_data_from_secret nova-cell1-mysql openstack DATABASE)
iniset $NOVA_CONF database connection "mysql+pymysql://$NOVA_CELL1_DATABASE_USER:$NOVA_CELL1_DATABASE_PASSWORD@nova-cell1-mysql-master.openstack.svc/$NOVA_CELL1_DATABASE_NAME?charset=utf8"
kubernetes_ensure_resource secret/nova-api-mysql
NOVA_API_DATABASE_USER=$(get_data_from_secret nova-api-mysql openstack USER)
NOVA_API_DATABASE_PASSWORD=$(get_data_from_secret nova-api-mysql openstack PASSWORD)
NOVA_API_DATABASE_NAME=$(get_data_from_secret nova-api-mysql openstack DATABASE)
iniset $NOVA_CONF api_database connection "mysql+pymysql://$NOVA_API_DATABASE_USER:$NOVA_API_DATABASE_PASSWORD@nova-api-mysql-master.openstack.svc/$NOVA_API_DATABASE_NAME?charset=utf8"
# Cache related settings
# Those settings aren't really needed in n-cpu thus it is configured
# only on nodes which runs controller services
iniset $NOVA_CONF cache enabled $NOVA_ENABLE_CACHE
iniset $NOVA_CONF cache backend $CACHE_BACKEND
iniset $NOVA_CONF cache memcache_servers mcrouter-memcached-nova.openstack.svc.cluster.local:11211
NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/,metadata//")
iniset $NOVA_CONF DEFAULT enabled_apis "$NOVA_ENABLED_APIS"
# Adop v3applicationcredential instead of password type
kubernetes_ensure_resource secret/nova-application-credential
NOVA_APPLICATION_CREDENTIAL_SECRET=$(get_data_from_secret nova-application-credential openstack secret)
NOVA_APPLICATION_CREDENTIAL_ID=$(get_data_from_secret nova-application-credential openstack id)
iniset $NOVA_CONF keystone_authtoken auth_url $KEYSTONE_AUTH_URI_V3
iniset $NOVA_CONF keystone_authtoken auth_type v3applicationcredential
iniset $NOVA_CONF keystone_authtoken application_credential_id $NOVA_APPLICATION_CREDENTIAL_ID
iniset $NOVA_CONF keystone_authtoken application_credential_secret $NOVA_APPLICATION_CREDENTIAL_SECRET
iniset $NOVA_CONF keystone_authtoken memcached_servers mcrouter-memcached-nova.openstack.svc.cluster.local:11211
if is_service_enabled cinder; then
configure_cinder_access
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
iniset $NOVA_CONF upgrade_levels compute "auto"
proxy_pass_to_kubernetes /compute nova nova-api-wsgi
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"
kubernetes_ensure_resource secret/nova-cell1-rabbitmq
NOVA_RABBITMQ_USERNAME=$(get_data_from_secret nova-cell1-rabbitmq openstack username)
NOVA_RABBITMQ_PASSWORD=$(get_data_from_secret nova-cell1-rabbitmq openstack password)
iniset $NOVA_CONF DEFAULT transport_url "rabbit://$NOVA_RABBITMQ_USERNAME:$NOVA_RABBITMQ_PASSWORD@rabbitmq-nova-cell1.openstack.svc.cluster.local:5672/"
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 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
NOVA_CELL_DATABASE_USER=$(get_data_from_secret nova-cell${i}-mysql openstack USER)
NOVA_CELL_DATABASE_PASSWORD=$(get_data_from_secret nova-cell${i}-mysql openstack PASSWORD)
NOVA_CELL_DATABASE_NAME=$(get_data_from_secret nova-cell${i}-mysql openstack DATABASE)
iniset $conf database connection "mysql+pymysql://$NOVA_CELL_DATABASE_USER:$NOVA_CELL_DATABASE_PASSWORD@nova-cell${i}-mysql-master.openstack.svc/$NOVA_CELL_DATABASE_NAME?charset=utf8"
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
kubernetes_ensure_resource secret/nova-cell1-rabbitmq
NOVA_RABBITMQ_USERNAME=$(get_data_from_secret nova-cell1-rabbitmq openstack username)
NOVA_RABBITMQ_PASSWORD=$(get_data_from_secret nova-cell1-rabbitmq openstack password)
iniset $NOVA_CONF DEFAULT transport_url "rabbit://$NOVA_RABBITMQ_USERNAME:$NOVA_RABBITMQ_PASSWORD@rabbitmq-nova-cell1.openstack.svc.cluster.local:5672/"
else
# NOTE(mnaser): Not supported for now and all this code is going away anyways
exit 1
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.
configure_console_proxies
# NOTE(Alex): Disable rootwrap and use sudo only
iniset $NOVA_CONF workarounds disable_rootwrap True
}
function create_nova_compute_conf {
# Bug #1802143: $NOVA_CPU_CONF is constructed by first copying $NOVA_CONF...
cp $NOVA_CONF $NOVA_CPU_CONF
# ...and then adding/overriding anything explicitly set in $NOVA_CPU_CONF
merge_config_file $TOP_DIR/local.conf post-config '$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
}
export -f create_nova_compute_conf
function init_nova {
# All nova components talk to a central database.
# Only do this step once on the API node for an entire cluster.
create_nova_keys_dir
}
# Helper to clean iptables rules
function clean_iptables {
echo noop
}
export -f clean_iptables
# 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}
kubernetes_ensure_resource secret/placement-application-credential
PLACEMENT_APPLICATION_CREDENTIAL_SECRET=$(get_data_from_secret placement-application-credential openstack secret)
PLACEMENT_APPLICATION_CREDENTIAL_ID=$(get_data_from_secret placement-application-credential openstack id)
iniset $conf placement auth_url $KEYSTONE_AUTH_URI_V3
iniset $conf placement auth_type v3applicationcredential
iniset $conf placement application_credential_id $PLACEMENT_APPLICATION_CREDENTIAL_ID
iniset $conf placement application_credential_secret $PLACEMENT_APPLICATION_CREDENTIAL_SECRET
}
# Configure access to cinder.
function configure_cinder_access {
kubernetes_ensure_resource secret/cinder-application-credential
CINDER_APPLICATION_CREDENTIAL_SECRET=$(get_data_from_secret cinder-application-credential openstack secret)
CINDER_APPLICATION_CREDENTIAL_ID=$(get_data_from_secret cinder-application-credential openstack id)
iniset $NOVA_CONF cinder auth_url $KEYSTONE_AUTH_URI_V3
iniset $NOVA_CONF cinder auth_type v3applicationcredential
iniset $NOVA_CONF cinder application_credential_id $CINDER_APPLICATION_CREDENTIAL_ID
iniset $NOVA_CONF cinder application_credential_secret $CINDER_APPLICATION_CREDENTIAL_SECRET
}
# 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
# nova-scheduler
kubernetes_ensure_resource ds/nova-scheduler
kubernetes_rollout_restart ds/nova-scheduler
kubernetes_rollout_status ds/nova-scheduler
# nova-scheduler
kubernetes_ensure_resource ds/nova-metadata-api
kubernetes_rollout_restart ds/nova-metadata-api
kubernetes_rollout_status ds/nova-metadata-api
export PATH=$old_path
}
function start_nova_conductor {
kubernetes_ensure_resource ds/nova-conductor
kubernetes_rollout_restart ds/nova-conductor
kubernetes_rollout_status ds/nova-conductor
}
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
# novncproxy
kubernetes_ensure_resource ds/nova-novncproxy
kubernetes_rollout_restart ds/nova-novncproxy
kubernetes_rollout_status ds/nova-novncproxy
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"
export PATH=$old_path
}
function configure_console_compute {
# NOTE(Alex): Now imagine using one cell and novnc only,
# so no need to offset the proxy port.
# Use the host IP instead of the service host because for multi-node, the
# service host will be the controller only.
local default_proxyclient_addr
default_proxyclient_addr=$(iniget $NOVA_CPU_CONF DEFAULT my_ip)
NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://nova-novncproxy.openstack.svc/vnc_auto.html"}
iniset $NOVA_CPU_CONF vnc novncproxy_base_url "$NOVNCPROXY_URL"
# 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_LISTEN_ADDRESS}
VNCSERVER_PROXYCLIENT_ADDRESS=${VNCSERVER_PROXYCLIENT_ADDRESS:-$default_proxyclient_addr}
iniset $NOVA_CPU_CONF vnc server_listen "$VNCSERVER_LISTEN"
iniset $NOVA_CPU_CONF vnc server_proxyclient_address "$VNCSERVER_PROXYCLIENT_ADDRESS"
}
function configure_console_proxies {
# Use the provided config file path or default to $NOVA_CONF.
local conf=${1:-$NOVA_CONF}
# NOTE(Alex): Now imagine using one cell and novnc only,
# so no need to offset the proxy port.
iniset $conf vnc novncproxy_host "$NOVA_SERVICE_LISTEN_ADDRESS"
iniset $conf vnc novncproxy_port 6080
}
# start_nova_api() - Start the API process ahead of other things
function start_nova_api {
# Hack to set the path for rootwrap
local old_path=$PATH
export PATH=$NOVA_BIN_DIR:$PATH
kubernetes_ensure_resource ds/nova-compute-api
kubernetes_rollout_restart ds/nova-compute-api
kubernetes_rollout_status ds/nova-compute-api
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
# libvirt
kubernetes_ensure_resource ds/nova-compute
kubernetes_rollout_restart ds/nova-compute
kubernetes_rollout_status ds/nova-compute
export PATH=$old_path
}
# install_nova() - Collect source and prepare
# NOTE(Alex): Because, the nova stuff is in the stach.sh,
# keep nova installation on host.(kinda status check)
function start_nova {
start_nova_rest
start_nova_console_proxies
start_nova_conductor
start_nova_compute
}
function create_nova_accounts {
# NOTE(Alex): Ignore ResellerAdmin
echo noop
}
function init_nova_service_user_conf {
kubernetes_ensure_resource secret/nova-application-credential
NOVA_APPLICATION_CREDENTIAL_SECRET=$(get_data_from_secret nova-application-credential openstack secret)
NOVA_APPLICATION_CREDENTIAL_ID=$(get_data_from_secret nova-application-credential openstack id)
iniset $NOVA_CONF service_user auth_url $KEYSTONE_SERVICE_URI
iniset $NOVA_CONF service_user auth_type v3applicationcredential
iniset $NOVA_CONF service_user application_credential_id $NOVA_APPLICATION_CREDENTIAL_ID
iniset $NOVA_CONF service_user application_credential_secret $NOVA_APPLICATION_CREDENTIAL_SECRET
iniset $NOVA_CONF service_user send_service_user_token True
iniset $NOVA_CONF service_user auth_strategy keystone
}