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

Proposed by Corey Bryant
Status: Merged
Merged at revision: 86
Proposed branch: lp:~corey.bryant/charms/trusty/cinder/git
Merge into: lp:~openstack-charmers-archive/charms/trusty/cinder/next
Diff against target: 1450 lines (+899/-90)
30 files modified
Makefile (+6/-2)
README.md (+91/-0)
actions.yaml (+2/-0)
actions/git_reinstall.py (+45/-0)
charm-helpers-hooks.yaml (+1/-1)
config.yaml (+16/-0)
hooks/charmhelpers/contrib/openstack/utils.py (+4/-1)
hooks/cinder_hooks.py (+18/-8)
hooks/cinder_utils.py (+181/-4)
templates/git/cinder_sudoers (+4/-0)
templates/git/cinder_tgt.conf (+1/-0)
templates/git/logging.conf (+76/-0)
tests/00-setup (+3/-2)
tests/11-basic-precise-folsom (+0/-11)
tests/12-basic-precise-grizzly (+0/-11)
tests/13-basic-precise-havana (+0/-11)
tests/16-basic-trusty-icehouse-git (+9/-0)
tests/16-basic-vivid-kilo (+0/-9)
tests/17-basic-trusty-juno (+11/-0)
tests/17-basic-trusty-kilo (+0/-11)
tests/18-basic-trusty-juno-git (+12/-0)
tests/19-basic-trusty-kilo (+11/-0)
tests/20-basic-trusty-kilo-git (+12/-0)
tests/21-basic-vivid-kilo (+9/-0)
tests/22-basic-vivid-kilo-git (+9/-0)
tests/basic_deployment.py (+27/-3)
unit_tests/__init__.py (+2/-0)
unit_tests/test_actions_git_reinstall.py (+110/-0)
unit_tests/test_cinder_hooks.py (+74/-10)
unit_tests/test_cinder_utils.py (+165/-6)
To merge this branch: bzr merge lp:~corey.bryant/charms/trusty/cinder/git
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+254951@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Corey Bryant (corey.bryant) wrote :

The conflicts don't make any sense to me so I'm leaving them as is. I don't think they're an issue.

92. By Corey Bryant

Move config_changed into try block

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

charm_lint_check #3409 cinder-next for corey.bryant mp254951
    LINT OK: passed

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

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

charm_unit_test #3197 cinder-next for corey.bryant mp254951
    UNIT OK: passed

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

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

charm_amulet_test #3202 cinder-next for corey.bryant mp254951
    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/10828226/
Build: http://10.245.162.77:8080/job/charm_amulet_test/3202/

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

The only amulet tests that are failing are kilo based tests.

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

> The only amulet tests that are failing are kilo based tests.

And that is expected atm.

93. By Corey Bryant

Sync charm-helpers

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

charm_lint_check #3451 cinder-next for corey.bryant mp254951
    LINT OK: passed

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

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

charm_unit_test #3239 cinder-next for corey.bryant mp254951
    UNIT OK: passed

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2015-02-19 11:51:46 +0000
+++ Makefile 2015-04-16 14:41:14 +0000
@@ -2,7 +2,7 @@
2PYTHON := /usr/bin/env python2PYTHON := /usr/bin/env python
33
4lint:4lint:
5 @flake8 --exclude hooks/charmhelpers hooks unit_tests tests5 @flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests
6 @charm proof6 @charm proof
77
8unit_test:8unit_test:
@@ -14,7 +14,11 @@
14 #NOTE(beisner): can remove -v after bug 1320357 is fixed14 #NOTE(beisner): can remove -v after bug 1320357 is fixed
15 # https://bugs.launchpad.net/amulet/+bug/132035715 # https://bugs.launchpad.net/amulet/+bug/1320357
16 @juju test -v -p AMULET_HTTP_PROXY --timeout 900 \16 @juju test -v -p AMULET_HTTP_PROXY --timeout 900 \
17 00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse17 00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse \
18 16-basic-trusty-icehouse-git 17-basic-trusty-juno \
19 18-basic-trusty-juno-git 19-basic-trusty-kilo \
20 20-basic-trusty-kilo-git 21-basic-vivid-kilo \
21 22-basic-vivid-kilo-git
1822
19bin/charm_helpers_sync.py:23bin/charm_helpers_sync.py:
20 @mkdir -p bin24 @mkdir -p bin
2125
=== modified file 'README.md'
--- README.md 2015-01-08 12:03:18 +0000
+++ README.md 2015-04-16 14:41:14 +0000
@@ -117,3 +117,94 @@
117117
118enabled-services: Can be used to separate cinder services between service118enabled-services: Can be used to separate cinder services between service
119 service units (see previous section)119 service units (see previous section)
120
121Deploying from source
122---------------------
123
124The minimum openstack-origin-git config required to deploy from source is:
125
126 openstack-origin-git:
127 "repositories:
128 - {name: requirements,
129 repository: 'git://git.openstack.org/openstack/requirements',
130 branch: stable/juno}
131 - {name: cinder,
132 repository: 'git://git.openstack.org/openstack/cinder',
133 branch: stable/juno}"
134
135Note that there are only two 'name' values the charm knows about: 'requirements'
136and 'cinder'. These repositories must correspond to these 'name' values.
137Additionally, the requirements repository must be specified first and the
138cinder repository must be specified last. All other repostories are installed
139in the order in which they are specified.
140
141The following is a full list of current tip repos (may not be up-to-date):
142
143 openstack-origin-git:
144 "repositories:
145 - {name: requirements,
146 repository: 'git://git.openstack.org/openstack/requirements',
147 branch: master}
148 - {name: oslo-concurrency,
149 repository: 'git://git.openstack.org/openstack/oslo.concurrency',
150 branch: master}
151 - {name: oslo-config,
152 repository: 'git://git.openstack.org/openstack/oslo.config',
153 branch: master}
154 - {name: oslo-context,
155 repository': 'git://git.openstack.org/openstack/oslo.context.git',
156 branch: master}
157 - {name: oslo-db,
158 repository: 'git://git.openstack.org/openstack/oslo.db',
159 branch: master}
160 - {name: oslo-i18n,
161 repository: 'git://git.openstack.org/openstack/oslo.i18n',
162 branch: master}
163 - {name: oslo-messaging,
164 repository: 'git://git.openstack.org/openstack/oslo.messaging.git',
165 branch: master}
166 - {name: oslo-serialization,
167 repository: 'git://git.openstack.org/openstack/oslo.serialization',
168 branch: master}
169 - {name: oslo-utils,
170 repository: 'git://git.openstack.org/openstack/oslo.utils',
171 branch: master}
172 - {name: oslo-rootwrap,
173 repository: 'git://git.openstack.org/openstack/oslo.rootwrap.git',
174 branch: master}
175 - {name: oslo-vmware,
176 repository: 'git://git.openstack.org/openstack/oslo.vmware.git',
177 branch: master}
178 - {name: osprofiler,
179 repository: 'git://git.openstack.org/stackforge/osprofiler.git',
180 branch: master}
181 - {name: pbr,
182 repository: 'git://git.openstack.org/openstack-dev/pbr',
183 branch: master}
184 - {name: python-barbicanclient,
185 repository: 'git://git.openstack.org/openstack/python-barbicanclient.git',
186 branch: master}
187 - {name: python-glanceclient,
188 repository: 'git://git.openstack.org/openstack/python-glanceclient.git',
189 branch: master}
190 - {name: python-novaclient,
191 repository: 'git://git.openstack.org/openstack/python-novaclient.git',
192 branch: master}
193 - {name: python-swiftclient:
194 repository: 'git://git.openstack.org/openstack/python-swiftclient.git',
195 branch: master}
196 - {name: sqlalchemy-migrate,
197 repository: 'git://git.openstack.org/stackforge/sqlalchemy-migrate',
198 branch: master}
199 - {name: stevedore,
200 repository: 'git://git.openstack.org/openstack/stevedore.git',
201 branch: master}
202 - {name: taskflow,
203 repository: 'git://git.openstack.org/openstack/taskflow.git',
204 branch: master}
205 - {name: keystonemiddleware,
206 repository: 'git://git.openstack.org/openstack/keystonemiddleware',
207 branch: master}
208 - {name: cinder,
209 repository: 'git://git.openstack.org/openstack/cinder',
210 branch: master}"
120211
=== added directory 'actions'
=== added file 'actions.yaml'
--- actions.yaml 1970-01-01 00:00:00 +0000
+++ actions.yaml 2015-04-16 14:41:14 +0000
@@ -0,0 +1,2 @@
1git-reinstall:
2 description: Reinstall cinder from the openstack-origin-git repositories.
03
=== added symlink 'actions/git-reinstall'
=== target is u'git_reinstall.py'
=== added file 'actions/git_reinstall.py'
--- actions/git_reinstall.py 1970-01-01 00:00:00 +0000
+++ actions/git_reinstall.py 2015-04-16 14:41:14 +0000
@@ -0,0 +1,45 @@
1#!/usr/bin/python
2import sys
3import traceback
4
5sys.path.append('hooks/')
6
7from charmhelpers.contrib.openstack.utils import (
8 git_install_requested,
9)
10
11from charmhelpers.core.hookenv import (
12 action_set,
13 action_fail,
14 config,
15)
16
17from cinder_utils import (
18 git_install,
19)
20
21from cinder_hooks import (
22 config_changed,
23)
24
25
26def git_reinstall():
27 """Reinstall from source and restart services.
28
29 If the openstack-origin-git config option was used to install openstack
30 from source git repositories, then this action can be used to reinstall
31 from updated git repositories, followed by a restart of services."""
32 if not git_install_requested():
33 action_fail('openstack-origin-git is not configured')
34 return
35
36 try:
37 git_install(config('openstack-origin-git'))
38 config_changed()
39 except:
40 action_set({'traceback': traceback.format_exc()})
41 action_fail('git-reinstall resulted in an unexpected error')
42
43
44if __name__ == '__main__':
45 git_reinstall()
046
=== modified file 'charm-helpers-hooks.yaml'
--- charm-helpers-hooks.yaml 2015-03-18 18:35:28 +0000
+++ charm-helpers-hooks.yaml 2015-04-16 14:41:14 +0000
@@ -1,4 +1,4 @@
1branch: lp:charm-helpers 1branch: lp:charm-helpers
2destination: hooks/charmhelpers2destination: hooks/charmhelpers
3include:3include:
4 - core4 - core
55
=== modified file 'config.yaml'
--- config.yaml 2015-03-16 09:38:03 +0000
+++ config.yaml 2015-04-16 14:41:14 +0000
@@ -15,6 +15,22 @@
15 the cloud:precise-folsom/updates repository instead, since Cinder15 the cloud:precise-folsom/updates repository instead, since Cinder
16 was not available in the Ubuntu archive for Precise and is only16 was not available in the Ubuntu archive for Precise and is only
17 available via the Ubuntu Cloud Archive.17 available via the Ubuntu Cloud Archive.
18
19 Note that when openstack-origin-git is specified, openstack
20 specific packages will be installed from source rather than
21 from the openstack-origin repository.
22 openstack-origin-git:
23 default:
24 type: string
25 description: |
26 Specifies a YAML-formatted dictionary listing the git
27 repositories and branches from which to install OpenStack and
28 its dependencies.
29
30 Note that the installed config files will be determined based on
31 the OpenStack release of the openstack-origin option.
32
33 For more details see README.md.
18 enabled-services:34 enabled-services:
19 default: all35 default: all
20 type: string36 type: string
2137
=== modified file 'hooks/charmhelpers/contrib/openstack/utils.py'
--- hooks/charmhelpers/contrib/openstack/utils.py 2015-04-09 04:52:26 +0000
+++ hooks/charmhelpers/contrib/openstack/utils.py 2015-04-16 14:41:14 +0000
@@ -524,9 +524,10 @@
524 projects = yaml.load(projects_yaml)524 projects = yaml.load(projects_yaml)
525 _git_validate_projects_yaml(projects, core_project)525 _git_validate_projects_yaml(projects, core_project)
526526
527 old_environ = dict(os.environ)
528
527 if 'http_proxy' in projects.keys():529 if 'http_proxy' in projects.keys():
528 os.environ['http_proxy'] = projects['http_proxy']530 os.environ['http_proxy'] = projects['http_proxy']
529
530 if 'https_proxy' in projects.keys():531 if 'https_proxy' in projects.keys():
531 os.environ['https_proxy'] = projects['https_proxy']532 os.environ['https_proxy'] = projects['https_proxy']
532533
@@ -544,6 +545,8 @@
544 repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,545 repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
545 update_requirements=True)546 update_requirements=True)
546547
548 os.environ = old_environ
549
547550
548def _git_validate_projects_yaml(projects, core_project):551def _git_validate_projects_yaml(projects, core_project):
549 """552 """
550553
=== modified file 'hooks/cinder_hooks.py'
--- hooks/cinder_hooks.py 2015-03-31 08:37:22 +0000
+++ hooks/cinder_hooks.py 2015-04-16 14:41:14 +0000
@@ -10,6 +10,7 @@
10from cinder_utils import (10from cinder_utils import (
11 determine_packages,11 determine_packages,
12 do_openstack_upgrade,12 do_openstack_upgrade,
13 git_install,
13 juju_log,14 juju_log,
14 migrate_database,15 migrate_database,
15 configure_lvm_storage,16 configure_lvm_storage,
@@ -53,10 +54,12 @@
53)54)
5455
55from charmhelpers.contrib.openstack.utils import (56from charmhelpers.contrib.openstack.utils import (
57 config_value_changed,
56 configure_installation_source,58 configure_installation_source,
59 git_install_requested,
57 openstack_upgrade_available,60 openstack_upgrade_available,
58 sync_db_with_multi_ipv6_addresses,61 sync_db_with_multi_ipv6_addresses,
59 get_os_codename_package62 os_release,
60)63)
6164
62from charmhelpers.contrib.storage.linux.ceph import (65from charmhelpers.contrib.storage.linux.ceph import (
@@ -101,9 +104,12 @@
101 src == 'distro'):104 src == 'distro'):
102 src = 'cloud:precise-folsom'105 src = 'cloud:precise-folsom'
103 configure_installation_source(src)106 configure_installation_source(src)
107
104 apt_update()108 apt_update()
105 apt_install(determine_packages(), fatal=True)109 apt_install(determine_packages(), fatal=True)
106110
111 git_install(config('openstack-origin-git'))
112
107113
108@hooks.hook('config-changed')114@hooks.hook('config-changed')
109@restart_on_change(restart_map(), stopstart=True)115@restart_on_change(restart_map(), stopstart=True)
@@ -123,12 +129,16 @@
123 conf['overwrite'] in ['true', 'True', True],129 conf['overwrite'] in ['true', 'True', True],
124 conf['remove-missing'])130 conf['remove-missing'])
125131
126 if openstack_upgrade_available('cinder-common'):132 if git_install_requested():
127 do_openstack_upgrade(configs=CONFIGS)133 if config_value_changed('openstack-origin-git'):
128 # NOTE(jamespage) tell any storage-backends we just upgraded134 git_install(config('openstack-origin-git'))
129 for rid in relation_ids('storage-backend'):135 else:
130 relation_set(relation_id=rid,136 if openstack_upgrade_available('cinder-common'):
131 upgrade_nonce=uuid.uuid4())137 do_openstack_upgrade(configs=CONFIGS)
138 # NOTE(jamespage) tell any storage-backends we just upgraded
139 for rid in relation_ids('storage-backend'):
140 relation_set(relation_id=rid,
141 upgrade_nonce=uuid.uuid4())
132142
133 CONFIGS.write_all()143 CONFIGS.write_all()
134 configure_https()144 configure_https()
@@ -255,7 +265,7 @@
255 'cinder_internal_url': internal_url,265 'cinder_internal_url': internal_url,
256 'cinder_admin_url': admin_url,266 'cinder_admin_url': admin_url,
257 }267 }
258 if get_os_codename_package('cinder-common') >= 'icehouse':268 if os_release('cinder-common') >= 'icehouse':
259 # NOTE(jamespage) register v2 endpoint as well269 # NOTE(jamespage) register v2 endpoint as well
260 public_url = '{}:{}/v2/$(tenant_id)s'.format(270 public_url = '{}:{}/v2/$(tenant_id)s'.format(
261 canonical_url(CONFIGS, PUBLIC),271 canonical_url(CONFIGS, PUBLIC),
262272
=== modified file 'hooks/cinder_utils.py'
--- hooks/cinder_utils.py 2015-04-09 03:10:16 +0000
+++ hooks/cinder_utils.py 2015-04-16 14:41:14 +0000
@@ -1,10 +1,12 @@
1import os1import os
2import shutil
2import subprocess3import subprocess
34
4from collections import OrderedDict5from collections import OrderedDict
5from copy import copy6from copy import copy
67
7from charmhelpers.core.hookenv import (8from charmhelpers.core.hookenv import (
9 charm_dir,
8 config,10 config,
9 relation_ids,11 relation_ids,
10 log,12 log,
@@ -19,12 +21,17 @@
19)21)
2022
21from charmhelpers.core.host import (23from charmhelpers.core.host import (
24 adduser,
25 add_group,
26 add_user_to_group,
27 lsb_release,
28 mkdir,
22 mounts,29 mounts,
23 umount,30 umount,
31 service_restart,
24 service_stop,32 service_stop,
25 service_start,33 service_start,
26 mkdir,34 write_file,
27 lsb_release
28)35)
2936
30from charmhelpers.contrib.openstack.alternatives import install_alternative37from charmhelpers.contrib.openstack.alternatives import install_alternative
@@ -58,10 +65,15 @@
5865
59from charmhelpers.contrib.openstack.utils import (66from charmhelpers.contrib.openstack.utils import (
60 configure_installation_source,67 configure_installation_source,
61 get_os_codename_package,
62 get_os_codename_install_source,68 get_os_codename_install_source,
69 git_install_requested,
70 git_clone_and_install,
71 git_src_dir,
72 os_release,
63)73)
6474
75from charmhelpers.core.templating import render
76
65import cinder_contexts77import cinder_contexts
6678
67COMMON_PACKAGES = [79COMMON_PACKAGES = [
@@ -81,6 +93,25 @@
81VOLUME_PACKAGES = ['cinder-volume']93VOLUME_PACKAGES = ['cinder-volume']
82SCHEDULER_PACKAGES = ['cinder-scheduler']94SCHEDULER_PACKAGES = ['cinder-scheduler']
8395
96BASE_GIT_PACKAGES = [
97 'libxml2-dev',
98 'libxslt1-dev',
99 'lvm2',
100 'python-dev',
101 'python-pip',
102 'python-setuptools',
103 'zlib1g-dev',
104]
105
106# ubuntu packages that should not be installed when deploying from source
107GIT_PACKAGE_BLACKLIST = [
108 'cinder-api',
109 'cinder-common',
110 'cinder-scheduler',
111 'cinder-volume',
112 'python-keystoneclient',
113]
114
84DEFAULT_LOOPBACK_SIZE = '5G'115DEFAULT_LOOPBACK_SIZE = '5G'
85116
86# Cluster resource used to determine leadership when hacluster'd117# Cluster resource used to determine leadership when hacluster'd
@@ -166,7 +197,7 @@
166 # if called without anything installed (eg during install hook)197 # if called without anything installed (eg during install hook)
167 # just default to earliest supported release. configs dont get touched198 # just default to earliest supported release. configs dont get touched
168 # till post-install, anyway.199 # till post-install, anyway.
169 release = get_os_codename_package('cinder-common', fatal=False) or 'folsom'200 release = os_release('cinder-common', base='folsom')
170 configs = templating.OSConfigRenderer(templates_dir=TEMPLATES,201 configs = templating.OSConfigRenderer(templates_dir=TEMPLATES,
171 openstack_release=release)202 openstack_release=release)
172203
@@ -218,6 +249,13 @@
218 ('scheduler', SCHEDULER_PACKAGES)]:249 ('scheduler', SCHEDULER_PACKAGES)]:
219 if service_enabled(s):250 if service_enabled(s):
220 pkgs += p251 pkgs += p
252
253 if git_install_requested():
254 pkgs.extend(BASE_GIT_PACKAGES)
255 # don't include packages that will be installed from git
256 for p in GIT_PACKAGE_BLACKLIST:
257 pkgs.remove(p)
258
221 return pkgs259 return pkgs
222260
223261
@@ -467,3 +505,142 @@
467 ' main')505 ' main')
468 apt_update()506 apt_update()
469 apt_install('haproxy/trusty-backports', fatal=True)507 apt_install('haproxy/trusty-backports', fatal=True)
508
509
510def git_install(projects_yaml):
511 """Perform setup, and install git repos specified in yaml parameter."""
512 if git_install_requested():
513 git_pre_install()
514 git_clone_and_install(projects_yaml, core_project='cinder')
515 git_post_install(projects_yaml)
516
517
518def git_pre_install():
519 """Perform cinder pre-install setup."""
520 dirs = [{'path': '/etc/tgt',
521 'owner': 'cinder',
522 'group': 'cinder',
523 'perms': 0750,
524 },
525 {'path': '/var/lib/cinder',
526 'owner': 'cinder',
527 'group': 'cinder',
528 'perms': 0755,
529 },
530 {'path': '/var/lib/cinder/volumes',
531 'owner': 'cinder',
532 'group': 'cinder',
533 'perms': 0750,
534 },
535 {'path': '/var/lock/cinder',
536 'owner': 'cinder',
537 'group': 'root',
538 'perms': 0750,
539 },
540 {'path': '/var/log/cinder',
541 'owner': 'cinder',
542 'group': 'cinder',
543 'perms': 0750,
544 }]
545
546 logs = [
547 '/var/log/cinder/cinder-api.log',
548 '/var/log/cinder/cinder-backup.log',
549 '/var/log/cinder/cinder-scheduler.log',
550 '/var/log/cinder/cinder-volume.log',
551 ]
552
553 adduser('cinder', shell='/bin/bash', system_user=True)
554 add_group('cinder', system_group=True)
555 add_user_to_group('cinder', 'cinder')
556
557 for d in dirs:
558 mkdir(d['path'], owner=d['owner'], group=d['group'], perms=d['perms'],
559 force=False)
560
561 for l in logs:
562 write_file(l, '', owner='cinder', group='cinder', perms=0600)
563
564
565def git_post_install(projects_yaml):
566 """Perform cinder post-install setup."""
567 src_etc = os.path.join(git_src_dir(projects_yaml, 'cinder'), 'etc/cinder')
568 configs = {
569 'src': src_etc,
570 'dest': '/etc/cinder',
571 }
572
573 if os.path.exists(configs['dest']):
574 shutil.rmtree(configs['dest'])
575 shutil.copytree(configs['src'], configs['dest'])
576
577 render('cinder.conf', '/etc/cinder/cinder.conf', {}, owner='cinder',
578 group='cinder', perms=0o644)
579 render('git/cinder_tgt.conf', '/etc/tgt/conf.d', {}, owner='cinder',
580 group='cinder', perms=0o644)
581 render('git/logging.conf', '/etc/cinder/logging.conf', {}, owner='cinder',
582 group='cinder', perms=0o644)
583 render('git/cinder_sudoers', '/etc/sudoers.d/cinder_sudoers', {},
584 owner='root', group='root', perms=0o440)
585
586 os.chmod('/etc/sudoers.d', 0o750)
587
588 cinder_api_context = {
589 'service_description': 'Cinder API server',
590 'service_name': 'Cinder',
591 'user_name': 'cinder',
592 'start_dir': '/var/lib/cinder',
593 'process_name': 'cinder-api',
594 'executable_name': '/usr/local/bin/cinder-api',
595 'config_files': ['/etc/cinder/cinder.conf'],
596 'log_file': '/var/log/cinder/cinder-api.log',
597 }
598
599 cinder_backup_context = {
600 'service_description': 'Cinder backup server',
601 'service_name': 'Cinder',
602 'user_name': 'cinder',
603 'start_dir': '/var/lib/cinder',
604 'process_name': 'cinder-backup',
605 'executable_name': '/usr/local/bin/cinder-backup',
606 'config_files': ['/etc/cinder/cinder.conf'],
607 'log_file': '/var/log/cinder/cinder-backup.log',
608 }
609
610 cinder_scheduler_context = {
611 'service_description': 'Cinder scheduler server',
612 'service_name': 'Cinder',
613 'user_name': 'cinder',
614 'start_dir': '/var/lib/cinder',
615 'process_name': 'cinder-scheduler',
616 'executable_name': '/usr/local/bin/cinder-scheduler',
617 'config_files': ['/etc/cinder/cinder.conf'],
618 'log_file': '/var/log/cinder/cinder-scheduler.log',
619 }
620
621 cinder_volume_context = {
622 'service_description': 'Cinder volume server',
623 'service_name': 'Cinder',
624 'user_name': 'cinder',
625 'start_dir': '/var/lib/cinder',
626 'process_name': 'cinder-volume',
627 'executable_name': '/usr/local/bin/cinder-volume',
628 'config_files': ['/etc/cinder/cinder.conf'],
629 'log_file': '/var/log/cinder/cinder-volume.log',
630 }
631
632 # NOTE(coreycb): Needs systemd support
633 templates_dir = 'hooks/charmhelpers/contrib/openstack/templates'
634 templates_dir = os.path.join(charm_dir(), templates_dir)
635 render('git.upstart', '/etc/init/cinder-api.conf',
636 cinder_api_context, perms=0o644, templates_dir=templates_dir)
637 render('git.upstart', '/etc/init/cinder-backup.conf',
638 cinder_backup_context, perms=0o644, templates_dir=templates_dir)
639 render('git.upstart', '/etc/init/cinder-scheduler.conf',
640 cinder_scheduler_context, perms=0o644, templates_dir=templates_dir)
641 render('git.upstart', '/etc/init/cinder-volume.conf',
642 cinder_volume_context, perms=0o644, templates_dir=templates_dir)
643
644 service_restart('tgtd')
645
646 [service_restart(s) for s in services()]
470647
=== added directory 'templates/git'
=== added file 'templates/git/cinder_sudoers'
--- templates/git/cinder_sudoers 1970-01-01 00:00:00 +0000
+++ templates/git/cinder_sudoers 2015-04-16 14:41:14 +0000
@@ -0,0 +1,4 @@
1Defaults:cinder !requiretty
2
3cinder ALL = (root) NOPASSWD: /usr/local/bin/cinder-rootwrap /etc/cinder/rootwrap.conf *
4
05
=== added file 'templates/git/cinder_tgt.conf'
--- templates/git/cinder_tgt.conf 1970-01-01 00:00:00 +0000
+++ templates/git/cinder_tgt.conf 2015-04-16 14:41:14 +0000
@@ -0,0 +1,1 @@
1include /var/lib/cinder/volumes/*
02
=== added file 'templates/git/logging.conf'
--- templates/git/logging.conf 1970-01-01 00:00:00 +0000
+++ templates/git/logging.conf 2015-04-16 14:41:14 +0000
@@ -0,0 +1,76 @@
1[loggers]
2keys = root, cinder
3
4[handlers]
5keys = stderr, stdout, watchedfile, syslog, null
6
7[formatters]
8keys = legacycinder, default
9
10[logger_root]
11level = WARNING
12handlers = null
13
14[logger_cinder]
15level = INFO
16handlers = stderr
17qualname = cinder
18
19[logger_amqplib]
20level = WARNING
21handlers = stderr
22qualname = amqplib
23
24[logger_sqlalchemy]
25level = WARNING
26handlers = stderr
27qualname = sqlalchemy
28# "level = INFO" logs SQL queries.
29# "level = DEBUG" logs SQL queries and results.
30# "level = WARNING" logs neither. (Recommended for production systems.)
31
32[logger_boto]
33level = WARNING
34handlers = stderr
35qualname = boto
36
37[logger_suds]
38level = INFO
39handlers = stderr
40qualname = suds
41
42[logger_eventletwsgi]
43level = WARNING
44handlers = stderr
45qualname = eventlet.wsgi.server
46
47[handler_stderr]
48class = StreamHandler
49args = (sys.stderr,)
50formatter = legacycinder
51
52[handler_stdout]
53class = StreamHandler
54args = (sys.stdout,)
55formatter = legacycinder
56
57[handler_watchedfile]
58class = handlers.WatchedFileHandler
59args = ('cinder.log',)
60formatter = legacycinder
61
62[handler_syslog]
63class = handlers.SysLogHandler
64args = ('/dev/log', handlers.SysLogHandler.LOG_USER)
65formatter = legacycinder
66
67[handler_null]
68class = cinder.log.NullHandler
69formatter = default
70args = ()
71
72[formatter_legacycinder]
73class = cinder.log.LegacyCinderFormatter
74
75[formatter_default]
76format = %(message)s
077
=== modified file 'tests/00-setup'
--- tests/00-setup 2014-10-07 18:32:59 +0000
+++ tests/00-setup 2015-04-16 14:41:14 +0000
@@ -5,6 +5,7 @@
5sudo add-apt-repository --yes ppa:juju/stable5sudo add-apt-repository --yes ppa:juju/stable
6sudo apt-get update --yes6sudo apt-get update --yes
7sudo apt-get install --yes python-amulet \7sudo apt-get install --yes python-amulet \
8 python-cinderclient \
9 python-glanceclient \
8 python-keystoneclient \10 python-keystoneclient \
9 python-cinderclient \11 python-novaclient
10 python-glanceclient
1112
=== removed file 'tests/11-basic-precise-folsom'
--- tests/11-basic-precise-folsom 2014-07-31 15:27:14 +0000
+++ tests/11-basic-precise-folsom 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic cinder deployment on precise-folsom."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='precise',
9 openstack='cloud:precise-folsom',
10 source='cloud:precise-updates/folsom')
11 deployment.run_tests()
120
=== removed file 'tests/12-basic-precise-grizzly'
--- tests/12-basic-precise-grizzly 2014-07-31 15:27:14 +0000
+++ tests/12-basic-precise-grizzly 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic cinder deployment on precise-grizzly."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='precise',
9 openstack='cloud:precise-grizzly',
10 source='cloud:precise-updates/grizzly')
11 deployment.run_tests()
120
=== removed file 'tests/13-basic-precise-havana'
--- tests/13-basic-precise-havana 2014-07-31 15:27:14 +0000
+++ tests/13-basic-precise-havana 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic cinder deployment on precise-havana."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='precise',
9 openstack='cloud:precise-havana',
10 source='cloud:precise-updates/havana')
11 deployment.run_tests()
120
=== added file 'tests/16-basic-trusty-icehouse-git'
--- tests/16-basic-trusty-icehouse-git 1970-01-01 00:00:00 +0000
+++ tests/16-basic-trusty-icehouse-git 2015-04-16 14:41:14 +0000
@@ -0,0 +1,9 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic Cinder git deployment on trusty-icehouse."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='trusty', git=True)
9 deployment.run_tests()
010
=== removed file 'tests/16-basic-vivid-kilo'
--- tests/16-basic-vivid-kilo 2015-04-13 19:33:14 +0000
+++ tests/16-basic-vivid-kilo 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic Cinder deployment on vivid-kilo."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='vivid')
9 deployment.run_tests()
100
=== added file 'tests/17-basic-trusty-juno'
--- tests/17-basic-trusty-juno 1970-01-01 00:00:00 +0000
+++ tests/17-basic-trusty-juno 2015-04-16 14:41:14 +0000
@@ -0,0 +1,11 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic Cinder deployment on trusty-juno."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='trusty',
9 openstack='cloud:trusty-juno',
10 source='cloud:trusty-updates/juno')
11 deployment.run_tests()
012
=== removed file 'tests/17-basic-trusty-kilo'
--- tests/17-basic-trusty-kilo 2015-04-13 19:33:14 +0000
+++ tests/17-basic-trusty-kilo 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic cinder deployment on trusty-kilo."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='trusty',
9 openstack='cloud:trusty-kilo',
10 source='cloud:trusty-updates/kilo')
11 deployment.run_tests()
120
=== added file 'tests/18-basic-trusty-juno-git'
--- tests/18-basic-trusty-juno-git 1970-01-01 00:00:00 +0000
+++ tests/18-basic-trusty-juno-git 2015-04-16 14:41:14 +0000
@@ -0,0 +1,12 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic Cinder git deployment on trusty-juno."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='trusty',
9 openstack='cloud:trusty-juno',
10 source='cloud:trusty-updates/juno',
11 git=True)
12 deployment.run_tests()
013
=== added file 'tests/19-basic-trusty-kilo'
--- tests/19-basic-trusty-kilo 1970-01-01 00:00:00 +0000
+++ tests/19-basic-trusty-kilo 2015-04-16 14:41:14 +0000
@@ -0,0 +1,11 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic cinder deployment on trusty-kilo."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='trusty',
9 openstack='cloud:trusty-kilo',
10 source='cloud:trusty-updates/kilo')
11 deployment.run_tests()
012
=== added file 'tests/20-basic-trusty-kilo-git'
--- tests/20-basic-trusty-kilo-git 1970-01-01 00:00:00 +0000
+++ tests/20-basic-trusty-kilo-git 2015-04-16 14:41:14 +0000
@@ -0,0 +1,12 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic cinder git deployment on trusty-kilo."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='trusty',
9 openstack='cloud:trusty-kilo',
10 source='cloud:trusty-updates/kilo',
11 git=True)
12 deployment.run_tests()
013
=== added file 'tests/21-basic-vivid-kilo'
--- tests/21-basic-vivid-kilo 1970-01-01 00:00:00 +0000
+++ tests/21-basic-vivid-kilo 2015-04-16 14:41:14 +0000
@@ -0,0 +1,9 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic Cinder deployment on vivid-kilo."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='vivid')
9 deployment.run_tests()
010
=== added file 'tests/22-basic-vivid-kilo-git'
--- tests/22-basic-vivid-kilo-git 1970-01-01 00:00:00 +0000
+++ tests/22-basic-vivid-kilo-git 2015-04-16 14:41:14 +0000
@@ -0,0 +1,9 @@
1#!/usr/bin/python
2
3"""Amulet tests on a basic Cinder git deployment on vivid-kilo."""
4
5from basic_deployment import CinderBasicDeployment
6
7if __name__ == '__main__':
8 deployment = CinderBasicDeployment(series='vivid', git=True)
9 deployment.run_tests()
010
=== modified file 'tests/basic_deployment.py'
--- tests/basic_deployment.py 2015-04-13 19:39:27 +0000
+++ tests/basic_deployment.py 2015-04-16 14:41:14 +0000
@@ -1,8 +1,10 @@
1#!/usr/bin/python1#!/usr/bin/python
22
3import amulet3import amulet
4import os
4import types5import types
5from time import sleep6from time import sleep
7import yaml
6import cinderclient.v1.client as cinder_client8import cinderclient.v1.client as cinder_client
79
8from charmhelpers.contrib.openstack.amulet.deployment import (10from charmhelpers.contrib.openstack.amulet.deployment import (
@@ -28,10 +30,12 @@
28 # NOTE(beisner): Features and tests vary across Openstack releases.30 # NOTE(beisner): Features and tests vary across Openstack releases.
29 # https://wiki.openstack.org/wiki/CinderSupportMatrix31 # https://wiki.openstack.org/wiki/CinderSupportMatrix
3032
31 def __init__(self, series=None, openstack=None, source=None, stable=False):33 def __init__(self, series=None, openstack=None, source=None, git=False,
34 stable=False):
32 '''Deploy the entire test environment.'''35 '''Deploy the entire test environment.'''
33 super(CinderBasicDeployment, self).__init__(series, openstack, source,36 super(CinderBasicDeployment, self).__init__(series, openstack, source,
34 stable)37 stable)
38 self.git = git
35 self._add_services()39 self._add_services()
36 self._add_relations()40 self._add_relations()
37 self._configure_services()41 self._configure_services()
@@ -67,11 +71,31 @@
6771
68 def _configure_services(self):72 def _configure_services(self):
69 '''Configure all of the services.'''73 '''Configure all of the services.'''
70 keystone_config = {'admin-password': 'openstack',
71 'admin-token': 'ubuntutesting'}
72 cinder_config = {'block-device': 'vdb',74 cinder_config = {'block-device': 'vdb',
73 'glance-api-version': '2',75 'glance-api-version': '2',
74 'overwrite': 'true'}76 'overwrite': 'true'}
77 if self.git:
78 branch = 'stable/' + self._get_openstack_release_string()
79 amulet_http_proxy = os.environ.get('AMULET_HTTP_PROXY')
80 openstack_origin_git = {
81 'repositories': [
82 {'name': 'requirements',
83 'repository':
84 'git://git.openstack.org/openstack/requirements',
85 'branch': branch},
86 {'name': 'cinder',
87 'repository': 'git://git.openstack.org/openstack/cinder',
88 'branch': branch},
89 ],
90 'directory': '/mnt/openstack-git',
91 'http_proxy': amulet_http_proxy,
92 'https_proxy': amulet_http_proxy,
93 }
94 cinder_config['openstack-origin-git'] = \
95 yaml.dump(openstack_origin_git)
96
97 keystone_config = {'admin-password': 'openstack',
98 'admin-token': 'ubuntutesting'}
75 mysql_config = {'dataset-size': '50%'}99 mysql_config = {'dataset-size': '50%'}
76 configs = {'cinder': cinder_config,100 configs = {'cinder': cinder_config,
77 'keystone': keystone_config,101 'keystone': keystone_config,
78102
=== modified file 'unit_tests/__init__.py'
--- unit_tests/__init__.py 2013-10-17 21:48:08 +0000
+++ unit_tests/__init__.py 2015-04-16 14:41:14 +0000
@@ -1,2 +1,4 @@
1import sys1import sys
2
3sys.path.append('actions')
2sys.path.append('hooks')4sys.path.append('hooks')
35
=== added file 'unit_tests/test_actions_git_reinstall.py'
--- unit_tests/test_actions_git_reinstall.py 1970-01-01 00:00:00 +0000
+++ unit_tests/test_actions_git_reinstall.py 2015-04-16 14:41:14 +0000
@@ -0,0 +1,110 @@
1from mock import patch, MagicMock
2import os
3
4os.environ['JUJU_UNIT_NAME'] = 'cinder'
5
6from test_utils import RESTART_MAP
7import cinder_utils as utils
8
9# Need to do some early patching to get the module loaded.
10_restart_map = utils.restart_map
11_register_configs = utils.register_configs
12
13utils.restart_map = MagicMock()
14utils.restart_map.return_value = RESTART_MAP
15utils.register_configs = MagicMock()
16
17import git_reinstall
18
19# Unpatch it now that its loaded.
20utils.restart_map = _restart_map
21utils.register_configs = _register_configs
22
23
24from test_utils import (
25 CharmTestCase
26)
27
28TO_PATCH = [
29 'config',
30]
31
32
33openstack_origin_git = \
34 """repositories:
35 - {name: requirements,
36 repository: 'git://git.openstack.org/openstack/requirements',
37 branch: stable/juno}
38 - {name: cinder,
39 repository: 'git://git.openstack.org/openstack/cinder',
40 branch: stable/juno}"""
41
42
43class TestCinderActions(CharmTestCase):
44
45 def setUp(self):
46 super(TestCinderActions, self).setUp(git_reinstall, TO_PATCH)
47 self.config.side_effect = self.test_config.get
48
49 @patch.object(git_reinstall, 'action_set')
50 @patch.object(git_reinstall, 'action_fail')
51 @patch.object(git_reinstall, 'git_install')
52 @patch.object(git_reinstall, 'config_changed')
53 @patch('charmhelpers.contrib.openstack.utils.config')
54 def test_git_reinstall(self, _config, config_changed, git_install,
55 action_fail, action_set):
56 _config.return_value = openstack_origin_git
57 self.test_config.set('openstack-origin-git', openstack_origin_git)
58
59 git_reinstall.git_reinstall()
60
61 git_install.assert_called_with(openstack_origin_git)
62 self.assertTrue(git_install.called)
63 self.assertTrue(config_changed.called)
64 self.assertFalse(action_set.called)
65 self.assertFalse(action_fail.called)
66
67 @patch.object(git_reinstall, 'action_set')
68 @patch.object(git_reinstall, 'action_fail')
69 @patch.object(git_reinstall, 'git_install')
70 @patch.object(git_reinstall, 'config_changed')
71 @patch('charmhelpers.contrib.openstack.utils.config')
72 def test_git_reinstall_not_configured(self, _config, config_changed,
73 git_install, action_fail,
74 action_set):
75 _config.return_value = None
76
77 git_reinstall.git_reinstall()
78
79 msg = 'openstack-origin-git is not configured'
80 action_fail.assert_called_with(msg)
81 self.assertFalse(git_install.called)
82 self.assertFalse(action_set.called)
83
84 @patch.object(git_reinstall, 'action_set')
85 @patch.object(git_reinstall, 'action_fail')
86 @patch.object(git_reinstall, 'git_install')
87 @patch.object(git_reinstall, 'config_changed')
88 @patch('traceback.format_exc')
89 @patch('charmhelpers.contrib.openstack.utils.config')
90 def test_git_reinstall_exception(self, _config, format_exc, config_changed,
91 git_install, action_fail, action_set):
92 _config.return_value = openstack_origin_git
93 e = OSError('something bad happened')
94 git_install.side_effect = e
95 traceback = (
96 "Traceback (most recent call last):\n"
97 " File \"actions/git_reinstall.py\", line 37, in git_reinstall\n"
98 " git_install(config(\'openstack-origin-git\'))\n"
99 " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 964, in __call__\n" # noqa
100 " return _mock_self._mock_call(*args, **kwargs)\n"
101 " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 1019, in _mock_call\n" # noqa
102 " raise effect\n"
103 "OSError: something bad happened\n")
104 format_exc.return_value = traceback
105
106 git_reinstall.git_reinstall()
107
108 msg = 'git-reinstall resulted in an unexpected error'
109 action_fail.assert_called_with(msg)
110 action_set.assert_called_with({'traceback': traceback})
0111
=== modified file 'unit_tests/test_cinder_hooks.py'
--- unit_tests/test_cinder_hooks.py 2015-03-31 08:37:22 +0000
+++ unit_tests/test_cinder_hooks.py 2015-04-16 14:41:14 +0000
@@ -4,6 +4,7 @@
4 patch,4 patch,
5 call5 call
6)6)
7import yaml
78
8import cinder_utils as utils9import cinder_utils as utils
9from test_utils import (10from test_utils import (
@@ -35,6 +36,7 @@
35 'determine_packages',36 'determine_packages',
36 'do_openstack_upgrade',37 'do_openstack_upgrade',
37 'ensure_ceph_keyring',38 'ensure_ceph_keyring',
39 'git_install',
38 'juju_log',40 'juju_log',
39 'log',41 'log',
40 'lsb_release',42 'lsb_release',
@@ -63,7 +65,7 @@
63 # charmhelpers.contrib.openstack.openstack_utils65 # charmhelpers.contrib.openstack.openstack_utils
64 'configure_installation_source',66 'configure_installation_source',
65 'openstack_upgrade_available',67 'openstack_upgrade_available',
66 'get_os_codename_package',68 'os_release',
67 # charmhelpers.contrib.hahelpers.cluster_utils69 # charmhelpers.contrib.hahelpers.cluster_utils
68 'canonical_url',70 'canonical_url',
69 'eligible_leader',71 'eligible_leader',
@@ -79,17 +81,47 @@
7981
80 def setUp(self):82 def setUp(self):
81 super(TestInstallHook, self).setUp(hooks, TO_PATCH)83 super(TestInstallHook, self).setUp(hooks, TO_PATCH)
82 self.config.side_effect = self.test_config.get_all84 self.config.side_effect = self.test_config.get
8385
84 def test_install_precise_distro(self):86 @patch.object(utils, 'git_install_requested')
87 def test_install_precise_distro(self, git_requested):
85 'It redirects to cloud archive if setup to install precise+distro'88 'It redirects to cloud archive if setup to install precise+distro'
89 git_requested.return_value = False
86 self.lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'}90 self.lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'}
87 hooks.hooks.execute(['hooks/install'])91 hooks.hooks.execute(['hooks/install'])
88 ca = 'cloud:precise-folsom'92 ca = 'cloud:precise-folsom'
89 self.configure_installation_source.assert_called_with(ca)93 self.configure_installation_source.assert_called_with(ca)
9094
91 def test_correct_install_packages(self):95 @patch.object(utils, 'git_install_requested')
96 def test_install_git(self, git_requested):
97 git_requested.return_value = True
98 self.determine_packages.return_value = ['foo', 'bar', 'baz']
99 repo = 'cloud:trusty-juno'
100 openstack_origin_git = {
101 'repositories': [
102 {'name': 'requirements',
103 'repository': 'git://git.openstack.org/openstack/requirements', # noqa
104 'branch': 'stable/juno'},
105 {'name': 'cinder',
106 'repository': 'git://git.openstack.org/openstack/cinder',
107 'branch': 'stable/juno'}
108 ],
109 'directory': '/mnt/openstack-git',
110 }
111 projects_yaml = yaml.dump(openstack_origin_git)
112 self.test_config.set('openstack-origin', repo)
113 self.test_config.set('openstack-origin-git', projects_yaml)
114 hooks.hooks.execute(['hooks/install'])
115 self.assertTrue(self.execd_preinstall.called)
116 self.configure_installation_source.assert_called_with(repo)
117 self.apt_update.assert_called_with()
118 self.apt_install.assert_called_with(['foo', 'bar', 'baz'], fatal=True)
119 self.git_install.assert_called_with(projects_yaml)
120
121 @patch.object(utils, 'git_install_requested')
122 def test_correct_install_packages(self, git_requested):
92 'It installs the correct packages based on what is determined'123 'It installs the correct packages based on what is determined'
124 git_requested.return_value = False
93 self.determine_packages.return_value = ['foo', 'bar', 'baz']125 self.determine_packages.return_value = ['foo', 'bar', 'baz']
94 hooks.hooks.execute(['hooks/install'])126 hooks.hooks.execute(['hooks/install'])
95 self.apt_install.assert_called_with(['foo', 'bar', 'baz'], fatal=True)127 self.apt_install.assert_called_with(['foo', 'bar', 'baz'], fatal=True)
@@ -99,7 +131,7 @@
99131
100 def setUp(self):132 def setUp(self):
101 super(TestChangedHooks, self).setUp(hooks, TO_PATCH)133 super(TestChangedHooks, self).setUp(hooks, TO_PATCH)
102 self.config.side_effect = self.test_config.get_all134 self.config.side_effect = self.test_config.get
103135
104 @patch.object(hooks, 'amqp_joined')136 @patch.object(hooks, 'amqp_joined')
105 def test_upgrade_charm_no_amqp(self, _joined):137 def test_upgrade_charm_no_amqp(self, _joined):
@@ -114,8 +146,10 @@
114 _joined.assert_called_with(relation_id='amqp:1')146 _joined.assert_called_with(relation_id='amqp:1')
115147
116 @patch.object(hooks, 'configure_https')148 @patch.object(hooks, 'configure_https')
117 def test_config_changed(self, conf_https):149 @patch.object(hooks, 'git_install_requested')
150 def test_config_changed(self, git_requested, conf_https):
118 'It writes out all config'151 'It writes out all config'
152 git_requested.return_value = False
119 self.openstack_upgrade_available.return_value = False153 self.openstack_upgrade_available.return_value = False
120 hooks.hooks.execute(['hooks/config-changed'])154 hooks.hooks.execute(['hooks/config-changed'])
121 self.assertTrue(self.CONFIGS.write_all.called)155 self.assertTrue(self.CONFIGS.write_all.called)
@@ -125,8 +159,10 @@
125 False, False)159 False, False)
126160
127 @patch.object(hooks, 'configure_https')161 @patch.object(hooks, 'configure_https')
128 def test_config_changed_block_devices(self, conf_https):162 @patch.object(hooks, 'git_install_requested')
163 def test_config_changed_block_devices(self, git_requested, conf_https):
129 'It writes out all config'164 'It writes out all config'
165 git_requested.return_value = False
130 self.openstack_upgrade_available.return_value = False166 self.openstack_upgrade_available.return_value = False
131 self.test_config.set('block-device', 'sdb /dev/sdc sde')167 self.test_config.set('block-device', 'sdb /dev/sdc sde')
132 self.test_config.set('volume-group', 'cinder-new')168 self.test_config.set('volume-group', 'cinder-new')
@@ -141,12 +177,40 @@
141 True, True)177 True, True)
142178
143 @patch.object(hooks, 'configure_https')179 @patch.object(hooks, 'configure_https')
144 def test_config_changed_upgrade_available(self, conf_https):180 @patch.object(hooks, 'git_install_requested')
181 def test_config_changed_upgrade_available(self, git_requested, conf_https):
145 'It writes out all config with an available OS upgrade'182 'It writes out all config with an available OS upgrade'
183 git_requested.return_value = False
146 self.openstack_upgrade_available.return_value = True184 self.openstack_upgrade_available.return_value = True
147 hooks.hooks.execute(['hooks/config-changed'])185 hooks.hooks.execute(['hooks/config-changed'])
148 self.do_openstack_upgrade.assert_called_with(configs=self.CONFIGS)186 self.do_openstack_upgrade.assert_called_with(configs=self.CONFIGS)
149187
188 @patch.object(hooks, 'configure_https')
189 @patch.object(hooks, 'git_install_requested')
190 @patch.object(hooks, 'config_value_changed')
191 def test_config_changed_git_updated(self, config_val_changed,
192 git_requested, conf_https):
193 git_requested.return_value = True
194 repo = 'cloud:trusty-juno'
195 openstack_origin_git = {
196 'repositories': [
197 {'name': 'requirements',
198 'repository': 'git://git.openstack.org/openstack/requirements', # noqa
199 'branch': 'stable/juno'},
200 {'name': 'cinder',
201 'repository': 'git://git.openstack.org/openstack/',
202 'branch': 'stable/juno'}
203 ],
204 'directory': '/mnt/openstack-git',
205 }
206 projects_yaml = yaml.dump(openstack_origin_git)
207 self.test_config.set('openstack-origin', repo)
208 self.test_config.set('openstack-origin-git', projects_yaml)
209 hooks.hooks.execute(['hooks/config-changed'])
210 self.git_install.assert_called_with(projects_yaml)
211 self.assertFalse(self.do_openstack_upgrade.called)
212 self.assertTrue(conf_https.called)
213
150 def test_db_changed(self):214 def test_db_changed(self):
151 'It writes out cinder.conf on db changed'215 'It writes out cinder.conf on db changed'
152 self.relation_get.return_value = 'cinder/0 cinder/1'216 self.relation_get.return_value = 'cinder/0 cinder/1'
@@ -341,7 +405,7 @@
341405
342 def test_identity_service_joined(self):406 def test_identity_service_joined(self):
343 'It properly requests unclustered endpoint via identity-service'407 'It properly requests unclustered endpoint via identity-service'
344 self.get_os_codename_package.return_value = 'havana'408 self.os_release.return_value = 'havana'
345 self.unit_get.return_value = 'cindernode1'409 self.unit_get.return_value = 'cindernode1'
346 self.config.side_effect = self.test_config.get410 self.config.side_effect = self.test_config.get
347 self.canonical_url.return_value = 'http://cindernode1'411 self.canonical_url.return_value = 'http://cindernode1'
@@ -363,7 +427,7 @@
363427
364 def test_identity_service_joined_icehouse(self):428 def test_identity_service_joined_icehouse(self):
365 'It properly requests unclustered endpoint via identity-service'429 'It properly requests unclustered endpoint via identity-service'
366 self.get_os_codename_package.return_value = 'icehouse'430 self.os_release.return_value = 'icehouse'
367 self.unit_get.return_value = 'cindernode1'431 self.unit_get.return_value = 'cindernode1'
368 self.config.side_effect = self.test_config.get432 self.config.side_effect = self.test_config.get
369 self.canonical_url.return_value = 'http://cindernode1'433 self.canonical_url.return_value = 'http://cindernode1'
370434
=== modified file 'unit_tests/test_cinder_utils.py'
--- unit_tests/test_cinder_utils.py 2014-12-15 10:17:11 +0000
+++ unit_tests/test_cinder_utils.py 2015-04-16 14:41:14 +0000
@@ -30,7 +30,7 @@
30 'ensure_loopback_device',30 'ensure_loopback_device',
31 'is_block_device',31 'is_block_device',
32 'zap_disk',32 'zap_disk',
33 'get_os_codename_package',33 'os_release',
34 'get_os_codename_install_source',34 'get_os_codename_install_source',
35 'configure_installation_source',35 'configure_installation_source',
36 'eligible_leader',36 'eligible_leader',
@@ -68,6 +68,15 @@
6868
69"""69"""
7070
71openstack_origin_git = \
72 """repositories:
73 - {name: requirements,
74 repository: 'git://git.openstack.org/openstack/requirements',
75 branch: stable/juno}
76 - {name: cinder,
77 repository: 'git://git.openstack.org/openstack/cinder',
78 branch: stable/juno}"""
79
7180
72class TestCinderUtils(CharmTestCase):81class TestCinderUtils(CharmTestCase):
7382
@@ -97,8 +106,10 @@
97 self.assertFalse(cinder_utils.service_enabled('volume'))106 self.assertFalse(cinder_utils.service_enabled('volume'))
98107
99 @patch('cinder_utils.service_enabled')108 @patch('cinder_utils.service_enabled')
100 def test_determine_packages_all(self, service_enabled):109 @patch('cinder_utils.git_install_requested')
110 def test_determine_packages_all(self, git_requested, service_enabled):
101 'It determines all packages required when all services enabled'111 'It determines all packages required when all services enabled'
112 git_requested.return_value = False
102 service_enabled.return_value = True113 service_enabled.return_value = True
103 pkgs = cinder_utils.determine_packages()114 pkgs = cinder_utils.determine_packages()
104 self.assertEquals(sorted(pkgs),115 self.assertEquals(sorted(pkgs),
@@ -108,8 +119,10 @@
108 cinder_utils.SCHEDULER_PACKAGES))119 cinder_utils.SCHEDULER_PACKAGES))
109120
110 @patch('cinder_utils.service_enabled')121 @patch('cinder_utils.service_enabled')
111 def test_determine_packages_subset(self, service_enabled):122 @patch('cinder_utils.git_install_requested')
123 def test_determine_packages_subset(self, git_requested, service_enabled):
112 'It determines packages required for a subset of enabled services'124 'It determines packages required for a subset of enabled services'
125 git_requested.return_value = False
113 service_enabled.side_effect = self.svc_enabled126 service_enabled.side_effect = self.svc_enabled
114127
115 self.test_config.set('enabled-services', 'api')128 self.test_config.set('enabled-services', 'api')
@@ -402,7 +415,7 @@
402 @patch('os.path.exists')415 @patch('os.path.exists')
403 def test_register_configs_apache(self, exists):416 def test_register_configs_apache(self, exists):
404 exists.return_value = False417 exists.return_value = False
405 self.get_os_codename_package.return_value = 'grizzly'418 self.os_release.return_value = 'grizzly'
406 self.relation_ids.return_value = False419 self.relation_ids.return_value = False
407 configs = cinder_utils.register_configs()420 configs = cinder_utils.register_configs()
408 calls = []421 calls = []
@@ -419,7 +432,7 @@
419 @patch('os.path.exists')432 @patch('os.path.exists')
420 def test_register_configs_apache24(self, exists):433 def test_register_configs_apache24(self, exists):
421 exists.return_value = True434 exists.return_value = True
422 self.get_os_codename_package.return_value = 'grizzly'435 self.os_release.return_value = 'grizzly'
423 self.relation_ids.return_value = False436 self.relation_ids.return_value = False
424 configs = cinder_utils.register_configs()437 configs = cinder_utils.register_configs()
425 calls = []438 calls = []
@@ -438,7 +451,7 @@
438 def test_register_configs_ceph(self, exists, isdir):451 def test_register_configs_ceph(self, exists, isdir):
439 exists.return_value = True452 exists.return_value = True
440 isdir.return_value = False453 isdir.return_value = False
441 self.get_os_codename_package.return_value = 'grizzly'454 self.os_release.return_value = 'grizzly'
442 self.relation_ids.return_value = ['ceph:0']455 self.relation_ids.return_value = ['ceph:0']
443 self.ceph_config_file.return_value = '/var/lib/charm/cinder/ceph.conf'456 self.ceph_config_file.return_value = '/var/lib/charm/cinder/ceph.conf'
444 configs = cinder_utils.register_configs()457 configs = cinder_utils.register_configs()
@@ -504,3 +517,149 @@
504 self.apt_install.assert_called_with(['mypackage'], fatal=True)517 self.apt_install.assert_called_with(['mypackage'], fatal=True)
505 configs.set_release.assert_called_with(openstack_release='havana')518 configs.set_release.assert_called_with(openstack_release='havana')
506 self.assertFalse(migrate.called)519 self.assertFalse(migrate.called)
520
521 @patch.object(cinder_utils, 'git_install_requested')
522 @patch.object(cinder_utils, 'git_clone_and_install')
523 @patch.object(cinder_utils, 'git_post_install')
524 @patch.object(cinder_utils, 'git_pre_install')
525 def test_git_install(self, git_pre, git_post, git_clone_and_install,
526 git_requested):
527 projects_yaml = openstack_origin_git
528 git_requested.return_value = True
529 cinder_utils.git_install(projects_yaml)
530 self.assertTrue(git_pre.called)
531 git_clone_and_install.assert_called_with(openstack_origin_git,
532 core_project='cinder')
533 self.assertTrue(git_post.called)
534
535 @patch.object(cinder_utils, 'mkdir')
536 @patch.object(cinder_utils, 'write_file')
537 @patch.object(cinder_utils, 'add_user_to_group')
538 @patch.object(cinder_utils, 'add_group')
539 @patch.object(cinder_utils, 'adduser')
540 def test_git_pre_install(self, adduser, add_group, add_user_to_group,
541 write_file, mkdir):
542 cinder_utils.git_pre_install()
543 adduser.assert_called_with('cinder', shell='/bin/bash',
544 system_user=True)
545 add_group.assert_called_with('cinder', system_group=True)
546 add_user_to_group.assert_called_with('cinder', 'cinder')
547 expected = [
548 call('/etc/tgt', owner='cinder', perms=488, force=False,
549 group='cinder'),
550 call('/var/lib/cinder', owner='cinder', perms=493, force=False,
551 group='cinder'),
552 call('/var/lib/cinder/volumes', owner='cinder', perms=488,
553 force=False, group='cinder'),
554 call('/var/lock/cinder', owner='cinder', perms=488, force=False,
555 group='root'),
556 call('/var/log/cinder', owner='cinder', perms=488, force=False,
557 group='cinder'),
558 ]
559 self.assertEquals(mkdir.call_args_list, expected)
560 expected = [
561 call('/var/log/cinder/cinder-api.log', '', perms=0600,
562 owner='cinder', group='cinder'),
563 call('/var/log/cinder/cinder-backup.log', '', perms=0600,
564 owner='cinder', group='cinder'),
565 call('/var/log/cinder/cinder-scheduler.log', '', perms=0600,
566 owner='cinder', group='cinder'),
567 call('/var/log/cinder/cinder-volume.log', '', perms=0600,
568 owner='cinder', group='cinder'),
569 ]
570 self.assertEquals(write_file.call_args_list, expected)
571
572 @patch.object(cinder_utils, 'git_src_dir')
573 @patch.object(cinder_utils, 'service_restart')
574 @patch.object(cinder_utils, 'render')
575 @patch('os.path.join')
576 @patch('os.path.exists')
577 @patch('shutil.copytree')
578 @patch('shutil.rmtree')
579 @patch('pwd.getpwnam')
580 @patch('grp.getgrnam')
581 @patch('os.chown')
582 @patch('os.chmod')
583 def test_git_post_install(self, chmod, chown, grp, pwd, rmtree, copytree,
584 exists, join, render, service_restart,
585 git_src_dir):
586 projects_yaml = openstack_origin_git
587 join.return_value = 'joined-string'
588 cinder_utils.git_post_install(projects_yaml)
589 expected = [
590 call('joined-string', '/etc/cinder'),
591 ]
592 copytree.assert_has_calls(expected)
593
594 cinder_api_context = {
595 'service_description': 'Cinder API server',
596 'service_name': 'Cinder',
597 'user_name': 'cinder',
598 'start_dir': '/var/lib/cinder',
599 'process_name': 'cinder-api',
600 'executable_name': '/usr/local/bin/cinder-api',
601 'config_files': ['/etc/cinder/cinder.conf'],
602 'log_file': '/var/log/cinder/cinder-api.log',
603 }
604
605 cinder_backup_context = {
606 'service_description': 'Cinder backup server',
607 'service_name': 'Cinder',
608 'user_name': 'cinder',
609 'start_dir': '/var/lib/cinder',
610 'process_name': 'cinder-backup',
611 'executable_name': '/usr/local/bin/cinder-backup',
612 'config_files': ['/etc/cinder/cinder.conf'],
613 'log_file': '/var/log/cinder/cinder-backup.log',
614 }
615
616 cinder_scheduler_context = {
617 'service_description': 'Cinder scheduler server',
618 'service_name': 'Cinder',
619 'user_name': 'cinder',
620 'start_dir': '/var/lib/cinder',
621 'process_name': 'cinder-scheduler',
622 'executable_name': '/usr/local/bin/cinder-scheduler',
623 'config_files': ['/etc/cinder/cinder.conf'],
624 'log_file': '/var/log/cinder/cinder-scheduler.log',
625 }
626
627 cinder_volume_context = {
628 'service_description': 'Cinder volume server',
629 'service_name': 'Cinder',
630 'user_name': 'cinder',
631 'start_dir': '/var/lib/cinder',
632 'process_name': 'cinder-volume',
633 'executable_name': '/usr/local/bin/cinder-volume',
634 'config_files': ['/etc/cinder/cinder.conf'],
635 'log_file': '/var/log/cinder/cinder-volume.log',
636 }
637 expected = [
638 call('cinder.conf', '/etc/cinder/cinder.conf', {}, owner='cinder',
639 group='cinder', perms=0o644),
640 call('git/cinder_tgt.conf', '/etc/tgt/conf.d', {}, owner='cinder',
641 group='cinder', perms=0o644),
642 call('git/logging.conf', '/etc/cinder/logging.conf', {},
643 owner='cinder', group='cinder', perms=0o644),
644 call('git/cinder_sudoers', '/etc/sudoers.d/cinder_sudoers', {},
645 owner='root', group='root', perms=0o440),
646 call('git.upstart', '/etc/init/cinder-api.conf',
647 cinder_api_context, perms=0o644,
648 templates_dir='joined-string'),
649 call('git.upstart', '/etc/init/cinder-backup.conf',
650 cinder_backup_context, perms=0o644,
651 templates_dir='joined-string'),
652 call('git.upstart', '/etc/init/cinder-scheduler.conf',
653 cinder_scheduler_context, perms=0o644,
654 templates_dir='joined-string'),
655 call('git.upstart', '/etc/init/cinder-volume.conf',
656 cinder_volume_context, perms=0o644,
657 templates_dir='joined-string'),
658 ]
659 self.assertEquals(render.call_args_list, expected)
660 expected = [
661 call('tgtd'), call('haproxy'), call('apache2'),
662 call('cinder-api'), call('cinder-volume'),
663 call('cinder-scheduler'),
664 ]
665 self.assertEquals(service_restart.call_args_list, expected)

Subscribers

People subscribed via source and target branches