summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Martin <jxm@risingtidesystems.com>2011-06-01 16:30:03 +0200
committerJerome Martin <jxm@risingtidesystems.com>2011-06-01 17:23:23 +0200
commitc68f4265a2810906227bb7e5f37bee711fb5b813 (patch)
tree52a250c2f4e0dd77c95c51bfe7080976d1098c39
parentc436cb8031ef2883ac2e3b6677d4313dfb766d65 (diff)
downloadtargetcli-c68f4265a2810906227bb7e5f37bee711fb5b813.tar.gz
Added auto_cd_after_create global.
* Automatically cd's to newly created object after a 'create' command if true. * Added autosave (always) of last created node's path under @last bookmark.
-rw-r--r--rtsadmin/ui_backstore.py25
-rw-r--r--rtsadmin/ui_backstore_legacy.py44
-rw-r--r--rtsadmin/ui_node.py50
-rw-r--r--rtsadmin/ui_target.py28
-rwxr-xr-xscripts/rtsadmin1
5 files changed, 109 insertions, 39 deletions
diff --git a/rtsadmin/ui_backstore.py b/rtsadmin/ui_backstore.py
index 9159d82..2d4282f 100644
--- a/rtsadmin/ui_backstore.py
+++ b/rtsadmin/ui_backstore.py
@@ -201,9 +201,12 @@ class UIPSCSIBackstore(UIBackstore):
except Exception, exception:
backstore.delete()
raise exception
- self.add_child(UIStorageObject(so))
+ ui_so = UIStorageObject(so)
+ self.add_child(ui_so)
self.log.info("Created pscsi storage object %s using %s"
% (name, dev))
+ return self.new_node(ui_so)
+
class UIRDDRBackstore(UIBackstore):
'''
@@ -239,9 +242,11 @@ class UIRDDRBackstore(UIBackstore):
except Exception, exception:
backstore.delete()
raise exception
- self.add_child(UIStorageObject(so))
+ ui_so = UIStorageObject(so)
+ self.add_child(ui_so)
self.log.info("Created rd_dr ramdisk storage object %s with size %s."
% (name, size))
+ return self.new_node(ui_so)
class UIRDMCPBackstore(UIBackstore):
'''
@@ -277,9 +282,11 @@ class UIRDMCPBackstore(UIBackstore):
except Exception, exception:
backstore.delete()
raise exception
- self.add_child(UIStorageObject(so))
+ ui_so = UIStorageObject(so)
+ self.add_child(ui_so)
self.log.info("Created rd_mcp ramdisk storage object %s with size %s."
% (name, size))
+ return self.new_node(ui_so)
class UIFileIOBackstore(UIBackstore):
'''
@@ -331,7 +338,9 @@ class UIFileIOBackstore(UIBackstore):
raise exception
self.log.info("Created fileio storage object %s with size %s."
% (name, size))
- self.add_child(UIStorageObject(so))
+ ui_so = UIStorageObject(so)
+ self.add_child(ui_so)
+ return self.new_node(ui_so)
elif size is not None and not is_dev:
backstore = FileIOBackstore(self.next_hba_index(), mode='create')
try:
@@ -344,7 +353,9 @@ class UIFileIOBackstore(UIBackstore):
backstore.delete()
raise exception
self.log.info("Created fileio storage object %s." % name)
- self.add_child(UIStorageObject(so))
+ ui_so = UIStorageObject(so)
+ self.add_child(ui_so)
+ return self.new_node(ui_so)
else:
self.log.error("For fileio, you must either specify both a file "
+ "and a size, or just a device path.")
@@ -372,9 +383,11 @@ class UIIBlockBackstore(UIBackstore):
except Exception, exception:
backstore.delete()
raise exception
- self.add_child(UIStorageObject(so))
+ ui_so = UIStorageObject(so)
+ self.add_child(ui_so)
self.log.info("Created iblock storage object %s using %s."
% (name, dev))
+ return self.new_node(ui_so)
class UIStorageObject(UIRTSLibNode, UIAttributes):
'''
diff --git a/rtsadmin/ui_backstore_legacy.py b/rtsadmin/ui_backstore_legacy.py
index 5e5aaa7..828e49b 100644
--- a/rtsadmin/ui_backstore_legacy.py
+++ b/rtsadmin/ui_backstore_legacy.py
@@ -124,19 +124,29 @@ class UIBackstoresLegacy(UINode):
if backstore_plugin == 'pscsi':
backstore = PSCSIBackstore(backstore_index, mode='create')
- self.add_child(UIPSCSIBackstoreLegacy(backstore))
+ ui_backstore = UIPSCSIBackstoreLegacy(backstore)
+ self.add_child(ui_backstore)
+ return self.new_node(ui_backstore)
elif backstore_plugin == 'rd_dr':
backstore = RDDRBackstore(backstore_index, mode='create')
- self.add_child(UIRDDRBackstoreLegacy(backstore))
+ ui_backstore = UIRDDRBackstoreLegacy(backstore)
+ self.add_child(ui_backstore)
+ return self.new_node(ui_backstore)
elif backstore_plugin == 'rd_mcp':
backstore = RDMCPBackstore(backstore_index, mode='create')
- self.add_child(UIRDMCPBackstoreLegacy(backstore))
+ ui_backstore = UIRDMCPBackstoreLegacy(backstore)
+ self.add_child(ui_backstore)
+ return self.new_node(ui_backstore)
elif backstore_plugin == 'fileio':
backstore = FileIOBackstore(backstore_index, mode='create')
- self.add_child(UIFileIOBackstoreLegacy(backstore))
+ ui_backstore = UIFileIOBackstoreLegacy(backstore)
+ self.add_child(ui_backstore)
+ return self.new_node(ui_backstore)
elif backstore_plugin == 'iblock':
backstore = IBlockBackstore(backstore_index, mode='create')
- self.add_child(UIIBlockBackstoreLegacy(backstore))
+ ui_backstore = UIIBlockBackstoreLegacy(backstore)
+ self.add_child(ui_backstore)
+ return self.new_node(ui_backstore)
else:
self.log.error("Invalid backstore plugin %s" % backstore_plugin)
return
@@ -325,9 +335,11 @@ class UIPSCSIBackstoreLegacy(UIBackstoreLegacy):
'''
self.assert_root()
so = PSCSIStorageObject(self.rtsnode, name, dev)
- self.add_child(UIStorageObjectLegacy(so))
+ ui_so = UIStorageObjectLegacy(so)
+ self.add_child(ui_so)
self.log.info("Created pscsi storage object %s using %s"
% (name, dev))
+ return self.new_node(ui_so)
class UIRDDRBackstoreLegacy(UIBackstoreLegacy):
'''
@@ -353,9 +365,11 @@ class UIRDDRBackstoreLegacy(UIBackstoreLegacy):
self.assert_root()
so = RDDRStorageObject(self.rtsnode, name, size,
self.prm_gen_wwn(generate_wwn))
- self.add_child(UIStorageObjectLegacy(so))
+ ui_so = UIStorageObjectLegacy(so)
+ self.add_child(ui_so)
self.log.info("Created rd_dr ramdisk storage object %s with size %s."
% (name, size))
+ return self.new_node(ui_so)
class UIRDMCPBackstoreLegacy(UIBackstoreLegacy):
'''
@@ -381,9 +395,11 @@ class UIRDMCPBackstoreLegacy(UIBackstoreLegacy):
self.assert_root()
so = RDMCPStorageObject(self.rtsnode, name, size,
self.prm_gen_wwn(generate_wwn))
- self.add_child(UIStorageObjectLegacy(so))
+ ui_so = UIStorageObjectLegacy(so)
+ self.add_child(ui_so)
self.log.info("Created rd_mcp ramdisk storage object %s with size %s."
% (name, size))
+ return self.new_node(ui_so)
class UIFileIOBackstoreLegacy(UIBackstoreLegacy):
'''
@@ -425,13 +441,17 @@ class UIFileIOBackstoreLegacy(UIBackstoreLegacy):
buffered_mode=self.prm_buffered(buffered))
self.log.info("Created fileio storage object %s with size %s."
% (name, size))
- self.add_child(UIStorageObjectLegacy(so))
+ ui_so = UIStorageObjectLegacy(so)
+ self.add_child(ui_so)
+ return self.new_node(ui_so)
elif size is not None and not is_dev:
so = FileIOStorageObject(self.rtsnode, name, file_or_dev, size,
gen_wwn=self.prm_gen_wwn(generate_wwn),
buffered_mode=self.prm_buffered(buffered))
self.log.info("Created fileio storage object %s." % name)
- self.add_child(UIStorageObjectLegacy(so))
+ ui_so = UIStorageObjectLegacy(so)
+ self.add_child(ui_so)
+ return self.new_node(ui_so)
else:
self.log.error("For fileio, you must either specify both a file "
+ "and a size, or just a device path.")
@@ -450,9 +470,11 @@ class UIIBlockBackstoreLegacy(UIBackstoreLegacy):
self.assert_root()
so = IBlockStorageObject(self.rtsnode, name, dev,
self.prm_gen_wwn(generate_wwn))
- self.add_child(UIStorageObjectLegacy(so))
+ ui_so = UIStorageObjectLegacy(so)
+ self.add_child(ui_so)
self.log.info("Created iblock storage object %s using %s."
% (name, dev))
+ return self.new_node(ui_so)
class UIStorageObjectLegacy(UIRTSLibNode, UIAttributes):
'''
diff --git a/rtsadmin/ui_node.py b/rtsadmin/ui_node.py
index 7c45c5e..677d31c 100644
--- a/rtsadmin/ui_node.py
+++ b/rtsadmin/ui_node.py
@@ -39,6 +39,9 @@ class UINode(ConfigNode):
[self.ui_type_bool,
'If true, use legacy HBA view, allowing to create more '
+ 'than one storage object per HBA.']
+ self._configuration_groups['global']['auto_cd_after_create'] = \
+ [self.ui_type_bool,
+ 'If true, changes current path to newly created objects.']
def assert_root(self):
'''
@@ -50,23 +53,21 @@ class UINode(ConfigNode):
raise ExecutionError("This privileged command is disabled: "
+ "you are not root.")
- def ui_command_refresh(self):
+ def new_node(self, new_node):
'''
- Refreshes and updates the objects tree from the current path.
- '''
- self.refresh()
-
- def ui_command_saveconfig(self):
- '''
- Saves the whole configuration tree to disk so that it will be restored
- on next boot. Unless you do that, changes are lost accross reboots.
+ Used to honor global 'auto_cd_after_create'.
+ Either returns None if the global is False, or the new_node if the
+ global is True. In both cases, set the @last bookmark to last_node.
'''
- self.assert_root()
- self.con.display("WARNING: Saving the current configuration to disk "
- + "will overwrite your boot settings.")
- self.con.display("The current target configuration will become the "
- + "default boot config.")
- system('PYTHONPATH="" python /usr/sbin/tcm_dump --o')
+ self.prefs['bookmarks']['last'] = new_node.path
+ self.prefs.save()
+ if self.prefs['auto_cd_after_create']:
+ self.log.info("Entering new node %s" % new_node.path)
+ # Piggy backs on cd instead of just returning new_node,
+ # so we update navigation history.
+ return self.ui_command_cd(new_node.path)
+ else:
+ return None
def refresh(self):
'''
@@ -97,6 +98,25 @@ class UINode(ConfigNode):
self.log.debug("Command %s succeeded." % command)
return result
+
+ def ui_command_refresh(self):
+ '''
+ Refreshes and updates the objects tree from the current path.
+ '''
+ self.refresh()
+
+ def ui_command_saveconfig(self):
+ '''
+ Saves the whole configuration tree to disk so that it will be restored
+ on next boot. Unless you do that, changes are lost accross reboots.
+ '''
+ self.assert_root()
+ self.con.display("WARNING: Saving the current configuration to disk "
+ + "will overwrite your boot settings.")
+ self.con.display("The current target configuration will become the "
+ + "default boot config.")
+ system('PYTHONPATH="" python /usr/sbin/tcm_dump --o')
+
def ui_command_status(self):
'''
Displays the current node's status summary.
diff --git a/rtsadmin/ui_target.py b/rtsadmin/ui_target.py
index ba4ba23..523e6d3 100644
--- a/rtsadmin/ui_target.py
+++ b/rtsadmin/ui_target.py
@@ -73,10 +73,12 @@ class UIFabricModule(UIRTSLibNode):
ui_target = UIMultiTPGTarget(target)
self.add_child(ui_target)
self.log.info("Created target %s." % wwn)
- ui_target.ui_command_create()
+ return ui_target.ui_command_create()
else:
- self.add_child(UITarget(target))
+ ui_target = UITarget(target)
+ self.add_child(ui_target)
self.log.info("Created target %s." % wwn)
+ return self.new_node(ui_target)
def ui_complete_create(self, parameters, text, current_param):
'''
@@ -238,7 +240,9 @@ class UIMultiTPGTarget(UIRTSLibNode):
if self.prefs['auto_enable_tpgt']:
tpg.enable = True
self.log.info("Successfully created TPG %s." % tpg.tag)
- self.add_child(UITPG(tpg))
+ ui_tpg = UITPG(tpg)
+ self.add_child(ui_tpg)
+ return self.new_node(ui_tpg)
def ui_command_delete(self, tag):
'''
@@ -413,7 +417,8 @@ class UINodeACLs(UINode):
else:
self.log.info("Successfully created Node ACL for %s"
% node_acl.node_wwn)
- self.add_child(UINodeACL(node_acl))
+ ui_node_acl = UINodeACL(node_acl)
+ self.add_child(ui_node_acl)
if add_mapped_luns:
for lun in self.tpg.luns:
@@ -421,6 +426,8 @@ class UINodeACLs(UINode):
self.log.info("Created mapped LUN %d." % lun.lun)
self.refresh()
+ return self.new_node(ui_node_acl)
+
def ui_command_delete(self, wwn):
'''
Deletes the Node ACL with the specified I{wwn}.
@@ -549,8 +556,10 @@ class UINodeACL(UIRTSLibNode, UIAttributes, UIParameters):
return
mlun = MappedLUN(self.rtsnode, mapped_lun, tpg_lun, write_protect)
- self.add_child(UIMappedLUN(mlun))
+ ui_mlun = UIMappedLUN(mlun)
+ self.add_child(ui_mlun)
self.log.info("Created Mapped LUN %s." % mlun.mapped_lun)
+ return self.new_node(ui_mlun)
def ui_command_delete(self, mapped_lun):
'''
@@ -693,7 +702,8 @@ class UILUNs(UINode):
lun_object = LUN(self.tpg, lun, storage_object)
self.log.info("Successfully created LUN %s." % lun_object.lun)
- self.add_child(UILUN(lun_object))
+ ui_lun = UILUN(lun_object)
+ self.add_child(ui_lun)
if add_mapped_luns:
for acl in self.tpg.node_acls:
@@ -715,6 +725,8 @@ class UILUNs(UINode):
% (mapped_lun, acl.node_wwn))
self.parent.refresh()
+ return self.new_node(ui_lun)
+
def ui_complete_create(self, parameters, text, current_param):
'''
Parameter auto-completion method for user command create.
@@ -880,7 +892,9 @@ class UIPortals(UINode):
ip_port, mode='create')
self.log.info("Successfully created network portal %s:%d."
% (ip_address, ip_port))
- self.add_child(UIPortal(portal))
+ ui_portal = UIPortal(portal)
+ self.add_child(ui_portal)
+ return self.new_node(ui_portal)
def ui_complete_create(self, parameters, text, current_param):
'''
diff --git a/scripts/rtsadmin b/scripts/rtsadmin
index d5692e0..832c798 100755
--- a/scripts/rtsadmin
+++ b/scripts/rtsadmin
@@ -42,6 +42,7 @@ class RTSAdmin(ConfigShell):
'tree_show_root': True,
'auto_enable_tpgt': True,
'auto_add_mapped_luns': True,
+ 'auto_cd_after_create': True,
'legacy_hba_view': False
}