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

Proposed by Corey Bryant
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
Reviewer Review Type Date Requested Status
James Page Needs Fixing
Review via email: mp+258923@code.launchpad.net
To post a comment you must log in.
176. By Corey Bryant

Add libyaml-dev as base git package

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

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/

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

charm_unit_test #4188 nova-cloud-controller-next for corey.bryant mp258923
    UNIT OK: passed

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

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

charm_amulet_test #4086 nova-cloud-controller-next for corey.bryant mp258923
    AMULET OK: passed

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

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

charm_lint_check #4531 nova-cloud-controller-next for corey.bryant mp258923
    LINT OK: passed

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

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

charm_unit_test #4256 nova-cloud-controller-next for corey.bryant mp258923
    UNIT OK: passed

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

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

charm_amulet_test #4110 nova-cloud-controller-next for corey.bryant mp258923
    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/11118316/
Build: http://10.245.162.77:8080/job/charm_amulet_test/4110/

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

charm_lint_check #4539 nova-cloud-controller-next for corey.bryant mp258923
    LINT OK: passed

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

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

charm_unit_test #4264 nova-cloud-controller-next for corey.bryant mp258923
    UNIT OK: passed

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

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

charm_amulet_test #4118 nova-cloud-controller-next for corey.bryant mp258923
    AMULET OK: passed

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

177. By Corey Bryant

Sync charm-helpers

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

charm_lint_check #4843 nova-cloud-controller-next for corey.bryant mp258923
    LINT OK: passed

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

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

charm_unit_test #4523 nova-cloud-controller-next for corey.bryant mp258923
    UNIT OK: passed

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

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

charm_amulet_test #4334 nova-cloud-controller-next for corey.bryant mp258923
    AMULET OK: passed

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

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

Looks OK - but see unit test failure on merged branch:

======================================================================
ERROR: test_config_changed_single_consoleauth (unit_tests.test_nova_cc_hooks.NovaCCHooksTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/mock.py", line 1210, in patched
    return func(*args, **keywargs)
  File "/home/jamespage/src/charms/git/nova-cloud-controller/unit_tests/test_nova_cc_hooks.py", line 800, in test_config_changed_single_consoleauth
    hooks.config_changed()
  File "hooks/nova_cc_utils.py", line 1005, in wrapped_f
    f(*args)
  File "hooks/charmhelpers/core/host.py", line 312, in wrapped_f
    f(*args, **kwargs)
  File "hooks/nova_cc_hooks.py", line 180, in config_changed
    if config_value_changed('openstack-origin-git'):
  File "hooks/charmhelpers/contrib/openstack/utils.py", line 346, in config_value_changed
    with hook_data():
  File "/usr/lib/python2.7/contextlib.py", line 17, in __enter__
    return self.gen.next()
  File "hooks/charmhelpers/core/unitdata.py", line 425, in __call__
    self._record_charm_version(hookenv.charm_dir())
  File "hooks/charmhelpers/core/unitdata.py", line 435, in _record_charm_version
    os.path.join(charm_dir, 'revision')).read().strip()
  File "/usr/lib/python2.7/posixpath.py", line 70, in join
    elif path == '' or path.endswith('/'):
AttributeError: 'NoneType' object has no attribute 'endswith'

review: Needs Fixing
178. By Corey Bryant

Merge next branch

179. By Corey Bryant

Update failing unit test

Revision history for this message
Corey Bryant (corey.bryant) wrote :

Thanks for the review! I've merged the latest next branch and updated the failing test.

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

charm_lint_check #5239 nova-cloud-controller-next for corey.bryant mp258923
    LINT OK: passed

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

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

charm_unit_test #4918 nova-cloud-controller-next for corey.bryant mp258923
    UNIT OK: passed

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

180. By Corey Bryant

Merge next branch

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

charm_lint_check #5338 nova-cloud-controller-next for corey.bryant mp258923
    LINT OK: passed

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

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

charm_unit_test #4971 nova-cloud-controller-next for corey.bryant mp258923
    UNIT OK: passed

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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)

Subscribers

People subscribed via source and target branches