[node-patches] Change in ovirt-node[master]: console: Capture console output
fabiand at fedoraproject.org
fabiand at fedoraproject.org
Wed Feb 27 09:30:29 UTC 2013
Fabian Deutsch has uploaded a new change for review.
Change subject: console: Capture console output
......................................................................
console: Capture console output
Sometimes transaction elements would call functions which wrote to
stderr/stdout, this scrambled the screen.
Now this output from transaction elements is captured (for a later
usage) to prevent the scramblind of the screen contents.
Change-Id: I78739975bf9290f650e1b163d68aedd0ce4ebf79
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/installer/progress_page.py
M scripts/tui/src/ovirt/node/ui/__init__.py
M scripts/tui/src/ovirt/node/utils/console.py
3 files changed, 84 insertions(+), 5 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/78/12478/1
diff --git a/scripts/tui/src/ovirt/node/installer/progress_page.py b/scripts/tui/src/ovirt/node/installer/progress_page.py
index 412f404..5a49308 100644
--- a/scripts/tui/src/ovirt/node/installer/progress_page.py
+++ b/scripts/tui/src/ovirt/node/installer/progress_page.py
@@ -20,6 +20,7 @@
# also available at http://www.gnu.org/copyleft/gpl.html.
from ovirt.node import plugins, ui, utils
from ovirt.node.config import defaults
+from ovirt.node.utils import console
import threading
import time
@@ -103,19 +104,29 @@
def do_commit():
tx_element.commit()
- self.progress_plugin.dry_or(do_commit)
+ with console.CaptureOutput() as captured:
+ # Sometimes a tx_element is wrapping some code that
+ # writes to stdout/stderr which scrambles the screen,
+ # therefore we are capturing this
+ self.progress_plugin.dry_or(do_commit)
progressbar.current(int(100.0 / txlen * idx))
log_lines[-1] = "%s (Done)" % log_lines[-1]
log.text("\n".join(log_lines))
+
except Exception as e:
msg = "Exception: %s" % repr(e)
- self.logger.warning(msg, exc_info=True)
+ self.logger.debug(msg, exc_info=True)
log.text(msg)
- raise
+
finally:
self.progress_plugin.widgets["action.reboot"].enabled(True)
+ if captured.stderr.getvalue():
+ se = captured.stderr.getvalue()
+ if se:
+ log.text("Stderr: %s" % se)
+
# We enforce a redraw, because this the non-mainloop thread
self.progress_plugin.application.ui.force_redraw()
diff --git a/scripts/tui/src/ovirt/node/ui/__init__.py b/scripts/tui/src/ovirt/node/ui/__init__.py
index 7237ff2..202b23b 100644
--- a/scripts/tui/src/ovirt/node/ui/__init__.py
+++ b/scripts/tui/src/ovirt/node/ui/__init__.py
@@ -19,6 +19,7 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
from ovirt.node import base
+from ovirt.node.utils import console
"""
This contains abstract UI Elements
@@ -723,7 +724,11 @@
txt = "(%s/%s) %s" % (idx + 1, len(self.transaction),
tx_element.title)
self.add_update(txt)
- self.plugin.dry_or(lambda: tx_element.commit())
+ with console.CaptureOutput() as captured:
+ # Sometimes a tx_element is wrapping some code that
+ # writes to stdout/stderr which scrambles the screen,
+ # therefore we are capturing this
+ self.plugin.dry_or(lambda: tx_element.commit())
self.add_update("\nAll changes were applied successfully.")
except Exception as e:
self.logger.info("An exception during the transaction: %s" % e,
@@ -731,6 +736,11 @@
self.add_update("\nAn error occurred while applying the changes:")
self.add_update("%s" % e)
+ if captured.stderr.getvalue():
+ se = captured.stderr.getvalue()
+ if se:
+ self.add_update("Stderr: %s" % se)
+
class AbstractUIBuilder(base.Base):
"""An abstract class
diff --git a/scripts/tui/src/ovirt/node/utils/console.py b/scripts/tui/src/ovirt/node/utils/console.py
index be3b02c..bdb22b4 100644
--- a/scripts/tui/src/ovirt/node/utils/console.py
+++ b/scripts/tui/src/ovirt/node/utils/console.py
@@ -19,6 +19,7 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
from ovirt.node import base
+import StringIO
import sys
import termios
import traceback
@@ -83,7 +84,11 @@
for idx, e in enumerate(self.transaction):
txt = "(%s/%s) %s" % (idx + 1, len(self.transaction), e.title)
self.add_update(txt)
- self.plugin.dry_or(lambda: e.commit())
+ with CaptureOutput() as captured:
+ # Sometimes a tx_element is wrapping some code that
+ # writes to stdout/stderr which scrambles the screen,
+ # therefore we are capturing this
+ self.plugin.dry_or(lambda: e.commit())
self.add_update("\nAll changes were applied successfully.")
except Exception as e:
self.add_update("\nAn error occurred while applying the changes:")
@@ -91,6 +96,11 @@
self.logger.warning("'%s' on transaction '%s': %s - %s" %
(type(e), self.transaction, e, e.message))
self.logger.debug(str(traceback.format_exc()))
+
+ if captured.stderr.getvalue():
+ se = captured.stderr.getvalue()
+ if se:
+ self.add_update("Stderr: %s" % se)
def getch():
@@ -114,3 +124,51 @@
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
+
+
+class CaptureOutput(base.Base):
+ """This context manager can be used to capture any output (from e.g. a
+ subprocess or wrongly configured loggers) to different streams
+
+ >>> import sys
+ >>> with CaptureOutput() as captured:
+ ... sys.stdout.write("Hey!")
+ ... sys.stderr.write("There!")
+ >>> captured.stdout.getvalue()
+ 'Hey!'
+ >>> captured.stderr.getvalue()
+ 'There!'
+ """
+
+ def __init__(self, stdout=None, stderr=None):
+ super(CaptureOutput, self).__init__()
+ self.stdout = stdout or StringIO.StringIO()
+ self.stderr = stderr or StringIO.StringIO()
+
+ def __enter__(self):
+ """Create redirections
+ """
+ self.logger.debug("Redirecting %s to %s" % (sys.stdout, self.stdout))
+ self.logger.debug("Redirecting %s to %s" % (sys.stderr, self.stderr))
+ self._stdout = sys.stdout
+ self._stderr = sys.stderr
+ sys.stdout = self.stdout
+ sys.stderr = self.stderr
+ return self
+
+ def __exit__(self, a, b, c):
+ """Remove all redirections
+ """
+ sys.stdout = self._stdout
+ sys.stderr = self._stderr
+ self.logger.debug("Removed redirections")
+ so = self.stdout.getvalue()
+ se = self.stderr.getvalue()
+ if so or se:
+ self.logger.info("Captured:")
+ else:
+ self.logger.info("Captured nothing")
+ if se:
+ self.logger.info("stderr: %s" % se)
+ if so:
+ self.logger.info("stdout: %s" % so)
--
To view, visit http://gerrit.ovirt.org/12478
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I78739975bf9290f650e1b163d68aedd0ce4ebf79
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>
More information about the node-patches
mailing list