Merge lp:~gandelman-a/charms/precise/nova-cloud-controller/live_migration into lp:~charmers/charms/precise/nova-cloud-controller/trunk

Proposed by Adam Gandelman
Status: Rejected
Rejected by: Adam Gandelman
Proposed branch: lp:~gandelman-a/charms/precise/nova-cloud-controller/live_migration
Merge into: lp:~charmers/charms/precise/nova-cloud-controller/trunk
Diff against target: 819 lines (+493/-85)
9 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)
revision (+1/-1)
To merge this branch: bzr merge lp:~gandelman-a/charms/precise/nova-cloud-controller/live_migration
Reviewer Review Type Date Requested Status
James Page Needs Fixing
Review via email: mp+142431@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Adam Gandelman (gandelman-a) wrote :

This adds grizzly support and makes nova-c-c the coordinator of ssh key access for compute nodes, for purposes of live migration.

Revision history for this message
James Page (james-page) wrote :

Hi Adam

First pass feedback

1) General approach to key distribution

Why use an HTTP server for distribution of keys and authorized hosts? This data could be passed using juju using bas64 encode/decode. That way if multiple cloud-controller instances are running the data transfer is simpler as data is always passed via juju rather than being retrieved from XX server.

2) QUANTUM_* variables

I hit a few issues testing this update with Quantum; most of the quantum functions rely on the QUANTUM_* variables being set every hook execution but the changes in nova-cloud-controller-common change this; as a result the initial configuration of quantum in hooks/lib/nova/nova-common fails as the PLUGIN is not set and configure_quantum_networking has a similar issue. Needs a bit more work.

review: Needs Fixing
56. By Adam Gandelman

Actually use determine_quantum_config when needed.

Revision history for this message
Adam Gandelman (gandelman-a) wrote :

James-

Thanks. I've updated the branch to address the second issue. There was existing functions set to deal with that issue, but they were not being called when needed.

Regarding key distribution, I've been hesitant to use the juju environment as a dumping ground for files but in this case I think you're right. Even with many compute nodes, the files / base64 encodings won't grow too big. I hadn't thought of the issue of multiple nova-c-c's but again you are right. It does complicate things and the current method would require some fixing to avoid nova-compute wget'ing the files from every nova-c-c node. I'll give the base64 method a shot and update the branch if it works out.

57. By Adam Gandelman

Replace WWW key distribution in favor of base64 encoded relation settings.

58. By Adam Gandelman

openstack-common: Update for Grizzly (and beyond) access via U.C.A.

59. By Adam Gandelman

Sync openstack-common.

Revision history for this message
Adam Gandelman (gandelman-a) wrote :

Closing this out. Rebased and redirected this work against other WIP charm branches:

https://code.launchpad.net/~gandelman-a/charms/precise/nova-cloud-controller/openstack-charmers-merge/+merge/143801

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

Subscribers

People subscribed via source and target branches