add msger.py for all unified colored message output
authorJF Ding <jian-feng.ding@intel.com>
Thu, 18 Aug 2011 03:12:28 +0000 (11:12 +0800)
committerJF Ding <jian-feng.ding@intel.com>
Thu, 18 Aug 2011 05:58:23 +0000 (13:58 +0800)
and some code cleanup

mic/chroot.py
mic/configmgr.py
mic/creator.py
mic/msger.py [new file with mode: 0644]
mic/utils/fs_related.py
mic/utils/kickstart.py
tests/micng.conf [deleted file]
tools/mic

index 319839f..8b519e7 100644 (file)
@@ -25,6 +25,7 @@ import subprocess
 import mic.utils.fs_related as fs_related
 import mic.utils.misc as misc
 import mic.utils.errors as errors
+from mic import msger
 
 BIND_MOUNTS = (
                 "/proc",
@@ -75,7 +76,7 @@ def check_bind_mounts(chrootdir, bindmounts):
 
             tmpdir = chrootdir + "/" + srcdst[1]
             if os.path.isdir(tmpdir):
-                print "Warning: dir %s has existed."  % tmpdir
+                msger.warning("Warning: dir %s has existed."  % tmpdir)
 
     return True
 
@@ -98,7 +99,7 @@ def cleanup_mounts(chrootdir):
                 args = [ umountcmd, "-l", point ]
                 ret = subprocess.call(args, stdout=dev_null, stderr=dev_null)
                 if ret != 0:
-                    print "ERROR: failed to unmount %s" % point
+                    msger.warning("failed to unmount %s" % point)
                     os.close(dev_null)
                     return ret
 
@@ -152,7 +153,7 @@ def setup_chrootenv(chrootdir, bindmounts = None):
 
     def bind_mount(chrootmounts):
         for b in chrootmounts:
-            print "bind_mount: %s -> %s" % (b.src, b.dest)
+            msger.info("bind_mount: %s -> %s" % (b.src, b.dest))
             b.mount()
 
     def setup_resolv(chrootdir):
@@ -179,7 +180,7 @@ def cleanup_chrootenv(chrootdir, bindmounts = None, globalmounts = []):
     def bind_unmount(chrootmounts):
         chrootmounts.reverse()
         for b in chrootmounts:
-            print "bind_unmount: %s -> %s" % (b.src, b.dest)
+            msger.info("bind_unmount: %s -> %s" % (b.src, b.dest))
             b.unmount()
 
     def cleanup_resolv(chrootdir):
@@ -219,7 +220,7 @@ def cleanup_chrootenv(chrootdir, bindmounts = None, globalmounts = []):
                 if len(os.listdir(tmpdir)) == 0:
                     shutil.rmtree(tmpdir, ignore_errors = True)
                 else:
-                    print "Warning: dir %s isn't empty." % tmpdir
+                    msger.warning("Warning: dir %s isn't empty." % tmpdir)
 
     chroot_lockfd.close()
     bind_unmount(globalmounts)
@@ -281,8 +282,7 @@ def chroot(chrootdir, bindmounts = None, execute = "/bin/bash"):
         raise errors.CreatorError("Failed to get architecture from any of the following files %s from chroot." % files_to_check)
 
     try:
-        print "Launching shell. Exit to continue."
-        print "----------------------------------"
+        msger.info("Launching shell. Exit to continue.\n----------------------------------")
         globalmounts = setup_chrootenv(chrootdir, bindmounts)
         subprocess.call(execute, preexec_fn = mychroot, shell=True)
 
index 7892591..69a7727 100644 (file)
@@ -22,6 +22,7 @@ import logging
 import ConfigParser
 import mic.utils as utils
 import mic.utils.errors as errors
+from mic import msger
 
 DEFAULT_GSITECONF='/etc/mic/mic.conf'
 
@@ -58,7 +59,7 @@ class ConfigMgr(object):
         self._siteconf = siteconf
         if not self.siteconf:
             self._siteconf = DEFAULT_GSITECONF
-        
+
         self._ksconf = ksconf
 
     def __set_siteconf(self, siteconf):
@@ -112,10 +113,10 @@ class ConfigMgr(object):
         try:
             kickstart = utils.kickstart.read_kickstart(ksconf)
             ksrepos = utils.misc.get_repostrs_from_ks(kickstart)
+            msger.info("Retrieving repo metadata:")
             repometadata = utils.misc.get_metadata_from_repos(ksrepos, self.create['cachedir'])
-            sys.stdout.write("Retrieving repo metadata:\n")
-            sys.stdout.write("%s" % repometadata)
-            sys.stdout.flush()
+            msger.info("\nDONE")
+
             self.create['ks'] = kickstart
             self.create['repomd'] = repometadata
             self.create['name'] = os.path.splitext(os.path.basename(ksconf))[0]
index 1fe9895..92594f2 100644 (file)
@@ -23,6 +23,7 @@ import logging
 import mic.utils.cmdln as cmdln
 import mic.configmgr as configmgr
 import mic.pluginmgr as pluginmgr
+from mic import msger
 
 class Creator(cmdln.Cmdln):
     """${name}: create an image
@@ -101,8 +102,7 @@ class Creator(cmdln.Cmdln):
 
         if args:
             if os.geteuid() != 0:
-                print >> sys.stderr, "You must run %s as root" % sys.argv[0]
-                return 1
+                msger.error('Need root permission to run this command')
 
             return self.cmd(args)
 
diff --git a/mic/msger.py b/mic/msger.py
new file mode 100644 (file)
index 0000000..030d1f0
--- /dev/null
@@ -0,0 +1,111 @@
+#!/usr/bin/python -tt
+# vim: ai ts=4 sts=4 et sw=4
+
+#    Copyright (c) 2009 Intel Corporation
+#
+#    This program is free software; you can redistribute it and/or modify it
+#    under the terms of the GNU General Public License as published by the Free
+#    Software Foundation; version 2 of the License
+#
+#    This program is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#    for more details.
+#
+#    You should have received a copy of the GNU General Public License along
+#    with this program; if not, write to the Free Software Foundation, Inc., 59
+#    Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import os,sys
+import re
+
+__ALL__ = ['set_mode', 'info', 'warning', 'error', 'ask']
+
+# COLORs in ANSI
+INFO_COLOR = 32 # green
+WARN_COLOR = 33 # yellow
+ERR_COLOR  = 31 # red
+ASK_COLOR  = 34 # blue
+
+PREFIX_RE = re.compile('^<(.*?)>\s*(.*)')
+
+INTERACTIVE = True
+
+def _color_print(head, color, msg = None, stream = sys.stdout):
+
+    colored = True
+    if not stream.isatty():
+        colored = False
+    elif os.getenv('ANSI_COLORS_DISABLED') is not None:
+        colored = False
+
+    if colored:
+        head = '\033[%dm%s:\033[0m' %(color, head)
+    else:
+        head += ':'
+
+    if msg:
+        stream.write('%s %s\n' % (head, msg))
+    else:
+        stream.write('%s ' % head)
+
+def _color_perror(head, color, msg):
+    _color_print(head, color, msg, sys.stderr)
+
+def _split_msg(head, msg):
+    if msg.startswith('\n'):
+        msg = msg.lstrip()
+        head = '\n' + head
+
+    m = PREFIX_RE.match(msg)
+    if m:
+        head += ' <%s>' % m.group(1)
+        msg = m.group(2)
+    return head, msg
+
+def set_mode(interactive):
+    global INTERACTIVE
+    if interactive:
+        INTERACTIVE = True
+    else:
+        INTERACTIVE = False
+
+def info(msg):
+    head, msg = _split_msg('Info', msg)
+    _color_print(head, INFO_COLOR, msg)
+
+def warning(msg):
+    head, msg = _split_msg('Warning', msg)
+    _color_perror(head, WARN_COLOR, msg)
+
+def error(msg):
+    head, msg = _split_msg('Error', msg)
+    _color_perror(head, ERR_COLOR, msg)
+    sys.exit(1)
+
+def ask(msg, default=True):
+    _color_print('Q', ASK_COLOR, '')
+    try:
+        if default:
+            msg += '(Y/n) '
+        else:
+            msg += '(y/N) '
+        if INTERACTIVE:
+            repl = raw_input(msg)
+            if repl.lower() == 'y':
+                return True
+            elif repl.lower() == 'n':
+                return False
+            else:
+                return default
+
+        else:
+            sys.stdout.write('%s ' % msg)
+            if default:
+                sys.stdout.write('Y\n')
+            else:
+                sys.stdout.write('N\n')
+            return default
+    except KeyboardInterrupt:
+        sys.stdout.write('\n')
+        sys.exit(2)
index e73d67c..6b9a684 100644 (file)
@@ -33,6 +33,7 @@ import termios
 from errors import *
 from urlgrabber.grabber import URLGrabber
 from urlgrabber.grabber import URLGrabError
+from mic import msger
 
 def terminal_width(fd=1):
     """ Get the real terminal width """
@@ -59,7 +60,7 @@ class TextProgress(object):
             if self.total is None:
                 sys.stdout.write("\rRetrieving %s ..." % truncate_url(self.url, self.termwidth - 15))
             else:
-                sys.stdout.write("\rRetrieving %s (%d|%d) ..." % (truncate_url(self.url, self.termwidth - 25), self.counter, self.total))
+                sys.stdout.write("\rRetrieving %s [%d/%d] ..." % (truncate_url(self.url, self.termwidth - 25), self.counter, self.total))
         else:
             sys.stdout.write("Retrieving %s ..." % truncate_url(self.url, self.termwidth - 15))
 
@@ -921,7 +922,7 @@ def load_module(module):
             found = True
             break
     if not found:
-        print "Loading %s..." % module
+        msger.info("Loading %s..." % module)
         dev_null = os.open("/dev/null", os.O_WRONLY)
         modprobecmd = find_binary_path("modprobe")
         modprobe = subprocess.Popen([modprobecmd, module],
index 827cc52..b26605f 100644 (file)
@@ -16,7 +16,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-import os
+import os, sys
 import os.path
 import shutil
 import subprocess
@@ -24,8 +24,6 @@ import time
 import logging
 import string
 
-#import rhpl.keyboard
-
 import pykickstart.commands as kscommands
 import pykickstart.constants as ksconstants
 import pykickstart.errors as kserrors
@@ -40,9 +38,7 @@ import kscommands.desktop as desktop
 import kscommands.moblinrepo as moblinrepo
 import kscommands.micboot as micboot
 
-import sys
-sys.path.append("~/0509/mic")
-import misc as misc
+import misc
 
 def read_kickstart(path):
     """Parse a kickstart file and return a KickstartParser instance.
diff --git a/tests/micng.conf b/tests/micng.conf
deleted file mode 100644 (file)
index 69e77bf..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-[main]
-cache=./cache
-outdir=.
-tmpdir=/var/tmp
index e9e9582..893831d 100755 (executable)
--- a/tools/mic
+++ b/tools/mic
@@ -36,7 +36,7 @@ class Mic(cmdln.Cmdln):
     Usage: mic SUBCOMMAND [OPTS] [ARGS...]
 
     Mic Image Creation Tool.
-    Try 'mic help SUBCOMAND' for help on a specific subcommand. 
+    Try 'mic help SUBCOMAND' for help on a specific subcommand.
 
     ${command_list}
     global ${option_list}