Pull from nova-cloud-controller-ha-support.

This commit is contained in:
Jerry Seutter 2013-03-19 16:41:03 -06:00
commit 37585336da
9 changed files with 523 additions and 152 deletions

@ -128,3 +128,13 @@ options:
description: |
Default multicast port number that will be used to communicate between
HA Cluster nodes.
ssl_cert:
type: string
description: |
SSL certificate to install and use for API ports. Setting this value
and ssl_key will enable reverse proxying, point Glance's entry in the
Keystone catalog to use https, and override any certficiate and key
issued by Keystone (if it is configured to do so).
ssl_key:
type: string
description: SSL key to use with certificate specified as ssl_cert.

@ -0,0 +1 @@
nova-cloud-controller-relations

@ -0,0 +1 @@
nova-cloud-controller-relations

1
hooks/ha-relation-changed Symbolic link

@ -0,0 +1 @@
nova-cloud-controller-relations

1
hooks/ha-relation-joined Symbolic link

@ -0,0 +1 @@
nova-cloud-controller-relations

@ -165,8 +165,9 @@ get_os_codename_install_source() {
fi
# have a guess based on the deb string provided
if [[ "${rel:0:3}" == "deb" ]]; then
CODENAMES="diablo essex folsom grizzly"
if [[ "${rel:0:3}" == "deb" ]] || \
[[ "${rel:0:3}" == "ppa" ]] ; then
CODENAMES="diablo essex folsom grizzly havana"
for cname in $CODENAMES; do
if echo $rel | grep -q $cname; then
codename=$cname
@ -178,11 +179,13 @@ get_os_codename_install_source() {
get_os_codename_package() {
local pkg_vers=$(dpkg -l | grep "$1" | awk '{ print $3 }') || echo "none"
pkg_vers=$(echo $pkg_vers | cut -d: -f2) # epochs
case "${pkg_vers:0:6}" in
"2011.2") echo "diablo" ;;
"2012.1") echo "essex" ;;
"2012.2") echo "folsom" ;;
"2013.1") echo "grizzly" ;;
"2013.2") echo "havana" ;;
esac
}
@ -191,7 +194,8 @@ get_os_version_codename() {
"diablo") echo "2011.2" ;;
"essex") echo "2012.1" ;;
"folsom") echo "2012.2" ;;
"grizzly") echo "2012.3" ;;
"grizzly") echo "2013.1" ;;
"havana") echo "2013.2" ;;
esac
}
@ -315,57 +319,20 @@ function get_block_device() {
return 0
}
##########################################################################
# Description: Creates an rc file exporting environment variables to a
# script_path local to the charm's installed directory.
# Any charm scripts run outside the juju hook environment can source this
# scriptrc to obtain updated config information necessary to perform health
# checks or service changes
#
# Parameters:
# An array of '=' delimited ENV_VAR:value combinations to export.
# If optional script_path key is not provided in the array, script_path
# defaults to scripts/scriptrc
##########################################################################
function save_script_rc {
if [ ! -n "$JUJU_UNIT_NAME" ]; then
echo "Error: Missing JUJU_UNIT_NAME environment variable"
exit 1
fi
# our default unit_path
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/scripts/scriptrc"
echo $unit_path
tmp_rc="/tmp/${JUJU_UNIT_NAME/\//-}rc"
echo "#!/bin/bash" > $tmp_rc
for env_var in "${@}"
do
if `echo $env_var | grep -q script_path`; then
# well then we need to reset the new unit-local script path
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/${env_var/script_path=/}"
else
echo "export $env_var" >> $tmp_rc
fi
done
chmod 755 $tmp_rc
mv $tmp_rc $unit_path
}
HAPROXY_CFG=/etc/haproxy/haproxy.cfg
HAPROXY_DEFAULT=/etc/default/haproxy
##########################################################################
# Description: Configures HAProxy services for Openstack API's
# Parameters:
# Space delimited list of service:port combinations for which
# Parameters:
# Space delimited list of service:port:mode combinations for which
# haproxy service configuration should be generated for. The function
# assumes the name of the peer relation is 'cluster' and that every
# service unit in the peer relation is running the same services.
#
# The HAProxy service will listen on port + 10000.
# Example:
# configure_haproxy cinder_api:12345 nova_api:9999
# Services that do not specify :mode in parameter will default to http.
#
# Example
# configure_haproxy cinder_api:8776:8756:tcp nova_api:8774:8764:http
##########################################################################
configure_haproxy() {
local address=`unit-get private-address`
@ -387,8 +354,8 @@ defaults
retries 3
timeout queue 1000
timeout connect 1000
timeout client 10000
timeout server 10000
timeout client 30000
timeout server 30000
listen stats :8888
mode http
@ -401,14 +368,21 @@ listen stats :8888
EOF
for service in $@; do
local service_name=$(echo $service | cut -d : -f 1)
local api_listen_port=$(echo $service | cut -d : -f 2)
local haproxy_listen_port=$(($api_listen_port + 10000))
local haproxy_listen_port=$(echo $service | cut -d : -f 2)
local api_listen_port=$(echo $service | cut -d : -f 3)
local mode=$(echo $service | cut -d : -f 4)
[[ -z "$mode" ]] && mode="http"
juju-log "Adding haproxy configuration entry for $service "\
"($haproxy_listen_port -> $api_listen_port)"
cat >> $HAPROXY_CFG << EOF
listen $service_name 0.0.0.0:$haproxy_listen_port
balance roundrobin
option tcplog
mode $mode
option ${mode}log
server $name $address:$api_listen_port check
EOF
local r_id=""
local unit=""
for r_id in `relation-ids cluster`; do
for unit in `relation-list -r $r_id`; do
local unit_name=${unit////-}
@ -421,6 +395,7 @@ EOF
done
done
echo "ENABLED=1" > $HAPROXY_DEFAULT
service haproxy restart
}
##########################################################################
@ -428,18 +403,20 @@ EOF
# Returns: 0 if configured, 1 if not configured
##########################################################################
is_clustered() {
local r_id=""
local unit=""
for r_id in $(relation-ids ha); do
if [ -n "$r_id" ]; then
for unit in $(relation-list -r $r_id); do
clustered=$(relation-get -r $r_id clustered $unit)
if [ -n "$clustered" ]; then
echo "Unit is clustered"
juju-log "Unit is haclustered"
return 0
fi
done
fi
done
echo "Unit is not clustered"
juju-log "Unit is not haclustered"
return 1
}
@ -448,6 +425,7 @@ is_clustered() {
##########################################################################
peer_units() {
local peers=""
local r_id=""
for r_id in $(relation-ids cluster); do
peers="$peers $(relation-list -r $r_id)"
done
@ -466,11 +444,11 @@ oldest_peer() {
echo "Comparing $JUJU_UNIT_NAME with peers: $peers"
local r_unit_no=$(echo $peer | cut -d / -f 2)
if (($r_unit_no<$l_unit_no)); then
echo "Not oldest peer; deferring"
juju-log "Not oldest peer; deferring"
return 1
fi
done
echo "Oldest peer; might take charge?"
juju-log "Oldest peer; might take charge?"
return 0
}
@ -484,13 +462,13 @@ oldest_peer() {
eligible_leader() {
if is_clustered; then
if ! is_leader $1; then
echo 'Deferring action to CRM leader'
juju-log 'Deferring action to CRM leader'
return 1
fi
else
peers=$(peer_units)
if [ -n "$peers" ] && ! oldest_peer "$peers"; then
echo 'Deferring action to oldest service unit.'
juju-log 'Deferring action to oldest service unit.'
return 1
fi
fi
@ -502,14 +480,14 @@ eligible_leader() {
# Returns: 0 if peered, 1 if not peered
##########################################################################
is_peered() {
r_id=$(relation-ids cluster)
local r_id=$(relation-ids cluster)
if [ -n "$r_id" ]; then
if [ -n "$(relation-list -r $r_id)" ]; then
echo "Unit peered"
juju-log "Unit peered"
return 0
fi
fi
echo "Unit not peered"
juju-log "Unit not peered"
return 1
}
@ -522,14 +500,209 @@ is_leader() {
hostname=`hostname`
if [ -x /usr/sbin/crm ]; then
if crm resource show $1 | grep -q $hostname; then
echo "$hostname is cluster leader"
juju-log "$hostname is cluster leader."
return 0
fi
fi
echo "$hostname is not cluster leader"
juju-log "$hostname is not cluster leader."
return 1
}
##########################################################################
# Description: Determines whether enough data has been provided in
# configuration or relation data to configure HTTPS.
# Parameters: None
# Returns: 0 if HTTPS can be configured, 1 if not.
##########################################################################
https() {
local r_id=""
if [[ -n "$(config-get ssl_cert)" ]] &&
[[ -n "$(config-get ssl_key)" ]] ; then
return 0
fi
for r_id in $(relation-ids identity-service) ; do
for unit in $(relation-list -r $r_id) ; do
if [[ "$(relation-get -r $r_id https_keystone $unit)" == "True" ]] &&
[[ -n "$(relation-get -r $r_id ssl_cert $unit)" ]] &&
[[ -n "$(relation-get -r $r_id ssl_key $unit)" ]] &&
[[ -n "$(relation-get -r $r_id ca_cert $unit)" ]] ; then
return 0
fi
done
done
return 1
}
##########################################################################
# Description: For a given number of port mappings, configures apache2
# HTTPs local reverse proxying using certficates and keys provided in
# either configuration data (preferred) or relation data. Assumes ports
# are not in use (calling charm should ensure that).
# Parameters: Variable number of proxy port mappings as
# $internal:$external.
# Returns: 0 if reverse proxy(s) have been configured, 0 if not.
##########################################################################
enable_https() {
local port_maps="$@"
local http_restart=""
juju-log "Enabling HTTPS for port mappings: $port_maps."
# allow overriding of keystone provided certs with those set manually
# in config.
local cert=$(config-get ssl_cert)
local key=$(config-get ssl_key)
local ca_cert=""
if [[ -z "$cert" ]] || [[ -z "$key" ]] ; then
juju-log "Inspecting identity-service relations for SSL certificate."
local r_id=""
cert=""
key=""
ca_cert=""
for r_id in $(relation-ids identity-service) ; do
for unit in $(relation-list -r $r_id) ; do
[[ -z "$cert" ]] && cert="$(relation-get -r $r_id ssl_cert $unit)"
[[ -z "$key" ]] && key="$(relation-get -r $r_id ssl_key $unit)"
[[ -z "$ca_cert" ]] && ca_cert="$(relation-get -r $r_id ca_cert $unit)"
done
done
[[ -n "$cert" ]] && cert=$(echo $cert | base64 -di)
[[ -n "$key" ]] && key=$(echo $key | base64 -di)
[[ -n "$ca_cert" ]] && ca_cert=$(echo $ca_cert | base64 -di)
else
juju-log "Using SSL certificate provided in service config."
fi
[[ -z "$cert" ]] || [[ -z "$key" ]] &&
juju-log "Expected but could not find SSL certificate data, not "\
"configuring HTTPS!" && return 1
apt-get -y install apache2
a2enmod ssl proxy proxy_http | grep -v "To activate the new configuration" &&
http_restart=1
mkdir -p /etc/apache2/ssl/$CHARM
echo "$cert" >/etc/apache2/ssl/$CHARM/cert
echo "$key" >/etc/apache2/ssl/$CHARM/key
if [[ -n "$ca_cert" ]] ; then
juju-log "Installing Keystone supplied CA cert."
echo "$ca_cert" >/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
update-ca-certificates --fresh
# XXX TODO: Find a better way of exporting this?
if [[ "$CHARM" == "nova-cloud-controller" ]] ; then
[[ -e /var/www/keystone_juju_ca_cert.crt ]] &&
rm -rf /var/www/keystone_juju_ca_cert.crt
ln -s /usr/local/share/ca-certificates/keystone_juju_ca_cert.crt \
/var/www/keystone_juju_ca_cert.crt
fi
fi
for port_map in $port_maps ; do
local ext_port=$(echo $port_map | cut -d: -f1)
local int_port=$(echo $port_map | cut -d: -f2)
juju-log "Creating apache2 reverse proxy vhost for $port_map."
cat >/etc/apache2/sites-available/${CHARM}_${ext_port} <<END
Listen $ext_port
NameVirtualHost *:$ext_port
<VirtualHost *:$ext_port>
ServerName $(unit-get private-address)
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/$CHARM/cert
SSLCertificateKeyFile /etc/apache2/ssl/$CHARM/key
ProxyPass / http://localhost:$int_port/
ProxyPassReverse / http://localhost:$int_port/
ProxyPreserveHost on
</VirtualHost>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
Order allow,deny
Allow from all
</Location>
END
a2ensite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
http_restart=1
done
if [[ -n "$http_restart" ]] ; then
service apache2 restart
fi
}
##########################################################################
# Description: Ensure HTTPS reverse proxying is disabled for given port
# mappings.
# Parameters: Variable number of proxy port mappings as
# $internal:$external.
# Returns: 0 if reverse proxy is not active for all portmaps, 1 on error.
##########################################################################
disable_https() {
local port_maps="$@"
local http_restart=""
juju-log "Ensuring HTTPS disabled for $port_maps."
( [[ ! -d /etc/apache2 ]] || [[ ! -d /etc/apache2/ssl/$CHARM ]] ) && return 0
for port_map in $port_maps ; do
local ext_port=$(echo $port_map | cut -d: -f1)
local int_port=$(echo $port_map | cut -d: -f2)
if [[ -e /etc/apache2/sites-available/${CHARM}_${ext_port} ]] ; then
juju-log "Disabling HTTPS reverse proxy for $CHARM $port_map."
a2dissite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
http_restart=1
fi
done
if [[ -n "$http_restart" ]] ; then
service apache2 restart
fi
}
##########################################################################
# Description: Ensures HTTPS is either enabled or disabled for given port
# mapping.
# Parameters: Variable number of proxy port mappings as
# $internal:$external.
# Returns: 0 if HTTPS reverse proxy is in place, 1 if it is not.
##########################################################################
setup_https() {
# configure https via apache reverse proxying either
# using certs provided by config or keystone.
[[ -z "$CHARM" ]] &&
error_out "setup_https(): CHARM not set."
if ! https ; then
disable_https $@
else
enable_https $@
fi
}
##########################################################################
# Description: Determine correct API server listening port based on
# existence of HTTPS reverse proxy and/or haproxy.
# Paremeters: The standard public port for given service.
# Returns: The correct listening port for API service.
##########################################################################
determine_api_port() {
local public_port="$1"
local i=0
( [[ -n "$(peer_units)" ]] || is_clustered >/dev/null 2>&1 ) && i=$[$i + 1]
https >/dev/null 2>&1 && i=$[$i + 1]
echo $[$public_port - $[$i * 10]]
}
##########################################################################
# Description: Determine correct proxy listening port based on public IP +
# existence of HTTPS reverse proxy.
# Paremeters: The standard public port for given service.
# Returns: The correct listening port for haproxy service public address.
##########################################################################
determine_haproxy_port() {
local public_port="$1"
local i=0
https >/dev/null 2>&1 && i=$[$i + 1]
echo $[$public_port - $[$i * 10]]
}
##########################################################################
# Description: Print the value for a given config option in an OpenStack
# .ini style configuration file.
@ -558,3 +731,39 @@ if value.startswith('%'): exit(0)
print value
"
}
##########################################################################
# Description: Creates an rc file exporting environment variables to a
# script_path local to the charm's installed directory.
# Any charm scripts run outside the juju hook environment can source this
# scriptrc to obtain updated config information necessary to perform health
# checks or service changes
#
# Parameters:
# An array of '=' delimited ENV_VAR:value combinations to export.
# If optional script_path key is not provided in the array, script_path
# defaults to scripts/scriptrc
##########################################################################
function save_script_rc {
if [ ! -n "$JUJU_UNIT_NAME" ]; then
echo "Error: Missing JUJU_UNIT_NAME environment variable"
exit 1
fi
# our default unit_path
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/scripts/scriptrc"
echo $unit_path
tmp_rc="/tmp/${JUJU_UNIT_NAME/\//-}rc"
echo "#!/bin/bash" > $tmp_rc
for env_var in "${@}"
do
if `echo $env_var | grep -q script_path`; then
# well then we need to reset the new unit-local script path
unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/${env_var/script_path=/}"
else
echo "export $env_var" >> $tmp_rc
fi
done
chmod 755 $tmp_rc
mv $tmp_rc $unit_path
}

@ -95,17 +95,19 @@ function determine_quantum_config {
function configure_quantum_networking {
determine_quantum_config
if [ "$(config-get conf-ext-net)" != "no" ] &&
[ "$QUANTUM_PLUGIN" == "ovs" ] &&
[ -f /etc/quantum/novarc ] &&
[ -n "$(relation-ids amqp)" ] &&
[ -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)
if eligible_leader "res_nova_vip"; then
# 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
set_or_update "default_floating_pool" "$(config-get ext-net-name)"
fi
}
@ -219,3 +221,73 @@ function ssh_compute {
known_hosts="$(base64 /etc/nova/compute_ssh/$sunit/known_hosts)" \
authorized_keys="$(base64 /etc/nova/compute_ssh/$sunit/authorized_keys)"
}
configure_https() {
# setup https termination for all api services, depending on what is running
# and topology of current deployment.
local clustered=""
( [[ -n "$(peer_units)" ]] || is_clustered ) && clustered="1"
local services=""
local ssl_port_maps=""
local haproxy_port_maps=""
local next_server=""
local api_port=""
# upstartService:defaultPort:configOption
local svcs="nova-api-ec2:8773:ec2_listen_port
nova-api-os-compute:8774:osapi_compute_listen_port
nova-objectstore:3333:s3_listen_port"
[[ "$NET_MANAGER" == "Quantum" ]] &&
svcs="$svcs quantum-server:9696:bind_port"
for s in $svcs ; do
local service=$(echo $s | cut -d: -f1)
local port=$(echo $s | cut -d: -f2)
local opt=$(echo $s | cut -d: -f3)
if [[ -n "$clustered" ]] ; then
next_server="$(determine_haproxy_port $port)"
api_port="$(determine_api_port $port)"
haproxy_port_maps="$haproxy_port_maps $service:$next_server:$api_port"
else
api_port="$(determine_api_port $port)"
next_server="$api_port"
fi
if [[ "$service" == "quantum-server" ]] ; then
set_or_update "$opt" "$api_port" "$QUANTUM_CONF"
else
set_or_update "$opt" "$api_port"
fi
ssl_port_maps="$ssl_port_maps $port:$next_server"
done
# make sure all backend api servers are bound to new backend port
# before setting up any frontends.
for s in $svcs ; do
local service=$(echo $s | cut -d: -f1)
service_ctl $service restart
done
[[ -n "$haproxy_port_maps" ]] && configure_haproxy $haproxy_port_maps
setup_https $ssl_port_maps
# another restart to ensure api servers are now bound to frontend ports
# that may have just been disabled.
for s in $svcs ; do
local service=$(echo $s | cut -d: -f1)
service_ctl $service restart
done
local r_id=""
# (re)configure ks endpoint accordingly
for r_id in $(relation-ids identity-service) ; do
keystone_joined "$r_id"
done
# pass on possibly updated quantum URL + ca_cert to compute nodes.
for r_id in $(relation-ids cloud-compute) ; do
compute_joined "$r_id"
done
# update the quantum relation, as well.
for r_id in $(relation-ids quantum-network-service) ; do
quantum_joined "$r_id"
done
}

@ -44,6 +44,7 @@ function install_hook {
cp files/create_tenant_net.py /usr/bin/quantum-tenant-net
service_ctl all stop
configure_https
}
function upgrade_charm {
@ -69,9 +70,7 @@ function config_changed {
set_config_flags
if [ "$NET_MANAGER" == "Quantum" ] && \
is_clustered && is_leader 'res_nova_vip' || \
! is_clustered; then
if [ "$NET_MANAGER" == "Quantum" ]; then
configure_quantum_networking
fi
@ -88,6 +87,7 @@ function config_changed {
'OPENSTACK_SERVICE_OBJECTSTORE=nova-objectstore'
'OPENSTACK_SERVICE_SCHEDULER=nova-scheduler')
save_script_rc ${env_vars[@]}
configure_https
}
function amqp_joined {
@ -142,6 +142,10 @@ function amqp_changed {
fi
determine_services && service_ctl all restart
if [ "$NET_MANAGER" == "Quantum" ]; then
configure_quantum_networking
fi
}
function db_joined {
@ -159,7 +163,7 @@ function db_joined {
}
function db_changed {
local db_host=`relation-get private-address`
local db_host=`relation-get db_host`
local db_password=`relation-get nova_password`
if [[ -z $db_host ]] || [[ -z $db_password ]] ; then
@ -181,11 +185,15 @@ function db_changed {
fi
determine_services
service_ctl all stop
/usr/bin/nova-manage db sync
eligible_leader 'res_nova_vip' && /usr/bin/nova-manage db sync
service_ctl all start
if [ "$NET_MANAGER" == "Quantum" ]; then
configure_quantum_networking
fi
trigger_remote_service_restarts
}
@ -202,28 +210,37 @@ function keystone_joined {
# we need to get two entries into keystone's catalog, nova + ec2
# group, them by prepending $service_ to each setting. the keystone
# charm will assemble settings into corresponding catalog entries
if is_clustered && is_leader 'res_nova_vip'; then
address=$(config-get vip)
nova_port=18774
ec2_port=18773
s3_port=13333
quantum_port=19696
vol_port=18776
elif ! is_clustered; then
address=$(unit-get private-address)
nova_port=8774
ec2_port=8773
s3_port=3333
quantum_port=9696
vol_port=8776
eligible_leader 'res_nova_vip' || return 0
is_clustered && local host=$(config-get vip) ||
local host=$(unit-get private-address)
if [[ "$arg0" == "identity-service-relation-joined" ]] ; then
# determine https status based only on config at this point,
# insepcting KS relation is not reliable. if KS has mulitple
# units, multiple relation-joineds are fired, resulting in the
# endpoint being configured in catalog as https before https
# is actually setup on this end. ends with failure to configure
# quantum network, if its enabled.
# if specified in config, https will have already been setup in
# install or config-changed.
if [[ -n "$(config-get ssl_cert)" ]] &&
[[ -n "$(config-get ssl_key)" ]] ; then
local scheme="https"
else
local scheme="http"
fi
else
# Not the leader and clustered - no action required
return 0
# this function is called from other hook contexts, use normal method
# for determining https
https && scheme="https" || scheme="http"
fi
nova_url="http://$address:$nova_port/v1.1/\$(tenant_id)s"
ec2_url="http://$address:$ec2_port/services/Cloud"
s3_url="http://$address:$s3_port"
region="$(config-get region)"
local nova_url="$scheme://$host:8774/v1.1/\$(tenant_id)s"
local ec2_url="$scheme://$host:8773/services/Cloud"
local s3_url="$scheme://$host:3333"
local region="$(config-get region)"
local quantum_url="$scheme://$host:9696"
# these are the default endpoints
relation-set nova_service="nova" \
@ -243,7 +260,6 @@ function keystone_joined {
s3_internal_url="$s3_url"
if [ "$(config-get network-manager)" == "Quantum" ]; then
quantum_url="http://$address:$quantum_port"
relation-set quantum_service="quantum" \
quantum_region="$region" \
quantum_public_url="$quantum_url" \
@ -253,7 +269,7 @@ function keystone_joined {
# tack on an endpoint for nova-volume a relation exists.
if [[ -n "$(relation-ids nova-volume-service)" ]] ; then
nova_vol_url="http://$address:$vol_port/v1/\$(tenant_id)s"
nova_vol_url="$scheme://$host:$vol_port/v1/\$(tenant_id)s"
relation-set nova-volume_service="nova-volume" \
nova-volume_region="$region" \
nova-volume_public_url="$nova_vol_url" \
@ -292,6 +308,13 @@ function keystone_changed {
sed -i '/--use_deprecated_auth/d' $NOVA_CONF
fi
local clustered=""
is_clustered && clustered="1"
[[ -n "$clustered" ]] && local host=$(config-get vip) ||
local host=$(unit-get private-address)
https && local scheme="https" || local scheme="http"
# update keystone authtoken settings accordingly
set_or_update "service_host" "$service_host" "$API_CONF"
set_or_update "service_port" "$service_port" "$API_CONF"
@ -307,7 +330,7 @@ function keystone_changed {
if [ "$NET_MANAGER" == "Quantum" ]; then
# Configure Nova for quantum
keystone_url="http://${auth_host}:${auth_port}/v2.0"
set_or_update "quantum_url" "http://$(unit-get private-address):9696"
set_or_update "quantum_url" "$scheme://$host:9696"
set_or_update "quantum_admin_tenant_name" "${service_tenant}"
set_or_update "quantum_admin_username" "${service_username}"
set_or_update "quantum_admin_password" "${service_password}"
@ -331,11 +354,13 @@ EOF
determine_services && service_ctl all restart
if [ "$NET_MANAGER" == "Quantum" ]; then
# if first time here, config quantum before setting up
# https.
configure_quantum_networking
# ripple out changes to identity to connected services
# which use cloud-controller as source of information for
# keystone
r_ids="$(relation-ids cloud-compute) $(relation-ids quantum-network-service)"
local r_ids="$(relation-ids cloud-compute) $(relation-ids quantum-network-service)"
for id in $r_ids ; do
relation-set -r $id \
keystone_host=$auth_host \
@ -350,6 +375,14 @@ EOF
done
fi
configure_https
# if this changed event happens as a result of clustered VIP
# reconfigure, configure_https needs to update VIP certificate
# before quantumclient is used.
if [[ "$NET_MANAGER" == "Quantum" ]]; then
configure_quantum_networking
fi
}
volume_joined() {
@ -401,19 +434,19 @@ volume_joined() {
}
compute_joined() {
if is_clustered && ! is_leader 'res_nova_vip'; then
# Clustered and not current leader - do nothing
return 0
fi
relation-set network_manager=$(config-get network-manager)
relation-set ec2_host=$(unit-get private-address)
local r_id="$1"
[[ -n "$r_id" ]] && r_id="-r $r_id"
eligible_leader 'res_nova_vip' || return 0
relation-set $r_id network_manager=$(config-get network-manager)
# XXX Should point to VIP if clustered, or this may not even be needed.
relation-set $r_id ec2_host=$(unit-get private-address)
local sect="filter:authtoken"
keystone_host=$(local_config_get $API_CONF auth_host $sect)
if [ "$NET_MANAGER" == "Quantum" ]; then
if [ -n "$keystone_host" ]; then
relation-set \
if [[ -n "$keystone_host" ]]; then
relation-set $r_id \
keystone_host=$keystone_host \
auth_port=$(local_config_get $API_CONF auth_port $sect) \
service_port=$(local_config_get $API_CONF service_port $sect) \
@ -421,19 +454,24 @@ compute_joined() {
service_password=$(local_config_get $API_CONF admin_password $sect) \
service_tenant=$(local_config_get $API_CONF admin_tenant_name $sect) \
auth_uri=$(local_config_get $API_CONF auth_uri $sect)
fi
if is_clustered; then
quantum_host=$(config-get vip)
quantum_port=19696
else
quantum_host=$(unit-get private-address)
quantum_port=9696
fi
is_clustered && local host=$(config-get vip) ||
local host=$(unit-get private-address)
https && local scheme="https" || local scheme="http"
local quantum_url="$scheme://$host:9696"
relation-set quantum_host=$quantum_host \
quantum_port=$quantum_port \
quantum_plugin=$(config-get quantum-plugin)
relation-set $r_id quantum_url=$quantum_url \
quantum_plugin=$(config-get quantum-plugin) \
region=$(config-get region)
fi
# must pass on the keystone CA certficiate, if it exists.
cert="/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
if [[ -n "$keystone_host" ]] && [[ -e $cert ]] ; then
cert=$(cat $cert | base64)
relation-set $r_id ca_cert="$cert"
fi
# volume driver is dependent on os version, or presence
@ -445,11 +483,10 @@ compute_joined() {
vol_drv="nova-volume"
;;
"folsom")
local r_ids=$(relation-ids cinder-volume-service)
[[ -z "$r_ids" ]] && vol_drv="nova-volume"
[[ -z "$(relation-ids cinder-volume-service)" ]] && vol_drv="nova-volume"
;;
esac
relation-set volume_service="$vol_drv"
relation-set $r_id volume_service="$vol_drv"
}
compute_changed() {
@ -469,15 +506,14 @@ compute_departed() {
function quantum_joined() {
# Tell quantum service about keystone
if is_clustered && ! is_leader 'res_nova_vip'; then
# Clustered and not current leader - do nothing
return 0
fi
eligible_leader || return 0
local r_id="$1"
[[ -n "$r_id" ]] && r_id="-r $r_id"
local sect="filter:authtoken"
keystone_host=$(local_config_get $API_CONF auth_host $sect)
if [ -n "$keystone_host" ]; then
relation-set \
relation-set $r_id \
keystone_host=$keystone_host \
auth_port=$(local_config_get $API_CONF auth_port $sect) \
service_port=$(local_config_get $API_CONF service_port $sect) \
@ -487,24 +523,51 @@ function quantum_joined() {
auth_uri=$(local_config_get $API_CONF auth_uri $sect)
fi
if is_clustered; then
quantum_host=$(config-get vip)
quantum_port=19696
else
quantum_host=$(unit-get private-address)
quantum_port=9696
# must pass on the keystone CA certficiate, if it exists.
cert="/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
if [[ -n "$keystone_host" ]] && [[ -e $cert ]] ; then
cert=$(cat $cert | base64)
relation-set $r_id ca_cert="$cert"
fi
relation-set quantum_host=$quantum_host \
quantum_port=$quantum_port \
quantum_plugin=$(config-get quantum-plugin) \
region=$(config-get region)
is_clustered && local host=$(config-get vip) ||
local host=$(unit-get private-address)
https && local scheme="https" || local scheme="http"
local quantum_url="$scheme://$host:9696"
relation-set $r_id quantum_host="$host" quantum_port="9696" \
quantum_url=$quantum_url \
quantum_plugin=$(config-get quantum-plugin) \
region=$(config-get region)
}
function cluster_changed() {
configure_haproxy "quantum_api:9696" "nova_api:8774" \
"ec2_api:8773" "s3_api:3333" \
"volume_api:8776"
[[ -z "$(peer_units)" ]] &&
juju-log "cluster_changed() with no peers." && exit 0
# upstartService:defaultPort:configOption
local svcs="nova-api-ec2:8773:ec2_listen_port
nova-api-os-compute:8774:osapi_compute_listen_port
nova-objectstore:3333:s3_listen_port"
[[ "$NET_MANAGER" == "Quantum" ]] &&
svcs="$svcs quantum-server:9696:bind_port"
for s in $svcs ; do
local service=$(echo $s | cut -d: -f1)
local port=$(echo $s | cut -d: -f2)
local opt=$(echo $s | cut -d: -f3)
local next_server="$(determine_haproxy_port $port)"
local api_port="$(determine_api_port $port)"
local haproxy_port_maps="$haproxy_port_maps $service:$next_server:$api_port:http"
if [[ "$service" == "quantum-server" ]] ; then
set_or_update "$opt" "$api_port" "$QUANTUM_CONF"
else
set_or_update "$opt" "$api_port"
fi
service_ctl $service restart
done
configure_haproxy $haproxy_port_maps
}
function ha_relation_joined() {
@ -529,13 +592,13 @@ function ha_relation_joined() {
init_services="{
'res_nova_haproxy':'haproxy'
}"
groups="{
'grp_nova_haproxy':'res_nova_vip res_nova_haproxy'
clones="{
'cl_nova_haproxy':'res_nova_haproxy'
}"
relation-set corosync_bindiface=$corosync_bindiface \
corosync_mcastport=$corosync_mcastport \
resources="$resources" resource_params="$resource_params" \
init_services="$init_services" groups="$groups"
init_services="$init_services" clones="$clones"
else
juju-log "Insufficient configuration data to configure hacluster"
exit 1
@ -545,45 +608,58 @@ function ha_relation_joined() {
function ha_relation_changed() {
local clustered=`relation-get clustered`
if [ -n "$clustered" ] && is_leader 'res_nova_vip'; then
https && local scheme="https" || local scheme="http"
for r_id in `relation-ids identity-service`; do
address=$(config-get vip)
nova_url="http://$address:18774/v1.1/\$(tenant_id)s"
ec2_url="http://$address:18773/services/Cloud"
s3_url="http://$address:13333"
local address=$(config-get vip)
local region=$(config-get region)
local nova_url="$scheme://$address:8774/v1.1/\$(tenant_id)s"
local ec2_url="$scheme://$address:8773/services/Cloud"
local s3_url="$scheme://$address:3333"
local quantum_url="$scheme://$address:9696"
local nova_vol_url="$scheme://$address:8776/v1/\$(tenant_id)s"
relation-set -r $r_id \
nova_service="nova" \
nova_region="$region" \
nova_public_url="$nova_url" \
nova_admin_url="$nova_url" \
nova_internal_url="$nova_url" \
ec2_service="ec2" \
ec2_region="$region" \
ec2_public_url="$ec2_url" \
ec2_admin_url="$ec2_url" \
ec2_internal_url="$ec2_url" \
s3_service="s3" \
s3_region="$region" \
s3_public_url="$s3_url" \
s3_admin_url="$s3_url" \
s3_internal_url="$s3_url"
if [ "$(config-get network-manager)" == "Quantum" ]; then
quantum_url="http://$address:19696"
relation-set -r $r_id \
quantum_service="quantum" \
quantum_region="$region" \
quantum_public_url="$quantum_url" \
quantum_admin_url="$quantum_url" \
quantum_internal_url="$quantum_url"
fi
if [[ -n "$(relation-ids nova-volume-service)" ]] ; then
nova_vol_url="http://$address:18776/v1/\$(tenant_id)s"
relation-set -r $r_id \
nova-volume_service="nova-volume" \
nova-volume_region="$region" \
nova-volume_public_url="$nova_vol_url" \
nova-volume_admin_url="$nova_vol_url" \
nova-volume_internal_url="$nova_vol_url"
fi
done
if [ "$(config-get network-manager)" == "Quantum" ]; then
# Let gateway nodes use the new HA address for the
# Let gateway nodes use the new HA address for the
# quantum API server
for r_id in `relation-ids quantum-network-service`; do
relation-set -r $r_id \
quantum_host=$address
quantum_port=19696
quantum_host="$address" quantum_port="9696" \
quantum_url="$quantum_url" region="$region"
done
fi
fi

@ -1 +1 @@
216
239