Discussion:
[Libstoragemgmt-devel] [PATCH 0/5] C and Python Library: Add flag for querying optional data
Gris Ge
2014-06-08 07:43:00 UTC
Permalink
Please check detail comments in each patches.

Thanks for reviewing this patch set.

Gris Ge (5):
C & Python Libaray: Add FLAG_RETRIEVE_FULL_INFO for query methods
Plugins: Sync with FLAG_RETRIEVE_FULL_INFO changes
lsmcli: Sync with FLAG_RETRIEVE_FULL_INFO changes
lsmcli: Fix optional property displaying
cmdtest.py: Add a simple optional data query test

c_binding/include/libstoragemgmt/libstoragemgmt.h | 22 +++++++----
.../include/libstoragemgmt/libstoragemgmt_types.h | 43 +++++++++++++++++++++-
plugin/ontap/ontap.py | 8 ++--
plugin/sim/simarray.py | 10 ++---
plugin/smispy/smis.py | 12 +++---
python_binding/lsm/_client.py | 4 +-
python_binding/lsm/_data.py | 14 ++++---
test/cmdtest.py | 15 +++++++-
tools/lsmcli/cmdline.py | 37 ++++++++++++-------
tools/lsmcli/data_display.py | 6 +++
10 files changed, 125 insertions(+), 46 deletions(-)
--
1.8.3.1
Gris Ge
2014-06-08 07:43:01 UTC
Permalink
* Python, added these constants:
System.FLAG_RETRIEVE_FULL_INFO
Pool.FLAG_RETRIEVE_FULL_INFO
# This is a rename.
Volume.FLAG_RETRIEVE_FULL_INFO
Disk.FLAG_RETRIEVE_FULL_INFO
# This is a rename and value change from 2 to '1 << 0'
AccessGroup.FLAG_RETRIEVE_FULL_INFO
FileSystem.FLAG_RETRIEVE_FULL_INFO
NfsExport.FLAG_RETRIEVE_FULL_INFO

* C, added these constants:
LSM_SYSTEM_FLAG_RETRIEVE_FULL_INFO
LSM_POOL_FLAG_RETRIEVE_FULL_INFO
LSM_VOLUME_FLAG_RETRIEVE_FULL_INFO
LSM_DISK_FLAG_RETRIEVE_FULL_INFO
LSM_ACCESS_GROUP_FLAG_RETRIEVE_FULL_INFO
LSM_FS_FLAG_RETRIEVE_FULL_INFO
LSM_NFS_FLAG_RETRIEVE_FULL_INFO

Signed-off-by: Gris Ge <***@redhat.com>
---
c_binding/include/libstoragemgmt/libstoragemgmt.h | 22 +++++++----
.../include/libstoragemgmt/libstoragemgmt_types.h | 43 +++++++++++++++++++++-
python_binding/lsm/_client.py | 4 +-
python_binding/lsm/_data.py | 14 ++++---
4 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt.h b/c_binding/include/libstoragemgmt/libstoragemgmt.h
index af082b9..ec995d8 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt.h
@@ -230,7 +230,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] pool_array Array of storage pools
* @param[out] count Number of storage pools
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_POOL_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error reason
*/
int LSM_DLL_EXPORT lsm_pool_list(lsm_connect *conn, char *search_key,
@@ -371,7 +372,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] volumes An array of lsm_volume
* @param[out] count Number of elements in the lsm_volume array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_VOLUME_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error reason
*/
int LSM_DLL_EXPORT lsm_volume_list(lsm_connect *conn,
@@ -388,8 +390,8 @@ extern "C" {
* @param[in] search_value Search value
* @param [out] disks An array of lsm_disk types
* @param [out] count Number of disks
- * @param [in] flags Use LSM_DISK_RETRIEVE_FULL_INFO for all
- * data, else 0
+ * @param [in] flags Use LSM_DISK_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error reason
*/
int LSM_DLL_EXPORT lsm_disk_list(lsm_connect *conn, const char * search_key,
@@ -568,7 +570,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] groups Array of access groups
* @param[out] group_count Size of array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_ACCESS_GROUP_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason.
*/
int LSM_DLL_EXPORT lsm_access_group_list(lsm_connect *conn,
@@ -753,7 +756,8 @@ extern "C" {
* @param[in] conn Valid connection
* @param[out] systems Array of lsm_system
* @param[out] system_count Number of systems
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_SYSTEM_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason
*/
int LSM_DLL_EXPORT lsm_system_list(lsm_connect *conn, lsm_system **systems[],
@@ -766,7 +770,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] fs Array of lsm_fs
* @param[out] fs_count Number of file systems
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_FS_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason
*/
int LSM_DLL_EXPORT lsm_fs_list(lsm_connect *conn, const char *search_key,
@@ -959,7 +964,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] exports An array of lsm_nfs_export
* @param[out] count Number of items in array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_NFS_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error code.
*/
int LSM_DLL_EXPORT lsm_nfs_list(lsm_connect *c, const char *search_key,
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
index eb22df4..8484a13 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
@@ -152,6 +152,12 @@ typedef enum {
#define LSM_VOLUME_OP_STATUS_DORMANT 0x10 /**< Volume is inactive or quiesced */

/**
+ * Used by 'flags' parameter of lsm_volume_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_VOLUME_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
+/**
* Different states a system status can be in.
* Bit field, can be in multiple states at the same time.
*/
@@ -166,6 +172,13 @@ typedef enum {
#define LSM_SYSTEM_STATUS_STOPPED 0x00000100 /**< Stopped by admin */
#define LSM_SYSTEM_STATUS_OTHER 0x00000200 /**< Vendor specific */

+
+/**
+ * Used by 'flags' parameter of lsm_system_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_SYSTEM_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
/**< \enum lsm_initiator_type Different types of initiator IDs */
typedef enum {
LSM_INITIATOR_OTHER = 1, /**< Other or unspecified */
@@ -187,6 +200,12 @@ typedef enum {
INIT_TYPE_ISCSI_WWPN_MIXED = 7 /**< More than 1 type */
} lsm_access_group_init_type;

+/**
+ * Used by 'flags' parameter of lsm_access_group_list() function to
+ * retrieve optional data also.
+ */
+#define LSM_ACCESS_GROUP_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
/**< \enum lsm_job_type Different types of jobs */
typedef enum {
LSM_JOB_VOL_CREATE = 1, /**< Volume create */
@@ -214,7 +233,11 @@ typedef enum {
LSM_DISK_TYPE_SCSI = 8
} lsm_disk_type;

-#define LSM_DISK_RETRIEVE_FULL_INFO 0x02
+/**
+ * Used by 'flags' parameter of lsm_disk_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_DISK_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001

#define LSM_DISK_STATUS_UNKNOWN 0x0000000000000001
#define LSM_DISK_STATUS_OK 0x0000000000000002
@@ -247,6 +270,12 @@ typedef enum {
#define LSM_POOL_STATUS_SHRINKING 0x0000000000010000
#define LSM_POOL_STATUS_DESTROYING 0x0000000000020000

+/**
+ * Used by 'flags' parameter of lsm_pool_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_POOL_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
typedef enum {
LSM_POOL_MEMBER_TYPE_UNKNOWN = 0,
LSM_POOL_MEMBER_TYPE_DISK = 1,
@@ -285,6 +314,18 @@ typedef enum {
LSM_POOL_RAID_TYPE_MIXED = 23
} lsm_pool_raid_type;

+/**
+ * Used by 'flags' parameter of lsm_fs_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_FS_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
+/**
+ * Used by 'flags' parameter of lsm_nfs_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_NFS_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
#ifdef __cplusplus
}
#endif
diff --git a/python_binding/lsm/_client.py b/python_binding/lsm/_client.py
index 11acd01..3942b8d 100644
--- a/python_binding/lsm/_client.py
+++ b/python_binding/lsm/_client.py
@@ -284,7 +284,7 @@ class Client(INetworkAttachedStorage):

## Returns an array of pool objects.
# @param self The this pointer
- # @param flags When equal to Pool.RETRIEVE_FULL_INFO,
+ # @param flags When equal to Pool.FLAG_RETRIEVE_FULL_INFO,
# returned objects will contain optional data.
# If not defined, only the mandatory properties will
# returned.
@@ -671,7 +671,7 @@ class Client(INetworkAttachedStorage):

## Returns an array of disk objects
# @param self The this pointer
- # @param flags When equal to DISK.RETRIEVE_FULL_INFO
+ # @param flags When equal to DISK.FLAG_RETRIEVE_FULL_INFO
# returned objects will contain optional data.
# If not defined, only the mandatory properties will
# be returned.
diff --git a/python_binding/lsm/_data.py b/python_binding/lsm/_data.py
index e10b982..dbb293d 100644
--- a/python_binding/lsm/_data.py
+++ b/python_binding/lsm/_data.py
@@ -208,7 +208,7 @@ class Disk(IData):
Represents a disk.
"""
SUPPORTED_SEARCH_KEYS = ['id', 'system_id']
- RETRIEVE_FULL_INFO = 2 # Used by _client.py for disks() call.
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0

# We use '-1' to indicate we failed to get the requested number.
# For example, when block found is undetectable, we use '-1' instead of
@@ -342,6 +342,8 @@ class Volume(IData):
"""
Represents a volume.
"""
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
+
SUPPORTED_SEARCH_KEYS = ['id', 'system_id', 'pool_id']
# Volume status Note: Volumes can have multiple status bits set at same
# time.
@@ -467,6 +469,8 @@ The lsm.System class does not have any extra constants.

The lsm.System class does not have class methods.
"""
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
+
STATUS_UNKNOWN = 1 << 0
STATUS_OK = 1 << 1
STATUS_ERROR = 1 << 2
@@ -502,9 +506,7 @@ class Pool(IData):
"""
Pool specific information
"""
- RETRIEVE_FULL_INFO = 1 # Used by _client.py for pools() call.
- # This might not be a good place, please
- # suggest a better one.
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'system_id']

TOTAL_SPACE_NOT_FOUND = -1
@@ -726,6 +728,7 @@ class Pool(IData):
@default_property("optional_data", "Optional data")
@default_property("plugin_data", "Private plugin data")
class FileSystem(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'system_id', 'pool_id']

def __init__(self, _id, _name, _total_space, _free_space, _pool_id,
@@ -764,6 +767,7 @@ class FsSnapshot(IData):
@default_property('optional_data', doc="Optional data")
@default_property('plugin_data', doc="Plugin private data")
class NfsExport(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'fs_id']
ANON_UID_GID_NA = -1
ANON_UID_GID_ERROR = (ANON_UID_GID_NA - 1)
@@ -789,7 +793,6 @@ class NfsExport(IData):
self._plugin_data = _plugin_data


-
@default_property('src_block', doc="Source logical block address")
@default_property('dest_block', doc="Destination logical block address")
@default_property('block_count', doc="Number of blocks")
@@ -808,6 +811,7 @@ class BlockRange(IData):
@default_property('optional_data', doc="Optional data")
@default_property('plugin_data', doc="Plugin private data")
class AccessGroup(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'system_id']

INIT_TYPE_UNKNOWN = 0
--
1.8.3.1
Gris Ge
2014-06-08 07:43:02 UTC
Permalink
* The 'flags' argument of query methods is now a bitmap. We change plugin
to use '&' instead of '=='.
* Sync plugins with FLAG_RETRIEVE_FULL_INFO changes.

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/ontap/ontap.py | 8 ++++----
plugin/sim/simarray.py | 10 +++++-----
plugin/smispy/smis.py | 12 ++++++------
3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index d97bfe7..a242668 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -290,7 +290,7 @@ class Ontap(IStorageAreaNetwork, INfs):
def _disk(self, d, flag):
opt_data = OptionalData()
status = Ontap._status_of_na_disk(d)
- if flag == Disk.RETRIEVE_FULL_INFO:
+ if flag & Disk.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('sn', d['serial-number'])
opt_data.set('model', d['disk-model'])
opt_data.set('vendor', d['vendor-id'])
@@ -358,7 +358,7 @@ class Ontap(IStorageAreaNetwork, INfs):
system_id = self.sys_info.id
status = self._status_of_na_aggr(na_aggr)
opt_data = OptionalData()
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('member_type', Pool.MEMBER_TYPE_DISK)
member_ids = []
for na_disk in na_disks:
@@ -415,7 +415,7 @@ class Ontap(IStorageAreaNetwork, INfs):
system_id = self.sys_info.id
status = self._status_of_na_vol(na_vol)
opt_data = OptionalData()
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('member_type', Pool.MEMBER_TYPE_POOL)
parent_aggr_name = na_vol['containing-aggregate']
for na_aggr in na_aggrs:
@@ -502,7 +502,7 @@ class Ontap(IStorageAreaNetwork, INfs):
na_disks = []
# We do extra flags check in order to save self.f.disks() calls
# in case we have multiple aggregates.
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
na_disks = self.f.disks()
for na_aggr in na_aggrs:
pools.extend([self._pool_from_na_aggr(na_aggr, na_disks, flags)])
diff --git a/plugin/sim/simarray.py b/plugin/sim/simarray.py
index f530763..10cfc27 100644
--- a/plugin/sim/simarray.py
+++ b/plugin/sim/simarray.py
@@ -159,7 +159,7 @@ class SimArray(object):
status_info = sim_pool['status_info']
sys_id = sim_pool['sys_id']
opt_data = OptionalData()
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('raid_type', sim_pool['raid_type'])
opt_data.set('member_type', sim_pool['member_type'])
opt_data.set('member_ids', sim_pool['member_ids'])
@@ -182,28 +182,28 @@ class SimArray(object):
sim_pool = self.data.pool_create(
sys_id, pool_name, size_bytes, raid_type, member_type, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_create_from_disks(self, sys_id, pool_name, disks_ids, raid_type,
flags=0):
sim_pool = self.data.pool_create_from_disks(
sys_id, pool_name, disks_ids, raid_type, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_create_from_volumes(self, sys_id, pool_name, member_ids,
raid_type, flags=0):
sim_pool = self.data.pool_create_from_volumes(
sys_id, pool_name, member_ids, raid_type, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_create_from_pool(self, sys_id, pool_name, member_id, size_bytes,
flags=0):
sim_pool = self.data.pool_create_from_pool(
sys_id, pool_name, member_id, size_bytes, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_delete(self, pool_id, flags=0):
return self.data.job_create(self.data.pool_delete(pool_id, flags))[0]
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index b2da486..baac1b1 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -1494,7 +1494,7 @@ class Smis(IStorageAreaNetwork):
"""
rc = []
cim_pool_pros = self._new_pool_cim_pool_pros(
- flags == Pool.RETRIEVE_FULL_INFO)
+ flags & Pool.FLAG_RETRIEVE_FULL_INFO)

cim_sys_pros = self._property_list_of_id("System")
cim_syss = self._root_cim_syss(cim_sys_pros)
@@ -1531,7 +1531,7 @@ class Smis(IStorageAreaNetwork):
pool = self._new_pool(cim_pool, system_id)
if pool:
rc.extend([pool])
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_pro_dict = self._pool_opt_data(cim_pool)
for key, value in opt_pro_dict.items():
pool.optional_data.set(key, value)
@@ -2332,7 +2332,7 @@ class Smis(IStorageAreaNetwork):
"""
pros = ['OperationalStatus', 'Name', 'SystemName',
'Caption', 'InterconnectType', 'DiskType']
- if flag == Disk.RETRIEVE_FULL_INFO:
+ if flag & Disk.FLAG_RETRIEVE_FULL_INFO:
pros.extend(['ErrorDescription', 'ErrorCleared'])
return pros

@@ -2351,8 +2351,8 @@ class Smis(IStorageAreaNetwork):
object.
"""
pros = [] # we don't need CIM_PhysicalPackage when not
- # RETRIEVE_FULL_INFO
- if flag == Disk.RETRIEVE_FULL_INFO:
+ # FLAG_RETRIEVE_FULL_INFO
+ if flag & Disk.FLAG_RETRIEVE_FULL_INFO:
pros.extend(['SerialNumber', 'PartNumber', 'Manufacturer',
'Model'])
return pros
@@ -2436,7 +2436,7 @@ class Smis(IStorageAreaNetwork):
disk_type = Disk.DISK_TYPE_SAS

optionals = OptionalData()
- if flag_full_info == Disk.RETRIEVE_FULL_INFO:
+ if flag_full_info & Disk.FLAG_RETRIEVE_FULL_INFO:
opt_pro_dict = {
'sn': '',
'part_num': '',
--
1.8.3.1
Gris Ge
2014-06-08 07:43:03 UTC
Permalink
* lsmcli: Sync with FLAG_RETRIEVE_FULL_INFO changes

Signed-off-by: Gris Ge <***@redhat.com>
---
tools/lsmcli/cmdline.py | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/tools/lsmcli/cmdline.py b/tools/lsmcli/cmdline.py
index 3a292b2..a1ccded 100644
--- a/tools/lsmcli/cmdline.py
+++ b/tools/lsmcli/cmdline.py
@@ -29,7 +29,7 @@ from argparse import RawTextHelpFormatter
from lsm import (Client, Pool, VERSION, LsmError, Capabilities, Disk,
Initiator, Volume, JobStatus, ErrorNumber, BlockRange,
uri_parse, Proxy, size_human_2_size_bytes,
- AccessGroup, FileSystem, NfsExport)
+ AccessGroup, FileSystem, NfsExport, System, FsSnapshot)

from lsm.lsmcli.data_display import (
DisplayData, PlugData, out,
@@ -925,6 +925,7 @@ class CmdLine:
def list(self, args):
search_key = None
search_value = None
+ flags = 0
if args.sys:
search_key = 'system_id'
search_value = args.sys
@@ -948,81 +949,91 @@ class CmdLine:
search_value = args.nfs_export

if args.type == 'VOLUMES':
+ if args.all:
+ flags |= Volume.FLAG_RETRIEVE_FULL_INFO
if search_key == 'volume_id':
search_key = 'id'
if search_key == 'access_group_id':
lsm_ag = _get_item(self.c.access_groups(), args.ag,
"Access Group ID")
return self.display_data(
- self.c.volumes_accessible_by_access_group(lsm_ag))
+ self.c.volumes_accessible_by_access_group(lsm_ag, flags))
elif search_key and search_key not in Volume.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"volume listing." % search_key)
- self.display_data(self.c.volumes(search_key, search_value))
+ self.display_data(self.c.volumes(search_key, search_value, flags))
elif args.type == 'POOLS':
if search_key == 'pool_id':
search_key = 'id'
if search_key and search_key not in Pool.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"pool listing." % search_key)
- flags = 0
if args.all:
- flags |= Pool.RETRIEVE_FULL_INFO
+ flags |= Pool.FLAG_RETRIEVE_FULL_INFO
self.display_data(
self.c.pools(search_key, search_value, flags))
elif args.type == 'FS':
+ if args.all:
+ flags |= FileSystem.FLAG_RETRIEVE_FULL_INFO
if search_key == 'fs_id':
search_key = 'id'
if search_key and \
search_key not in FileSystem.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"volume listing." % search_key)
- self.display_data(self.c.fs(search_key, search_value))
+ self.display_data(self.c.fs(search_key, search_value, flags))
elif args.type == 'SNAPSHOTS':
if args.fs is None:
raise ArgError("--fs <file system id> required")

+ if args.all:
+ flags |= FsSnapshot.FLAG_RETRIEVE_FULL_INFO
fs = _get_item(self.c.fs(), args.fs, 'filesystem')
- self.display_data(self.c.fs_snapshots(fs))
+ self.display_data(self.c.fs_snapshots(fs, flags))
elif args.type == 'INITIATORS':
self.display_data(self.c.initiators())
elif args.type == 'EXPORTS':
+ if args.all:
+ flags |= NfsExport.FLAG_RETRIEVE_FULL_INFO
if search_key == 'nfs_export_id':
search_key = 'id'
if search_key and \
search_key not in NfsExport.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"NFS Export listing" % search_key)
- self.display_data(self.c.exports(search_key, search_value))
+ self.display_data(self.c.exports(search_key, search_value, flags))
elif args.type == 'NFS_CLIENT_AUTH':
self.display_nfs_client_authentication()
elif args.type == 'ACCESS_GROUPS':
+ if args.all:
+ flags |= AccessGroup.FLAG_RETRIEVE_FULL_INFO
if search_key == 'access_group_id':
search_key = 'id'
if search_key == 'volume_id':
lsm_vol = _get_item(self.c.volumes(), args.vol,
"Volume ID")
return self.display_data(
- self.c.access_groups_granted_to_volume(lsm_vol))
+ self.c.access_groups_granted_to_volume(lsm_vol, flags))
elif search_key and \
search_key not in AccessGroup.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"Access Group listing" % search_key)
self.display_data(
- self.c.access_groups(search_key,search_value))
+ self.c.access_groups(search_key,search_value, flags))
elif args.type == 'SYSTEMS':
+ if args.all:
+ flags |= System.FLAG_RETRIEVE_FULL_INFO
if search_key:
raise ArgError("System listing with search is not supported")
- self.display_data(self.c.systems())
+ self.display_data(self.c.systems(flags))
elif args.type == 'DISKS':
if search_key == 'disk_id':
search_key = 'id'
if search_key and search_key not in Disk.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"disk listing" % search_key)
- flags = 0
if args.all:
- flags |= Disk.RETRIEVE_FULL_INFO
+ flags |= Disk.FLAG_RETRIEVE_FULL_INFO
self.display_data(
self.c.disks(search_key, search_value, flags))
elif args.type == 'PLUGINS':
--
1.8.3.1
Gris Ge
2014-06-08 07:43:04 UTC
Permalink
* Fix the problem when returned object missing some optional properties.

Signed-off-by: Gris Ge <***@redhat.com>
---
tools/lsmcli/data_display.py | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/lsmcli/data_display.py b/tools/lsmcli/data_display.py
index d9424dc..10f569b 100644
--- a/tools/lsmcli/data_display.py
+++ b/tools/lsmcli/data_display.py
@@ -707,7 +707,10 @@ class DisplayData(object):
data_dict[key_str] = value

if flag_dsp_all_data:
+ cur_support_opt_keys = obj.optional_data.list()
for key in optional_headers.keys():
+ if key not in cur_support_opt_keys:
+ continue
key_str = optional_headers[key]
value = DisplayData._get_opt_pro_value(
obj, key, value_conv_enum, value_conv_human, flag_human,
@@ -715,6 +718,7 @@ class DisplayData(object):
data_dict[key_str] = value

if extra_properties:
+ cur_support_opt_keys = obj.optional_data.list()
for key in extra_properties:
if key in data_dict.keys():
# already contained
@@ -726,6 +730,8 @@ class DisplayData(object):
flag_human, flag_enum)
data_dict[key_str] = value
elif key in optional_headers.keys():
+ if key not in cur_support_opt_keys:
+ continue
key_str = optional_headers[key]
value = DisplayData._get_opt_pro_value(
obj, key, value_conv_enum, value_conv_human,
--
1.8.3.1
Gris Ge
2014-06-08 07:43:05 UTC
Permalink
* Add a pretty simple optional data query test to cmdtest.py.

Signed-off-by: Gris Ge <***@redhat.com>
---
test/cmdtest.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/test/cmdtest.py b/test/cmdtest.py
index 78b9ee7..f782a32 100755
--- a/test/cmdtest.py
+++ b/test/cmdtest.py
@@ -34,7 +34,6 @@ import os
from subprocess import Popen, PIPE
from optparse import OptionParser

-
(OP_SYS, OP_POOL, OP_VOL, OP_INIT, OP_FS, OP_EXPORTS, OP_SS) = \
('SYSTEMS', 'POOLS', 'VOLUMES', 'INITIATORS', 'FS', 'EXPORTS',
'SNAPSHOTS')
@@ -724,6 +723,18 @@ def search_test(cap, system_id):
volume_delete(vol_id)
return

+def optional_data_check():
+ opt_support_list=['SYSTEMS', 'POOLS', 'VOLUMES', 'DISKS', 'ACCESS_GROUPS',
+ 'FS', 'EXPORTS']
+ # TODO:
+ # 1. Missing SNAPSHOTS
+ # 2. As simulator support all optional properties, we should check
+ # whether output contain all optional properties.
+
+ print "\nTesting query with optional data\n"
+ for list_type in opt_support_list:
+ call([cmd, 'list', '--type', list_type, '-a'])
+
def run_all_tests(cap, system_id):
test_display(cap, system_id)
test_plugin_list(cap, system_id)
@@ -734,7 +745,7 @@ def run_all_tests(cap, system_id):
test_mapping(cap, system_id)

search_test(cap, system_id)
-
+ optional_data_check()

if __name__ == "__main__":
parser = OptionParser()
--
1.8.3.1
Gris Ge
2014-06-10 08:52:20 UTC
Permalink
Changes in V2:
1. Removed the LSM_FLAG_UNUSED_CHECK in C library query methods.
2. Removed duplicated checking on '--optoinal' lsmcli argument.
3. Added lsm.FsSnapshot.FLAG_RETRIEVE_FULL_INFO(Python) and
LSM_FS_SNAPSHOT_FLAG_RETRIEVE_FULL_INFO(C) constants.

Please commit this patch set after these:
1. Patch set from Tony: '[PATCH 0/6] Add optional data/plugin data'
2. Patch set from Tony: '[PATCH 1/4] lsm_convert.cpp: Remove duplicate code'

Thanks for the review and comments in advance.

Gris Ge (7):
C & Python Libaray: Add FLAG_RETRIEVE_FULL_INFO for query
Plugins: Sync with FLAG_RETRIEVE_FULL_INFO changes
lsmcli: Sync with FLAG_RETRIEVE_FULL_INFO changes
lsmcli: Fix optional property displaying
cmdtest.py: Add a simple optional data query test
lsmcli: Revert argument back to "-o, --optional"
C and Python library: Changes on lsm.Disk

c_binding/include/libstoragemgmt/libstoragemgmt.h | 33 +++---
.../include/libstoragemgmt/libstoragemgmt_types.h | 62 ++++++++++-
c_binding/lsm_mgmt.cpp | 16 +--
doc/man/lsmcli.1.in | 13 ++-
plugin/ontap/ontap.py | 14 ++-
plugin/sim/simarray.py | 10 +-
plugin/smispy/smis.py | 12 +-
python_binding/lsm/_client.py | 4 +-
python_binding/lsm/_data.py | 121 ++++++---------------
test/cmdtest.py | 21 +++-
tools/lsmcli/cmdline.py | 55 ++++++----
tools/lsmcli/data_display.py | 10 +-
12 files changed, 205 insertions(+), 166 deletions(-)
--
1.8.3.1
Gris Ge
2014-06-10 08:52:21 UTC
Permalink
* Python, added these constants:
System.FLAG_RETRIEVE_FULL_INFO
Pool.FLAG_RETRIEVE_FULL_INFO
# This is a rename.
Volume.FLAG_RETRIEVE_FULL_INFO
Disk.FLAG_RETRIEVE_FULL_INFO
# This is a rename and value change from 2 to '1 << 0'
AccessGroup.FLAG_RETRIEVE_FULL_INFO
FileSystem.FLAG_RETRIEVE_FULL_INFO
NfsExport.FLAG_RETRIEVE_FULL_INFO
FsSnapshot.FLAG_RETRIEVE_FULL_INFO

* C, added these constants:
LSM_SYSTEM_FLAG_RETRIEVE_FULL_INFO
LSM_POOL_FLAG_RETRIEVE_FULL_INFO
LSM_VOLUME_FLAG_RETRIEVE_FULL_INFO
LSM_DISK_FLAG_RETRIEVE_FULL_INFO
LSM_ACCESS_GROUP_FLAG_RETRIEVE_FULL_INFO
LSM_FS_FLAG_RETRIEVE_FULL_INFO
LSM_NFS_FLAG_RETRIEVE_FULL_INFO
LSM_FS_SNAPSHOT_FLAG_RETRIEVE_FULL_INFO
* Remove LSM_FLAG_UNUSED_CHECK for query methods in C library.

Signed-off-by: Gris Ge <***@redhat.com>
---
c_binding/include/libstoragemgmt/libstoragemgmt.h | 33 ++++++++------
.../include/libstoragemgmt/libstoragemgmt_types.h | 49 +++++++++++++++++++-
c_binding/lsm_mgmt.cpp | 15 +++----
python_binding/lsm/_client.py | 4 +-
python_binding/lsm/_data.py | 52 +++++++---------------
5 files changed, 93 insertions(+), 60 deletions(-)

diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt.h b/c_binding/include/libstoragemgmt/libstoragemgmt.h
index af082b9..c646899 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt.h
@@ -230,7 +230,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] pool_array Array of storage pools
* @param[out] count Number of storage pools
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_POOL_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error reason
*/
int LSM_DLL_EXPORT lsm_pool_list(lsm_connect *conn, char *search_key,
@@ -371,7 +372,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] volumes An array of lsm_volume
* @param[out] count Number of elements in the lsm_volume array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_VOLUME_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error reason
*/
int LSM_DLL_EXPORT lsm_volume_list(lsm_connect *conn,
@@ -388,8 +390,8 @@ extern "C" {
* @param[in] search_value Search value
* @param [out] disks An array of lsm_disk types
* @param [out] count Number of disks
- * @param [in] flags Use LSM_DISK_RETRIEVE_FULL_INFO for all
- * data, else 0
+ * @param [in] flags Use LSM_DISK_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error reason
*/
int LSM_DLL_EXPORT lsm_disk_list(lsm_connect *conn, const char * search_key,
@@ -568,7 +570,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] groups Array of access groups
* @param[out] group_count Size of array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_ACCESS_GROUP_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason.
*/
int LSM_DLL_EXPORT lsm_access_group_list(lsm_connect *conn,
@@ -753,7 +756,8 @@ extern "C" {
* @param[in] conn Valid connection
* @param[out] systems Array of lsm_system
* @param[out] system_count Number of systems
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_SYSTEM_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason
*/
int LSM_DLL_EXPORT lsm_system_list(lsm_connect *conn, lsm_system **systems[],
@@ -766,7 +770,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] fs Array of lsm_fs
* @param[out] fs_count Number of file systems
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_FS_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason
*/
int LSM_DLL_EXPORT lsm_fs_list(lsm_connect *conn, const char *search_key,
@@ -881,11 +886,12 @@ extern "C" {

/**
* Return a list of snapshots
- * @param[in] conn Valid connection
- * @param[in] fs File system to check for snapshots
- * @param[out] ss An array of snapshot pointers
- * @param[out] ss_count Number of elements in the array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] conn Valid connection
+ * @param[in] fs File system to check for snapshots
+ * @param[out] ss An array of snapshot pointers
+ * @param[out] ss_count Number of elements in the array
+ * @param[in] flags Use LSM_FS_SNAPSHOT_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success, else error reason
*/
int LSM_DLL_EXPORT lsm_fs_ss_list(lsm_connect *conn, lsm_fs *fs,
@@ -959,7 +965,8 @@ extern "C" {
* @param[in] search_value Search value
* @param[out] exports An array of lsm_nfs_export
* @param[out] count Number of items in array
- * @param[in] flags Reserved for future use, must be zero.
+ * @param[in] flags Use LSM_NFS_FLAG_RETRIEVE_FULL_INFO
+ * for all data, else 0
* @return LSM_ERR_OK on success else error code.
*/
int LSM_DLL_EXPORT lsm_nfs_list(lsm_connect *c, const char *search_key,
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
index eb22df4..5ac7db3 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
@@ -152,6 +152,12 @@ typedef enum {
#define LSM_VOLUME_OP_STATUS_DORMANT 0x10 /**< Volume is inactive or quiesced */

/**
+ * Used by 'flags' parameter of lsm_volume_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_VOLUME_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
+/**
* Different states a system status can be in.
* Bit field, can be in multiple states at the same time.
*/
@@ -166,6 +172,13 @@ typedef enum {
#define LSM_SYSTEM_STATUS_STOPPED 0x00000100 /**< Stopped by admin */
#define LSM_SYSTEM_STATUS_OTHER 0x00000200 /**< Vendor specific */

+
+/**
+ * Used by 'flags' parameter of lsm_system_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_SYSTEM_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
/**< \enum lsm_initiator_type Different types of initiator IDs */
typedef enum {
LSM_INITIATOR_OTHER = 1, /**< Other or unspecified */
@@ -187,6 +200,12 @@ typedef enum {
INIT_TYPE_ISCSI_WWPN_MIXED = 7 /**< More than 1 type */
} lsm_access_group_init_type;

+/**
+ * Used by 'flags' parameter of lsm_access_group_list() function to
+ * retrieve optional data also.
+ */
+#define LSM_ACCESS_GROUP_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
/**< \enum lsm_job_type Different types of jobs */
typedef enum {
LSM_JOB_VOL_CREATE = 1, /**< Volume create */
@@ -214,7 +233,11 @@ typedef enum {
LSM_DISK_TYPE_SCSI = 8
} lsm_disk_type;

-#define LSM_DISK_RETRIEVE_FULL_INFO 0x02
+/**
+ * Used by 'flags' parameter of lsm_disk_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_DISK_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001

#define LSM_DISK_STATUS_UNKNOWN 0x0000000000000001
#define LSM_DISK_STATUS_OK 0x0000000000000002
@@ -247,6 +270,12 @@ typedef enum {
#define LSM_POOL_STATUS_SHRINKING 0x0000000000010000
#define LSM_POOL_STATUS_DESTROYING 0x0000000000020000

+/**
+ * Used by 'flags' parameter of lsm_pool_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_POOL_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
typedef enum {
LSM_POOL_MEMBER_TYPE_UNKNOWN = 0,
LSM_POOL_MEMBER_TYPE_DISK = 1,
@@ -285,6 +314,24 @@ typedef enum {
LSM_POOL_RAID_TYPE_MIXED = 23
} lsm_pool_raid_type;

+/**
+ * Used by 'flags' parameter of lsm_fs_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_FS_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
+/**
+ * Used by 'flags' parameter of lsm_nfs_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_NFS_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
+/**
+ * Used by 'flags' parameter of lsm_fs_ss_list() function to retrieve
+ * optional data also.
+ */
+#define LSM_FS_SNAPSHOT_FLAG_RETRIEVE_FULL_INFO 0x0000000000000001
+
#ifdef __cplusplus
}
#endif
diff --git a/c_binding/lsm_mgmt.cpp b/c_binding/lsm_mgmt.cpp
index 54bdc33..8b3d468 100644
--- a/c_binding/lsm_mgmt.cpp
+++ b/c_binding/lsm_mgmt.cpp
@@ -682,7 +682,7 @@ int lsm_pool_list(lsm_connect *c, char *search_key, char *search_value,
int rc = LSM_ERR_OK;
CONN_SETUP(c);

- if( !poolArray || !count || CHECK_RP(poolArray) || LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( !poolArray || !count || CHECK_RP(poolArray) ) {
return LSM_ERR_INVALID_ARGUMENT;
}

@@ -801,8 +801,7 @@ int lsm_volume_list(lsm_connect *c, const char *search_key,
{
CONN_SETUP(c);

- if( !volumes || !count || CHECK_RP(volumes) ||
- LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( !volumes || !count || CHECK_RP(volumes)){
return LSM_ERR_INVALID_ARGUMENT;
}

@@ -1547,7 +1546,7 @@ int lsm_access_group_list(lsm_connect *c, const char *search_key,
{
CONN_SETUP(c);

- if( !groups || !groupCount || LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( !groups || !groupCount ) {
return LSM_ERR_INVALID_ARGUMENT;
}

@@ -1885,7 +1884,7 @@ int lsm_system_list(lsm_connect *c, lsm_system **systems[],
int rc = LSM_ERR_OK;
CONN_SETUP(c);

- if( !systems || ! systemCount || LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( !systems || ! systemCount ) {
return LSM_ERR_INVALID_ARGUMENT;
}

@@ -1937,7 +1936,7 @@ int lsm_fs_list(lsm_connect *c, const char *search_key,
int rc = LSM_ERR_OK;
CONN_SETUP(c);

- if( !fs || !fsCount || LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( !fs || !fsCount ) {
return LSM_ERR_INVALID_ARGUMENT;
}

@@ -2222,7 +2221,7 @@ int lsm_fs_ss_list(lsm_connect *c, lsm_fs *fs, lsm_fs_ss **ss[],
return LSM_ERR_INVALID_FS;
}

- if( CHECK_RP(ss) || !ssCount || LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( CHECK_RP(ss) || !ssCount ) {
return LSM_ERR_INVALID_ARGUMENT;
}

@@ -2385,7 +2384,7 @@ int lsm_nfs_list( lsm_connect *c, const char *search_key,
int rc = LSM_ERR_OK;
CONN_SETUP(c);

- if( CHECK_RP(exports) || !count || LSM_FLAG_UNUSED_CHECK(flags) ) {
+ if( CHECK_RP(exports) || !count ) {
return LSM_ERR_INVALID_ARGUMENT;
}

diff --git a/python_binding/lsm/_client.py b/python_binding/lsm/_client.py
index 11acd01..3942b8d 100644
--- a/python_binding/lsm/_client.py
+++ b/python_binding/lsm/_client.py
@@ -284,7 +284,7 @@ class Client(INetworkAttachedStorage):

## Returns an array of pool objects.
# @param self The this pointer
- # @param flags When equal to Pool.RETRIEVE_FULL_INFO,
+ # @param flags When equal to Pool.FLAG_RETRIEVE_FULL_INFO,
# returned objects will contain optional data.
# If not defined, only the mandatory properties will
# returned.
@@ -671,7 +671,7 @@ class Client(INetworkAttachedStorage):

## Returns an array of disk objects
# @param self The this pointer
- # @param flags When equal to DISK.RETRIEVE_FULL_INFO
+ # @param flags When equal to DISK.FLAG_RETRIEVE_FULL_INFO
# returned objects will contain optional data.
# If not defined, only the mandatory properties will
# be returned.
diff --git a/python_binding/lsm/_data.py b/python_binding/lsm/_data.py
index f7929f1..6104ec4 100644
--- a/python_binding/lsm/_data.py
+++ b/python_binding/lsm/_data.py
@@ -208,7 +208,7 @@ class Disk(IData):
Represents a disk.
"""
SUPPORTED_SEARCH_KEYS = ['id', 'system_id']
- RETRIEVE_FULL_INFO = 2 # Used by _client.py for disks() call.
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0

# We use '-1' to indicate we failed to get the requested number.
# For example, when block found is undetectable, we use '-1' instead of
@@ -302,20 +302,8 @@ class Disk(IData):
self._num_of_blocks = _num_of_blocks
self._status = _status
self._system_id = _system_id
-
- if _optional_data is None:
- self._optional_data = OptionalData()
- else:
- #Make sure the properties only contain ones we permit
- allowed = set(Disk.OPT_PROPERTIES)
- actual = set(_optional_data.list())
-
- if actual <= allowed:
- self._optional_data = _optional_data
- else:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Property keys are invalid: %s" %
- "".join(actual - allowed))
+ self._optional_data = _check_opt_data(_optional_data,
+ self.OPT_PROPERTIES)

@property
def size_bytes(self):
@@ -342,6 +330,8 @@ class Volume(IData):
"""
Represents a volume.
"""
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
+
SUPPORTED_SEARCH_KEYS = ['id', 'system_id', 'pool_id']
# Volume status Note: Volumes can have multiple status bits set at same
# time.
@@ -379,7 +369,7 @@ class Volume(IData):
self._system_id = _system_id # System id this volume belongs
self._pool_id = _pool_id # Pool id this volume belongs
self._optional_data = _check_opt_data(_optional_data,
- Volume.OPT_PROPERTIES)
+ self.OPT_PROPERTIES)
self._plugin_data = _plugin_data

@property
@@ -467,6 +457,8 @@ The lsm.System class does not have any extra constants.

The lsm.System class does not have class methods.
"""
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
+
STATUS_UNKNOWN = 1 << 0
STATUS_OK = 1 << 1
STATUS_ERROR = 1 << 2
@@ -502,9 +494,7 @@ class Pool(IData):
"""
Pool specific information
"""
- RETRIEVE_FULL_INFO = 1 # Used by _client.py for pools() call.
- # This might not be a good place, please
- # suggest a better one.
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'system_id']

TOTAL_SPACE_NOT_FOUND = -1
@@ -701,21 +691,8 @@ class Pool(IData):
self._status_info = _status_info # Additional status text of pool
self._system_id = _system_id # System id this pool belongs
self._plugin_data = _plugin_data # Plugin private data
-
- if _optional_data is None:
- self._optional_data = OptionalData()
- else:
- #Make sure the properties only contain ones we permit
- allowed = set(Pool.OPT_PROPERTIES)
- actual = set(_optional_data.list())
-
- if actual <= allowed:
- self._optional_data = _optional_data
- else:
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Property keys are invalid: %s" %
- "".join(actual - allowed))
-
+ self._optional_data = _check_opt_data(_optional_data,
+ self.OPT_PROPERTIES)

@default_property('id', doc="Unique identifier")
@default_property('name', doc="File system name")
@@ -726,6 +703,7 @@ class Pool(IData):
@default_property("optional_data", "Optional data")
@default_property("plugin_data", "Private plugin data")
class FileSystem(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'system_id', 'pool_id']

def __init__(self, _id, _name, _total_space, _free_space, _pool_id,
@@ -747,6 +725,7 @@ class FileSystem(IData):
@default_property("optional_data", "Optional data")
@default_property("plugin_data", "Private plugin data")
class FsSnapshot(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
def __init__(self, _id, _name, _ts, _optional_data=None,
_plugin_data=None):
self._id = _id
@@ -770,6 +749,7 @@ class FsSnapshot(IData):
@default_property('optional_data', doc="Optional data")
@default_property('plugin_data', doc="Plugin private data")
class NfsExport(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'fs_id']
ANON_UID_GID_NA = -1
ANON_UID_GID_ERROR = (ANON_UID_GID_NA - 1)
@@ -795,7 +775,6 @@ class NfsExport(IData):
self._plugin_data = _plugin_data


-
@default_property('src_block', doc="Source logical block address")
@default_property('dest_block', doc="Destination logical block address")
@default_property('block_count', doc="Number of blocks")
@@ -814,6 +793,7 @@ class BlockRange(IData):
@default_property('optional_data', doc="Optional data")
@default_property('plugin_data', doc="Plugin private data")
class AccessGroup(IData):
+ FLAG_RETRIEVE_FULL_INFO = 1 << 0
SUPPORTED_SEARCH_KEYS = ['id', 'system_id']

INIT_TYPE_UNKNOWN = 0
@@ -834,7 +814,7 @@ class AccessGroup(IData):
self._system_id = _system_id # System id this group belongs
self._plugin_data = _plugin_data
self._optional_data = _check_opt_data(_optional_data,
- AccessGroup.OPT_PROPERTIES)
+ self.OPT_PROPERTIES)


class OptionalData(IData):
--
1.8.3.1
Gris Ge
2014-06-10 08:52:22 UTC
Permalink
* The 'flags' argument of query methods is now a bitmap. We change plugin
to use '&' instead of '=='.
* Sync plugins with FLAG_RETRIEVE_FULL_INFO changes.

Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/ontap/ontap.py | 8 ++++----
plugin/sim/simarray.py | 10 +++++-----
plugin/smispy/smis.py | 12 ++++++------
3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index d97bfe7..a242668 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -290,7 +290,7 @@ class Ontap(IStorageAreaNetwork, INfs):
def _disk(self, d, flag):
opt_data = OptionalData()
status = Ontap._status_of_na_disk(d)
- if flag == Disk.RETRIEVE_FULL_INFO:
+ if flag & Disk.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('sn', d['serial-number'])
opt_data.set('model', d['disk-model'])
opt_data.set('vendor', d['vendor-id'])
@@ -358,7 +358,7 @@ class Ontap(IStorageAreaNetwork, INfs):
system_id = self.sys_info.id
status = self._status_of_na_aggr(na_aggr)
opt_data = OptionalData()
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('member_type', Pool.MEMBER_TYPE_DISK)
member_ids = []
for na_disk in na_disks:
@@ -415,7 +415,7 @@ class Ontap(IStorageAreaNetwork, INfs):
system_id = self.sys_info.id
status = self._status_of_na_vol(na_vol)
opt_data = OptionalData()
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('member_type', Pool.MEMBER_TYPE_POOL)
parent_aggr_name = na_vol['containing-aggregate']
for na_aggr in na_aggrs:
@@ -502,7 +502,7 @@ class Ontap(IStorageAreaNetwork, INfs):
na_disks = []
# We do extra flags check in order to save self.f.disks() calls
# in case we have multiple aggregates.
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
na_disks = self.f.disks()
for na_aggr in na_aggrs:
pools.extend([self._pool_from_na_aggr(na_aggr, na_disks, flags)])
diff --git a/plugin/sim/simarray.py b/plugin/sim/simarray.py
index f530763..10cfc27 100644
--- a/plugin/sim/simarray.py
+++ b/plugin/sim/simarray.py
@@ -159,7 +159,7 @@ class SimArray(object):
status_info = sim_pool['status_info']
sys_id = sim_pool['sys_id']
opt_data = OptionalData()
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_data.set('raid_type', sim_pool['raid_type'])
opt_data.set('member_type', sim_pool['member_type'])
opt_data.set('member_ids', sim_pool['member_ids'])
@@ -182,28 +182,28 @@ class SimArray(object):
sim_pool = self.data.pool_create(
sys_id, pool_name, size_bytes, raid_type, member_type, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_create_from_disks(self, sys_id, pool_name, disks_ids, raid_type,
flags=0):
sim_pool = self.data.pool_create_from_disks(
sys_id, pool_name, disks_ids, raid_type, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_create_from_volumes(self, sys_id, pool_name, member_ids,
raid_type, flags=0):
sim_pool = self.data.pool_create_from_volumes(
sys_id, pool_name, member_ids, raid_type, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_create_from_pool(self, sys_id, pool_name, member_id, size_bytes,
flags=0):
sim_pool = self.data.pool_create_from_pool(
sys_id, pool_name, member_id, size_bytes, flags)
return self.data.job_create(
- self._sim_pool_2_lsm(sim_pool, Pool.RETRIEVE_FULL_INFO))
+ self._sim_pool_2_lsm(sim_pool, Pool.FLAG_RETRIEVE_FULL_INFO))

def pool_delete(self, pool_id, flags=0):
return self.data.job_create(self.data.pool_delete(pool_id, flags))[0]
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index b2da486..42e2749 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -1494,7 +1494,7 @@ class Smis(IStorageAreaNetwork):
"""
rc = []
cim_pool_pros = self._new_pool_cim_pool_pros(
- flags == Pool.RETRIEVE_FULL_INFO)
+ bool(flags & Pool.FLAG_RETRIEVE_FULL_INFO))

cim_sys_pros = self._property_list_of_id("System")
cim_syss = self._root_cim_syss(cim_sys_pros)
@@ -1531,7 +1531,7 @@ class Smis(IStorageAreaNetwork):
pool = self._new_pool(cim_pool, system_id)
if pool:
rc.extend([pool])
- if flags == Pool.RETRIEVE_FULL_INFO:
+ if flags & Pool.FLAG_RETRIEVE_FULL_INFO:
opt_pro_dict = self._pool_opt_data(cim_pool)
for key, value in opt_pro_dict.items():
pool.optional_data.set(key, value)
@@ -2332,7 +2332,7 @@ class Smis(IStorageAreaNetwork):
"""
pros = ['OperationalStatus', 'Name', 'SystemName',
'Caption', 'InterconnectType', 'DiskType']
- if flag == Disk.RETRIEVE_FULL_INFO:
+ if flag & Disk.FLAG_RETRIEVE_FULL_INFO:
pros.extend(['ErrorDescription', 'ErrorCleared'])
return pros

@@ -2351,8 +2351,8 @@ class Smis(IStorageAreaNetwork):
object.
"""
pros = [] # we don't need CIM_PhysicalPackage when not
- # RETRIEVE_FULL_INFO
- if flag == Disk.RETRIEVE_FULL_INFO:
+ # FLAG_RETRIEVE_FULL_INFO
+ if flag & Disk.FLAG_RETRIEVE_FULL_INFO:
pros.extend(['SerialNumber', 'PartNumber', 'Manufacturer',
'Model'])
return pros
@@ -2436,7 +2436,7 @@ class Smis(IStorageAreaNetwork):
disk_type = Disk.DISK_TYPE_SAS

optionals = OptionalData()
- if flag_full_info == Disk.RETRIEVE_FULL_INFO:
+ if flag_full_info & Disk.FLAG_RETRIEVE_FULL_INFO:
opt_pro_dict = {
'sn': '',
'part_num': '',
--
1.8.3.1
Gris Ge
2014-06-10 08:52:23 UTC
Permalink
* lsmcli: Sync with FLAG_RETRIEVE_FULL_INFO changes

Signed-off-by: Gris Ge <***@redhat.com>
---
tools/lsmcli/cmdline.py | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/tools/lsmcli/cmdline.py b/tools/lsmcli/cmdline.py
index 3a292b2..a1ccded 100644
--- a/tools/lsmcli/cmdline.py
+++ b/tools/lsmcli/cmdline.py
@@ -29,7 +29,7 @@ from argparse import RawTextHelpFormatter
from lsm import (Client, Pool, VERSION, LsmError, Capabilities, Disk,
Initiator, Volume, JobStatus, ErrorNumber, BlockRange,
uri_parse, Proxy, size_human_2_size_bytes,
- AccessGroup, FileSystem, NfsExport)
+ AccessGroup, FileSystem, NfsExport, System, FsSnapshot)

from lsm.lsmcli.data_display import (
DisplayData, PlugData, out,
@@ -925,6 +925,7 @@ class CmdLine:
def list(self, args):
search_key = None
search_value = None
+ flags = 0
if args.sys:
search_key = 'system_id'
search_value = args.sys
@@ -948,81 +949,91 @@ class CmdLine:
search_value = args.nfs_export

if args.type == 'VOLUMES':
+ if args.all:
+ flags |= Volume.FLAG_RETRIEVE_FULL_INFO
if search_key == 'volume_id':
search_key = 'id'
if search_key == 'access_group_id':
lsm_ag = _get_item(self.c.access_groups(), args.ag,
"Access Group ID")
return self.display_data(
- self.c.volumes_accessible_by_access_group(lsm_ag))
+ self.c.volumes_accessible_by_access_group(lsm_ag, flags))
elif search_key and search_key not in Volume.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"volume listing." % search_key)
- self.display_data(self.c.volumes(search_key, search_value))
+ self.display_data(self.c.volumes(search_key, search_value, flags))
elif args.type == 'POOLS':
if search_key == 'pool_id':
search_key = 'id'
if search_key and search_key not in Pool.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"pool listing." % search_key)
- flags = 0
if args.all:
- flags |= Pool.RETRIEVE_FULL_INFO
+ flags |= Pool.FLAG_RETRIEVE_FULL_INFO
self.display_data(
self.c.pools(search_key, search_value, flags))
elif args.type == 'FS':
+ if args.all:
+ flags |= FileSystem.FLAG_RETRIEVE_FULL_INFO
if search_key == 'fs_id':
search_key = 'id'
if search_key and \
search_key not in FileSystem.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"volume listing." % search_key)
- self.display_data(self.c.fs(search_key, search_value))
+ self.display_data(self.c.fs(search_key, search_value, flags))
elif args.type == 'SNAPSHOTS':
if args.fs is None:
raise ArgError("--fs <file system id> required")

+ if args.all:
+ flags |= FsSnapshot.FLAG_RETRIEVE_FULL_INFO
fs = _get_item(self.c.fs(), args.fs, 'filesystem')
- self.display_data(self.c.fs_snapshots(fs))
+ self.display_data(self.c.fs_snapshots(fs, flags))
elif args.type == 'INITIATORS':
self.display_data(self.c.initiators())
elif args.type == 'EXPORTS':
+ if args.all:
+ flags |= NfsExport.FLAG_RETRIEVE_FULL_INFO
if search_key == 'nfs_export_id':
search_key = 'id'
if search_key and \
search_key not in NfsExport.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"NFS Export listing" % search_key)
- self.display_data(self.c.exports(search_key, search_value))
+ self.display_data(self.c.exports(search_key, search_value, flags))
elif args.type == 'NFS_CLIENT_AUTH':
self.display_nfs_client_authentication()
elif args.type == 'ACCESS_GROUPS':
+ if args.all:
+ flags |= AccessGroup.FLAG_RETRIEVE_FULL_INFO
if search_key == 'access_group_id':
search_key = 'id'
if search_key == 'volume_id':
lsm_vol = _get_item(self.c.volumes(), args.vol,
"Volume ID")
return self.display_data(
- self.c.access_groups_granted_to_volume(lsm_vol))
+ self.c.access_groups_granted_to_volume(lsm_vol, flags))
elif search_key and \
search_key not in AccessGroup.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"Access Group listing" % search_key)
self.display_data(
- self.c.access_groups(search_key,search_value))
+ self.c.access_groups(search_key,search_value, flags))
elif args.type == 'SYSTEMS':
+ if args.all:
+ flags |= System.FLAG_RETRIEVE_FULL_INFO
if search_key:
raise ArgError("System listing with search is not supported")
- self.display_data(self.c.systems())
+ self.display_data(self.c.systems(flags))
elif args.type == 'DISKS':
if search_key == 'disk_id':
search_key = 'id'
if search_key and search_key not in Disk.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"disk listing" % search_key)
- flags = 0
if args.all:
- flags |= Disk.RETRIEVE_FULL_INFO
+ flags |= Disk.FLAG_RETRIEVE_FULL_INFO
self.display_data(
self.c.disks(search_key, search_value, flags))
elif args.type == 'PLUGINS':
--
1.8.3.1
Gris Ge
2014-06-10 08:52:24 UTC
Permalink
* Fix the problem when returned object missing some optional properties.

Signed-off-by: Gris Ge <***@redhat.com>
---
tools/lsmcli/data_display.py | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/tools/lsmcli/data_display.py b/tools/lsmcli/data_display.py
index d9424dc..10f569b 100644
--- a/tools/lsmcli/data_display.py
+++ b/tools/lsmcli/data_display.py
@@ -707,7 +707,10 @@ class DisplayData(object):
data_dict[key_str] = value

if flag_dsp_all_data:
+ cur_support_opt_keys = obj.optional_data.list()
for key in optional_headers.keys():
+ if key not in cur_support_opt_keys:
+ continue
key_str = optional_headers[key]
value = DisplayData._get_opt_pro_value(
obj, key, value_conv_enum, value_conv_human, flag_human,
@@ -715,6 +718,7 @@ class DisplayData(object):
data_dict[key_str] = value

if extra_properties:
+ cur_support_opt_keys = obj.optional_data.list()
for key in extra_properties:
if key in data_dict.keys():
# already contained
@@ -726,6 +730,8 @@ class DisplayData(object):
flag_human, flag_enum)
data_dict[key_str] = value
elif key in optional_headers.keys():
+ if key not in cur_support_opt_keys:
+ continue
key_str = optional_headers[key]
value = DisplayData._get_opt_pro_value(
obj, key, value_conv_enum, value_conv_human,
--
1.8.3.1
Gris Ge
2014-06-10 08:52:25 UTC
Permalink
* Add a pretty simple optional data query test to cmdtest.py.

Signed-off-by: Gris Ge <***@redhat.com>
---
test/cmdtest.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/test/cmdtest.py b/test/cmdtest.py
index 78b9ee7..f782a32 100755
--- a/test/cmdtest.py
+++ b/test/cmdtest.py
@@ -34,7 +34,6 @@ import os
from subprocess import Popen, PIPE
from optparse import OptionParser

-
(OP_SYS, OP_POOL, OP_VOL, OP_INIT, OP_FS, OP_EXPORTS, OP_SS) = \
('SYSTEMS', 'POOLS', 'VOLUMES', 'INITIATORS', 'FS', 'EXPORTS',
'SNAPSHOTS')
@@ -724,6 +723,18 @@ def search_test(cap, system_id):
volume_delete(vol_id)
return

+def optional_data_check():
+ opt_support_list=['SYSTEMS', 'POOLS', 'VOLUMES', 'DISKS', 'ACCESS_GROUPS',
+ 'FS', 'EXPORTS']
+ # TODO:
+ # 1. Missing SNAPSHOTS
+ # 2. As simulator support all optional properties, we should check
+ # whether output contain all optional properties.
+
+ print "\nTesting query with optional data\n"
+ for list_type in opt_support_list:
+ call([cmd, 'list', '--type', list_type, '-a'])
+
def run_all_tests(cap, system_id):
test_display(cap, system_id)
test_plugin_list(cap, system_id)
@@ -734,7 +745,7 @@ def run_all_tests(cap, system_id):
test_mapping(cap, system_id)

search_test(cap, system_id)
-
+ optional_data_check()

if __name__ == "__main__":
parser = OptionParser()
--
1.8.3.1
Gris Ge
2014-06-10 08:52:26 UTC
Permalink
* Revert back to "-o, --optional" lsmcli argument.
* Update manpage warning user:
Due to console text width limitation(78), NOT all mandatory properties will
be displayed in column way(default display way). But all mandatory
properties will be displayed in script way. When with "-o, --optional",
both mandatory properties and optional properties will be displayed.
* If "-o, --optional" is defined, the display method will be forced as
script way due to console text width limitation.
* The lsmcli test has been updated also for this change.

Signed-off-by: Gris Ge <***@redhat.com>
---
doc/man/lsmcli.1.in | 13 ++++++++++---
test/cmdtest.py | 8 ++++----
tools/lsmcli/cmdline.py | 30 +++++++++++++++---------------
3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/doc/man/lsmcli.1.in b/doc/man/lsmcli.1.in
index 53d8673..96f1725 100644
--- a/doc/man/lsmcli.1.in
+++ b/doc/man/lsmcli.1.in
@@ -120,7 +120,7 @@ Displaying data in script friendly way.
Without this option, data is displayed in this manner:

ID | Name | Member IDs
- -------------------------------------+-------+-------------
+ -----------------------------------------------------------
87720e90-3a83-11df-b8bf-00a0980ad71b | aggr0 | ID_A
| | ID_B
aa0ffc70-3dba-11df-b8cf-00a0980ad71b | aggr1 | ID_C
@@ -140,6 +140,14 @@ With this option, data is displayed in this manner.
| ID_D
--------------------------------------------------

+Please note:
+.br
+Due to console text width limitation(78), NOT all mandatory properties will be
+displayed in column way(default display way).
+But all mandatory properties will be displayed in script way. When with "-o,
+--optional", both mandatory properties and optional properties will be
+displayed.
+
.SH COMMANDS
.SS list
List information on LSM objects
@@ -159,8 +167,7 @@ filesystem.
PLUGINS will list all supported plugins of LSM, not only the current one.
.TP
\fB-o\fR, \fB--optional\fR
-Optional. Valid for \fBPOOLS\fR and \fBDISKS\fR to retrieve optional data if
-available.
+Optional. Retrive and display optional data in '--script, -s' display way.
.TP
\fB--sys\fR \fI<SYS_ID>\fR
Search resources from system with SYS_ID. Only supported when querying these
diff --git a/test/cmdtest.py b/test/cmdtest.py
index f782a32..81d5ee4 100755
--- a/test/cmdtest.py
+++ b/test/cmdtest.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python

-# Copyright (C) 2011-2013 Red Hat, Inc.
+# Copyright (C) 2011-2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -89,7 +89,7 @@ def call(command, expected_rc=0):
"""

if code_coverage:
- actual_command = ['coverage', 'run', '-a']
+ actual_command = ['coverage', 'run', '-o']
actual_command.extend(command)
else:
actual_command = command
@@ -430,7 +430,7 @@ def display_check(display_list, system_id):
call([cmd, 'list', '--type', 'SNAPSHOTS', '--fs', fs_id])

if 'POOLS' in display_list:
- call([cmd, '-H', '-t' + sep, 'list', '--type', 'POOLS', '-a'])
+ call([cmd, '-H', '-t' + sep, 'list', '--type', 'POOLS', '-o'])


def test_display(cap, system_id):
@@ -733,7 +733,7 @@ def optional_data_check():

print "\nTesting query with optional data\n"
for list_type in opt_support_list:
- call([cmd, 'list', '--type', list_type, '-a'])
+ call([cmd, 'list', '--type', list_type, '-o'])

def run_all_tests(cap, system_id):
test_display(cap, system_id)
diff --git a/tools/lsmcli/cmdline.py b/tools/lsmcli/cmdline.py
index a1ccded..ef3561b 100644
--- a/tools/lsmcli/cmdline.py
+++ b/tools/lsmcli/cmdline.py
@@ -71,7 +71,6 @@ def getch():
termios.tcsetattr(fd, termios.TCSADRAIN, prev)
return ch

-
## This class represents a command line argument error
class ArgError(Exception):
def __init__(self, message, *args, **kwargs):
@@ -189,11 +188,11 @@ cmds = (
type=str.upper),
],
optional=[
- dict(name=('-a', '--all'),
- help='Retrieve and display in script friendly way with ' +
- 'all information including optional data if available',
+ dict(name=('-o', '--optional'),
+ help='Retrieve both mandatory and optional properties.\n'
+ 'Once define, will use "-s, --script" display way',
default=False,
- dest='all',
+ dest='optional',
action='store_true'),
dict(sys_id_filter_opt),
dict(pool_id_filter_opt),
@@ -789,8 +788,10 @@ class CmdLine:
if len(objects) == 0:
return

- if hasattr(self.args, 'all') and self.args.all:
+ display_way = DisplayData.DISPLAY_WAY_DEFAULT
+ if hasattr(self.args, 'optional') and self.args.optional:
display_all = True
+ display_way = DisplayData.DISPLAY_WAY_SCRIPT

flag_with_header = True
if self.args.sep:
@@ -798,7 +799,6 @@ class CmdLine:
if self.args.header:
flag_with_header = True

- display_way = DisplayData.DISPLAY_WAY_DEFAULT
if self.args.script:
display_way = DisplayData.DISPLAY_WAY_SCRIPT

@@ -949,7 +949,7 @@ class CmdLine:
search_value = args.nfs_export

if args.type == 'VOLUMES':
- if args.all:
+ if args.optional:
flags |= Volume.FLAG_RETRIEVE_FULL_INFO
if search_key == 'volume_id':
search_key = 'id'
@@ -968,12 +968,12 @@ class CmdLine:
if search_key and search_key not in Pool.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"pool listing." % search_key)
- if args.all:
+ if args.optional:
flags |= Pool.FLAG_RETRIEVE_FULL_INFO
self.display_data(
self.c.pools(search_key, search_value, flags))
elif args.type == 'FS':
- if args.all:
+ if args.optional:
flags |= FileSystem.FLAG_RETRIEVE_FULL_INFO
if search_key == 'fs_id':
search_key = 'id'
@@ -986,14 +986,14 @@ class CmdLine:
if args.fs is None:
raise ArgError("--fs <file system id> required")

- if args.all:
+ if args.optional:
flags |= FsSnapshot.FLAG_RETRIEVE_FULL_INFO
fs = _get_item(self.c.fs(), args.fs, 'filesystem')
self.display_data(self.c.fs_snapshots(fs, flags))
elif args.type == 'INITIATORS':
self.display_data(self.c.initiators())
elif args.type == 'EXPORTS':
- if args.all:
+ if args.optional:
flags |= NfsExport.FLAG_RETRIEVE_FULL_INFO
if search_key == 'nfs_export_id':
search_key = 'id'
@@ -1005,7 +1005,7 @@ class CmdLine:
elif args.type == 'NFS_CLIENT_AUTH':
self.display_nfs_client_authentication()
elif args.type == 'ACCESS_GROUPS':
- if args.all:
+ if args.optional:
flags |= AccessGroup.FLAG_RETRIEVE_FULL_INFO
if search_key == 'access_group_id':
search_key = 'id'
@@ -1021,7 +1021,7 @@ class CmdLine:
self.display_data(
self.c.access_groups(search_key,search_value, flags))
elif args.type == 'SYSTEMS':
- if args.all:
+ if args.optional:
flags |= System.FLAG_RETRIEVE_FULL_INFO
if search_key:
raise ArgError("System listing with search is not supported")
@@ -1032,7 +1032,7 @@ class CmdLine:
if search_key and search_key not in Disk.SUPPORTED_SEARCH_KEYS:
raise ArgError("Search key '%s' is not supported by "
"disk listing" % search_key)
- if args.all:
+ if args.optional:
flags |= Disk.FLAG_RETRIEVE_FULL_INFO
self.display_data(
self.c.disks(search_key, search_value, flags))
--
1.8.3.1
Gris Ge
2014-06-10 08:52:27 UTC
Permalink
* Added constants:
* Python
* lsm.Disk.DISK_TYPE_LUN
* lsm.Pool.MEMBER_TYPE_DISK_LUN
# Using remote LUN to create pool is not "Volume Pool" of LSM.
# The "Volume Pool" is defined as "Pool created from local volumes"
* C
* LSM_DISK_TYPE_LUN
* LSM_DISK_TYPE_NL_SAS
* LSM_DISK_TYPE_HDD
* LSM_DISK_TYPE_SSD
* LSM_DISK_TYPE_HYBRID
* LSM_DISK_BLOCK_SIZE_NOT_FOUND
* LSM_DISK_BLOCK_COUNT_NOT_FOUND
* LSM_POOL_MEMBER_TYPE_DISK_LUN
* Removed constants:
* lsm.Disk.STATUS_RECONSTRUCTING (Python)
* LSM_DISK_STATUS_RECONSTRUCTING (C)
# Disk should not holding status of a pool. The lsm.Disk.status should
# only containing physical health of itself.
* Removed optional properties:
* status_info
# Not needed.
* owner_ctrler_id
# Not needed.
* Removed private method:
lsm.Disk._value_convert()
# Replaced by lsm.lsmcli.DataDisplay

* Synced ONTAP plugin for these changes.
* Synced lsmcli for these changes.
* "make check" passed.

Signed-off-by: Gris Ge <***@redhat.com>
---
.../include/libstoragemgmt/libstoragemgmt_types.h | 13 +++-
c_binding/lsm_mgmt.cpp | 1 +
plugin/ontap/ontap.py | 6 +-
python_binding/lsm/_data.py | 70 +++++-----------------
tools/lsmcli/data_display.py | 4 +-
5 files changed, 33 insertions(+), 61 deletions(-)

diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
index 5ac7db3..533f887 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
@@ -230,7 +230,12 @@ typedef enum {
LSM_DISK_TYPE_SAS = 5,
LSM_DISK_TYPE_FC = 6,
LSM_DISK_TYPE_SOP = 7,
- LSM_DISK_TYPE_SCSI = 8
+ LSM_DISK_TYPE_SCSI = 8,
+ LSM_DISK_TYPE_LUN = 9,
+ LSM_DISK_TYPE_NL_SAS = 51,
+ LSM_DISK_TYPE_HDD = 52,
+ LSM_DISK_TYPE_SSD = 53,
+ LSM_DISK_TYPE_HYBRID = 54,
} lsm_disk_type;

/**
@@ -248,8 +253,9 @@ typedef enum {
#define LSM_DISK_STATUS_STOPPING 0x0000000000000040
#define LSM_DISK_STATUS_STOPPED 0x0000000000000080
#define LSM_DISK_STATUS_INITIALIZING 0x0000000000000100
-#define LSM_DISK_STATUS_RECONSTRUCTING 0x0000000000000200

+#define LSM_DISK_BLOCK_SIZE_NOT_FOUND -1
+#define LSM_DISK_BLOCK_COUNT_NOT_FOUND -1

#define LSM_POOL_STATUS_UNKNOWN 0x0000000000000001
#define LSM_POOL_STATUS_OK 0x0000000000000002
@@ -291,7 +297,8 @@ typedef enum {
LSM_POOL_MEMBER_TYPE_DISK_NL_SAS = 17,
LSM_POOL_MEMBER_TYPE_DISK_HDD = 18,
LSM_POOL_MEMBER_TYPE_DISK_SSD = 19,
- LSM_POOL_MEMBER_TYPE_DISK_HYBRID = 110
+ LSM_POOL_MEMBER_TYPE_DISK_HYBRID = 110,
+ LSM_POOL_MEMBER_TYPE_DISK_LUN = 111
} lsm_pool_member_type;

typedef enum {
diff --git a/c_binding/lsm_mgmt.cpp b/c_binding/lsm_mgmt.cpp
index 8b3d468..f5976ae 100644
--- a/c_binding/lsm_mgmt.cpp
+++ b/c_binding/lsm_mgmt.cpp
@@ -939,6 +939,7 @@ static int valid_pool_member_type(lsm_pool_member_type validate)
case (LSM_POOL_MEMBER_TYPE_DISK_HDD):
case (LSM_POOL_MEMBER_TYPE_DISK_SSD):
case (LSM_POOL_MEMBER_TYPE_DISK_HYBRID):
+ case (LSM_POOL_MEMBER_TYPE_DISK_LUN):
break;
default:
return 0;
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index a242668..ca3aed2 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -226,7 +226,7 @@ class Ontap(IStorageAreaNetwork, INfs):
def _disk_type(netapp_disk_type):
conv = {'ATA': Disk.DISK_TYPE_ATA, 'BSAS': Disk.DISK_TYPE_SAS,
'EATA': Disk.DISK_TYPE_ATA, 'FCAL': Disk.DISK_TYPE_FC,
- 'FSAS': Disk.DISK_TYPE_SAS, 'LUN': Disk.DISK_TYPE_OTHER,
+ 'FSAS': Disk.DISK_TYPE_SAS, 'LUN': Disk.DISK_TYPE_LUN,
'SAS': Disk.DISK_TYPE_SAS, 'SATA': Disk.DISK_TYPE_SATA,
'SCSI': Disk.DISK_TYPE_SCSI, 'SSD': Disk.DISK_TYPE_SSD,
'XATA': Disk.DISK_TYPE_ATA, 'XSAS': Disk.DISK_TYPE_SAS,
@@ -261,7 +261,9 @@ class Ontap(IStorageAreaNetwork, INfs):
elif rs == 'zeroing':
status = Disk.STATUS_INITIALIZING
elif rs == 'reconstructing':
- status = Disk.STATUS_RECONSTRUCTING
+ # "reconstructing' should be a pool status, not disk status.
+ # disk under reconstructing should be considered as OK.
+ status = Disk.STATUS_OK

if 'is-prefailed' in na_disk and na_disk['is-prefailed'] == 'true':
status = Disk.STATUS_PREDICTIVE_FAILURE
diff --git a/python_binding/lsm/_data.py b/python_binding/lsm/_data.py
index 6104ec4..b9fef89 100644
--- a/python_binding/lsm/_data.py
+++ b/python_binding/lsm/_data.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2013 Red Hat, Inc.
+# Copyright (C) 2011-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
@@ -14,6 +14,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Author: tasleson
+# Gris Ge <***@redhat.com>

from abc import ABCMeta as _ABCMeta

@@ -203,6 +204,7 @@ class Initiator(IData):
@default_property('status', doc="Enumerated status")
@default_property('system_id', doc="System identifier")
@default_property("optional_data", doc="Optional data")
+@default_property("plugin_data", doc="Private plugin data")
class Disk(IData):
"""
Represents a disk.
@@ -216,16 +218,16 @@ class Disk(IData):
BLOCK_COUNT_NOT_FOUND = -1
BLOCK_SIZE_NOT_FOUND = -1

- # Disk Type, using DMTF 2.31.0+ CIM_DiskDrive['InterconnectType']
DISK_TYPE_UNKNOWN = 0
DISK_TYPE_OTHER = 1
DISK_TYPE_NOT_APPLICABLE = 2
- DISK_TYPE_ATA = 3 # IDE disk is seldomly used.
+ DISK_TYPE_ATA = 3 # IDE disk which is seldomly used.
DISK_TYPE_SATA = 4
DISK_TYPE_SAS = 5
DISK_TYPE_FC = 6
- DISK_TYPE_SOP = 7 # SCSI over PCIe, often holding SSD
+ DISK_TYPE_SOP = 7 # SCSI over PCIe(SSD)
DISK_TYPE_SCSI = 8
+ DISK_TYPE_LUN = 9 # Remote LUN was treated as a disk.

# Due to complesity of disk types, we are defining these beside DMTF
# standards:
@@ -237,64 +239,21 @@ class Disk(IData):
DISK_TYPE_SSD = 53 # Solid State Drive
DISK_TYPE_HYBRID = 54 # uses a combination of HDD and SSD

- MAX_DISK_STATUS_BITS = 64
- # Disk status could be any combination of these status.
STATUS_UNKNOWN = 1 << 0
- # UNKNOWN:
- # Failed to query out the status of Disk.
STATUS_OK = 1 << 1
- # OK:
- # Disk is accessible with no issue.
STATUS_OTHER = 1 << 2
- # OTHER:
- # Should explain in Disk.status_info for detail.
STATUS_PREDICTIVE_FAILURE = 1 << 3
- # PREDICTIVE_FAILURE:
- # Disk is in unstable state and will predictive fail.
STATUS_ERROR = 1 << 4
- # ERROR:
- # Disk data is not accessible due to hardware issue or connection error.
STATUS_OFFLINE = 1 << 5
- # OFFLINE:
- # Disk is connected but disabled by array for internal issue
- # Should explain in Disk.status_info for reason.
STATUS_STARTING = 1 << 6
- # STARTING:
- # Disk is reviving from STOPPED status. Disk is not accessible.
STATUS_STOPPING = 1 << 7
- # STOPPING:
- # Disk is stopping by administrator. Disk is not accessible.
STATUS_STOPPED = 1 << 8
- # STOPPING:
- # Disk is stopped by administrator. Disk is not accessible.
STATUS_INITIALIZING = 1 << 9
- # INITIALIZING:
- # Disk is in initialing state.
- # Mostly shown when new disk inserted or creating spare disk.
- STATUS_RECONSTRUCTING = 1 << 10
- # RECONSTRUCTING:
- # Disk is in reconstructing date from other RAID member.
- # Should explain progress in Disk.status_info
-
- OPT_PROPERTIES = ['sn', 'part_num', 'vendor', 'model', 'status_info',
- 'owner_ctrler_id']
-
- def _value_convert(self, key_name, value, human, enum_as_number,
- list_convert):
- if enum_as_number is False:
- if key_name == 'status':
- value = self.status_to_str(value)
- elif key_name == 'disk_type':
- value = self.disk_type_to_str(value)
- if human:
- if key_name == 'size_bytes':
- value = sh(value, human)
- elif key_name == 'block_size':
- value = sh(value, human)
- return value
+
+ OPT_PROPERTIES = ['sn', 'part_num', 'vendor', 'model']

def __init__(self, _id, _name, _disk_type, _block_size, _num_of_blocks,
- _status, _system_id, _optional_data=None):
+ _status, _system_id, _optional_data=None, _plugin_data=None):
self._id = _id
self._name = _name
self._disk_type = _disk_type
@@ -304,6 +263,7 @@ class Disk(IData):
self._system_id = _system_id
self._optional_data = _check_opt_data(_optional_data,
self.OPT_PROPERTIES)
+ self._plugin_data = _plugin_data

@property
def size_bytes(self):
@@ -322,10 +282,10 @@ class Disk(IData):
@default_property('block_size', doc="Volume block size")
@default_property('num_of_blocks', doc="Number of blocks")
@default_property('status', doc="Enumerated volume status")
-@default_property('system_id', "System identifier")
-@default_property('pool_id', "Pool identifier")
-@default_property("optional_data", "Optional data")
-@default_property("plugin_data", "Private plugin data")
+@default_property('system_id', doc="System identifier")
+@default_property('pool_id', doc="Pool identifier")
+@default_property("optional_data", doc="Optional data")
+@default_property("plugin_data", doc="Private plugin data")
class Volume(IData):
"""
Represents a volume.
@@ -536,6 +496,7 @@ class Pool(IData):
MEMBER_TYPE_DISK_HDD = 18
MEMBER_TYPE_DISK_SSD = 19
MEMBER_TYPE_DISK_HYBRID = 110
+ MEMBER_TYPE_DISK_LUN = 111

MEMBER_TYPE_POOL = 2
MEMBER_TYPE_VOLUME = 3
@@ -553,6 +514,7 @@ class Pool(IData):
MEMBER_TYPE_DISK_HDD: Disk.DISK_TYPE_HDD,
MEMBER_TYPE_DISK_SSD: Disk.DISK_TYPE_SSD,
MEMBER_TYPE_DISK_HYBRID: Disk.DISK_TYPE_HYBRID,
+ MEMBER_TYPE_DISK_LUN: Disk.DISK_TYPE_LUN,
}

@staticmethod
diff --git a/tools/lsmcli/data_display.py b/tools/lsmcli/data_display.py
index 10f569b..05eda29 100644
--- a/tools/lsmcli/data_display.py
+++ b/tools/lsmcli/data_display.py
@@ -265,11 +265,12 @@ _DISK_TYPE_CONV = {
Disk.DISK_TYPE_SATA: 'SATA',
Disk.DISK_TYPE_SAS: 'SAS',
Disk.DISK_TYPE_FC: 'FC',
- Disk.DISK_TYPE_SOP: 'SOP',
+ Disk.DISK_TYPE_SOP: 'SCSI Over PCI-E(SSD)',
Disk.DISK_TYPE_NL_SAS: 'NL_SAS',
Disk.DISK_TYPE_HDD: 'HDD',
Disk.DISK_TYPE_SSD: 'SSD',
Disk.DISK_TYPE_HYBRID: 'HYBRID',
+ Disk.DISK_TYPE_LUN: 'Remote LUN',
}


@@ -288,7 +289,6 @@ _DISK_STATUS_CONV = {
Disk.STATUS_STOPPING: 'STOPPING',
Disk.STATUS_STOPPED: 'STOPPED',
Disk.STATUS_INITIALIZING: 'INITIALIZING',
- Disk.STATUS_RECONSTRUCTING: 'RECONSTRUCTING',
}
--
1.8.3.1
Tony Asleson
2014-06-10 19:11:08 UTC
Permalink
Patch series committed.

Thanks!

Regards,
Tony
Post by Gris Ge
1. Removed the LSM_FLAG_UNUSED_CHECK in C library query methods.
2. Removed duplicated checking on '--optoinal' lsmcli argument.
3. Added lsm.FsSnapshot.FLAG_RETRIEVE_FULL_INFO(Python) and
LSM_FS_SNAPSHOT_FLAG_RETRIEVE_FULL_INFO(C) constants.
1. Patch set from Tony: '[PATCH 0/6] Add optional data/plugin data'
2. Patch set from Tony: '[PATCH 1/4] lsm_convert.cpp: Remove duplicate code'
Thanks for the review and comments in advance.
C & Python Libaray: Add FLAG_RETRIEVE_FULL_INFO for query
Plugins: Sync with FLAG_RETRIEVE_FULL_INFO changes
lsmcli: Sync with FLAG_RETRIEVE_FULL_INFO changes
lsmcli: Fix optional property displaying
cmdtest.py: Add a simple optional data query test
lsmcli: Revert argument back to "-o, --optional"
C and Python library: Changes on lsm.Disk
c_binding/include/libstoragemgmt/libstoragemgmt.h | 33 +++---
.../include/libstoragemgmt/libstoragemgmt_types.h | 62 ++++++++++-
c_binding/lsm_mgmt.cpp | 16 +--
doc/man/lsmcli.1.in | 13 ++-
plugin/ontap/ontap.py | 14 ++-
plugin/sim/simarray.py | 10 +-
plugin/smispy/smis.py | 12 +-
python_binding/lsm/_client.py | 4 +-
python_binding/lsm/_data.py | 121 ++++++---------------
test/cmdtest.py | 21 +++-
tools/lsmcli/cmdline.py | 55 ++++++----
tools/lsmcli/data_display.py | 10 +-
12 files changed, 205 insertions(+), 166 deletions(-)
Loading...