VMware: Handle concurrent registrations of the VC extension
During initialization, the Nova compute driver checks whether a vCenter extension with key 'org.openstack.compute' exists and if not, it registers one. This is a race condition. If multiple services try to register the same extension, only one of them will succeed. The fix is to catch InvalidArgument fault from vSphere API and ignore the exception. Change-Id: I92c24709a2f55b601c31a31b9e748f19e7e31984 Closes-Bug: #1704952
This commit is contained in:
parent
100a194ab1
commit
46c7fa492f
|
@ -2055,6 +2055,18 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
|
|||
'find_extension',
|
||||
constants.EXTENSION_KEY)
|
||||
|
||||
def test_register_extension_concurrent(self):
|
||||
def fake_call_method(module, method, *args, **kwargs):
|
||||
if method == "find_extension":
|
||||
return None
|
||||
elif method == "register_extension":
|
||||
raise vexc.VimFaultException(['InvalidArgument'], 'error')
|
||||
else:
|
||||
raise Exception()
|
||||
with (mock.patch.object(
|
||||
self.conn._session, '_call_method', fake_call_method)):
|
||||
self.conn._register_openstack_extension()
|
||||
|
||||
def test_list_instances(self):
|
||||
instances = self.conn.list_instances()
|
||||
self.assertEqual(0, len(instances))
|
||||
|
|
|
@ -183,16 +183,23 @@ class VMwareVCDriver(driver.ComputeDriver):
|
|||
|
||||
def _register_openstack_extension(self):
|
||||
# Register an 'OpenStack' extension in vCenter
|
||||
LOG.debug('Registering extension %s with vCenter',
|
||||
constants.EXTENSION_KEY)
|
||||
os_extension = self._session._call_method(vim_util, 'find_extension',
|
||||
constants.EXTENSION_KEY)
|
||||
if os_extension is None:
|
||||
LOG.debug('Extension does not exist. Registering type %s.',
|
||||
constants.EXTENSION_TYPE_INSTANCE)
|
||||
self._session._call_method(vim_util, 'register_extension',
|
||||
constants.EXTENSION_KEY,
|
||||
constants.EXTENSION_TYPE_INSTANCE)
|
||||
try:
|
||||
self._session._call_method(vim_util, 'register_extension',
|
||||
constants.EXTENSION_KEY,
|
||||
constants.EXTENSION_TYPE_INSTANCE)
|
||||
LOG.info('Registered extension %s with vCenter',
|
||||
constants.EXTENSION_KEY)
|
||||
except vexc.VimFaultException as e:
|
||||
with excutils.save_and_reraise_exception() as ctx:
|
||||
if 'InvalidArgument' in e.fault_list:
|
||||
LOG.debug('Extension %s already exists.',
|
||||
constants.EXTENSION_KEY)
|
||||
ctx.reraise = False
|
||||
else:
|
||||
LOG.debug('Extension %s already exists.', constants.EXTENSION_KEY)
|
||||
|
||||
def cleanup(self, context, instance, network_info, block_device_info=None,
|
||||
destroy_disks=True, migrate_data=None, destroy_vifs=True):
|
||||
|
|
Loading…
Reference in New Issue