len(expected),
len(mock_client.method_calls))
+ def test_update_migrated_volume(self):
+ mock_client = self.setup_driver()
+ volume_id = 'fake_vol_id'
+ clone_id = 'fake_clone_id'
+ fake_old_volume = {'id': volume_id}
+ provider_location = 'foo'
+ fake_new_volume = {'id': clone_id,
+ '_name_id': clone_id,
+ 'provider_location': provider_location}
+ original_volume_status = 'available'
+ with mock.patch.object(hp_lefthand_rest_proxy.HPLeftHandRESTProxy,
+ '_create_client') as mock_do_setup:
+ mock_do_setup.return_value = mock_client
+ actual_update = self.driver.update_migrated_volume(
+ context.get_admin_context(), fake_old_volume,
+ fake_new_volume, original_volume_status)
+
+ expected_update = {'_name_id': None,
+ 'provider_location': None}
+ self.assertEqual(expected_update, actual_update)
+
+ def test_update_migrated_volume_attached(self):
+ mock_client = self.setup_driver()
+ volume_id = 'fake_vol_id'
+ clone_id = 'fake_clone_id'
+ fake_old_volume = {'id': volume_id}
+ provider_location = 'foo'
+ fake_new_volume = {'id': clone_id,
+ '_name_id': clone_id,
+ 'provider_location': provider_location}
+ original_volume_status = 'in-use'
+
+ with mock.patch.object(hp_lefthand_rest_proxy.HPLeftHandRESTProxy,
+ '_create_client') as mock_do_setup:
+ mock_do_setup.return_value = mock_client
+ actual_update = self.driver.update_migrated_volume(
+ context.get_admin_context(), fake_old_volume,
+ fake_new_volume, original_volume_status)
+
+ expected_update = {'_name_id': fake_new_volume['_name_id'],
+ 'provider_location': provider_location}
+ self.assertEqual(expected_update, actual_update)
+
@mock.patch.object(volume_types, 'get_volume_type',
return_value={'extra_specs': {'hplh:ao': 'true'}})
def test_create_volume_with_ao_true(self, _mock_volume_type):
1.2.1 - Fixed bug #1279897, HP LeftHand CLIQ proxy may return incorrect
capacity values.
1.2.2 - Fixed driver with Paramiko 1.13.0, bug #1298608.
+ 1.2.3 - Added update_migrated_volume #1493546
"""
- VERSION = "1.2.2"
+ VERSION = "1.2.3"
device_stats = {}
dictionary of its reported capabilities.
"""
return (False, None)
+
+ def update_migrated_volume(self, context, volume, new_volume,
+ original_volume_status):
+ raise NotImplementedError()
1.0.6 - Updated minimum client version. bug #1432757
1.0.7 - Update driver to use ABC metaclasses
1.0.8 - Adds consistency group support
+ 1.0.9 - Added update_migrated_volume #1493546
"""
- VERSION = "1.0.8"
+ VERSION = "1.0.9"
def __init__(self, *args, **kwargs):
super(HPLeftHandISCSIDriver, self).__init__(*args, **kwargs)
"""Migrate directly if source and dest are managed by same storage."""
return self.proxy.migrate_volume(ctxt, volume, host)
+ def update_migrated_volume(self, context, volume, new_volume,
+ original_volume_status):
+ return self.proxy.update_migrated_volume(context, volume, new_volume,
+ original_volume_status)
+
def manage_existing(self, volume, existing_ref):
return self.proxy.manage_existing(volume, existing_ref)
1.0.10 - Add stats for goodness_function and filter_function
1.0.11 - Add over subscription support
1.0.12 - Adds consistency group support
+ 1.0.13 - Added update_migrated_volume #1493546
"""
- VERSION = "1.0.12"
+ VERSION = "1.0.13"
device_stats = {}
return (True, None)
+ def update_migrated_volume(self, context, volume, new_volume,
+ original_volume_status):
+ """Rename the new (temp) volume to it's original name.
+
+
+ This method tries to rename the new volume to it's original
+ name after the migration has completed.
+
+ """
+ LOG.debug("Update volume name for %(id)s.", {'id': new_volume['id']})
+ name_id = None
+ provider_location = None
+ if original_volume_status == 'available':
+ # volume isn't attached and can be updated
+ original_name = CONF.volume_name_template % volume['id']
+ current_name = CONF.volume_name_template % new_volume['id']
+ client = self._login()
+ try:
+ volume_info = client.getVolumeByName(current_name)
+ volumeMods = {'name': original_name}
+ client.modifyVolume(volume_info['id'], volumeMods)
+ LOG.info(_LI("Volume name changed from %(tmp)s to %(orig)s."),
+ {'tmp': current_name, 'orig': original_name})
+ except Exception as e:
+ LOG.error(_LE("Changing the volume name from %(tmp)s to "
+ "%(orig)s failed because %(reason)s."),
+ {'tmp': current_name, 'orig': original_name,
+ 'reason': e})
+ name_id = new_volume['_name_id'] or new_volume['id']
+ provider_location = new_volume['provider_location']
+ finally:
+ self._logout(client)
+ else:
+ # the backend can't change the name.
+ name_id = new_volume['_name_id'] or new_volume['id']
+ provider_location = new_volume['provider_location']
+
+ return {'_name_id': name_id, 'provider_location': provider_location}
+
def manage_existing(self, volume, existing_ref):
"""Manage an existing LeftHand volume.