Merge lp:~chad.smith/charms/precise/openstack-dashboard/openstack-dashboard-internal-port-health-update into lp:~charmers/charms/precise/openstack-dashboard/trunk

Proposed by Chad Smith
Status: Superseded
Proposed branch: lp:~chad.smith/charms/precise/openstack-dashboard/openstack-dashboard-internal-port-health-update
Merge into: lp:~charmers/charms/precise/openstack-dashboard/trunk
Diff against target: 887 lines (+703/-22)
11 files modified
config.yaml (+55/-7)
hooks/horizon-common (+49/-8)
hooks/horizon-relations (+90/-3)
hooks/lib/openstack-common (+456/-3)
metadata.yaml (+6/-0)
revision (+1/-1)
scripts/add_to_cluster (+2/-0)
scripts/health_checks.d/service_ports_live (+13/-0)
scripts/health_checks.d/service_running (+13/-0)
scripts/health_checks.d/service_url_checks (+16/-0)
scripts/remove_from_cluster (+2/-0)
To merge this branch: bzr merge lp:~chad.smith/charms/precise/openstack-dashboard/openstack-dashboard-internal-port-health-update
Reviewer Review Type Date Requested Status
Adam Gandelman Pending
Review via email: mp+155775@code.launchpad.net

Description of the change

Update health script to use the new internal service port numbers 70 and 433 as they have been updated in the rest of the charm for new HA configuration.

To post a comment you must log in.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'config.yaml'
2--- config.yaml 2013-01-11 21:59:22 +0000
3+++ config.yaml 2013-03-27 15:50:37 +0000
4@@ -1,5 +1,5 @@
5 options:
6- openstack-origin:
7+ openstack-origin:
8 default: distro
9 type: string
10 description: |
11@@ -14,15 +14,63 @@
12 Note that updating this setting to a source that is known to
13 provide a later version of OpenStack will trigger a software
14 upgrade.
15- webroot:
16+ webroot:
17 default: "/horizon"
18 type: string
19 description: |
20- Directory where application will be accessible, relative to
21- http://$hostname/.
22- default-role:
23+ Directory where application will be accessible, relative to
24+ http://$hostname/.
25+ default-role:
26 default: "Member"
27 type: string
28 description: |
29- Default role for Horizon operations that will be created in
30- Keystone upon introduction of an identity-service relation.
31+ Default role for Horizon operations that will be created in
32+ Keystone upon introduction of an identity-service relation.
33+ vip:
34+ type: string
35+ description: "Virtual IP to use to front openstack dashboard ha configuration"
36+ vip_iface:
37+ type: string
38+ default: eth0
39+ description: "Network Interface where to place the Virtual IP"
40+ vip_cidr:
41+ type: int
42+ default: 24
43+ description: "Netmask that will be used for the Virtual IP"
44+ ha-bindiface:
45+ type: string
46+ default: eth0
47+ description: |
48+ Default network interface on which HA cluster will bind to communication
49+ with the other members of the HA Cluster.
50+ ha-mcastport:
51+ type: int
52+ default: 5410
53+ description: |
54+ Default multicast port number that will be used to communicate between
55+ HA Cluster nodes.
56+ # User provided SSL cert and key
57+ ssl_cert:
58+ type: string
59+ description: |
60+ Base64 encoded SSL certificate to install and use for API ports.
61+ .
62+ juju set swift-proxy ssl_cert="$(cat cert | base64)" \
63+ ssl_key="$(cat key | base64)"
64+ .
65+ Setting this value (and ssl_key) will enable reverse proxying, point
66+ Swifts's entry in the Keystone catalog to use https, and override
67+ any certficiate and key issued by Keystone (if it is configured to
68+ do so).
69+ ssl_key:
70+ type: string
71+ description: |
72+ Base64 encoded SSL key to use with certificate specified as ssl_cert.
73+ offline-compression:
74+ type: string
75+ default: "yes"
76+ description: Use pre-generated Less compiled JS and CSS.
77+ debug:
78+ type: string
79+ default: "no"
80+ description: Show Django debug messages.
81
82=== added symlink 'hooks/cluster-relation-changed'
83=== target is u'horizon-relations'
84=== added symlink 'hooks/cluster-relation-departed'
85=== target is u'horizon-relations'
86=== added symlink 'hooks/ha-relation-changed'
87=== target is u'horizon-relations'
88=== added symlink 'hooks/ha-relation-joined'
89=== target is u'horizon-relations'
90=== modified file 'hooks/horizon-common'
91--- hooks/horizon-common 2012-10-10 23:32:24 +0000
92+++ hooks/horizon-common 2013-03-27 15:50:37 +0000
93@@ -1,8 +1,9 @@
94 #!/bin/bash
95+# vim: set ts=2:et
96
97 CHARM="openstack-dashboard"
98
99-PACKAGES="openstack-dashboard openstack-dashboard-ubuntu-theme python-keystoneclient python-memcache memcached"
100+PACKAGES="openstack-dashboard openstack-dashboard-ubuntu-theme python-keystoneclient python-memcache memcached haproxy"
101 LOCAL_SETTINGS="/etc/openstack-dashboard/local_settings.py"
102
103 if [[ -e "$CHARM_DIR/lib/openstack-common" ]] ; then
104@@ -16,15 +17,28 @@
105 local key=$1 value=$2
106 [[ -z "$key" ]] || [[ -z "$value" ]] &&
107 juju-log "$CHARM set_or_update: ERROR - missing parameters" && return 1
108- grep -q "^$key = \"$value\"" "$LOCAL_SETTINGS" &&
109- juju-log "$CHARM set_or_update: $key = $value already set" && return 0
110+ if [ "$value" == "True" ] || [ "$value" == "False" ]; then
111+ grep -q "^$key = $value" "$LOCAL_SETTINGS" &&
112+ juju-log "$CHARM set_or_update: $key = $value already set" && return 0
113+ else
114+ grep -q "^$key = \"$value\"" "$LOCAL_SETTINGS" &&
115+ juju-log "$CHARM set_or_update: $key = $value already set" && return 0
116+ fi
117 if grep -q "^$key = " "$LOCAL_SETTINGS" ; then
118 juju-log "$CHARM set_or_update: Setting $key = $value"
119 cp "$LOCAL_SETTINGS" /etc/openstack-dashboard/local_settings.last
120- sed -i "s|\(^$key = \).*|\1\"$value\"|g" "$LOCAL_SETTINGS" || return 1
121+ if [ "$value" == "True" ] || [ "$value" == "False" ]; then
122+ sed -i "s|\(^$key = \).*|\1$value|g" "$LOCAL_SETTINGS" || return 1
123+ else
124+ sed -i "s|\(^$key = \).*|\1\"$value\"|g" "$LOCAL_SETTINGS" || return 1
125+ fi
126 else
127 juju-log "$CHARM set_or_update: Adding $key = $value"
128- echo "$key = \"$value\"" >>$LOCAL_SETTINGS || return 1
129+ if [ "$value" == "True" ] || [ "$value" == "False" ]; then
130+ echo "$key = $value" >>$LOCAL_SETTINGS || return 1
131+ else
132+ echo "$key = \"$value\"" >>$LOCAL_SETTINGS || return 1
133+ fi
134 fi
135 return 0
136 }
137@@ -46,10 +60,37 @@
138 export JUJU_REMOTE_UNIT=$(relation-list -r $r_id | head -n1)
139 export JUJU_RELATION="identity-service"
140 export JUJU_RELATION_ID="$r_id"
141- local ks_host=$(relation-get -r $r_id private-address)
142- if [[ -n "$ks_host" ]] ; then
143- service_url="http://$ks_host:5000/v2.0"
144+ local service_host=$(relation-get -r $r_id service_host)
145+ local service_port=$(relation-get -r $r_id service_port)
146+ if [[ -n "$service_host" ]] && [[ -n "$service_port" ]] ; then
147+ service_url="http://$service_host:$service_port/v2.0"
148 set_or_update OPENSTACK_KEYSTONE_URL "$service_url"
149 fi
150 fi
151 }
152+
153+configure_apache() {
154+ # Reconfigure to listen on provided port
155+ a2ensite default-ssl || :
156+ a2enmod ssl || :
157+ for ports in $@; do
158+ from_port=$(echo $ports | cut -d : -f 1)
159+ to_port=$(echo $ports | cut -d : -f 2)
160+ sed -i -e "s/$from_port/$to_port/g" /etc/apache2/ports.conf
161+ for site in $(ls -1 /etc/apache2/sites-available); do
162+ sed -i -e "s/$from_port/$to_port/g" \
163+ /etc/apache2/sites-available/$site
164+ done
165+ done
166+}
167+
168+configure_apache_cert() {
169+ cert=$1
170+ key=$2
171+ echo $cert | base64 -di > /etc/ssl/certs/dashboard.cert
172+ echo $key | base64 -di > /etc/ssl/private/dashboard.key
173+ chmod 0600 /etc/ssl/private/dashboard.key
174+ sed -i -e "s|\(.*SSLCertificateFile\).*|\1 /etc/ssl/certs/dashboard.cert|g" \
175+ -e "s|\(.*SSLCertificateKeyFile\).*|\1 /etc/ssl/private/dashboard.key|g" \
176+ /etc/apache2/sites-available/default-ssl
177+}
178
179=== modified file 'hooks/horizon-relations'
180--- hooks/horizon-relations 2013-01-11 21:59:22 +0000
181+++ hooks/horizon-relations 2013-03-27 15:50:37 +0000
182@@ -44,7 +44,19 @@
183 }
184
185 function keystone_changed {
186- service_url="http://$(relation-get private-address):5000/v2.0"
187+ local service_host=$(relation-get service_host)
188+ local service_port=$(relation-get service_port)
189+ if [ -z "${service_host}" ] || [ -z "${service_port}" ]; then
190+ juju-log "Insufficient information to configure keystone url"
191+ exit 0
192+ fi
193+ local ca_cert=$(relation-get ca_cert)
194+ if [ -n "$ca_cert" ]; then
195+ juju-log "Installing Keystone supplied CA cert."
196+ echo $ca_cert | base64 -di > /usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
197+ update-ca-certificates --fresh
198+ fi
199+ service_url="http://${service_host}:${service_port}/v2.0"
200 juju-log "$CHARM: Configuring Horizon to access keystone @ $service_url."
201 set_or_update OPENSTACK_KEYSTONE_URL "$service_url"
202 service apache2 restart
203@@ -73,6 +85,15 @@
204 set_or_update LOGIN_URL "$web_root/auth/login"
205 set_or_update LOGIN_REDIRECT_URL "$web_root"
206
207+ # Save our scriptrc env variables for health checks
208+ declare -a env_vars=(
209+ 'OPENSTACK_URL_HORIZON="http://localhost:70'$web_root'|Login+-+OpenStack"'
210+ 'OPENSTACK_SERVICE_HORIZON=apache2'
211+ 'OPENSTACK_PORT_HORIZON_SSL=433'
212+ 'OPENSTACK_PORT_HORIZON=70')
213+ save_script_rc ${env_vars[@]}
214+
215+
216 # Set default role and trigger a identity-service relation event to
217 # ensure role is created in keystone.
218 set_or_update OPENSTACK_KEYSTONE_DEFAULT_ROLE "$(config-get default-role)"
219@@ -81,8 +102,71 @@
220 keystone_joined "$relid"
221 done
222
223- service apache2 reload
224-
225+ if [ "$(config-get offline-compression)" != "yes" ]; then
226+ set_or_update COMPRESS_OFFLINE False
227+ apt-get install -y nodejs node-less
228+ else
229+ set_or_update COMPRESS_OFFLINE True
230+ fi
231+
232+ # Configure default HAProxy + Apache config
233+ if [ -n "$(config-get ssl_cert)" ] && \
234+ [ -n "$(config-get ssl_key)" ]; then
235+ configure_apache_cert "$(config-get ssl_cert)" "$(config-get ssl_key)"
236+ fi
237+
238+ if [ "$(config-get debug)" != "yes" ]; then
239+ set_or_update DEBUG False
240+ else
241+ set_or_update DEBUG True
242+ fi
243+
244+ # Reconfigure Apache Ports
245+ configure_apache "80:70" "443:433"
246+ service apache2 restart
247+ configure_haproxy "dash_insecure:80:70:http dash_secure:443:433:tcp"
248+ service haproxy restart
249+}
250+
251+function cluster_changed() {
252+ configure_haproxy "dash_insecure:80:70:http dash_secure:443:433:tcp"
253+ service haproxy reload
254+}
255+
256+function ha_relation_joined() {
257+ # Configure HA Cluster
258+ local corosync_bindiface=`config-get ha-bindiface`
259+ local corosync_mcastport=`config-get ha-mcastport`
260+ local vip=`config-get vip`
261+ local vip_iface=`config-get vip_iface`
262+ local vip_cidr=`config-get vip_cidr`
263+ if [ -n "$vip" ] && [ -n "$vip_iface" ] && \
264+ [ -n "$vip_cidr" ] && [ -n "$corosync_bindiface" ] && \
265+ [ -n "$corosync_mcastport" ]; then
266+ # TODO: This feels horrible but the data required by the hacluster
267+ # charm is quite complex and is python ast parsed.
268+ resources="{
269+'res_horizon_vip':'ocf:heartbeat:IPaddr2',
270+'res_horizon_haproxy':'lsb:haproxy'
271+}"
272+ resource_params="{
273+'res_horizon_vip': 'params ip=\"$vip\" cidr_netmask=\"$vip_cidr\" nic=\"$vip_iface\"',
274+'res_horizon_haproxy': 'op monitor interval=\"5s\"'
275+}"
276+ init_services="{
277+'res_horizon_haproxy':'haproxy'
278+}"
279+ clones="{
280+'cl_horizon_haproxy':'res_horizon_haproxy'
281+}"
282+ relation-set corosync_bindiface=$corosync_bindiface \
283+ corosync_mcastport=$corosync_mcastport \
284+ resources="$resources" resource_params="$resource_params" \
285+ init_services="$init_services" clones="$clones"
286+ else
287+ juju-log "Insufficient configuration data to configure hacluster"
288+ exit 1
289+ fi
290 }
291
292 juju-log "$CHARM: Running hook $ARG0."
293@@ -95,4 +179,7 @@
294 "identity-service-relation-joined") keystone_joined;;
295 "identity-service-relation-changed") keystone_changed;;
296 "config-changed") config_changed;;
297+ "cluster-relation-changed") cluster_changed ;;
298+ "cluster-relation-departed") cluster_changed ;;
299+ "ha-relation-joined") ha_relation_joined ;;
300 esac
301
302=== modified file 'hooks/lib/openstack-common'
303--- hooks/lib/openstack-common 2013-01-11 18:30:45 +0000
304+++ hooks/lib/openstack-common 2013-03-27 15:50:37 +0000
305@@ -165,8 +165,9 @@
306 fi
307
308 # have a guess based on the deb string provided
309- if [[ "${rel:0:3}" == "deb" ]]; then
310- CODENAMES="diablo essex folsom grizzly"
311+ if [[ "${rel:0:3}" == "deb" ]] || \
312+ [[ "${rel:0:3}" == "ppa" ]] ; then
313+ CODENAMES="diablo essex folsom grizzly havana"
314 for cname in $CODENAMES; do
315 if echo $rel | grep -q $cname; then
316 codename=$cname
317@@ -178,11 +179,13 @@
318
319 get_os_codename_package() {
320 local pkg_vers=$(dpkg -l | grep "$1" | awk '{ print $3 }') || echo "none"
321+ pkg_vers=$(echo $pkg_vers | cut -d: -f2) # epochs
322 case "${pkg_vers:0:6}" in
323 "2011.2") echo "diablo" ;;
324 "2012.1") echo "essex" ;;
325 "2012.2") echo "folsom" ;;
326 "2013.1") echo "grizzly" ;;
327+ "2013.2") echo "havana" ;;
328 esac
329 }
330
331@@ -191,7 +194,8 @@
332 "diablo") echo "2011.2" ;;
333 "essex") echo "2012.1" ;;
334 "folsom") echo "2012.2" ;;
335- "grizzly") echo "2012.3" ;;
336+ "grizzly") echo "2013.1" ;;
337+ "havana") echo "2013.2" ;;
338 esac
339 }
340
341@@ -314,3 +318,452 @@
342 echo "$found"
343 return 0
344 }
345+
346+HAPROXY_CFG=/etc/haproxy/haproxy.cfg
347+HAPROXY_DEFAULT=/etc/default/haproxy
348+##########################################################################
349+# Description: Configures HAProxy services for Openstack API's
350+# Parameters:
351+# Space delimited list of service:port:mode combinations for which
352+# haproxy service configuration should be generated for. The function
353+# assumes the name of the peer relation is 'cluster' and that every
354+# service unit in the peer relation is running the same services.
355+#
356+# Services that do not specify :mode in parameter will default to http.
357+#
358+# Example
359+# configure_haproxy cinder_api:8776:8756:tcp nova_api:8774:8764:http
360+##########################################################################
361+configure_haproxy() {
362+ local address=`unit-get private-address`
363+ local name=${JUJU_UNIT_NAME////-}
364+ cat > $HAPROXY_CFG << EOF
365+global
366+ log 127.0.0.1 local0
367+ log 127.0.0.1 local1 notice
368+ maxconn 20000
369+ user haproxy
370+ group haproxy
371+ spread-checks 0
372+
373+defaults
374+ log global
375+ mode http
376+ option httplog
377+ option dontlognull
378+ retries 3
379+ timeout queue 1000
380+ timeout connect 1000
381+ timeout client 30000
382+ timeout server 30000
383+
384+listen stats :8888
385+ mode http
386+ stats enable
387+ stats hide-version
388+ stats realm Haproxy\ Statistics
389+ stats uri /
390+ stats auth admin:password
391+
392+EOF
393+ for service in $@; do
394+ local service_name=$(echo $service | cut -d : -f 1)
395+ local haproxy_listen_port=$(echo $service | cut -d : -f 2)
396+ local api_listen_port=$(echo $service | cut -d : -f 3)
397+ local mode=$(echo $service | cut -d : -f 4)
398+ [[ -z "$mode" ]] && mode="http"
399+ juju-log "Adding haproxy configuration entry for $service "\
400+ "($haproxy_listen_port -> $api_listen_port)"
401+ cat >> $HAPROXY_CFG << EOF
402+listen $service_name 0.0.0.0:$haproxy_listen_port
403+ balance roundrobin
404+ mode $mode
405+ option ${mode}log
406+ server $name $address:$api_listen_port check
407+EOF
408+ local r_id=""
409+ local unit=""
410+ for r_id in `relation-ids cluster`; do
411+ for unit in `relation-list -r $r_id`; do
412+ local unit_name=${unit////-}
413+ local unit_address=`relation-get -r $r_id private-address $unit`
414+ if [ -n "$unit_address" ]; then
415+ echo " server $unit_name $unit_address:$api_listen_port check" \
416+ >> $HAPROXY_CFG
417+ fi
418+ done
419+ done
420+ done
421+ echo "ENABLED=1" > $HAPROXY_DEFAULT
422+ service haproxy restart
423+}
424+
425+##########################################################################
426+# Description: Query HA interface to determine is cluster is configured
427+# Returns: 0 if configured, 1 if not configured
428+##########################################################################
429+is_clustered() {
430+ local r_id=""
431+ local unit=""
432+ for r_id in $(relation-ids ha); do
433+ if [ -n "$r_id" ]; then
434+ for unit in $(relation-list -r $r_id); do
435+ clustered=$(relation-get -r $r_id clustered $unit)
436+ if [ -n "$clustered" ]; then
437+ juju-log "Unit is haclustered"
438+ return 0
439+ fi
440+ done
441+ fi
442+ done
443+ juju-log "Unit is not haclustered"
444+ return 1
445+}
446+
447+##########################################################################
448+# Description: Return a list of all peers in cluster relations
449+##########################################################################
450+peer_units() {
451+ local peers=""
452+ local r_id=""
453+ for r_id in $(relation-ids cluster); do
454+ peers="$peers $(relation-list -r $r_id)"
455+ done
456+ echo $peers
457+}
458+
459+##########################################################################
460+# Description: Determines whether the current unit is the oldest of all
461+# its peers - supports partial leader election
462+# Returns: 0 if oldest, 1 if not
463+##########################################################################
464+oldest_peer() {
465+ peers=$1
466+ local l_unit_no=$(echo $JUJU_UNIT_NAME | cut -d / -f 2)
467+ for peer in $peers; do
468+ echo "Comparing $JUJU_UNIT_NAME with peers: $peers"
469+ local r_unit_no=$(echo $peer | cut -d / -f 2)
470+ if (($r_unit_no<$l_unit_no)); then
471+ juju-log "Not oldest peer; deferring"
472+ return 1
473+ fi
474+ done
475+ juju-log "Oldest peer; might take charge?"
476+ return 0
477+}
478+
479+##########################################################################
480+# Description: Determines whether the current service units is the
481+# leader within a) a cluster of its peers or b) across a
482+# set of unclustered peers.
483+# Parameters: CRM resource to check ownership of if clustered
484+# Returns: 0 if leader, 1 if not
485+##########################################################################
486+eligible_leader() {
487+ if is_clustered; then
488+ if ! is_leader $1; then
489+ juju-log 'Deferring action to CRM leader'
490+ return 1
491+ fi
492+ else
493+ peers=$(peer_units)
494+ if [ -n "$peers" ] && ! oldest_peer "$peers"; then
495+ juju-log 'Deferring action to oldest service unit.'
496+ return 1
497+ fi
498+ fi
499+ return 0
500+}
501+
502+##########################################################################
503+# Description: Query Cluster peer interface to see if peered
504+# Returns: 0 if peered, 1 if not peered
505+##########################################################################
506+is_peered() {
507+ local r_id=$(relation-ids cluster)
508+ if [ -n "$r_id" ]; then
509+ if [ -n "$(relation-list -r $r_id)" ]; then
510+ juju-log "Unit peered"
511+ return 0
512+ fi
513+ fi
514+ juju-log "Unit not peered"
515+ return 1
516+}
517+
518+##########################################################################
519+# Description: Determines whether host is owner of clustered services
520+# Parameters: Name of CRM resource to check ownership of
521+# Returns: 0 if leader, 1 if not leader
522+##########################################################################
523+is_leader() {
524+ hostname=`hostname`
525+ if [ -x /usr/sbin/crm ]; then
526+ if crm resource show $1 | grep -q $hostname; then
527+ juju-log "$hostname is cluster leader."
528+ return 0
529+ fi
530+ fi
531+ juju-log "$hostname is not cluster leader."
532+ return 1
533+}
534+
535+##########################################################################
536+# Description: Determines whether enough data has been provided in
537+# configuration or relation data to configure HTTPS.
538+# Parameters: None
539+# Returns: 0 if HTTPS can be configured, 1 if not.
540+##########################################################################
541+https() {
542+ local r_id=""
543+ if [[ -n "$(config-get ssl_cert)" ]] &&
544+ [[ -n "$(config-get ssl_key)" ]] ; then
545+ return 0
546+ fi
547+ for r_id in $(relation-ids identity-service) ; do
548+ for unit in $(relation-list -r $r_id) ; do
549+ if [[ "$(relation-get -r $r_id https_keystone $unit)" == "True" ]] &&
550+ [[ -n "$(relation-get -r $r_id ssl_cert $unit)" ]] &&
551+ [[ -n "$(relation-get -r $r_id ssl_key $unit)" ]] &&
552+ [[ -n "$(relation-get -r $r_id ca_cert $unit)" ]] ; then
553+ return 0
554+ fi
555+ done
556+ done
557+ return 1
558+}
559+
560+##########################################################################
561+# Description: For a given number of port mappings, configures apache2
562+# HTTPs local reverse proxying using certficates and keys provided in
563+# either configuration data (preferred) or relation data. Assumes ports
564+# are not in use (calling charm should ensure that).
565+# Parameters: Variable number of proxy port mappings as
566+# $internal:$external.
567+# Returns: 0 if reverse proxy(s) have been configured, 0 if not.
568+##########################################################################
569+enable_https() {
570+ local port_maps="$@"
571+ local http_restart=""
572+ juju-log "Enabling HTTPS for port mappings: $port_maps."
573+
574+ # allow overriding of keystone provided certs with those set manually
575+ # in config.
576+ local cert=$(config-get ssl_cert)
577+ local key=$(config-get ssl_key)
578+ local ca_cert=""
579+ if [[ -z "$cert" ]] || [[ -z "$key" ]] ; then
580+ juju-log "Inspecting identity-service relations for SSL certificate."
581+ local r_id=""
582+ cert=""
583+ key=""
584+ ca_cert=""
585+ for r_id in $(relation-ids identity-service) ; do
586+ for unit in $(relation-list -r $r_id) ; do
587+ [[ -z "$cert" ]] && cert="$(relation-get -r $r_id ssl_cert $unit)"
588+ [[ -z "$key" ]] && key="$(relation-get -r $r_id ssl_key $unit)"
589+ [[ -z "$ca_cert" ]] && ca_cert="$(relation-get -r $r_id ca_cert $unit)"
590+ done
591+ done
592+ [[ -n "$cert" ]] && cert=$(echo $cert | base64 -di)
593+ [[ -n "$key" ]] && key=$(echo $key | base64 -di)
594+ [[ -n "$ca_cert" ]] && ca_cert=$(echo $ca_cert | base64 -di)
595+ else
596+ juju-log "Using SSL certificate provided in service config."
597+ fi
598+
599+ [[ -z "$cert" ]] || [[ -z "$key" ]] &&
600+ juju-log "Expected but could not find SSL certificate data, not "\
601+ "configuring HTTPS!" && return 1
602+
603+ apt-get -y install apache2
604+ a2enmod ssl proxy proxy_http | grep -v "To activate the new configuration" &&
605+ http_restart=1
606+
607+ mkdir -p /etc/apache2/ssl/$CHARM
608+ echo "$cert" >/etc/apache2/ssl/$CHARM/cert
609+ echo "$key" >/etc/apache2/ssl/$CHARM/key
610+ if [[ -n "$ca_cert" ]] ; then
611+ juju-log "Installing Keystone supplied CA cert."
612+ echo "$ca_cert" >/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
613+ update-ca-certificates --fresh
614+
615+ # XXX TODO: Find a better way of exporting this?
616+ if [[ "$CHARM" == "nova-cloud-controller" ]] ; then
617+ [[ -e /var/www/keystone_juju_ca_cert.crt ]] &&
618+ rm -rf /var/www/keystone_juju_ca_cert.crt
619+ ln -s /usr/local/share/ca-certificates/keystone_juju_ca_cert.crt \
620+ /var/www/keystone_juju_ca_cert.crt
621+ fi
622+
623+ fi
624+ for port_map in $port_maps ; do
625+ local ext_port=$(echo $port_map | cut -d: -f1)
626+ local int_port=$(echo $port_map | cut -d: -f2)
627+ juju-log "Creating apache2 reverse proxy vhost for $port_map."
628+ cat >/etc/apache2/sites-available/${CHARM}_${ext_port} <<END
629+Listen $ext_port
630+NameVirtualHost *:$ext_port
631+<VirtualHost *:$ext_port>
632+ ServerName $(unit-get private-address)
633+ SSLEngine on
634+ SSLCertificateFile /etc/apache2/ssl/$CHARM/cert
635+ SSLCertificateKeyFile /etc/apache2/ssl/$CHARM/key
636+ ProxyPass / http://localhost:$int_port/
637+ ProxyPassReverse / http://localhost:$int_port/
638+ ProxyPreserveHost on
639+</VirtualHost>
640+<Proxy *>
641+ Order deny,allow
642+ Allow from all
643+</Proxy>
644+<Location />
645+ Order allow,deny
646+ Allow from all
647+</Location>
648+END
649+ a2ensite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
650+ http_restart=1
651+ done
652+ if [[ -n "$http_restart" ]] ; then
653+ service apache2 restart
654+ fi
655+}
656+
657+##########################################################################
658+# Description: Ensure HTTPS reverse proxying is disabled for given port
659+# mappings.
660+# Parameters: Variable number of proxy port mappings as
661+# $internal:$external.
662+# Returns: 0 if reverse proxy is not active for all portmaps, 1 on error.
663+##########################################################################
664+disable_https() {
665+ local port_maps="$@"
666+ local http_restart=""
667+ juju-log "Ensuring HTTPS disabled for $port_maps."
668+ ( [[ ! -d /etc/apache2 ]] || [[ ! -d /etc/apache2/ssl/$CHARM ]] ) && return 0
669+ for port_map in $port_maps ; do
670+ local ext_port=$(echo $port_map | cut -d: -f1)
671+ local int_port=$(echo $port_map | cut -d: -f2)
672+ if [[ -e /etc/apache2/sites-available/${CHARM}_${ext_port} ]] ; then
673+ juju-log "Disabling HTTPS reverse proxy for $CHARM $port_map."
674+ a2dissite ${CHARM}_${ext_port} | grep -v "To activate the new configuration" &&
675+ http_restart=1
676+ fi
677+ done
678+ if [[ -n "$http_restart" ]] ; then
679+ service apache2 restart
680+ fi
681+}
682+
683+
684+##########################################################################
685+# Description: Ensures HTTPS is either enabled or disabled for given port
686+# mapping.
687+# Parameters: Variable number of proxy port mappings as
688+# $internal:$external.
689+# Returns: 0 if HTTPS reverse proxy is in place, 1 if it is not.
690+##########################################################################
691+setup_https() {
692+ # configure https via apache reverse proxying either
693+ # using certs provided by config or keystone.
694+ [[ -z "$CHARM" ]] &&
695+ error_out "setup_https(): CHARM not set."
696+ if ! https ; then
697+ disable_https $@
698+ else
699+ enable_https $@
700+ fi
701+}
702+
703+##########################################################################
704+# Description: Determine correct API server listening port based on
705+# existence of HTTPS reverse proxy and/or haproxy.
706+# Paremeters: The standard public port for given service.
707+# Returns: The correct listening port for API service.
708+##########################################################################
709+determine_api_port() {
710+ local public_port="$1"
711+ local i=0
712+ ( [[ -n "$(peer_units)" ]] || is_clustered >/dev/null 2>&1 ) && i=$[$i + 1]
713+ https >/dev/null 2>&1 && i=$[$i + 1]
714+ echo $[$public_port - $[$i * 10]]
715+}
716+
717+##########################################################################
718+# Description: Determine correct proxy listening port based on public IP +
719+# existence of HTTPS reverse proxy.
720+# Paremeters: The standard public port for given service.
721+# Returns: The correct listening port for haproxy service public address.
722+##########################################################################
723+determine_haproxy_port() {
724+ local public_port="$1"
725+ local i=0
726+ https >/dev/null 2>&1 && i=$[$i + 1]
727+ echo $[$public_port - $[$i * 10]]
728+}
729+
730+##########################################################################
731+# Description: Print the value for a given config option in an OpenStack
732+# .ini style configuration file.
733+# Parameters: File path, option to retrieve, optional
734+# section name (default=DEFAULT)
735+# Returns: Prints value if set, prints nothing otherwise.
736+##########################################################################
737+local_config_get() {
738+ # return config values set in openstack .ini config files.
739+ # default placeholders starting (eg, %AUTH_HOST%) treated as
740+ # unset values.
741+ local file="$1"
742+ local option="$2"
743+ local section="$3"
744+ [[ -z "$section" ]] && section="DEFAULT"
745+ python -c "
746+import ConfigParser
747+config = ConfigParser.RawConfigParser()
748+config.read('$file')
749+try:
750+ value = config.get('$section', '$option')
751+except:
752+ print ''
753+ exit(0)
754+if value.startswith('%'): exit(0)
755+print value
756+"
757+}
758+
759+##########################################################################
760+# Description: Creates an rc file exporting environment variables to a
761+# script_path local to the charm's installed directory.
762+# Any charm scripts run outside the juju hook environment can source this
763+# scriptrc to obtain updated config information necessary to perform health
764+# checks or service changes
765+#
766+# Parameters:
767+# An array of '=' delimited ENV_VAR:value combinations to export.
768+# If optional script_path key is not provided in the array, script_path
769+# defaults to scripts/scriptrc
770+##########################################################################
771+function save_script_rc {
772+ if [ ! -n "$JUJU_UNIT_NAME" ]; then
773+ echo "Error: Missing JUJU_UNIT_NAME environment variable"
774+ exit 1
775+ fi
776+ # our default unit_path
777+ unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/scripts/scriptrc"
778+ echo $unit_path
779+ tmp_rc="/tmp/${JUJU_UNIT_NAME/\//-}rc"
780+
781+ echo "#!/bin/bash" > $tmp_rc
782+ for env_var in "${@}"
783+ do
784+ if `echo $env_var | grep -q script_path`; then
785+ # well then we need to reset the new unit-local script path
786+ unit_path="/var/lib/juju/units/${JUJU_UNIT_NAME/\//-}/charm/${env_var/script_path=/}"
787+ else
788+ echo "export $env_var" >> $tmp_rc
789+ fi
790+ done
791+ chmod 755 $tmp_rc
792+ mv $tmp_rc $unit_path
793+}
794
795=== modified file 'metadata.yaml'
796--- metadata.yaml 2012-08-09 20:29:51 +0000
797+++ metadata.yaml 2013-03-27 15:50:37 +0000
798@@ -8,3 +8,9 @@
799 interface: mysql
800 identity-service:
801 interface: keystone
802+ ha:
803+ interface: hacluster
804+ scope: container
805+peers:
806+ cluster:
807+ interface: openstack-dashboard-ha
808
809=== modified file 'revision'
810--- revision 2013-01-11 21:59:22 +0000
811+++ revision 2013-03-27 15:50:37 +0000
812@@ -1,1 +1,1 @@
813-22
814+27
815
816=== added directory 'scripts'
817=== added file 'scripts/add_to_cluster'
818--- scripts/add_to_cluster 1970-01-01 00:00:00 +0000
819+++ scripts/add_to_cluster 2013-03-27 15:50:37 +0000
820@@ -0,0 +1,2 @@
821+#!/bin/bash
822+crm node online
823
824=== added directory 'scripts/health_checks.d'
825=== added file 'scripts/health_checks.d/service_ports_live'
826--- scripts/health_checks.d/service_ports_live 1970-01-01 00:00:00 +0000
827+++ scripts/health_checks.d/service_ports_live 2013-03-27 15:50:37 +0000
828@@ -0,0 +1,13 @@
829+#!/bin/bash
830+# Validate that service ports are active
831+HEALTH_DIR=`dirname $0`
832+SCRIPTS_DIR=`dirname $HEALTH_DIR`
833+. $SCRIPTS_DIR/scriptrc
834+set -e
835+
836+# Grab any OPENSTACK_PORT* environment variables
837+openstack_ports=`env| awk -F '=' '(/OPENSTACK_PORT/){print $2}'`
838+for port in $openstack_ports
839+do
840+ netstat -ln | grep -q ":$port "
841+done
842
843=== added file 'scripts/health_checks.d/service_running'
844--- scripts/health_checks.d/service_running 1970-01-01 00:00:00 +0000
845+++ scripts/health_checks.d/service_running 2013-03-27 15:50:37 +0000
846@@ -0,0 +1,13 @@
847+#!/bin/bash
848+# Validate that service is running
849+HEALTH_DIR=`dirname $0`
850+SCRIPTS_DIR=`dirname $HEALTH_DIR`
851+. $SCRIPTS_DIR/scriptrc
852+set -e
853+
854+# Grab any OPENSTACK_SERVICE* environment variables
855+openstack_service_names=`env| awk -F '=' '(/OPENSTACK_SERVICE/){print $2}'`
856+for service_name in $openstack_service_names
857+do
858+ service $service_name status 2>/dev/null | grep -q running
859+done
860
861=== added file 'scripts/health_checks.d/service_url_checks'
862--- scripts/health_checks.d/service_url_checks 1970-01-01 00:00:00 +0000
863+++ scripts/health_checks.d/service_url_checks 2013-03-27 15:50:37 +0000
864@@ -0,0 +1,16 @@
865+#!/bin/bash
866+# Validate that service urls return expected content
867+HEALTH_DIR=`dirname $0`
868+SCRIPTS_DIR=`dirname $HEALTH_DIR`
869+. $SCRIPTS_DIR/scriptrc
870+set -e
871+
872+# Grab any OPENSTACK_URL* environment variables and validate content response
873+openstack_urls=`env| awk -F '=' '(/OPENSTACK_URL/){print $2 }'`
874+for url_check in $openstack_urls
875+do
876+ url=`echo $url_check| awk -F '|' '{print $1}'`
877+ expected_content=`echo $url_check| awk -F '|' '{print $2}'`
878+ wget -q -O - $url | grep -q "${expected_content//+/ }"
879+done
880+
881
882=== added file 'scripts/remove_from_cluster'
883--- scripts/remove_from_cluster 1970-01-01 00:00:00 +0000
884+++ scripts/remove_from_cluster 2013-03-27 15:50:37 +0000
885@@ -0,0 +1,2 @@
886+#!/bin/bash
887+crm node standby

Subscribers

People subscribed via source and target branches

to all changes: