Merge lp:~gandelman-a/charms/precise/nova-cloud-controller/live_migration into lp:~charmers/charms/precise/nova-cloud-controller/trunk
- Precise Pangolin (12.04)
- live_migration
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Needs Fixing | ||
Review via email: mp+142431@code.launchpad.net |
Commit message
Description of the change
Adam Gandelman (gandelman-a) wrote : | # |
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-
- 56. By Adam Gandelman
-
Actually use determine_
quantum_ config when needed.
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.
Adam Gandelman (gandelman-a) wrote : | # |
Closing this out. Rebased and redirected this work against other WIP charm branches:
Unmerged revisions
Preview Diff
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 |
This adds grizzly support and makes nova-c-c the coordinator of ssh key access for compute nodes, for purposes of live migration.