#!/bin/bash # # lib/watcher # Functions to control the configuration and operation of the watcher services # Dependencies: # # - ``functions`` file # - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined # - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined # ``stack.sh`` calls the entry points in this order: # # - is_watcher_enabled # - install_watcher # - configure_watcher # - create_watcher_conf # - init_watcher # - start_watcher # - stop_watcher # - cleanup_watcher # Save trace setting _XTRACE_WATCHER=$(set +o | grep xtrace) set +o xtrace # Defaults # -------- # Set up default directories WATCHER_REPO=${WATCHER_REPO:-${GIT_BASE}/openstack/watcher.git} WATCHER_BRANCH=${WATCHER_BRANCH:-master} WATCHER_DIR=$DEST/watcher GITREPO["python-watcherclient"]=${WATCHERCLIENT_REPO:-${GIT_BASE}/openstack/python-watcherclient.git} GITBRANCH["python-watcherclient"]=${WATCHERCLIENT_BRANCH:-master} GITDIR["python-watcherclient"]=$DEST/python-watcherclient WATCHER_STATE_PATH=${WATCHER_STATE_PATH:=$DATA_DIR/watcher} WATCHER_AUTH_CACHE_DIR=${WATCHER_AUTH_CACHE_DIR:-/var/cache/watcher} WATCHER_CONF_DIR=/etc/watcher WATCHER_CONF=$WATCHER_CONF_DIR/watcher.conf WATCHER_POLICY_YAML=$WATCHER_CONF_DIR/policy.yaml.sample WATCHER_DEVSTACK_DIR=$WATCHER_DIR/devstack WATCHER_DEVSTACK_FILES_DIR=$WATCHER_DEVSTACK_DIR/files if is_ssl_enabled_service "watcher" || is_service_enabled tls-proxy; then WATCHER_SERVICE_PROTOCOL="https" fi # Support entry points installation of console scripts if [[ -d $WATCHER_DIR/bin ]]; then WATCHER_BIN_DIR=$WATCHER_DIR/bin else WATCHER_BIN_DIR=$(get_python_exec_prefix) fi # There are 2 modes, which is "uwsgi" which runs with an apache # proxy uwsgi in front of it, or "mod_wsgi", which runs in # apache. mod_wsgi is deprecated, don't use it. WATCHER_USE_WSGI_MODE=${WATCHER_USE_WSGI_MODE:-$WSGI_MODE} WATCHER_UWSGI=$WATCHER_BIN_DIR/watcher-api-wsgi WATCHER_UWSGI_CONF=$WATCHER_CONF_DIR/watcher-uwsgi.ini if is_suse; then WATCHER_WSGI_DIR=${WATCHER_WSGI_DIR:-/srv/www/htdocs/watcher} else WATCHER_WSGI_DIR=${WATCHER_WSGI_DIR:-/var/www/watcher} fi # Public facing bits WATCHER_SERVICE_HOST=${WATCHER_SERVICE_HOST:-$SERVICE_HOST} WATCHER_SERVICE_PORT=${WATCHER_SERVICE_PORT:-9322} WATCHER_SERVICE_PORT_INT=${WATCHER_SERVICE_PORT_INT:-19322} WATCHER_SERVICE_PROTOCOL=${WATCHER_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL} if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then WATCHER_API_URL="$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST/infra-optim" else WATCHER_API_URL="$WATCHER_SERVICE_PROTOCOL://$WATCHER_SERVICE_HOST:$WATCHER_SERVICE_PORT" fi # Entry Points # ------------ # Test if any watcher services are enabled # is_watcher_enabled function is_watcher_enabled { [[ ,${ENABLED_SERVICES} =~ ,"watcher-" ]] && return 0 return 1 } #_cleanup_watcher_apache_wsgi - Remove wsgi files, #disable and remove apache vhost file function _cleanup_watcher_apache_wsgi { sudo rm -rf $WATCHER_WSGI_DIR sudo rm -f $(apache_site_config_for watcher-api) restart_apache_server } # cleanup_watcher() - Remove residual data files, anything left over from previous # runs that a clean run would need to clean up function cleanup_watcher { sudo rm -rf $WATCHER_STATE_PATH $WATCHER_AUTH_CACHE_DIR if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then remove_uwsgi_config "$WATCHER_UWSGI_CONF" "$WATCHER_UWSGI" else _cleanup_watcher_apache_wsgi fi } # configure_watcher() - Set config files, create data dirs, etc function configure_watcher { # Put config files in ``/etc/watcher`` for everyone to find sudo install -d -o $STACK_USER $WATCHER_CONF_DIR local project=watcher local project_uc project_uc=$(echo watcher|tr a-z A-Z) local conf_dir="${project_uc}_CONF_DIR" # eval conf dir to get the variable conf_dir="${!conf_dir}" local project_dir="${project_uc}_DIR" # eval project dir to get the variable project_dir="${!project_dir}" local sample_conf_dir="${project_dir}/etc/${project}" local sample_policy_dir="${project_dir}/etc/${project}/policy.d" local sample_policy_generator="${project_dir}/etc/${project}/oslo-policy-generator/watcher-policy-generator.conf" # first generate policy.yaml oslopolicy-sample-generator --config-file $sample_policy_generator # then optionally copy over policy.d if [[ -d $sample_policy_dir ]]; then cp -r $sample_policy_dir $conf_dir/policy.d fi # Rebuild the config file from scratch create_watcher_conf } # create_watcher_accounts() - Set up common required watcher accounts # # Project User Roles # ------------------------------------------------------------------ # SERVICE_TENANT_NAME watcher service function create_watcher_accounts { create_service_user "watcher" "admin" local watcher_service=$(get_or_create_service "watcher" \ "infra-optim" "Watcher Infrastructure Optimization Service") get_or_create_endpoint $watcher_service \ "$REGION_NAME" \ "$WATCHER_API_URL"\ "$WATCHER_API_URL"\ "$WATCHER_API_URL" } # _config_watcher_apache_wsgi() - Set WSGI config files of watcher function _config_watcher_apache_wsgi { local watcher_apache_conf if [[ "$WATCHER_USE_WSGI_MODE" == "mod_wsgi" ]]; then local service_port=$WATCHER_SERVICE_PORT if is_service_enabled tls-proxy; then service_port=$WATCHER_SERVICE_PORT_INT service_protocol="http" fi sudo mkdir -p $WATCHER_WSGI_DIR sudo cp $WATCHER_DIR/watcher/api/app.wsgi $WATCHER_WSGI_DIR/app.wsgi watcher_apache_conf=$(apache_site_config_for watcher-api) sudo cp $WATCHER_DEVSTACK_FILES_DIR/apache-watcher-api.template $watcher_apache_conf sudo sed -e " s|%WATCHER_SERVICE_PORT%|$service_port|g; s|%WATCHER_WSGI_DIR%|$WATCHER_WSGI_DIR|g; s|%USER%|$STACK_USER|g; s|%APIWORKERS%|$API_WORKERS|g; s|%APACHE_NAME%|$APACHE_NAME|g; " -i $watcher_apache_conf enable_apache_site watcher-api fi } # create_watcher_conf() - Create a new watcher.conf file function create_watcher_conf { # (Re)create ``watcher.conf`` rm -f $WATCHER_CONF iniset $WATCHER_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL" iniset $WATCHER_CONF DEFAULT control_exchange watcher iniset_rpc_backend watcher $WATCHER_CONF iniset $WATCHER_CONF database connection $(database_connection_url watcher) iniset $WATCHER_CONF api host "$(ipv6_unquote $WATCHER_SERVICE_HOST)" if is_service_enabled tls-proxy; then iniset $WATCHER_CONF api host "$(ipv6_unquote $WATCHER_SERVICE_HOST)" iniset $WATCHER_CONF api port "$WATCHER_SERVICE_PORT_INT" # iniset $WATCHER_CONF api enable_ssl_api "True" else if [[ "$WATCHER_USE_WSGI_MODE" == "mod_wsgi" ]]; then iniset $WATCHER_CONF api host "$(ipv6_unquote $WATCHER_SERVICE_HOST)" iniset $WATCHER_CONF api port "$WATCHER_SERVICE_PORT" fi fi iniset $WATCHER_CONF oslo_policy policy_file $WATCHER_POLICY_YAML iniset $WATCHER_CONF oslo_messaging_notifications driver "messagingv2" configure_auth_token_middleware $WATCHER_CONF watcher $WATCHER_AUTH_CACHE_DIR configure_auth_token_middleware $WATCHER_CONF watcher $WATCHER_AUTH_CACHE_DIR "watcher_clients_auth" if is_fedora || is_suse; then # watcher defaults to /usr/local/bin, but fedora and suse pip like to # install things in /usr/bin iniset $WATCHER_CONF DEFAULT bindir "/usr/bin" fi if [ -n "$WATCHER_STATE_PATH" ]; then iniset $WATCHER_CONF DEFAULT state_path "$WATCHER_STATE_PATH" iniset $WATCHER_CONF oslo_concurrency lock_path "$WATCHER_STATE_PATH" fi if [ "$SYSLOG" != "False" ]; then iniset $WATCHER_CONF DEFAULT use_syslog "True" fi # Format logging setup_logging $WATCHER_CONF #config apache files if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then write_uwsgi_config "$WATCHER_UWSGI_CONF" "$WATCHER_UWSGI" "/infra-optim" else _config_watcher_apache_wsgi fi # Register SSL certificates if provided if is_ssl_enabled_service watcher; then ensure_certificates WATCHER iniset $WATCHER_CONF DEFAULT ssl_cert_file "$WATCHER_SSL_CERT" iniset $WATCHER_CONF DEFAULT ssl_key_file "$WATCHER_SSL_KEY" iniset $WATCHER_CONF DEFAULT enabled_ssl_apis "$WATCHER_ENABLED_APIS" fi } # create_watcher_cache_dir() - Part of the init_watcher() process function create_watcher_cache_dir { # Create cache dir sudo install -d -o $STACK_USER $WATCHER_AUTH_CACHE_DIR rm -rf $WATCHER_AUTH_CACHE_DIR/* } # init_watcher() - Initialize databases, etc. function init_watcher { # clean up from previous (possibly aborted) runs # create required data files if is_service_enabled $DATABASE_BACKENDS && is_service_enabled watcher-api; then # (Re)create watcher database recreate_database watcher # Create watcher schema $WATCHER_BIN_DIR/watcher-db-manage --config-file $WATCHER_CONF upgrade fi create_watcher_cache_dir } # install_watcherclient() - Collect source and prepare function install_watcherclient { if use_library_from_git "python-watcherclient"; then git_clone_by_name "python-watcherclient" setup_dev_lib "python-watcherclient" fi } # install_watcher() - Collect source and prepare function install_watcher { git_clone $WATCHER_REPO $WATCHER_DIR $WATCHER_BRANCH setup_develop $WATCHER_DIR if [[ "$WATCHER_USE_WSGI_MODE" == "mod_wsgi" ]]; then install_apache_wsgi fi } # start_watcher_api() - Start the API process ahead of other things function start_watcher_api { # Get right service port for testing local service_port=$WATCHER_SERVICE_PORT local service_protocol=$WATCHER_SERVICE_PROTOCOL local watcher_url if is_service_enabled tls-proxy; then service_port=$WATCHER_SERVICE_PORT_INT service_protocol="http" fi if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then run_process "watcher-api" "$(which uwsgi) --procname-prefix watcher-api --ini $WATCHER_UWSGI_CONF" watcher_url=$service_protocol://$SERVICE_HOST/infra-optim else watcher_url=$service_protocol://$SERVICE_HOST:$service_port enable_apache_site watcher-api restart_apache_server # Start proxies if enabled if is_service_enabled tls-proxy; then start_tls_proxy watcher '*' $WATCHER_SERVICE_PORT $WATCHER_SERVICE_HOST $WATCHER_SERVICE_PORT_INT fi fi echo "Waiting for watcher-api to start..." if ! wait_for_service $SERVICE_TIMEOUT $watcher_url; then die $LINENO "watcher-api did not start" fi } # start_watcher() - Start running processes, including screen function start_watcher { # ``run_process`` checks ``is_service_enabled``, it is not needed here start_watcher_api run_process watcher-decision-engine "$WATCHER_BIN_DIR/watcher-decision-engine --config-file $WATCHER_CONF" run_process watcher-applier "$WATCHER_BIN_DIR/watcher-applier --config-file $WATCHER_CONF" } # stop_watcher() - Stop running processes (non-screen) function stop_watcher { if [[ "$WATCHER_USE_WSGI_MODE" == "uwsgi" ]]; then stop_process watcher-api else disable_apache_site watcher-api restart_apache_server fi for serv in watcher-decision-engine watcher-applier; do stop_process $serv done } # Restore xtrace $_XTRACE_WATCHER # Tell emacs to use shell-script-mode ## Local variables: ## mode: shell-script ## End: