Introduce a bool CLI option type
authorIustin Pop <iustin@google.com>
Mon, 22 Mar 2010 16:23:36 +0000 (17:23 +0100)
committerIustin Pop <iustin@google.com>
Tue, 23 Mar 2010 08:35:05 +0000 (09:35 +0100)
This option type enforces its value to either True or False, relieving
the scripts from manually parsing the values in each function.

We also update the bash completion code to use the option type if
possible.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>

autotools/build-bash-completion
lib/cli.py
scripts/gnt-node

index 56204af..79258c2 100755 (executable)
@@ -312,6 +312,10 @@ class CompletionWriter:
       # Only static choices implemented so far (e.g. no node list)
       suggest = getattr(opt, "completion_suggest", None)
 
+      # our custom option type
+      if opt.type == "bool":
+        suggest = ["yes", "no"]
+
       if not suggest:
         suggest = opt.choices
 
index 9c480d6..5df4aae 100644 (file)
@@ -457,6 +457,21 @@ def check_key_val(option, opt, value):  # pylint: disable-msg=W0613
   return _SplitKeyVal(opt, value)
 
 
+def check_bool(option, opt, value): # pylint: disable-msg=W0613
+  """Custom parser for yes/no options.
+
+  This will store the parsed value as either True or False.
+
+  """
+  value = value.lower()
+  if value == constants.VALUE_FALSE or value == "no":
+    return False
+  elif value == constants.VALUE_TRUE or value == "yes":
+    return True
+  else:
+    raise errors.ParameterError("Invalid boolean value '%s'" % value)
+
+
 # completion_suggestion is normally a list. Using numeric values not evaluating
 # to False for dynamic completion.
 (OPT_COMPL_MANY_NODES,
@@ -487,18 +502,19 @@ class CliOption(Option):
     "identkeyval",
     "keyval",
     "unit",
+    "bool",
     )
   TYPE_CHECKER = Option.TYPE_CHECKER.copy()
   TYPE_CHECKER["identkeyval"] = check_ident_key_val
   TYPE_CHECKER["keyval"] = check_key_val
   TYPE_CHECKER["unit"] = check_unit
+  TYPE_CHECKER["bool"] = check_bool
 
 
 # optparse.py sets make_option, so we do it for our own option class, too
 cli_option = CliOption
 
 
-_YESNO = ("yes", "no")
 _YORNO = "yes|no"
 
 DEBUG_OPT = cli_option("-d", "--debug", default=0, action="count",
@@ -759,19 +775,19 @@ NOSSH_KEYCHECK_OPT = cli_option("--no-ssh-key-check", dest="ssh_key_check",
 
 
 MC_OPT = cli_option("-C", "--master-candidate", dest="master_candidate",
-                    choices=_YESNO, default=None, metavar=_YORNO,
+                    type="bool", default=None, metavar=_YORNO,
                     help="Set the master_candidate flag on the node")
 
 OFFLINE_OPT = cli_option("-O", "--offline", dest="offline", metavar=_YORNO,
-                         choices=_YESNO, default=None,
+                         type="bool", default=None,
                          help="Set the offline flag on the node")
 
 DRAINED_OPT = cli_option("-D", "--drained", dest="drained", metavar=_YORNO,
-                         choices=_YESNO, default=None,
+                         type="bool", default=None,
                          help="Set the drained flag on the node")
 
 ALLOCATABLE_OPT = cli_option("--allocatable", dest="allocatable",
-                             choices=_YESNO, default=None, metavar=_YORNO,
+                             type="bool", default=None, metavar=_YORNO,
                              help="Set the allocatable flag on a volume")
 
 NOLVM_STORAGE_OPT = cli_option("--no-lvm-storage", dest="lvm_storage",
index 5c98561..61c4f27 100755 (executable)
@@ -571,7 +571,7 @@ def ModifyStorage(opts, args):
   changes = {}
 
   if opts.allocatable is not None:
-    changes[constants.SF_ALLOCATABLE] = (opts.allocatable == "yes")
+    changes[constants.SF_ALLOCATABLE] = opts.allocatable
 
   if changes:
     op = opcodes.OpModifyNodeStorage(node_name=node_name,
@@ -618,23 +618,10 @@ def SetNodeParams(opts, args):
     ToStderr("Please give at least one of the parameters.")
     return 1
 
-  if opts.master_candidate is not None:
-    candidate = opts.master_candidate == 'yes'
-  else:
-    candidate = None
-  if opts.offline is not None:
-    offline = opts.offline == 'yes'
-  else:
-    offline = None
-
-  if opts.drained is not None:
-    drained = opts.drained == 'yes'
-  else:
-    drained = None
   op = opcodes.OpSetNodeParams(node_name=args[0],
-                               master_candidate=candidate,
-                               offline=offline,
-                               drained=drained,
+                               master_candidate=opts.master_candidate,
+                               offline=opts.offline,
+                               drained=opts.drained,
                                force=opts.force,
                                auto_promote=opts.auto_promote)