'-8ffd-0800200c9a66',
version='1.9')
- def test_extend_volume(self):
+ @mock.patch('oslo_messaging.RPCClient.can_send_version',
+ return_value=True)
+ def test_extend_volume(self, can_send_version):
self._test_volume_api('extend_volume',
rpc_method='cast',
- volume=self.fake_volume,
+ volume=self.fake_volume_obj,
+ new_size=1,
+ reservations=self.fake_reservations,
+ version='1.35')
+ can_send_version.assert_called_once_with('1.35')
+
+ @mock.patch('oslo_messaging.RPCClient.can_send_version',
+ return_value=False)
+ def test_extend_volume_old(self, can_send_version):
+ self._test_volume_api('extend_volume',
+ rpc_method='cast',
+ volume=self.fake_volume_obj,
new_size=1,
reservations=self.fake_reservations,
version='1.14')
+ can_send_version.assert_called_once_with('1.35')
def test_migrate_volume(self):
class FakeHost(object):
@wrap_check_policy
def extend(self, context, volume, new_size):
- if volume['status'] != 'available':
+ if volume.status != 'available':
msg = _('Volume %(vol_id)s status must be available '
'to extend, but current status is: '
- '%(vol_status)s.') % {'vol_id': volume['id'],
- 'vol_status': volume['status']}
+ '%(vol_status)s.') % {'vol_id': volume.id,
+ 'vol_status': volume.status}
raise exception.InvalidVolume(reason=msg)
- size_increase = (int(new_size)) - volume['size']
+ size_increase = (int(new_size)) - volume.size
if size_increase <= 0:
msg = (_("New size for extend must be greater "
"than current size. (current: %(size)s, "
"extended: %(new_size)s).") % {'new_size': new_size,
- 'size': volume['size']})
+ 'size': volume.size})
raise exception.InvalidInput(reason=msg)
try:
reserve_opts = {'gigabytes': size_increase}
QUOTAS.add_volume_type_opts(context, reserve_opts,
- volume.get('volume_type_id'))
+ volume.volume_type_id)
reservations = QUOTAS.reserve(context,
- project_id=volume['project_id'],
+ project_id=volume.project_id,
**reserve_opts)
except exception.OverQuota as exc:
usages = exc.kwargs['usages']
class VolumeManager(manager.SchedulerDependentManager):
"""Manages attachable block storage devices."""
- RPC_API_VERSION = '1.34'
+ RPC_API_VERSION = '1.35'
target = messaging.Target(version=RPC_API_VERSION)
context, snapshot, event_suffix,
extra_usage_info=extra_usage_info, host=self.host)
- def extend_volume(self, context, volume_id, new_size, reservations):
+ def extend_volume(self, context, volume_id, new_size, reservations,
+ volume=None):
+ # FIXME(thangp): Remove this in v2.0 of RPC API.
+ if volume is None:
+ # For older clients, mimic the old behavior and look up the volume
+ # by its volume_id.
+ volume = objects.Volume.get_by_id(context, volume_id)
+
try:
# NOTE(flaper87): Verify the driver is enabled
# before going forward. The exception will be caught
utils.require_driver_initialized(self.driver)
except exception.DriverNotInitialized:
with excutils.save_and_reraise_exception():
- self.db.volume_update(context, volume_id,
- {'status': 'error_extending'})
+ volume.status = 'error_extending'
+ volume.save()
- volume = self.db.volume_get(context, volume_id)
- project_id = volume['project_id']
- size_increase = (int(new_size)) - volume['size']
+ project_id = volume.project_id
+ size_increase = (int(new_size)) - volume.size
self._notify_about_volume_usage(context, volume, "resize.start")
try:
self.driver.extend_volume(volume, new_size)
LOG.exception(_LE("Extend volume failed."),
resource=volume)
try:
- self.db.volume_update(context, volume['id'],
+ self.db.volume_update(context, volume.id,
{'status': 'error_extending'})
raise exception.CinderException(_("Volume %s: Error trying "
"to extend volume") %
- volume_id)
+ volume.id)
finally:
QUOTAS.rollback(context, reservations, project_id=project_id)
return
QUOTAS.commit(context, reservations, project_id=project_id)
- volume = self.db.volume_update(context,
- volume['id'],
- {'size': int(new_size),
- 'status': 'available'})
- pool = vol_utils.extract_host(volume['host'], 'pool')
+ volume.update({'size': int(new_size), 'status': 'available'})
+ volume.save()
+ pool = vol_utils.extract_host(volume.host, 'pool')
if pool is None:
# Legacy volume, put them into default pool
pool = self.driver.configuration.safe_get(
'volume_backend_name') or vol_utils.extract_host(
- volume['host'], 'pool', True)
+ volume.host, 'pool', True)
try:
self.stats['pools'][pool]['allocated_capacity_gb'] += size_increase
1.32 - Adds support for sending objects over RPC in create_volume().
1.33 - Adds support for sending objects over RPC in delete_volume().
1.34 - Adds support for sending objects over RPC in retype().
+ 1.35 - Adds support for sending objects over RPC in extend_volume().
"""
BASE_RPC_API_VERSION = '1.0'
new_user=new_user, new_project=new_project)
def extend_volume(self, ctxt, volume, new_size, reservations):
- new_host = utils.extract_host(volume['host'])
- cctxt = self.client.prepare(server=new_host, version='1.14')
- cctxt.cast(ctxt, 'extend_volume', volume_id=volume['id'],
- new_size=new_size, reservations=reservations)
+ new_host = utils.extract_host(volume.host)
+
+ msg_args = {'volume_id': volume.id, 'new_size': new_size,
+ 'reservations': reservations}
+ if self.client.can_send_version('1.35'):
+ version = '1.35'
+ msg_args['volume'] = volume
+ else:
+ version = '1.14'
+
+ cctxt = self.client.prepare(server=new_host, version=version)
+ cctxt.cast(ctxt, 'extend_volume', **msg_args)
def migrate_volume(self, ctxt, volume, dest_host, force_host_copy):
new_host = utils.extract_host(volume['host'])