Merge "Add create & attach times to SolidFire attributes."

This commit is contained in:
Jenkins 2013-07-23 18:24:44 +00:00 committed by Gerrit Code Review
commit 8d1156383a
6 changed files with 110 additions and 24 deletions

@ -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."""