221 lines
7.9 KiB
Bash
Executable File
221 lines
7.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
CHARM="nova-cloud-controller"
|
|
CONF_DIR="/etc/nova"
|
|
|
|
NOVA_CONF="/etc/nova/nova.conf"
|
|
API_CONF="/etc/nova/api-paste.ini"
|
|
QUANTUM_CONF="/etc/quantum/quantum.conf"
|
|
QUANTUM_API_CONF="/etc/quantum/api-paste.ini"
|
|
|
|
NET_MANAGER=$(config-get network-manager)
|
|
|
|
if [[ -e $CHARM_DIR/lib/nova/nova-common ]] ; then
|
|
. $CHARM_DIR/lib/nova/nova-common
|
|
else
|
|
juju-log "Couldn't load $CHARM_DIR/lib/nova/nova-common" && exit 1
|
|
fi
|
|
|
|
function determine_services {
|
|
# Sets the global $SERVICES which contains a list of all services
|
|
# managed by the charm. This changes based on OpenStack release.
|
|
# Currently, the services also determines what ends up in $PACKAGES.
|
|
|
|
# base c-c services supported across all os releases since essex.
|
|
SERVICES="nova-api-ec2 nova-api-os-compute nova-objectstore nova-cert nova-scheduler"
|
|
|
|
# determine additional services, dependent on what version of OS.
|
|
local install_src="$(config-get openstack-origin)"
|
|
install_src=$(get_os_codename_install_source "$install_src")
|
|
local os_vers=$(get_os_codename_package "nova-common")
|
|
if [[ "$os_vers" == "none" ]] ; then
|
|
[[ "$install_src" == "unknown" ]] && echo "$SERVICES" && return 0
|
|
fi
|
|
|
|
os_vers="$install_src"
|
|
if [[ "$os_vers" != "essex" ]] && [[ "$os_vers" != "folsom" ]] ; then
|
|
# nova-conductor was introduced in grizzly.
|
|
SERVICES="$SERVICES nova-conductor"
|
|
else
|
|
local n_vol=$(relation-ids nova-volume-service)
|
|
if [[ -n "$n_vol" ]] ; then
|
|
# nova-volume was dropped in G but may still be deployed for E + F,
|
|
# but should only be managed when a relation to nova-volume exists.
|
|
SERVICES="$SERVICES nova-api-os-volume"
|
|
# need to also ensure the package gets installed here. if the relation
|
|
# is introduced during another hook, a call to 'service_ctl all' will
|
|
# require it to be there.
|
|
dpkg -l | grep -q nova-api-os-volume ||
|
|
apt-get -y install nova-api-os-volume
|
|
fi
|
|
fi
|
|
|
|
# quantum is really only supported for folsom and beyond.
|
|
if [[ "$NET_MANAGER" == "Quantum" ]] ; then
|
|
[[ "$os_vers" == "essex" ]] &&
|
|
error_out "Quantum network manager only supported for Folsom + beyond."
|
|
SERVICES="$SERVICES quantum-server"
|
|
fi
|
|
}
|
|
|
|
function determine_packages {
|
|
# Derive a list of packages based on what our service needs are. This changes
|
|
# depending on several factors.
|
|
determine_services
|
|
PACKAGES="$SERVICES python-mysqldb python-keystone uuid charm-helper-sh"
|
|
|
|
if echo $PACKAGES | grep -q "quantum-server" ; then
|
|
case "$(config-get quantum-plugin)" in
|
|
"ovs") PACKAGES="$PACKAGES quantum-plugin-openvswitch" ;;
|
|
"nvp") PACKAGES="$PACKAGES quantum-plugin-nicira" ;;
|
|
esac
|
|
fi
|
|
juju-log "$CHARM: Determined required packages: $PACKAGES."
|
|
}
|
|
|
|
function determine_quantum_config {
|
|
# Set QUANTUM_PLUGIN and point QUANTUM_CORE_PLUGIN and QUANTUM_PLUGIN_CONF
|
|
# to the correct files based on configuration.
|
|
QUANTUM_PLUGIN=${QUANTUM_PLUGIN:-$(config-get quantum-plugin)}
|
|
case "$QUANTUM_PLUGIN" in
|
|
"ovs")
|
|
QUANTUM_CORE_PLUGIN="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
|
|
QUANTUM_PLUGIN_CONF="/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"
|
|
;;
|
|
"nvp")
|
|
QUANTUM_CORE_PLUGIN="quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2"
|
|
QUANTUM_PLUGIN_CONF="/etc/quantum/plugins/nicira/nvp.ini"
|
|
;;
|
|
*)
|
|
juju-log "Unrecognised plugin for quantum: $QUANTUM_PLUGIN" && exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function configure_quantum_networking {
|
|
determine_quantum_config
|
|
if [ "$(config-get conf-ext-net)" != "no" ] &&
|
|
[ "$QUANTUM_PLUGIN" == "ovs" ] &&
|
|
[ -f /etc/quantum/novarc ] &&
|
|
[ -n "$(relation-ids shared-db)" ]; then
|
|
juju-log "Configuring external networking for quantum"
|
|
# Use helper to create external network gateway
|
|
# and router using generated credentials
|
|
. /etc/quantum/novarc
|
|
quantum-ext-net -g $(config-get ext-net-gateway) \
|
|
-c $(config-get ext-net-cidr) \
|
|
-f $(config-get pool-floating-start):$(config-get pool-floating-end) \
|
|
$(config-get ext-net-name)
|
|
fi
|
|
}
|
|
|
|
function ssh_authorized_keys {
|
|
local key="$1"
|
|
local action="$2"
|
|
local exists=""
|
|
|
|
local sunit=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f1)
|
|
mkdir -p /etc/nova/compute_ssh/$sunit
|
|
local authorized_keys="/etc/nova/compute_ssh/$sunit/authorized_keys"
|
|
|
|
[[ -e "$authorized_keys" ]] &&
|
|
grep -q "^$key" $authorized_keys && exists="true"
|
|
|
|
if [[ "$action" == "add" ]] ; then
|
|
[[ -n "$exists" ]] &&
|
|
juju-log "$CHARM: SSH key already authorized for $JUJU_REMOTE_UNIT." &&
|
|
return 0
|
|
|
|
echo "$key" >>$authorized_keys
|
|
juju-log "$CHARM: Authorized new SSH key for $JUJU_REMOTE_UNIT."
|
|
return 0
|
|
elif [[ "$action" == "remove" ]] ; then
|
|
# we have no way of getting to the relation state during a departed hook.
|
|
# we only have the peer's unit name, so remove an authorized key based on
|
|
# its comment, which should can be derived from the remote unit name and
|
|
# gets passed in here from caller as key/$1
|
|
local key_ln=$(sed -n "\, ${key}$,=" $authorized_keys)
|
|
[[ -z "$key_ln" ]] &&
|
|
juju-log "$CHARM: Cannot remove SSH key for $key, not authorized?" &&
|
|
return 0
|
|
|
|
for ln in $key_ln ; do
|
|
sed -i "${ln}d" $authorized_keys
|
|
juju-log "$CHARM: Removed existing SSH key ($key) from authorized_keys."
|
|
done
|
|
return 0
|
|
else
|
|
error_out "$CHARM: ssh_authorize_keys() invalid action specified: $action."
|
|
fi
|
|
}
|
|
|
|
function ssh_known_hosts {
|
|
# Keeps the system-wide SSH known hosts file up to date with compute
|
|
# nodes host keys.
|
|
local host="$1"
|
|
local sunit=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f1)
|
|
mkdir -p /etc/nova/compute_ssh/$sunit
|
|
local known_hosts="/etc/nova/compute_ssh/$sunit/known_hosts"
|
|
juju-log "$CHARM: Ensuring host is included and up to date in $known_hosts."
|
|
|
|
[[ ! -e $known_hosts ]] && touch $known_hosts
|
|
|
|
local remote_key=""
|
|
remote_key=$(ssh-keyscan -H -t rsa $host) ||
|
|
error_out "$CHARM: Couldn't obtain SSH host key from $host."
|
|
local existing=$(ssh-keygen -f $known_hosts -H -F $host | tail -n1)
|
|
if [[ -n "$existing" ]] ; then
|
|
juju-log "$CHARM: Found existing SSH known host key for $host."
|
|
[[ "$existing" == "$remote_key" ]] && echo "HI"
|
|
remote=$(echo $remote_key | awk '{ print $2" "$3 }')
|
|
existing=$(echo $existing | awk '{ print $2" "$3 }')
|
|
if [[ "$remote" == "$existing" ]] ; then
|
|
juju-log "$CHARM: SSH known host key for $host is up to date."
|
|
return 0
|
|
fi
|
|
juju-log "$CHARM: Removing outdated SSH host key for $host."
|
|
ssh-keygen -f $known_hosts -R $host
|
|
else
|
|
juju-log "$CHARM: No known hosts entry for $host."
|
|
fi
|
|
juju-log "$CHARM: Adding new SSH known hosts entry for $host."
|
|
echo $remote_key >>$known_hosts
|
|
|
|
}
|
|
|
|
function ssh_compute {
|
|
if [[ "$1" == "add" ]] ; then
|
|
local ssh_key=$(relation-get ssh_public_key)
|
|
[[ -z "$ssh_key" ]] &&
|
|
juju-log "$CHARM: ssh_compute peer not ready." && exit 0
|
|
|
|
ssh_authorized_keys "$ssh_key" "add"
|
|
|
|
# need to ensure known hosts entries for all possible addresses
|
|
. /usr/share/charm-helper/sh/net.sh
|
|
local known_hosts=""
|
|
local private_address=$(relation-get private-address)
|
|
known_hosts="$private_address"
|
|
if ! ch_is_ip "$private_address" ; then
|
|
known_hosts="$known_hosts $(get_ip $private_address)"
|
|
known_hosts="$known_hosts $(echo $private_address | cut -d. -f1)"
|
|
fi
|
|
for host in $known_hosts ; do
|
|
ssh_known_hosts "$host"
|
|
done
|
|
elif [[ "$1" == "remove" ]] ; then
|
|
# remove key by referencing remote unit, not entire key.
|
|
local remote_unit=$(echo $JUJU_REMOTE_UNIT | sed -e 's,/,-,g')
|
|
ssh_authorized_keys "$remote_unit" remove
|
|
else
|
|
error_out "ssh_compute: Invalid parameter: $1."
|
|
fi
|
|
|
|
local sunit=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f1)
|
|
|
|
# base64 encodings should trigger new relation events as needed.
|
|
relation-set \
|
|
known_hosts="$(base64 /etc/nova/compute_ssh/$sunit/known_hosts)" \
|
|
authorized_keys="$(base64 /etc/nova/compute_ssh/$sunit/authorized_keys)"
|
|
}
|