Merge lp:~gandelman-a/charms/precise/nova-cloud-controller/openstack-charmers-merge into lp:~openstack-charmers/charms/precise/nova-cloud-controller/ha-support

Proposed by Adam Gandelman
Status: Merged
Merged at revision: 53
Proposed branch: lp:~gandelman-a/charms/precise/nova-cloud-controller/openstack-charmers-merge
Merge into: lp:~openstack-charmers/charms/precise/nova-cloud-controller/ha-support
Diff against target: 817 lines (+492/-84)
8 files modified
config.yaml (+0/-4)
hooks/lib/nova/essex (+2/-2)
hooks/lib/nova/folsom (+3/-5)
hooks/lib/nova/grizzly (+80/-0)
hooks/lib/nova/nova-common (+27/-2)
hooks/lib/openstack-common (+136/-22)
hooks/nova-cloud-controller-common (+190/-35)
hooks/nova-cloud-controller-relations (+54/-14)
To merge this branch: bzr merge lp:~gandelman-a/charms/precise/nova-cloud-controller/openstack-charmers-merge
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+143801@code.launchpad.net

Description of the change

Adds ssh key distribution required for nova migration support.

To post a comment you must log in.
Revision history for this message
Adam Gandelman (gandelman-a) wrote :

Note, this MP is a redirect of work originally targeted at the upstream branch but still under review, to help consolidate the number of in-flight charm branches we have right now. Rebased it against the rest of our HA work so it should be a clean merge atm. Original MP @ https://code.launchpad.net/~gandelman-a/charms/precise/nova-cloud-controller/live_migration/+merge/142431

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-09 09:55:00 +0000
3+++ config.yaml 2013-01-18 00:30:31 +0000
4@@ -14,10 +14,6 @@
5 Note that updating this setting to a source that is known to
6 provide a later version of OpenStack will trigger a software
7 upgrade.
8- nova-config:
9- default: /etc/nova/nova.conf
10- type: string
11- description: Full path to nova.conf
12 rabbit-user:
13 default: nova
14 type: string
15
16=== modified file 'hooks/lib/nova/essex'
17--- hooks/lib/nova/essex 2012-10-03 00:37:57 +0000
18+++ hooks/lib/nova/essex 2013-01-18 00:30:31 +0000
19@@ -12,7 +12,7 @@
20
21 local nova_conf=${NOVA_CONF:-/etc/nova/nova.conf}
22 local api_conf=${API_CONF:-/etc/nova/api-paste.ini}
23-
24+ local libvirtd_conf=${LIBVIRTD_CONF:-/etc/libvirt/libvirtd.conf}
25 [[ -z $key ]] && juju-log "$CHARM set_or_update: value $value missing key" && exit 1
26 [[ -z $value ]] && juju-log "$CHARM set_or_update: key $key missing value" && exit 1
27 [[ -z "$conf_file" ]] && conf_file=$nova_conf
28@@ -22,7 +22,7 @@
29 pattern="--$key="
30 out=$pattern
31 ;;
32- "$api_conf") match="^$key = "
33+ "$api_conf"|"$libvirtd_conf") match="^$key = "
34 pattern="$match"
35 out="$key = "
36 ;;
37
38=== modified file 'hooks/lib/nova/folsom'
39--- hooks/lib/nova/folsom 2012-11-29 16:38:54 +0000
40+++ hooks/lib/nova/folsom 2013-01-18 00:30:31 +0000
41@@ -15,6 +15,7 @@
42 local quantum_conf=${QUANTUM_CONF:-/etc/quantum/quantum.conf}
43 local quantum_api_conf=${QUANTUM_API_CONF:-/etc/quantum/api-paste.ini}
44 local quantum_plugin_conf=${QUANTUM_PLUGIN_CONF:-/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini}
45+ local libvirtd_conf=${LIBVIRTD_CONF:-/etc/libvirt/libvirtd.conf}
46
47 [[ -z $key ]] && juju-log "$CHARM: set_or_update: value $value missing key" && exit 1
48 [[ -z $value ]] && juju-log "$CHARM: set_or_update: key $key missing value" && exit 1
49@@ -27,11 +28,8 @@
50 pattern="$key="
51 out=$pattern
52 ;;
53- "$api_conf") match="^$key = "
54- pattern="$match"
55- out="$key = "
56- ;;
57- "$quantum_conf"|"$quantum_api_conf"|"$quantum_plugin_conf")
58+ "$api_conf"|"$quantum_conf"|"$quantum_api_conf"|"$quantum_plugin_conf"| \
59+ "$libvirtd_conf")
60 match="^$key = "
61 pattern="$match"
62 out="$key = "
63
64=== added file 'hooks/lib/nova/grizzly'
65--- hooks/lib/nova/grizzly 1970-01-01 00:00:00 +0000
66+++ hooks/lib/nova/grizzly 2013-01-18 00:30:31 +0000
67@@ -0,0 +1,80 @@
68+#!/bin/bash -e
69+
70+# Folsom-specific functions
71+
72+nova_set_or_update() {
73+ # TODO: This needs to be shared among folsom, grizzly and beyond.
74+ # Set a config option in nova.conf or api-paste.ini, depending
75+ # Defaults to updating nova.conf
76+ local key="$1"
77+ local value="$2"
78+ local conf_file="$3"
79+ local section="${4:-DEFAULT}"
80+
81+ local nova_conf=${NOVA_CONF:-/etc/nova/nova.conf}
82+ local api_conf=${API_CONF:-/etc/nova/api-paste.ini}
83+ local quantum_conf=${QUANTUM_CONF:-/etc/quantum/quantum.conf}
84+ local quantum_api_conf=${QUANTUM_API_CONF:-/etc/quantum/api-paste.ini}
85+ local quantum_plugin_conf=${QUANTUM_PLUGIN_CONF:-/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini}
86+ local libvirtd_conf=${LIBVIRTD_CONF:-/etc/libvirt/libvirtd.conf}
87+
88+ [[ -z $key ]] && juju-log "$CHARM: set_or_update: value $value missing key" && exit 1
89+ [[ -z $value ]] && juju-log "$CHARM: set_or_update: key $key missing value" && exit 1
90+
91+ [[ -z "$conf_file" ]] && conf_file=$nova_conf
92+
93+ local pattern=""
94+ case "$conf_file" in
95+ "$nova_conf") match="^$key="
96+ pattern="$key="
97+ out=$pattern
98+ ;;
99+ "$api_conf"|"$quantum_conf"|"$quantum_api_conf"|"$quantum_plugin_conf"| \
100+ "$libvirtd_conf")
101+ match="^$key = "
102+ pattern="$match"
103+ out="$key = "
104+ ;;
105+ *) juju-log "$CHARM ERROR: set_or_update: Invalid conf_file ($conf_file)"
106+ esac
107+
108+ cat $conf_file | grep "$match$value" >/dev/null &&
109+ juju-log "$CHARM: $key=$value already in set in $conf_file" \
110+ && return 0
111+
112+ case $conf_file in
113+ "$quantum_conf"|"$quantum_api_conf"|"$quantum_plugin_conf")
114+ python -c "
115+import ConfigParser
116+config = ConfigParser.RawConfigParser()
117+config.read('$conf_file')
118+config.set('$section','$key','$value')
119+with open('$conf_file', 'wb') as configfile:
120+ config.write(configfile)
121+"
122+ ;;
123+ *)
124+ if cat $conf_file | grep "$match" >/dev/null ; then
125+ juju-log "$CHARM: Updating $conf_file, $key=$value"
126+ sed -i "s|\($pattern\).*|\1$value|" $conf_file
127+ else
128+ juju-log "$CHARM: Setting new option $key=$value in $conf_file"
129+ echo "$out$value" >>$conf_file
130+ fi
131+ ;;
132+ esac
133+}
134+
135+# Upgrade Helpers
136+nova_pre_upgrade() {
137+ # Pre-upgrade helper. Caller should pass the version of OpenStack we are
138+ # upgrading from.
139+ return 0 # Nothing to do here, yet.
140+}
141+
142+nova_post_upgrade() {
143+ # Post-upgrade helper. Caller should pass the version of OpenStack we are
144+ # upgrading from.
145+ juju-log "$CHARM: Running post-upgrade hook: $upgrade_from -> folsom."
146+ # nothing to do here yet.
147+}
148
149=== removed symlink 'hooks/lib/nova/grizzly'
150=== target was u'folsom'
151=== modified file 'hooks/lib/nova/nova-common'
152--- hooks/lib/nova/nova-common 2012-12-06 21:32:44 +0000
153+++ hooks/lib/nova/nova-common 2013-01-18 00:30:31 +0000
154@@ -32,9 +32,15 @@
155
156 configure_volume_service() {
157 local svc="$1"
158+ local cur_vers="$(get_os_codename_package "nova-common")"
159 case "$svc" in
160- "cinder") set_or_update "volume_api_class" "nova.volume.cinder.API" ;;
161- "nova-volume") set_or_update "volume_api_class" "nova.volume.api.API" ;;
162+ "cinder")
163+ set_or_update "volume_api_class" "nova.volume.cinder.API" ;;
164+ "nova-volume")
165+ # nova-volume only supported before grizzly.
166+ [[ "$cur_vers" == "essex" ]] || [[ "$cur_vers" == "folsom" ]] &&
167+ set_or_update "volume_api_class" "nova.volume.api.API"
168+ ;;
169 *) juju-log "$CHARM ERROR - configure_volume_service: Invalid service $svc"
170 return 1 ;;
171 esac
172@@ -49,6 +55,25 @@
173 ;;
174 "FlatDHCPManager")
175 set_or_update "network_manager" "nova.network.manager.FlatDHCPManager"
176+
177+ if [[ "$CHARM" == "nova-compute" ]] ; then
178+ local flat_interface=$(config-get flat-interface)
179+ local ec2_host=$(relation-get ec2_host)
180+ set_or_update flat_inteface "$flat_interface"
181+ set_or_update ec2_dmz_host "$ec2_host"
182+
183+ # Ensure flat_interface has link.
184+ if ip link show $flat_interface >/dev/null 2>&1 ; then
185+ ip link set $flat_interface up
186+ fi
187+
188+ # work around (LP: #1035172)
189+ if [[ -e /dev/vhost-net ]] ; then
190+ iptables -A POSTROUTING -t mangle -p udp --dport 68 -j CHECKSUM \
191+ --checksum-fill
192+ fi
193+ fi
194+
195 ;;
196 "Quantum")
197 local local_ip=$(get_ip `unit-get private-address`)
198
199=== modified file 'hooks/lib/openstack-common'
200--- hooks/lib/openstack-common 2013-01-09 09:55:00 +0000
201+++ hooks/lib/openstack-common 2013-01-18 00:30:31 +0000
202@@ -70,46 +70,62 @@
203 # gpg key id tagged to end of url folloed by a |
204 url=$(echo $src | cut -d'|' -f1)
205 key=$(echo $src | cut -d'|' -f2)
206- if [[ -n "$key" ]] ; then
207- juju-log "$CHARM: Importing repository key: $key"
208- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$key" || \
209- juju-log "$CHARM WARN: Could not import key from keyserver: $key"
210- else
211- juju-log "$CHARM No repository key specified"
212- url="$src"
213- fi
214- echo $url > /etc/apt/sources.list.d/juju_deb.list
215+ juju-log "$CHARM: Importing repository key: $key"
216+ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$key" || \
217+ juju-log "$CHARM WARN: Could not import key from keyserver: $key"
218+ else
219+ juju-log "$CHARM No repository key specified."
220+ url="$src"
221 fi
222+ echo "$url" > /etc/apt/sources.list.d/juju_deb.list
223 return 0
224 fi
225
226 # Cloud Archive
227 if [[ "${src:0:6}" == "cloud:" ]] ; then
228- local archive_key="5EDB1B62EC4926EA"
229- local rel=$(echo $src | cut -d: -f2)
230- local u_rel=$(echo $rel | cut -d- -f1)
231- local ca_rel=$(echo $rel | cut -d- -f2)
232+
233+ # current os releases supported by the UCA.
234+ local cloud_archive_versions="folsom grizzly"
235+
236+ local ca_rel=$(echo $src | cut -d: -f2)
237+ local u_rel=$(echo $ca_rel | cut -d- -f1)
238+ local os_rel=$(echo $ca_rel | cut -d- -f2 | cut -d/ -f1)
239
240 [[ "$u_rel" != "$DISTRIB_CODENAME" ]] &&
241 error_out "Cannot install from Cloud Archive pocket $src " \
242 "on this Ubuntu version ($DISTRIB_CODENAME)!"
243
244- if [[ "$ca_rel" == "folsom/staging" ]] ; then
245- # cloud archive staging is just a regular PPA.
246- add-apt-repository -y ppa:ubuntu-cloud-archive/folsom-staging
247+ valid_release=""
248+ for rel in $cloud_archive_versions ; do
249+ if [[ "$os_rel" == "$rel" ]] ; then
250+ valid_release=1
251+ juju-log "Installing OpenStack ($os_rel) from the Ubuntu Cloud Archive."
252+ fi
253+ done
254+ if [[ -z "$valid_release" ]] ; then
255+ error_out "OpenStack release ($os_rel) not supported by "\
256+ "the Ubuntu Cloud Archive."
257+ fi
258+
259+ # CA staging repos are standard PPAs.
260+ if echo $ca_rel | grep -q "staging" ; then
261+ add-apt-repository -y ppa:ubuntu-cloud-archive/${os_rel}-staging
262 return 0
263 fi
264
265+ # the others are LP-external deb repos.
266 case "$ca_rel" in
267- "folsom"|"folsom/updates") pocket="precise-updates/folsom" ;;
268- "folsom/proposed") pocket="precise-proposed/folsom" ;;
269+ "$u_rel-$os_rel"|"$u_rel-$os_rel/updates") pocket="$u_rel-updates/$os_rel" ;;
270+ "$u_rel-$os_rel/proposed") pocket="$u_rel-proposed/$os_rel" ;;
271+ "$u_rel-$os_rel"|"$os_rel/updates") pocket="$u_rel-updates/$os_rel" ;;
272+ "$u_rel-$os_rel/proposed") pocket="$u_rel-proposed/$os_rel" ;;
273 *) error_out "Invalid Cloud Archive repo specified: $src"
274 esac
275
276+ apt-get -y install ubuntu-cloud-keyring
277 entry="deb http://ubuntu-cloud.archive.canonical.com/ubuntu $pocket main"
278 echo "$entry" \
279 >/etc/apt/sources.list.d/ubuntu-cloud-archive-$DISTRIB_CODENAME.list
280- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $archive_key
281 return 0
282 fi
283
284@@ -142,8 +158,8 @@
285 case "$ca_rel" in
286 "folsom"|"folsom/updates"|"folsom/proposed"|"folsom/staging")
287 codename="folsom" ;;
288- "grizzly"|"grizzly/updates"|"grizzly/proposed"|"grizzy/staging")
289- codename="grizly" ;;
290+ "grizzly"|"grizzly/updates"|"grizzly/proposed"|"grizzly/staging")
291+ codename="grizzly" ;;
292 esac
293 fi
294 fi
295@@ -161,7 +177,7 @@
296 }
297
298 get_os_codename_package() {
299- local pkg_vers=$(dpkg -l | grep "$1" | awk '{ print $3 }')
300+ local pkg_vers=$(dpkg -l | grep "$1" | awk '{ print $3 }') || echo "none"
301 case "${pkg_vers:0:6}" in
302 "2011.2") echo "diablo" ;;
303 "2012.1") echo "essex" ;;
304@@ -201,6 +217,104 @@
305 "
306 }
307
308+# Common storage routines used by cinder, nova-volume and swift-storage.
309+clean_storage() {
310+ # if configured to overwrite existing storage, we unmount the block-dev
311+ # if mounted and clear any previous pv signatures
312+ local block_dev="$1"
313+ juju-log "Cleaining storage '$block_dev'"
314+ if grep -q "^$block_dev" /proc/mounts ; then
315+ mp=$(grep "^$block_dev" /proc/mounts | awk '{ print $2 }')
316+ juju-log "Unmounting $block_dev from $mp"
317+ umount "$mp" || error_out "ERROR: Could not unmount storage from $mp"
318+ fi
319+ if pvdisplay "$block_dev" >/dev/null 2>&1 ; then
320+ juju-log "Removing existing LVM PV signatures from $block_dev"
321+
322+ # deactivate any volgroups that may be built on this dev
323+ vg=$(pvdisplay $block_dev | grep "VG Name" | awk '{ print $3 }')
324+ if [[ -n "$vg" ]] ; then
325+ juju-log "Deactivating existing volume group: $vg"
326+ vgchange -an "$vg" ||
327+ error_out "ERROR: Could not deactivate volgroup $vg. Is it in use?"
328+ fi
329+ echo "yes" | pvremove -ff "$block_dev" ||
330+ error_out "Could not pvremove $block_dev"
331+ else
332+ juju-log "Zapping disk of all GPT and MBR structures"
333+ sgdisk --zap-all $block_dev ||
334+ error_out "Unable to zap $block_dev"
335+ fi
336+}
337+
338+function get_block_device() {
339+ # given a string, return full path to the block device for that
340+ # if input is not a block device, find a loopback device
341+ local input="$1"
342+
343+ case "$input" in
344+ /dev/*) [[ ! -b "$input" ]] && error_out "$input does not exist."
345+ echo "$input"; return 0;;
346+ /*) :;;
347+ *) [[ ! -b "/dev/$input" ]] && error_out "/dev/$input does not exist."
348+ echo "/dev/$input"; return 0;;
349+ esac
350+
351+ # this represents a file
352+ # support "/path/to/file|5G"
353+ local fpath size oifs="$IFS"
354+ if [ "${input#*|}" != "${input}" ]; then
355+ size=${input##*|}
356+ fpath=${input%|*}
357+ else
358+ fpath=${input}
359+ size=5G
360+ fi
361+
362+ ## loop devices are not namespaced. This is bad for containers.
363+ ## it means that the output of 'losetup' may have the given $fpath
364+ ## in it, but that may not represent this containers $fpath, but
365+ ## another containers. To address that, we really need to
366+ ## allow some uniq container-id to be expanded within path.
367+ ## TODO: find a unique container-id that will be consistent for
368+ ## this container throughout its lifetime and expand it
369+ ## in the fpath.
370+ # fpath=${fpath//%{id}/$THAT_ID}
371+
372+ local found=""
373+ # parse through 'losetup -a' output, looking for this file
374+ # output is expected to look like:
375+ # /dev/loop0: [0807]:961814 (/tmp/my.img)
376+ found=$(losetup -a |
377+ awk 'BEGIN { found=0; }
378+ $3 == f { sub(/:$/,"",$1); print $1; found=found+1; }
379+ END { if( found == 0 || found == 1 ) { exit(0); }; exit(1); }' \
380+ f="($fpath)")
381+
382+ if [ $? -ne 0 ]; then
383+ echo "multiple devices found for $fpath: $found" 1>&2
384+ return 1;
385+ fi
386+
387+ [ -n "$found" -a -b "$found" ] && { echo "$found"; return 1; }
388+
389+ if [ -n "$found" ]; then
390+ echo "confused, $found is not a block device for $fpath";
391+ return 1;
392+ fi
393+
394+ # no existing device was found, create one
395+ mkdir -p "${fpath%/*}"
396+ truncate --size "$size" "$fpath" ||
397+ { echo "failed to create $fpath of size $size"; return 1; }
398+
399+ found=$(losetup --find --show "$fpath") ||
400+ { echo "failed to setup loop device for $fpath" 1>&2; return 1; }
401+
402+ echo "$found"
403+ return 0
404+}
405+
406 HAPROXY_CFG=/etc/haproxy/haproxy.cfg
407 HAPROXY_DEFAULT=/etc/default/haproxy
408
409
410=== modified file 'hooks/nova-cloud-controller-common'
411--- hooks/nova-cloud-controller-common 2013-01-09 09:55:00 +0000
412+++ hooks/nova-cloud-controller-common 2013-01-18 00:30:31 +0000
413@@ -3,52 +3,97 @@
414 CHARM="nova-cloud-controller"
415 CONF_DIR="/etc/nova"
416
417-SERVICES="nova-api-ec2 nova-api-os-compute nova-objectstore nova-cert nova-scheduler"
418-
419-# If we have a relation to nova-volume-service, we'll also manage its API
420-# endpoint here.
421-n_vol=$(relation-ids nova-volume-service)
422-if [[ -n "$n_vol" ]] ; then
423- SERVICES="$SERVICES nova-api-os-volume"
424- dpkg -l | grep -q nova-api-os-volume || apt-get -y install nova-api-os-volume
425-fi
426-
427-PACKAGES="$SERVICES python-mysqldb python-keystone uuid haproxy"
428-
429-NET_MANAGER=$(config-get network-manager)
430-if [ "$NET_MANAGER" == "Quantum" ]; then
431- SERVICES="$SERVICES quantum-server"
432- PACKAGES="$PACKAGES quantum-server"
433- QUANTUM_PLUGIN=$(config-get quantum-plugin)
434- case $QUANTUM_PLUGIN in
435- "ovs")
436- PACKAGES="$PACKAGES quantum-plugin-openvswitch"
437- QUANTUM_CORE_PLUGIN="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
438- QUANTUM_PLUGIN_CONF="/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"
439- ;;
440- "nvp")
441- PACKAGES="$PACKAGES quantum-plugin-nicira"
442- QUANTUM_CORE_PLUGIN="quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2"
443- QUANTUM_PLUGIN_CONF="/etc/quantum/plugins/nicira/nvp.ini"
444- ;;
445- *)
446- juju-log "Unrecognised plugin for quantum: $QUANTUM_PLUGIN" && exit 1
447- ;;
448- esac
449-fi
450-
451-NOVA_CONF=$(config-get nova-config)
452+NOVA_CONF="/etc/nova/nova.conf"
453 API_CONF="/etc/nova/api-paste.ini"
454 QUANTUM_CONF="/etc/quantum/quantum.conf"
455 QUANTUM_API_CONF="/etc/quantum/api-paste.ini"
456
457+NET_MANAGER=$(config-get network-manager)
458+
459 if [[ -e $CHARM_DIR/lib/nova/nova-common ]] ; then
460 . $CHARM_DIR/lib/nova/nova-common
461 else
462 juju-log "Couldn't load $CHARM_DIR/lib/nova/nova-common" && exit 1
463 fi
464
465+function determine_services {
466+ # Sets the global $SERVICES which contains a list of all services
467+ # managed by the charm. This changes based on OpenStack release.
468+ # Currently, the services also determines what ends up in $PACKAGES.
469+
470+ # base c-c services supported across all os releases since essex.
471+ SERVICES="nova-api-ec2 nova-api-os-compute nova-objectstore nova-cert nova-scheduler"
472+
473+ # determine additional services, dependent on what version of OS.
474+ local install_src="$(config-get openstack-origin)"
475+ install_src=$(get_os_codename_install_source "$install_src")
476+ local os_vers=$(get_os_codename_package "nova-common")
477+ if [[ "$os_vers" == "none" ]] ; then
478+ [[ "$install_src" == "unknown" ]] && echo "$SERVICES" && return 0
479+ fi
480+
481+ os_vers="$install_src"
482+ if [[ "$os_vers" != "essex" ]] && [[ "$os_vers" != "folsom" ]] ; then
483+ # nova-conductor was introduced in grizzly.
484+ SERVICES="$SERVICES nova-conductor"
485+ else
486+ local n_vol=$(relation-ids nova-volume-service)
487+ if [[ -n "$n_vol" ]] ; then
488+ # nova-volume was dropped in G but may still be deployed for E + F,
489+ # but should only be managed when a relation to nova-volume exists.
490+ SERVICES="$SERVICES nova-api-os-volume"
491+ # need to also ensure the package gets installed here. if the relation
492+ # is introduced during another hook, a call to 'service_ctl all' will
493+ # require it to be there.
494+ dpkg -l | grep -q nova-api-os-volume ||
495+ apt-get -y install nova-api-os-volume
496+ fi
497+ fi
498+
499+ # quantum is really only supported for folsom and beyond.
500+ if [[ "$NET_MANAGER" == "Quantum" ]] ; then
501+ [[ "$os_vers" == "essex" ]] &&
502+ error_out "Quantum network manager only supported for Folsom + beyond."
503+ SERVICES="$SERVICES quantum-server"
504+ fi
505+}
506+
507+function determine_packages {
508+ # Derive a list of packages based on what our service needs are. This changes
509+ # depending on several factors.
510+ determine_services
511+ PACKAGES="$SERVICES python-mysqldb python-keystone uuid charm-helper-sh haproxy"
512+
513+ if echo $PACKAGES | grep -q "quantum-server" ; then
514+ case "$(config-get quantum-plugin)" in
515+ "ovs") PACKAGES="$PACKAGES quantum-plugin-openvswitch" ;;
516+ "nvp") PACKAGES="$PACKAGES quantum-plugin-nicira" ;;
517+ esac
518+ fi
519+ juju-log "$CHARM: Determined required packages: $PACKAGES."
520+}
521+
522+function determine_quantum_config {
523+ # Set QUANTUM_PLUGIN and point QUANTUM_CORE_PLUGIN and QUANTUM_PLUGIN_CONF
524+ # to the correct files based on configuration.
525+ QUANTUM_PLUGIN=${QUANTUM_PLUGIN:-$(config-get quantum-plugin)}
526+ case "$QUANTUM_PLUGIN" in
527+ "ovs")
528+ QUANTUM_CORE_PLUGIN="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
529+ QUANTUM_PLUGIN_CONF="/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"
530+ ;;
531+ "nvp")
532+ QUANTUM_CORE_PLUGIN="quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2"
533+ QUANTUM_PLUGIN_CONF="/etc/quantum/plugins/nicira/nvp.ini"
534+ ;;
535+ *)
536+ juju-log "Unrecognised plugin for quantum: $QUANTUM_PLUGIN" && exit 1
537+ ;;
538+ esac
539+}
540+
541 function configure_quantum_networking {
542+ determine_quantum_config
543 if [ "$(config-get conf-ext-net)" != "no" ] &&
544 [ "$QUANTUM_PLUGIN" == "ovs" ] &&
545 [ -f /etc/quantum/novarc ] &&
546@@ -63,3 +108,113 @@
547 $(config-get ext-net-name)
548 fi
549 }
550+
551+function ssh_authorized_keys {
552+ local key="$1"
553+ local action="$2"
554+ local exists=""
555+
556+ local sunit=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f1)
557+ mkdir -p /etc/nova/compute_ssh/$sunit
558+ local authorized_keys="/etc/nova/compute_ssh/$sunit/authorized_keys"
559+
560+ [[ -e "$authorized_keys" ]] &&
561+ grep -q "^$key" $authorized_keys && exists="true"
562+
563+ if [[ "$action" == "add" ]] ; then
564+ [[ -n "$exists" ]] &&
565+ juju-log "$CHARM: SSH key already authorized for $JUJU_REMOTE_UNIT." &&
566+ return 0
567+
568+ echo "$key" >>$authorized_keys
569+ juju-log "$CHARM: Authorized new SSH key for $JUJU_REMOTE_UNIT."
570+ return 0
571+ elif [[ "$action" == "remove" ]] ; then
572+ # we have no way of getting to the relation state during a departed hook.
573+ # we only have the peer's unit name, so remove an authorized key based on
574+ # its comment, which should can be derived from the remote unit name and
575+ # gets passed in here from caller as key/$1
576+ local key_ln=$(sed -n "\, ${key}$,=" $authorized_keys)
577+ [[ -z "$key_ln" ]] &&
578+ juju-log "$CHARM: Cannot remove SSH key for $key, not authorized?" &&
579+ return 0
580+
581+ for ln in $key_ln ; do
582+ sed -i "${ln}d" $authorized_keys
583+ juju-log "$CHARM: Removed existing SSH key ($key) from authorized_keys."
584+ done
585+ return 0
586+ else
587+ error_out "$CHARM: ssh_authorize_keys() invalid action specified: $action."
588+ fi
589+}
590+
591+function ssh_known_hosts {
592+ # Keeps the system-wide SSH known hosts file up to date with compute
593+ # nodes host keys.
594+ local host="$1"
595+ local sunit=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f1)
596+ mkdir -p /etc/nova/compute_ssh/$sunit
597+ local known_hosts="/etc/nova/compute_ssh/$sunit/known_hosts"
598+ juju-log "$CHARM: Ensuring host is included and up to date in $known_hosts."
599+
600+ [[ ! -e $known_hosts ]] && touch $known_hosts
601+
602+ local remote_key=""
603+ remote_key=$(ssh-keyscan -H -t rsa $host) ||
604+ error_out "$CHARM: Couldn't obtain SSH host key from $host."
605+ local existing=$(ssh-keygen -f $known_hosts -H -F $host | tail -n1)
606+ if [[ -n "$existing" ]] ; then
607+ juju-log "$CHARM: Found existing SSH known host key for $host."
608+ [[ "$existing" == "$remote_key" ]] && echo "HI"
609+ remote=$(echo $remote_key | awk '{ print $2" "$3 }')
610+ existing=$(echo $existing | awk '{ print $2" "$3 }')
611+ if [[ "$remote" == "$existing" ]] ; then
612+ juju-log "$CHARM: SSH known host key for $host is up to date."
613+ return 0
614+ fi
615+ juju-log "$CHARM: Removing outdated SSH host key for $host."
616+ ssh-keygen -f $known_hosts -R $host
617+ else
618+ juju-log "$CHARM: No known hosts entry for $host."
619+ fi
620+ juju-log "$CHARM: Adding new SSH known hosts entry for $host."
621+ echo $remote_key >>$known_hosts
622+
623+}
624+
625+function ssh_compute {
626+ if [[ "$1" == "add" ]] ; then
627+ local ssh_key=$(relation-get ssh_public_key)
628+ [[ -z "$ssh_key" ]] &&
629+ juju-log "$CHARM: ssh_compute peer not ready." && exit 0
630+
631+ ssh_authorized_keys "$ssh_key" "add"
632+
633+ # need to ensure known hosts entries for all possible addresses
634+ . /usr/share/charm-helper/sh/net.sh
635+ local known_hosts=""
636+ local private_address=$(relation-get private-address)
637+ known_hosts="$private_address"
638+ if ! ch_is_ip "$private_address" ; then
639+ known_hosts="$known_hosts $(get_ip $private_address)"
640+ known_hosts="$known_hosts $(echo $private_address | cut -d. -f1)"
641+ fi
642+ for host in $known_hosts ; do
643+ ssh_known_hosts "$host"
644+ done
645+ elif [[ "$1" == "remove" ]] ; then
646+ # remove key by referencing remote unit, not entire key.
647+ local remote_unit=$(echo $JUJU_REMOTE_UNIT | sed -e 's,/,-,g')
648+ ssh_authorized_keys "$remote_unit" remove
649+ else
650+ error_out "ssh_compute: Invalid parameter: $1."
651+ fi
652+
653+ local sunit=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f1)
654+
655+ # base64 encodings should trigger new relation events as needed.
656+ relation-set \
657+ known_hosts="$(base64 /etc/nova/compute_ssh/$sunit/known_hosts)" \
658+ authorized_keys="$(base64 /etc/nova/compute_ssh/$sunit/authorized_keys)"
659+}
660
661=== modified file 'hooks/nova-cloud-controller-relations'
662--- hooks/nova-cloud-controller-relations 2013-01-16 20:43:56 +0000
663+++ hooks/nova-cloud-controller-relations 2013-01-18 00:30:31 +0000
664@@ -15,9 +15,13 @@
665 configure_install_source "$(config-get openstack-origin)"
666 apt-get update || exit 1
667
668+ determine_packages
669 DEBIAN_FRONTEND=noninteractive apt-get -y \
670 install --no-install-recommends $PACKAGES || exit 1
671
672+ if [[ "$NET_MANAGER" == "Quantum" ]] ; then
673+ determine_quantum_config
674+ fi
675 configure_network_manager $NET_MANAGER
676
677 # Configure any flags specified in deployment config
678@@ -59,6 +63,7 @@
679 if dpkg --compare-versions $(get_os_version_codename "$cur") lt \
680 $(get_os_version_codename "$available") ; then
681 juju-log "$CHARM: Upgrading OpenStack release: $cur -> $available."
682+ determine_packages
683 do_openstack_upgrade "$install_src" $PACKAGES
684 fi
685
686@@ -70,6 +75,7 @@
687 configure_quantum_networking
688 fi
689
690+ determine_services
691 service_ctl all restart
692 }
693
694@@ -124,7 +130,7 @@
695 set_or_update rabbit_virtual_host "$rabbit_vhost" "$QUANTUM_CONF"
696 fi
697
698- service_ctl all restart
699+ determine_services && service_ctl all restart
700 }
701
702 function db_joined {
703@@ -158,9 +164,11 @@
704
705 if [ "$NET_MANAGER" == "Quantum" ]; then
706 local quantum_db_password=`relation-get quantum_password`
707+ determine_quantum_config
708 set_or_update sql_connection "mysql://quantum:$quantum_db_password@$db_host/quantum?charset=utf8" \
709 $QUANTUM_PLUGIN_CONF "DATABASE"
710 fi
711+ determine_services
712 service_ctl all stop
713 /usr/bin/nova-manage db sync
714 service_ctl all start
715@@ -176,7 +184,7 @@
716 juju-log "$CHARM - image-service_changed: Peer not ready?" && exit 0
717 set_or_update glance_api_servers $api_server
718 set_or_update image_service "nova.image.glance.GlanceImageService"
719- service_ctl all restart
720+ determine_services && service_ctl all restart
721 }
722
723 function keystone_joined {
724@@ -305,8 +313,8 @@
725 EOF
726 fi
727
728- service_ctl all restart
729-
730+ determine_services && service_ctl all restart
731+
732 if [ "$NET_MANAGER" == "Quantum" ]; then
733 configure_quantum_networking
734 # ripple out changes to identity to connected services
735@@ -333,8 +341,16 @@
736 *) svc="nova-volume" ;;
737 esac
738
739+ local cur_vers=$(get_os_codename_package "nova-common")
740+ if [[ "$cur_vers" != "essex" ]] && [[ "$cur_vers" != "folsom" ]] &&
741+ [[ "$svc" == "nova-volume" ]] ; then
742+ juju-log "$CHARM: WARNING nova-volume is only supported on Essex "\
743+ "and Folsom. Ignoring new relation to nova-volume service."
744+ exit 0
745+ fi
746+
747 configure_volume_service "$svc"
748- service_ctl all restart
749+ deteremine_services && service_ctl all restart
750
751 # The nova-volume API can be hosted here alongside the other
752 # nova API services, but there needs to be a new endpoint
753@@ -388,13 +404,35 @@
754 relation-set quantum_plugin=$(config-get quantum-plugin)
755 fi
756
757- # Compute's volume driver is dependent on volume service deployed.
758- local r_ids=$(relation-ids cinder-volume-service)
759- if [[ -n "$r_ids" ]] ; then
760- relation-set volume_service="cinder"
761- else
762- relation-set volume_service="nova-volume"
763- fi
764+ # volume driver is dependent on os version, or presence
765+ # of cinder (on folsom, at least)
766+ local cur_vers=$(get_os_codename_package "nova-common")
767+ local vol_drv="cinder"
768+ case "$cur_vers" in
769+ "essex")
770+ vol_drv="nova-volume"
771+ ;;
772+ "folsom")
773+ local r_ids=$(relation-get cinder-volume-service)
774+ [[ -z "$r_ids" ]] && vol_drv="nova-volume"
775+ ;;
776+ esac
777+ relation-set volume_service="$vol_drv"
778+}
779+
780+compute_changed() {
781+ local migration_auth="$(relation-get migration_auth_type)"
782+ [[ -z "$migration_auth" ]] &&
783+ juju-log "$CHARM: compute_changed - Peer not ready or "\
784+ "no migration auth. configured." && exit 0
785+
786+ case "$migration_auth" in
787+ "ssh") ssh_compute add ;;
788+ esac
789+}
790+
791+compute_departed() {
792+ ssh_compute remove
793 }
794
795 function quantum_joined() {
796@@ -499,10 +537,10 @@
797
798 arg0=$(basename $0)
799 case $arg0 in
800- "start"|"stop") service_ctl all $arg0 ;;
801+ "start"|"stop") determine_services ; service_ctl all $arg0 ;;
802 "install") install_hook ;;
803 "config-changed") config_changed ;;
804- "upgrade-charm") upgrade_charm ;;
805+ "upgrade-charm") upgrade_charm ;;
806 "amqp-relation-joined") amqp_joined ;;
807 "amqp-relation-changed") amqp_changed ;;
808 "shared-db-relation-joined") db_joined ;;
809@@ -514,6 +552,8 @@
810 "cinder-volume-service-relation-joined") volume_joined ;;
811 "nova-volume-service-relation-joined") volume_joined ;;
812 "cloud-compute-relation-joined") compute_joined ;;
813+ "cloud-compute-relation-changed") compute_changed ;;
814+ "cloud-compute-relation-departed") compute_departed ;;
815 "quantum-network-service-relation-joined") quantum_joined ;;
816 "cluster-relation-changed") cluster_changed ;;
817 "cluster-relation-departed") cluster_changed ;;

Subscribers

People subscribed via source and target branches