diff options
author | Jerome Martin <jxm@risingtidesystems.com> | 2011-06-14 21:45:03 +0200 |
---|---|---|
committer | Jerome Martin <jxm@risingtidesystems.com> | 2011-07-18 17:43:22 +0200 |
commit | e83faf72fae59ea85272874753e06d8c6313d219 (patch) | |
tree | 3264e30a95bbb803666388a4f582311341835406 | |
parent | ccb88b277e88a566c8e84f3e44d5aaf3104da1e8 (diff) | |
download | targetcli-e83faf72fae59ea85272874753e06d8c6313d219.tar.gz |
Converted to refactored ConfigShell/Node layout.
* Now using console, log, prefs through shell.
* Root node binds to shell, not the other way.
* Replaced del_child() calls by remove_child()
* Replaced a children loop scan by ConfigNode get_child() method.
-rw-r--r-- | rtsadmin/ui_backstore.py | 144 | ||||
-rw-r--r-- | rtsadmin/ui_backstore_legacy.py | 161 | ||||
-rw-r--r-- | rtsadmin/ui_node.py | 40 | ||||
-rw-r--r-- | rtsadmin/ui_root.py | 51 | ||||
-rw-r--r-- | rtsadmin/ui_target.py | 233 | ||||
-rwxr-xr-x | scripts/rtsadmin | 15 |
6 files changed, 302 insertions, 342 deletions
diff --git a/rtsadmin/ui_backstore.py b/rtsadmin/ui_backstore.py index 2ba63ff..ddaae69 100644 --- a/rtsadmin/ui_backstore.py +++ b/rtsadmin/ui_backstore.py @@ -44,27 +44,25 @@ class UIBackstores(UINode): ''' The backstores container UI. ''' - def __init__(self): - UINode.__init__(self) - self.name = 'backstores' + def __init__(self, parent): + UINode.__init__(self, 'backstores', parent) self.cfs_cwd = "%s/core" % self.cfs_cwd self.refresh() def refresh(self): self._children = set([]) - self.add_child(UIPSCSIBackstore()) - self.add_child(UIRDDRBackstore()) - self.add_child(UIRDMCPBackstore()) - self.add_child(UIFileIOBackstore()) - self.add_child(UIIBlockBackstore()) + UIPSCSIBackstore(self) + UIRDDRBackstore(self) + UIRDMCPBackstore(self) + UIFileIOBackstore(self) + UIIBlockBackstore(self) class UIBackstore(UINode): ''' A backstore UI. ''' - def __init__(self, plugin): - UINode.__init__(self) - self.name = plugin + def __init__(self, plugin, parent): + UINode.__init__(self, plugin, parent) self.cfs_cwd = "%s/core" % self.cfs_cwd self.refresh() @@ -72,9 +70,8 @@ class UIBackstore(UINode): self._children = set([]) for so in RTSRoot().storage_objects: if so.backstore.plugin == self.name: - ui_so = UIStorageObject(so) + ui_so = UIStorageObject(so, self) ui_so.name = dedup_so_name(so) - self.add_child(ui_so) def summary(self): no_storage_objects = len(self._children) @@ -88,18 +85,18 @@ class UIBackstore(UINode): generate_wwn = \ self.ui_eval_param(generate_wwn, 'bool', True) if generate_wwn: - self.log.info("Generating a wwn serial.") + self.shell.log.info("Generating a wwn serial.") else: - self.log.info("Not generating a wwn serial.") + self.shell.log.info("Not generating a wwn serial.") return generate_wwn def prm_buffered(self, buffered): generate_wwn = \ self.ui_eval_param(buffered, 'bool', True) if buffered: - self.log.info("Using buffered mode.") + self.shell.log.info("Using buffered mode.") else: - self.log.info("Not using buffered mode.") + self.shell.log.info("Not using buffered mode.") return buffered def ui_command_delete(self, name): @@ -114,19 +111,18 @@ class UIBackstore(UINode): Deletes the storage object named mystorage, and all associated LUNs. ''' self.assert_root() - for child in self.children: - if child.name == name: - hba = child.rtsnode.backstore - child.rtsnode.delete() - if not hba.storage_objects: - hba.delete() - self.del_child(child) - self.log.info("Deleted storage object %s." % name) - self.parent.parent.refresh() - break + try: + child = self.get_child(name) + except ValueError: + self.shell.log.error("No storage object named %s." % name) else: - self.log.error("Could not find storage object to delete: %s." - % name) + hba = child.rtsnode.backstore + child.rtsnode.delete() + if not hba.storage_objects: + hba.delete() + self.remove_child(child) + self.shell.log.info("Deleted storage object %s." % name) + self.parent.parent.refresh() def ui_complete_delete(self, parameters, text, current_param): ''' @@ -153,12 +149,12 @@ class UIBackstore(UINode): return completions def next_hba_index(self): - self.log.debug("%r" % [(backstore.plugin, backstore.index) - for backstore in RTSRoot().backstores]) + self.shell.log.debug("%r" % [(backstore.plugin, backstore.index) + for backstore in RTSRoot().backstores]) indexes = [backstore.index for backstore in RTSRoot().backstores if backstore.plugin == self.name] - self.log.debug("Existing %s backstore indexes: %r" - % (self.name, indexes)) + self.shell.log.debug("Existing %s backstore indexes: %r" + % (self.name, indexes)) for index in range(1048576): if index not in indexes: backstore_index = index @@ -167,8 +163,8 @@ class UIBackstore(UINode): if backstore_index is None: raise ExecutionError("Cannot find an available backstore index.") else: - self.log.debug("First available %s backstore index is %d." - % (self.name, backstore_index)) + self.shell.log.debug("First available %s backstore index is %d." + % (self.name, backstore_index)) return backstore_index def assert_available_so_name(self, name): @@ -181,8 +177,8 @@ class UIPSCSIBackstore(UIBackstore): ''' PSCSI backstore UI. ''' - def __init__(self): - UIBackstore.__init__(self, 'pscsi') + def __init__(self, parent): + UIBackstore.__init__(self, 'pscsi', parent) def ui_command_create(self, name, dev): ''' @@ -201,10 +197,9 @@ class UIPSCSIBackstore(UIBackstore): except Exception, exception: backstore.delete() raise exception - ui_so = UIStorageObject(so) - self.add_child(ui_so) - self.log.info("Created pscsi storage object %s using %s" - % (name, dev)) + ui_so = UIStorageObject(so, self) + self.shell.log.info("Created pscsi storage object %s using %s" + % (name, dev)) return self.new_node(ui_so) @@ -212,8 +207,8 @@ class UIRDDRBackstore(UIBackstore): ''' RDDR backstore UI. ''' - def __init__(self): - UIBackstore.__init__(self, 'rd_dr') + def __init__(self, parent): + UIBackstore.__init__(self, 'rd_dr', parent) def ui_command_create(self, name, size, generate_wwn=None): ''' @@ -242,18 +237,17 @@ class UIRDDRBackstore(UIBackstore): except Exception, exception: backstore.delete() raise exception - ui_so = UIStorageObject(so) - self.add_child(ui_so) - self.log.info("Created rd_dr ramdisk storage object %s with size %s." - % (name, size)) + ui_so = UIStorageObject(so, self) + self.shell.log.info("Created rd_dr ramdisk %s with size %s." + % (name, size)) return self.new_node(ui_so) class UIRDMCPBackstore(UIBackstore): ''' RDMCP backstore UI. ''' - def __init__(self): - UIBackstore.__init__(self, 'rd_mcp') + def __init__(self, parent): + UIBackstore.__init__(self, 'rd_mcp', parent) def ui_command_create(self, name, size, generate_wwn=None): ''' @@ -282,18 +276,17 @@ class UIRDMCPBackstore(UIBackstore): except Exception, exception: backstore.delete() raise exception - ui_so = UIStorageObject(so) - self.add_child(ui_so) - self.log.info("Created rd_mcp ramdisk storage object %s with size %s." - % (name, size)) + ui_so = UIStorageObject(so, self) + self.shell.log.info("Created rd_mcp ramdisk %s with size %s." + % (name, size)) return self.new_node(ui_so) class UIFileIOBackstore(UIBackstore): ''' FileIO backstore UI. ''' - def __init__(self): - UIBackstore.__init__(self, 'fileio') + def __init__(self, parent): + UIBackstore.__init__(self, 'fileio', parent) def ui_command_create(self, name, file_or_dev, size=None, generate_wwn=None, buffered=None): @@ -321,8 +314,8 @@ class UIFileIOBackstore(UIBackstore): ''' self.assert_root() self.assert_available_so_name(name) - self.log.debug('Using params: size=%s generate_wwn=%s buffered=%s' - % (size, generate_wwn, buffered)) + self.shell.log.debug("Using params size=%s generate_wwn=%s buffered=%s" + % (size, generate_wwn, buffered)) is_dev = get_block_type(file_or_dev) is not None \ or is_disk_partition(file_or_dev) @@ -336,10 +329,9 @@ class UIFileIOBackstore(UIBackstore): except Exception, exception: backstore.delete() raise exception - self.log.info("Created fileio storage object %s with size %s." - % (name, size)) - ui_so = UIStorageObject(so) - self.add_child(ui_so) + self.shell.log.info("Created fileio %s with size %s." + % (name, size)) + ui_so = UIStorageObject(so, self) return self.new_node(ui_so) elif size is not None and not is_dev: backstore = FileIOBackstore(self.next_hba_index(), mode='create') @@ -352,20 +344,19 @@ class UIFileIOBackstore(UIBackstore): except Exception, exception: backstore.delete() raise exception - self.log.info("Created fileio storage object %s." % name) - ui_so = UIStorageObject(so) - self.add_child(ui_so) + self.shell.log.info("Created fileio %s." % name) + ui_so = UIStorageObject(so, self) 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.") + self.shell.log.error("For fileio, you must either specify both a " + + "file and a size, or just a device path.") class UIIBlockBackstore(UIBackstore): ''' IBlock backstore UI. ''' - def __init__(self): - UIBackstore.__init__(self, 'iblock') + def __init__(self, parent): + UIBackstore.__init__(self, 'iblock', parent) def ui_command_create(self, name, dev, generate_wwn=None): ''' @@ -383,19 +374,18 @@ class UIIBlockBackstore(UIBackstore): except Exception, exception: backstore.delete() raise exception - ui_so = UIStorageObject(so) - self.add_child(ui_so) - self.log.info("Created iblock storage object %s using %s." - % (name, dev)) + ui_so = UIStorageObject(so, self) + self.shell.log.info("Created iblock storage object %s using %s." + % (name, dev)) return self.new_node(ui_so) class UIStorageObject(UIRTSLibNode): ''' A storage object UI. ''' - def __init__(self, storage_object): - UIRTSLibNode.__init__(self, storage_object) - self.name = storage_object.name + def __init__(self, storage_object, parent): + name = storage_object.name + UIRTSLibNode.__init__(self, name, storage_object, parent) self.cfs_cwd = storage_object.path self.refresh() @@ -404,8 +394,8 @@ class UIStorageObject(UIRTSLibNode): Displays the version of the current backstore's plugin. ''' backstore = self.rtsnode.backstore - self.con.display("Backstore plugin %s %s" \ - % (backstore.plugin, backstore.version)) + self.shell.con.display("Backstore plugin %s %s" + % (backstore.plugin, backstore.version)) def summary(self): so = self.rtsnode diff --git a/rtsadmin/ui_backstore_legacy.py b/rtsadmin/ui_backstore_legacy.py index 3f78316..47ccd02 100644 --- a/rtsadmin/ui_backstore_legacy.py +++ b/rtsadmin/ui_backstore_legacy.py @@ -19,9 +19,8 @@ class UIBackstoresLegacy(UINode): ''' The backstores container UI. ''' - def __init__(self): - UINode.__init__(self) - self.name = 'backstores' + def __init__(self, parent): + UINode.__init__(self, 'backstores', parent) self.cfs_cwd = "%s/core" % self.cfs_cwd self.refresh() @@ -30,15 +29,15 @@ class UIBackstoresLegacy(UINode): for backstore in RTSRoot().backstores: backstore_plugin = backstore.plugin if backstore_plugin == 'pscsi': - self.add_child(UIPSCSIBackstoreLegacy(backstore)) + UIPSCSIBackstoreLegacy(backstore, self) elif backstore_plugin == 'rd_dr': - self.add_child(UIRDDRBackstoreLegacy(backstore)) + UIRDDRBackstoreLegacy(backstore, self) elif backstore_plugin == 'rd_mcp': - self.add_child(UIRDMCPBackstoreLegacy(backstore)) + UIRDMCPBackstoreLegacy(backstore, self) elif backstore_plugin == 'fileio': - self.add_child(UIFileIOBackstoreLegacy(backstore)) + UIFileIOBackstoreLegacy(backstore, self) elif backstore_plugin == 'iblock': - self.add_child(UIIBlockBackstoreLegacy(backstore)) + UIIBlockBackstoreLegacy(backstore, self) def summary(self): no_backstores = len(self._children) @@ -104,54 +103,45 @@ class UIBackstoresLegacy(UINode): Creates a new backstore, using the B{iblock} I{backstore_plugin}. ''' self.assert_root() - self.log.debug("%r" % [(backstore.plugin, backstore.index) - for backstore in RTSRoot().backstores]) + self.shell.log.debug("%r" % [(backstore.plugin, backstore.index) + for backstore in RTSRoot().backstores]) indexes = [backstore.index for backstore in RTSRoot().backstores if backstore.plugin == backstore_plugin] - self.log.debug("Existing %s backstore indexes: %r" - % (backstore_plugin, indexes)) + self.shell.log.debug("Existing %s backstore indexes: %r" + % (backstore_plugin, indexes)) for index in range(1048576): if index not in indexes: backstore_index = index break if backstore_index is None: - self.log.error("Cannot find an available backstore index.") + self.shell.log.error("Cannot find an available backstore index.") return else: - self.log.info("First available %s backstore index is %d." - % (backstore_plugin, backstore_index)) + self.shell.log.info("First available %s backstore index is %d." + % (backstore_plugin, backstore_index)) if backstore_plugin == 'pscsi': backstore = PSCSIBackstore(backstore_index, mode='create') - ui_backstore = UIPSCSIBackstoreLegacy(backstore) - self.add_child(ui_backstore) - return self.new_node(ui_backstore) + return self.new_node(UIPSCSIBackstoreLegacy(backstore, self)) elif backstore_plugin == 'rd_dr': backstore = RDDRBackstore(backstore_index, mode='create') - ui_backstore = UIRDDRBackstoreLegacy(backstore) - self.add_child(ui_backstore) - return self.new_node(ui_backstore) + return self.new_node(UIRDDRBackstoreLegacy(backstore, self)) elif backstore_plugin == 'rd_mcp': backstore = RDMCPBackstore(backstore_index, mode='create') - ui_backstore = UIRDMCPBackstoreLegacy(backstore) - self.add_child(ui_backstore) - return self.new_node(ui_backstore) + return self.new_node(UIRDMCPBackstoreLegacy(backstore, self)) elif backstore_plugin == 'fileio': backstore = FileIOBackstore(backstore_index, mode='create') - ui_backstore = UIFileIOBackstoreLegacy(backstore) - self.add_child(ui_backstore) - return self.new_node(ui_backstore) + return self.new_node(UIFileIOBackstoreLegacy(backstore, self)) elif backstore_plugin == 'iblock': backstore = IBlockBackstore(backstore_index, mode='create') - ui_backstore = UIIBlockBackstoreLegacy(backstore) - self.add_child(ui_backstore) - return self.new_node(ui_backstore) + return self.new_node(UIIBlockBackstoreLegacy(backstore, self)) else: - self.log.error("Invalid backstore plugin %s" % backstore_plugin) + self.shell.log.error("Invalid backstore plugin %s" + % backstore_plugin) return - self.log.info("Created new backstore %s" % backstore.name) + self.shell.log.info("Created new backstore %s" % backstore.name) def ui_complete_create(self, parameters, text, current_param): ''' @@ -190,16 +180,15 @@ class UIBackstoresLegacy(UINode): That would recursively delete the B{iblock} backstore with index 2. ''' self.assert_root() - for child in self.children: - if child.name == backstore: - child.rtsnode.delete() - self.del_child(child) - self.log.info("Deleted backstore %s." % backstore) - self.parent.refresh() - break + try: + child = self.get_child(backstore) + except ValueError: + self.shell.log.error("No backstore named %s." % backstore) else: - self.log.error("Cannot find backstore to delete: %s." - % backstore) + child.rtsnode.delete() + self.remove_child(child) + self.shell.log.info("Deleted backstore %s." % backstore) + self.parent.refresh() def ui_complete_delete(self, parameters, text, current_param): ''' @@ -229,16 +218,15 @@ class UIBackstoreLegacy(UIRTSLibNode): ''' A backstore UI. ''' - def __init__(self, backstore): - UIRTSLibNode.__init__(self, backstore) - self.name = backstore.name + def __init__(self, backstore, parent): + UIRTSLibNode.__init__(self, backstore.name, backstore, parent) self.cfs_cwd = backstore.path self.refresh() def refresh(self): self._children = set([]) for storage_object in self.rtsnode.storage_objects: - self.add_child(UIStorageObjectLegacy(storage_object)) + UIStorageObjectLegacy(storage_object, self) def summary(self): no_storage_objects = len(self._children) @@ -252,26 +240,26 @@ class UIBackstoreLegacy(UIRTSLibNode): generate_wwn = \ self.ui_eval_param(generate_wwn, 'bool', True) if generate_wwn: - self.log.info("Generating a wwn serial.") + self.shell.log.info("Generating a wwn serial.") else: - self.log.info("Not generating a wwn serial.") + self.shell.log.info("Not generating a wwn serial.") return generate_wwn def prm_buffered(self, buffered): generate_wwn = \ self.ui_eval_param(buffered, 'bool', True) if buffered: - self.log.info("Using buffered mode.") + self.shell.log.info("Using buffered mode.") else: - self.log.info("Not using buffered mode.") + self.shell.log.info("Not using buffered mode.") return buffered def ui_command_version(self): ''' Displays the version of the current backstore's plugin. ''' - self.con.display("Backstore plugin %s %s" \ - % (self.rtsnode.plugin, self.rtsnode.version)) + self.shell.con.display("Backstore plugin %s %s" + % (self.rtsnode.plugin, self.rtsnode.version)) def ui_command_delete(self, name): ''' @@ -285,16 +273,15 @@ class UIBackstoreLegacy(UIRTSLibNode): Deletes the storage object named mystorage, and all associated LUNs. ''' self.assert_root() - for child in self.children: - if child.name == name: - child.rtsnode.delete() - self.del_child(child) - self.log.info("Deleted storage object %s." % name) - self.parent.parent.refresh() - break + try: + child = self.get_child(name) + except ValueError: + self.shell.log.error("No storage object named %s." % name) else: - self.log.error("Could not find storage object to delete: %s." - % name) + child.rtsnode.delete() + self.remove_child(child) + self.shell.log.info("Deleted storage object %s." % name) + self.parent.parent.refresh() def ui_complete_delete(self, parameters, text, current_param): ''' @@ -335,10 +322,9 @@ class UIPSCSIBackstoreLegacy(UIBackstoreLegacy): ''' self.assert_root() so = PSCSIStorageObject(self.rtsnode, name, dev) - ui_so = UIStorageObjectLegacy(so) - self.add_child(ui_so) - self.log.info("Created pscsi storage object %s using %s" - % (name, dev)) + ui_so = UIStorageObjectLegacy(so, self) + self.shell.log.info("Created pscsi storage object %s using %s." + % (name, dev)) return self.new_node(ui_so) class UIRDDRBackstoreLegacy(UIBackstoreLegacy): @@ -365,10 +351,9 @@ class UIRDDRBackstoreLegacy(UIBackstoreLegacy): self.assert_root() so = RDDRStorageObject(self.rtsnode, name, size, self.prm_gen_wwn(generate_wwn)) - ui_so = UIStorageObjectLegacy(so) - self.add_child(ui_so) - self.log.info("Created rd_dr ramdisk storage object %s with size %s." - % (name, size)) + ui_so = UIStorageObjectLegacy(so, self) + self.shell.log.info("Created rd_dr ramdisk %s with size %s." + % (name, size)) return self.new_node(ui_so) class UIRDMCPBackstoreLegacy(UIBackstoreLegacy): @@ -395,10 +380,9 @@ class UIRDMCPBackstoreLegacy(UIBackstoreLegacy): self.assert_root() so = RDMCPStorageObject(self.rtsnode, name, size, self.prm_gen_wwn(generate_wwn)) - ui_so = UIStorageObjectLegacy(so) - self.add_child(ui_so) - self.log.info("Created rd_mcp ramdisk storage object %s with size %s." - % (name, size)) + ui_so = UIStorageObjectLegacy(so, self) + self.shell.log.info("Created rd_mcp ramdisk %s with size %s." + % (name, size)) return self.new_node(ui_so) class UIFileIOBackstoreLegacy(UIBackstoreLegacy): @@ -430,8 +414,8 @@ class UIFileIOBackstoreLegacy(UIBackstoreLegacy): - B{t}, B{T}, B{tB}, B{TB} for TB (terabytes) ''' self.assert_root() - self.log.debug('Using params: size=%s generate_wwn=%s buffered=%s' - % (size, generate_wwn, buffered)) + self.shell.log.debug('Using params size=%s generate_wwn=%s buffered=%s' + % (size, generate_wwn, buffered)) is_dev = get_block_type(file_or_dev) is not None \ or is_disk_partition(file_or_dev) @@ -439,22 +423,20 @@ class UIFileIOBackstoreLegacy(UIBackstoreLegacy): so = FileIOStorageObject(self.rtsnode, name, file_or_dev, gen_wwn=self.prm_gen_wwn(generate_wwn), buffered_mode=self.prm_buffered(buffered)) - self.log.info("Created fileio storage object %s with size %s." - % (name, size)) - ui_so = UIStorageObjectLegacy(so) - self.add_child(ui_so) + self.shell.log.info("Created fileio %s with size %s." + % (name, size)) + ui_so = UIStorageObjectLegacy(so, self) 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) - ui_so = UIStorageObjectLegacy(so) - self.add_child(ui_so) + self.shell.log.info("Created fileio storage object %s." % name) + ui_so = UIStorageObjectLegacy(so, self) 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.") + self.shell.log.error("For fileio, you must either specify both a " + + "file and a size, or just a device path.") class UIIBlockBackstoreLegacy(UIBackstoreLegacy): ''' @@ -470,19 +452,18 @@ class UIIBlockBackstoreLegacy(UIBackstoreLegacy): self.assert_root() so = IBlockStorageObject(self.rtsnode, name, dev, self.prm_gen_wwn(generate_wwn)) - ui_so = UIStorageObjectLegacy(so) - self.add_child(ui_so) - self.log.info("Created iblock storage object %s using %s." - % (name, dev)) + ui_so = UIStorageObjectLegacy(so, self) + self.shell.log.info("Created iblock storage object %s using %s." + % (name, dev)) return self.new_node(ui_so) class UIStorageObjectLegacy(UIRTSLibNode): ''' A storage object UI. ''' - def __init__(self, storage_object): - UIRTSLibNode.__init__(self, storage_object) - self.name = storage_object.name + def __init__(self, storage_object, parent): + name = storage_object.name + UIRTSLibNode.__init__(self, name, storage_object, parent) self.cfs_cwd = storage_object.path self.refresh() diff --git a/rtsadmin/ui_node.py b/rtsadmin/ui_node.py index 08ed84c..dcbc035 100644 --- a/rtsadmin/ui_node.py +++ b/rtsadmin/ui_node.py @@ -25,8 +25,8 @@ class UINode(ConfigNode): ''' Our rtsadmin basic UI node. ''' - def __init__(self): - ConfigNode.__init__(self) + def __init__(self, name, parent=None, shell=None): + ConfigNode.__init__(self, name, parent, shell) self.cfs_cwd = RTSRoot.configfs_dir self.define_config_group_param( 'global', 'auto_enable_tpgt', 'bool', @@ -59,10 +59,10 @@ class UINode(ConfigNode): 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.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) + self.shell.prefs['bookmarks']['last'] = new_node.path + self.shell.prefs.save() + if self.shell.prefs['auto_cd_after_create']: + self.shell.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) @@ -82,20 +82,20 @@ class UINode(ConfigNode): and not just configshell's ExecutionError. ''' if command == '_cfs': - self.log.info(self.cfs_cwd) + self.shell.log.info(self.cfs_cwd) return elif command == '_sh': - self.log.info("Opening a shell in %s." % self.cfs_cwd) - self.con.display("Type [CTRL-D] or exit to come back.") + self.shell.log.info("Opening a shell in %s." % self.cfs_cwd) + self.shell.con.display("Type [CTRL-D] or exit to come back.") system("(cd %s; bash)" % self.cfs_cwd ) return try: result = ConfigNode.execute_command(self, command, pparams, kparams) except RTSLibError, msg: - self.log.error(msg) + self.shell.log.error(msg) else: - self.log.debug("Command %s succeeded." % command) + self.shell.log.debug("Command %s succeeded." % command) return result @@ -111,10 +111,10 @@ class UINode(ConfigNode): 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.") + self.shell.con.display("WARNING: Saving current configuration to " + + "disk will overwrite your boot settings.") + self.shell.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): @@ -126,7 +126,7 @@ class UINode(ConfigNode): B{ls} ''' description, is_healthy = self.summary() - self.log.info("Status for %s: %s" % (self.path, description)) + self.shell.log.info("Status for %s: %s" % (self.path, description)) def ui_setgroup_global(self, parameter, value): ConfigNode.ui_setgroup_global(self, parameter, value) @@ -136,12 +136,12 @@ class UIRTSLibNode(UINode): ''' A subclass of UINode for nodes with an underlying RTSLib object. ''' - def __init__(self, rtslib_object): + def __init__(self, name, rtslib_object, parent): ''' Call from the class that inherits this, with the rtslib object that should be checked upon. ''' - UINode.__init__(self) + UINode.__init__(self, name, parent) self.rtsnode = rtslib_object # If the rtsnode has parameters, use them @@ -168,8 +168,8 @@ class UIRTSLibNode(UINode): RTSLib object still exists before returning. ''' if not self.rtsnode.exists: - self.log.error("The underlying rtslib object for " - + "%s does not exist." % self.path) + self.shell.log.error("The underlying rtslib object for " + + "%s does not exist." % self.path) root = self.get_root() root.refresh() return root diff --git a/rtsadmin/ui_root.py b/rtsadmin/ui_root.py index 1735888..906a0fe 100644 --- a/rtsadmin/ui_root.py +++ b/rtsadmin/ui_root.py @@ -27,10 +27,9 @@ class UIRoot(UINode): ''' The rtsadmin hierarchy root node. ''' - def __init__(self, as_root=False): + def __init__(self, shell, as_root=False): self.loaded = False - UINode.__init__(self) - self.name = '/' + UINode.__init__(self, '/', shell=shell) self.as_root = as_root def refresh(self): @@ -38,37 +37,37 @@ class UIRoot(UINode): Refreshes the tree of target fabric modules. ''' self._children = set([]) - if self.prefs['legacy_hba_view']: - self.add_child(UIBackstoresLegacy()) + if self.shell.prefs['legacy_hba_view']: + UIBackstoresLegacy(self) else: - self.add_child(UIBackstores()) + UIBackstores(self) if not self.loaded: - self.log.debug("Refreshing in non-loaded mode.") + self.shell.log.debug("Refreshing in non-loaded mode.") for fabric_module in RTSRoot().fabric_modules: if fabric_module: - self.log.info("Using %s fabric module." \ - % fabric_module.name) - self.add_child(UIFabricModule(fabric_module)) + self.shell.log.info("Using %s fabric module." \ + % fabric_module.name) + UIFabricModule(fabric_module, self) elif self.as_root: try: for step in fabric_module.load(yield_steps=True): (action, taken, desc) = step if taken: - self.log.info(desc) - self.log.info("Done loading %s fabric module." \ - % fabric_module.name) + self.shell.log.info(desc) + self.shell.log.info("Done loading %s fabric module." \ + % fabric_module.name) except Exception, msg: - self.log.warning("Can't load fabric module %s." - % fabric_module.name) - self.log.debug(msg) + self.shell.log.warning("Can't load fabric module %s." + % fabric_module.name) + self.shell.log.debug(msg) else: - self.add_child(UIFabricModule(fabric_module)) + UIFabricModule(fabric_module, self) self.loaded = True else: - self.log.debug("Refreshing in loaded mode.") + self.shell.log.debug("Refreshing in loaded mode.") for fabric_module in RTSRoot().loaded_fabric_modules: - self.log.debug("Loading %s." % fabric_module.name) - self.add_child(UIFabricModule(fabric_module)) + self.shell.log.debug("Loading %s." % fabric_module.name) + UIFabricModule(fabric_module, self) def ui_command_version(self): ''' @@ -81,11 +80,11 @@ class UIRoot(UINode): rtslib=rtslib_version, configshell=configshell_version).items(): if version == 'GIT_VERSION': - self.log.error("Cannot find %s version. The %s package has " - % (package, package) - + "probably not been built properly from " - + "either the git repository or a public " - + "tarball.") + self.shell.log.error("Cannot find %s version. The %s package " + % (package, package) + + "has probably not been built properly " + + "from either the git repository or a " + + "public tarball.") else: - self.log.info("Using %s version %s" % (package, version)) + self.shell.log.info("Using %s version %s" % (package, version)) diff --git a/rtsadmin/ui_target.py b/rtsadmin/ui_target.py index add6870..cde8c2d 100644 --- a/rtsadmin/ui_target.py +++ b/rtsadmin/ui_target.py @@ -27,9 +27,8 @@ class UIFabricModule(UIRTSLibNode): ''' A fabric module UI. ''' - def __init__(self, fabric_module): - UIRTSLibNode.__init__(self, fabric_module) - self.name = fabric_module.name + def __init__(self, fabric_module, parent): + UIRTSLibNode.__init__(self, fabric_module.name, fabric_module, parent) self.cfs_cwd = fabric_module.path self.refresh() if self.rtsnode.has_feature('discovery_auth'): @@ -86,12 +85,12 @@ class UIFabricModule(UIRTSLibNode): def refresh(self): self._children = set([]) for target in self.rtsnode.targets: - self.log.debug("Found target %s under fabric module %s." - % (target.wwn, target.fabric_module)) + self.shell.log.debug("Found target %s under fabric module %s." + % (target.wwn, target.fabric_module)) if target.has_feature('tpgts'): - self.add_child(UIMultiTPGTarget(target)) + UIMultiTPGTarget(target, self) else: - self.add_child(UITarget(target)) + UITarget(target, self) def summary(self): no_targets = len(self._children) @@ -120,14 +119,12 @@ class UIFabricModule(UIRTSLibNode): target = Target(self.rtsnode, wwn, mode='create') wwn = target.wwn if target.has_feature('tpgts'): - ui_target = UIMultiTPGTarget(target) - self.add_child(ui_target) - self.log.info("Created target %s." % wwn) + ui_target = UIMultiTPGTarget(target, self) + self.shell.log.info("Created target %s." % wwn) return ui_target.ui_command_create() else: - ui_target = UITarget(target) - self.add_child(ui_target) - self.log.info("Created target %s." % wwn) + ui_target = UITarget(target, self) + self.shell.log.info("Created target %s." % wwn) return self.new_node(ui_target) def ui_complete_create(self, parameters, text, current_param): @@ -168,7 +165,7 @@ class UIFabricModule(UIRTSLibNode): self.assert_root() target = Target(self.rtsnode, wwn, mode='lookup') target.delete() - self.log.info("Deleted Target %s." % wwn) + self.shell.log.info("Deleted Target %s." % wwn) self.refresh() def ui_complete_delete(self, parameters, text, current_param): @@ -201,20 +198,21 @@ class UIFabricModule(UIRTSLibNode): features. ''' spec = self.rtsnode.spec - self.log.info("Fabric module name: %s" % self.name) - self.log.info("ConfigFS path: %s" % self.rtsnode.path) + self.shell.log.info("Fabric module name: %s" % self.name) + self.shell.log.info("ConfigFS path: %s" % self.rtsnode.path) if spec['wwn_list'] is not None: - self.log.info("Allowed WWNs list (%s type): %s" - % (spec['wwn_type'], ', '.join(spec['wwn_list']))) + self.shell.log.info("Allowed WWNs list (%s type): %s" + % (spec['wwn_type'], + ', '.join(spec['wwn_list']))) else: - self.log.info("Supported WWN type: %s" % spec['wwn_type']) + self.shell.log.info("Supported WWN type: %s" % spec['wwn_type']) - self.log.info("Fabric module specfile: %s" - % self.rtsnode.spec_file) - self.log.info("Fabric module features: %s" - % ', '.join(spec['features'])) - self.log.info("Corresponding kernel module: %s" - % spec['kernel_module']) + self.shell.log.info("Fabric module specfile: %s" + % self.rtsnode.spec_file) + self.shell.log.info("Fabric module features: %s" + % ', '.join(spec['features'])) + self.shell.log.info("Corresponding kernel module: %s" + % spec['kernel_module']) def ui_command_version(self): ''' @@ -222,22 +220,21 @@ class UIFabricModule(UIRTSLibNode): ''' version = "Target fabric module %s: %s" \ % (self.rtsnode.name, self.rtsnode.version) - self.con.display(version.strip()) + self.shell.con.display(version.strip()) class UIMultiTPGTarget(UIRTSLibNode): ''' A generic target UI that has multiple TPGs. ''' - def __init__(self, target): - UIRTSLibNode.__init__(self, target) - self.name = target.wwn + def __init__(self, target, parent): + UIRTSLibNode.__init__(self, target.wwn, target, parent) self.cfs_cwd = target.path self.refresh() def refresh(self): self._children = set([]) for tpg in self.rtsnode.tpgs: - self.add_child(UITPG(tpg)) + UITPG(tpg, self) def summary(self): if not self.rtsnode.fabric_module.is_valid_wwn(self.rtsnode.wwn): @@ -271,27 +268,26 @@ class UIMultiTPGTarget(UIRTSLibNode): tag = index break if tag is None: - self.log.error("Cannot find an available TPG Tag.") + self.shell.log.error("Cannot find an available TPG Tag.") return else: - self.log.info("Selected TPG Tag %d." % tag) + self.shell.log.info("Selected TPG Tag %d." % tag) else: try: tag = int(tag) except ValueError: - self.log.error("The TPG Tag must be an integer value.") + self.shell.log.error("The TPG Tag must be an integer value.") return else: if tag < 1: - self.log.error("The TPG Tag must be >0.") + self.shell.log.error("The TPG Tag must be >0.") return tpg = TPG(self.rtsnode, tag, mode='create') - if self.prefs['auto_enable_tpgt']: + if self.shell.prefs['auto_enable_tpgt']: tpg.enable = True - self.log.info("Successfully created TPG %s." % tpg.tag) - ui_tpg = UITPG(tpg) - self.add_child(ui_tpg) + self.shell.log.info("Successfully created TPG %s." % tpg.tag) + ui_tpg = UITPG(tpg, self) return self.new_node(ui_tpg) def ui_command_delete(self, tag): @@ -306,7 +302,7 @@ class UIMultiTPGTarget(UIRTSLibNode): self.assert_root() tpg = TPG(self.rtsnode, tag, mode='lookup') tpg.delete() - self.log.info("Deleted TPGT %s." % tag) + self.shell.log.info("Deleted TPGT %s." % tag) self.refresh() def ui_complete_delete(self, parameters, text, current_param): @@ -336,18 +332,18 @@ class UITPG(UIRTSLibNode): ''' A generic TPG UI. ''' - def __init__(self, tpg): - UIRTSLibNode.__init__(self, tpg) - self.name = "tpgt%d" % tpg.tag + def __init__(self, tpg, parent): + name = "tpgt%d" % tpg.tag + UIRTSLibNode.__init__(self, name, tpg, parent) self.cfs_cwd = tpg.path self.refresh() - self.add_child(UILUNs(tpg)) + UILUNs(tpg, self) if tpg.has_feature('acls'): - self.add_child(UINodeACLs(self.rtsnode)) + UINodeACLs(self.rtsnode, self) if tpg.has_feature('nps'): - self.add_child(UIPortals(self.rtsnode)) + UIPortals(self.rtsnode, self) def summary(self): if self.rtsnode.has_feature('nexus'): @@ -368,10 +364,10 @@ class UITPG(UIRTSLibNode): ''' self.assert_root() if self.rtsnode.enable: - self.log.info("The TPGT is already enabled.") + self.shell.log.info("The TPGT is already enabled.") else: self.rtsnode.enable = True - self.log.info("The TPGT has been enabled.") + self.shell.log.info("The TPGT has been enabled.") def ui_command_disable(self): ''' @@ -384,21 +380,19 @@ class UITPG(UIRTSLibNode): self.assert_root() if self.rtsnode.enable: self.rtsnode.enable = False - self.log.info("The TPGT has been disabled.") + self.shell.log.info("The TPGT has been disabled.") else: - self.log.info("The TPGT is already disabled.") + self.shell.log.info("The TPGT is already disabled.") class UITarget(UITPG): ''' A generic target UI merged with its only TPG. ''' - # FIXME: This is a workaround for rtslib/kernel-side LIO enforcing at least - # one TPG layer even for non-iSCSI fabric modules, for legacy reasons. - def __init__(self, target): - UITPG.__init__(self, TPG(target, 1)) + def __init__(self, target, parent): + UITPG.__init__(self, TPG(target, 1), parent) + self._name = target.wwn self.target = target self.rtsnode.enable = True - self.name = target.wwn def summary(self): if not self.target.fabric_module.is_valid_wwn(self.target.wwn): @@ -410,9 +404,8 @@ class UINodeACLs(UINode): ''' A generic UI for node ACLs. ''' - def __init__(self, tpg): - UINode.__init__(self) - self.name = "acls" + def __init__(self, tpg, parent): + UINode.__init__(self, "acls", parent) self.tpg = tpg self.cfs_cwd = "%s/acls" % tpg.path self.refresh() @@ -420,7 +413,7 @@ class UINodeACLs(UINode): def refresh(self): self._children = set([]) for node_acl in self.tpg.node_acls: - self.add_child(UINodeACL(node_acl)) + UINodeACL(node_acl, self) def summary(self): no_acls = len(self._children) @@ -448,29 +441,28 @@ class UINodeACLs(UINode): self.assert_root() spec = self.tpg.parent_target.fabric_module.spec if not utils.is_valid_wwn(spec['wwn_type'], wwn): - self.log.error("'%s' is not a valid %s WWN." - % (wwn, spec['wwn_type'])) + self.shell.log.error("'%s' is not a valid %s WWN." + % (wwn, spec['wwn_type'])) return add_mapped_luns = \ self.ui_eval_param(add_mapped_luns, 'bool', - self.prefs['auto_add_mapped_luns']) + self.shell.prefs['auto_add_mapped_luns']) try: node_acl = NodeACL(self.tpg, wwn, mode="create") except RTSLibError, msg: - self.log.error(msg) + self.shell.log.error(msg) return else: - self.log.info("Successfully created Node ACL for %s" - % node_acl.node_wwn) - ui_node_acl = UINodeACL(node_acl) - self.add_child(ui_node_acl) + self.shell.log.info("Successfully created Node ACL for %s" + % node_acl.node_wwn) + ui_node_acl = UINodeACL(node_acl, self) if add_mapped_luns: for lun in self.tpg.luns: MappedLUN(node_acl, lun.lun, lun.lun, write_protect=False) - self.log.info("Created mapped LUN %d." % lun.lun) + self.shell.log.info("Created mapped LUN %d." % lun.lun) self.refresh() return self.new_node(ui_node_acl) @@ -486,7 +478,7 @@ class UINodeACLs(UINode): self.assert_root() node_acl = NodeACL(self.tpg, wwn, mode='lookup') node_acl.delete() - self.log.info("Successfully deleted Node ACL %s." % wwn) + self.shell.log.info("Successfully deleted Node ACL %s." % wwn) self.refresh() def ui_complete_delete(self, parameters, text, current_param): @@ -516,9 +508,8 @@ class UINodeACL(UIRTSLibNode): ''' A generic UI for a node ACL. ''' - def __init__(self, node_acl): - UIRTSLibNode.__init__(self, node_acl) - self.name = node_acl.node_wwn + def __init__(self, node_acl, parent): + UIRTSLibNode.__init__(self, node_acl.node_wwn, node_acl, parent) self.cfs_cwd = node_acl.path if self.rtsnode.has_feature('acls_auth'): @@ -569,7 +560,7 @@ class UINodeACL(UIRTSLibNode): def refresh(self): self._children = set([]) for mlun in self.rtsnode.mapped_luns: - self.add_child(UIMappedLUN(mlun)) + UIMappedLUN(mlun, self) def summary(self): no_mluns = len(self._children) @@ -595,13 +586,12 @@ class UINodeACL(UIRTSLibNode): tpg_lun = int(tpg_lun) mapped_lun = int(mapped_lun) except ValueError: - self.log.error("Incorrect LUN value.") + self.shell.log.error("Incorrect LUN value.") return mlun = MappedLUN(self.rtsnode, mapped_lun, tpg_lun, write_protect) - ui_mlun = UIMappedLUN(mlun) - self.add_child(ui_mlun) - self.log.info("Created Mapped LUN %s." % mlun.mapped_lun) + ui_mlun = UIMappedLUN(mlun, self) + self.shell.log.info("Created Mapped LUN %s." % mlun.mapped_lun) return self.new_node(ui_mlun) def ui_command_delete(self, mapped_lun): @@ -615,7 +605,7 @@ class UINodeACL(UIRTSLibNode): self.assert_root() mlun = MappedLUN(self.rtsnode, mapped_lun) mlun.delete() - self.log.info("Deleted Mapped LUN %s." % mapped_lun) + self.shell.log.info("Deleted Mapped LUN %s." % mapped_lun) self.refresh() def ui_complete_delete(self, parameters, text, current_param): @@ -645,9 +635,9 @@ class UIMappedLUN(UIRTSLibNode): ''' A generic UI for MappedLUN objects. ''' - def __init__(self, mapped_lun): - UIRTSLibNode.__init__(self, mapped_lun) - self.name = "mapped_lun%d" % mapped_lun.mapped_lun + def __init__(self, mapped_lun, parent): + name = "mapped_lun%d" % mapped_lun.mapped_lun + UIRTSLibNode.__init__(self, name, mapped_lun, parent) self.cfs_cwd = mapped_lun.path self.refresh() @@ -672,9 +662,8 @@ class UILUNs(UINode): ''' A generic UI for TPG LUNs. ''' - def __init__(self, tpg): - UINode.__init__(self) - self.name = "luns" + def __init__(self, tpg, parent): + UINode.__init__(self, "luns", parent) self.cfs_cwd = "%s/lun" % tpg.path self.tpg = tpg self.refresh() @@ -682,7 +671,7 @@ class UILUNs(UINode): def refresh(self): self._children = set([]) for lun in self.tpg.luns: - self.add_child(UILUN(lun)) + UILUN(lun, self) def summary(self): no_luns = len(self._children) @@ -718,34 +707,33 @@ class UILUNs(UINode): lun = index break if lun is None: - self.log.error("Cannot find an available LUN.") + self.shell.log.error("Cannot find an available LUN.") return else: - self.log.info("Selected LUN %d." % lun) + self.shell.log.info("Selected LUN %d." % lun) else: try: lun = int(lun) except ValueError: - self.log.error("The LUN must be an integer value.") + self.shell.log.error("The LUN must be an integer value.") return else: if lun < 0: - self.log.error("The LUN cannot be negative.") + self.shell.log.error("The LUN cannot be negative.") return add_mapped_luns = \ self.ui_eval_param(add_mapped_luns, 'bool', - self.prefs['auto_add_mapped_luns']) + self.shell.prefs['auto_add_mapped_luns']) try: storage_object = self.get_node(storage_object).rtsnode except AttributeError: - self.log.error("Wrong storage object path.") + self.shell.log.error("Wrong storage object path.") lun_object = LUN(self.tpg, lun, storage_object) - self.log.info("Successfully created LUN %s." % lun_object.lun) - ui_lun = UILUN(lun_object) - self.add_child(ui_lun) + self.shell.log.info("Successfully created LUN %s." % lun_object.lun) + ui_lun = UILUN(lun_object, self) if add_mapped_luns: for acl in self.tpg.node_acls: @@ -756,15 +744,15 @@ class UILUNs(UINode): while mapped_lun == lun: if tentative_mlun not in existing_mluns: mapped_lun = tentative_mlun - self.log.warning("Mapped LUN %d already exists in" - % lun - + " ACL %s, using %d instead." - % (acl.node_wwn, mapped_lun)) + self.shell.log.warning( + "Mapped LUN %d already " % lun + + "exists in ACL %s, using %d instead." + % (acl.node_wwn, mapped_lun)) else: tentative_mlun += 1 mlun = MappedLUN(acl, mapped_lun, lun, write_protect=False) - self.log.info("Created mapped LUN %d in node ACL %s" - % (mapped_lun, acl.node_wwn)) + self.shell.log.info("Created mapped LUN %d in node ACL %s" + % (mapped_lun, acl.node_wwn)) self.parent.refresh() return self.new_node(ui_lun) @@ -807,7 +795,7 @@ class UILUNs(UINode): self.assert_root() lun_object = LUN(self.tpg, lun) lun_object.delete() - self.log.info("Successfully deleted LUN %s." % lun) + self.shell.log.info("Successfully deleted LUN %s." % lun) # Refresh the TPG as we need to also refresh acls MappedLUNs self.parent.refresh() @@ -838,9 +826,9 @@ class UILUN(UIRTSLibNode): ''' A generic UI for LUN objects. ''' - def __init__(self, lun): - UIRTSLibNode.__init__(self, lun) - self.name = "lun%d" % lun.lun + def __init__(self, lun, parent): + name = "lun%d" % lun.lun + UIRTSLibNode.__init__(self, name, lun, parent) self.cfs_cwd = lun.path self.refresh() @@ -858,7 +846,7 @@ class UILUN(UIRTSLibNode): path = "ramdisk" else: path = storage_object.udev_path - if self.prefs['legacy_hba_view']: + if self.shell.prefs['legacy_hba_view']: description = "%s%s/%s (%s)" % (backstore.plugin, backstore.index, storage_object.name, path) @@ -873,17 +861,16 @@ class UIPortals(UINode): ''' A generic UI for TPG network portals. ''' - def __init__(self, tpg): - UINode.__init__(self) + def __init__(self, tpg, parent): + UINode.__init__(self, "portals", parent) self.tpg = tpg - self.name = "portals" self.cfs_cwd = "%s/np" % tpg.path self.refresh() def refresh(self): self._children = set([]) for portal in self.tpg.network_portals: - self.add_child(UIPortal(portal)) + UIPortal(portal, self) def summary(self): no_portals = len(self._children) @@ -908,33 +895,32 @@ class UIPortals(UINode): if ip_port is None: # FIXME: Add a specfile parameter to determine that ip_port = 3260 - self.log.info("Using default IP port %d" % ip_port) + self.shell.log.info("Using default IP port %d" % ip_port) if ip_address is None: if not ip_address: ip_address = utils.get_main_ip() if ip_address: - self.log.info("Automatically selected IP address %s." - % ip_address) + self.shell.log.info("Automatically selected IP address %s." + % ip_address) else: - self.log.error("Cannot find a usable IP address to " - + "create the Network Portal, aborting.") + self.shell.log.error("Cannot find a usable IP address to " + + "create the Network Portal.") return elif ip_address not in utils.list_eth_ips(): - self.log.error("IP address does not exist: %s" % ip_address) + self.shell.log.error("IP address does not exist: %s" % ip_address) return try: ip_port = int(ip_port) except ValueError: - self.log.error("The ip_port must be an integer value.") + self.shell.log.error("The ip_port must be an integer value.") return portal = NetworkPortal(self.tpg, ip_address, ip_port, mode='create') - self.log.info("Successfully created network portal %s:%d." - % (ip_address, ip_port)) - ui_portal = UIPortal(portal) - self.add_child(ui_portal) + self.shell.log.info("Successfully created network portal %s:%d." + % (ip_address, ip_port)) + ui_portal = UIPortal(portal, self) return self.new_node(ui_portal) def ui_complete_create(self, parameters, text, current_param): @@ -971,7 +957,8 @@ class UIPortals(UINode): self.assert_root() portal = NetworkPortal(self.tpg, ip_address, ip_port, mode='lookup') portal.delete() - self.log.info("Deleted network portal %s:%s" % (ip_address, ip_port)) + self.shell.log.info("Deleted network portal %s:%s" + % (ip_address, ip_port)) self.refresh() def ui_complete_delete(self, parameters, text, current_param): @@ -1025,9 +1012,9 @@ class UIPortal(UIRTSLibNode): ''' A generic UI for a network portal. ''' - def __init__(self, portal): - UIRTSLibNode.__init__(self, portal) - self.name = "%s:%s" % (portal.ip_address, portal.port) + def __init__(self, portal, parent): + name = "%s:%s" % (portal.ip_address, portal.port) + UIRTSLibNode.__init__(self, name, portal, parent) self.cfs_cwd = portal.path self.refresh() diff --git a/scripts/rtsadmin b/scripts/rtsadmin index 832c798..b010823 100755 --- a/scripts/rtsadmin +++ b/scripts/rtsadmin @@ -54,18 +54,21 @@ def main(): is_root = True else: is_root = False - root_node = UIRoot(as_root=is_root) - shell = RTSAdmin(root_node, '~/.rtsadmin') - shell.con.epy_write('Welcome to the B{RTSAdmin Community Edition} CLI.') - shell.con.display('') - shell.con.epy_write('Copyright (c) 2011 by RisingTide Systems LLC.') - shell.con.epy_write('Visit us at U{http://www.risingtidesystems.com}.') + shell = RTSAdmin('~/.rtsadmin') + shell.con.epy_write(''' + Welcome to the B{rtsadmin Community Edition} CLI:: + Copyright (c) 2011 by RisingTide Systems LLC. + + Visit us at U{http://www.risingtidesystems.com}. + ''') shell.con.display('') if not is_root: shell.con.display('You are not root, disabling privileged commands.') shell.con.display('') + root_node = UIRoot(shell, as_root=is_root) + try: root_node.refresh() except RTSLibError, error: |