vcluster-setup: Create $vnode/etc/ganeti directory
[ganeti-local] / tools / cfgshell
index 253d32a..90b3dcf 100755 (executable)
 
 """
 
+# functions in this module need to have a given name structure, so:
+# pylint: disable=C0103
+
 
-import os
-import sys
 import optparse
-import time
 import cmd
 
 try:
@@ -53,6 +53,8 @@ class ConfigShell(cmd.Cmd):
   responsibility to know what they're doing.
 
   """
+  # all do_/complete_* functions follow the same API
+  # pylint: disable=W0613
   prompt = "(/) "
 
   def __init__(self, cfg_file=None):
@@ -63,7 +65,7 @@ class ConfigShell(cmd.Cmd):
 
     """
     cmd.Cmd.__init__(self)
-    self.cfg = self.cluster_name = None
+    self.cfg = None
     self.parents = []
     self.path = []
     if cfg_file:
@@ -91,7 +93,7 @@ class ConfigShell(cmd.Cmd):
     dirs = []
     entries = []
     if isinstance(obj, objects.ConfigObject):
-      for name in obj.__slots__:
+      for name in obj.GetAllSlots():
         child = getattr(obj, name, None)
         if isinstance(child, (list, dict, tuple, objects.ConfigObject)):
           dirs.append(name)
@@ -115,7 +117,7 @@ class ConfigShell(cmd.Cmd):
     configuration is loaded.
 
     """
-    if line.startswith("load") or line == 'EOF' or line == "quit":
+    if line.startswith("load") or line == "EOF" or line == "quit":
       return line
     if not self.parents or self.cfg is None:
       print "No config data loaded"
@@ -133,7 +135,7 @@ class ConfigShell(cmd.Cmd):
     if self.cfg is None:
       self.prompt = "(#no config) "
     else:
-      self.prompt = "(%s:/%s) " % (self.cluster_name, "/".join(self.path))
+      self.prompt = "(/%s) " % ("/".join(self.path),)
     return stop
 
   def do_load(self, line):
@@ -152,10 +154,8 @@ class ConfigShell(cmd.Cmd):
       arg = None
     try:
       self.cfg = config.ConfigWriter(cfg_file=arg, offline=True)
-      self.cfg._OpenConfig()
-      self.parents = [self.cfg._config_data]
+      self.parents = [self.cfg._config_data] # pylint: disable=W0212
       self.path = []
-      self.cluster_name = self.cfg.GetClusterName()
     except errors.ConfigurationError, err:
       print "Error: %s" % str(err)
     return False
@@ -179,14 +179,15 @@ class ConfigShell(cmd.Cmd):
 
     """
     pointer = self.parents[-1]
-    dirs, entries = self._get_entries(pointer)
+    dirs, _ = self._get_entries(pointer)
     matches = [str(name) for name in dirs if name.startswith(text)]
     return matches
 
   def do_cd(self, line):
     """Changes the current path.
 
-    Valid arguments: either .. or a child of the current object.
+    Valid arguments: either .., /, "" (no argument) or a child of the current
+    object.
 
     """
     if line == "..":
@@ -197,9 +198,13 @@ class ConfigShell(cmd.Cmd):
       else:
         print "Already at top level"
         return False
+    elif len(line) == 0 or line == "/":
+      self.parents = self.parents[0:1]
+      self.path = []
+      return False
 
     pointer = self.parents[-1]
-    dirs, entries = self._get_entries(pointer)
+    dirs, _ = self._get_entries(pointer)
 
     if line not in dirs:
       print "No such child"
@@ -229,7 +234,7 @@ class ConfigShell(cmd.Cmd):
 
     """
     pointer = self.parents[-1]
-    dirs, entries = self._get_entries(pointer)
+    _, entries = self._get_entries(pointer)
     matches = [name for name in entries if name.startswith(text)]
     return matches
 
@@ -241,7 +246,7 @@ class ConfigShell(cmd.Cmd):
 
     """
     pointer = self.parents[-1]
-    dirs, entries = self._get_entries(pointer)
+    _, entries = self._get_entries(pointer)
     if line not in entries:
       print "No such entry"
       return False
@@ -281,7 +286,7 @@ class ConfigShell(cmd.Cmd):
     if self.cfg.VerifyConfig():
       print "Config data does not validate, refusing to save."
       return False
-    self.cfg._WriteConfig()
+    self.cfg._WriteConfig() # pylint: disable=W0212
 
   def do_rm(self, line):
     """Removes an instance or a node.
@@ -291,7 +296,7 @@ class ConfigShell(cmd.Cmd):
 
     """
     pointer = self.parents[-1]
-    data = self.cfg._config_data
+    data = self.cfg._config_data  # pylint: disable=W0212
     if pointer not in (data.instances, data.nodes):
       print "Can only delete instances and nodes"
       return False
@@ -306,17 +311,23 @@ class ConfigShell(cmd.Cmd):
       else:
         print "Invalid node name"
 
-  def do_EOF(self, line):
+  @staticmethod
+  def do_EOF(line):
+    """Exit the application.
+
+    """
     print
     return True
 
-  def do_quit(self, line):
+  @staticmethod
+  def do_quit(line):
     """Exit the application.
 
     """
     print
     return True
 
+
 class Error(Exception):
   """Generic exception"""
   pass
@@ -328,10 +339,9 @@ def ParseOptions():
   In case of command line errors, it will show the usage and exit the
   program.
 
-  Returns:
-    (options, args), as returned by OptionParser.parse_args
-  """
+  @return: a tuple (options, args), as returned by OptionParser.parse_args
 
+  """
   parser = optparse.OptionParser()
 
   options, args = parser.parse_args()
@@ -342,9 +352,8 @@ def ParseOptions():
 def main():
   """Application entry point.
 
-  This is just a wrapper over BootStrap, to handle our own exceptions.
   """
-  options, args = ParseOptions()
+  _, args = ParseOptions()
   if args:
     cfg_file = args[0]
   else: