We also add two function for printing messages, so that scripts won't
have to import logger to get these. They are a simple extension over the
logger ones, as they accept the call style from logging:
ToStdout("Message: %s", msg)
(instead of requiring formatting by the client.
---
I've changed and added the new call style since it's easier to use
lib/cli.py | 53 +++++++++++++++++++++++++++++++++++++++---
test/ganeti.cli_unittest.py | 26 +++++++++++++++++++++
2 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/lib/cli.py b/lib/cli.py
index 956be3d..4de1c29 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -27,6 +27,7 @@ import textwrap
import os.path
import copy
import time
+import logging
from cStringIO import StringIO
from ganeti import utils
@@ -50,6 +51,7 @@ __all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain",
"FormatError", "SplitNodeOption", "SubmitOrSend",
"JobSubmittedException", "FormatTimestamp", "ParseTimespec",
"ValidateBeParams",
+ "ToStderr", "ToStdout",
]
@@ -626,7 +628,7 @@ def FormatError(err):
msg = str(err)
if isinstance(err, errors.ConfigurationError):
txt = "Corrupt configuration file: %s" % msg
- logger.Error(txt)
+ logging.error(txt)
obuf.write(txt + "\n")
obuf.write("Aborting.")
retcode = 2
@@ -718,15 +720,16 @@ def GenericMain(commands, override=None, aliases=None):
utils.debug = options.debug
if old_cmdline:
- logger.Info("run with arguments '%s'" % old_cmdline)
+ logging.info("run with arguments '%s'", old_cmdline)
else:
- logger.Info("run with no arguments")
+ logging.info("run with no arguments")
try:
result = func(options, args)
except (errors.GenericError, luxi.ProtocolError), err:
result, err_msg = FormatError(err)
- logger.ToStderr(err_msg)
+ logging.exception("Error durring command processing")
+ ToStderr(err_msg)
return result
@@ -858,3 +861,45 @@ def ParseTimespec(value):
except ValueError:
raise errors.OpPrereqError("Invalid time specification '%s'" % value)
return value
+
+
+def _ToStream(stream, txt, *args):
+ """Write a message to a stream, bypassing the logging system
+
+ @type stream: file object
+ @param stream: the file to which we should write
+ @type txt: str
+ @param txt: the message
+
+ """
+ if args:
+ args = tuple(args)
+ stream.write(txt % args)
+ else:
+ stream.write(txt)
+ stream.write('\n')
+ stream.flush()
+
+
+def ToStdout(txt, *args):
+ """Write a message to stdout only, bypassing the logging system
+
+ This is just a wrapper over _ToStream.
+
+ @type txt: str
+ @param txt: the message
+
+ """
+ _ToStream(sys.stdout, txt, *args)
+
+
+def ToStderr(txt, *args):
+ """Write a message to stderr only, bypassing the logging system
+
+ This is just a wrapper over _ToStream.
+
+ @type txt: str
+ @param txt: the message
+
+ """
+ _ToStream(sys.stderr, txt, *args)
diff --git a/test/ganeti.cli_unittest.py b/test/ganeti.cli_unittest.py
index cb3b788..29734ae 100755
--- a/test/ganeti.cli_unittest.py
+++ b/test/ganeti.cli_unittest.py
@@ -22,6 +22,7 @@
"""Script for unittesting the cli module"""
import unittest
+from cStringIO import StringIO
import ganeti
import testutils
@@ -75,5 +76,30 @@ class TestSplitKeyVal(unittest.TestCase):
"option", data)
+class TestToStream(unittest.TestCase):
+ """Thes the ToStream functions"""
+
+ def testBasic(self):
+ for data in ["foo",
+ "foo %s",
+ "foo %(test)s",
+ "foo %s %s",
+ "",
+ ]:
+ buf = StringIO()
+ cli._ToStream(buf, data)
+ self.failUnlessEqual(buf.getvalue(), data+'\n')
+
+ def testParams(self):
+ buf = StringIO()
+ cli._ToStream(buf, "foo %s", 1)
+ self.failUnlessEqual(buf.getvalue(), "foo 1\n")
+ buf = StringIO()
+ cli._ToStream(buf, "foo %s", (15,16))
+ self.failUnlessEqual(buf.getvalue(), "foo (15, 16)\n")
+ buf = StringIO()
+ cli._ToStream(buf, "foo %s %s", "a", "b")
+ self.failUnlessEqual(buf.getvalue(), "foo a b\n")
+
if __name__ == '__main__':
unittest.main()
--
1.5.6.5