Kien Nguyen 486e91f961 Add procname for uwsgi based services
Code in grenade and elsewhere rely on the process/service name
when one runs "ps auxw" and they grep for example "grep -e glance-api"
to check if the service is running. with uwsgi, let us make sure
we use process name prefix so it is easier to spot the services
and be compatible with code elsewhere that relies on this.

Follow patch set I4d1cd223ed9904fcb19b26fc9362b676e0b4f9b3
Change-Id: I78e6f578d26f6ed6f8ec2b336da55316e25e5ad9
2018-01-24 11:48:32 +07:00

410 lines
13 KiB
Bash

#!/bin/bash
#
# lib/zun
# Functions to control the configuration and operation of the **zun** service
# Dependencies:
#
# - ``functions`` file
# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
# ``stack.sh`` calls the entry points in this order:
#
# - install_zun
# - configure_zun
# - create_zun_conf
# - create_zun_accounts
# - init_zun
# - start_zun
# - stop_zun
# - cleanup_zun
# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace
# Defaults
# --------
# Set up default directories
ZUN_REPO=${ZUN_REPO:-${GIT_BASE}/openstack/zun.git}
ZUN_BRANCH=${ZUN_BRANCH:-master}
ZUN_DIR=$DEST/zun
ZUN_TEMPEST_PLUGIN_REPO=${ZUN_TEMPEST_PLUGIN_REPO:-${GIT_BASE}/openstack/zun-tempest-plugin.git}
ZUN_TEMPEST_PLUGIN_BRANCH=${ZUN_TEMPEST_PLUGIN_BRANCH:-master}
ZUN_TEMPEST_PLUGIN_DIR=$DEST/zun-tempest-plugin
GITREPO["python-zunclient"]=${ZUNCLIENT_REPO:-${GIT_BASE}/openstack/python-zunclient.git}
GITBRANCH["python-zunclient"]=${ZUNCLIENT_BRANCH:-master}
GITDIR["python-zunclient"]=$DEST/python-zunclient
ZUN_STATE_PATH=${ZUN_STATE_PATH:=$DATA_DIR/zun}
ZUN_AUTH_CACHE_DIR=${ZUN_AUTH_CACHE_DIR:-/var/cache/zun}
ZUN_CONF_DIR=/etc/zun
ZUN_CONF=$ZUN_CONF_DIR/zun.conf
ZUN_API_PASTE=$ZUN_CONF_DIR/api-paste.ini
if is_ssl_enabled_service "zun" || is_service_enabled tls-proxy; then
ZUN_SERVICE_PROTOCOL="https"
fi
# Toggle for deploying ZUN-API under a wsgi server
ZUN_USE_UWSGI=${ZUN_USE_UWSGI:-True}
# Public facing bits
ZUN_SERVICE_HOST=${ZUN_SERVICE_HOST:-$SERVICE_HOST}
ZUN_SERVICE_PORT=${ZUN_SERVICE_PORT:-9517}
ZUN_SERVICE_PORT_INT=${ZUN_SERVICE_PORT_INT:-19517}
ZUN_SERVICE_PROTOCOL=${ZUN_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
ZUN_TRUSTEE_DOMAIN_ADMIN_PASSWORD=${ZUN_TRUSTEE_DOMAIN_ADMIN_PASSWORD:-secret}
# Support entry points installation of console scripts
if [[ -d $ZUN_DIR/bin ]]; then
ZUN_BIN_DIR=$ZUN_DIR/bin
else
ZUN_BIN_DIR=$(get_python_exec_prefix)
fi
ZUN_UWSGI=$ZUN_BIN_DIR/zun-api-wsgi
ZUN_UWSGI_CONF=$ZUN_CONF_DIR/zun-api-uwsgi.ini
DOCKER_REMOTE_API_PORT=2375
ZUN_DRIVER=${ZUN_DRIVER:-docker}
ZUN_DB_TYPE=${ZUN_DB_TYPE:-sql}
ZUN_ETCD_VERSION=${ZUN_ETCD_VERSION:-v3.0.13}
ZUN_ETCD_PORT=${ZUN_ETCD_PORT:-2379}
ZUN_WEBSOCKET_PROXY_PORT=${ZUN_WEBSOCKET_PROXY_PORT:-6784}
ZUN_WEBSOCKET_PROXY_IP=${ZUN_WEBSOCKET_PROXY_IP:-0.0.0.0}
if is_ubuntu; then
UBUNTU_RELEASE_BASE_NUM=`lsb_release -r | awk '{print $2}' | cut -d '.' -f 1`
fi
# Functions
# ---------
# cleanup_zun() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_zun {
sudo rm -rf $ZUN_STATE_PATH $ZUN_AUTH_CACHE_DIR
# Destroy old containers
local container_name_prefix=${CONTAINER_NAME_PREFIX:-zun-}
local containers
containers=`sudo docker ps -a | grep $container_name_prefix | sed "s/.*\($container_name_prefix[0-9a-zA-Z-]*\).*/\1/g"`
if [ ! "$containers" = "" ]; then
sudo docker rm -f $containers || true
fi
remove_uwsgi_config "$ZUN_UWSGI_CONF" "$ZUN_UWSGI"
}
# configure_zun() - Set config files, create data dirs, etc
function configure_zun {
# Put config files in ``/etc/zun`` for everyone to find
if [[ ! -d $ZUN_CONF_DIR ]]; then
sudo mkdir -p $ZUN_CONF_DIR
sudo chown $STACK_USER $ZUN_CONF_DIR
fi
# Rebuild the config file from scratch
create_zun_conf
create_api_paste_conf
write_uwsgi_config "$ZUN_UWSGI_CONF" "$ZUN_UWSGI" "/container"
if [[ "$USE_PYTHON3" = "True" ]]; then
# Switch off glance->swift communication as swift fails under py3.x
iniset /etc/glance/glance-api.conf glance_store default_store file
fi
}
# upload_sandbox_image() - Upload sandbox image to glance
function upload_sandbox_image {
if "${ZUN_DRIVER}" == "docker" && is_service_enabled g-api; then
sudo docker pull kubernetes/pause
sudo docker save kubernetes/pause | openstack image create kubernetes/pause --public --container-format docker --disk-format raw
fi
}
# create_zun_accounts() - Set up common required ZUN accounts
#
# Project User Roles
# ------------------------------------------------------------------
# SERVICE_PROJECT_NAME zun service
function create_zun_accounts {
create_service_user "zun" "admin"
create_service_user "zun-experimental" "admin"
if is_service_enabled zun-api; then
local zun_api_url
if [[ "$ZUN_USE_UWSGI" == "True" ]]; then
zun_api_url="$ZUN_SERVICE_PROTOCOL://$ZUN_SERVICE_HOST/container"
else
zun_api_url="$ZUN_SERVICE_PROTOCOL://$ZUN_SERVICE_HOST:$ZUN_SERVICE_PORT"
fi
local zun_service=$(get_or_create_service "zun" \
"container" "Container As Service")
local zun_experimental_service=$(get_or_create_service "zun-experimental" \
"container-experimental" "Container As Service - Experimental")
get_or_create_endpoint $zun_service \
"$REGION_NAME" \
"$zun_api_url/v1" \
"$zun_api_url/v1" \
"$zun_api_url/v1"
get_or_create_endpoint $zun_experimental_service \
"$REGION_NAME" \
"$zun_api_url/experimental" \
"$zun_api_url/experimental" \
"$zun_api_url/experimental"
fi
}
# create_zun_conf() - Create a new zun.conf file
function create_zun_conf {
# (Re)create ``zun.conf``
rm -f $ZUN_CONF
if [[ ${ZUN_DRIVER} == "docker" ]]; then
iniset $ZUN_CONF DEFAULT container_driver docker.driver.DockerDriver
fi
if [[ ${ZUN_DB_TYPE} == "etcd" ]]; then
iniset $ZUN_CONF DEFAULT db_type etcd
elif [[ ${ZUN_DB_TYPE} == "sql" ]]; then
iniset $ZUN_CONF DEFAULT db_type sql
fi
iniset $ZUN_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
iniset $ZUN_CONF DEFAULT my_ip "$HOST_IP"
iniset $ZUN_CONF oslo_messaging_rabbit rabbit_userid $RABBIT_USERID
iniset $ZUN_CONF oslo_messaging_rabbit rabbit_password $RABBIT_PASSWORD
iniset $ZUN_CONF oslo_messaging_rabbit rabbit_host $RABBIT_HOST
iniset $ZUN_CONF database connection `database_connection_url zun`
iniset $ZUN_CONF etcd etcd_host "$SERVICE_HOST"
iniset $ZUN_CONF etcd etcd_port "$ZUN_ETCD_PORT"
iniset $ZUN_CONF websocket_proxy wsproxy_port "$ZUN_WEBSOCKET_PROXY_PORT"
iniset $ZUN_CONF websocket_proxy wsproxy_host "$ZUN_WEBSOCKET_PROXY_IP"
iniset $ZUN_CONF websocket_proxy base_url "ws://${SERVICE_HOST}:${ZUN_WEBSOCKET_PROXY_PORT}/"
iniset $ZUN_CONF api host_ip "$ZUN_SERVICE_HOST"
iniset $ZUN_CONF api port "$ZUN_SERVICE_PORT"
iniset $ZUN_CONF docker docker_remote_api_host "$HOST_IP"
iniset $ZUN_CONF keystone_auth auth_type password
iniset $ZUN_CONF keystone_auth username zun
iniset $ZUN_CONF keystone_auth password $SERVICE_PASSWORD
iniset $ZUN_CONF keystone_auth project_name $SERVICE_PROJECT_NAME
iniset $ZUN_CONF keystone_auth project_domain_id default
iniset $ZUN_CONF keystone_auth user_domain_id default
# FIXME(pauloewerton): keystone_authtoken section is deprecated. Remove it
# after deprecation period.
iniset $ZUN_CONF keystone_authtoken admin_user zun
iniset $ZUN_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
iniset $ZUN_CONF keystone_authtoken admin_tenant_name $SERVICE_PROJECT_NAME
configure_auth_token_middleware $ZUN_CONF zun $ZUN_AUTH_CACHE_DIR
iniset $ZUN_CONF keystone_auth auth_url $KEYSTONE_AUTH_URI_V3
iniset $ZUN_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_URI_V3
iniset $ZUN_CONF keystone_authtoken auth_url $KEYSTONE_AUTH_URI_V3
iniset $ZUN_CONF keystone_authtoken auth_version v3
iniset $ZUN_CONF glance images_directory $ZUN_STATE_PATH/images
if is_fedora || is_suse; then
# zun defaults to /usr/local/bin, but fedora and suse pip like to
# install things in /usr/bin
iniset $ZUN_CONF DEFAULT bindir "/usr/bin"
fi
if [ -n "$ZUN_STATE_PATH" ]; then
iniset $ZUN_CONF DEFAULT state_path "$ZUN_STATE_PATH"
iniset $ZUN_CONF oslo_concurrency lock_path "$ZUN_STATE_PATH"
fi
if [ "$SYSLOG" != "False" ]; then
iniset $ZUN_CONF DEFAULT use_syslog "True"
fi
# Format logging
if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
setup_colorized_logging $ZUN_CONF DEFAULT
else
# Show user_name and project_name instead of user_id and project_id
iniset $ZUN_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
fi
# Register SSL certificates if provided
if is_ssl_enabled_service zun; then
ensure_certificates zun
iniset $ZUN_CONF DEFAULT ssl_cert_file "$ZUN_SSL_CERT"
iniset $ZUN_CONF DEFAULT ssl_key_file "$ZUN_SSL_KEY"
iniset $ZUN_CONF DEFAULT enabled_ssl_apis "$ZUN_ENABLED_APIS"
fi
}
function create_api_paste_conf {
# copy api_paste.ini
cp $ZUN_DIR/etc/zun/api-paste.ini $ZUN_API_PASTE
}
# create_zun_cache_dir() - Part of the init_ZUN() process
function create_zun_cache_dir {
# Create cache dir
sudo mkdir -p $ZUN_AUTH_CACHE_DIR
sudo chown $STACK_USER $ZUN_AUTH_CACHE_DIR
rm -f $ZUN_AUTH_CACHE_DIR/*
}
# init_zun() - Initialize databases, etc.
function init_zun {
# Only do this step once on the API node for an entire cluster.
if is_service_enabled zun-api; then
if is_service_enabled $DATABASE_BACKENDS; then
# (Re)create zun database
recreate_database zun
# Migrate zun database
$ZUN_BIN_DIR/zun-db-manage upgrade
fi
if is_service_enabled zun-etcd; then
install_etcd_server
fi
create_zun_cache_dir
fi
}
# install_zunclient() - Collect source and prepare
function install_zunclient {
if use_library_from_git "python-zunclient"; then
git_clone_by_name "python-zunclient"
setup_dev_lib "python-zunclient"
sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-zunclient"]}/tools/,/etc/bash_completion.d/}zun.bash_completion
fi
}
# install_zun() - Collect source and prepare
function install_zun {
git_clone $ZUN_REPO $ZUN_DIR $ZUN_BRANCH
setup_develop $ZUN_DIR
git_clone $ZUN_TEMPEST_PLUGIN_REPO $ZUN_TEMPEST_PLUGIN_DIR $ZUN_TEMPEST_PLUGIN_BRANCH
setup_develop $ZUN_TEMPEST_PLUGIN_DIR
}
function install_etcd_server {
echo "Installing etcd"
# If there's a container named 'etcd' already exists, remove it.
if [ $(sudo docker ps -a | awk '{print $NF}' | grep -w etcd) ]; then
sudo docker rm -f etcd || true
fi
[[ $(pgrep -x "etcd") ]] || sudo docker run -d --net=host --name etcd quay.io/coreos/etcd:${ZUN_ETCD_VERSION} \
/usr/local/bin/etcd \
--data-dir=data.etcd \
--name node0 \
--initial-advertise-peer-urls http://${HOST_IP}:2380 \
--listen-peer-urls http://${HOST_IP}:2380 \
--advertise-client-urls http://${HOST_IP}:${ZUN_ETCD_PORT} \
--listen-client-urls http://${HOST_IP}:${ZUN_ETCD_PORT} \
--initial-cluster node0=http://${HOST_IP}:2380 \
--initial-cluster-state new \
--initial-cluster-token etcd-token
}
# start_zun_api() - Start the API process ahead of other things
function start_zun_api {
# Get right service port for testing
local service_port=$ZUN_SERVICE_PORT
local service_protocol=$ZUN_SERVICE_PROTOCOL
if is_service_enabled tls-proxy; then
service_port=$ZUN_SERVICE_PORT_INT
service_protocol="http"
fi
local zun_url
if [ "$ZUN_USE_UWSGI" == "True" ]; then
run_process zun-api "$ZUN_BIN_DIR/uwsgi --procname-prefix zun-api --ini $ZUN_UWSGI_CONF"
zun_url=$service_protocol://$ZUN_SERVICE_HOST/container
else
run_process zun-api "$ZUN_BIN_DIR/zun-api"
zun_url=$service_protocol://$ZUN_SERVICE_HOST:$service_port
fi
echo "Waiting for zun-api to start..."
if ! wait_for_service $SERVICE_TIMEOUT $zun_url; then
die $LINENO "zun-api did not start"
fi
# Start proxies if enabled
if is_service_enabled tls-proxy; then
start_tls_proxy '*' $ZUN_SERVICE_PORT $ZUN_SERVICE_HOST $ZUN_SERVICE_PORT_INT &
fi
# Start websocket proxy for interactive mode
if is_service_enabled zun-wsproxy; then
run_process zun-wsproxy "$ZUN_BIN_DIR/zun-wsproxy"
fi
}
# start_zun_compute() - Start Zun compute agent
function start_zun_compute {
echo "Start zun compute..."
run_process zun-compute "$ZUN_BIN_DIR/zun-compute"
}
function start_zun_etcd {
echo "Start zun etcd..."
sudo docker start etcd || true
}
function stop_zun_etcd {
echo "Stop zun etcd..."
sudo docker stop etcd
sudo docker rm -f etcd || true
}
# start_zun() - Start running processes, including screen
function start_zun {
# ``run_process`` checks ``is_service_enabled``, it is not needed here
start_zun_api
start_zun_compute
if is_service_enabled zun-etcd; then
start_zun_etcd
fi
}
# stop_zun() - Stop running processes (non-screen)
function stop_zun {
if is_service_enabled zun-etcd; then
stop_zun_etcd
fi
if [ "$ZUN_USE_UWSGI" == "True" ]; then
disable_apache_site zun
restart_apache_server
else
stop_process zun-api
fi
stop_process zun-compute
if is_service_enabled zun-wsproxy; then
stop_process zun-wsproxy
fi
}
# Restore xtrace
$XTRACE