From 6480e33b9800a501371aeca554d3289d2965a906 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Mon, 25 Sep 2017 11:49:13 +0100 Subject: [PATCH] VMAX driver - Remove workload for next gen arrays The next release of VMAX no longer has an option to set 'Workload' on a storage group. Currently, the VMAX driver expects a workload to be set when the user creates a VMAX volume type, which will cause an issue for users using the next gen VMAX arrays. This patch rectifies the issue. Change-Id: I8ad7fbdca5a2695734b118d60a29a71064ae9b0b Closes-Bug: 1717289 --- .../volume/drivers/dell_emc/vmax/test_vmax.py | 27 +++++++++++++++---- cinder/volume/drivers/dell_emc/vmax/rest.py | 26 +++++++++++++++--- cinder/volume/drivers/dell_emc/vmax/utils.py | 12 ++++++--- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py b/cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py index 1e2b62f386c..9e2eede9051 100644 --- a/cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py +++ b/cinder/tests/unit/volume/drivers/dell_emc/vmax/test_vmax.py @@ -52,6 +52,7 @@ CINDER_EMC_CONFIG_DIR = '/etc/cinder/' class VMAXCommonData(object): # array info array = '000197800123' + array_herc = '000197900123' srp = 'SRP_1' srp2 = 'SRP_2' slo = 'Diamond' @@ -613,9 +614,12 @@ class VMAXCommonData(object): "resourceLink": "storagegroup/%s" % storagegroup_name_f}, {"status": "RUNNING", "jobId": "55555"}, {"status": "FAILED", "jobId": "09999"}] - symmetrix = {"symmetrixId": array, - "model": "VMAX250F", - "ucode": "5977.1091.1092"} + symmetrix = [{"symmetrixId": array, + "model": "VMAX250F", + "ucode": "5977.1091.1092"}, + {"symmetrixId": array_herc, + "model": "VMAXHERC", + "ucode": "5978.1091.1092"}] headroom = {"headroom": [{"headroomCapacity": 20348.29}]} @@ -805,7 +809,10 @@ class FakeRequestsSession(object): return_object = job break else: - return_object = self.data.symmetrix + for symm in self.data.symmetrix: + if symm['symmetrixId'] in url: + return_object = symm + break return return_object def _post_or_put(self, url, payload): @@ -1527,7 +1534,7 @@ class VMAXRestTest(test.TestCase): resource_type, resource_name) def test_get_array_serial(self): - ref_details = self.data.symmetrix + ref_details = self.data.symmetrix[0] array_details = self.rest.get_array_serial(self.data.array) self.assertEqual(ref_details, array_details) @@ -1556,6 +1563,10 @@ class VMAXRestTest(test.TestCase): wl_settings = self.rest.get_workload_settings( self.data.failed_resource) self.assertEqual([], wl_settings) + # New array + wl_settings = self.rest.get_workload_settings( + self.data.array_herc) + self.assertEqual([], wl_settings) def test_is_compression_capable_true(self): compr_capable = self.rest.is_compression_capable('000197800128') @@ -2633,6 +2644,12 @@ class VMAXRestTest(test.TestCase): self.data.rdf_group_no) mock_del.assert_called_once() + def test_is_next_gen_array(self): + is_next_gen = self.rest.is_next_gen_array(self.data.array) + self.assertFalse(is_next_gen) + is_next_gen2 = self.rest.is_next_gen_array(self.data.array_herc) + self.assertTrue(is_next_gen2) + class VMAXProvisionTest(test.TestCase): def setUp(self): diff --git a/cinder/volume/drivers/dell_emc/vmax/rest.py b/cinder/volume/drivers/dell_emc/vmax/rest.py index b7ec2109d02..ba0f4e4fcf2 100644 --- a/cinder/volume/drivers/dell_emc/vmax/rest.py +++ b/cinder/volume/drivers/dell_emc/vmax/rest.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Dell Inc. or its subsidiaries. +# Copyright (c) 2018 Dell Inc. or its subsidiaries. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -35,6 +35,7 @@ LOG = logging.getLogger(__name__) SLOPROVISIONING = 'sloprovisioning' REPLICATION = 'replication' U4V_VERSION = '84' +UCODE_5978 = '5978' retry_exc_tuple = (exception.VolumeBackendAPIException,) # HTTP constants GET = 'GET' @@ -413,6 +414,20 @@ class VMAXRest(object): {'array': array}) return array_details + def is_next_gen_array(self, array): + """Check to see if array is a next gen array(ucode 5978 or greater). + + :param array: the array serial number + :returns: bool + """ + is_next_gen = False + array_details = self.get_array_serial(array) + if array_details: + ucode_version = array_details['ucode'].split('.')[0] + if ucode_version >= UCODE_5978: + is_next_gen = True + return is_next_gen + def get_srp_by_name(self, array, srp=None): """Returns the details of a storage pool. @@ -441,13 +456,16 @@ class VMAXRest(object): def get_workload_settings(self, array): """Get valid workload options from array. + Workloads are no longer supported from HyperMaxOS 5978 onwards. :param array: the array serial number :returns: workload_setting -- list of workload names """ workload_setting = [] - wl_details = self.get_resource(array, SLOPROVISIONING, 'workloadtype') - if wl_details: - workload_setting = wl_details['workloadId'] + if not self.is_next_gen_array(array): + wl_details = self.get_resource( + array, SLOPROVISIONING, 'workloadtype') + if wl_details: + workload_setting = wl_details['workloadId'] return workload_setting def is_compression_capable(self, array): diff --git a/cinder/volume/drivers/dell_emc/vmax/utils.py b/cinder/volume/drivers/dell_emc/vmax/utils.py index 01fa24d3e3b..4b6c7b1aabb 100644 --- a/cinder/volume/drivers/dell_emc/vmax/utils.py +++ b/cinder/volume/drivers/dell_emc/vmax/utils.py @@ -538,9 +538,15 @@ class VMAXUtils(object): try: pool_details = extraspecs['pool_name'].split('+') extraspecs[SLO] = pool_details[0] - extraspecs[WORKLOAD] = pool_details[1] - extraspecs[SRP] = pool_details[2] - extraspecs[ARRAY] = pool_details[3] + if len(pool_details) == 4: + extraspecs[WORKLOAD] = pool_details[1] + extraspecs[SRP] = pool_details[2] + extraspecs[ARRAY] = pool_details[3] + else: + # Assume no workload given in pool name + extraspecs[SRP] = pool_details[1] + extraspecs[ARRAY] = pool_details[2] + extraspecs[WORKLOAD] = 'NONE' except KeyError: LOG.error("Error parsing SLO, workload from" " the provided extra_specs.")