summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Grover <andy@groveronline.com>2015-01-12 10:58:55 -0800
committerAndy Grover <andy@groveronline.com>2015-01-12 10:58:55 -0800
commit5025acdba6b0187231555e0391dbce91a4d2a263 (patch)
tree495f1bd6e1074b6e958bea1daa8b5c427abf04f9
parent3947c435cb32f8f8347b8f51f8dde967ac0d47c6 (diff)
parent1f3a182a166eace0865afeece11bbe77e81e3f31 (diff)
downloadtargetcli-5025acdba6b0187231555e0391dbce91a4d2a263.tar.gz
Merge pull request #49 from cvubrugier/document-parameters
Document target parameters and attributes
-rw-r--r--targetcli/ui_backstore.py32
-rw-r--r--targetcli/ui_node.py31
-rw-r--r--targetcli/ui_target.py51
3 files changed, 110 insertions, 4 deletions
diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py
index 5d30e5b..163b491 100644
--- a/targetcli/ui_backstore.py
+++ b/targetcli/ui_backstore.py
@@ -453,6 +453,38 @@ class UIStorageObject(UIRTSLibNode):
A storage object UI.
Abstract Base Class, do not instantiate.
'''
+ ui_desc_attributes = {
+ 'block_size': ('number', 'Block size of the underlying device.'),
+ 'emulate_3pc': ('number', 'If set to 1, enable Third Party Copy.'),
+ 'emulate_caw': ('number', 'If set to 1, enable Compare and Write.'),
+ 'emulate_dpo': ('number', 'If set to 1, turn on Disable Page Out.'),
+ 'emulate_fua_read': ('number', 'If set to 1, enable Force Unit Access read.'),
+ 'emulate_fua_write': ('number', 'If set to 1, enable Force Unit Access write.'),
+ 'emulate_model_alias': ('number', 'If set to 1, use the backend device name for the model alias.'),
+ 'emulate_rest_reord': ('number', 'If set to 0, the Queue Algorithm Modifier is Restricted Reordering.'),
+ 'emulate_tas': ('number', 'If set to 1, enable Task Aborted Status.'),
+ 'emulate_tpu': ('number', 'If set to 1, enable Thin Provisioning Unmap.'),
+ 'emulate_tpws': ('number', 'If set to 1, enable Thin Provisioning Write Same.'),
+ 'emulate_ua_intlck_ctrl': ('number', 'If set to 1, enable Unit Attention Interlock.'),
+ 'emulate_write_cache': ('number', 'If set to 1, turn on Write Cache Enable.'),
+ 'enforce_pr_isids': ('number', 'If set to 1, enforce persistent reservation ISIDs.'),
+ 'fabric_max_sectors': ('number', 'Maximum number of sectors the fabric can transfer at once.'),
+ 'hw_block_size': ('number', 'Hardware block size in bytes.'),
+ 'hw_max_sectors': ('number', 'Maximum number of sectors the hardware can transfer at once.'),
+ 'hw_pi_prot_type': ('number', 'If non-zero, DIF protection is enabled on the underlying hardware.'),
+ 'hw_queue_depth': ('number', 'Hardware queue depth.'),
+ 'is_nonrot': ('number', 'If set to 1, the backstore is a non rotational device.'),
+ 'max_unmap_block_desc_count': ('number', 'Maximum number of block descriptors for UNMAP.'),
+ 'max_unmap_lba_count': ('number', 'Maximum number of LBA for UNMAP.'),
+ 'max_write_same_len': ('number', 'Maximum length for WRITE_SAME.'),
+ 'optimal_sectors': ('number', 'Optimal request size in sectors.'),
+ 'pi_prot_format': ('number', 'DIF protection format.'),
+ 'pi_prot_type': ('number', 'DIF protection type.'),
+ 'queue_depth': ('number', 'Queue depth.'),
+ 'unmap_granularity': ('number', 'UNMAP granularity.'),
+ 'unmap_granularity_alignment': ('number', 'UNMAP granularity alignment.'),
+ }
+
def __init__(self, storage_object, parent):
name = storage_object.name
UIRTSLibNode.__init__(self, name, storage_object, parent)
diff --git a/targetcli/ui_node.py b/targetcli/ui_node.py
index 5abfd7f..838f124 100644
--- a/targetcli/ui_node.py
+++ b/targetcli/ui_node.py
@@ -101,6 +101,29 @@ class UINode(ConfigNode):
ConfigNode.ui_setgroup_global(self, parameter, value)
self.get_root().refresh()
+ def ui_type_yesno(self, value=None, enum=False, reverse=False):
+ '''
+ UI parameter type helper for "Yes" and "No" boolean values.
+ "Yes" and "No" are used for boolean iSCSI session parameters.
+ '''
+ if reverse:
+ if value is not None:
+ return value
+ else:
+ return 'n/a'
+ type_enum = ('Yes', 'No')
+ syntax = '|'.join(type_enum)
+ if value is None:
+ if enum:
+ return enum_type
+ else:
+ return syntax
+ elif value in type_enum:
+ return value
+ else:
+ raise ValueError("Syntax error, '%s' is not %s."
+ % (value, syntax))
+
class UIRTSLibNode(UINode):
'''
@@ -122,18 +145,18 @@ class UIRTSLibNode(UINode):
parameters_ro = self.rtsnode.list_parameters(writable=False)
for parameter in parameters:
writable = parameter not in parameters_ro
- description = "The %s parameter." % parameter
+ type, desc = getattr(self.__class__, 'ui_desc_parameters', {}).get(parameter, ('string', ''))
self.define_config_group_param(
- 'parameter', parameter, 'string', description, writable)
+ 'parameter', parameter, type, desc, writable)
# If the rtsnode has attributes, enable them
attributes = self.rtsnode.list_attributes()
attributes_ro = self.rtsnode.list_attributes(writable=False)
for attribute in attributes:
writable = attribute not in attributes_ro
- description = "The %s attribute." % attribute
+ type, desc = getattr(self.__class__, 'ui_desc_attributes', {}).get(attribute, ('string', ''))
self.define_config_group_param(
- 'attribute', attribute, 'string', description, writable)
+ 'attribute', attribute, type, desc, writable)
def ui_getgroup_attribute(self, attribute):
'''
diff --git a/targetcli/ui_target.py b/targetcli/ui_target.py
index 7fcaab0..8e3519a 100644
--- a/targetcli/ui_target.py
+++ b/targetcli/ui_target.py
@@ -390,6 +390,44 @@ class UIMultiTPGTarget(UIRTSLibNode):
class UITPG(UIRTSLibNode):
+ ui_desc_attributes = {
+ 'authentication': ('number', 'If set to 1, enforce authentication for this TPG.'),
+ 'cache_dynamic_acls': ('number', 'If set to 1 in demo mode, cache dynamically generated ACLs.'),
+ 'default_cmdsn_depth': ('number', 'Default CmdSN (Command Sequence Number) depth.'),
+ 'default_erl': ('number', 'Default Error Recovery Level.'),
+ 'demo_mode_discovery': ('number', 'If set to 1 in demo mode, enable discovery.'),
+ 'demo_mode_write_protect': ('number', 'If set to 1 in demo mode, prevent writes to LUNs.'),
+ 'generate_node_acls': ('number', 'If set to 1, allow all initiators to login (i.e. demo mode).'),
+ 'login_timeout': ('number', 'Login timeout value in seconds.'),
+ 'netif_timeout': ('number', 'NIC failure timeout in seconds.'),
+ 'prod_mode_write_protect': ('number', 'If set to 1, prevent writes to LUNs.'),
+ 't10_pi': ('number', 'If set to 1, enable T10 Protection Information.'),
+ }
+
+ ui_desc_parameters = {
+ 'AuthMethod': ('string', 'Authentication method used by the TPG.'),
+ 'DataDigest': ('string', 'If set to CRC32C, the integrity of the PDU data part is verified.'),
+ 'DataPDUInOrder': ('yesno', 'If set to Yes, the data PDUs within sequences must be in order.'),
+ 'DataSequenceInOrder': ('yesno', 'If set to Yes, the data sequences must be in order.'),
+ 'DefaultTime2Retain': ('number', 'Maximum time, in seconds, after an initial wait, before which an active task reassignment is still possible after an unexpected connection termination or a connection reset.'),
+ 'DefaultTime2Wait': ('number', 'Minimum time, in seconds, to wait before attempting an explicit/implicit logout or an active task reassignment after an unexpected connection termination or a connection reset.'),
+ 'ErrorRecoveryLevel': ('number', 'Recovery levels represent a combination of recovery capabilities.'),
+ 'FirstBurstLength': ('number', 'Maximum amount in bytes of unsolicited data an initiator may send.'),
+ 'HeaderDigest': ('yesno', 'If set to CRC32C, the integrity of the PDU header part is verified.'),
+ 'IFMarker': ('yesno', 'Deprecated according to RFC 7143.'),
+ 'IFMarkInt': ('string', 'Deprecated according to RFC 7143.'),
+ 'ImmediateData': ('string', 'Immediate data support.'),
+ 'InitialR2T': ('yesno', 'If set to No, the default use of R2T (Ready To Transfer) is disabled.'),
+ 'MaxBurstLength': ('number', 'Maximum SCSI data payload in bytes in a Data-In or a solicited Data-Out iSCSI sequence.'),
+ 'MaxConnections': ('number', 'Maximum number of connections acceptable.'),
+ 'MaxOutstandingR2T': ('number', 'Maximum number of outstanding R2Ts per task.'),
+ 'MaxRecvDataSegmentLength': ('number', 'Maximum data segment length in bytes the target can receive in an iSCSI PDU.'),
+ 'MaxXmitDataSegmentLength': ('number', 'Outgoing MaxRecvDataSegmentLength sent over the wire during iSCSI login response.'),
+ 'OFMarker': ('yesno', 'Deprecated according to RFC 7143.'),
+ 'OFMarkInt': ('string', 'Deprecated according to RFC 7143.'),
+ 'TargetAlias': ('string', 'Human-readable target name or description.'),
+ }
+
'''
A generic TPG UI.
'''
@@ -734,6 +772,19 @@ class UINodeACL(UIRTSLibNode):
All sets are performed on all NodeACLs.
This is to make management of multiple ACLs easier.
'''
+ ui_desc_attributes = {
+ 'dataout_timeout': ('number', 'Data-Out timeout in seconds before invoking recovery.'),
+ 'dataout_timeout_retries': ('number', 'Number of Data-Out timeout recovery attempts before failing a path.'),
+ 'default_erl': ('number', 'Default Error Recovery Level.'),
+ 'nopin_response_timeout': ('number', 'Nop-In response timeout in seconds.'),
+ 'nopin_timeout': ('number', 'Nop-In timeout in seconds.'),
+ 'random_datain_pdu_offsets': ('number', 'If set to 1, request random Data-In PDU offsets.'),
+ 'random_datain_seq_offsets': ('number', 'If set to 1, request random Data-In sequence offsets.'),
+ 'random_r2t_offsets': ('number', 'If set to 1, request random R2T (Ready To Transfer) offsets.'),
+ }
+
+ ui_desc_parameters = UITPG.ui_desc_parameters
+
def __init__(self, name, parent):
# Don't want to duplicate work in UIRTSLibNode, so call it but