Skip to content

Commit a35eba2

Browse files
authored
Merge pull request #37 from bingyanh/master
update manila Rocky
2 parents f2540ed + 8146926 commit a35eba2

File tree

9 files changed

+188
-31
lines changed

9 files changed

+188
-31
lines changed

Manila/Rocky-eol/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"""Version: 2.3.RC2"""
1+
"""Version: 2.5.RC1"""

Manila/Rocky-eol/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
METRO_RUNNING_STATUS_TO_BE_SYNC) = (
129129
'1', '23', '35', '41', '93', '94', '100')
130130

131-
VALID_PRODUCTS = ('V3', 'V5', 'Dorado')
131+
VALID_PRODUCTS = ('V3', 'V5', 'Dorado', 'V6')
132132

133133
AVAILABLE_FEATURE_STATUS = (1, 2)
134134
VALID_NETWORK_TYPE = ('flat', 'vlan', 'vxlan', None)
@@ -139,3 +139,5 @@
139139
SNAPSHOT_ROLLBACK_COMPLETED = "0"
140140

141141
FILESYSTEM_MODES = ('0', '2')
142+
RPC_CALL_TIMES = 2
143+
RPC_CALL_INTERVAL = 1

Manila/Rocky-eol/helper.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,11 @@ def get_share_by_name(self, share_name, share_proto, vstore_id=None):
537537
url = "/CIFSHARE?filter=DESCRIPTION:%s&range=[0-100]" % share_name
538538
result = self.call(url, "GET", data)
539539

540+
if share_proto == 'CIFS' and result.get('data'):
541+
for data in result.get('data'):
542+
if data.get('NAME') == cifs_share:
543+
return data
544+
540545
for data in result.get('data', []):
541546
return data
542547

@@ -648,7 +653,7 @@ def update_qos_fs(self, qos_id, new_fs_list):
648653
_assert_result(result, 'Associate FS %s to Qos %s error.',
649654
new_fs_list, qos_id)
650655

651-
def create_qos(self, qos, fs_id):
656+
def create_qos(self, qos, fs_id, vstore_id):
652657
localtime = time.strftime('%Y%m%d%H%M%S', time.localtime())
653658
qos_name = constants.QOS_NAME_PREFIX + fs_id + '_' + localtime
654659
data = {"NAME": qos_name,
@@ -658,6 +663,7 @@ def create_qos(self, qos, fs_id):
658663
"SCHEDULESTARTTIME": "1410969600",
659664
"STARTTIME": "00:00",
660665
"DURATION": "86400",
666+
"vstoreId": vstore_id,
661667
}
662668
data.update(qos)
663669
result = self.call("/ioclass", 'POST', data)
@@ -963,7 +969,7 @@ def sync_hypermetro_pair(self, pair_id):
963969
_assert_result(result, 'Sync HyperMetro pair %s error.', pair_id)
964970

965971
def delete_hypermetro_pair(self, pair_id):
966-
url = "/HyperMetroPair/%s" % pair_id
972+
url = "/HyperMetroPair/%s?isOnlineDeleting=0" % pair_id
967973
result = self.call(url, "DELETE")
968974
if _error_code(result) == constants.ERROR_HYPERMETRO_NOT_EXIST:
969975
LOG.warning('Hypermetro pair %s to delete not exist.', pair_id)

Manila/Rocky-eol/huawei_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from oslo_log import log as logging
2020
from oslo_utils import strutils
21-
from xml.etree import ElementTree as ET
21+
from defusedxml import ElementTree as ET
2222

2323
from manila import exception
2424
from manila.i18n import _
@@ -82,7 +82,7 @@ def _encode_authentication(self, tree, xml_root):
8282
need_encode = True
8383

8484
if need_encode:
85-
tree.write(self.config.manila_huawei_conf_file, 'UTF-8')
85+
tree.write(self.config.manila_huawei_conf_file, encoding='UTF-8')
8686

8787
def _nas_address(self, xml_root):
8888
text = xml_root.findtext('Storage/RestURL')

Manila/Rocky-eol/huawei_nas.py

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,10 @@ def _check_lun_type(opts):
188188
LOG.error(msg)
189189
raise exception.InvalidInput(reason=msg)
190190

191-
def _add_smartx(self, opts, fs_id):
191+
def _add_smartx(self, opts, fs_id, vstore_id):
192192
try:
193193
if opts['qos']:
194-
self.smart_qos.add(opts['qos'], fs_id)
194+
self.smart_qos.add(opts['qos'], fs_id, vstore_id)
195195
if opts['huawei_smartpartition']:
196196
self.smart_partition.add(opts['partitionname'], fs_id)
197197
if opts['huawei_smartcache']:
@@ -318,7 +318,8 @@ def _create_filesystem(self, share, pool_name, share_fs_id=None,
318318
self.configuration.timeout)
319319
fs_info = self._split_clone_fs(context, share, fs_id)
320320

321-
self._add_smartx(opts, fs_id)
321+
vstore_id = fs_info.get('vstoreId')
322+
self._add_smartx(opts, fs_id, vstore_id)
322323
self._add_hypermetro(context, opts, params, remote_vstore_id, fs_info)
323324
return fs_id
324325

@@ -546,29 +547,44 @@ def delete_share(self, context, share, share_server=None):
546547
def update_replica_filesystem(self, replica_fs_id, params):
547548
self.helper.update_filesystem(replica_fs_id, params)
548549

549-
def _update_filesystem(self, fs_info, params):
550-
fs_id = fs_info.get('ID')
551-
if (not self.is_dorado_v6 and
552-
json.loads(fs_info.get('HYPERMETROPAIRIDS'))):
550+
def _check_and_get_hypermetro_pair(self, fs_info):
551+
if json.loads(fs_info.get('HYPERMETROPAIRIDS')):
553552
metro_id = self._get_metro_id_from_fs_info(fs_info)
554553
metro_info = self.helper.get_hypermetro_pair_by_id(metro_id)
555554
if not metro_info:
556555
msg = (_("The hypermetro pair %(metro_id)s does not exist.") %
557556
{"metro_id": metro_id})
558557
LOG.error(msg)
559558
raise exception.InvalidInput(reason=msg)
559+
return metro_info
560+
return {}
560561

561-
remote_fs_id = self._get_remote_fs_id(fs_id, metro_info)
562-
try:
563-
context = manila_context.get_admin_context()
564-
self.rpc_client.update_filesystem(context, self.remote_backend,
565-
remote_fs_id, params)
566-
except Exception as err:
567-
msg = (_("Failed to update remote filesystem %(fs_id)s. "
568-
"Reason: %(err)s") %
569-
{"fs_id": remote_fs_id, "err": err})
570-
LOG.error(msg)
571-
raise exception.InvalidInput(reason=msg)
562+
def _is_dorado_v6_hypermetro_filesystem_not_active(self, fs_info):
563+
return (self.is_dorado_v6
564+
and bool(self._check_and_get_hypermetro_pair(fs_info))
565+
and not self._check_is_active_client())
566+
567+
def _update_hypermetro_remote_filesystem(self, fs_info, params):
568+
fs_id = fs_info.get('ID')
569+
metro_info = self._check_and_get_hypermetro_pair(fs_info)
570+
571+
remote_fs_id = self._get_remote_fs_id(fs_id, metro_info)
572+
try:
573+
context = manila_context.get_admin_context()
574+
self.rpc_client.update_filesystem(context, self.remote_backend,
575+
remote_fs_id, params)
576+
except Exception as err:
577+
msg = (_("Failed to update remote filesystem %(fs_id)s. "
578+
"Reason: %(err)s") %
579+
{"fs_id": remote_fs_id, "err": err})
580+
LOG.error(msg)
581+
raise exception.InvalidInput(reason=msg)
582+
583+
def _update_filesystem(self, fs_info, params):
584+
fs_id = fs_info.get('ID')
585+
if (not self.is_dorado_v6 and
586+
json.loads(fs_info.get('HYPERMETROPAIRIDS'))):
587+
self._update_hypermetro_remote_filesystem(fs_info, params)
572588

573589
if json.loads(fs_info.get('REMOTEREPLICATIONIDS')):
574590
replica_id = self._get_replica_id_from_fs_info(fs_info)
@@ -591,6 +607,11 @@ def _update_filesystem(self, fs_info, params):
591607
LOG.error(msg)
592608
raise exception.InvalidInput(reason=msg)
593609

610+
if (self.is_dorado_v6 and json.loads(fs_info.get('HYPERMETROPAIRIDS'))
611+
and not self._check_is_active_client()):
612+
self._update_hypermetro_remote_filesystem(fs_info, params)
613+
return
614+
594615
self.helper.update_filesystem(fs_id, params)
595616

596617
def _get_fs_info_by_name(self, share_name, raise_exception=True):
@@ -645,16 +666,49 @@ def shrink_share(self, share, new_size, share_server=None):
645666
params = {"CAPACITY": size}
646667
self._update_filesystem(fs_info, params)
647668

669+
def rpc_create_hypermetro_snapshot(self, context,
670+
share_name, snapshot_name):
671+
fs_info = self._get_fs_info_by_name(share_name)
672+
return self.helper.create_snapshot(fs_info['ID'], snapshot_name)
673+
648674
def create_snapshot(self, context, snapshot, share_server=None):
649675
fs_info = self._get_fs_info_by_name(snapshot['share_name'])
650-
snapshot_id = self.helper.create_snapshot(fs_info['ID'],
651-
snapshot['name'])
676+
if self._is_dorado_v6_hypermetro_filesystem_not_active(fs_info):
677+
snapshot_id = self.rpc_client.create_hypermetro_snapshot(
678+
context, snapshot['share_name'], snapshot['name'],
679+
self.remote_backend)
680+
else:
681+
snapshot_id = self.helper.create_snapshot(fs_info['ID'],
682+
snapshot['name'])
652683
LOG.info("Create snapshot %(snapshot)s from share %(share)s "
653684
"successfully.", {"snapshot": snapshot["id"],
654685
"share": snapshot['share_name']})
655686
return {'provider_location': snapshot_id}
656687

688+
def rpc_delete_hypermetro_snapshot(self, context, share_name,
689+
snapshot_name):
690+
fs_info = self._get_fs_info_by_name(share_name)
691+
snapshot_id = huawei_utils.snapshot_id(fs_info['ID'],
692+
snapshot_name)
693+
self.helper.delete_snapshot(snapshot_id)
694+
657695
def delete_snapshot(self, context, snapshot, share_server=None):
696+
fs_info = self._get_fs_info_by_name(snapshot['share_name'],
697+
raise_exception=False)
698+
if not fs_info:
699+
LOG.error("The filestsyetm %s is not exist, return success.",
700+
snapshot['share_name'])
701+
return
702+
703+
if self._is_dorado_v6_hypermetro_filesystem_not_active(fs_info):
704+
self.rpc_client.delete_hypermetro_snapshot(context,
705+
snapshot['share_name'],
706+
snapshot['name'],
707+
self.remote_backend)
708+
LOG.info("Delete snapshot %(snapshot)s successfully.",
709+
{"snapshot": snapshot["id"]})
710+
return
711+
658712
provider_location = snapshot.get('provider_location')
659713
if provider_location and '@' in provider_location:
660714
snapshot_id = provider_location
@@ -749,6 +803,7 @@ def _update_pool_info(self):
749803
capacity.get('PROVISIONEDCAPACITY', 0.0),
750804
'allocated_capacity_gb': capacity.get('CONSUMEDCAPACITY', 0.0),
751805
'reserved_percentage': 0,
806+
'reserved_snapshot_percentage': 0,
752807
'qos': [self.feature_supports['SmartQoS'], False],
753808
'huawei_smartcache':
754809
[self.feature_supports['SmartCache'], False],
@@ -783,7 +838,7 @@ def _update_share_stats(self, date=None):
783838
data = {
784839
'share_backend_name': backend_name or 'HUAWEI_NAS_Driver',
785840
'vendor_name': 'Huawei',
786-
'driver_version': '2.3.RC2',
841+
'driver_version': '2.5.RC1',
787842
'storage_protocol': 'NFS_CIFS',
788843
'snapshot_support': (self.feature_supports['HyperSnap']
789844
and self.configuration.snapshot_support),
@@ -850,9 +905,19 @@ def _get_access_for_share_copy(self, share):
850905
{'access': access, 'share': share['name']})
851906
return access
852907

908+
def rpc_create_share_from_hypermetro_snapshot(self, context, share,
909+
snapshot, share_server):
910+
return self.create_share_from_snapshot(
911+
context, share, snapshot, share_server)
912+
853913
def create_share_from_snapshot(self, context, share,
854914
snapshot, share_server=None):
855915
share_fs_info = self._get_fs_info_by_name(snapshot['share_name'])
916+
if self._is_dorado_v6_hypermetro_filesystem_not_active(share_fs_info):
917+
return self.rpc_client.create_share_from_hypermetro_snapshot(
918+
context, share, snapshot, share_server, self.remote_backend)
919+
920+
share_fs_info = self._get_fs_info_by_name(snapshot['share_name'])
856921
share_fs_id = share_fs_info['ID']
857922
snapshot_id = huawei_utils.snapshot_id(share_fs_id, snapshot['name'])
858923

@@ -1907,9 +1972,19 @@ def _snapshot_rollback_finish():
19071972
constants.SNAPSHOT_ROLLBACK_TIMEOUT)
19081973
LOG.info("Snapshot %s rollback successful.", snapshot_name)
19091974

1975+
def rpc_revert_to_hypermetro_snapshot(self, context, share_name,
1976+
snapshot_name):
1977+
self._revert_to_snapshot(share_name, snapshot_name)
1978+
19101979
def revert_to_snapshot(self, context, snapshot, share_access_rules,
19111980
snapshot_access_rules, share_server=None):
1912-
self._revert_to_snapshot(snapshot['share_name'], snapshot['name'])
1981+
fs_info = self._get_fs_info_by_name(snapshot['share_name'])
1982+
if self._is_dorado_v6_hypermetro_filesystem_not_active(fs_info):
1983+
self.rpc_client.revert_to_hypermetro_snapshot(
1984+
context, snapshot['share_name'], snapshot['name'],
1985+
self.remote_backend)
1986+
else:
1987+
self._revert_to_snapshot(snapshot['share_name'], snapshot['name'])
19131988

19141989
def rpc_update_snapshot(self, replica_share_name,
19151990
active_snapshot_name, replica_snapshot_name):

Manila/Rocky-eol/huawei_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def _get_string_param(k, v):
9595
def _get_opts_from_specs(specs, is_dorado):
9696
default_support = True if is_dorado else False
9797
opts_capability = {
98-
'capabilities:dedupe': (_get_bool_param, default_support),
98+
'capabilities:dedupe': (_get_bool_param, False),
9999
'capabilities:compression': (_get_bool_param, default_support),
100100
'capabilities:huawei_smartcache': (_get_bool_param, False),
101101
'capabilities:huawei_smartpartition': (_get_bool_param, False),

Manila/Rocky-eol/manager.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,21 @@ def allow_access(self, context, params):
8181

8282
def get_remote_fs_info(self, context, share_name):
8383
self.metro_mgr.get_remote_fs_info(share_name)
84+
85+
def create_hypermetro_snapshot(self, context, share_name, snapshot_name):
86+
return self.driver.rpc_create_hypermetro_snapshot(context, share_name,
87+
snapshot_name)
88+
89+
def delete_hypermetro_snapshot(self, context, share_name, snapshot_name):
90+
return self.driver.rpc_delete_hypermetro_snapshot(context, share_name,
91+
snapshot_name)
92+
93+
def revert_to_hypermetro_snapshot(self, context, share_name,
94+
snapshot_name):
95+
self.driver.rpc_revert_to_hypermetro_snapshot(context, share_name,
96+
snapshot_name)
97+
98+
def create_share_from_hypermetro_snapshot(self, context, share, snapshot,
99+
share_server):
100+
return self.driver.rpc_create_share_from_hypermetro_snapshot(
101+
context, share, snapshot, share_server)

Manila/Rocky-eol/rpcapi.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1313
# License for the specific language governing permissions and limitations
1414
# under the License.
15+
import time
1516

1617
import oslo_messaging as messaging
1718

1819
from manila import rpc
1920
from manila.share import utils
21+
from manila.share.drivers.huawei import constants
2022

2123

2224
class HuaweiAPI(object):
@@ -35,6 +37,19 @@ def __init__(self):
3537
version=self.BASE_RPC_API_VERSION)
3638
self.client = rpc.get_client(target, version_cap='1.0')
3739

40+
@staticmethod
41+
def _retry_rpc_call(call_times, interval, call_context_call, context,
42+
rpc_fun_name, **kwargs):
43+
while call_times:
44+
try:
45+
return call_context_call(context, rpc_fun_name, **kwargs)
46+
except Exception:
47+
call_times -= 1
48+
if not call_times:
49+
raise
50+
time.sleep(interval)
51+
continue
52+
3853
def create_replica_pair(
3954
self, context, host, local_share_info, remote_device_wwn,
4055
remote_fs_id, local_replication):
@@ -217,3 +232,44 @@ def delete_replica_snapshot(
217232
replica_share_name=replica_share_name,
218233
replica_snapshot_name=replica_snapshot_name,
219234
)
235+
236+
def create_hypermetro_snapshot(self, context, share_name, snapshot_name,
237+
host):
238+
call_context = self.client.prepare(server=host, version='1.0')
239+
return self._retry_rpc_call(constants.RPC_CALL_TIMES,
240+
constants.RPC_CALL_INTERVAL,
241+
call_context.call, context,
242+
"create_hypermetro_snapshot",
243+
share_name=share_name,
244+
snapshot_name=snapshot_name)
245+
246+
def delete_hypermetro_snapshot(self, context, share_name, snapshot_name,
247+
host):
248+
call_context = self.client.prepare(server=host, version='1.0')
249+
return self._retry_rpc_call(constants.RPC_CALL_TIMES,
250+
constants.RPC_CALL_INTERVAL,
251+
call_context.call, context,
252+
"delete_hypermetro_snapshot",
253+
share_name=share_name,
254+
snapshot_name=snapshot_name)
255+
256+
def revert_to_hypermetro_snapshot(self, context, share_name, snapshot_name,
257+
host):
258+
call_context = self.client.prepare(server=host, version='1.0')
259+
return self._retry_rpc_call(constants.RPC_CALL_TIMES,
260+
constants.RPC_CALL_INTERVAL,
261+
call_context.call, context,
262+
"revert_to_hypermetro_snapshot",
263+
share_name=share_name,
264+
snapshot_name=snapshot_name)
265+
266+
def create_share_from_hypermetro_snapshot(self, context, share,
267+
snapshot, share_server, host):
268+
call_context = self.client.prepare(server=host, version='1.0')
269+
return self._retry_rpc_call(constants.RPC_CALL_TIMES,
270+
constants.RPC_CALL_INTERVAL,
271+
call_context.call, context,
272+
"create_share_from_hypermetro_snapshot",
273+
share=share,
274+
snapshot=snapshot,
275+
share_server=share_server)

0 commit comments

Comments
 (0)