From d23abb794d2594adde158f2242c0a5cb0fea5e31 Mon Sep 17 00:00:00 2001
From: Nikos Skalkotos <skalkoto@grnet.gr>
Date: Thu, 18 Dec 2014 18:20:39 +0200
Subject: [PATCH] Add a result() method in the output interface
By default the output goes to sys.stdout. This is used in snf-mkimage
to output the plankton answer when registering an image to a synnefo
deployment.
This resolves #21
---
image_creator/dialog_main.py | 3 ++-
image_creator/dialog_menu.py | 2 +-
image_creator/dialog_util.py | 4 ++--
image_creator/main.py | 11 +++++------
image_creator/output/__init__.py | 4 ++++
image_creator/output/cli.py | 24 +++++++++++++++---------
image_creator/output/composite.py | 16 ++++++++++------
image_creator/output/dialog.py | 18 ++++++++++++++++++
8 files changed, 57 insertions(+), 25 deletions(-)
diff --git a/image_creator/dialog_main.py b/image_creator/dialog_main.py
index dadf4c0..614ad0b 100644
--- a/image_creator/dialog_main.py
+++ b/image_creator/dialog_main.py
@@ -201,7 +201,8 @@ def dialog_main(media, logfile, tmpdir, snapshot):
tmplog = None if logfile else tempfile.NamedTemporaryFile(prefix='fatal-',
delete=False)
try:
- log = SimpleOutput(False, logfile if logfile else tmplog)
+ stream = logfile if logfile else tmplog
+ log = SimpleOutput(colored=False, stderr=stream, stdout=stream)
while 1:
try:
out = CompositeOutput([log])
diff --git a/image_creator/dialog_menu.py b/image_creator/dialog_menu.py
index 0fd555f..0f1f274 100644
--- a/image_creator/dialog_menu.py
+++ b/image_creator/dialog_menu.py
@@ -932,7 +932,7 @@ def show_log(session):
"""Show the current execution log"""
d = session['dialog']
- log = session['image'].out[0].stream
+ log = session['image'].out[0].stderr
log.file.flush()
diff --git a/image_creator/dialog_util.py b/image_creator/dialog_util.py
index 6e1e959..675322b 100644
--- a/image_creator/dialog_util.py
+++ b/image_creator/dialog_util.py
@@ -214,13 +214,13 @@ def extract_image(session):
image.dump(path)
# Extract metadata file
- out.info("Extracting metadata file ...")
+ out.info("Extracting metadata file ...", False)
with open('%s.meta' % path, 'w') as f:
f.write(extract_metadata_string(session))
out.success('done')
# Extract md5sum file
- out.info("Extracting md5sum file ...")
+ out.info("Extracting md5sum file ...", False)
md5str = "%s %s\n" % (session['checksum'], name)
with open('%s.md5sum' % path, 'w') as f:
f.write(md5str)
diff --git a/image_creator/main.py b/image_creator/main.py
index ec18bd4..e1c2fec 100644
--- a/image_creator/main.py
+++ b/image_creator/main.py
@@ -214,10 +214,10 @@ def image_creator():
"be set")
if options.silent:
- out = SilentOutput()
+ out = SilentOutput(colored=sys.stderr.isatty())
else:
- out = OutputWthProgress(True) if sys.stderr.isatty() else \
- SimpleOutput(False)
+ out = OutputWthProgress() if sys.stderr.isatty() else \
+ SimpleOutput(colored=False)
title = 'snf-image-creator %s' % version
out.info(title)
@@ -430,7 +430,7 @@ def image_creator():
out.info("Sharing metadata file ...", False)
kamaki.share("%s.meta" % options.upload)
out.success('done')
-
+ out.result(json.dumps(result, indent=4))
out.info()
except ClientError as e:
raise FatalError("Service client: %d %s" % (e.status, e.message))
@@ -449,8 +449,7 @@ def main():
try:
sys.exit(image_creator())
except FatalError as e:
- colored = sys.stderr.isatty()
- SimpleOutput(colored).error(e)
+ SimpleOutput(colored=sys.stderr.isatty()).error(e)
sys.exit(1)
if __name__ == '__main__':
diff --git a/image_creator/output/__init__.py b/image_creator/output/__init__.py
index 8ca8963..4ace944 100644
--- a/image_creator/output/__init__.py
+++ b/image_creator/output/__init__.py
@@ -40,6 +40,10 @@ class Output(object):
"""Print normal program output"""
pass
+ def result(self, msg='', new_line=True):
+ """Print a result"""
+ pass
+
def cleanup(self):
"""Cleanup this output class"""
pass
diff --git a/image_creator/output/cli.py b/image_creator/output/cli.py
index f22f1a1..a1bd78f 100644
--- a/image_creator/output/cli.py
+++ b/image_creator/output/cli.py
@@ -33,14 +33,20 @@ def write(msg, new_line, decorate, stream):
class SilentOutput(Output):
"""Silent Output class. Only Errors are printed"""
- def __init__(self, colored=True, stream=None):
- self.colored = colored
- self.stream = sys.stderr if stream is None else stream
+ def __init__(self, **kwargs):
+ """Initialize a SilentOutput instance"""
+ self.colored = kwargs['colored'] if 'colored' in kwargs else True
+ self.stdout = kwargs['stdout'] if 'stdout' in kwargs else sys.stdout
+ self.stderr = kwargs['stderr'] if 'stderr' in kwargs else sys.stderr
+
+ def result(self, msg, new_line=True):
+ """Print a result"""
+ write(msg, new_line, lambda x: x, self.stdout)
def error(self, msg, new_line=True):
"""Print an error"""
color = red if self.colored else lambda x: x
- write("Error: %s" % msg, new_line, color, self.stream)
+ write("Error: %s" % msg, new_line, color, self.stderr)
class SimpleOutput(SilentOutput):
@@ -51,21 +57,21 @@ class SimpleOutput(SilentOutput):
def warn(self, msg, new_line=True):
"""Print a warning"""
color = yellow if self.colored else lambda x: x
- write("Warning: %s" % msg, new_line, color, self.stream)
+ write("Warning: %s" % msg, new_line, color, self.stderr)
def success(self, msg, new_line=True):
"""Print msg after an action is completed"""
color = green if self.colored else lambda x: x
- write(msg, new_line, color, self.stream)
+ write(msg, new_line, color, self.stderr)
def info(self, msg='', new_line=True):
"""Print msg as normal program output"""
- write(msg, new_line, lambda x: x, self.stream)
+ write(msg, new_line, lambda x: x, self.stderr)
def clear(self):
"""Clear the screen"""
- if self.stream.isatty():
- self.stream.write('\033[H\033[2J')
+ if self.stderr.isatty():
+ self.stderr.write('\033[H\033[2J')
class OutputWthProgress(SimpleOutput):
diff --git a/image_creator/output/composite.py b/image_creator/output/composite.py
index fbcb76d..fe1185c 100644
--- a/image_creator/output/composite.py
+++ b/image_creator/output/composite.py
@@ -56,6 +56,11 @@ class CompositeOutput(Output, list):
for out in self:
out.info(msg, new_line)
+ def result(self, msg='', new_line=True):
+ """Call the output method of each of the output instances"""
+ for out in self:
+ out.result(msg, new_line)
+
def cleanup(self):
"""Call the cleanup method of each of the output instances"""
for out in self:
@@ -66,28 +71,27 @@ class CompositeOutput(Output, list):
for out in self:
out.clear()
- class _Progress(object):
+ class _Progress(list):
"""Class used to composite different Progress objects"""
def __init__(self, size, title, bar_type='default'):
"""Create a progress on each of the added output instances"""
- self._progresses = []
for out in self.parent:
- self._progresses.append(out.Progress(size, title, bar_type))
+ self.append(out.Progress(size, title, bar_type))
def goto(self, dest):
"""Call the goto method of each of the progress instances"""
- for progress in self._progresses:
+ for progress in self:
progress.goto(dest)
def next(self):
"""Call the next method of each of the progress instances"""
- for progress in self._progresses:
+ for progress in self:
progress.next()
def success(self, result):
"""Call the success method of each of the progress instances"""
- for progress in self._progresses:
+ for progress in self:
progress.success(result)
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/image_creator/output/dialog.py b/image_creator/output/dialog.py
index 8fb93cc..c7fbc64 100644
--- a/image_creator/output/dialog.py
+++ b/image_creator/output/dialog.py
@@ -48,6 +48,10 @@ class GaugeOutput(Output):
self.d.gauge_update(self.percent, self.msg, update_text=True)
time.sleep(0.4)
+ def result(self, msg='', new_line=True):
+ """Print a result"""
+ self.info(msg, new_line)
+
def success(self, result, new_line=True):
"""Print result after a successful action"""
self.percent = 100
@@ -61,6 +65,12 @@ class GaugeOutput(Output):
update_text=True)
time.sleep(0.4)
+ def error(self, msg, new_line=True):
+ """Print an error"""
+ self.d.gauge_update(self.percent, "%s Error: %s" % (self.msg, msg),
+ update_text=True)
+ time.sleep(0.4)
+
def cleanup(self):
"""Cleanup the GaugeOutput instance"""
self.d.gauge_stop()
@@ -120,6 +130,10 @@ class InfoBoxOutput(Output):
self.d.infobox(display, title=self.title, height=self.height,
width=self.width)
+ def result(self, msg='', new_line=True):
+ """Print a result"""
+ self.info(msg, new_line)
+
def success(self, result, new_line=True):
"""Print result after an action is completed successfully"""
self.info(result, new_line)
@@ -128,6 +142,10 @@ class InfoBoxOutput(Output):
"""Print a warning message"""
self.info("Warning: %s" % msg, new_line)
+ def error(self, msg, new_line=True):
+ """Print an error message"""
+ self.info("Error: %s" % msg, new_line)
+
def finalize(self):
"""Finalize the output. After this is called, the InfoboxOutput
instance should be destroyed
--
GitLab