Merge lp:~hopem/charms/trusty/nova-compute/rbd-imagebackend-support into lp:~openstack-charmers-archive/charms/trusty/nova-compute/next

Proposed by Edward Hope-Morley
Status: Merged
Merged at revision: 94
Proposed branch: lp:~hopem/charms/trusty/nova-compute/rbd-imagebackend-support
Merge into: lp:~openstack-charmers-archive/charms/trusty/nova-compute/next
Diff against target: 548 lines (+214/-75)
10 files modified
config.yaml (+23/-0)
hooks/charmhelpers/contrib/storage/linux/ceph.py (+43/-0)
hooks/nova_compute_context.py (+32/-6)
hooks/nova_compute_hooks.py (+36/-5)
hooks/nova_compute_utils.py (+18/-21)
revision (+1/-1)
templates/havana/nova.conf (+15/-7)
templates/juno/nova.conf (+8/-0)
unit_tests/test_nova_compute_hooks.py (+12/-19)
unit_tests/test_nova_compute_utils.py (+26/-16)
To merge this branch: bzr merge lp:~hopem/charms/trusty/nova-compute/rbd-imagebackend-support
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+244708@code.launchpad.net
To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #171 nova-compute-next for hopem mp244708
    LINT OK: passed

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

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

charm_unit_test #205 nova-compute-next for hopem mp244708
    UNIT OK: passed

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'config.yaml'
--- config.yaml 2014-12-11 20:11:41 +0000
+++ config.yaml 2014-12-15 10:50:53 +0000
@@ -154,6 +154,29 @@
154 order for this charm to function correctly, the privacy extension must be154 order for this charm to function correctly, the privacy extension must be
155 disabled and a non-temporary address must be configured/available on155 disabled and a non-temporary address must be configured/available on
156 your network interface.156 your network interface.
157 libvirt-image-backend:
158 default: ""
159 type: string
160 description:
161 Tell Nova which libvirt image backend to use. Supported backends are rbd and lvm.
162 If no backend is specified, the Nova default is used (probably qcow2).
163 rbd-pool:
164 default: "nova"
165 type: string
166 description: |
167 RBD pool to use with Nova RBD image backend. Only required when
168 libvirt_image_backend is rbd. IMPORTANT: pool must exist before adding
169 ceph-relation.
170 ceph-osd-replication-count:
171 default: 3
172 type: int
173 description: |
174 This value dictates the number of replicas ceph must make of any
175 object it stores withing the nova rbd pool. Of course, this only
176 applies if using Ceph as a backend store. Note that once the nova
177 rbd pool has been created, changing this value will not have any
178 effect (although it can be changed in ceph by manually configuring
179 your ceph cluster).
157 sysctl:180 sysctl:
158 type: string181 type: string
159 default:182 default:
160183
=== modified file 'hooks/charmhelpers/contrib/storage/linux/ceph.py'
--- hooks/charmhelpers/contrib/storage/linux/ceph.py 2014-12-15 09:10:57 +0000
+++ hooks/charmhelpers/contrib/storage/linux/ceph.py 2014-12-15 10:50:53 +0000
@@ -372,3 +372,46 @@
372 return None372 return None
373 else:373 else:
374 return None374 return None
375
376
377class CephBrokerRq(object):
378 """Ceph broker request.
379
380 Multiple operations can be added to a request and sent to the Ceph broker
381 to be executed.
382
383 Request is json-encoded for sending over the wire.
384
385 The API is versioned and defaults to version 1.
386 """
387 def __init__(self, api_version=1):
388 self.api_version = api_version
389 self.ops = []
390
391 def add_op_create_pool(self, name, replica_count=3):
392 self.ops.append({'op': 'create-pool', 'name': name,
393 'replicas': replica_count})
394
395 @property
396 def request(self):
397 return json.dumps({'api-version': self.api_version, 'ops': self.ops})
398
399
400class CephBrokerRsp(object):
401 """Ceph broker response.
402
403 Response is json-decoded and contents provided as methods/properties.
404
405 The API is versioned and defaults to version 1.
406 """
407 def __init__(self, encoded_rsp):
408 self.api_version = None
409 self.rsp = json.loads(encoded_rsp)
410
411 @property
412 def exit_code(self):
413 return self.rsp.get('exit-code')
414
415 @property
416 def exit_msg(self):
417 return self.rsp.get('stderr')
375418
=== modified file 'hooks/nova_compute_context.py'
--- hooks/nova_compute_context.py 2014-12-03 23:54:27 +0000
+++ hooks/nova_compute_context.py 2014-12-15 10:50:53 +0000
@@ -1,9 +1,6 @@
1
2from charmhelpers.contrib.openstack import context1from charmhelpers.contrib.openstack import context
3
4from charmhelpers.core.host import service_running, service_start2from charmhelpers.core.host import service_running, service_start
5from charmhelpers.fetch import apt_install, filter_installed_packages3from charmhelpers.fetch import apt_install, filter_installed_packages
6
7from charmhelpers.core.hookenv import (4from charmhelpers.core.hookenv import (
8 config,5 config,
9 log,6 log,
@@ -14,8 +11,12 @@
14 unit_get,11 unit_get,
15 ERROR,12 ERROR,
16)13)
1714from charmhelpers.contrib.openstack.utils import (
18from charmhelpers.contrib.openstack.utils import get_host_ip, os_release15 get_host_ip,
16 os_release,
17 get_os_version_package,
18 get_os_version_codename
19)
19from charmhelpers.contrib.network.ovs import add_bridge20from charmhelpers.contrib.network.ovs import add_bridge
2021
21from charmhelpers.contrib.network.ip import (22from charmhelpers.contrib.network.ip import (
@@ -30,6 +31,13 @@
3031
31OVS_BRIDGE = 'br-int'32OVS_BRIDGE = 'br-int'
3233
34CEPH_CONF = '/etc/ceph/ceph.conf'
35CHARM_CEPH_CONF = '/var/lib/charm/{}/ceph.conf'
36
37
38def ceph_config_file():
39 return CHARM_CEPH_CONF.format(service_name())
40
3341
34def _save_flag_file(path, data):42def _save_flag_file(path, data):
35 '''43 '''
@@ -121,6 +129,17 @@
121 return {}129 return {}
122130
123131
132def assert_libvirt_imagebackend_allowed():
133 os_rel = "Juno"
134 os_ver = get_os_version_package('nova-compute')
135 if float(os_ver) < float(get_os_version_codename(os_rel.lower())):
136 msg = ("Libvirt RBD imagebackend only supported for openstack >= %s" %
137 os_rel)
138 raise Exception(msg)
139
140 return True
141
142
124class NovaComputeCephContext(context.CephContext):143class NovaComputeCephContext(context.CephContext):
125144
126 def __call__(self):145 def __call__(self):
@@ -134,7 +153,14 @@
134 ctxt['service_name'] = svc153 ctxt['service_name'] = svc
135 ctxt['rbd_user'] = svc154 ctxt['rbd_user'] = svc
136 ctxt['rbd_secret_uuid'] = CEPH_SECRET_UUID155 ctxt['rbd_secret_uuid'] = CEPH_SECRET_UUID
137 ctxt['rbd_pool'] = 'nova'156 ctxt['rbd_pool'] = config('rbd-pool')
157
158 if (config('libvirt-image-backend') == 'rbd' and
159 assert_libvirt_imagebackend_allowed()):
160 ctxt['libvirt_images_type'] = 'rbd'
161 ctxt['libvirt_rbd_images_ceph_conf'] = ceph_config_file()
162 elif config('libvirt-image-backend') == 'lvm':
163 ctxt['libvirt_images_type'] = 'lvm'
138164
139 return ctxt165 return ctxt
140166
141167
=== modified file 'hooks/nova_compute_hooks.py'
--- hooks/nova_compute_hooks.py 2014-12-11 20:11:41 +0000
+++ hooks/nova_compute_hooks.py 2014-12-15 10:50:53 +0000
@@ -1,5 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python
2
3import sys2import sys
43
5from charmhelpers.core.hookenv import (4from charmhelpers.core.hookenv import (
@@ -7,6 +6,7 @@
7 config,6 config,
8 is_relation_made,7 is_relation_made,
9 log,8 log,
9 INFO,
10 ERROR,10 ERROR,
11 relation_ids,11 relation_ids,
12 relation_get,12 relation_get,
@@ -30,7 +30,11 @@
30 openstack_upgrade_available,30 openstack_upgrade_available,
31)31)
3232
33from charmhelpers.contrib.storage.linux.ceph import ensure_ceph_keyring33from charmhelpers.contrib.storage.linux.ceph import (
34 ensure_ceph_keyring,
35 CephBrokerRq,
36 CephBrokerRsp,
37)
34from charmhelpers.payload.execd import execd_preinstall38from charmhelpers.payload.execd import execd_preinstall
35from nova_compute_utils import (39from nova_compute_utils import (
36 create_libvirt_secret,40 create_libvirt_secret,
@@ -57,9 +61,12 @@
57 get_ipv6_addr61 get_ipv6_addr
58)62)
5963
64from nova_compute_context import (
65 CEPH_SECRET_UUID,
66 assert_libvirt_imagebackend_allowed
67)
60from charmhelpers.core.sysctl import create as create_sysctl68from charmhelpers.core.sysctl import create as create_sysctl
6169
62from nova_compute_context import CEPH_SECRET_UUID
63from socket import gethostname70from socket import gethostname
6471
65hooks = Hooks()72hooks = Hooks()
@@ -231,10 +238,12 @@
231 if 'ceph' not in CONFIGS.complete_contexts():238 if 'ceph' not in CONFIGS.complete_contexts():
232 log('ceph relation incomplete. Peer not ready?')239 log('ceph relation incomplete. Peer not ready?')
233 return240 return
234 svc = service_name()241
235 if not ensure_ceph_keyring(service=svc):242 if not ensure_ceph_keyring(service=service_name(), user='nova',
243 group='nova'):
236 log('Could not create ceph keyring: peer not ready?')244 log('Could not create ceph keyring: peer not ready?')
237 return245 return
246
238 CONFIGS.write(ceph_config_file())247 CONFIGS.write(ceph_config_file())
239 CONFIGS.write(CEPH_SECRET)248 CONFIGS.write(CEPH_SECRET)
240 CONFIGS.write(NOVA_CONF)249 CONFIGS.write(NOVA_CONF)
@@ -246,6 +255,28 @@
246 secret_uuid=CEPH_SECRET_UUID,255 secret_uuid=CEPH_SECRET_UUID,
247 key=relation_get('key'))256 key=relation_get('key'))
248257
258 if (config('libvirt-image-backend') == 'rbd' and
259 assert_libvirt_imagebackend_allowed()):
260 settings = relation_get()
261 if settings and 'broker_rsp' in settings:
262 rsp = CephBrokerRsp(settings['broker_rsp'])
263 # Non-zero return code implies failure
264 if rsp.exit_code:
265 log("Ceph broker request failed (rc=%s, msg=%s)" %
266 (rsp.exit_code, rsp.exit_msg), level=ERROR)
267 return
268
269 log("Ceph broker request succeeded (rc=%s, msg=%s)" %
270 (rsp.exit_code, rsp.exit_msg), level=INFO)
271 else:
272 rq = CephBrokerRq()
273 replicas = config('ceph-osd-replication-count')
274 rq.add_op_create_pool(name=config('rbd-pool'),
275 replica_count=replicas)
276 for rid in relation_ids('ceph'):
277 relation_set(broker_req=rq.request)
278 log("Request(s) sent to Ceph broker (rid=%s)" % (rid))
279
249280
250@hooks.hook('amqp-relation-broken',281@hooks.hook('amqp-relation-broken',
251 'ceph-relation-broken',282 'ceph-relation-broken',
252283
=== modified file 'hooks/nova_compute_utils.py'
--- hooks/nova_compute_utils.py 2014-12-03 23:54:27 +0000
+++ hooks/nova_compute_utils.py 2014-12-15 10:50:53 +0000
@@ -23,8 +23,7 @@
23 related_units,23 related_units,
24 relation_ids,24 relation_ids,
25 relation_get,25 relation_get,
26 DEBUG,26 DEBUG
27 service_name,
28)27)
2928
30from charmhelpers.contrib.openstack.neutron import neutron_plugin_attribute29from charmhelpers.contrib.openstack.neutron import neutron_plugin_attribute
@@ -43,6 +42,8 @@
43 NovaComputeCephContext,42 NovaComputeCephContext,
44 NeutronComputeContext,43 NeutronComputeContext,
45 InstanceConsoleContext,44 InstanceConsoleContext,
45 CEPH_CONF,
46 ceph_config_file,
46 HostIPContext,47 HostIPContext,
47)48)
4849
@@ -95,8 +96,6 @@
95 },96 },
96}97}
9798
98CEPH_CONF = '/etc/ceph/ceph.conf'
99CHARM_CEPH_CONF = '/var/lib/charm/{}/ceph.conf'
100CEPH_SECRET = '/etc/ceph/secret.xml'99CEPH_SECRET = '/etc/ceph/secret.xml'
101100
102CEPH_RESOURCES = {101CEPH_RESOURCES = {
@@ -150,10 +149,6 @@
150}149}
151150
152151
153def ceph_config_file():
154 return CHARM_CEPH_CONF.format(service_name())
155
156
157def resource_map():152def resource_map():
158 '''153 '''
159 Dynamically generate a map of resources that will be managed for a single154 Dynamically generate a map of resources that will be managed for a single
@@ -198,21 +193,9 @@
198 resource_map[NOVA_CONF]['contexts'].append(NeutronComputeContext())193 resource_map[NOVA_CONF]['contexts'].append(NeutronComputeContext())
199194
200 if relation_ids('ceph'):195 if relation_ids('ceph'):
201 # Add charm ceph configuration to resources and
202 # ensure directory actually exists
203 mkdir(os.path.dirname(ceph_config_file()))
204 mkdir(os.path.dirname(CEPH_CONF))
205 # Install ceph config as an alternative for co-location with
206 # ceph and ceph-osd charms - nova-compute ceph.conf will be
207 # lower priority that both of these but thats OK
208 if not os.path.exists(ceph_config_file()):
209 # touch file for pre-templated generation
210 open(ceph_config_file(), 'w').close()
211 install_alternative(os.path.basename(CEPH_CONF),
212 CEPH_CONF, ceph_config_file())
213 CEPH_RESOURCES[ceph_config_file()] = {196 CEPH_RESOURCES[ceph_config_file()] = {
214 'contexts': [NovaComputeCephContext()],197 'contexts': [NovaComputeCephContext()],
215 'services': [],198 'services': ['nova-compute']
216 }199 }
217 resource_map.update(CEPH_RESOURCES)200 resource_map.update(CEPH_RESOURCES)
218201
@@ -243,6 +226,20 @@
243 configs = templating.OSConfigRenderer(templates_dir=TEMPLATES,226 configs = templating.OSConfigRenderer(templates_dir=TEMPLATES,
244 openstack_release=release)227 openstack_release=release)
245228
229 if relation_ids('ceph'):
230 # Add charm ceph configuration to resources and
231 # ensure directory actually exists
232 mkdir(os.path.dirname(ceph_config_file()))
233 mkdir(os.path.dirname(CEPH_CONF))
234 # Install ceph config as an alternative for co-location with
235 # ceph and ceph-osd charms - nova-compute ceph.conf will be
236 # lower priority that both of these but thats OK
237 if not os.path.exists(ceph_config_file()):
238 # touch file for pre-templated generation
239 open(ceph_config_file(), 'w').close()
240 install_alternative(os.path.basename(CEPH_CONF),
241 CEPH_CONF, ceph_config_file())
242
246 for cfg, d in resource_map().iteritems():243 for cfg, d in resource_map().iteritems():
247 configs.register(cfg, d['contexts'])244 configs.register(cfg, d['contexts'])
248 return configs245 return configs
249246
=== modified file 'revision'
--- revision 2014-03-27 11:08:20 +0000
+++ revision 2014-12-15 10:50:53 +0000
@@ -1,1 +1,1 @@
11321133
22
=== modified file 'templates/havana/nova.conf'
--- templates/havana/nova.conf 2014-12-03 23:23:54 +0000
+++ templates/havana/nova.conf 2014-12-15 10:50:53 +0000
@@ -31,12 +31,6 @@
31glance_api_servers = {{ glance_api_servers }}31glance_api_servers = {{ glance_api_servers }}
32{% endif -%}32{% endif -%}
3333
34{% if rbd_pool -%}
35rbd_pool = {{ rbd_pool }}
36rbd_user = {{ rbd_user }}
37rbd_secret_uuid = {{ rbd_secret_uuid }}
38{% endif -%}
39
40{% if console_vnc_type -%}34{% if console_vnc_type -%}
41vnc_enabled = True35vnc_enabled = True
42novnc_enabled = True36novnc_enabled = True
@@ -116,7 +110,21 @@
116server_proxyclient_address = {{ console_listen_addr }}110server_proxyclient_address = {{ console_listen_addr }}
117{% endif -%}111{% endif -%}
118112
113[libvirt]
114{% if libvirt_images_type -%}
115images_type = {{ libvirt_images_type }}
116images_rbd_pool = {{ rbd_pool }}
117images_rbd_ceph_conf = {{ libvirt_rbd_images_ceph_conf }}
118inject_password=false
119inject_key=false
120inject_partition=-2
121{% endif -%}
122{% if rbd_pool -%}
123rbd_pool = {{ rbd_pool }}
124rbd_user = {{ rbd_user }}
125rbd_secret_uuid = {{ rbd_secret_uuid }}
126{% endif -%}
119{% if disk_cachemodes -%}127{% if disk_cachemodes -%}
120[libvirt]
121disk_cachemodes = {{ disk_cachemodes }}128disk_cachemodes = {{ disk_cachemodes }}
122{% endif -%}129{% endif -%}
130
123131
=== modified file 'templates/juno/nova.conf'
--- templates/juno/nova.conf 2014-12-03 23:23:54 +0000
+++ templates/juno/nova.conf 2014-12-15 10:50:53 +0000
@@ -107,6 +107,14 @@
107{% endif -%}107{% endif -%}
108108
109[libvirt]109[libvirt]
110{% if libvirt_images_type -%}
111images_type = {{ libvirt_images_type }}
112images_rbd_pool = {{ rbd_pool }}
113images_rbd_ceph_conf = {{ libvirt_rbd_images_ceph_conf }}
114inject_password=false
115inject_key=false
116inject_partition=-2
117{% endif -%}
110{% if rbd_pool -%}118{% if rbd_pool -%}
111rbd_pool = {{ rbd_pool }}119rbd_pool = {{ rbd_pool }}
112rbd_user = {{ rbd_user }}120rbd_user = {{ rbd_user }}
113121
=== modified file 'unit_tests/test_nova_compute_hooks.py'
--- unit_tests/test_nova_compute_hooks.py 2014-12-11 20:11:41 +0000
+++ unit_tests/test_nova_compute_hooks.py 2014-12-15 10:50:53 +0000
@@ -1,19 +1,15 @@
1from mock import call, patch, MagicMock1from mock import (
2 call,
3 patch,
4 MagicMock
5)
26
3from test_utils import CharmTestCase7from test_utils import CharmTestCase
48
5import nova_compute_utils as utils9with patch("nova_compute_utils.restart_map"):
610 with patch("nova_compute_utils.register_configs"):
7_reg = utils.register_configs11 import nova_compute_hooks as hooks
8_map = utils.restart_map12
9
10utils.register_configs = MagicMock()
11utils.restart_map = MagicMock()
12
13import nova_compute_hooks as hooks
14
15utils.register_configs = _reg
16utils.restart_map = _map
1713
18TO_PATCH = [14TO_PATCH = [
19 # charmhelpers.core.hookenv15 # charmhelpers.core.hookenv
@@ -59,17 +55,14 @@
59]55]
6056
6157
62def fake_filter(packages):
63 return packages
64
65
66class NovaComputeRelationsTests(CharmTestCase):58class NovaComputeRelationsTests(CharmTestCase):
6759
68 def setUp(self):60 def setUp(self):
69 super(NovaComputeRelationsTests, self).setUp(hooks,61 super(NovaComputeRelationsTests, self).setUp(hooks,
70 TO_PATCH)62 TO_PATCH)
71 self.config.side_effect = self.test_config.get63 self.config.side_effect = self.test_config.get
72 self.filter_installed_packages.side_effect = fake_filter64 self.filter_installed_packages.side_effect = \
65 MagicMock(side_effect=lambda pkgs: pkgs)
73 self.gethostname.return_value = 'testserver'66 self.gethostname.return_value = 'testserver'
7467
75 def test_install_hook(self):68 def test_install_hook(self):
@@ -368,7 +361,7 @@
368 'Could not create ceph keyring: peer not ready?'361 'Could not create ceph keyring: peer not ready?'
369 )362 )
370363
371 @patch.object(utils, 'service_name')364 @patch('nova_compute_context.service_name')
372 @patch.object(hooks, 'CONFIGS')365 @patch.object(hooks, 'CONFIGS')
373 def test_ceph_changed_with_key_and_relation_data(self, configs,366 def test_ceph_changed_with_key_and_relation_data(self, configs,
374 service_name):367 service_name):
375368
=== modified file 'unit_tests/test_nova_compute_utils.py'
--- unit_tests/test_nova_compute_utils.py 2014-11-28 14:17:10 +0000
+++ unit_tests/test_nova_compute_utils.py 2014-12-15 10:50:53 +0000
@@ -1,10 +1,18 @@
1from mock import patch, MagicMock, call1import itertools
22import tempfile
3from test_utils import CharmTestCase, patch_open
4
53
6import nova_compute_utils as utils4import nova_compute_utils as utils
7import itertools5
6from mock import (
7 patch,
8 MagicMock,
9 call
10)
11from test_utils import (
12 CharmTestCase,
13 patch_open
14)
15
816
9TO_PATCH = [17TO_PATCH = [
10 'config',18 'config',
@@ -14,7 +22,6 @@
14 'related_units',22 'related_units',
15 'relation_ids',23 'relation_ids',
16 'relation_get',24 'relation_get',
17 'service_name',
18 'mkdir',25 'mkdir',
19 'install_alternative'26 'install_alternative'
20]27]
@@ -32,7 +39,6 @@
32 def setUp(self):39 def setUp(self):
33 super(NovaComputeUtilsTests, self).setUp(utils, TO_PATCH)40 super(NovaComputeUtilsTests, self).setUp(utils, TO_PATCH)
34 self.config.side_effect = self.test_config.get41 self.config.side_effect = self.test_config.get
35 self.service_name.return_value = 'nova-compute'
3642
37 @patch.object(utils, 'network_manager')43 @patch.object(utils, 'network_manager')
38 def test_determine_packages_nova_network(self, net_man):44 def test_determine_packages_nova_network(self, net_man):
@@ -271,10 +277,12 @@
271 _file.write.assert_called_with('foo_cert\n')277 _file.write.assert_called_with('foo_cert\n')
272 check_call.assert_called_with(['update-ca-certificates'])278 check_call.assert_called_with(['update-ca-certificates'])
273279
280 @patch.object(utils, 'ceph_config_file')
274 @patch('charmhelpers.contrib.openstack.templating.OSConfigRenderer')281 @patch('charmhelpers.contrib.openstack.templating.OSConfigRenderer')
275 @patch.object(utils, 'quantum_enabled')282 @patch.object(utils, 'quantum_enabled')
276 @patch.object(utils, 'resource_map')283 @patch.object(utils, 'resource_map')
277 def test_register_configs(self, resource_map, quantum, renderer):284 def test_register_configs(self, resource_map, quantum, renderer,
285 mock_ceph_config_file):
278 quantum.return_value = False286 quantum.return_value = False
279 self.os_release.return_value = 'havana'287 self.os_release.return_value = 'havana'
280 fake_renderer = MagicMock()288 fake_renderer = MagicMock()
@@ -293,14 +301,16 @@
293 },301 },
294 }302 }
295 resource_map.return_value = rsc_map303 resource_map.return_value = rsc_map
296 utils.register_configs()304 with tempfile.NamedTemporaryFile() as tmpfile:
297 renderer.assert_called_with(305 mock_ceph_config_file.return_value = tmpfile.name
298 openstack_release='havana', templates_dir='templates/')306 utils.register_configs()
299 ex_reg = [307 renderer.assert_called_with(
300 call('/etc/nova/nova-compute.conf', [ctxt2]),308 openstack_release='havana', templates_dir='templates/')
301 call('/etc/nova/nova.conf', [ctxt1])309 ex_reg = [
302 ]310 call('/etc/nova/nova-compute.conf', [ctxt2]),
303 self.assertEquals(fake_renderer.register.call_args_list, ex_reg)311 call('/etc/nova/nova.conf', [ctxt1])
312 ]
313 self.assertEquals(fake_renderer.register.call_args_list, ex_reg)
304314
305 @patch.object(utils, 'check_call')315 @patch.object(utils, 'check_call')
306 def test_enable_shell(self, _check_call):316 def test_enable_shell(self, _check_call):

Subscribers

People subscribed via source and target branches