cinder-fusioncompute/cinder/volume/drivers/huawei/fusioncompute/volume_snapshot_proxy.py

309 lines
12 KiB
Python

# Copyright 2016 Huawei Technologies Co.,LTD.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
[VRM DRIVER] VRM CLIENT.
"""
import json
from oslo_config import cfg
from oslo_log import log as logging
from cinder import exception as cinder_exception
from cinder.i18n import _
from cinder.volume.drivers.huawei.fusioncompute.base_proxy import BaseProxy
from cinder.volume.drivers.huawei.fusioncompute import exception as driver_exception
from cinder.volume.drivers.huawei.fusioncompute.task_proxy import TaskProxy
from cinder.volume.drivers.huawei.fusioncompute.utils import Delete_Snapshot_Code
CONF = cfg.CONF
try:
from eventlet import sleep
except ImportError:
from time import sleep
TASK_WAITING = 'waiting'
TASK_RUNNING = 'running'
TASK_SUCCESS = 'success'
TASK_FAILED = 'failed'
TASK_CANCELLING = 'cancelling'
TASK_UNKNOWN = 'unknown'
LOG = logging.getLogger(__name__)
class VolumeSnapshotProxy(BaseProxy):
def __init__(self, *args, **kwargs):
super(VolumeSnapshotProxy, self).__init__()
LOG.info(_("[VRM-CINDER] start __init__()"))
self.task_proxy = TaskProxy()
self.create_retry = ['10000009', '10430056', '10430050', '10300421',
'10430057', '10300318', '10300162', '10300026']
self.delete_retry = Delete_Snapshot_Code
self.number = CONF.vrm_vol_snapshot_retries
self.sleep_time = CONF.vrm_snapshot_sleeptime
if not self.number:
LOG.error('conf number is None, use 3')
self.number = 3
if not self.sleep_time:
LOG.error('conf sleeptime is None, use 300')
self.sleep_time = 300
def query_volumesnapshot(self, **kwargs):
'''query_volumesnapshot
'list_volumesnapshot': ('GET',
('/volumesnapshots', None, kwargs.get('uuid'),
None),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope')
},
{},
False),
'''
LOG.info(_("[VRM-CINDER] start query_volumesnapshot()"))
uri = '/volumesnapshots'
method = 'GET'
path = self.site_uri + uri + '/' + kwargs.get('uuid')
new_url = self._generate_url(path)
try:
resp, body = self.vrmhttpclient.request(new_url, method)
except driver_exception.ClientException as ex:
LOG.info(_("[VRM-CINDER] query snapshot (%s)"), ex.errorCode)
if ex.errorCode == "10430051":
return None
else:
raise ex
'''
error_code = body.get('errorCode')
if error_code != None:
if '10430010' == error_code:
LOG.info(_("[VRM-CINDER] snapshot not exist"))
return None
'''
return body
def list_snapshot(self, **kwargs):
'''list_snapshot
'list_volumesnapshot': ('GET',
('/volumesnapshots', None, kwargs.get('uuid'),
None),
{'limit': kwargs.get('limit'),
'offset': kwargs.get('offset'),
'scope': kwargs.get('scope')
},
{},
False),
'''
LOG.info(_("[VRM-CINDER] start list_snapshot()"))
uri = '/volumesnapshots/queryVolumeSnapshots'
method = 'GET'
path = self.site_uri + uri
body = None
offset = 0
snapshots = []
while True:
parames = {
'limit': self.limit,
'offset': offset}
appendix = self._joined_params(parames)
new_url = self._generate_url(path, appendix)
resp, body = self.vrmhttpclient.request(new_url, method)
total = int(body.get('total') or 0)
if total > 0:
res = body.get('snapshots')
snapshots += res
offset += len(res)
if offset >= total or len(snapshots) >= total or len(
res) < self.limit:
break
else:
break
return snapshots
def create_volumesnapshot(self, **kwargs):
'''create_volumesnapshot
'create_volumesnapshot': ('POST',
('/volumesnapshots', None, None, None),
{},
{'volumeUrn': kwargs.get('vol_urn'),
'snapshotUuid': kwargs.get('uuid'),
},
False),
'''
LOG.info(_("[VRM-CINDER] start create_volumesnapshot()"))
uri = '/volumesnapshots'
method = 'POST'
path = self.site_uri + uri
body = {
'volumeUrn': kwargs.get('vol_urn'),
'snapshotUuid': kwargs.get('snapshot_uuid')
}
enable_active = kwargs.get('enable_active', None)
if enable_active is not None:
body.update({'enableActive': enable_active})
new_url = self._generate_url(path)
number = self.number
sleep_time = self.sleep_time
while(number >= 0):
try:
resp, body = self.vrmhttpclient.request(new_url, method,
body=json.dumps(body))
task_uri = body.get('taskUri')
if task_uri is not None:
self.task_proxy.wait_task(task_uri=task_uri)
return body
except driver_exception.ClientException as ex:
LOG.info(_("[VRM-CINDER] create volumesnapshot (%s)"),
ex.errorCode)
if ex.errorCode not in self.create_retry:
raise ex
LOG.debug(
'[VRM-CINDER] The errorcode is in retry list:%d' % number)
number -= 1
if number < 0:
raise ex
sleep(sleep_time)
def active_snapshots(self, **kwargs):
'''active_snapshots
'active_snapshots': ('POST',
('/volumesnapshots/enableSnapshots',
None, None, None),
{},
{'snapshotList': kwargs.get('snapshot_urns')},
False),
'''
LOG.info(_("[VRM-CINDER] start active_snapshots()"))
uri = '/volumesnapshots/enableSnapshots'
method = 'POST'
path = self.site_uri + uri
body = {
'snapshotUuidList': kwargs.get('snapshot_uuids')
}
new_url = self._generate_url(path)
resp, body = self.vrmhttpclient.request(new_url, method,
body=json.dumps(body))
task_uri = body.get('taskUri')
if task_uri is not None:
self.task_proxy.wait_task(task_uri=task_uri)
return body
def delete_volumesnapshot(self, **kwargs):
'''delete_volumesnapshot
'delete_volumesnapshot': ('DELETE',
('/volumesnapshots', None, None,
kwargs.get('id')),
{},
{
'snapshotUuid': kwargs.get('snapshotUuid'),
},
True),
'''
LOG.info(_("[VRM-CINDER] start delete_volumesnapshot()"))
uri = '/volumesnapshots'
method = 'DELETE'
path = self.site_uri + uri + '/' + kwargs.get('id')
body = {
'volumeUrn': kwargs.get('vol_urn'),
'snapshotUuid': kwargs.get('snapshot_uuid')}
new_url = self._generate_url(path)
number = self.number
sleep_time = self.sleep_time
while(number >= 0):
try:
resp, body = self.vrmhttpclient.request(new_url, method)
task_uri = body.get('taskUri')
self.task_proxy.wait_task(task_uri=task_uri)
break
except driver_exception.ClientException as ex:
LOG.info(_("[VRM-CINDER] delete volumesnapshot (%s)"),
ex.errorCode)
normal_errorcode = ['10300026', '10300057', '10430052',
'10430054', '10430056', '10300421',
'10300318', '10300162', '10300153',
'10300170', '10000009', '10300421',
'10420138']
if ex.errorCode in normal_errorcode:
LOG.error(_(
"[VRM-CINDER] snapshot status conflicts, "
"try delete later."))
raise cinder_exception.SnapshotIsBusy(
snapshot_name=kwargs.get('snapshot_uuid'))
if ex.errorCode not in self.delete_retry:
raise ex
LOG.info(
'[VRM-CINDER] The errorcode is in retry list, number:%d' %
number)
number -= 1
if number < 0:
raise ex
sleep(sleep_time)
def create_volume_from_snapshot(self, **kwargs):
'''create_volume_from_snapshot
'createvolumefromsnapshot': ('POST',
('/volumesnapshots', None, "createvol",
None),
{},
{'snapshotUuid': kwargs.get('uuid'),
'volumeName': kwargs.get('name'),
'volumeType': normal/share
'volumeUuid': uuid
'snapshotVolumeType': 0/1
},
True),
'''
LOG.info(_("[VRM-CINDER] start createvolumefromsnapshot()"))
uri = '/volumesnapshots/createvol'
method = 'POST'
path = self.site_uri + uri
snapshotVolumeType = 0
if str(kwargs.get('full_clone')) == '0':
snapshotVolumeType = 1
body = {
'snapshotUuid': kwargs.get('snapshot_uuid'),
'volumeName': kwargs.get('volume_name'),
'volumeType': kwargs.get('type'),
'volumeUuid': kwargs.get('volume_uuid'),
'snapshotVolumeType': snapshotVolumeType,
}
if kwargs.get('volume_size') is not None:
body.update({'volumeSize': kwargs.get('volume_size')})
new_url = self._generate_url(path)
resp, body = self.vrmhttpclient.request(new_url, method,
body=json.dumps(body))
task_uri = body.get('taskUri')
self.task_proxy.wait_task(task_uri=task_uri)
return body