diff --git a/devstack/lib/cyborg b/devstack/lib/cyborg new file mode 100644 index 00000000..16a1a3f8 --- /dev/null +++ b/devstack/lib/cyborg @@ -0,0 +1,346 @@ +#!/bin/bash +# +# lib/cyborg +# Functions to control the configuration and operation of the **Cyborg** service + +# Dependencies: +# +# - ``functions`` file +# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined +# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined +# - ``SERVICE_HOST`` +# - ``KEYSTONE_TOKEN_FORMAT`` must be defined + +# ``stack.sh`` calls the entry points in this order: +# +# - install_cyborg +# - init_cyborg +# - start_cyborg +# - stop_cyborg +# - cleanup_cyborg + + +# ensure we don't re-source this in the same environment +[[ -z "$_CYBORG_DEVSTACK_LIB" ]] || return 0 +declare -r -g _CYBORG_DEVSTACK_LIB=1 + +# Save xtrace and pipefail settings +_XTRACE_CYBORG=$(set +o | grep xtrace) +_PIPEFAIL_CYBORG=$(set +o | grep pipefail) +set -o xtrace +set +o pipefail + +# Defaults +# -------- + +# Set up default directories + +GITREPO["virtualbmc"]=${VIRTUALBMC_REPO:-${GIT_BASE}/openstack/virtualbmc.git} +GITBRANCH["virtualbmc"]=${VIRTUALBMC_BRANCH:-master} +GITDIR["virtualbmc"]=$DEST/virtualbmc + +CYBORG_DIR=$DEST/cyborg +CYBORG_DEVSTACK_DIR=$CYBORG_DIR/devstack +CYBORG_DEVSTACK_FILES_DIR=$CYBORG_DEVSTACK_DIR/files +CYBORG_DATA_DIR=$DATA_DIR/cyborg +CYBORG_STATE_PATH=/var/lib/cyborg +CYBORG_AUTH_CACHE_DIR=${CYBORG_AUTH_CACHE_DIR:-/var/cache/cyborg} +CYBORG_CONF_DIR=${CYBORG_CONF_DIR:-/etc/cyborg} +CYBORG_CONF_FILE=$CYBORG_CONF_DIR/cyborg.conf +CYBORG_ROOTWRAP_CONF=$CYBORG_CONF_DIR/rootwrap.conf +CYBORG_POLICY_JSON=$CYBORG_CONF_DIR/policy.json + +# Deploy callback timeout can be changed from its default (1800), if required. +CYBORG_CALLBACK_TIMEOUT=${CYBORG_CALLBACK_TIMEOUT:-} + +# driver / hardware type options + +if [[ "$CYBORG_VM_ENGINE" == "auto" ]]; then + sudo modprobe kvm || true + if [ ! -e /dev/kvm ]; then + echo "WARNING: Switching to QEMU" + CYBORG_VM_ENGINE=qemu + if [[ -z "$CYBORG_VM_EMULATOR" ]]; then + CYBORG_VM_EMULATOR='/usr/bin/qemu-system-x86_64' + fi + else + CYBORG_VM_ENGINE=kvm + fi +fi + +if [[ "$CYBORG_VM_ENGINE" == "kvm" ]]; then + # Set this to empty, so configure-vm.py can autodetect location + # of KVM binary + CYBORG_VM_EMULATOR="" +fi + + +function setup_virtualbmc { + # Install pyghmi from source, if requested, otherwise it will be + # downloaded as part of the virtualbmc installation + if use_library_from_git "pyghmi"; then + git_clone_by_name "pyghmi" + setup_dev_lib "pyghmi" + fi + + if use_library_from_git "virtualbmc"; then + git_clone_by_name "virtualbmc" + setup_dev_lib "virtualbmc" + else + pip_install_gr "virtualbmc" + fi + + if [[ ! -d $(dirname $CYBORG_VBMC_CONFIG_FILE) ]]; then + mkdir -p $(dirname $CYBORG_VBMC_CONFIG_FILE) + fi + + iniset $CYBORG_VBMC_CONFIG_FILE log debug True + iniset $CYBORG_VBMC_CONFIG_FILE log logfile $CYBORG_VBMC_LOGFILE +} + + +# install_cyborg() - Install the things! +function install_cyborg { + # make sure all needed service were enabled + local req_services="key" + if is_service_enabled nova && [[ "$VIRT_DRIVER" == "cyborg" ]]; then + req_services+=" nova glance neutron" + fi + for srv in $req_services; do + if ! is_service_enabled "$srv"; then + die $LINENO "$srv should be enabled for Ironic." + fi + done + + setup_develop $CYBORG_DIR +} + + +# cleanup_cyborg_config_files() - Remove residual cache/config/log files, +# left over from previous runs that would need to clean up. +function cleanup_cyborg_config_files { + sudo rm -rf $CYBORG_AUTH_CACHE_DIR $CYBORG_CONF_DIR + sudo rm -rf $CYBORG_VM_LOG_DIR/* +} + + +# cleanup_cyborg() - Clean everything left from Cyborg +function cleanup_cyborg { + cleanup_cyborg_config_files +} + + +# configure_cyborg_dirs() - Create all directories required by Ironic and +# associated services. +function configure_cyborg_dirs { + sudo install -d -o $STACK_USER $CYBORG_CONF_DIR $STACK_USER $CYBORG_DATA_DIR \ + $CYBORG_STATE_PATH + sudo chown -R $STACK_USER:$STACK_USER $CYBORG_TFTPBOOT_DIR + + # Create the logs directory when saving the deploy logs to the filesystem + if [[ "$CYBORG_DEPLOY_LOGS_STORAGE_BACKEND" == "local" && "$CYBORG_DEPLOY_LOGS_COLLECT" != "never" ]]; then + install -d -o $STACK_USER $CYBORG_DEPLOY_LOGS_LOCAL_PATH + fi +} + + +# configure_cyborg() - Set config files, create data dirs, etc +function configure_cyborg { + configure_cyborg_dirs + + # Copy over cyborg configuration file and configure common parameters. + cp $CYBORG_DIR/etc/cyborg/cyborg.conf.sample $CYBORG_CONF_FILE + iniset $CYBORG_CONF_FILE DEFAULT debug True + inicomment $CYBORG_CONF_FILE DEFAULT log_file + iniset $CYBORG_CONF_FILE database connection `database_connection_url cyborg` + iniset $CYBORG_CONF_FILE DEFAULT state_path $CYBORG_STATE_PATH + iniset $CYBORG_CONF_FILE DEFAULT use_syslog $SYSLOG + iniset $CYBORG_CONF_FILE DEFAULT host $LOCAL_HOSTNAME + + # Configure Ironic conductor, if it was enabled. + if is_service_enabled cyborg-cond; then + configure_cyborg_conductor + fi + + # Configure Ironic API, if it was enabled. + if is_service_enabled cyborg-api; then + configure_cyborg_api + fi + + # Format logging + setup_logging $CYBORG_CONF_FILE + + if [[ "$os_VENDOR" =~ (Debian|Ubuntu) ]]; then + # The groups change with newer libvirt. Older Ubuntu used + # 'libvirtd', but now uses libvirt like Debian. Do a quick check + # to see if libvirtd group already exists to handle grenade's case. + LIBVIRT_GROUP=$(cut -d ':' -f 1 /etc/group | grep 'libvirtd$' || true) + LIBVIRT_GROUP=${LIBVIRT_GROUP:-libvirt} + else + LIBVIRT_GROUP=libvirtd + fi + if ! getent group $LIBVIRT_GROUP >/dev/null; then + sudo groupadd $LIBVIRT_GROUP + fi + # NOTE(vsaienko) Add stack to libvirt group when installing without nova. + if ! is_service_enabled nova; then + add_user_to_group $STACK_USER $LIBVIRT_GROUP + + # This is the basic set of devices allowed / required by all virtual machines. + # Add /dev/net/tun to cgroup_device_acl, needed for type=ethernet interfaces + if ! sudo grep -q '^cgroup_device_acl' /etc/libvirt/qemu.conf; then + cat <$tempfile + chmod 0440 $tempfile + sudo chown root:root $tempfile + sudo mv $tempfile /etc/sudoers.d/cyborg-rootwrap + + # set up drivers / hardware types + iniset $CYBORG_CONF_FILE DEFAULT enabled_drivers $CYBORG_ENABLED_DRIVERS + + if is_deployed_by_agent; then + iniset $CYBORG_CONF_FILE api ramdisk_heartbeat_timeout 30 + fi +} + +# create_cyborg_cache_dir() - Part of the init_cyborg() process +function create_cyborg_cache_dir { + # Create cache dir + sudo mkdir -p $CYBORG_AUTH_CACHE_DIR/api + sudo chown $STACK_USER $CYBORG_AUTH_CACHE_DIR/api + rm -f $CYBORG_AUTH_CACHE_DIR/api/* + sudo mkdir -p $CYBORG_AUTH_CACHE_DIR/registry + sudo chown $STACK_USER $CYBORG_AUTH_CACHE_DIR/registry + rm -f $CYBORG_AUTH_CACHE_DIR/registry/* +} + +# init_cyborg() - Initialize databases, etc. +function init_cyborg { + # Migrate cyborg database + $CYBORG_BIN_DIR/cyborg-dbsync --config-file=$CYBORG_CONF_FILE + create_cyborg_cache_dir +} + + +# start_cyborg() - Start running processes, including screen +function start_cyborg { + # Start Cyborg API server, if enabled. + if is_service_enabled cyborg-api; then + start_cyborg_api + fi + + # Start Cyborg conductor, if enabled. + if is_service_enabled cyborg-cond; then + start_cyborg_conductor + fi + + # Start Cyborg agent, if enabled. + if is_service_enabled cyborg-agent; then + start_cyborg_agent + fi +} + +# start_cyborg_api() - Used by start_cyborg(). +# Starts Cyborg API server. +function start_cyborg_api { + run_process cyborg-api "$CYBORG_BIN_DIR/cyborg-api --config-file=$CYBORG_CONF_FILE" +} + +# start_cyborg_conductor() - Used by start_cyborg(). +# Starts Cyborg conductor. +function start_cyborg_conductor { + run_process cyborg-cond "$CYBORG_BIN_DIR/cyborg-conductor --config-file=$CYBORG_CONF_FILE" +} + +# start_cyborg_agent() - Used by start_cyborg(). +# Starts Cyborg agent. +function start_cyborg_agent { + run_process cyborg-agent "$CYBORG_BIN_DIR/cyborg-agent --config-file=$CYBORG_CONF_FILE" +} + +# stop_cyborg() - Stop running processes +function stop_cyborg { + stop_process cyborg-api + stop_process cyborg-cond + stop_process cyborg-agent +} + + wait_for_nova_resources "count" $total_nodes + wait_for_nova_resources "vcpus" $total_cpus + fi +} + +function die_if_module_not_loaded { + if ! grep -q $1 /proc/modules; then + die $LINENO "$1 kernel module is not loaded" + fi +} + +# Restore xtrace + pipefail +$_XTRACE_CYBORG +$_PIPEFAIL_CYBORG + +# Tell emacs to use shell-script-mode +## Local variables: +## mode: shell-script +## End: diff --git a/devstack/plugin.sh b/devstack/plugin.sh new file mode 100644 index 00000000..2349c5c8 --- /dev/null +++ b/devstack/plugin.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# plugin.sh - devstack plugin for cyborg + +# devstack plugin contract defined at: +# https://docs.openstack.org/devstack/latest/plugins.html + +echo_summary "cyborg devstack plugin.sh called: $1/$2" + +if is_service_enabled cyborg-api cyborg-cond; then + if [[ "$1" == "stack" ]]; then + if [[ "$2" == "install" ]]; then + # stack/install - Called after the layer 1 and 2 projects source and + # their dependencies have been installed + + echo_summary "Installing Cyborg" + if ! is_service_enabled nova; then + source $RC_DIR/lib/nova_plugins/functions-libvirt + install_libvirt + fi + install_cyborg + cleanup_cyborg_config_files + + elif [[ "$2" == "post-config" ]]; then + # stack/post-config - Called after the layer 1 and 2 services have been + # configured. All configuration files for enabled services should exist + # at this point. + + echo_summary "Configuring Cyborg" + configure_cyborg + + if is_service_enabled key; then + create_cyborg_accounts + fi + + elif [[ "$2" == "extra" ]]; then + # stack/extra - Called near the end after layer 1 and 2 services have + # been started. + + # Initialize cyborg + init_cyborg + + # Start the cyborg API and cyborg taskmgr components + echo_summary "Starting Cyborg" + start_cyborg + + fi + fi + + if [[ "$1" == "unstack" ]]; then + # unstack - Called by unstack.sh before other services are shut down. + + stop_cyborg + fi + + if [[ "$1" == "clean" ]]; then + # clean - Called by clean.sh before other services are cleaned, but after + # unstack.sh has been called. + cleanup_cyborg + fi +fi + diff --git a/devstack/settings b/devstack/settings new file mode 100644 index 00000000..e9a16e63 --- /dev/null +++ b/devstack/settings @@ -0,0 +1 @@ +enable_service cyborg cyborg-api cyborg-cond cyborg-agent