Wenzhi Yu b098d117b4 Set up etcd in devstack
We intend to use etcd as data store for Zun, so we need to
set up etcd server and client in devstack.

Part of blueprint etcd-db-driver

Change-Id: I63bf91bc0cdb894b53c4f8385c7d3d651035831a
2016-09-08 14:19:27 +08:00

395 lines
12 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
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_POLICY_JSON=$ZUN_CONF_DIR/policy.json
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
# Public facing bits
ZUN_SERVICE_HOST=${ZUN_SERVICE_HOST:-$HOST_IP}
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
DOCKER_GROUP=docker
DEFAULT_CONTAINER_DRIVER=docker
ETCD_VERSION=v3.0.7
if is_ubuntu; then
UBUNTU_RELEASE_BASE_NUM=`lsb_release -r | awk '{print $2}' | cut -d '.' -f 1`
fi
# Functions
# ---------
function check_docker {
if is_ubuntu; then
dpkg -s docker-engine > /dev/null 2>&1
else
rpm -q docker-engine > /dev/null 2>&1
fi
}
# Test if any zun services are enabled
# is_zun_enabled
function is_zun_enabled {
[[ ,${ENABLED_SERVICES} =~ ,"zun-" ]] && return 0
return 1
}
# 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
}
# 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
install_default_policy zun
# Rebuild the config file from scratch
create_zun_conf
create_api_paste_conf
if [[ ${DEFAULT_CONTAINER_DRIVER} == "docker" ]]; then
check_docker || curl -fsSL https://get.docker.com/ | sudo sh
sudo service docker start || true
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"
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
local zun_service=$(get_or_create_service "zun" \
"container" "Container As Service")
get_or_create_endpoint $zun_service \
"$REGION_NAME" \
"$ZUN_SERVICE_PROTOCOL://$ZUN_SERVICE_HOST:$ZUN_SERVICE_PORT/v1" \
"$ZUN_SERVICE_PROTOCOL://$ZUN_SERVICE_HOST:$ZUN_SERVICE_PORT/v1" \
"$ZUN_SERVICE_PROTOCOL://$ZUN_SERVICE_HOST:$ZUN_SERVICE_PORT/v1"
fi
}
# create_zun_conf() - Create a new zun.conf file
function create_zun_conf {
# (Re)create ``zun.conf``
rm -f $ZUN_CONF
iniset $ZUN_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
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 api host "$ZUN_SERVICE_HOST"
iniset $ZUN_CONF api port "$ZUN_SERVICE_PORT"
iniset $ZUN_CONF oslo_policy policy_file $ZUN_POLICY_JSON
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_SERVICE_URI/v3
iniset $ZUN_CONF keystone_authtoken auth_uri \
${KEYSTONE_SERVICE_PROTOCOL}://${HOST_IP}:${KEYSTONE_SERVICE_PORT}/v3
iniset $ZUN_CONF keystone_authtoken auth_version v3
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
install_etcd_client
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"
fi
}
# install_zun() - Collect source and prepare
function install_zun {
git_clone $ZUN_REPO $ZUN_DIR $ZUN_BRANCH
setup_develop $ZUN_DIR
}
function configure_etcd_systemd_service {
ETCD_CONF_DIR=/etc/etcd
ETCD_CONF=$ETCD_CONF_DIR/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd"
# Delete any existing etcd database:
sudo rm -rf $ETCD_DATA_DIR
sudo mkdir -p $ETCD_DATA_DIR
sudo rm -rf $ETCD_CONF_DIR
sudo install -d -o $STACK_USER $ETCD_CONF_DIR
cp $ZUN_DIR/devstack/etcd.service.conf $ETCD_CONF
iniset $ETCD_CONF DEFAULT ETCD_INITIAL_CLUSTER "$HOSTNAME=http://$HOST_IP:2380"
iniset $ETCD_CONF DEFAULT ETCD_INITIAL_CLUSTER_STATE "new"
iniset $ETCD_CONF DEFAULT ETCD_INITIAL_CLUSTER_TOKEN "etcd-cluster-01"
iniset $ETCD_CONF DEFAULT ETCD_INITIAL_ADVERTISE_PEER_URLS "http://$HOST_IP:2380"
iniset $ETCD_CONF DEFAULT ETCD_DATA_DIR "$ETCD_DATA_DIR"
iniset $ETCD_CONF DEFAULT ETCD_LISTEN_PEER_URLS "http://0.0.0.0:2380"
iniset $ETCD_CONF DEFAULT ETCD_LISTEN_CLIENT_URLS "http://$HOST_IP:2379"
iniset $ETCD_CONF DEFAULT ETCD_ADVERTISE_CLIENT_URLS "http://$HOST_IP:2379"
iniset $ETCD_CONF DEFAULT ETCD_NAME "$HOSTNAME"
sudo cp $ZUN_DIR/devstack/etcd.service /lib/systemd/system/
sudo systemctl enable etcd
}
function configure_etcd {
sudo cp $ZUN_DIR/devstack/etcd.conf /etc/init/etcd.conf
# Delete any existing etcd database:
sudo rm -rf /var/etcd
OVERRIDE_FILE=$ZUN_DIR/devstack/etcd.override
sudo rm -f $OVERRIDE_FILE
cat <<EOF > $OVERRIDE_FILE
# Override file for etcd Upstart script providing some environment variables
env ETCD_INITIAL_CLUSTER="$HOSTNAME=http://$HOST_IP:2380"
env ETCD_INITIAL_CLUSTER_STATE="new"
env ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"
env ETCD_INITIAL_ADVERTISE_PEER_URLS="http://$HOST_IP:2380"
env ETCD_DATA_DIR="/var/etcd"
env ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
env ETCD_LISTEN_CLIENT_URLS="http://$HOST_IP:2379"
env ETCD_ADVERTISE_CLIENT_URLS="http://$HOST_IP:2379"
env ETCD_NAME="$HOSTNAME"
EOF
sudo cp $OVERRIDE_FILE /etc/init/etcd.override
}
function install_etcd_server {
echo "Installing etcd"
if [ ! -f "$ZUN_DIR/etcd/etcd-$ETCD_VERSION-linux-amd64/etcd" ]; then
mkdir -p $ZUN_DIR/etcd
curl -L https://github.com/coreos/etcd/releases/download/$ETCD_VERSION/etcd-$ETCD_VERSION-linux-amd64.tar.gz -o $ZUN_DIR/etcd/etcd-$ETCD_VERSION-linux-amd64.tar.gz
tar xzvf $ZUN_DIR/etcd/etcd-$ETCD_VERSION-linux-amd64.tar.gz -C $ZUN_DIR/etcd
sudo cp $ZUN_DIR/etcd/etcd-$ETCD_VERSION-linux-amd64/etcd /usr/local/bin/etcd
fi
if [ ! -f "/usr/local/bin/etcd" ]; then
sudo cp $DEST/etcd/etcd-$ETCD_VERSION-linux-amd64/etcd /usr/local/bin/etcd
fi
if is_ubuntu; then
if [ $UBUNTU_RELEASE_BASE_NUM -ge 16 ] ; then
configure_etcd_systemd_service
else
configure_etcd
fi
elif is_fedora; then
configure_etcd_systemd_service
fi
}
function install_etcd_client {
sudo pip install python-etcd
}
# 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
run_process zun-api "$ZUN_BIN_DIR/zun-api"
echo "Waiting for zun-api to start..."
if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$ZUN_SERVICE_HOST:$service_port; 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_zun_compute() - Start Zun compute agent
function start_zun_compute {
echo "Adding $(whoami) to ${DOCKER_GROUP}..."
# TODO(eliqiao) this should depend on which container driver is using.
sudo usermod -a -G ${DOCKER_GROUP} $(whoami)
echo "Start zun compute..."
run_process zun-compute "$ZUN_BIN_DIR/zun-compute" ${DOCKER_GROUP}
}
function start_zun_etcd {
echo "Start zun etcd..."
if is_ubuntu; then
sudo service etcd start || true
elif is_fedora; then
sudo systemctl start etcd || true
fi
}
# 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 {
for serv in zun-api zun-compute; do
stop_process $serv
done
}
# Restore xtrace
$XTRACE