Discussion:
[Libstoragemgmt-devel] [PATCH 0/7] Move lsm.System related methods to smis_sys.py.
Gris Ge
2014-09-25 12:58:25 UTC
Permalink
New smis_sys.py file to contain all lsm.System related methods including
the CIM_ComputerSystem to lsm.System converter method.

This patchset is based on:
* [V2 0/3] Move capablities to separate file
* [PATCH V3 00/10] SMI-S plugin: Reorganize code layout.

Plan for this change:
1. smis.py will only handle:
* plugin interface.
* some actions require two or more smis_xxx file:
Example A: Get all cim_pool.
Step 1: This require list all cim_sys first.1]
Step 2: Then find all associated cim_pool.
# Step 1 is in smis_sys.py
# Step 2 will be in smis_pool.py
# As smis_pool.py cannot depend on smis_sys.py[1],
# smis.py has to combine these two steps to provide all
# cim_pools.
Example B: job_status() for volume_create()
* Common job handling will be in smis_common.py like query
CIM_ConcreteJob and use CIM_AffectedJobElement to get cim_pool.
* Converting cim_pool to lsm.Pool will be in smis_pool.py
# As smis_common cannot depend on smis_pool[1],
# A method like _new_vol_from_job() has to be placed in smis.py,
# not smis_common.py or smis_pool.py
2. smis_xxx.py contain all lsm.XXX related methods:
smis_sys: lsm.System
smis_pool: lsm.Pool
smis_vol: lsm.Volume and volume_mask() _unmask()
smis_ag: lsm.AccessGroup

[1] In case of looping requirement.

Gris Ge (7):
SMI-S Plugin: Add smis_sys.py to smis-s plugin.
SMI-S Plugin: Move lsm.System.id generator to smis_sys.py
SMI-S Plugin: Move URI system filter to SmisCommon
SMI-S Plugin: Move Smis._root_cim_syss() to smis_sys.py
SMI-S Plugin: Move Smis._cim_sys_pros() to smis_sys.py
SMI-S Plugin: Move System converter to smis_sys.py
SMI-S Plugin: Improve cim_sys query on system_id

packaging/libstoragemgmt.spec.in | 1 +
plugin/Makefile.am | 3 +-
plugin/smispy/dmtf.py | 25 +-----
plugin/smispy/smis.py | 170 +++++++++------------------------------
plugin/smispy/smis_common.py | 3 +-
plugin/smispy/smis_sys.py | 149 ++++++++++++++++++++++++++++++++++
6 files changed, 197 insertions(+), 154 deletions(-)
create mode 100644 plugin/smispy/smis_sys.py
--
1.8.3.1
Gris Ge
2014-09-25 12:58:26 UTC
Permalink
* Just empty smis_sys.py file with license only.
* Makefile and RPM spec file updated.

Signed-off-by: Gris Ge <***@redhat.com>
---
packaging/libstoragemgmt.spec.in | 1 +
plugin/Makefile.am | 3 ++-
plugin/smispy/smis_sys.py | 16 ++++++++++++++++
3 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 plugin/smispy/smis_sys.py

diff --git a/packaging/libstoragemgmt.spec.in b/packaging/libstoragemgmt.spec.in
index ef39361..6eb1d55 100644
--- a/packaging/libstoragemgmt.spec.in
+++ b/packaging/libstoragemgmt.spec.in
@@ -318,6 +318,7 @@ fi
%{python_sitelib}/lsm/plugin/smispy/smis_constants.*
%{python_sitelib}/lsm/plugin/smispy/smis_common.*
%{python_sitelib}/lsm/plugin/smispy/smis_cap.*
+%{python_sitelib}/lsm/plugin/smispy/smis_sys.*
%{_bindir}/smispy_lsmplugin

%files netapp-plugin
diff --git a/plugin/Makefile.am b/plugin/Makefile.am
index 30b4ea5..df411f3 100644
--- a/plugin/Makefile.am
+++ b/plugin/Makefile.am
@@ -29,7 +29,8 @@ smispy_PYTHON = \
smispy/smis_constants.py \
smispy/smis_common.py \
smispy/dmtf.py \
- smispy/smis_cap.py
+ smispy/smis_cap.py \
+ smispy/smis_sys.py

nstordir = $(plugindir)/nstor
nstor_PYTHON = \
diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
new file mode 100644
index 0000000..e1f46a5
--- /dev/null
+++ b/plugin/smispy/smis_sys.py
@@ -0,0 +1,16 @@
+## Copyright (C) 2014 Red Hat, Inc.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Author: Gris Ge <***@redhat.com>
--
1.8.3.1
Gris Ge
2014-09-25 12:58:27 UTC
Permalink
* Replace Smis._property_list_of_id(self, "System") with
smis_sys.cim_sys_id_pros()
* Replace Smis._sys_id(self, cim_sys) with
smis_sys.sys_id_of_cim_sys(cim_sys)

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 34 ++++++++++++++--------------------
plugin/smispy/smis_sys.py | 18 ++++++++++++++++++
2 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index 84537bc..c9d6919 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -30,6 +30,7 @@ import pywbem
from pywbem import CIMError
from smis_constants import *
import smis_cap
+import smis_sys

from lsm import (IStorageAreaNetwork, uri_parse, LsmError, ErrorNumber,
JobStatus, md5, Volume, AccessGroup,
@@ -427,12 +428,6 @@ class Smis(IStorageAreaNetwork):
"""
return self._id('SystemChild', cim_xxx)

- def _sys_id(self, cim_sys):
- """
- Return CIM_ComputerSystem['Name']
- """
- return self._id('System', cim_sys)
-
def _pool_id(self, cim_pool):
"""
Return CIM_StoragePool['InstanceID']
@@ -819,11 +814,11 @@ class Smis(IStorageAreaNetwork):
profile.
"""
rc = []
- cim_sys_pros = self._property_list_of_id("System")
+ cim_sys_pros = smis_sys.cim_sys_id_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)
cim_vol_pros = self._cim_vol_pros()
for cim_sys in cim_syss:
- sys_id = self._sys_id(cim_sys)
+ sys_id = smis_sys.sys_id_of_cim_sys(cim_sys)
pool_pros = self._property_list_of_id('Pool')
for cim_pool in self._cim_pools_of(cim_sys.path, pool_pros):
pool_id = self._pool_id(cim_pool)
@@ -884,11 +879,11 @@ class Smis(IStorageAreaNetwork):
rc = []
cim_pool_pros = self._new_pool_cim_pool_pros()

- cim_sys_pros = self._property_list_of_id("System")
+ cim_sys_pros = smis_sys.cim_sys_id_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)

for cim_sys in cim_syss:
- system_id = self._sys_id(cim_sys)
+ system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
for cim_pool in self._cim_pools_of(cim_sys.path, cim_pool_pros):
# Skip spare storage pool.
if 'Usage' in cim_pool and \
@@ -930,12 +925,12 @@ class Smis(IStorageAreaNetwork):
Find out the system ID for certain CIM_StoragePool.
Will return '' if failed.
"""
- sys_pros = self._property_list_of_id('System')
+ sys_pros = smis_sys.cim_sys_id_pros()
cim_syss = self._c.Associators(cim_pool.path,
ResultClass='CIM_ComputerSystem',
PropertyList=sys_pros)
if len(cim_syss) == 1:
- return self._sys_id(cim_syss[0])
+ return smis_sys.sys_id_of_cim_sys(cim_syss[0])
return ''

@handle_cim_errors
@@ -987,9 +982,8 @@ class Smis(IStorageAreaNetwork):
"""
Return a list of properties required to create a LSM System
"""
- cim_sys_pros = self._property_list_of_id('System',
- ['ElementName',
- 'OperationalStatus'])
+ cim_sys_pros = smis_sys.cim_sys_id_pros()
+ cim_sys_pros.extend(['ElementName', 'OperationalStatus'])
return cim_sys_pros

@handle_cim_errors
@@ -2054,7 +2048,7 @@ class Smis(IStorageAreaNetwork):
rc = []
mask_type = smis_cap.mask_type(self._c, raise_error=True)

- cim_sys_pros = self._property_list_of_id('System')
+ cim_sys_pros = smis_sys.cim_sys_id_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)

cim_spc_pros = self._cim_spc_pros()
@@ -2065,7 +2059,7 @@ class Smis(IStorageAreaNetwork):
# CIM_RegisteredProfile, but actually they don't support it.
mask_type = smis_cap.MASK_TYPE_MASK

- system_id = self._sys_id(cim_sys)
+ system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
if mask_type == smis_cap.MASK_TYPE_GROUP:
cim_init_mg_pros = self._cim_init_mg_pros()
cim_init_mgs = self._cim_init_mg_of(cim_sys.path,
@@ -2597,7 +2591,7 @@ class Smis(IStorageAreaNetwork):
if self.system_list:
needed_cim_syss = []
for cim_sys in cim_syss:
- if self._sys_id(cim_sys) in self.system_list:
+ if smis_sys.sys_id_of_cim_sys(cim_sys) in self.system_list:
needed_cim_syss.extend([cim_sys])
return needed_cim_syss
else:
@@ -2891,9 +2885,9 @@ class Smis(IStorageAreaNetwork):
'LinkTechnology', 'DeviceID']

cim_syss = self._root_cim_syss(
- property_list=self._property_list_of_id('System'))
+ property_list=smis_sys.cim_sys_id_pros())
for cim_sys in cim_syss:
- system_id = self._sys_id(cim_sys)
+ system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
flag_fc_support = smis_cap.fc_tgt_is_supported(self._c)
flag_iscsi_support = smis_cap.iscsi_tgt_is_supported(self._c)

diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
index e1f46a5..175bd70 100644
--- a/plugin/smispy/smis_sys.py
+++ b/plugin/smispy/smis_sys.py
@@ -14,3 +14,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Author: Gris Ge <***@redhat.com>
+
+
+def cim_sys_id_pros():
+ """
+ Return the property of CIM_ComputerSystem required to gernarate
+ lsm.System.id
+ """
+ return ['Name']
+
+
+def sys_id_of_cim_sys(cim_sys):
+ if 'Name' in cim_sys:
+ return cim_sys['Name']
+ else:
+ raise LsmError(
+ ErrorNumber.PLUGIN_BUG,
+ "sys_id_of_cim_sys(): Got a CIM_ComputerSystem does not have "
+ "'Name' property: %s, %s" % (cim_sys.items(), cim_sys.path))
--
1.8.3.1
Gris Ge
2014-09-25 12:58:28 UTC
Permalink
* Move Smis.system_list to SmisCommon.system_list to allow
other smis_sys.py to do system filtering.

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 16 ++++++++--------
plugin/smispy/smis_common.py | 3 ++-
2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index c9d6919..40cd359 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -141,7 +141,6 @@ class Smis(IStorageAreaNetwork):
def __init__(self):
self._c = None
self.tmo = 0
- self.system_list = None
self.debug_path = None

def _get_cim_instance_by_id(self, class_type, requested_id,
@@ -247,10 +246,10 @@ class Smis(IStorageAreaNetwork):
url = "%s://%s:%s" % (protocol, u['host'], port)

# System filtering
- self.system_list = None
+ system_list = None

if 'systems' in u['parameters']:
- self.system_list = split(u['parameters']["systems"], ":")
+ system_list = split(u['parameters']["systems"], ":")

namespace = None
if 'namespace' in u['parameters']:
@@ -267,7 +266,8 @@ class Smis(IStorageAreaNetwork):
debug = True

self._c = SmisCommon(
- url, u['username'], password, namespace, no_ssl_verify, debug)
+ url, u['username'], password, namespace, no_ssl_verify, debug,
+ system_list)

self.tmo = timeout

@@ -2338,8 +2338,8 @@ class Smis(IStorageAreaNetwork):
cim_disks = self._c.EnumerateInstances(
'CIM_DiskDrive', PropertyList=cim_disk_pros)
for cim_disk in cim_disks:
- if self.system_list:
- if self._sys_id_child(cim_disk) not in self.system_list:
+ if self._c.system_list:
+ if self._sys_id_child(cim_disk) not in self._c.system_list:
continue
cim_ext_pros = Smis._new_disk_cim_ext_pros(flags)
cim_ext = self._pri_cim_ext_of_cim_disk(cim_disk.path,
@@ -2588,10 +2588,10 @@ class Smis(IStorageAreaNetwork):
"to 'Array' CIM_RegisteredProfile.")

# System URI Filtering
- if self.system_list:
+ if self._c.system_list:
needed_cim_syss = []
for cim_sys in cim_syss:
- if smis_sys.sys_id_of_cim_sys(cim_sys) in self.system_list:
+ if smis_sys.sys_id_of_cim_sys(cim_sys) in self._c.system_list:
needed_cim_syss.extend([cim_sys])
return needed_cim_syss
else:
diff --git a/plugin/smispy/smis_common.py b/plugin/smispy/smis_common.py
index 6f91b20..d66286c 100644
--- a/plugin/smispy/smis_common.py
+++ b/plugin/smispy/smis_common.py
@@ -161,11 +161,12 @@ class SmisCommon(object):

def __init__(self, url, username, password,
namespace=DMTF.DEFAULT_NAMESPACE,
- no_ssl_verify=False, debug=False):
+ no_ssl_verify=False, debug=False, system_list=None):
self._wbem_conn = None
self._profile_dict = {}
self.root_blk_cim_rp = None # For root_cim_
self._vendor_product = None # For vendor workaround codes.
+ self.system_list = system_list

if namespace is None:
namespace = DMTF.DEFAULT_NAMESPACE
--
1.8.3.1
Gris Ge
2014-09-25 12:58:29 UTC
Permalink
* Replaced Smis._root_cim_syss(self) with smis_sys.root_cim_sys(smis_common)

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 57 +++++------------------------------------------
plugin/smispy/smis_sys.py | 45 +++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index 40cd359..b31db90 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -815,7 +815,7 @@ class Smis(IStorageAreaNetwork):
"""
rc = []
cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_syss = self._root_cim_syss(cim_sys_pros)
+ cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)
cim_vol_pros = self._cim_vol_pros()
for cim_sys in cim_syss:
sys_id = smis_sys.sys_id_of_cim_sys(cim_sys)
@@ -880,7 +880,7 @@ class Smis(IStorageAreaNetwork):
cim_pool_pros = self._new_pool_cim_pool_pros()

cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_syss = self._root_cim_syss(cim_sys_pros)
+ cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)

for cim_sys in cim_syss:
system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
@@ -996,7 +996,7 @@ class Smis(IStorageAreaNetwork):
profile.
"""
cim_sys_pros = self._cim_sys_pros()
- cim_syss = self._root_cim_syss(cim_sys_pros)
+ cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)

return [Smis._cim_sys_to_lsm(s) for s in cim_syss]

@@ -2049,7 +2049,7 @@ class Smis(IStorageAreaNetwork):
mask_type = smis_cap.mask_type(self._c, raise_error=True)

cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_syss = self._root_cim_syss(cim_sys_pros)
+ cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)

cim_spc_pros = self._cim_spc_pros()
for cim_sys in cim_syss:
@@ -2552,51 +2552,6 @@ class Smis(IStorageAreaNetwork):

return element_type, unsupported

- def _root_cim_syss(self, property_list=None):
- """
- Use this association to find out the root CIM_ComputerSystem
-
- CIM_RegisteredProfile # Root Profile('Array') in interop
- |
- | CIM_ElementConformsToProfile
- v
- CIM_ComputerSystem # vendor namespace
- For LSI MegaRAID, we just EnumerateInstances CIM_ComputerSystem.
- """
- cim_scss_path = []
- id_pros = self._property_list_of_id('System', property_list)
- if property_list is None:
- property_list = id_pros
- else:
- property_list = merge_list(property_list, id_pros)
-
- cim_syss = []
- if self._c.is_megaraid():
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem', PropertyList=property_list)
-
- else:
- cim_syss = self._c.Associators(
- self._c.root_blk_cim_rp.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile',
- PropertyList=property_list)
- if len(cim_syss) == 0:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Current SMI-S provider does not provide "
- "the root CIM_ComputerSystem associated "
- "to 'Array' CIM_RegisteredProfile.")
-
- # System URI Filtering
- if self._c.system_list:
- needed_cim_syss = []
- for cim_sys in cim_syss:
- if smis_sys.sys_id_of_cim_sys(cim_sys) in self._c.system_list:
- needed_cim_syss.extend([cim_sys])
- return needed_cim_syss
- else:
- return cim_syss
-
@staticmethod
def _is_frontend_fc_tgt(cim_fc_tgt):
"""
@@ -2884,8 +2839,8 @@ class Smis(IStorageAreaNetwork):
'PermanentAddress', 'PortDiscriminator',
'LinkTechnology', 'DeviceID']

- cim_syss = self._root_cim_syss(
- property_list=smis_sys.cim_sys_id_pros())
+ cim_syss = smis_sys.root_cim_sys(
+ self._c, property_list=smis_sys.cim_sys_id_pros())
for cim_sys in cim_syss:
system_id = smis_sys.sys_id_of_cim_sys(cim_sys)
flag_fc_support = smis_cap.fc_tgt_is_supported(self._c)
diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
index 175bd70..ca33d36 100644
--- a/plugin/smispy/smis_sys.py
+++ b/plugin/smispy/smis_sys.py
@@ -15,6 +15,8 @@
#
# Author: Gris Ge <***@redhat.com>

+from utils import merge_list
+

def cim_sys_id_pros():
"""
@@ -32,3 +34,46 @@ def sys_id_of_cim_sys(cim_sys):
ErrorNumber.PLUGIN_BUG,
"sys_id_of_cim_sys(): Got a CIM_ComputerSystem does not have "
"'Name' property: %s, %s" % (cim_sys.items(), cim_sys.path))
+
+
+def root_cim_sys(smis_common, property_list=None):
+ """
+ Use this association to find out the root CIM_ComputerSystem:
+ CIM_RegisteredProfile # Root Profile('Array') in interop
+ |
+ | CIM_ElementConformsToProfile
+ v
+ CIM_ComputerSystem # vendor namespace
+ """
+ id_pros = cim_sys_id_pros()
+ if property_list is None:
+ property_list = id_pros
+ else:
+ property_list = merge_list(property_list, id_pros)
+
+ cim_syss = []
+ if smis_common.is_megaraid():
+ cim_syss = smis_common.EnumerateInstances(
+ 'CIM_ComputerSystem', PropertyList=property_list)
+ else:
+ cim_syss = smis_common.Associators(
+ smis_common.root_blk_cim_rp.path,
+ ResultClass='CIM_ComputerSystem',
+ AssocClass='CIM_ElementConformsToProfile',
+ PropertyList=property_list)
+
+ if len(cim_syss) == 0:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "Current SMI-S provider does not provide "
+ "the root CIM_ComputerSystem associated "
+ "to 'Array' CIM_RegisteredProfile.")
+
+ # System URI Filtering
+ if smis_common.system_list:
+ needed_cim_syss = []
+ for cim_sys in cim_syss:
+ if sys_id_of_cim_sys(cim_sys) in smis_common.system_list:
+ needed_cim_syss.extend([cim_sys])
+ return needed_cim_syss
+ else:
+ return cim_syss
--
1.8.3.1
Gris Ge
2014-09-25 12:58:30 UTC
Permalink
* Replace Smis._cim_sys_pros(self) with smis_sys.cim_sys_pros()

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 10 +---------
plugin/smispy/smis_sys.py | 8 ++++++++
2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index b31db90..8ea318e 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -978,14 +978,6 @@ class Smis(IStorageAreaNetwork):
return System(cim_sys['Name'], cim_sys['ElementName'], status,
status_info)

- def _cim_sys_pros(self):
- """
- Return a list of properties required to create a LSM System
- """
- cim_sys_pros = smis_sys.cim_sys_id_pros()
- cim_sys_pros.extend(['ElementName', 'OperationalStatus'])
- return cim_sys_pros
-
@handle_cim_errors
def systems(self, flags=0):
"""
@@ -995,7 +987,7 @@ class Smis(IStorageAreaNetwork):
don't check support status here as startup() already checked 'Array'
profile.
"""
- cim_sys_pros = self._cim_sys_pros()
+ cim_sys_pros = smis_sys.cim_sys_pros()
cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)

return [Smis._cim_sys_to_lsm(s) for s in cim_syss]
diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
index ca33d36..d14ecde 100644
--- a/plugin/smispy/smis_sys.py
+++ b/plugin/smispy/smis_sys.py
@@ -77,3 +77,11 @@ def root_cim_sys(smis_common, property_list=None):
return needed_cim_syss
else:
return cim_syss
+
+def cim_sys_pros():
+ """
+ Return a list of properties required to create a LSM System
+ """
+ cim_sys_pros = cim_sys_id_pros()
+ cim_sys_pros.extend(['ElementName', 'OperationalStatus'])
+ return cim_sys_pros
--
1.8.3.1
Gris Ge
2014-09-25 12:58:31 UTC
Permalink
* Make DMTF._dmtf_op_status_list_conv() public as
DMTF.dmtf_op_status_list_conv().

* Move DMTF.cim_sys_status_of() to smis_sys._sys_status_of_cim_sys().
# Only used in smis_sys internally, hence hide from public.

* Move Smis._cim_sys_to_lsm() to smis_sys.cim_sys_to_lsm_sys()

* Add DMTF.OP_STATUS_UNKNOWN -> System.STATUS_UNKNOWN map.
Found EMC SMI-S provider will use 0(Unknown) for outdated system.

* Including smis_sys._sys_status_of_cim_sys() and
smis_sys.cim_sys_to_lsm_sys() changes in one patch as
_sys_status_of_cim_sys() is only used by smis_sys.cim_sys_to_lsm_sys().

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/dmtf.py | 25 ++++---------------------
plugin/smispy/smis.py | 16 +---------------
plugin/smispy/smis_sys.py | 42 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/plugin/smispy/dmtf.py b/plugin/smispy/dmtf.py
index 2bea0fe..d020a9a 100644
--- a/plugin/smispy/dmtf.py
+++ b/plugin/smispy/dmtf.py
@@ -77,17 +77,8 @@ class DMTF(object):
except KeyError:
return ''

- _LSM_SYS_OP_STATUS_CONV = {
- OP_STATUS_OK: System.STATUS_OK,
- OP_STATUS_ERROR: System.STATUS_ERROR,
- OP_STATUS_DEGRADED: System.STATUS_DEGRADED,
- OP_STATUS_NON_RECOVERABLE_ERROR: System.STATUS_ERROR,
- OP_STATUS_PREDICTIVE_FAILURE: System.STATUS_PREDICTIVE_FAILURE,
- OP_STATUS_SUPPORTING_ENTITY_IN_ERROR: System.STATUS_ERROR,
- }
-
@staticmethod
- def _dmtf_op_status_list_conv(conv_dict, dmtf_op_status_list,
+ def dmtf_op_status_list_conv(conv_dict, dmtf_op_status_list,
unknown_value, other_value):
status = 0
status_info_list = []
@@ -104,14 +95,6 @@ class DMTF(object):
status = unknown_value
return status, " ".join(status_info_list)

- @staticmethod
- def cim_sys_status_of(dmtf_op_status_list):
- """
- Convert CIM_ComputerSystem['OperationalStatus']
- """
- return DMTF._dmtf_op_status_list_conv(
- DMTF._LSM_SYS_OP_STATUS_CONV, dmtf_op_status_list,
- System.STATUS_UNKNOWN, System.STATUS_OTHER)

_LSM_POOL_OP_STATUS_CONV = {
OP_STATUS_OK: Pool.STATUS_OK,
@@ -126,7 +109,7 @@ class DMTF(object):
"""
Convert CIM_StoragePool['OperationalStatus'] to LSM
"""
- return DMTF._dmtf_op_status_list_conv(
+ return DMTF.dmtf_op_status_list_conv(
DMTF._LSM_POOL_OP_STATUS_CONV, dmtf_op_status_list,
Pool.STATUS_UNKNOWN, Pool.STATUS_OTHER)

@@ -149,7 +132,7 @@ class DMTF(object):
Convert CIM_DiskDrive['OperationalStatus'] to LSM
Only return status, no status_info
"""
- return DMTF._dmtf_op_status_list_conv(
+ return DMTF.dmtf_op_status_list_conv(
DMTF._LSM_DISK_OP_STATUS_CONV, dmtf_op_status_list,
Disk.STATUS_UNKNOWN, Disk.STATUS_OTHER)[0]

@@ -278,4 +261,4 @@ DMTF_STATUS_ABORTED = 14
DMTF_STATUS_DORMANT = 15
DMTF_STATUS_SUPPORTING_ENTITY_IN_ERROR = 16
DMTF_STATUS_COMPLETED = 17
-DMTF_STATUS_POWER_MODE = 18
\ No newline at end of file
+DMTF_STATUS_POWER_MODE = 18
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index 8ea318e..7815ace 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -964,20 +964,6 @@ class Smis(IStorageAreaNetwork):
total_space, free_space,
status, status_info, system_id)

- @staticmethod
- def _cim_sys_to_lsm(cim_sys):
- # In the case of systems we are assuming that the System Name is
- # unique.
- status = System.STATUS_UNKNOWN
- status_info = ''
-
- if 'OperationalStatus' in cim_sys:
- (status, status_info) = \
- DMTF.cim_sys_status_of(cim_sys['OperationalStatus'])
-
- return System(cim_sys['Name'], cim_sys['ElementName'], status,
- status_info)
-
@handle_cim_errors
def systems(self, flags=0):
"""
@@ -990,7 +976,7 @@ class Smis(IStorageAreaNetwork):
cim_sys_pros = smis_sys.cim_sys_pros()
cim_syss = smis_sys.root_cim_sys(self._c, cim_sys_pros)

- return [Smis._cim_sys_to_lsm(s) for s in cim_syss]
+ return [smis_sys.cim_sys_to_lsm_sys(s) for s in cim_syss]

def _check_for_dupe_vol(self, volume_name, original_exception):
"""
diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
index d14ecde..287269c 100644
--- a/plugin/smispy/smis_sys.py
+++ b/plugin/smispy/smis_sys.py
@@ -16,6 +16,8 @@
# Author: Gris Ge <***@redhat.com>

from utils import merge_list
+from dmtf import DMTF
+from lsm import System


def cim_sys_id_pros():
@@ -78,6 +80,7 @@ def root_cim_sys(smis_common, property_list=None):
else:
return cim_syss

+
def cim_sys_pros():
"""
Return a list of properties required to create a LSM System
@@ -85,3 +88,42 @@ def cim_sys_pros():
cim_sys_pros = cim_sys_id_pros()
cim_sys_pros.extend(['ElementName', 'OperationalStatus'])
return cim_sys_pros
+
+
+_LSM_SYS_OP_STATUS_CONV = {
+ DMTF.OP_STATUS_UNKNOWN: System.STATUS_UNKNOWN,
+ DMTF.OP_STATUS_OK: System.STATUS_OK,
+ DMTF.OP_STATUS_ERROR: System.STATUS_ERROR,
+ DMTF.OP_STATUS_DEGRADED: System.STATUS_DEGRADED,
+ DMTF.OP_STATUS_NON_RECOVERABLE_ERROR: System.STATUS_ERROR,
+ DMTF.OP_STATUS_PREDICTIVE_FAILURE: System.STATUS_PREDICTIVE_FAILURE,
+ DMTF.OP_STATUS_SUPPORTING_ENTITY_IN_ERROR: System.STATUS_ERROR,
+}
+
+
+def _sys_status_of_cim_sys(cim_sys):
+ """
+ Convert CIM_ComputerSystem['OperationalStatus']
+ """
+ if 'OperationalStatus' not in cim_sys:
+ raise LsmError(
+ ErrorNumber.PLUGIN_BUG,
+ "sys_status_of_cim_sys(): Got a CIM_ComputerSystem with no "
+ "OperationalStatus: %s, %s" % (cim_sys.items(), cim_sys.path))
+
+ return DMTF.dmtf_op_status_list_conv(
+ _LSM_SYS_OP_STATUS_CONV, cim_sys['OperationalStatus'],
+ System.STATUS_UNKNOWN, System.STATUS_OTHER)
+
+
+def cim_sys_to_lsm_sys(cim_sys):
+ status = System.STATUS_UNKNOWN
+ status_info = ''
+
+ if 'OperationalStatus' in cim_sys:
+ (status, status_info) = _sys_status_of_cim_sys(cim_sys)
+
+ sys_id = sys_id_of_cim_sys(cim_sys)
+ sys_name = cim_sys['ElementName']
+
+ return System(sys_id, sys_name, status, status_info)
--
1.8.3.1
Gris Ge
2014-09-25 12:58:32 UTC
Permalink
* Replace Smis._get_cim_instance_by_id("System") with
smis_sys.cim_sys_of_sys_id()

* Fix the bug when query filtered system.
Example:

URI: smispy://***@emc-smi?systems=CLARiiON+APM00041704073
CMD: lsmcli capabilities --sys CLARiiON+FCN00122500421

Expected result:
lsmcli should report system not found as URI already filter that
requested system out.

Actual result:
lsmcli got capabilities of filtered system.

Fix:
Replace EnumerateInstances("CIM_ComputerSystem") with
smis_sys.root_cim_sys() which implemented the system filter.

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 49 +++++++++++++++--------------------------------
plugin/smispy/smis_sys.py | 22 ++++++++++++++++++++-
2 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index 7815ace..fc231dd 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -285,8 +285,7 @@ class Smis(IStorageAreaNetwork):

@handle_cim_errors
def capabilities(self, system, flags=0):
- cim_sys = self._get_cim_instance_by_id(
- 'System', system.id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, system.id)
return smis_cap.get(self._c, cim_sys, system)

@handle_cim_errors
@@ -358,8 +357,6 @@ class Smis(IStorageAreaNetwork):
def _cim_class_name_of(class_type):
if class_type == 'Volume':
return 'CIM_StorageVolume'
- if class_type == 'System':
- return 'CIM_ComputerSystem'
if class_type == 'Pool':
return 'CIM_StoragePool'
if class_type == 'Disk':
@@ -378,8 +375,6 @@ class Smis(IStorageAreaNetwork):
def _not_found_error_of_class(class_type):
if class_type == 'Volume':
return ErrorNumber.NOT_FOUND_VOLUME
- if class_type == 'System':
- return ErrorNumber.NOT_FOUND_SYSTEM
if class_type == 'Pool':
return ErrorNumber.NOT_FOUND_POOL
if class_type == 'Job':
@@ -400,8 +395,6 @@ class Smis(IStorageAreaNetwork):
rc = []
if class_type == 'Volume':
rc = ['SystemName', 'DeviceID']
- elif class_type == 'System':
- rc = ['Name']
elif class_type == 'Pool':
rc = ['InstanceID']
elif class_type == 'SystemChild':
@@ -1466,8 +1459,7 @@ class Smis(IStorageAreaNetwork):
target ports(all FC and FCoE port for access_group.init_type == WWPN,
and the same to iSCSI)
"""
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)

cim_init_mg = self._cim_init_mg_of_id(access_group.id,
raise_error=True)
@@ -1549,8 +1541,7 @@ class Smis(IStorageAreaNetwork):
mask_type = smis_cap.mask_type(self._c, raise_error=True)
# Workaround for EMC VNX/CX
if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = smis_cap.MASK_TYPE_MASK

@@ -1569,8 +1560,7 @@ class Smis(IStorageAreaNetwork):
access_group.id +
"will not do volume_mask()")

- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
cim_css_path = self._c.get_cim_service_path(
cim_sys.path, 'CIM_ControllerConfigurationService')

@@ -1598,8 +1588,7 @@ class Smis(IStorageAreaNetwork):
"""
cim_vol = self._get_cim_instance_by_id(
'Volume', volume.id, raise_error=True)
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)

cim_gmm_cap = self._c.Associators(
cim_sys.path,
@@ -1693,8 +1682,7 @@ class Smis(IStorageAreaNetwork):
mask_type = smis_cap.mask_type(self._c, raise_error=True)
# Workaround for EMC VNX/CX
if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = smis_cap.MASK_TYPE_MASK

@@ -1703,8 +1691,7 @@ class Smis(IStorageAreaNetwork):
return self._volume_unmask_old(access_group, volume)

def _volume_unmask_old(self, access_group, volume):
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)
cim_ccs_path = self._c.get_cim_service_path(
cim_sys.path, 'CIM_ControllerConfigurationService')

@@ -1896,8 +1883,8 @@ class Smis(IStorageAreaNetwork):

# Workaround for EMC VNX/CX
if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(
+ self._c, access_group.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = smis_cap.MASK_TYPE_MASK

@@ -1936,8 +1923,7 @@ class Smis(IStorageAreaNetwork):

# Workaround for EMC VNX/CX
if mask_type == smis_cap.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, volume.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = smis_cap.MASK_TYPE_MASK

@@ -2096,8 +2082,7 @@ class Smis(IStorageAreaNetwork):
expect_class='CIM_StorageHardwareID')

def _ag_init_add_group(self, access_group, init_id, init_type):
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)

if cim_sys.path.classname == 'Clar_StorageSystem':
raise LsmError(ErrorNumber.NO_SUPPORT,
@@ -2154,8 +2139,7 @@ class Smis(IStorageAreaNetwork):
def _ag_init_add_old(self, access_group, init_id, init_type):
# CIM_StorageHardwareIDManagementService.CreateStorageHardwareID()
# is mandatory since 1.4rev6
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)

if cim_sys.path.classname == 'Clar_StorageSystem':
raise LsmError(ErrorNumber.NO_SUPPORT,
@@ -2201,8 +2185,7 @@ class Smis(IStorageAreaNetwork):
Call CIM_GroupMaskingMappingService.RemoveMembers() against
CIM_InitiatorMaskingGroup.
"""
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)

cim_init_mg_pros = self._cim_init_mg_pros()
cim_init_mg = self._cim_init_mg_of_id(
@@ -2263,8 +2246,7 @@ class Smis(IStorageAreaNetwork):
return self._ag_init_del_old(access_group, init_id)

def _ag_init_del_old(self, access_group, init_id):
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, access_group.system_id)

cim_spc = self._cim_spc_of_id(access_group.id, raise_error=True)

@@ -3042,8 +3024,7 @@ class Smis(IStorageAreaNetwork):
"SMI-S plugin only support creating FC/FCoE WWPN "
"and iSCSI AccessGroup")

- cim_sys = self._get_cim_instance_by_id(
- 'System', system.id, raise_error=True)
+ cim_sys = smis_sys.cim_sys_of_sys_id(self._c, system.id)
if cim_sys.path.classname == 'Clar_StorageSystem':
# EMC VNX/CX does not support Group M&M, which incorrectly exposed
# in CIM_RegisteredProfile
diff --git a/plugin/smispy/smis_sys.py b/plugin/smispy/smis_sys.py
index 287269c..683ae2b 100644
--- a/plugin/smispy/smis_sys.py
+++ b/plugin/smispy/smis_sys.py
@@ -17,7 +17,7 @@

from utils import merge_list
from dmtf import DMTF
-from lsm import System
+from lsm import System, LsmError, ErrorNumber


def cim_sys_id_pros():
@@ -127,3 +127,23 @@ def cim_sys_to_lsm_sys(cim_sys):
sys_name = cim_sys['ElementName']

return System(sys_id, sys_name, status, status_info)
+
+
+def cim_sys_of_sys_id(smis_common, sys_id, property_list=None):
+ """
+ Find out the CIM_ComputerSystem for given lsm.System.id using
+ root_cim_sys()
+ """
+ id_pros = cim_sys_id_pros()
+ if property_list is None:
+ property_list = id_pros
+ else:
+ property_list = merge_list(property_list, id_pros)
+
+ cim_syss = root_cim_sys(smis_common, property_list)
+ for cim_sys in cim_syss:
+ if sys_id_of_cim_sys(cim_sys) == sys_id:
+ return cim_sys
+ raise LsmError(
+ ErrorNumber.NOT_FOUND_SYSTEM,
+ "Not found System")
--
1.8.3.1
Tony Asleson
2014-09-25 20:37:07 UTC
Permalink
Looks good, any concerns with me committing any of the outstanding patch
sets?

Thanks,
Tony
Post by Gris Ge
New smis_sys.py file to contain all lsm.System related methods including
the CIM_ComputerSystem to lsm.System converter method.
* [V2 0/3] Move capablities to separate file
* [PATCH V3 00/10] SMI-S plugin: Reorganize code layout.
* plugin interface.
Example A: Get all cim_pool.
Step 1: This require list all cim_sys first.1]
Step 2: Then find all associated cim_pool.
# Step 1 is in smis_sys.py
# Step 2 will be in smis_pool.py
# As smis_pool.py cannot depend on smis_sys.py[1],
# smis.py has to combine these two steps to provide all
# cim_pools.
Example B: job_status() for volume_create()
* Common job handling will be in smis_common.py like query
CIM_ConcreteJob and use CIM_AffectedJobElement to get cim_pool.
* Converting cim_pool to lsm.Pool will be in smis_pool.py
# As smis_common cannot depend on smis_pool[1],
# A method like _new_vol_from_job() has to be placed in smis.py,
# not smis_common.py or smis_pool.py
smis_sys: lsm.System
smis_pool: lsm.Pool
smis_vol: lsm.Volume and volume_mask() _unmask()
smis_ag: lsm.AccessGroup
[1] In case of looping requirement.
SMI-S Plugin: Add smis_sys.py to smis-s plugin.
SMI-S Plugin: Move lsm.System.id generator to smis_sys.py
SMI-S Plugin: Move URI system filter to SmisCommon
SMI-S Plugin: Move Smis._root_cim_syss() to smis_sys.py
SMI-S Plugin: Move Smis._cim_sys_pros() to smis_sys.py
SMI-S Plugin: Move System converter to smis_sys.py
SMI-S Plugin: Improve cim_sys query on system_id
packaging/libstoragemgmt.spec.in | 1 +
plugin/Makefile.am | 3 +-
plugin/smispy/dmtf.py | 25 +-----
plugin/smispy/smis.py | 170 +++++++++------------------------------
plugin/smispy/smis_common.py | 3 +-
plugin/smispy/smis_sys.py | 149 ++++++++++++++++++++++++++++++++++
6 files changed, 197 insertions(+), 154 deletions(-)
create mode 100644 plugin/smispy/smis_sys.py
Gris Ge
2014-09-26 05:21:35 UTC
Permalink
Post by Tony Asleson
Looks good, any concerns with me committing any of the outstanding patch
sets?
Thanks,
Tony
Hi Tony,

Can you allow me to finish the smis_pool.py?
Only after that can I really say whether this layout works or not.

Thank you for the review.
--
Gris Ge
Tony Asleson
2014-09-26 13:36:49 UTC
Permalink
Post by Gris Ge
Can you allow me to finish the smis_pool.py?
Only after that can I really say whether this layout works or not.
OK, will do, thanks!

-Tony

Loading...