Merge lp:~corey.bryant/charms/trusty/nova-cloud-controller/git-ods into lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next
- Trusty Tahr (14.04)
- git-ods
- Merge into next
Status: | Merged |
---|---|
Merged at revision: | 166 |
Proposed branch: | lp:~corey.bryant/charms/trusty/nova-cloud-controller/git-ods |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next |
Diff against target: |
1342 lines (+1001/-21) 17 files modified
.bzrignore (+1/-0) Makefile (+1/-1) README.txt (+89/-0) actions.yaml (+2/-0) actions/git_reinstall.py (+45/-0) config.yaml (+16/-0) hooks/nova_cc_hooks.py (+17/-6) hooks/nova_cc_utils.py (+323/-3) templates/git/nova_sudoers (+4/-0) tests/050-basic-trusty-icehouse-git (+10/-0) tests/051-basic-trusty-juno-git (+13/-0) tests/basic_deployment.py (+25/-2) unit_tests/__init__.py (+2/-0) unit_tests/test_actions_git_reinstall.py (+107/-0) unit_tests/test_nova_cc_contexts.py (+1/-3) unit_tests/test_nova_cc_hooks.py (+56/-0) unit_tests/test_nova_cc_utils.py (+289/-6) |
To merge this branch: | bzr merge lp:~corey.bryant/charms/trusty/nova-cloud-controller/git-ods |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Needs Fixing | ||
Review via email: mp+258923@code.launchpad.net |
Commit message
Description of the change
- 176. By Corey Bryant
-
Add libyaml-dev as base git package
uosci-testing-bot (uosci-testing-bot) wrote : | # |
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4188 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4086 nova-cloud-
AMULET OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #4531 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4256 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4110 nova-cloud-
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #4539 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4264 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4118 nova-cloud-
AMULET OK: passed
Build: http://
- 177. By Corey Bryant
-
Sync charm-helpers
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #4843 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4523 nova-cloud-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #4334 nova-cloud-
AMULET OK: passed
Build: http://
James Page (james-page) wrote : | # |
Looks OK - but see unit test failure on merged branch:
=======
ERROR: test_config_
-------
Traceback (most recent call last):
File "/usr/lib/
return func(*args, **keywargs)
File "/home/
hooks.
File "hooks/
f(*args)
File "hooks/
f(*args, **kwargs)
File "hooks/
if config_
File "hooks/
with hook_data():
File "/usr/lib/
return self.gen.next()
File "hooks/
self.
File "hooks/
os.
File "/usr/lib/
elif path == '' or path.endswith('/'):
AttributeError: 'NoneType' object has no attribute 'endswith'
- 178. By Corey Bryant
-
Merge next branch
- 179. By Corey Bryant
-
Update failing unit test
Corey Bryant (corey.bryant) wrote : | # |
Thanks for the review! I've merged the latest next branch and updated the failing test.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #5239 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4918 nova-cloud-
UNIT OK: passed
- 180. By Corey Bryant
-
Merge next branch
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #5338 nova-cloud-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #4971 nova-cloud-
UNIT OK: passed
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2015-04-20 10:21:36 +0000 |
3 | +++ .bzrignore 2015-06-11 13:34:00 +0000 |
4 | @@ -1,2 +1,3 @@ |
5 | bin |
6 | .coverage |
7 | +tags |
8 | |
9 | === modified file 'Makefile' |
10 | --- Makefile 2015-04-20 10:21:36 +0000 |
11 | +++ Makefile 2015-06-11 13:34:00 +0000 |
12 | @@ -2,7 +2,7 @@ |
13 | PYTHON := /usr/bin/env python |
14 | |
15 | lint: |
16 | - @flake8 --exclude hooks/charmhelpers hooks unit_tests tests |
17 | + @flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests |
18 | @charm proof |
19 | |
20 | unit_test: |
21 | |
22 | === modified file 'README.txt' |
23 | --- README.txt 2015-04-20 10:21:36 +0000 |
24 | +++ README.txt 2015-06-11 13:34:00 +0000 |
25 | @@ -23,3 +23,92 @@ |
26 | |
27 | juju add-relation "nova-cloud-controller:pgsql-nova-db" "postgresql:db" |
28 | juju add-relation "nova-cloud-controller:pgsql-neutron-db" "postgresql:db" |
29 | + |
30 | +Deploying from source |
31 | +===================== |
32 | + |
33 | +The minimum openstack-origin-git config required to deploy from source is: |
34 | + |
35 | + openstack-origin-git: include-file://nova-juno.yaml |
36 | + |
37 | + nova-juno.yaml |
38 | + repositories: |
39 | + - {name: requirements, |
40 | + repository: 'git://github.com/openstack/requirements', |
41 | + branch: stable/juno} |
42 | + - {name: nova, |
43 | + repository: 'git://github.com/openstack/nova', |
44 | + branch: stable/juno} |
45 | + |
46 | +Note that there are only two 'name' values the charm knows about: 'requirements' |
47 | +and 'nova'. These repositories must correspond to these 'name' values. |
48 | +Additionally, the requirements repository must be specified first and the |
49 | +nova repository must be specified last. All other repostories are installed |
50 | +in the order in which they are specified. |
51 | + |
52 | +The following is a full list of current tip repos (may not be up-to-date): |
53 | + |
54 | + openstack-origin-git: include-file://nova-master.yaml |
55 | + |
56 | + nova-master.yaml |
57 | + repositories: |
58 | + - {name: requirements, |
59 | + repository: 'git://github.com/openstack/requirements', |
60 | + branch: master} |
61 | + - {name: oslo-concurrency, |
62 | + repository: 'git://github.com/openstack/oslo.concurrency', |
63 | + branch: master} |
64 | + - {name: oslo-config, |
65 | + repository: 'git://github.com/openstack/oslo.config', |
66 | + branch: master} |
67 | + - {name: oslo-context, |
68 | + repository: 'git://github.com/openstack/oslo.context', |
69 | + branch: master} |
70 | + - {name: oslo-db, |
71 | + repository: 'git://github.com/openstack/oslo.db', |
72 | + branch: master} |
73 | + - {name: oslo-i18n, |
74 | + repository: 'git://github.com/openstack/oslo.i18n', |
75 | + branch: master} |
76 | + - {name: oslo-log, |
77 | + repository: 'git://github.com/openstack/oslo.log', |
78 | + branch: master} |
79 | + - {name: oslo-messaging, |
80 | + repository: 'git://github.com/openstack/oslo.messaging', |
81 | + branch: master} |
82 | + - {name: oslo-middleware, |
83 | + repository': 'git://github.com/openstack/oslo.middleware', |
84 | + branch: master} |
85 | + - {name: oslo-rootwrap', |
86 | + repository: 'git://github.com/openstack/oslo.rootwrap', |
87 | + branch: master} |
88 | + - {name: oslo-serialization, |
89 | + repository: 'git://github.com/openstack/oslo.serialization', |
90 | + branch: master} |
91 | + - {name: oslo-utils, |
92 | + repository: 'git://github.com/openstack/oslo.utils', |
93 | + branch: master} |
94 | + - {name: pbr, |
95 | + repository: 'git://github.com/openstack-dev/pbr', |
96 | + branch: master} |
97 | + - {name: stevedore, |
98 | + repository: 'git://github.com/openstack/stevedore', |
99 | + branch: 'master'} |
100 | + - {name: sqlalchemy-migrate, |
101 | + repository: 'git://github.com/stackforge/sqlalchemy-migrate', |
102 | + branch: master} |
103 | + - {name: python-cinderclient, |
104 | + repository: 'git://github.com/openstack/python-cinderclient', |
105 | + branch: master} |
106 | + - {name: python-glanceclient, |
107 | + repository': 'git://github.com/openstack/python-glanceclient', |
108 | + branch: master} |
109 | + - {name: python-neutronlient, |
110 | + repository': 'git://github.com/openstack/python-neutronclient', |
111 | + branch: master} |
112 | + - {name: keystonemiddleware, |
113 | + repository: 'git://github.com/openstack/keystonemiddleware', |
114 | + branch: master} |
115 | + - {name: nova, |
116 | + repository: 'git://github.com/openstack/nova', |
117 | + branch: master} |
118 | |
119 | === added directory 'actions' |
120 | === added file 'actions.yaml' |
121 | --- actions.yaml 1970-01-01 00:00:00 +0000 |
122 | +++ actions.yaml 2015-06-11 13:34:00 +0000 |
123 | @@ -0,0 +1,2 @@ |
124 | +git-reinstall: |
125 | + description: Reinstall nova-cloud-controller from the openstack-origin-git repositories. |
126 | |
127 | === added symlink 'actions/git-reinstall' |
128 | === target is u'git_reinstall.py' |
129 | === added file 'actions/git_reinstall.py' |
130 | --- actions/git_reinstall.py 1970-01-01 00:00:00 +0000 |
131 | +++ actions/git_reinstall.py 2015-06-11 13:34:00 +0000 |
132 | @@ -0,0 +1,45 @@ |
133 | +#!/usr/bin/python |
134 | +import sys |
135 | +import traceback |
136 | + |
137 | +sys.path.append('hooks/') |
138 | + |
139 | +from charmhelpers.contrib.openstack.utils import ( |
140 | + git_install_requested, |
141 | +) |
142 | + |
143 | +from charmhelpers.core.hookenv import ( |
144 | + action_set, |
145 | + action_fail, |
146 | + config, |
147 | +) |
148 | + |
149 | +from nova_cc_utils import ( |
150 | + git_install, |
151 | +) |
152 | + |
153 | +from nova_cc_hooks import ( |
154 | + config_changed, |
155 | +) |
156 | + |
157 | + |
158 | +def git_reinstall(): |
159 | + """Reinstall from source and restart services. |
160 | + |
161 | + If the openstack-origin-git config option was used to install openstack |
162 | + from source git repositories, then this action can be used to reinstall |
163 | + from updated git repositories, followed by a restart of services.""" |
164 | + if not git_install_requested(): |
165 | + action_fail('openstack-origin-git is not configured') |
166 | + return |
167 | + |
168 | + try: |
169 | + git_install(config('openstack-origin-git')) |
170 | + config_changed() |
171 | + except: |
172 | + action_set({'traceback': traceback.format_exc()}) |
173 | + action_fail('git-reinstall resulted in an unexpected error') |
174 | + |
175 | + |
176 | +if __name__ == '__main__': |
177 | + git_reinstall() |
178 | |
179 | === modified file 'config.yaml' |
180 | --- config.yaml 2015-06-10 20:32:48 +0000 |
181 | +++ config.yaml 2015-06-11 13:34:00 +0000 |
182 | @@ -14,6 +14,22 @@ |
183 | Note that updating this setting to a source that is known to |
184 | provide a later version of OpenStack will trigger a software |
185 | upgrade. |
186 | + |
187 | + Note that when openstack-origin-git is specified, openstack |
188 | + specific packages will be installed from source rather than |
189 | + from the openstack-origin repository. |
190 | + openstack-origin-git: |
191 | + default: |
192 | + type: string |
193 | + description: | |
194 | + Specifies a YAML-formatted dictionary listing the git |
195 | + repositories and branches from which to install OpenStack and |
196 | + its dependencies. |
197 | + |
198 | + Note that the installed config files will be determined based on |
199 | + the OpenStack release of the openstack-origin option. |
200 | + |
201 | + For more details see README.md. |
202 | rabbit-user: |
203 | default: nova |
204 | type: string |
205 | |
206 | === modified file 'hooks/nova_cc_hooks.py' |
207 | --- hooks/nova_cc_hooks.py 2015-06-04 08:45:01 +0000 |
208 | +++ hooks/nova_cc_hooks.py 2015-06-11 13:34:00 +0000 |
209 | @@ -43,7 +43,9 @@ |
210 | ) |
211 | |
212 | from charmhelpers.contrib.openstack.utils import ( |
213 | + config_value_changed, |
214 | configure_installation_source, |
215 | + git_install_requested, |
216 | openstack_upgrade_available, |
217 | os_release, |
218 | os_requires_version, |
219 | @@ -75,6 +77,7 @@ |
220 | disable_services, |
221 | do_openstack_upgrade, |
222 | enable_services, |
223 | + git_install, |
224 | keystone_ca_cert_b64, |
225 | migrate_neutron_database, |
226 | migrate_nova_database, |
227 | @@ -142,9 +145,12 @@ |
228 | def install(): |
229 | execd_preinstall() |
230 | configure_installation_source(config('openstack-origin')) |
231 | + |
232 | apt_update() |
233 | apt_install(determine_packages(), fatal=True) |
234 | |
235 | + git_install(config('openstack-origin-git')) |
236 | + |
237 | _files = os.path.join(charm_dir(), 'files') |
238 | if os.path.isdir(_files): |
239 | for f in os.listdir(_files): |
240 | @@ -170,16 +176,21 @@ |
241 | relation_prefix='nova') |
242 | |
243 | global CONFIGS |
244 | - if openstack_upgrade_available('nova-common'): |
245 | - CONFIGS = do_openstack_upgrade() |
246 | - [neutron_api_relation_joined(rid=rid, remote_restart=True) |
247 | - for rid in relation_ids('neutron-api')] |
248 | + if git_install_requested(): |
249 | + if config_value_changed('openstack-origin-git'): |
250 | + git_install(config('openstack-origin-git')) |
251 | + else: |
252 | + if openstack_upgrade_available('nova-common'): |
253 | + CONFIGS = do_openstack_upgrade() |
254 | + [neutron_api_relation_joined(rid=rid, remote_restart=True) |
255 | + for rid in relation_ids('neutron-api')] |
256 | save_script_rc() |
257 | configure_https() |
258 | CONFIGS.write_all() |
259 | if console_attributes('protocol'): |
260 | - apt_update() |
261 | - apt_install(console_attributes('packages'), fatal=True) |
262 | + if not git_install_requested(): |
263 | + apt_update() |
264 | + apt_install(console_attributes('packages'), fatal=True) |
265 | [compute_joined(rid=rid) |
266 | for rid in relation_ids('cloud-compute')] |
267 | for r_id in relation_ids('identity-service'): |
268 | |
269 | === modified file 'hooks/nova_cc_utils.py' |
270 | --- hooks/nova_cc_utils.py 2015-05-11 07:38:35 +0000 |
271 | +++ hooks/nova_cc_utils.py 2015-06-11 13:34:00 +0000 |
272 | @@ -1,4 +1,5 @@ |
273 | import os |
274 | +import shutil |
275 | import subprocess |
276 | import ConfigParser |
277 | |
278 | @@ -14,11 +15,20 @@ |
279 | |
280 | from charmhelpers.contrib.peerstorage import peer_store |
281 | |
282 | +from charmhelpers.contrib.python.packages import ( |
283 | + pip_install, |
284 | +) |
285 | + |
286 | from charmhelpers.contrib.openstack.utils import ( |
287 | configure_installation_source, |
288 | get_host_ip, |
289 | get_hostname, |
290 | get_os_codename_install_source, |
291 | + git_install_requested, |
292 | + git_clone_and_install, |
293 | + git_src_dir, |
294 | + git_pip_venv_dir, |
295 | + git_yaml_value, |
296 | is_ip, |
297 | os_release, |
298 | save_script_rc as _save_script_rc) |
299 | @@ -31,6 +41,7 @@ |
300 | ) |
301 | |
302 | from charmhelpers.core.hookenv import ( |
303 | + charm_dir, |
304 | config, |
305 | log, |
306 | relation_get, |
307 | @@ -42,13 +53,19 @@ |
308 | ) |
309 | |
310 | from charmhelpers.core.host import ( |
311 | + adduser, |
312 | + add_group, |
313 | + add_user_to_group, |
314 | + mkdir, |
315 | service, |
316 | service_start, |
317 | service_stop, |
318 | service_running, |
319 | - lsb_release |
320 | + lsb_release, |
321 | ) |
322 | |
323 | +from charmhelpers.core.templating import render |
324 | + |
325 | from charmhelpers.contrib.network.ip import ( |
326 | is_ipv6 |
327 | ) |
328 | @@ -76,6 +93,46 @@ |
329 | 'python-memcache', |
330 | ] |
331 | |
332 | +BASE_GIT_PACKAGES = [ |
333 | + 'libffi-dev', |
334 | + 'libmysqlclient-dev', |
335 | + 'libssl-dev', |
336 | + 'libxml2-dev', |
337 | + 'libxslt1-dev', |
338 | + 'libyaml-dev', |
339 | + 'python-dev', |
340 | + 'python-pip', |
341 | + 'python-setuptools', |
342 | + 'zlib1g-dev', |
343 | +] |
344 | + |
345 | +LATE_GIT_PACKAGES = [ |
346 | + 'novnc', |
347 | + 'spice-html5', |
348 | + 'websockify', |
349 | +] |
350 | + |
351 | +# ubuntu packages that should not be installed when deploying from git |
352 | +GIT_PACKAGE_BLACKLIST = [ |
353 | + 'neutron-common', |
354 | + 'neutron-server', |
355 | + 'neutron-plugin-ml2', |
356 | + 'nova-api-ec2', |
357 | + 'nova-api-os-compute', |
358 | + 'nova-api-os-volume', |
359 | + 'nova-cert', |
360 | + 'nova-conductor', |
361 | + 'nova-consoleauth', |
362 | + 'nova-novncproxy', |
363 | + 'nova-objectstore', |
364 | + 'nova-scheduler', |
365 | + 'nova-spiceproxy', |
366 | + 'nova-xvpvncproxy', |
367 | + 'python-keystoneclient', |
368 | + 'python-six', |
369 | + 'quantum-server', |
370 | +] |
371 | + |
372 | BASE_SERVICES = [ |
373 | 'nova-api-ec2', |
374 | 'nova-api-os-compute', |
375 | @@ -381,6 +438,15 @@ |
376 | packages.extend(pkgs) |
377 | if console_attributes('packages'): |
378 | packages.extend(console_attributes('packages')) |
379 | + |
380 | + if git_install_requested(): |
381 | + packages = list(set(packages)) |
382 | + packages.extend(BASE_GIT_PACKAGES) |
383 | + # don't include packages that will be installed from git |
384 | + for p in GIT_PACKAGE_BLACKLIST: |
385 | + if p in packages: |
386 | + packages.remove(p) |
387 | + |
388 | return list(set(packages)) |
389 | |
390 | |
391 | @@ -454,8 +520,8 @@ |
392 | os.unlink('/usr/sbin/policy-rc.d') |
393 | |
394 | |
395 | -QUANTUM_DB_MANAGE = "/usr/bin/quantum-db-manage" |
396 | -NEUTRON_DB_MANAGE = "/usr/bin/neutron-db-manage" |
397 | +QUANTUM_DB_MANAGE = "quantum-db-manage" |
398 | +NEUTRON_DB_MANAGE = "neutron-db-manage" |
399 | |
400 | |
401 | def reset_os_release(): |
402 | @@ -985,3 +1051,257 @@ |
403 | ' main') |
404 | apt_update() |
405 | apt_install('haproxy/trusty-backports', fatal=True) |
406 | + |
407 | + |
408 | +def git_install(projects_yaml): |
409 | + """Perform setup, and install git repos specified in yaml parameter.""" |
410 | + if git_install_requested(): |
411 | + git_pre_install() |
412 | + git_clone_and_install(projects_yaml, core_project='nova') |
413 | + git_post_install(projects_yaml) |
414 | + |
415 | + |
416 | +def git_pre_install(): |
417 | + """Perform pre-install setup.""" |
418 | + dirs = [ |
419 | + '/var/lib/nova', |
420 | + '/var/lib/nova/buckets', |
421 | + '/var/lib/nova/CA', |
422 | + '/var/lib/nova/CA/INTER', |
423 | + '/var/lib/nova/CA/newcerts', |
424 | + '/var/lib/nova/CA/private', |
425 | + '/var/lib/nova/CA/reqs', |
426 | + '/var/lib/nova/images', |
427 | + '/var/lib/nova/instances', |
428 | + '/var/lib/nova/keys', |
429 | + '/var/lib/nova/networks', |
430 | + '/var/lib/nova/tmp', |
431 | + '/var/lib/neutron', |
432 | + '/var/lib/neutron/lock', |
433 | + '/var/log/nova', |
434 | + '/etc/neutron', |
435 | + '/etc/neutron/plugins', |
436 | + '/etc/neutron/plugins/ml2', |
437 | + ] |
438 | + |
439 | + adduser('nova', shell='/bin/bash', system_user=True) |
440 | + subprocess.check_call(['usermod', '--home', '/var/lib/nova', 'nova']) |
441 | + add_group('nova', system_group=True) |
442 | + add_user_to_group('nova', 'nova') |
443 | + |
444 | + adduser('neutron', shell='/bin/bash', system_user=True) |
445 | + add_group('neutron', system_group=True) |
446 | + add_user_to_group('neutron', 'neutron') |
447 | + |
448 | + for d in dirs: |
449 | + mkdir(d, owner='nova', group='nova', perms=0755, force=False) |
450 | + |
451 | + |
452 | +def git_post_install(projects_yaml): |
453 | + """Perform post-install setup.""" |
454 | + http_proxy = git_yaml_value(projects_yaml, 'http_proxy') |
455 | + if http_proxy: |
456 | + pip_install('mysql-python', proxy=http_proxy, |
457 | + venv=git_pip_venv_dir(projects_yaml)) |
458 | + else: |
459 | + pip_install('mysql-python', |
460 | + venv=git_pip_venv_dir(projects_yaml)) |
461 | + |
462 | + src_etc = os.path.join(git_src_dir(projects_yaml, 'nova'), 'etc/nova') |
463 | + configs = [ |
464 | + {'src': src_etc, |
465 | + 'dest': '/etc/nova'}, |
466 | + ] |
467 | + |
468 | + for c in configs: |
469 | + if os.path.exists(c['dest']): |
470 | + shutil.rmtree(c['dest']) |
471 | + shutil.copytree(c['src'], c['dest']) |
472 | + |
473 | + # NOTE(coreycb): Need to find better solution than bin symlinks. |
474 | + symlinks = [ |
475 | + {'src': os.path.join(git_pip_venv_dir(projects_yaml), |
476 | + 'bin/nova-manage'), |
477 | + 'link': '/usr/local/bin/nova-manage'}, |
478 | + {'src': os.path.join(git_pip_venv_dir(projects_yaml), |
479 | + 'bin/nova-rootwrap'), |
480 | + 'link': '/usr/local/bin/nova-rootwrap'}, |
481 | + ] |
482 | + |
483 | + for s in symlinks: |
484 | + if os.path.lexists(s['link']): |
485 | + os.remove(s['link']) |
486 | + os.symlink(s['src'], s['link']) |
487 | + |
488 | + render('git/nova_sudoers', '/etc/sudoers.d/nova_sudoers', {}, perms=0o440) |
489 | + |
490 | + nova_cc = 'nova-cloud-controller' |
491 | + nova_user = 'nova' |
492 | + start_dir = '/var/lib/nova' |
493 | + bin_dir = os.path.join(git_pip_venv_dir(projects_yaml), 'bin') |
494 | + nova_conf = '/etc/nova/nova.conf' |
495 | + nova_ec2_api_context = { |
496 | + 'service_description': 'Nova EC2 API server', |
497 | + 'service_name': nova_cc, |
498 | + 'user_name': nova_user, |
499 | + 'start_dir': start_dir, |
500 | + 'process_name': 'nova-api-ec2', |
501 | + 'executable_name': os.path.join(bin_dir, 'nova-api-ec2'), |
502 | + 'config_files': [nova_conf], |
503 | + } |
504 | + nova_api_os_compute_context = { |
505 | + 'service_description': 'Nova OpenStack Compute API server', |
506 | + 'service_name': nova_cc, |
507 | + 'user_name': nova_user, |
508 | + 'start_dir': start_dir, |
509 | + 'process_name': 'nova-api-os-compute', |
510 | + 'executable_name': os.path.join(bin_dir, 'nova-api-os-compute'), |
511 | + 'config_files': [nova_conf], |
512 | + } |
513 | + nova_cells_context = { |
514 | + 'service_description': 'Nova cells', |
515 | + 'service_name': nova_cc, |
516 | + 'user_name': nova_user, |
517 | + 'start_dir': start_dir, |
518 | + 'process_name': 'nova-cells', |
519 | + 'executable_name': os.path.join(bin_dir, 'nova-cells'), |
520 | + 'config_files': [nova_conf], |
521 | + } |
522 | + nova_cert_context = { |
523 | + 'service_description': 'Nova cert', |
524 | + 'service_name': nova_cc, |
525 | + 'user_name': nova_user, |
526 | + 'start_dir': start_dir, |
527 | + 'process_name': 'nova-cert', |
528 | + 'executable_name': os.path.join(bin_dir, 'nova-cert'), |
529 | + 'config_files': [nova_conf], |
530 | + } |
531 | + nova_conductor_context = { |
532 | + 'service_description': 'Nova conductor', |
533 | + 'service_name': nova_cc, |
534 | + 'user_name': nova_user, |
535 | + 'start_dir': start_dir, |
536 | + 'process_name': 'nova-conductor', |
537 | + 'executable_name': os.path.join(bin_dir, 'nova-conductor'), |
538 | + 'config_files': [nova_conf], |
539 | + } |
540 | + nova_consoleauth_context = { |
541 | + 'service_description': 'Nova console auth', |
542 | + 'service_name': nova_cc, |
543 | + 'user_name': nova_user, |
544 | + 'start_dir': start_dir, |
545 | + 'process_name': 'nova-consoleauth', |
546 | + 'executable_name': os.path.join(bin_dir, 'nova-consoleauth'), |
547 | + 'config_files': [nova_conf], |
548 | + } |
549 | + nova_console_context = { |
550 | + 'service_description': 'Nova console', |
551 | + 'service_name': nova_cc, |
552 | + 'user_name': nova_user, |
553 | + 'start_dir': start_dir, |
554 | + 'process_name': 'nova-console', |
555 | + 'executable_name': os.path.join(bin_dir, 'nova-console'), |
556 | + 'config_files': [nova_conf], |
557 | + } |
558 | + nova_novncproxy_context = { |
559 | + 'service_description': 'Nova NoVNC proxy', |
560 | + 'service_name': nova_cc, |
561 | + 'user_name': nova_user, |
562 | + 'start_dir': start_dir, |
563 | + 'process_name': 'nova-novncproxy', |
564 | + 'executable_name': os.path.join(bin_dir, 'nova-novncproxy'), |
565 | + 'config_files': [nova_conf], |
566 | + } |
567 | + nova_objectstore_context = { |
568 | + 'service_description': 'Nova object store', |
569 | + 'service_name': nova_cc, |
570 | + 'user_name': nova_user, |
571 | + 'start_dir': start_dir, |
572 | + 'process_name': 'nova-objectstore', |
573 | + 'executable_name': os.path.join(bin_dir, 'nova-objectstore'), |
574 | + 'config_files': [nova_conf], |
575 | + } |
576 | + nova_scheduler_context = { |
577 | + 'service_description': 'Nova scheduler', |
578 | + 'service_name': nova_cc, |
579 | + 'user_name': nova_user, |
580 | + 'start_dir': start_dir, |
581 | + 'process_name': 'nova-scheduler', |
582 | + 'executable_name': os.path.join(bin_dir, 'nova-scheduler'), |
583 | + 'config_files': [nova_conf], |
584 | + } |
585 | + nova_serialproxy_context = { |
586 | + 'service_description': 'Nova serial proxy', |
587 | + 'service_name': nova_cc, |
588 | + 'user_name': nova_user, |
589 | + 'start_dir': start_dir, |
590 | + 'process_name': 'nova-serialproxy', |
591 | + 'executable_name': os.path.join(bin_dir, 'nova-serialproxy'), |
592 | + 'config_files': [nova_conf], |
593 | + } |
594 | + nova_spiceproxy_context = { |
595 | + 'service_description': 'Nova spice proxy', |
596 | + 'service_name': nova_cc, |
597 | + 'user_name': nova_user, |
598 | + 'start_dir': start_dir, |
599 | + 'process_name': 'nova-spicehtml5proxy', |
600 | + 'executable_name': os.path.join(bin_dir, 'nova-spicehtml5proxy'), |
601 | + 'config_files': [nova_conf], |
602 | + } |
603 | + nova_xvpvncproxy_context = { |
604 | + 'service_description': 'Nova XVPVNC proxy', |
605 | + 'service_name': nova_cc, |
606 | + 'user_name': nova_user, |
607 | + 'start_dir': start_dir, |
608 | + 'process_name': 'nova-xvpvncproxy', |
609 | + 'executable_name': os.path.join(bin_dir, 'nova-xvpvncproxy'), |
610 | + 'config_files': [nova_conf], |
611 | + } |
612 | + |
613 | + # NOTE(coreycb): Needs systemd support |
614 | + templates_dir = 'hooks/charmhelpers/contrib/openstack/templates' |
615 | + templates_dir = os.path.join(charm_dir(), templates_dir) |
616 | + os_rel = os_release('nova-common') |
617 | + render('git.upstart', '/etc/init/nova-api-ec2.conf', |
618 | + nova_ec2_api_context, perms=0o644, |
619 | + templates_dir=templates_dir) |
620 | + render('git.upstart', '/etc/init/nova-api-os-compute.conf', |
621 | + nova_api_os_compute_context, perms=0o644, |
622 | + templates_dir=templates_dir) |
623 | + render('git.upstart', '/etc/init/nova-cells.conf', |
624 | + nova_cells_context, perms=0o644, |
625 | + templates_dir=templates_dir) |
626 | + render('git.upstart', '/etc/init/nova-cert.conf', |
627 | + nova_cert_context, perms=0o644, |
628 | + templates_dir=templates_dir) |
629 | + render('git.upstart', '/etc/init/nova-conductor.conf', |
630 | + nova_conductor_context, perms=0o644, |
631 | + templates_dir=templates_dir) |
632 | + render('git.upstart', '/etc/init/nova-consoleauth.conf', |
633 | + nova_consoleauth_context, perms=0o644, |
634 | + templates_dir=templates_dir) |
635 | + render('git.upstart', '/etc/init/nova-console.conf', |
636 | + nova_console_context, perms=0o644, |
637 | + templates_dir=templates_dir) |
638 | + render('git.upstart', '/etc/init/nova-novncproxy.conf', |
639 | + nova_novncproxy_context, perms=0o644, |
640 | + templates_dir=templates_dir) |
641 | + render('git.upstart', '/etc/init/nova-objectstore.conf', |
642 | + nova_objectstore_context, perms=0o644, |
643 | + templates_dir=templates_dir) |
644 | + render('git.upstart', '/etc/init/nova-scheduler.conf', |
645 | + nova_scheduler_context, perms=0o644, |
646 | + templates_dir=templates_dir) |
647 | + if os_rel >= 'juno': |
648 | + render('git.upstart', '/etc/init/nova-serialproxy.conf', |
649 | + nova_serialproxy_context, perms=0o644, |
650 | + templates_dir=templates_dir) |
651 | + render('git.upstart', '/etc/init/nova-spiceproxy.conf', |
652 | + nova_spiceproxy_context, perms=0o644, |
653 | + templates_dir=templates_dir) |
654 | + render('git.upstart', '/etc/init/nova-xvpvncproxy.conf', |
655 | + nova_xvpvncproxy_context, perms=0o644, |
656 | + templates_dir=templates_dir) |
657 | + |
658 | + apt_update() |
659 | + apt_install(LATE_GIT_PACKAGES, fatal=True) |
660 | |
661 | === added directory 'templates/git' |
662 | === added file 'templates/git/nova_sudoers' |
663 | --- templates/git/nova_sudoers 1970-01-01 00:00:00 +0000 |
664 | +++ templates/git/nova_sudoers 2015-06-11 13:34:00 +0000 |
665 | @@ -0,0 +1,4 @@ |
666 | +Defaults:nova !requiretty |
667 | + |
668 | +nova ALL = (root) NOPASSWD: /usr/local/bin/nova-rootwrap /etc/nova/rootwrap.conf * |
669 | + |
670 | |
671 | === added file 'tests/050-basic-trusty-icehouse-git' |
672 | --- tests/050-basic-trusty-icehouse-git 1970-01-01 00:00:00 +0000 |
673 | +++ tests/050-basic-trusty-icehouse-git 2015-06-11 13:34:00 +0000 |
674 | @@ -0,0 +1,10 @@ |
675 | +#!/usr/bin/python |
676 | + |
677 | +"""Amulet tests on a basic nova cloud controller git deployment on |
678 | + trusty-icehouse.""" |
679 | + |
680 | +from basic_deployment import NovaCCBasicDeployment |
681 | + |
682 | +if __name__ == '__main__': |
683 | + deployment = NovaCCBasicDeployment(series='trusty', git=True) |
684 | + deployment.run_tests() |
685 | |
686 | === added file 'tests/051-basic-trusty-juno-git' |
687 | --- tests/051-basic-trusty-juno-git 1970-01-01 00:00:00 +0000 |
688 | +++ tests/051-basic-trusty-juno-git 2015-06-11 13:34:00 +0000 |
689 | @@ -0,0 +1,13 @@ |
690 | +#!/usr/bin/python |
691 | + |
692 | +"""Amulet tests on a basic nova cloud controller git deployment on |
693 | + trusty-juno.""" |
694 | + |
695 | +from basic_deployment import NovaCCBasicDeployment |
696 | + |
697 | +if __name__ == '__main__': |
698 | + deployment = NovaCCBasicDeployment(series='trusty', |
699 | + openstack='cloud:trusty-juno', |
700 | + source='cloud:trusty-updates/juno', |
701 | + git=True) |
702 | + deployment.run_tests() |
703 | |
704 | === modified file 'tests/basic_deployment.py' |
705 | --- tests/basic_deployment.py 2015-04-20 10:21:36 +0000 |
706 | +++ tests/basic_deployment.py 2015-06-11 13:34:00 +0000 |
707 | @@ -1,6 +1,8 @@ |
708 | #!/usr/bin/python |
709 | |
710 | import amulet |
711 | +import os |
712 | +import yaml |
713 | |
714 | from charmhelpers.contrib.openstack.amulet.deployment import ( |
715 | OpenStackAmuletDeployment |
716 | @@ -19,9 +21,11 @@ |
717 | class NovaCCBasicDeployment(OpenStackAmuletDeployment): |
718 | """Amulet tests on a basic nova cloud controller deployment.""" |
719 | |
720 | - def __init__(self, series=None, openstack=None, source=None, stable=False): |
721 | + def __init__(self, series=None, openstack=None, source=None, git=False, |
722 | + stable=False): |
723 | """Deploy the entire test environment.""" |
724 | super(NovaCCBasicDeployment, self).__init__(series, openstack, source, stable) |
725 | + self.git = git |
726 | self._add_services() |
727 | self._add_relations() |
728 | self._configure_services() |
729 | @@ -62,9 +66,28 @@ |
730 | |
731 | def _configure_services(self): |
732 | """Configure all of the services.""" |
733 | + nova_cc_config = {} |
734 | + if self.git: |
735 | + branch = 'stable/' + self._get_openstack_release_string() |
736 | + amulet_http_proxy = os.environ.get('AMULET_HTTP_PROXY') |
737 | + openstack_origin_git = { |
738 | + 'repositories': [ |
739 | + {'name': 'requirements', |
740 | + 'repository': 'git://github.com/openstack/requirements', |
741 | + 'branch': branch}, |
742 | + {'name': 'nova', |
743 | + 'repository': 'git://github.com/openstack/nova', |
744 | + 'branch': branch}, |
745 | + ], |
746 | + 'directory': '/mnt/openstack-git', |
747 | + 'http_proxy': amulet_http_proxy, |
748 | + 'https_proxy': amulet_http_proxy, |
749 | + } |
750 | + nova_cc_config['openstack-origin-git'] = yaml.dump(openstack_origin_git) |
751 | keystone_config = {'admin-password': 'openstack', |
752 | 'admin-token': 'ubuntutesting'} |
753 | - configs = {'keystone': keystone_config} |
754 | + configs = {'nova-cloud-controller': nova_cc_config, |
755 | + 'keystone': keystone_config} |
756 | super(NovaCCBasicDeployment, self)._configure_services(configs) |
757 | |
758 | def _initialize_tests(self): |
759 | |
760 | === modified file 'unit_tests/__init__.py' |
761 | --- unit_tests/__init__.py 2015-04-20 10:21:36 +0000 |
762 | +++ unit_tests/__init__.py 2015-06-11 13:34:00 +0000 |
763 | @@ -1,2 +1,4 @@ |
764 | import sys |
765 | + |
766 | +sys.path.append('actions/') |
767 | sys.path.append('hooks/') |
768 | |
769 | === added file 'unit_tests/test_actions_git_reinstall.py' |
770 | --- unit_tests/test_actions_git_reinstall.py 1970-01-01 00:00:00 +0000 |
771 | +++ unit_tests/test_actions_git_reinstall.py 2015-06-11 13:34:00 +0000 |
772 | @@ -0,0 +1,107 @@ |
773 | +from mock import patch, MagicMock |
774 | + |
775 | +with patch('charmhelpers.core.hookenv.config') as config: |
776 | + config.return_value = 'nova' |
777 | + import nova_cc_utils as utils # noqa |
778 | + |
779 | +_reg = utils.register_configs |
780 | +_map = utils.restart_map |
781 | + |
782 | +utils.register_configs = MagicMock() |
783 | +utils.restart_map = MagicMock() |
784 | + |
785 | +with patch('nova_cc_utils.guard_map') as gmap: |
786 | + with patch('charmhelpers.core.hookenv.config') as config: |
787 | + config.return_value = False |
788 | + gmap.return_value = {} |
789 | + import git_reinstall |
790 | + |
791 | +utils.register_configs = _reg |
792 | +utils.restart_map = _map |
793 | + |
794 | +from test_utils import ( |
795 | + CharmTestCase |
796 | +) |
797 | + |
798 | +TO_PATCH = [ |
799 | + 'config', |
800 | +] |
801 | + |
802 | + |
803 | +openstack_origin_git = \ |
804 | + """repositories: |
805 | + - {name: requirements, |
806 | + repository: 'git://git.openstack.org/openstack/requirements', |
807 | + branch: stable/juno} |
808 | + - {name: nova, |
809 | + repository: 'git://git.openstack.org/openstack/nova', |
810 | + branch: stable/juno}""" |
811 | + |
812 | + |
813 | +class TestnovaAPIActions(CharmTestCase): |
814 | + |
815 | + def setUp(self): |
816 | + super(TestnovaAPIActions, self).setUp(git_reinstall, TO_PATCH) |
817 | + self.config.side_effect = self.test_config.get |
818 | + |
819 | + @patch.object(git_reinstall, 'action_set') |
820 | + @patch.object(git_reinstall, 'action_fail') |
821 | + @patch.object(git_reinstall, 'git_install') |
822 | + @patch.object(git_reinstall, 'config_changed') |
823 | + def test_git_reinstall(self, config_changed, git_install, action_fail, |
824 | + action_set): |
825 | + self.test_config.set('openstack-origin-git', openstack_origin_git) |
826 | + |
827 | + git_reinstall.git_reinstall() |
828 | + |
829 | + git_install.assert_called_with(openstack_origin_git) |
830 | + self.assertTrue(git_install.called) |
831 | + self.assertTrue(config_changed.called) |
832 | + self.assertFalse(action_set.called) |
833 | + self.assertFalse(action_fail.called) |
834 | + |
835 | + @patch.object(git_reinstall, 'action_set') |
836 | + @patch.object(git_reinstall, 'action_fail') |
837 | + @patch.object(git_reinstall, 'git_install') |
838 | + @patch.object(git_reinstall, 'config_changed') |
839 | + @patch('charmhelpers.contrib.openstack.utils.config') |
840 | + def test_git_reinstall_not_configured(self, _config, config_changed, |
841 | + git_install, action_fail, |
842 | + action_set): |
843 | + _config.return_value = None |
844 | + |
845 | + git_reinstall.git_reinstall() |
846 | + |
847 | + msg = 'openstack-origin-git is not configured' |
848 | + action_fail.assert_called_with(msg) |
849 | + self.assertFalse(git_install.called) |
850 | + self.assertFalse(action_set.called) |
851 | + |
852 | + @patch.object(git_reinstall, 'action_set') |
853 | + @patch.object(git_reinstall, 'action_fail') |
854 | + @patch.object(git_reinstall, 'git_install') |
855 | + @patch.object(git_reinstall, 'config_changed') |
856 | + @patch('traceback.format_exc') |
857 | + @patch('charmhelpers.contrib.openstack.utils.config') |
858 | + def test_git_reinstall_exception(self, _config, format_exc, |
859 | + config_changed, git_install, action_fail, |
860 | + action_set): |
861 | + _config.return_value = openstack_origin_git |
862 | + e = OSError('something bad happened') |
863 | + git_install.side_effect = e |
864 | + traceback = ( |
865 | + "Traceback (most recent call last):\n" |
866 | + " File \"actions/git_reinstall.py\", line 37, in git_reinstall\n" |
867 | + " git_install(config(\'openstack-origin-git\'))\n" |
868 | + " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 964, in __call__\n" # noqa |
869 | + " return _mock_self._mock_call(*args, **kwargs)\n" |
870 | + " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 1019, in _mock_call\n" # noqa |
871 | + " raise effect\n" |
872 | + "OSError: something bad happened\n") |
873 | + format_exc.return_value = traceback |
874 | + |
875 | + git_reinstall.git_reinstall() |
876 | + |
877 | + msg = 'git-reinstall resulted in an unexpected error' |
878 | + action_fail.assert_called_with(msg) |
879 | + action_set.assert_called_with({'traceback': traceback}) |
880 | |
881 | === modified file 'unit_tests/test_nova_cc_contexts.py' |
882 | --- unit_tests/test_nova_cc_contexts.py 2015-06-03 00:06:30 +0000 |
883 | +++ unit_tests/test_nova_cc_contexts.py 2015-06-11 13:34:00 +0000 |
884 | @@ -9,9 +9,7 @@ |
885 | from charmhelpers.core import hookenv |
886 | _conf = hookenv.config |
887 | hookenv.config = mock.MagicMock() |
888 | -import nova_cc_utils as _utils |
889 | -# this assert is a double check + to avoid pep8 warning |
890 | -assert _utils.config == hookenv.config |
891 | +import nova_cc_utils as _utils # noqa |
892 | hookenv.config = _conf |
893 | ##### |
894 | |
895 | |
896 | === modified file 'unit_tests/test_nova_cc_hooks.py' |
897 | --- unit_tests/test_nova_cc_hooks.py 2015-06-10 20:32:48 +0000 |
898 | +++ unit_tests/test_nova_cc_hooks.py 2015-06-11 13:34:00 +0000 |
899 | @@ -1,6 +1,7 @@ |
900 | from mock import MagicMock, patch, call |
901 | from test_utils import CharmTestCase, patch_open |
902 | import os |
903 | +import yaml |
904 | import tempfile |
905 | |
906 | with patch('charmhelpers.core.hookenv.config') as config: |
907 | @@ -70,6 +71,8 @@ |
908 | 'get_iface_for_address', |
909 | 'get_netmask_for_address', |
910 | 'update_nrpe_config', |
911 | + 'git_install', |
912 | + 'git_install_requested', |
913 | ] |
914 | |
915 | |
916 | @@ -116,12 +119,63 @@ |
917 | self.disable_services.assert_called() |
918 | self.cmd_all_services.assert_called_with('stop') |
919 | |
920 | + def test_install_hook_git(self): |
921 | + self.git_install_requested.return_value = True |
922 | + self.determine_packages.return_value = ['foo', 'bar'] |
923 | + self.determine_ports.return_value = [80, 81, 82] |
924 | + repo = 'cloud:trusty-juno' |
925 | + openstack_origin_git = { |
926 | + 'repositories': [ |
927 | + {'name': 'requirements', |
928 | + 'repository': 'git://git.openstack.org/openstack/requirements', # noqa |
929 | + 'branch': 'stable/juno'}, |
930 | + {'name': 'nova', |
931 | + 'repository': 'git://git.openstack.org/openstack/nova', |
932 | + 'branch': 'stable/juno'} |
933 | + ], |
934 | + 'directory': '/mnt/openstack-git', |
935 | + } |
936 | + projects_yaml = yaml.dump(openstack_origin_git) |
937 | + self.test_config.set('openstack-origin', repo) |
938 | + self.test_config.set('openstack-origin-git', projects_yaml) |
939 | + hooks.install() |
940 | + self.git_install.assert_called_with(projects_yaml) |
941 | + self.apt_install.assert_called_with(['foo', 'bar'], fatal=True) |
942 | + self.execd_preinstall.assert_called() |
943 | + self.disable_services.assert_called() |
944 | + self.cmd_all_services.assert_called_with('stop') |
945 | + |
946 | @patch.object(hooks, 'configure_https') |
947 | def test_config_changed_no_upgrade(self, conf_https): |
948 | + self.git_install_requested.return_value = False |
949 | self.openstack_upgrade_available.return_value = False |
950 | hooks.config_changed() |
951 | self.assertTrue(self.save_script_rc.called) |
952 | |
953 | + @patch.object(hooks, 'config_value_changed') |
954 | + @patch.object(hooks, 'configure_https') |
955 | + def test_config_changed_git(self, configure_https, config_val_changed): |
956 | + self.git_install_requested.return_value = True |
957 | + repo = 'cloud:trusty-juno' |
958 | + openstack_origin_git = { |
959 | + 'repositories': [ |
960 | + {'name': 'requirements', |
961 | + 'repository': |
962 | + 'git://git.openstack.org/openstack/requirements', |
963 | + 'branch': 'stable/juno'}, |
964 | + {'name': 'nova', |
965 | + 'repository': 'git://git.openstack.org/openstack/nova', |
966 | + 'branch': 'stable/juno'} |
967 | + ], |
968 | + 'directory': '/mnt/openstack-git', |
969 | + } |
970 | + projects_yaml = yaml.dump(openstack_origin_git) |
971 | + self.test_config.set('openstack-origin', repo) |
972 | + self.test_config.set('openstack-origin-git', projects_yaml) |
973 | + hooks.config_changed() |
974 | + self.git_install.assert_called_with(projects_yaml) |
975 | + self.assertFalse(self.do_openstack_upgrade.called) |
976 | + |
977 | @patch('charmhelpers.contrib.openstack.ip.service_name', |
978 | lambda *args: 'nova-cloud-controller') |
979 | @patch.object(hooks, 'cluster_joined') |
980 | @@ -130,6 +184,7 @@ |
981 | @patch.object(hooks, 'configure_https') |
982 | def test_config_changed_with_upgrade(self, conf_https, neutron_api_joined, |
983 | identity_joined, cluster_joined): |
984 | + self.git_install_requested.return_value = False |
985 | self.openstack_upgrade_available.return_value = True |
986 | self.relation_ids.return_value = ['generic_rid'] |
987 | _zmq_joined = self.patch('zeromq_configuration_relation_joined') |
988 | @@ -768,6 +823,7 @@ |
989 | @patch('nova_cc_hooks.configure_https') |
990 | @patch('nova_cc_utils.config') |
991 | def test_config_changed_single_consoleauth(self, config, *args): |
992 | + self.git_install_requested.return_value = False |
993 | config.return_value = 'novnc' |
994 | rids = {'ha': ['ha:1']} |
995 | |
996 | |
997 | === modified file 'unit_tests/test_nova_cc_utils.py' |
998 | --- unit_tests/test_nova_cc_utils.py 2015-05-11 09:51:21 +0000 |
999 | +++ unit_tests/test_nova_cc_utils.py 2015-06-11 13:34:00 +0000 |
1000 | @@ -127,6 +127,15 @@ |
1001 | '--option', 'Dpkg::Options::=--force-confdef', |
1002 | ] |
1003 | |
1004 | +openstack_origin_git = \ |
1005 | + """repositories: |
1006 | + - {name: requirements, |
1007 | + repository: 'git://git.openstack.org/openstack/requirements', |
1008 | + branch: stable/juno} |
1009 | + - {name: nova, |
1010 | + repository: 'git://git.openstack.org/openstack/nova', |
1011 | + branch: stable/juno}""" |
1012 | + |
1013 | |
1014 | def fake_plugin_attribute(plugin, attr, net_manager): |
1015 | if plugin in PLUGIN_ATTRIBUTES: |
1016 | @@ -298,26 +307,34 @@ |
1017 | self.assertEquals(_proxy_page, None) |
1018 | |
1019 | @patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext') |
1020 | - def test_determine_packages_quantum(self, subcontext): |
1021 | + @patch.object(utils, 'git_install_requested') |
1022 | + def test_determine_packages_quantum(self, git_requested, subcontext): |
1023 | + git_requested.return_value = False |
1024 | self._resource_map(network_manager='quantum') |
1025 | pkgs = utils.determine_packages() |
1026 | self.assertIn('quantum-server', pkgs) |
1027 | |
1028 | @patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext') |
1029 | - def test_determine_packages_neutron(self, subcontext): |
1030 | + @patch.object(utils, 'git_install_requested') |
1031 | + def test_determine_packages_neutron(self, git_requested, subcontext): |
1032 | + git_requested.return_value = False |
1033 | self.is_relation_made.return_value = False |
1034 | self._resource_map(network_manager='neutron') |
1035 | pkgs = utils.determine_packages() |
1036 | self.assertIn('neutron-server', pkgs) |
1037 | |
1038 | @patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext') |
1039 | - def test_determine_packages_nova_volume(self, subcontext): |
1040 | + @patch.object(utils, 'git_install_requested') |
1041 | + def test_determine_packages_nova_volume(self, git_requested, subcontext): |
1042 | + git_requested.return_value = False |
1043 | self.relation_ids.return_value = ['nova-volume-service:0'] |
1044 | pkgs = utils.determine_packages() |
1045 | self.assertIn('nova-api-os-volume', pkgs) |
1046 | |
1047 | @patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext') |
1048 | - def test_determine_packages_console(self, subcontext): |
1049 | + @patch.object(utils, 'git_install_requested') |
1050 | + def test_determine_packages_console(self, git_requested, subcontext): |
1051 | + git_requested.return_value = False |
1052 | self.test_config.set('console-access-protocol', 'spice') |
1053 | self.relation_ids.return_value = [] |
1054 | pkgs = utils.determine_packages() |
1055 | @@ -326,7 +343,9 @@ |
1056 | self.assertIn(console_pkg, pkgs) |
1057 | |
1058 | @patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext') |
1059 | - def test_determine_packages_base(self, subcontext): |
1060 | + @patch.object(utils, 'git_install_requested') |
1061 | + def test_determine_packages_base(self, git_requested, subcontext): |
1062 | + git_requested.return_value = False |
1063 | self.relation_ids.return_value = [] |
1064 | self.os_release.return_value = 'folsom' |
1065 | pkgs = utils.determine_packages() |
1066 | @@ -334,7 +353,10 @@ |
1067 | self.assertEquals(ex, pkgs) |
1068 | |
1069 | @patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext') |
1070 | - def test_determine_packages_base_grizzly_beyond(self, subcontext): |
1071 | + @patch.object(utils, 'git_install_requested') |
1072 | + def test_determine_packages_base_grizzly_beyond(self, git_requested, |
1073 | + subcontext): |
1074 | + git_requested.return_value = False |
1075 | self.relation_ids.return_value = [] |
1076 | self.os_release.return_value = 'grizzly' |
1077 | pkgs = utils.determine_packages() |
1078 | @@ -847,3 +869,264 @@ |
1079 | self.assertFalse(self.service_running.called) |
1080 | self.assertFalse(self.service_stop.called) |
1081 | self.assertTrue(contexts.complete_contexts.called) |
1082 | + |
1083 | + @patch.object(utils, 'git_install_requested') |
1084 | + @patch.object(utils, 'git_clone_and_install') |
1085 | + @patch.object(utils, 'git_post_install') |
1086 | + @patch.object(utils, 'git_pre_install') |
1087 | + def test_git_install(self, git_pre, git_post, git_clone_and_install, |
1088 | + git_requested): |
1089 | + projects_yaml = openstack_origin_git |
1090 | + git_requested.return_value = True |
1091 | + utils.git_install(projects_yaml) |
1092 | + self.assertTrue(git_pre.called) |
1093 | + git_clone_and_install.assert_called_with(openstack_origin_git, |
1094 | + core_project='nova') |
1095 | + self.assertTrue(git_post.called) |
1096 | + |
1097 | + @patch.object(utils, 'mkdir') |
1098 | + @patch.object(utils, 'add_user_to_group') |
1099 | + @patch.object(utils, 'add_group') |
1100 | + @patch.object(utils, 'adduser') |
1101 | + @patch('subprocess.check_call') |
1102 | + def test_git_pre_install(self, check_call, adduser, add_group, |
1103 | + add_user_to_group, mkdir): |
1104 | + utils.git_pre_install() |
1105 | + expected = [ |
1106 | + call('nova', shell='/bin/bash', system_user=True), |
1107 | + call('neutron', shell='/bin/bash', system_user=True), |
1108 | + ] |
1109 | + self.assertEquals(adduser.call_args_list, expected) |
1110 | + check_call.assert_called_with(['usermod', '--home', '/var/lib/nova', |
1111 | + 'nova']) |
1112 | + expected = [ |
1113 | + call('nova', system_group=True), |
1114 | + call('neutron', system_group=True), |
1115 | + ] |
1116 | + self.assertEquals(add_group.call_args_list, expected) |
1117 | + expected = [ |
1118 | + call('nova', 'nova'), |
1119 | + call('neutron', 'neutron'), |
1120 | + ] |
1121 | + self.assertEquals(add_user_to_group.call_args_list, expected) |
1122 | + expected = [ |
1123 | + call('/var/lib/nova', owner='nova', |
1124 | + group='nova', perms=0755, force=False), |
1125 | + call('/var/lib/nova/buckets', owner='nova', |
1126 | + group='nova', perms=0755, force=False), |
1127 | + call('/var/lib/nova/CA', owner='nova', |
1128 | + group='nova', perms=0755, force=False), |
1129 | + call('/var/lib/nova/CA/INTER', owner='nova', |
1130 | + group='nova', perms=0755, force=False), |
1131 | + call('/var/lib/nova/CA/newcerts', owner='nova', |
1132 | + group='nova', perms=0755, force=False), |
1133 | + call('/var/lib/nova/CA/private', owner='nova', |
1134 | + group='nova', perms=0755, force=False), |
1135 | + call('/var/lib/nova/CA/reqs', owner='nova', |
1136 | + group='nova', perms=0755, force=False), |
1137 | + call('/var/lib/nova/images', owner='nova', |
1138 | + group='nova', perms=0755, force=False), |
1139 | + call('/var/lib/nova/instances', owner='nova', |
1140 | + group='nova', perms=0755, force=False), |
1141 | + call('/var/lib/nova/keys', owner='nova', |
1142 | + group='nova', perms=0755, force=False), |
1143 | + call('/var/lib/nova/networks', owner='nova', |
1144 | + group='nova', perms=0755, force=False), |
1145 | + call('/var/lib/nova/tmp', owner='nova', |
1146 | + group='nova', perms=0755, force=False), |
1147 | + call('/var/lib/neutron', owner='nova', |
1148 | + group='nova', perms=0755, force=False), |
1149 | + call('/var/lib/neutron/lock', owner='nova', |
1150 | + group='nova', perms=0755, force=False), |
1151 | + call('/var/log/nova', owner='nova', |
1152 | + group='nova', perms=0755, force=False), |
1153 | + call('/etc/neutron', owner='nova', |
1154 | + group='nova', perms=0755, force=False), |
1155 | + call('/etc/neutron/plugins', owner='nova', |
1156 | + group='nova', perms=0755, force=False), |
1157 | + call('/etc/neutron/plugins/ml2', owner='nova', |
1158 | + group='nova', perms=0755, force=False), |
1159 | + ] |
1160 | + self.assertEquals(mkdir.call_args_list, expected) |
1161 | + |
1162 | + @patch.object(utils, 'git_src_dir') |
1163 | + @patch.object(utils, 'render') |
1164 | + @patch.object(utils, 'git_pip_venv_dir') |
1165 | + @patch.object(utils, 'pip_install') |
1166 | + @patch('os.path.join') |
1167 | + @patch('os.path.exists') |
1168 | + @patch('os.symlink') |
1169 | + @patch('shutil.copytree') |
1170 | + @patch('shutil.rmtree') |
1171 | + def test_git_post_install(self, rmtree, copytree, symlink, |
1172 | + exists, join, pip_install, venv, render, |
1173 | + git_src_dir): |
1174 | + projects_yaml = openstack_origin_git |
1175 | + join.return_value = 'joined-string' |
1176 | + venv.return_value = '/mnt/openstack-git/venv' |
1177 | + utils.git_post_install(projects_yaml) |
1178 | + expected = [ |
1179 | + call('joined-string', '/etc/nova'), |
1180 | + ] |
1181 | + copytree.assert_has_calls(expected) |
1182 | + expected = [ |
1183 | + call('joined-string', '/usr/local/bin/nova-manage'), |
1184 | + call('joined-string', '/usr/local/bin/nova-rootwrap'), |
1185 | + ] |
1186 | + |
1187 | + nova_cc = 'nova-cloud-controller' |
1188 | + nova_user = 'nova' |
1189 | + start_dir = '/var/lib/nova' |
1190 | + nova_conf = '/etc/nova/nova.conf' |
1191 | + nova_ec2_api_context = { |
1192 | + 'service_description': 'Nova EC2 API server', |
1193 | + 'service_name': nova_cc, |
1194 | + 'user_name': nova_user, |
1195 | + 'start_dir': start_dir, |
1196 | + 'process_name': 'nova-api-ec2', |
1197 | + 'executable_name': 'joined-string', |
1198 | + 'config_files': [nova_conf], |
1199 | + } |
1200 | + nova_api_os_compute_context = { |
1201 | + 'service_description': 'Nova OpenStack Compute API server', |
1202 | + 'service_name': nova_cc, |
1203 | + 'user_name': nova_user, |
1204 | + 'start_dir': start_dir, |
1205 | + 'process_name': 'nova-api-os-compute', |
1206 | + 'executable_name': 'joined-string', |
1207 | + 'config_files': [nova_conf], |
1208 | + } |
1209 | + nova_cells_context = { |
1210 | + 'service_description': 'Nova cells', |
1211 | + 'service_name': nova_cc, |
1212 | + 'user_name': nova_user, |
1213 | + 'start_dir': start_dir, |
1214 | + 'process_name': 'nova-cells', |
1215 | + 'executable_name': 'joined-string', |
1216 | + 'config_files': [nova_conf], |
1217 | + } |
1218 | + nova_cert_context = { |
1219 | + 'service_description': 'Nova cert', |
1220 | + 'service_name': nova_cc, |
1221 | + 'user_name': nova_user, |
1222 | + 'start_dir': start_dir, |
1223 | + 'process_name': 'nova-cert', |
1224 | + 'executable_name': 'joined-string', |
1225 | + 'config_files': [nova_conf], |
1226 | + } |
1227 | + nova_conductor_context = { |
1228 | + 'service_description': 'Nova conductor', |
1229 | + 'service_name': nova_cc, |
1230 | + 'user_name': nova_user, |
1231 | + 'start_dir': start_dir, |
1232 | + 'process_name': 'nova-conductor', |
1233 | + 'executable_name': 'joined-string', |
1234 | + 'config_files': [nova_conf], |
1235 | + } |
1236 | + nova_consoleauth_context = { |
1237 | + 'service_description': 'Nova console auth', |
1238 | + 'service_name': nova_cc, |
1239 | + 'user_name': nova_user, |
1240 | + 'start_dir': start_dir, |
1241 | + 'process_name': 'nova-consoleauth', |
1242 | + 'executable_name': 'joined-string', |
1243 | + 'config_files': [nova_conf], |
1244 | + } |
1245 | + nova_console_context = { |
1246 | + 'service_description': 'Nova console', |
1247 | + 'service_name': nova_cc, |
1248 | + 'user_name': nova_user, |
1249 | + 'start_dir': start_dir, |
1250 | + 'process_name': 'nova-console', |
1251 | + 'executable_name': 'joined-string', |
1252 | + 'config_files': [nova_conf], |
1253 | + } |
1254 | + nova_novncproxy_context = { |
1255 | + 'service_description': 'Nova NoVNC proxy', |
1256 | + 'service_name': nova_cc, |
1257 | + 'user_name': nova_user, |
1258 | + 'start_dir': start_dir, |
1259 | + 'process_name': 'nova-novncproxy', |
1260 | + 'executable_name': 'joined-string', |
1261 | + 'config_files': [nova_conf], |
1262 | + } |
1263 | + nova_objectstore_context = { |
1264 | + 'service_description': 'Nova object store', |
1265 | + 'service_name': nova_cc, |
1266 | + 'user_name': nova_user, |
1267 | + 'start_dir': start_dir, |
1268 | + 'process_name': 'nova-objectstore', |
1269 | + 'executable_name': 'joined-string', |
1270 | + 'config_files': [nova_conf], |
1271 | + } |
1272 | + nova_scheduler_context = { |
1273 | + 'service_description': 'Nova scheduler', |
1274 | + 'service_name': nova_cc, |
1275 | + 'user_name': nova_user, |
1276 | + 'start_dir': start_dir, |
1277 | + 'process_name': 'nova-scheduler', |
1278 | + 'executable_name': 'joined-string', |
1279 | + 'config_files': [nova_conf], |
1280 | + } |
1281 | + nova_spiceproxy_context = { |
1282 | + 'service_description': 'Nova spice proxy', |
1283 | + 'service_name': nova_cc, |
1284 | + 'user_name': nova_user, |
1285 | + 'start_dir': start_dir, |
1286 | + 'process_name': 'nova-spicehtml5proxy', |
1287 | + 'executable_name': 'joined-string', |
1288 | + 'config_files': [nova_conf], |
1289 | + } |
1290 | + nova_xvpvncproxy_context = { |
1291 | + 'service_description': 'Nova XVPVNC proxy', |
1292 | + 'service_name': nova_cc, |
1293 | + 'user_name': nova_user, |
1294 | + 'start_dir': start_dir, |
1295 | + 'process_name': 'nova-xvpvncproxy', |
1296 | + 'executable_name': 'joined-string', |
1297 | + 'config_files': [nova_conf], |
1298 | + } |
1299 | + expected = [ |
1300 | + call('git/nova_sudoers', '/etc/sudoers.d/nova_sudoers', |
1301 | + {}, perms=0o440), |
1302 | + call('git.upstart', '/etc/init/nova-api-ec2.conf', |
1303 | + nova_ec2_api_context, perms=0o644, |
1304 | + templates_dir='joined-string'), |
1305 | + call('git.upstart', '/etc/init/nova-api-os-compute.conf', |
1306 | + nova_api_os_compute_context, perms=0o644, |
1307 | + templates_dir='joined-string'), |
1308 | + call('git.upstart', '/etc/init/nova-cells.conf', |
1309 | + nova_cells_context, perms=0o644, |
1310 | + templates_dir='joined-string'), |
1311 | + call('git.upstart', '/etc/init/nova-cert.conf', |
1312 | + nova_cert_context, perms=0o644, |
1313 | + templates_dir='joined-string'), |
1314 | + call('git.upstart', '/etc/init/nova-conductor.conf', |
1315 | + nova_conductor_context, perms=0o644, |
1316 | + templates_dir='joined-string'), |
1317 | + call('git.upstart', '/etc/init/nova-consoleauth.conf', |
1318 | + nova_consoleauth_context, perms=0o644, |
1319 | + templates_dir='joined-string'), |
1320 | + call('git.upstart', '/etc/init/nova-console.conf', |
1321 | + nova_console_context, perms=0o644, |
1322 | + templates_dir='joined-string'), |
1323 | + call('git.upstart', '/etc/init/nova-novncproxy.conf', |
1324 | + nova_novncproxy_context, perms=0o644, |
1325 | + templates_dir='joined-string'), |
1326 | + call('git.upstart', '/etc/init/nova-objectstore.conf', |
1327 | + nova_objectstore_context, perms=0o644, |
1328 | + templates_dir='joined-string'), |
1329 | + call('git.upstart', '/etc/init/nova-scheduler.conf', |
1330 | + nova_scheduler_context, perms=0o644, |
1331 | + templates_dir='joined-string'), |
1332 | + call('git.upstart', '/etc/init/nova-spiceproxy.conf', |
1333 | + nova_spiceproxy_context, perms=0o644, |
1334 | + templates_dir='joined-string'), |
1335 | + call('git.upstart', '/etc/init/nova-xvpvncproxy.conf', |
1336 | + nova_xvpvncproxy_context, perms=0o644, |
1337 | + templates_dir='joined-string'), |
1338 | + ] |
1339 | + self.assertEquals(render.call_args_list, expected) |
1340 | + self.assertTrue(self.apt_update.called) |
1341 | + self.apt_install.assert_called_with(['novnc', 'spice-html5', |
1342 | + 'websockify'], fatal=True) |
charm_lint_check #4463 nova-cloud- controller- next for corey.bryant mp258923
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/4463/