Merge "Refactor nova.volume.cinder.API to reduce roundtrips with Cinder"
This commit is contained in:
@@ -391,8 +391,8 @@ class CloudController(object):
|
||||
LOG.audit(_("Create snapshot of volume %s"), volume_id,
|
||||
context=context)
|
||||
volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
args = (context, volume, kwargs.get('name'), kwargs.get('description'))
|
||||
args = (context, volume_id, kwargs.get('name'),
|
||||
kwargs.get('description'))
|
||||
if kwargs.get('force', False):
|
||||
snapshot = self.volume_api.create_snapshot_force(*args)
|
||||
else:
|
||||
@@ -403,8 +403,7 @@ class CloudController(object):
|
||||
|
||||
def delete_snapshot(self, context, snapshot_id, **kwargs):
|
||||
snapshot_id = ec2utils.ec2_snap_id_to_uuid(snapshot_id)
|
||||
snapshot = self.volume_api.get_snapshot(context, snapshot_id)
|
||||
self.volume_api.delete_snapshot(context, snapshot)
|
||||
self.volume_api.delete_snapshot(context, snapshot_id)
|
||||
return True
|
||||
|
||||
def describe_key_pairs(self, context, key_name=None, **kwargs):
|
||||
@@ -860,8 +859,7 @@ class CloudController(object):
|
||||
validate_ec2_id(volume_id)
|
||||
volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id)
|
||||
try:
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
self.volume_api.delete(context, volume)
|
||||
self.volume_api.delete(context, volume_id)
|
||||
except exception.InvalidVolume:
|
||||
raise exception.EC2APIError(_('Delete Failed'))
|
||||
|
||||
|
||||
@@ -188,8 +188,7 @@ class VolumeController(wsgi.Controller):
|
||||
LOG.audit(_("Delete volume with id: %s"), id, context=context)
|
||||
|
||||
try:
|
||||
vol = self.volume_api.get(context, id)
|
||||
self.volume_api.delete(context, vol)
|
||||
self.volume_api.delete(context, id)
|
||||
except exception.NotFound:
|
||||
raise exc.HTTPNotFound()
|
||||
return webob.Response(status_int=202)
|
||||
@@ -578,8 +577,7 @@ class SnapshotController(wsgi.Controller):
|
||||
LOG.audit(_("Delete snapshot with id: %s"), id, context=context)
|
||||
|
||||
try:
|
||||
snapshot = self.volume_api.get_snapshot(context, id)
|
||||
self.volume_api.delete_snapshot(context, snapshot)
|
||||
self.volume_api.delete_snapshot(context, id)
|
||||
except exception.NotFound:
|
||||
return exc.HTTPNotFound()
|
||||
return webob.Response(status_int=202)
|
||||
@@ -615,7 +613,6 @@ class SnapshotController(wsgi.Controller):
|
||||
|
||||
snapshot = body['snapshot']
|
||||
volume_id = snapshot['volume_id']
|
||||
vol = self.volume_api.get(context, volume_id)
|
||||
|
||||
force = snapshot.get('force', False)
|
||||
LOG.audit(_("Create snapshot from volume %s"), volume_id,
|
||||
@@ -627,12 +624,12 @@ class SnapshotController(wsgi.Controller):
|
||||
|
||||
if strutils.bool_from_string(force):
|
||||
new_snapshot = self.volume_api.create_snapshot_force(context,
|
||||
vol,
|
||||
volume_id,
|
||||
snapshot.get('display_name'),
|
||||
snapshot.get('display_description'))
|
||||
else:
|
||||
new_snapshot = self.volume_api.create_snapshot(context,
|
||||
vol,
|
||||
volume_id,
|
||||
snapshot.get('display_name'),
|
||||
snapshot.get('display_description'))
|
||||
|
||||
|
||||
+6
-7
@@ -1202,18 +1202,17 @@ class API(base.Base):
|
||||
# cleanup volumes
|
||||
for bdm in bdms:
|
||||
if bdm['volume_id']:
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
# NOTE(vish): We don't have access to correct volume
|
||||
# connector info, so just pass a fake
|
||||
# connector. This can be improved when we
|
||||
# expose get_volume_connector to rpc.
|
||||
connector = {'ip': '127.0.0.1', 'initiator': 'iqn.fake'}
|
||||
self.volume_api.terminate_connection(context,
|
||||
volume,
|
||||
bdm['volume_id'],
|
||||
connector)
|
||||
self.volume_api.detach(elevated, volume)
|
||||
self.volume_api.detach(elevated, bdm['volume_id'])
|
||||
if bdm['delete_on_termination']:
|
||||
self.volume_api.delete(context, volume)
|
||||
self.volume_api.delete(context, bdm['volume_id'])
|
||||
self.db.block_device_mapping_destroy(context, bdm['id'])
|
||||
instance = self._instance_update(context,
|
||||
instance_uuid,
|
||||
@@ -1633,7 +1632,7 @@ class API(base.Base):
|
||||
# short time, it doesn't matter for now.
|
||||
name = _('snapshot for %s') % image_meta['name']
|
||||
snapshot = self.volume_api.create_snapshot_force(
|
||||
context, volume, name, volume['display_description'])
|
||||
context, volume['id'], name, volume['display_description'])
|
||||
bdm['snapshot_id'] = snapshot['id']
|
||||
bdm['volume_id'] = None
|
||||
|
||||
@@ -2334,7 +2333,7 @@ class API(base.Base):
|
||||
try:
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
self.volume_api.check_attach(context, volume, instance=instance)
|
||||
self.volume_api.reserve_volume(context, volume)
|
||||
self.volume_api.reserve_volume(context, volume_id)
|
||||
self.compute_rpcapi.attach_volume(context, instance=instance,
|
||||
volume_id=volume_id, mountpoint=device)
|
||||
except Exception:
|
||||
@@ -2349,7 +2348,7 @@ class API(base.Base):
|
||||
it easier for cells version to override.
|
||||
"""
|
||||
self.volume_api.check_detach(context, volume)
|
||||
self.volume_api.begin_detaching(context, volume)
|
||||
self.volume_api.begin_detaching(context, volume['id'])
|
||||
self.compute_rpcapi.detach_volume(context, instance=instance,
|
||||
volume_id=volume['id'])
|
||||
|
||||
|
||||
+21
-30
@@ -793,7 +793,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
if bdm['volume_id'] is not None:
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
self.volume_api.check_attach(context, volume,
|
||||
instance=instance)
|
||||
instance=instance)
|
||||
cinfo = self._attach_volume_boot(context,
|
||||
instance,
|
||||
volume,
|
||||
@@ -1352,12 +1352,11 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
try:
|
||||
# NOTE(vish): actual driver detach done in driver.destroy, so
|
||||
# just tell nova-volume that we are done with it.
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
self.volume_api.terminate_connection(context,
|
||||
volume,
|
||||
bdm['volume_id'],
|
||||
connector)
|
||||
self.volume_api.detach(context, volume)
|
||||
self.volume_api.detach(context, bdm['volume_id'])
|
||||
except exception.DiskNotFound as exc:
|
||||
LOG.warn(_('Ignoring DiskNotFound: %s') % exc,
|
||||
instance=instance)
|
||||
@@ -1372,8 +1371,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
LOG.debug(_("terminating bdm %s") % bdm,
|
||||
instance_uuid=instance_uuid)
|
||||
if bdm['volume_id'] and bdm['delete_on_termination']:
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
self.volume_api.delete(context, volume)
|
||||
self.volume_api.delete(context, bdm['volume_id'])
|
||||
# NOTE(vish): bdms will be deleted on instance destroy
|
||||
|
||||
@hooks.add_hook("delete_instance")
|
||||
@@ -1688,8 +1686,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
# NOTE(sirp): this detach is necessary b/c we will reattach the
|
||||
# volumes in _prep_block_devices below.
|
||||
for bdm in self._get_volume_bdms(bdms):
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
self.volume_api.detach(context, volume)
|
||||
self.volume_api.detach(context, bdm['volume_id'])
|
||||
|
||||
if not recreate:
|
||||
block_device_info = self._get_volume_block_device_info(
|
||||
@@ -1762,7 +1759,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
LOG.info(_("Detaching from volume api: %s") % volume_id)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
self.volume_api.check_detach(context, volume)
|
||||
self.volume_api.begin_detaching(context, volume)
|
||||
self.volume_api.begin_detaching(context, volume_id)
|
||||
|
||||
# Manager-detach
|
||||
self.detach_volume(context, volume_id, instance)
|
||||
@@ -2245,9 +2242,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
|
||||
for bdm in bdms:
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
cinfo = self.volume_api.initialize_connection(
|
||||
context, volume, connector)
|
||||
context, bdm['volume_id'], connector)
|
||||
|
||||
self.conductor_api.block_device_mapping_update(
|
||||
context, bdm['id'],
|
||||
@@ -2509,9 +2505,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
if bdms:
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
for bdm in bdms:
|
||||
volume = self.volume_api.get(context, bdm['volume_id'])
|
||||
self.volume_api.terminate_connection(context, volume,
|
||||
connector)
|
||||
self.volume_api.terminate_connection(context, bdm['volume_id'],
|
||||
connector)
|
||||
|
||||
def _finish_resize(self, context, instance, migration, disk_info,
|
||||
image):
|
||||
@@ -2916,9 +2911,9 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
locals(), context=context, instance=instance)
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
connection_info = self.volume_api.initialize_connection(context,
|
||||
volume,
|
||||
volume_id,
|
||||
connector)
|
||||
self.volume_api.attach(context, volume, instance_uuid, mountpoint)
|
||||
self.volume_api.attach(context, volume_id, instance_uuid, mountpoint)
|
||||
return connection_info
|
||||
|
||||
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
|
||||
@@ -2961,14 +2956,13 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
context, instance, mountpoint)
|
||||
|
||||
def _attach_volume(self, context, volume_id, mountpoint, instance):
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
context = context.elevated()
|
||||
LOG.audit(_('Attaching volume %(volume_id)s to %(mountpoint)s'),
|
||||
locals(), context=context, instance=instance)
|
||||
try:
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
connection_info = self.volume_api.initialize_connection(context,
|
||||
volume,
|
||||
volume_id,
|
||||
connector)
|
||||
except Exception: # pylint: disable=W0702
|
||||
with excutils.save_and_reraise_exception():
|
||||
@@ -2976,7 +2970,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
"while attaching at %(mountpoint)s")
|
||||
LOG.exception(msg % locals(), context=context,
|
||||
instance=instance)
|
||||
self.volume_api.unreserve_volume(context, volume)
|
||||
self.volume_api.unreserve_volume(context, volume_id)
|
||||
|
||||
if 'serial' not in connection_info:
|
||||
connection_info['serial'] = volume_id
|
||||
@@ -2992,11 +2986,11 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
LOG.exception(msg % locals(), context=context,
|
||||
instance=instance)
|
||||
self.volume_api.terminate_connection(context,
|
||||
volume,
|
||||
volume_id,
|
||||
connector)
|
||||
|
||||
self.volume_api.attach(context,
|
||||
volume,
|
||||
volume_id,
|
||||
instance['uuid'],
|
||||
mountpoint)
|
||||
values = {
|
||||
@@ -3037,8 +3031,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
msg = _("Failed to detach volume %(volume_id)s from %(mp)s")
|
||||
LOG.exception(msg % locals(), context=context,
|
||||
instance=instance)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
self.volume_api.roll_detaching(context, volume)
|
||||
self.volume_api.roll_detaching(context, volume_id)
|
||||
|
||||
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
|
||||
@reverts_task_state
|
||||
@@ -3067,10 +3060,9 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
update_totals=True)
|
||||
|
||||
self._detach_volume(context, instance, bdm)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
self.volume_api.terminate_connection(context, volume, connector)
|
||||
self.volume_api.detach(context.elevated(), volume)
|
||||
self.volume_api.terminate_connection(context, volume_id, connector)
|
||||
self.volume_api.detach(context.elevated(), volume_id)
|
||||
self.conductor_api.block_device_mapping_destroy_by_instance_and_volume(
|
||||
context, instance, volume_id)
|
||||
|
||||
@@ -3083,9 +3075,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
try:
|
||||
bdm = self._get_instance_volume_bdm(context, instance, volume_id)
|
||||
self._detach_volume(context, instance, bdm)
|
||||
volume = self.volume_api.get(context, volume_id)
|
||||
connector = self.driver.get_volume_connector(instance)
|
||||
self.volume_api.terminate_connection(context, volume, connector)
|
||||
self.volume_api.terminate_connection(context, volume_id, connector)
|
||||
except exception.NotFound:
|
||||
pass
|
||||
|
||||
@@ -3314,8 +3305,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
||||
|
||||
# remove the volume connection without detaching from hypervisor
|
||||
# because the instance is not running anymore on the current host
|
||||
volume = self.volume_api.get(ctxt, bdm['volume_id'])
|
||||
self.volume_api.terminate_connection(ctxt, volume, connector)
|
||||
self.volume_api.terminate_connection(ctxt, bdm['volume_id'],
|
||||
connector)
|
||||
|
||||
# Releasing vlan.
|
||||
# (not necessary in current implementation?)
|
||||
|
||||
@@ -401,12 +401,12 @@ class CinderCloudTestCase(test.TestCase):
|
||||
**kwargs)
|
||||
if 'snapshot_id' in values:
|
||||
self.volume_api.create_snapshot(self.context,
|
||||
vol,
|
||||
vol['id'],
|
||||
'snapshot-bdm',
|
||||
'fake snap for bdm tests',
|
||||
values['snapshot_id'])
|
||||
|
||||
self.volume_api.attach(self.context, vol,
|
||||
self.volume_api.attach(self.context, vol['id'],
|
||||
instance_uuid, bdm['device_name'])
|
||||
volumes.append(vol)
|
||||
return volumes
|
||||
@@ -471,7 +471,7 @@ class CinderCloudTestCase(test.TestCase):
|
||||
|
||||
def _tearDownBlockDeviceMapping(self, inst1, inst2, volumes):
|
||||
for vol in volumes:
|
||||
self.volume_api.delete(self.context, vol)
|
||||
self.volume_api.delete(self.context, vol['id'])
|
||||
for uuid in (inst1['uuid'], inst2['uuid']):
|
||||
for bdm in db.block_device_mapping_get_all_by_instance(
|
||||
self.context, uuid):
|
||||
@@ -776,10 +776,10 @@ class CinderCloudTestCase(test.TestCase):
|
||||
self.assertTrue(str(vol['id']) == str(vol1_uuid) or
|
||||
str(vol['id']) == str(vol2_uuid))
|
||||
if str(vol['id']) == str(vol1_uuid):
|
||||
self.volume_api.attach(self.context, vol,
|
||||
self.volume_api.attach(self.context, vol['id'],
|
||||
instance_uuid, '/dev/sdb')
|
||||
elif str(vol['id']) == str(vol2_uuid):
|
||||
self.volume_api.attach(self.context, vol,
|
||||
self.volume_api.attach(self.context, vol['id'],
|
||||
instance_uuid, '/dev/sdc')
|
||||
|
||||
vol = self.volume_api.get(self.context, vol1_uuid)
|
||||
|
||||
@@ -217,7 +217,7 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(resp.status_int, 200)
|
||||
|
||||
def test_volume_show_no_volume(self):
|
||||
self.stubs.Set(cinder.API, "get", fakes.stub_volume_get_notfound)
|
||||
self.stubs.Set(cinder.API, "get", fakes.stub_volume_notfound)
|
||||
|
||||
req = webob.Request.blank('/v2/fake/os-volumes/456')
|
||||
resp = req.get_response(self.app)
|
||||
@@ -230,7 +230,7 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
|
||||
def test_volume_delete_no_volume(self):
|
||||
self.stubs.Set(cinder.API, "get", fakes.stub_volume_get_notfound)
|
||||
self.stubs.Set(cinder.API, "delete", fakes.stub_volume_notfound)
|
||||
|
||||
req = webob.Request.blank('/v2/fake/os-volumes/456')
|
||||
req.method = 'DELETE'
|
||||
|
||||
@@ -838,7 +838,7 @@ class ServerActionsControllerTest(test.TestCase):
|
||||
self.mox.StubOutWithMock(self.controller.compute_api, 'volume_api')
|
||||
volume_api = self.controller.compute_api.volume_api
|
||||
volume_api.get(mox.IgnoreArg(), volume['id']).AndReturn(volume)
|
||||
volume_api.create_snapshot_force(mox.IgnoreArg(), volume,
|
||||
volume_api.create_snapshot_force(mox.IgnoreArg(), volume['id'],
|
||||
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(snapshot)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
@@ -581,7 +581,7 @@ def stub_volume_get(self, context, volume_id):
|
||||
return stub_volume(volume_id)
|
||||
|
||||
|
||||
def stub_volume_get_notfound(self, context, volume_id):
|
||||
def stub_volume_notfound(self, context, volume_id):
|
||||
raise exc.VolumeNotFound(volume_id=volume_id)
|
||||
|
||||
|
||||
@@ -611,13 +611,13 @@ def stub_snapshot(id, **kwargs):
|
||||
return snapshot
|
||||
|
||||
|
||||
def stub_snapshot_create(self, context, volume, name, description):
|
||||
return stub_snapshot(100, volume_id=volume['id'], display_name=name,
|
||||
def stub_snapshot_create(self, context, volume_id, name, description):
|
||||
return stub_snapshot(100, volume_id=volume_id, display_name=name,
|
||||
display_description=description)
|
||||
|
||||
|
||||
def stub_snapshot_delete(self, context, snapshot):
|
||||
if snapshot['id'] == '-1':
|
||||
def stub_snapshot_delete(self, context, snapshot_id):
|
||||
if snapshot_id == '-1':
|
||||
raise exc.NotFound
|
||||
|
||||
|
||||
|
||||
@@ -7268,11 +7268,6 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
def fake_roll_detaching(*args, **kwargs):
|
||||
called['fake_roll_detaching'] = True
|
||||
|
||||
def fake_volume_get(self, context, volume_id):
|
||||
called['fake_volume_get'] = True
|
||||
return {'id': volume_id, 'attach_status': 'in-use'}
|
||||
|
||||
self.stubs.Set(cinder.API, 'get', fake_volume_get)
|
||||
self.stubs.Set(cinder.API, 'roll_detaching', fake_roll_detaching)
|
||||
self.stubs.Set(self.compute, "_get_instance_volume_bdm",
|
||||
fake_get_instance_volume_bdm)
|
||||
@@ -7284,7 +7279,6 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
self.assertRaises(AttributeError, self.compute.detach_volume,
|
||||
self.context, 1, instance)
|
||||
self.assertTrue(called.get('fake_libvirt_driver_instance_exists'))
|
||||
self.assertTrue(called.get('fake_volume_get'))
|
||||
self.assertTrue(called.get('fake_roll_detaching'))
|
||||
|
||||
def test_terminate_with_volumes(self):
|
||||
@@ -7300,18 +7294,18 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
}
|
||||
db.block_device_mapping_create(admin, values)
|
||||
|
||||
def fake_volume_get(self, context, volume):
|
||||
def fake_volume_get(self, context, volume_id):
|
||||
return {'id': volume_id}
|
||||
self.stubs.Set(cinder.API, "get", fake_volume_get)
|
||||
|
||||
# Stub out and record whether it gets detached
|
||||
result = {"detached": False}
|
||||
|
||||
def fake_detach(self, context, volume):
|
||||
result["detached"] = volume["id"] == volume_id
|
||||
def fake_detach(self, context, volume_id_param):
|
||||
result["detached"] = volume_id_param == volume_id
|
||||
self.stubs.Set(cinder.API, "detach", fake_detach)
|
||||
|
||||
def fake_terminate_connection(self, context, volume, connector):
|
||||
def fake_terminate_connection(self, context, volume_id, connector):
|
||||
return {}
|
||||
self.stubs.Set(cinder.API, "terminate_connection",
|
||||
fake_terminate_connection)
|
||||
|
||||
+29
-25
@@ -178,9 +178,10 @@ class API(object):
|
||||
def get_all(self, context):
|
||||
return self.volume_list
|
||||
|
||||
def delete(self, context, volume):
|
||||
LOG.info('deleting volume %s', volume['id'])
|
||||
self.volume_list = [v for v in self.volume_list if v != volume]
|
||||
def delete(self, context, volume_id):
|
||||
LOG.info('deleting volume %s', volume_id)
|
||||
self.volume_list = [v for v in self.volume_list
|
||||
if v['id'] != volume_id]
|
||||
|
||||
def check_attach(self, context, volume, instance=None):
|
||||
if volume['status'] != 'available':
|
||||
@@ -200,9 +201,9 @@ class API(object):
|
||||
msg = _("already detached")
|
||||
raise exception.InvalidVolume(reason=msg)
|
||||
|
||||
def attach(self, context, volume, instance_uuid, mountpoint):
|
||||
LOG.info('attaching volume %s', volume['id'])
|
||||
volume = self.get(context, volume['id'])
|
||||
def attach(self, context, volume_id, instance_uuid, mountpoint):
|
||||
LOG.info('attaching volume %s', volume_id)
|
||||
volume = self.get(context, volume_id)
|
||||
volume['status'] = 'in-use'
|
||||
volume['mountpoint'] = mountpoint
|
||||
volume['attach_status'] = 'attached'
|
||||
@@ -216,9 +217,9 @@ class API(object):
|
||||
del self.volume_list[:]
|
||||
del self.snapshot_list[:]
|
||||
|
||||
def detach(self, context, volume):
|
||||
LOG.info('detaching volume %s', volume['id'])
|
||||
volume = self.get(context, volume['id'])
|
||||
def detach(self, context, volume_id):
|
||||
LOG.info('detaching volume %s', volume_id)
|
||||
volume = self.get(context, volume_id)
|
||||
volume['status'] = 'available'
|
||||
volume['mountpoint'] = None
|
||||
volume['attach_status'] = 'detached'
|
||||
@@ -238,7 +239,8 @@ class API(object):
|
||||
def get_all_snapshots(self, context):
|
||||
return self.snapshot_list
|
||||
|
||||
def create_snapshot(self, context, volume, name, description, id=None):
|
||||
def create_snapshot(self, context, volume_id, name, description, id=None):
|
||||
volume = self.get(context, volume_id)
|
||||
snapshot = fake_snapshot(volume['id'], volume['size'],
|
||||
name, description, id)
|
||||
self.snapshot_list.append(snapshot.snap)
|
||||
@@ -256,32 +258,34 @@ class API(object):
|
||||
self.snapshot_list.append(snapshot.snap)
|
||||
return snapshot.snap
|
||||
|
||||
def create_snapshot_force(self, context, volume,
|
||||
def create_snapshot_force(self, context, volume_id,
|
||||
name, description, id=None):
|
||||
volume = self.get(context, volume_id)
|
||||
snapshot = fake_snapshot(volume['id'], volume['size'],
|
||||
name, description, id)
|
||||
self.snapshot_list.append(snapshot.snap)
|
||||
return snapshot.snap
|
||||
|
||||
def delete_snapshot(self, context, snapshot):
|
||||
self.snapshot_list = [s for s in self.snapshot_list if s != snapshot]
|
||||
def delete_snapshot(self, context, snapshot_id):
|
||||
self.snapshot_list = [s for s in self.snapshot_list
|
||||
if s['id'] != snapshot_id]
|
||||
|
||||
def reserve_volume(self, context, volume):
|
||||
LOG.info('reserving volume %s', volume['id'])
|
||||
volume = self.get(context, volume['id'])
|
||||
def reserve_volume(self, context, volume_id):
|
||||
LOG.info('reserving volume %s', volume_id)
|
||||
volume = self.get(context, volume_id)
|
||||
volume['status'] = 'attaching'
|
||||
|
||||
def unreserve_volume(self, context, volume):
|
||||
LOG.info('unreserving volume %s', volume['id'])
|
||||
volume = self.get(context, volume['id'])
|
||||
def unreserve_volume(self, context, volume_id):
|
||||
LOG.info('unreserving volume %s', volume_id)
|
||||
volume = self.get(context, volume_id)
|
||||
volume['status'] = 'available'
|
||||
|
||||
def begin_detaching(self, context, volume):
|
||||
LOG.info('beging detaching volume %s', volume['id'])
|
||||
volume = self.get(context, volume['id'])
|
||||
def begin_detaching(self, context, volume_id):
|
||||
LOG.info('beging detaching volume %s', volume_id)
|
||||
volume = self.get(context, volume_id)
|
||||
volume['status'] = 'detaching'
|
||||
|
||||
def roll_detaching(self, context, volume):
|
||||
LOG.info('roll detaching volume %s', volume['id'])
|
||||
volume = self.get(context, volume['id'])
|
||||
def roll_detaching(self, context, volume_id):
|
||||
LOG.info('roll detaching volume %s', volume_id)
|
||||
volume = self.get(context, volume_id)
|
||||
volume['status'] = 'in-use'
|
||||
|
||||
@@ -3654,7 +3654,6 @@ class SnapshotsSampleJsonTests(ApiSampleTestBase):
|
||||
def _create_snapshot(self):
|
||||
self.stubs.Set(cinder.API, "create_snapshot",
|
||||
fakes.stub_snapshot_create)
|
||||
self.stubs.Set(cinder.API, "get", fakes.stub_volume_get)
|
||||
|
||||
response = self._do_post("os-snapshots",
|
||||
"snapshot-create-req",
|
||||
|
||||
@@ -80,10 +80,10 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.api.create(self.ctx, 1, '', '')
|
||||
|
||||
def test_create_failed(self):
|
||||
cinder.cinderclient(self.ctx).AndRaise(cinder_exception.NotFound(''))
|
||||
cinder.cinderclient(self.ctx).AndRaise(cinder_exception.BadRequest(''))
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.assertRaises(exception.VolumeNotFound,
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.api.create, self.ctx, 1, '', '')
|
||||
|
||||
def test_get_all(self):
|
||||
@@ -142,7 +142,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.reserve('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.reserve_volume(self.ctx, {'id': 'id1'})
|
||||
self.api.reserve_volume(self.ctx, 'id1')
|
||||
|
||||
def test_unreserve_volume(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -151,7 +151,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.unreserve('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.unreserve_volume(self.ctx, {'id': 'id1'})
|
||||
self.api.unreserve_volume(self.ctx, 'id1')
|
||||
|
||||
def test_begin_detaching(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -160,7 +160,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.begin_detaching('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.begin_detaching(self.ctx, {'id': 'id1'})
|
||||
self.api.begin_detaching(self.ctx, 'id1')
|
||||
|
||||
def test_roll_detaching(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -169,7 +169,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.roll_detaching('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.roll_detaching(self.ctx, {'id': 'id1'})
|
||||
self.api.roll_detaching(self.ctx, 'id1')
|
||||
|
||||
def test_attach(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -178,7 +178,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.attach('id1', 'uuid', 'point')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.attach(self.ctx, {'id': 'id1'}, 'uuid', 'point')
|
||||
self.api.attach(self.ctx, 'id1', 'uuid', 'point')
|
||||
|
||||
def test_detach(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -187,7 +187,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.detach('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.detach(self.ctx, {'id': 'id1'})
|
||||
self.api.detach(self.ctx, 'id1')
|
||||
|
||||
def test_initialize_connection(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -196,7 +196,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.initialize_connection('id1', 'connector')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.initialize_connection(self.ctx, {'id': 'id1'}, 'connector')
|
||||
self.api.initialize_connection(self.ctx, 'id1', 'connector')
|
||||
|
||||
def test_terminate_connection(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -205,7 +205,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.terminate_connection('id1', 'connector')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.terminate_connection(self.ctx, {'id': 'id1'}, 'connector')
|
||||
self.api.terminate_connection(self.ctx, 'id1', 'connector')
|
||||
|
||||
def test_delete(self):
|
||||
cinder.cinderclient(self.ctx).AndReturn(self.cinderclient)
|
||||
@@ -214,7 +214,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volumes.delete('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.delete(self.ctx, {'id': 'id1'})
|
||||
self.api.delete(self.ctx, 'id1')
|
||||
|
||||
def test_update(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
@@ -270,7 +270,7 @@ class CinderApiTestCase(test.TestCase):
|
||||
self.cinderclient.volume_snapshots.delete('id1')
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.api.delete_snapshot(self.ctx, {'id': 'id1'})
|
||||
self.api.delete_snapshot(self.ctx, 'id1')
|
||||
|
||||
def test_get_volume_metadata(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
|
||||
+89
-69
@@ -168,41 +168,46 @@ def _untranslate_snapshot_summary_view(context, snapshot):
|
||||
return d
|
||||
|
||||
|
||||
def translate_volume_exception(method):
|
||||
"""Transforms the exception for the volume but keeps its traceback intact.
|
||||
"""
|
||||
def wrapper(self, ctx, volume_id, *args, **kwargs):
|
||||
try:
|
||||
res = method(self, ctx, volume_id, *args, **kwargs)
|
||||
except cinder_exception.ClientException:
|
||||
exc_type, exc_value, exc_trace = sys.exc_info()
|
||||
if isinstance(exc_value, cinder_exception.NotFound):
|
||||
exc_value = exception.VolumeNotFound(volume_id=volume_id)
|
||||
elif isinstance(exc_value, cinder_exception.BadRequest):
|
||||
exc_value = exception.InvalidInput(reason=exc_value.message)
|
||||
raise exc_value, None, exc_trace
|
||||
return res
|
||||
return wrapper
|
||||
|
||||
|
||||
def translate_snapshot_exception(method):
|
||||
"""Transforms the exception for the snapshot but keeps its traceback
|
||||
intact.
|
||||
"""
|
||||
def wrapper(self, ctx, snapshot_id, *args, **kwargs):
|
||||
try:
|
||||
res = method(self, ctx, snapshot_id, *args, **kwargs)
|
||||
except cinder_exception.ClientException:
|
||||
exc_type, exc_value, exc_trace = sys.exc_info()
|
||||
if isinstance(exc_value, cinder_exception.NotFound):
|
||||
exc_value = exception.SnapshotNotFound(snapshot_id=snapshot_id)
|
||||
raise exc_value, None, exc_trace
|
||||
return res
|
||||
return wrapper
|
||||
|
||||
|
||||
class API(base.Base):
|
||||
"""API for interacting with the volume manager."""
|
||||
|
||||
def _reraise_translated_volume_exception(self, volume_id=None):
|
||||
"""Transform the exception for the volume but keep its traceback
|
||||
intact."""
|
||||
exc_type, exc_value, exc_trace = sys.exc_info()
|
||||
new_exc = self._translate_volume_exception(volume_id, exc_value)
|
||||
raise new_exc, None, exc_trace
|
||||
|
||||
def _translate_volume_exception(self, volume_id, exc_value):
|
||||
if isinstance(exc_value, cinder_exception.NotFound):
|
||||
return exception.VolumeNotFound(volume_id=volume_id)
|
||||
elif isinstance(exc_value, cinder_exception.BadRequest):
|
||||
return exception.InvalidInput(reason=exc_value.message)
|
||||
return exc_value
|
||||
|
||||
def _reraise_translated_snapshot_exception(self, snapshot_id=None):
|
||||
"""Transform the exception for the snapshot but keep its traceback
|
||||
intact."""
|
||||
exc_type, exc_value, exc_trace = sys.exc_info()
|
||||
new_exc = self._translate_snapshot_exception(snapshot_id, exc_value)
|
||||
raise new_exc, None, exc_trace
|
||||
|
||||
def _translate_snapshot_exception(self, snapshot_id, exc_value):
|
||||
if isinstance(exc_value, cinder_exception.NotFound):
|
||||
return exception.SnapshotNotFound(snapshot_id=snapshot_id)
|
||||
return exc_value
|
||||
|
||||
@translate_volume_exception
|
||||
def get(self, context, volume_id):
|
||||
try:
|
||||
item = cinderclient(context).volumes.get(volume_id)
|
||||
return _untranslate_volume_summary_view(context, item)
|
||||
except Exception:
|
||||
self._reraise_translated_volume_exception(volume_id)
|
||||
item = cinderclient(context).volumes.get(volume_id)
|
||||
return _untranslate_volume_summary_view(context, item)
|
||||
|
||||
def get_all(self, context, search_opts={}):
|
||||
items = cinderclient(context).volumes.list(detailed=True)
|
||||
@@ -238,33 +243,40 @@ class API(base.Base):
|
||||
msg = _("already detached")
|
||||
raise exception.InvalidVolume(reason=msg)
|
||||
|
||||
def reserve_volume(self, context, volume):
|
||||
cinderclient(context).volumes.reserve(volume['id'])
|
||||
@translate_volume_exception
|
||||
def reserve_volume(self, context, volume_id):
|
||||
cinderclient(context).volumes.reserve(volume_id)
|
||||
|
||||
def unreserve_volume(self, context, volume):
|
||||
cinderclient(context).volumes.unreserve(volume['id'])
|
||||
@translate_volume_exception
|
||||
def unreserve_volume(self, context, volume_id):
|
||||
cinderclient(context).volumes.unreserve(volume_id)
|
||||
|
||||
def begin_detaching(self, context, volume):
|
||||
cinderclient(context).volumes.begin_detaching(volume['id'])
|
||||
@translate_volume_exception
|
||||
def begin_detaching(self, context, volume_id):
|
||||
cinderclient(context).volumes.begin_detaching(volume_id)
|
||||
|
||||
def roll_detaching(self, context, volume):
|
||||
cinderclient(context).volumes.roll_detaching(volume['id'])
|
||||
@translate_volume_exception
|
||||
def roll_detaching(self, context, volume_id):
|
||||
cinderclient(context).volumes.roll_detaching(volume_id)
|
||||
|
||||
def attach(self, context, volume, instance_uuid, mountpoint):
|
||||
cinderclient(context).volumes.attach(volume['id'],
|
||||
instance_uuid,
|
||||
@translate_volume_exception
|
||||
def attach(self, context, volume_id, instance_uuid, mountpoint):
|
||||
cinderclient(context).volumes.attach(volume_id, instance_uuid,
|
||||
mountpoint)
|
||||
|
||||
def detach(self, context, volume):
|
||||
cinderclient(context).volumes.detach(volume['id'])
|
||||
@translate_volume_exception
|
||||
def detach(self, context, volume_id):
|
||||
cinderclient(context).volumes.detach(volume_id)
|
||||
|
||||
def initialize_connection(self, context, volume, connector):
|
||||
return cinderclient(context).\
|
||||
volumes.initialize_connection(volume['id'], connector)
|
||||
@translate_volume_exception
|
||||
def initialize_connection(self, context, volume_id, connector):
|
||||
return cinderclient(context).volumes.initialize_connection(volume_id,
|
||||
connector)
|
||||
|
||||
def terminate_connection(self, context, volume, connector):
|
||||
return cinderclient(context).\
|
||||
volumes.terminate_connection(volume['id'], connector)
|
||||
@translate_volume_exception
|
||||
def terminate_connection(self, context, volume_id, connector):
|
||||
return cinderclient(context).volumes.terminate_connection(volume_id,
|
||||
connector)
|
||||
|
||||
def create(self, context, size, name, description, snapshot=None,
|
||||
image_id=None, volume_type=None, metadata=None,
|
||||
@@ -288,20 +300,20 @@ class API(base.Base):
|
||||
try:
|
||||
item = cinderclient(context).volumes.create(size, **kwargs)
|
||||
return _untranslate_volume_summary_view(context, item)
|
||||
except Exception:
|
||||
self._reraise_translated_volume_exception()
|
||||
except cinder_exception.BadRequest as e:
|
||||
raise exception.InvalidInput(reason=e.message)
|
||||
|
||||
def delete(self, context, volume):
|
||||
cinderclient(context).volumes.delete(volume['id'])
|
||||
@translate_volume_exception
|
||||
def delete(self, context, volume_id):
|
||||
cinderclient(context).volumes.delete(volume_id)
|
||||
|
||||
def update(self, context, volume, fields):
|
||||
@translate_volume_exception
|
||||
def update(self, context, volume_id, fields):
|
||||
raise NotImplementedError()
|
||||
|
||||
@translate_snapshot_exception
|
||||
def get_snapshot(self, context, snapshot_id):
|
||||
try:
|
||||
item = cinderclient(context).volume_snapshots.get(snapshot_id)
|
||||
except Exception:
|
||||
self._reraise_translated_snapshot_exception(snapshot_id)
|
||||
item = cinderclient(context).volume_snapshots.get(snapshot_id)
|
||||
return _untranslate_snapshot_summary_view(context, item)
|
||||
|
||||
def get_all_snapshots(self, context):
|
||||
@@ -313,32 +325,40 @@ class API(base.Base):
|
||||
|
||||
return rvals
|
||||
|
||||
def create_snapshot(self, context, volume, name, description):
|
||||
item = cinderclient(context).volume_snapshots.create(volume['id'],
|
||||
@translate_volume_exception
|
||||
def create_snapshot(self, context, volume_id, name, description):
|
||||
item = cinderclient(context).volume_snapshots.create(volume_id,
|
||||
False,
|
||||
name,
|
||||
description)
|
||||
return _untranslate_snapshot_summary_view(context, item)
|
||||
|
||||
def create_snapshot_force(self, context, volume, name, description):
|
||||
item = cinderclient(context).volume_snapshots.create(volume['id'],
|
||||
@translate_volume_exception
|
||||
def create_snapshot_force(self, context, volume_id, name, description):
|
||||
item = cinderclient(context).volume_snapshots.create(volume_id,
|
||||
True,
|
||||
name,
|
||||
description)
|
||||
|
||||
return _untranslate_snapshot_summary_view(context, item)
|
||||
|
||||
def delete_snapshot(self, context, snapshot):
|
||||
cinderclient(context).volume_snapshots.delete(snapshot['id'])
|
||||
@translate_snapshot_exception
|
||||
def delete_snapshot(self, context, snapshot_id):
|
||||
cinderclient(context).volume_snapshots.delete(snapshot_id)
|
||||
|
||||
def get_volume_metadata(self, context, volume):
|
||||
@translate_volume_exception
|
||||
def get_volume_metadata(self, context, volume_id):
|
||||
raise NotImplementedError()
|
||||
|
||||
def delete_volume_metadata(self, context, volume, key):
|
||||
@translate_volume_exception
|
||||
def delete_volume_metadata(self, context, volume_id, key):
|
||||
raise NotImplementedError()
|
||||
|
||||
def update_volume_metadata(self, context, volume, metadata, delete=False):
|
||||
@translate_volume_exception
|
||||
def update_volume_metadata(self, context, volume_id,
|
||||
metadata, delete=False):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_volume_metadata_value(self, volume, key):
|
||||
@translate_volume_exception
|
||||
def get_volume_metadata_value(self, volume_id, key):
|
||||
raise NotImplementedError()
|
||||
|
||||
Reference in New Issue
Block a user