Merge lp:~corey.bryant/charms/trusty/nova-cloud-controller/git into lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next

Proposed by Corey Bryant
Status: Superseded
Proposed branch: lp:~corey.bryant/charms/trusty/nova-cloud-controller/git
Merge into: lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next
Diff against target: 1382 lines (+956/-74)
23 files modified
.bzrignore (+1/-0)
Makefile (+5/-3)
README.txt (+85/-0)
actions.yaml (+2/-0)
actions/git_reinstall.py (+45/-0)
config.yaml (+16/-0)
hooks/charmhelpers/contrib/openstack/utils.py (+4/-1)
hooks/nova_cc_hooks.py (+17/-6)
hooks/nova_cc_utils.py (+272/-1)
templates/git/nova_sudoers (+4/-0)
tests/10-basic-precise-essex (+0/-10)
tests/11-basic-precise-folsom (+0/-18)
tests/12-basic-precise-grizzly (+0/-12)
tests/13-basic-precise-havana (+0/-12)
tests/16-basic-trusty-icehouse-git (+10/-0)
tests/17-basic-trusty-juno (+12/-0)
tests/18-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 (+55/-0)
unit_tests/test_nova_cc_utils.py (+280/-6)
To merge this branch: bzr merge lp:~corey.bryant/charms/trusty/nova-cloud-controller/git
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+256298@code.launchpad.net
To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3416 nova-cloud-controller-next for corey.bryant mp256298
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3416/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #3204 nova-cloud-controller-next for corey.bryant mp256298
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3204/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #3209 nova-cloud-controller-next for corey.bryant mp256298
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/3209/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3448 nova-cloud-controller-next for corey.bryant mp256298
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3448/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #3236 nova-cloud-controller-next for corey.bryant mp256298
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3236/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3457 nova-cloud-controller-next for corey.bryant mp256298
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3457/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #3245 nova-cloud-controller-next for corey.bryant mp256298
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3245/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3464 nova-cloud-controller-next for corey.bryant mp256298
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3464/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #3252 nova-cloud-controller-next for corey.bryant mp256298
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3252/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #3261 nova-cloud-controller-next for corey.bryant mp256298
    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://paste.ubuntu.com/10834679/
Build: http://10.245.162.77:8080/job/charm_amulet_test/3261/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3517 nova-cloud-controller-next for corey.bryant mp256298
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3517/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #3305 nova-cloud-controller-next for corey.bryant mp256298
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3305/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #3272 nova-cloud-controller-next for corey.bryant mp256298
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [test] Error 124
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/10835667/
Build: http://10.245.162.77:8080/job/charm_amulet_test/3272/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #3541 nova-cloud-controller-next for corey.bryant mp256298
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3541/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #3329 nova-cloud-controller-next for corey.bryant mp256298
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3329/

158. By Corey Bryant

Sync charm-helpers

159. By Corey Bryant

Add libffi-dev, libssl-dev, and libyaml-dev to base git install packages

160. By Corey Bryant

Add nova serial proxy upstart script

161. By Corey Bryant

Generalize neutron-db-manage and quantum-db-manage executable names as they may come from /usr/local/bin when deploying from source.

162. By Corey Bryant

Merge next branch

163. By Corey Bryant

Put base packages in correct list

164. By Corey Bryant

Sync charm-helpers

165. By Corey Bryant

Sync charm-helpers

166. By Corey Bryant

Install neutorn-common as python-six conflict workaround

167. By Corey Bryant

Sync charm-helpers

168. By Corey Bryant

Drop libffi-dev, libssl-dev, and libyaml-dev.

Unmerged revisions

Preview Diff

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

Subscribers

People subscribed via source and target branches