VMware: Send additional connection info

Change I743e676372703e74178c79683dd622d530981e04 removed volume
backend driver calls for creating and restoring volume backups.
The overridden methods for creating and restoring backups in
the VMDK driver is no longer called and this breaks the backup-
restore of volumes created by the VMDK driver. Now backup and
restore of volumes use os-brick connectors.

Change Ia1a20f93780593b1efbb74484c3fdd3ca3564290 added a new
connector in os-brick to support vmdk volumes. The new vmdk
connector requires additional connection info so that it can
connect to vCenter server and access the volume vmdk to perform
volume connect and disconnect.

Closes-bug: #1602660
Change-Id: I66a30366ccdae74e13f7a0e35cd7bfdfed2785be
This commit is contained in:
Vipin Balachandran 2016-07-11 22:38:08 +05:30
parent c9148ead00
commit 18325aebc6
3 changed files with 112 additions and 22 deletions

View File

@ -1681,13 +1681,67 @@ class VMwareVcVmdkDriverTestCase(test.TestCase):
vops.get_dc.assert_called_once_with(rp) vops.get_dc.assert_called_once_with(rp)
get_volume_group_folder.assert_called_once_with(dc, vol['project_id']) get_volume_group_folder.assert_called_once_with(dc, vol['project_id'])
@mock.patch.object(VMDK_DRIVER, 'volumeops')
def _test_get_connection_info(self, vops, vmdk_connector=False):
volume = self._create_volume_obj()
backing = mock.Mock(value='ref-1')
if vmdk_connector:
vmdk_path = mock.sentinel.vmdk_path
vops.get_vmdk_path.return_value = vmdk_path
datastore = mock.Mock(value='ds-1')
vops.get_datastore.return_value = datastore
datacenter = mock.Mock(value='dc-1')
vops.get_dc.return_value = datacenter
connector = {'platform': mock.sentinel.platform,
'os_type': mock.sentinel.os_type}
else:
connector = {'instance': 'vm-1'}
ret = self._driver._get_connection_info(volume, backing, connector)
self.assertEqual('vmdk', ret['driver_volume_type'])
self.assertEqual('ref-1', ret['data']['volume'])
self.assertEqual(volume.id, ret['data']['volume_id'])
self.assertEqual(volume.name, ret['data']['name'])
if vmdk_connector:
self.assertEqual(volume.size * units.Gi, ret['data']['vmdk_size'])
self.assertEqual(vmdk_path, ret['data']['vmdk_path'])
self.assertEqual('ds-1', ret['data']['datastore'])
self.assertEqual('dc-1', ret['data']['datacenter'])
config = self._driver.configuration
exp_config = {
'vmware_host_ip': config.vmware_host_ip,
'vmware_host_port': config.vmware_host_port,
'vmware_host_username': config.vmware_host_username,
'vmware_host_password': config.vmware_host_password,
'vmware_api_retry_count': config.vmware_api_retry_count,
'vmware_task_poll_interval': config.vmware_task_poll_interval,
'vmware_ca_file': config.vmware_ca_file,
'vmware_insecure': config.vmware_insecure,
'vmware_tmp_dir': config.vmware_tmp_dir,
'vmware_image_transfer_timeout_secs':
config.vmware_image_transfer_timeout_secs,
}
self.assertEqual(exp_config, ret['data']['config'])
def test_get_connection_info(self):
self._test_get_connection_info()
def test_get_connection_info_vmdk_connector(self):
self._test_get_connection_info(vmdk_connector=True)
@mock.patch.object(VMDK_DRIVER, 'volumeops') @mock.patch.object(VMDK_DRIVER, 'volumeops')
@mock.patch('oslo_vmware.vim_util.get_moref') @mock.patch('oslo_vmware.vim_util.get_moref')
@mock.patch.object(VMDK_DRIVER, '_create_backing') @mock.patch.object(VMDK_DRIVER, '_create_backing')
@mock.patch.object(VMDK_DRIVER, '_relocate_backing') @mock.patch.object(VMDK_DRIVER, '_relocate_backing')
@mock.patch.object(VMDK_DRIVER, '_get_connection_info')
def _test_initialize_connection( def _test_initialize_connection(
self, relocate_backing, create_backing, get_moref, vops, self, get_connection_info, relocate_backing, create_backing,
backing_exists=True, instance_exists=True): get_moref, vops, backing_exists=True, instance_exists=True):
backing_val = mock.sentinel.backing_val backing_val = mock.sentinel.backing_val
backing = mock.Mock(value=backing_val) backing = mock.Mock(value=backing_val)
@ -1709,14 +1763,13 @@ class VMwareVcVmdkDriverTestCase(test.TestCase):
else: else:
connector = {} connector = {}
conn_info = mock.sentinel.conn_info
get_connection_info.return_value = conn_info
volume = self._create_volume_obj() volume = self._create_volume_obj()
conn_info = self._driver.initialize_connection(volume, connector) ret = self._driver.initialize_connection(volume, connector)
self.assertEqual('vmdk', conn_info['driver_volume_type'])
self.assertEqual(backing_val, conn_info['data']['volume'])
self.assertEqual(volume.id, conn_info['data']['volume_id'])
self.assertEqual(volume.name, conn_info['data']['name'])
self.assertEqual(conn_info, ret)
if instance_exists: if instance_exists:
vops.get_host.assert_called_once_with(instance_moref) vops.get_host.assert_called_once_with(instance_moref)
if backing_exists: if backing_exists:
@ -1731,6 +1784,7 @@ class VMwareVcVmdkDriverTestCase(test.TestCase):
else: else:
create_backing.assert_not_called() create_backing.assert_not_called()
relocate_backing.assert_not_called() relocate_backing.assert_not_called()
get_connection_info.assert_called_once_with(volume, backing, connector)
def test_initialize_connection_with_instance_and_backing(self): def test_initialize_connection_with_instance_and_backing(self):
self._test_initialize_connection() self._test_initialize_connection()

View File

@ -502,6 +502,51 @@ class VMwareVcVmdkDriver(driver.VolumeDriver):
return (host_ref, resource_pool, folder, summary) return (host_ref, resource_pool, folder, summary)
def _get_connection_info(self, volume, backing, connector):
connection_info = {'driver_volume_type': 'vmdk'}
connection_info['data'] = {
'volume': backing.value,
'volume_id': volume.id,
'name': volume.name,
}
# vmdk connector in os-brick needs additional connection info.
if 'platform' in connector and 'os_type' in connector:
connection_info['data']['vmdk_size'] = volume['size'] * units.Gi
vmdk_path = self.volumeops.get_vmdk_path(backing)
connection_info['data']['vmdk_path'] = vmdk_path
datastore = self.volumeops.get_datastore(backing)
connection_info['data']['datastore'] = datastore.value
datacenter = self.volumeops.get_dc(backing)
connection_info['data']['datacenter'] = datacenter.value
config = self.configuration
vmdk_connector_config = {
'vmware_host_ip': config.vmware_host_ip,
'vmware_host_port': config.vmware_host_port,
'vmware_host_username': config.vmware_host_username,
'vmware_host_password': config.vmware_host_password,
'vmware_api_retry_count': config.vmware_api_retry_count,
'vmware_task_poll_interval': config.vmware_task_poll_interval,
'vmware_ca_file': config.vmware_ca_file,
'vmware_insecure': config.vmware_insecure,
'vmware_tmp_dir': config.vmware_tmp_dir,
'vmware_image_transfer_timeout_secs':
config.vmware_image_transfer_timeout_secs,
}
connection_info['data']['config'] = vmdk_connector_config
LOG.debug("Returning connection_info (volume: '%(volume)s', volume_id:"
" '%(volume_id)s') for connector: %(connector)s.",
{'volume': connection_info['data']['volume'],
'volume_id': volume.id,
'connector': connector})
return connection_info
def _initialize_connection(self, volume, connector): def _initialize_connection(self, volume, connector):
"""Get information of volume's backing. """Get information of volume's backing.
@ -511,8 +556,6 @@ class VMwareVcVmdkDriver(driver.VolumeDriver):
:param connector: Connector information :param connector: Connector information
:return: Return connection information :return: Return connection information
""" """
connection_info = {'driver_volume_type': 'vmdk'}
backing = self.volumeops.get_backing(volume.name) backing = self.volumeops.get_backing(volume.name)
if 'instance' in connector: if 'instance' in connector:
# The instance exists # The instance exists
@ -543,18 +586,7 @@ class VMwareVcVmdkDriver(driver.VolumeDriver):
# Create backing # Create backing
backing = self._create_backing(volume) backing = self._create_backing(volume)
# Set volume ID and backing moref value and name. return self._get_connection_info(volume, backing, connector)
connection_info['data'] = {'volume': backing.value,
'volume_id': volume.id,
'name': volume.name}
LOG.info(_LI("Returning connection_info: %(info)s for volume: "
"%(volume)s with connector: %(connector)s."),
{'info': connection_info,
'volume': volume.name,
'connector': connector})
return connection_info
def initialize_connection(self, volume, connector): def initialize_connection(self, volume, connector):
"""Allow connection to connector and return connection info. """Allow connection to connector and return connection info.

View File

@ -0,0 +1,4 @@
---
fixes:
- Fixed backup and restore of volumes in VMware VMDK driver.