From ef9fa5b9bfcac8b742446864344be0abb1aad3da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Nussbaumer?= <rn@google.com>
Date: Wed, 2 Nov 2011 16:07:15 +0100
Subject: [PATCH] Make it possible to pass in flags using ENV variables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: RenΓ© Nussbaumer <rn@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/cli.py                 | 34 +++++++++++++++++++++++-----------
 lib/client/gnt_group.py    |  6 +++++-
 lib/client/gnt_instance.py |  6 +++++-
 lib/client/gnt_node.py     |  6 +++++-
 4 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/lib/cli.py b/lib/cli.py
index 8d5cc614b..eeea6ed72 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -29,6 +29,7 @@ import time
 import logging
 import errno
 import itertools
+import shlex
 from cStringIO import StringIO
 
 from ganeti import utils
@@ -1297,7 +1298,7 @@ COMMON_CREATE_OPTS = [
   ]
 
 
-def _ParseArgs(argv, commands, aliases):
+def _ParseArgs(argv, commands, aliases, env_override):
   """Parser for the command line arguments.
 
   This function parses the arguments and returns the function which
@@ -1307,8 +1308,11 @@ def _ParseArgs(argv, commands, aliases):
   @param commands: dictionary with special contents, see the design
       doc for cmdline handling
   @param aliases: dictionary with command aliases {'alias': 'target, ...}
+  @param env_override: list of env variables allowed for default args
 
   """
+  assert not (env_override - set(commands))
+
   if len(argv) == 0:
     binary = "<command>"
   else:
@@ -1362,13 +1366,19 @@ def _ParseArgs(argv, commands, aliases):
 
     cmd = aliases[cmd]
 
+  if cmd in env_override:
+    args_env_name = ("%s_%s" % (binary.replace("-", "_"), cmd)).upper()
+    env_args = os.environ.get(args_env_name)
+    if env_args:
+      argv = utils.InsertAtPos(argv, 1, shlex.split(env_args))
+
   func, args_def, parser_opts, usage, description = commands[cmd]
   parser = OptionParser(option_list=parser_opts + COMMON_OPTS,
                         description=description,
                         formatter=TitledHelpFormatter(),
                         usage="%%prog %s %s" % (cmd, usage))
   parser.disable_interspersed_args()
-  options, args = parser.parse_args()
+  options, args = parser.parse_args(args=argv[1:])
 
   if not _CheckArguments(cmd, args_def, args):
     return None, None, None
@@ -2002,16 +2012,18 @@ def FormatError(err):
   return retcode, obuf.getvalue().rstrip("\n")
 
 
-def GenericMain(commands, override=None, aliases=None):
+def GenericMain(commands, override=None, aliases=None,
+                env_override=frozenset()):
   """Generic main function for all the gnt-* commands.
 
-  Arguments:
-    - commands: a dictionary with a special structure, see the design doc
-                for command line handling.
-    - override: if not None, we expect a dictionary with keys that will
-                override command line options; this can be used to pass
-                options from the scripts to generic functions
-    - aliases: dictionary with command aliases {'alias': 'target, ...}
+  @param commands: a dictionary with a special structure, see the design doc
+                   for command line handling.
+  @param override: if not None, we expect a dictionary with keys that will
+                   override command line options; this can be used to pass
+                   options from the scripts to generic functions
+  @param aliases: dictionary with command aliases {'alias': 'target, ...}
+  @param env_override: list of environment names which are allowed to submit
+                       default args for commands
 
   """
   # save the program name and the entire command line for later logging
@@ -2030,7 +2042,7 @@ def GenericMain(commands, override=None, aliases=None):
     aliases = {}
 
   try:
-    func, options, args = _ParseArgs(sys.argv, commands, aliases)
+    func, options, args = _ParseArgs(sys.argv, commands, aliases, env_override)
   except errors.ParameterError, err:
     result, err_msg = FormatError(err)
     ToStderr(err_msg)
diff --git a/lib/client/gnt_group.py b/lib/client/gnt_group.py
index 096bb9934..0365e31fb 100644
--- a/lib/client/gnt_group.py
+++ b/lib/client/gnt_group.py
@@ -34,6 +34,9 @@ from ganeti import utils
 _LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"]
 
 
+_ENV_OVERRIDE = frozenset(["list"])
+
+
 def AddGroup(opts, args):
   """Add a node group to the cluster.
 
@@ -258,4 +261,5 @@ commands = {
 
 def Main():
   return GenericMain(commands,
-                     override={"tag_type": constants.TAG_NODEGROUP})
+                     override={"tag_type": constants.TAG_NODEGROUP},
+                     env_override=_ENV_OVERRIDE)
diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py
index 84cc869af..8ba787dd4 100644
--- a/lib/client/gnt_instance.py
+++ b/lib/client/gnt_instance.py
@@ -64,6 +64,9 @@ _LIST_DEF_FIELDS = [
   ]
 
 
+_ENV_OVERRIDE = frozenset(["list"])
+
+
 def _ExpandMultiNames(mode, names, client=None):
   """Expand the given names using the passed mode.
 
@@ -1552,4 +1555,5 @@ aliases = {
 
 def Main():
   return GenericMain(commands, aliases=aliases,
-                     override={"tag_type": constants.TAG_INSTANCE})
+                     override={"tag_type": constants.TAG_INSTANCE},
+                     env_override=_ENV_OVERRIDE)
diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py
index 270aff55e..7ac8a3968 100644
--- a/lib/client/gnt_node.py
+++ b/lib/client/gnt_node.py
@@ -106,6 +106,9 @@ _OOB_COMMAND_ASK = frozenset([constants.OOB_POWER_OFF,
                               constants.OOB_POWER_CYCLE])
 
 
+_ENV_OVERRIDE = frozenset(["list"])
+
+
 NONODE_SETUP_OPT = cli_option("--no-node-setup", default=True,
                               action="store_false", dest="node_setup",
                               help=("Do not make initial SSH setup on remote"
@@ -963,4 +966,5 @@ commands = {
 
 
 def Main():
-  return GenericMain(commands, override={"tag_type": constants.TAG_NODE})
+  return GenericMain(commands, override={"tag_type": constants.TAG_NODE},
+                     env_override=_ENV_OVERRIDE)
-- 
GitLab