SF remove deprecated sf_allow_template_caching
The solidfire driver currently has built in template image caching. It is not manageable through the normal OpenStack API's. SolidFires template image caching is the main cause for the exception DuplicateSFVolumeNames when the system is running in an HA A/A configuration. The current implementation has the configuration variable sf_allow_template_caching, the module _create_image_volume, and _verify_image_volume, which will be removed. Cinder has the same functionality which is managed through the OpenStack APIs and will not have the same HA A/A side effect of throwing DuplicateSDuplicateSFVolumeNames exception. Change-Id: I69ce8bda4302bf821739eb7276f2db12b7a259fe
This commit is contained in:
committed by
Jay Rubenstein
parent
99a6fcdcf6
commit
fd495d010c
@@ -314,6 +314,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
}]
|
||||
}
|
||||
}
|
||||
elif method == 'ListSnapshots':
|
||||
raise exception.VolumeNotFound('test clone unconfigured image')
|
||||
else:
|
||||
# Crap, unimplemented API call in Fake
|
||||
return None
|
||||
@@ -347,12 +349,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
return {'fake': 'fake-model'}
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_template_account')
|
||||
def test_create_volume_with_qos_type(self,
|
||||
_mock_create_template_account,
|
||||
_mock_issue_api_request):
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
_mock_create_template_account.return_value = 1
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
@@ -411,12 +410,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
sfv.create_volume(testvol)['qos'])
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_template_account')
|
||||
def test_create_volume(self,
|
||||
_mock_create_template_account,
|
||||
_mock_issue_api_request):
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
_mock_create_template_account.return_value = 1
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
@@ -440,12 +436,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
self.assertIsNone(model_update.get('provider_geometry', None))
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_template_account')
|
||||
def test_create_volume_non_512e(self,
|
||||
_mock_create_template_account,
|
||||
_mock_issue_api_request):
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
_mock_create_template_account.return_value = 1
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
@@ -500,12 +493,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
sfv.delete_snapshot(testsnap)
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_template_account')
|
||||
def test_create_clone(self,
|
||||
_mock_create_template_account,
|
||||
_mock_issue_api_request):
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
_mock_create_template_account.return_value = 1
|
||||
_fake_get_snaps = [{'snapshotID': 5, 'name': 'testvol'}]
|
||||
_fake_get_volume = (
|
||||
{'volumeID': 99,
|
||||
@@ -1218,12 +1208,9 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
self.assertEqual(2, size)
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_template_account')
|
||||
def test_create_volume_for_migration(self,
|
||||
_mock_create_template_account,
|
||||
_mock_issue_api_request):
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
_mock_create_template_account.return_value = 1
|
||||
testvol = {'project_id': 'testprjid',
|
||||
'name': 'testvol',
|
||||
'size': 1,
|
||||
@@ -1258,81 +1245,6 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
self.assertEqual('UUID-a720b3c0-d1f0-11e1-9b23-0800200c9a66',
|
||||
sf_vol_object['name'])
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_update_cluster_status')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_get_sfaccount')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_get_sf_volume')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_image_volume')
|
||||
def test_verify_image_volume_out_of_date(self,
|
||||
_mock_create_image_volume,
|
||||
_mock_get_sf_volume,
|
||||
_mock_get_sfaccount,
|
||||
_mock_issue_api_request,
|
||||
_mock_update_cluster_status):
|
||||
fake_sf_vref = {
|
||||
'status': 'active', 'volumeID': 1,
|
||||
'attributes': {
|
||||
'image_info':
|
||||
{'image_updated_at': '2014-12-17T00:16:23+00:00',
|
||||
'image_id': '17c550bb-a411-44c0-9aaf-0d96dd47f501',
|
||||
'image_name': 'fake-image',
|
||||
'image_created_at': '2014-12-17T00:16:23+00:00'}}}
|
||||
|
||||
_mock_update_cluster_status.return_value = None
|
||||
_mock_issue_api_request.side_effect = (
|
||||
self.fake_issue_api_request)
|
||||
_mock_get_sfaccount.return_value = {'username': 'openstack-vtemplate',
|
||||
'accountID': 7777}
|
||||
_mock_get_sf_volume.return_value = fake_sf_vref
|
||||
_mock_create_image_volume.return_value = fake_sf_vref
|
||||
|
||||
image_meta = {'id': '17c550bb-a411-44c0-9aaf-0d96dd47f501',
|
||||
'updated_at': datetime.datetime(2013, 9, 28,
|
||||
15, 27, 36,
|
||||
325355)}
|
||||
image_service = 'null'
|
||||
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
sfv._verify_image_volume(self.ctxt, image_meta, image_service)
|
||||
self.assertTrue(_mock_create_image_volume.called)
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_update_cluster_status')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_get_sfaccount')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_get_sf_volume')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_image_volume')
|
||||
def test_verify_image_volume_ok(self,
|
||||
_mock_create_image_volume,
|
||||
_mock_get_sf_volume,
|
||||
_mock_get_sfaccount,
|
||||
_mock_issue_api_request,
|
||||
_mock_update_cluster_status):
|
||||
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
_mock_update_cluster_status.return_value = None
|
||||
_mock_get_sfaccount.return_value = {'username': 'openstack-vtemplate',
|
||||
'accountID': 7777}
|
||||
_mock_get_sf_volume.return_value =\
|
||||
{'status': 'active', 'volumeID': 1,
|
||||
'attributes': {
|
||||
'image_info':
|
||||
{'image_updated_at': '2013-09-28T15:27:36.325355',
|
||||
'image_id': '17c550bb-a411-44c0-9aaf-0d96dd47f501',
|
||||
'image_name': 'fake-image',
|
||||
'image_created_at': '2014-12-17T00:16:23+00:00'}}}
|
||||
_mock_create_image_volume.return_value = None
|
||||
|
||||
image_meta = {'id': '17c550bb-a411-44c0-9aaf-0d96dd47f501',
|
||||
'updated_at': datetime.datetime(2013, 9, 28,
|
||||
15, 27, 36,
|
||||
325355)}
|
||||
image_service = 'null'
|
||||
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
|
||||
sfv._verify_image_volume(self.ctxt, image_meta, image_service)
|
||||
self.assertFalse(_mock_create_image_volume.called)
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
|
||||
def test_clone_image_not_configured(self, _mock_issue_api_request):
|
||||
_mock_issue_api_request.side_effect = self.fake_issue_api_request
|
||||
@@ -1345,129 +1257,6 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
self.fake_image_meta,
|
||||
'fake'))
|
||||
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_template_account')
|
||||
@mock.patch.object(solidfire.SolidFireDriver, '_create_image_volume')
|
||||
def test_clone_image_authorization(self,
|
||||
_mock_create_image_volume,
|
||||
_mock_create_template_account):
|
||||
fake_sf_vref = {
|
||||
'status': 'active', 'volumeID': 1,
|
||||
'attributes': {
|
||||
'image_info':
|
||||
{'image_updated_at': '2014-12-17T00:16:23+00:00',
|
||||
'image_id': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
||||
'image_name': 'fake-image',
|
||||
'image_created_at': '2014-12-17T00:16:23+00:00'}}}
|
||||
_mock_create_image_volume.return_value = fake_sf_vref
|
||||
_mock_create_template_account.return_value = 1
|
||||
|
||||
self.configuration.sf_allow_template_caching = True
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
|
||||
# Make sure if it's NOT public and we're NOT the owner it
|
||||
# doesn't try and cache
|
||||
timestamp = datetime.datetime(2011, 1, 1, 1, 2, 3)
|
||||
_fake_image_meta = {
|
||||
'id': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
||||
'name': 'fakeimage123456',
|
||||
'created_at': timestamp,
|
||||
'updated_at': timestamp,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
'status': 'active',
|
||||
'visibility': 'private',
|
||||
'protected': False,
|
||||
'container_format': 'raw',
|
||||
'disk_format': 'raw',
|
||||
'owner': 'wrong-owner',
|
||||
'properties': {'kernel_id': 'nokernel',
|
||||
'ramdisk_id': 'nokernel',
|
||||
'architecture': 'x86_64'}}
|
||||
|
||||
with mock.patch.object(sfv, '_do_clone_volume',
|
||||
return_value=('fe', 'fi', 'fo')):
|
||||
self.assertEqual((None, False),
|
||||
sfv.clone_image(self.ctxt,
|
||||
self.mock_volume,
|
||||
'fake',
|
||||
_fake_image_meta,
|
||||
self.fake_image_service))
|
||||
|
||||
# And is_public False, but the correct owner does work
|
||||
_fake_image_meta['owner'] = 'testprjid'
|
||||
self.assertEqual(
|
||||
('fo', True),
|
||||
sfv.clone_image(
|
||||
self.ctxt,
|
||||
self.mock_volume,
|
||||
'fake',
|
||||
_fake_image_meta,
|
||||
self.fake_image_service))
|
||||
|
||||
# And is_public True, even if not the correct owner
|
||||
_fake_image_meta['is_public'] = True
|
||||
_fake_image_meta['owner'] = 'wrong-owner'
|
||||
self.assertEqual(
|
||||
('fo', True),
|
||||
sfv.clone_image(self.ctxt,
|
||||
self.mock_volume,
|
||||
'fake',
|
||||
_fake_image_meta,
|
||||
self.fake_image_service))
|
||||
# And using the new V2 visibility tag
|
||||
_fake_image_meta['visibility'] = 'public'
|
||||
_fake_image_meta['owner'] = 'wrong-owner'
|
||||
self.assertEqual(
|
||||
('fo', True),
|
||||
sfv.clone_image(self.ctxt,
|
||||
self.mock_volume,
|
||||
'fake',
|
||||
_fake_image_meta,
|
||||
self.fake_image_service))
|
||||
|
||||
def test_create_template_no_account(self):
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
|
||||
def _fake_issue_api_req(method, params, version=0):
|
||||
if 'GetAccountByName' in method:
|
||||
raise solidfire.SolidFireAPIException
|
||||
return {'result': {'accountID': 1}}
|
||||
|
||||
with mock.patch.object(sfv,
|
||||
'_issue_api_request',
|
||||
side_effect=_fake_issue_api_req):
|
||||
self.assertEqual(1,
|
||||
sfv._create_template_account('foo'))
|
||||
|
||||
def test_configured_svip(self):
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
|
||||
def _fake_get_volumes(account_id, endpoint=None):
|
||||
return [{'volumeID': 1,
|
||||
'iqn': ''}]
|
||||
|
||||
def _fake_get_cluster_info():
|
||||
return {'clusterInfo': {'svip': '10.10.10.10',
|
||||
'mvip': '1.1.1.1'}}
|
||||
|
||||
with mock.patch.object(sfv,
|
||||
'_get_volumes_by_sfaccount',
|
||||
side_effect=_fake_get_volumes),\
|
||||
mock.patch.object(sfv,
|
||||
'_issue_api_request',
|
||||
side_effect=self.fake_issue_api_request):
|
||||
|
||||
sfaccount = {'targetSecret': 'yakitiyak',
|
||||
'accountID': 5,
|
||||
'username': 'bobthebuilder'}
|
||||
v = sfv._get_model_info(sfaccount, 1)
|
||||
self.assertEqual('1.1.1.1:3260 0', v['provider_location'])
|
||||
|
||||
configured_svip = '9.9.9.9:6500'
|
||||
sfv.active_cluster['svip'] = configured_svip
|
||||
v = sfv._get_model_info(sfaccount, 1)
|
||||
self.assertEqual('%s 0' % configured_svip, v['provider_location'])
|
||||
|
||||
def test_init_volume_mappings(self):
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import six
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.image import image_utils
|
||||
from cinder import interface
|
||||
from cinder.objects import fields
|
||||
from cinder import utils
|
||||
@@ -68,21 +67,6 @@ sf_opts = [
|
||||
'are of the form <sf_volume_prefix><cinder-volume-id>. '
|
||||
'The default is to use a prefix of \'UUID-\'.'),
|
||||
|
||||
cfg.StrOpt('sf_template_account_name',
|
||||
default='openstack-vtemplate',
|
||||
help='Account name on the SolidFire Cluster to use as owner of '
|
||||
'template/cache volumes (created if does not exist).'),
|
||||
|
||||
cfg.BoolOpt('sf_allow_template_caching',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_reason='The Cinder caching feature should be '
|
||||
'used rather than this driver specific '
|
||||
'implementation.',
|
||||
default=False,
|
||||
help='This option is deprecated and will be removed in '
|
||||
'the next OpenStack release. Please use the general '
|
||||
'cinder image-caching feature instead.'),
|
||||
|
||||
cfg.StrOpt('sf_svip',
|
||||
help='Overrides default cluster SVIP with the one specified. '
|
||||
'This is required or deployments that have implemented '
|
||||
@@ -311,10 +295,6 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
except SolidFireAPIException:
|
||||
pass
|
||||
|
||||
if self.configuration.sf_allow_template_caching:
|
||||
account = self.configuration.sf_template_account_name
|
||||
self.template_account_id = self._create_template_account(account)
|
||||
|
||||
self._set_cluster_pairs()
|
||||
|
||||
@staticmethod
|
||||
@@ -497,27 +477,6 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
snapshot_updates = self._init_snapshot_mappings(snaprefs)
|
||||
return (volume_updates, snapshot_updates)
|
||||
|
||||
def _create_template_account(self, account_name):
|
||||
# We raise an API exception if the account doesn't exist
|
||||
|
||||
# We need to take account_prefix settings into consideration
|
||||
# This just uses the same method to do template account create
|
||||
# as we use for any other OpenStack account
|
||||
account_name = self._get_sf_account_name(account_name)
|
||||
try:
|
||||
id = self._issue_api_request(
|
||||
'GetAccountByName',
|
||||
{'username': account_name})['result']['account']['accountID']
|
||||
except SolidFireAPIException:
|
||||
chap_secret = self._generate_random_string(12)
|
||||
params = {'username': account_name,
|
||||
'initiatorSecret': chap_secret,
|
||||
'targetSecret': chap_secret,
|
||||
'attributes': {}}
|
||||
id = self._issue_api_request('AddAccount',
|
||||
params)['result']['accountID']
|
||||
return id
|
||||
|
||||
def _build_endpoint_info(self, **kwargs):
|
||||
endpoint = {}
|
||||
|
||||
@@ -1001,122 +960,6 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
return self._issue_api_request(
|
||||
'ListSnapshots', params, version='6.0')['result']['snapshots']
|
||||
|
||||
def _create_image_volume(self, context,
|
||||
image_meta, image_service,
|
||||
image_id):
|
||||
with image_utils.TemporaryImages.fetch(image_service,
|
||||
context,
|
||||
image_id) as tmp_image:
|
||||
data = image_utils.qemu_img_info(tmp_image)
|
||||
fmt = data.file_format
|
||||
if fmt is None:
|
||||
raise exception.ImageUnacceptable(
|
||||
reason=_("'qemu-img info' parsing failed."),
|
||||
image_id=image_id)
|
||||
|
||||
backing_file = data.backing_file
|
||||
if backing_file is not None:
|
||||
raise exception.ImageUnacceptable(
|
||||
image_id=image_id,
|
||||
reason=_("fmt=%(fmt)s backed by:%(backing_file)s")
|
||||
% {'fmt': fmt, 'backing_file': backing_file, })
|
||||
|
||||
virtual_size = int(math.ceil(float(data.virtual_size) / units.Gi))
|
||||
attributes = {}
|
||||
attributes['image_info'] = {}
|
||||
attributes['image_info']['image_updated_at'] = (
|
||||
image_meta['updated_at'].isoformat())
|
||||
attributes['image_info']['image_name'] = (
|
||||
image_meta['name'])
|
||||
attributes['image_info']['image_created_at'] = (
|
||||
image_meta['created_at'].isoformat())
|
||||
attributes['image_info']['image_id'] = image_meta['id']
|
||||
params = {'name': 'OpenStackIMG-%s' % image_id,
|
||||
'accountID': self.template_account_id,
|
||||
'sliceCount': 1,
|
||||
'totalSize': int(virtual_size * units.Gi),
|
||||
'enable512e': self.configuration.sf_emulate_512,
|
||||
'attributes': attributes,
|
||||
'qos': {}}
|
||||
|
||||
sf_account = self._issue_api_request(
|
||||
'GetAccountByID',
|
||||
{'accountID': self.template_account_id})['result']['account']
|
||||
template_vol = self._do_volume_create(sf_account, params)
|
||||
|
||||
tvol = {}
|
||||
tvol['id'] = image_id
|
||||
tvol['provider_location'] = template_vol['provider_location']
|
||||
tvol['provider_auth'] = template_vol['provider_auth']
|
||||
|
||||
attach_info = None
|
||||
|
||||
try:
|
||||
connector = {'multipath': False}
|
||||
conn = self.initialize_connection(tvol, connector)
|
||||
attach_info = super(SolidFireDriver, self)._connect_device(
|
||||
conn)
|
||||
properties = 'na'
|
||||
image_utils.convert_image(tmp_image,
|
||||
attach_info['device']['path'],
|
||||
'raw',
|
||||
run_as_root=True)
|
||||
data = image_utils.qemu_img_info(attach_info['device']['path'],
|
||||
run_as_root=True)
|
||||
if data.file_format != 'raw':
|
||||
raise exception.ImageUnacceptable(
|
||||
image_id=image_id,
|
||||
reason=_("Converted to %(vol_format)s, but format is "
|
||||
"now %(file_format)s") % {'vol_format': 'raw',
|
||||
'file_format': data.
|
||||
file_format})
|
||||
except Exception as exc:
|
||||
vol = self._get_sf_volume(image_id)
|
||||
LOG.error('Failed image conversion during '
|
||||
'cache creation: %s',
|
||||
exc)
|
||||
LOG.debug('Removing SolidFire Cache Volume (SF ID): %s',
|
||||
vol['volumeID'])
|
||||
if attach_info is not None:
|
||||
self._detach_volume(context, attach_info, tvol, properties)
|
||||
self._issue_api_request('DeleteVolume', params)
|
||||
self._issue_api_request('PurgeDeletedVolume', params)
|
||||
return
|
||||
|
||||
self._detach_volume(context, attach_info, tvol, properties)
|
||||
sf_vol = self._get_sf_volume(image_id, params)
|
||||
LOG.debug('Successfully created SolidFire Image Template '
|
||||
'for image-id: %s', image_id)
|
||||
return sf_vol
|
||||
|
||||
def _verify_image_volume(self, context, image_meta, image_service):
|
||||
# This method just verifies that IF we have a cache volume that
|
||||
# it's still up to date and current WRT the image in Glance
|
||||
# ie an image-update hasn't occurred since we grabbed it
|
||||
|
||||
# If it's out of date, just delete it and we'll create a new one
|
||||
# Any other case we don't care and just return without doing anything
|
||||
|
||||
params = {'accountID': self.template_account_id}
|
||||
sf_vol = self._get_sf_volume(image_meta['id'], params)
|
||||
if not sf_vol:
|
||||
self._create_image_volume(context,
|
||||
image_meta,
|
||||
image_service,
|
||||
image_meta['id'])
|
||||
return
|
||||
|
||||
if sf_vol['attributes']['image_info']['image_updated_at'] != (
|
||||
image_meta['updated_at'].isoformat()):
|
||||
params = {'accountID': self.template_account_id}
|
||||
params['volumeID'] = sf_vol['volumeID']
|
||||
self._issue_api_request('DeleteVolume', params)
|
||||
self._issue_api_request('PurgeDeletedVolume', params)
|
||||
self._create_image_volume(context,
|
||||
image_meta,
|
||||
image_service,
|
||||
image_meta['id'])
|
||||
|
||||
def _get_sfaccounts_for_tenant(self, cinder_project_id):
|
||||
accounts = self._issue_api_request(
|
||||
'ListAccounts', {})['result']['accounts']
|
||||
@@ -1341,11 +1184,6 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
image_meta, image_service):
|
||||
"""Clone an existing image volume."""
|
||||
public = False
|
||||
# Check out pre-requisites:
|
||||
# Is template caching enabled?
|
||||
if not self.configuration.sf_allow_template_caching:
|
||||
return None, False
|
||||
|
||||
# NOTE(jdg): Glance V2 moved from is_public to visibility
|
||||
# so we check both, as we don't necessarily know or want
|
||||
# to care which we're using. Will need to look at
|
||||
@@ -1363,17 +1201,14 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
LOG.warning("Requested image is not "
|
||||
"accessible by current Tenant.")
|
||||
return None, False
|
||||
|
||||
# If we don't have the image-volume to clone from return failure
|
||||
# cinder driver will then create source for clone first
|
||||
try:
|
||||
self._verify_image_volume(context,
|
||||
image_meta,
|
||||
image_service)
|
||||
except SolidFireAPIException:
|
||||
(data, sfaccount, model) = self._do_clone_volume(image_meta['id'],
|
||||
volume)
|
||||
except exception.VolumeNotFound:
|
||||
return None, False
|
||||
|
||||
# Ok, should be good to go now, try it again
|
||||
(data, sfaccount, model) = self._do_clone_volume(image_meta['id'],
|
||||
volume)
|
||||
return model, True
|
||||
|
||||
def _retrieve_qos_setting(self, volume):
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
prelude: >
|
||||
SolidFire cinder driver deprecate sf_allow_template_caching
|
||||
deprecations:
|
||||
- |
|
||||
The configuration option sf_allow_template_caching for the
|
||||
SolidFire cinder driver has been removed. Use image_volume_cache_enabled
|
||||
equals True for a better template image cache that is managed from
|
||||
cinder.
|
||||
Reference in New Issue
Block a user