Merge "Add create & attach times to SolidFire attributes."
This commit is contained in:
commit
8d1156383a
cinder
@ -1078,6 +1078,7 @@ def volume_detached(context, volume_id):
|
||||
volume_ref['attach_status'] = 'detached'
|
||||
volume_ref['instance_uuid'] = None
|
||||
volume_ref['attached_host'] = None
|
||||
volume_ref['attach_time'] = None
|
||||
volume_ref.save(session=session)
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ import mox
|
||||
|
||||
from cinder import exception
|
||||
from cinder.openstack.common import log as logging
|
||||
from cinder.openstack.common import timeutils
|
||||
from cinder import test
|
||||
from cinder.volume import configuration as conf
|
||||
from cinder.volume.drivers.solidfire import SolidFireDriver
|
||||
@ -143,7 +144,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'volume_type_id': 'fast'}
|
||||
'volume_type_id': 'fast',
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
model_update = sfv.create_volume(testvol)
|
||||
@ -156,7 +158,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'volume_type_id': None}
|
||||
'volume_type_id': None,
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
model_update = sfv.create_volume(testvol)
|
||||
self.assertNotEqual(model_update, None)
|
||||
@ -169,7 +173,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'volume_type_id': None}
|
||||
'volume_type_id': None,
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
self.configuration.sf_emulate_512 = False
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
model_update = sfv.create_volume(testvol)
|
||||
@ -189,7 +195,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
'74-4cb7-bd55-14aed659a0cc.4060 0',
|
||||
'provider_auth': 'CHAP stack-1-a60e2611875f40199931f2'
|
||||
'c76370d66b 2FE0CQ8J196R',
|
||||
'provider_geometry': '4096 4096'
|
||||
'provider_geometry': '4096 4096',
|
||||
'created_at': timeutils.utcnow(),
|
||||
}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
@ -208,7 +215,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'metadata': [preset_qos],
|
||||
'volume_type_id': None}
|
||||
'volume_type_id': None,
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
model_update = sfv.create_volume(testvol)
|
||||
@ -224,7 +232,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'created_at': timeutils.utcnow()}
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
try:
|
||||
sfv.create_volume(testvol)
|
||||
@ -266,7 +275,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'test_volume',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
sfv.delete_volume(testvol)
|
||||
|
||||
@ -276,7 +287,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'no-name',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
try:
|
||||
sfv.delete_volume(testvol)
|
||||
@ -294,7 +307,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'no-name',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
self.assertRaises(exception.SfAccountNotFound,
|
||||
sfv.delete_volume,
|
||||
@ -323,7 +338,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'test_volume',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
sfv.extend_volume(testvol, 2)
|
||||
|
||||
@ -349,7 +366,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'no-name',
|
||||
'size': 1,
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66'}
|
||||
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
self.assertRaises(exception.SfAccountNotFound,
|
||||
sfv.extend_volume,
|
||||
|
@ -167,12 +167,12 @@ class VolumeDriver(object):
|
||||
"""Disallow connection from connector"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def attach_volume(self, context, volume_id, instance_uuid, host_name,
|
||||
def attach_volume(self, context, volume, instance_uuid, host_name,
|
||||
mountpoint):
|
||||
"""Callback for volume attached to instance or host."""
|
||||
pass
|
||||
|
||||
def detach_volume(self, context, volume_id):
|
||||
def detach_volume(self, context, volume):
|
||||
"""Callback for volume detached."""
|
||||
pass
|
||||
|
||||
|
@ -210,7 +210,7 @@ class ScalityDriver(driver.VolumeDriver):
|
||||
"""Disallow connection from connector."""
|
||||
pass
|
||||
|
||||
def detach_volume(self, context, volume_id):
|
||||
def detach_volume(self, context, volume):
|
||||
"""Callback for volume detached."""
|
||||
pass
|
||||
|
||||
|
@ -30,6 +30,7 @@ from oslo.config import cfg
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.openstack.common import log as logging
|
||||
from cinder.openstack.common import timeutils
|
||||
from cinder.volume.drivers.san.san import SanISCSIDriver
|
||||
from cinder.volume import volume_types
|
||||
|
||||
@ -364,9 +365,11 @@ class SolidFireDriver(SanISCSIDriver):
|
||||
# to set any that were provided
|
||||
params = {'volumeID': sf_volume_id}
|
||||
|
||||
create_time = timeutils.strtime(v_ref['created_at'])
|
||||
attributes = {'uuid': v_ref['id'],
|
||||
'is_clone': 'True',
|
||||
'src_uuid': src_uuid}
|
||||
'src_uuid': src_uuid,
|
||||
'created_at': create_time}
|
||||
if qos:
|
||||
params['qos'] = qos
|
||||
for k, v in qos.items():
|
||||
@ -484,8 +487,10 @@ class SolidFireDriver(SanISCSIDriver):
|
||||
if type_id is not None:
|
||||
qos = self._set_qos_by_volume_type(ctxt, type_id)
|
||||
|
||||
create_time = timeutils.strtime(volume['created_at'])
|
||||
attributes = {'uuid': volume['id'],
|
||||
'is_clone': 'False'}
|
||||
'is_clone': 'False',
|
||||
'created_at': create_time}
|
||||
if qos:
|
||||
for k, v in qos.items():
|
||||
attributes[k] = str(v)
|
||||
@ -662,3 +667,55 @@ class SolidFireDriver(SanISCSIDriver):
|
||||
data['thin_provision_percent'] =\
|
||||
results['thinProvisioningPercent']
|
||||
self.cluster_stats = data
|
||||
|
||||
def attach_volume(self, context, volume,
|
||||
instance_uuid, host_name,
|
||||
mountpoint):
|
||||
|
||||
LOG.debug(_("Entering SolidFire attach_volume..."))
|
||||
sfaccount = self._get_sfaccount(volume['project_id'])
|
||||
params = {'accountID': sfaccount['accountID']}
|
||||
|
||||
sf_vol = self._get_sf_volume(volume['id'], params)
|
||||
if sf_vol is None:
|
||||
LOG.error(_("Volume ID %s was not found on "
|
||||
"the SolidFire Cluster!"), volume['id'])
|
||||
raise exception.VolumeNotFound(volume_id=volume['id'])
|
||||
|
||||
attributes = sf_vol['attributes']
|
||||
attributes['attach_time'] = volume.get('attach_time', None)
|
||||
attributes['attached_to'] = instance_uuid
|
||||
params = {
|
||||
'volumeID': sf_vol['volumeID'],
|
||||
'attributes': attributes
|
||||
}
|
||||
|
||||
data = self._issue_api_request('ModifyVolume', params)
|
||||
|
||||
if 'result' not in data:
|
||||
raise exception.SolidFireAPIDataException(data=data)
|
||||
|
||||
def detach_volume(self, context, volume):
|
||||
|
||||
LOG.debug(_("Entering SolidFire attach_volume..."))
|
||||
sfaccount = self._get_sfaccount(volume['project_id'])
|
||||
params = {'accountID': sfaccount['accountID']}
|
||||
|
||||
sf_vol = self._get_sf_volume(volume['id'], params)
|
||||
if sf_vol is None:
|
||||
LOG.error(_("Volume ID %s was not found on "
|
||||
"the SolidFire Cluster!"), volume['id'])
|
||||
raise exception.VolumeNotFound(volume_id=volume['id'])
|
||||
|
||||
attributes = sf_vol['attributes']
|
||||
attributes['attach_time'] = None
|
||||
attributes['attached_to'] = None
|
||||
params = {
|
||||
'volumeID': sf_vol['volumeID'],
|
||||
'attributes': attributes
|
||||
}
|
||||
|
||||
data = self._issue_api_request('ModifyVolume', params)
|
||||
|
||||
if 'result' not in data:
|
||||
raise exception.SolidFireAPIDataException(data=data)
|
||||
|
@ -371,7 +371,7 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||
self.db.volume_update(context,
|
||||
volume_ref['id'],
|
||||
{'status': volume_ref['status'],
|
||||
'launched_at': now})
|
||||
'launched_at': now})
|
||||
LOG.info(_("volume %s: created successfully"), volume_ref['name'])
|
||||
self._reset_stats()
|
||||
|
||||
@ -609,10 +609,16 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||
elif volume['status'] != "available":
|
||||
msg = _("status must be available")
|
||||
raise exception.InvalidVolume(reason=msg)
|
||||
|
||||
# TODO(jdg): attach_time column is currently varchar
|
||||
# we should update this to a date-time object
|
||||
# also consider adding detach_time?
|
||||
now = timeutils.strtime()
|
||||
self.db.volume_update(context, volume_id,
|
||||
{"instance_uuid": instance_uuid,
|
||||
"attached_host": host_name,
|
||||
"status": "attaching"})
|
||||
"status": "attaching",
|
||||
"attach_time": now})
|
||||
|
||||
if instance_uuid and not uuidutils.is_uuid_like(instance_uuid):
|
||||
self.db.volume_update(context,
|
||||
@ -623,9 +629,10 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||
host_name_sanitized = utils.sanitize_hostname(
|
||||
host_name) if host_name else None
|
||||
|
||||
volume = self.db.volume_get(context, volume_id)
|
||||
try:
|
||||
self.driver.attach_volume(context,
|
||||
volume_id,
|
||||
volume,
|
||||
instance_uuid,
|
||||
host_name_sanitized,
|
||||
mountpoint)
|
||||
@ -646,8 +653,10 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||
"""Updates db to show volume is detached"""
|
||||
# TODO(vish): refactor this into a more general "unreserve"
|
||||
# TODO(sleepsonthefloor): Is this 'elevated' appropriate?
|
||||
|
||||
volume = self.db.volume_get(context, volume_id)
|
||||
try:
|
||||
self.driver.detach_volume(context, volume_id)
|
||||
self.driver.detach_volume(context, volume)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.db.volume_update(context,
|
||||
@ -657,10 +666,10 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||
self.db.volume_detached(context.elevated(), volume_id)
|
||||
|
||||
# Check for https://bugs.launchpad.net/cinder/+bug/1065702
|
||||
volume_ref = self.db.volume_get(context, volume_id)
|
||||
if (volume_ref['provider_location'] and
|
||||
volume_ref['name'] not in volume_ref['provider_location']):
|
||||
self.driver.ensure_export(context, volume_ref)
|
||||
volume = self.db.volume_get(context, volume_id)
|
||||
if (volume['provider_location'] and
|
||||
volume['name'] not in volume['provider_location']):
|
||||
self.driver.ensure_export(context, volume)
|
||||
|
||||
def _copy_image_to_volume(self, context, volume, image_service, image_id):
|
||||
"""Downloads Glance image to the specified volume."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user