move msger.run to utils.runner module and more apis
authorJF Ding <Jian-feng.Ding@intel.com>
Mon, 5 Sep 2011 09:03:55 +0000 (18:03 +0900)
committerJF Ding <Jian-feng.Ding@intel.com>
Mon, 5 Sep 2011 09:03:55 +0000 (18:03 +0900)
in new separate module mic/utils/runner.py, three new apis
provided:
    runner.show (similar with msger.run)
    runner.quiet
    runner.outs
    and a more generic runner.runtool

13 files changed:
mic/chroot.py
mic/imager/baseimager.py
mic/imager/fs.py
mic/imager/livecd.py
mic/imager/liveusb.py
mic/imager/raw.py
mic/kickstart/__init__.py
mic/msger.py
mic/utils/fs_related.py
mic/utils/rpmmisc.py
mic/utils/runner.py [new file with mode: 0644]
plugins/imager/raw_plugin.py
tools/mic

index 9b4ae37..35abc0b 100644 (file)
@@ -86,7 +86,7 @@ def cleanup_mounts(chrootdir):
     umountcmd = misc.find_binary_path("umount")
     for point in BIND_MOUNTS:
         args = [ umountcmd, "-l", chrootdir + point ]
-        msger.run(args, True)
+        runner.quiet(args)
 
     abs_chrootdir = os.path.abspath(chrootdir)
     with open('/proc/mounts') as f:
@@ -98,7 +98,7 @@ def cleanup_mounts(chrootdir):
                     continue
 
                 args = [ umountcmd, "-l", point ]
-                ret = msger.run(args, True)
+                ret = runner.quiet(args)
                 if ret != 0:
                     msger.warning("failed to unmount %s" % point)
                     return ret
index f1aba09..fffbe07 100644 (file)
@@ -30,7 +30,7 @@ import rpm
 from mic.utils.errors import CreatorError
 from mic.utils.misc import get_filesystem_avail, is_statically_linked,setup_qemu_emulator, create_release
 from mic.utils.fs_related import find_binary_path, makedirs, BindChrootMount
-from mic.utils import rpmmisc
+from mic.utils import rpmmisc, runner
 from mic import kickstart
 from mic import msger
 
@@ -993,12 +993,12 @@ class BaseImageCreator(object):
             if self.__img_compression_method == "bz2":
                 bzip2 = find_binary_path('bzip2')
                 msger.info("Compressing %s with bzip2. Please wait..." % img_location)
-                rc = msger.run([bzip2, "-f", img_location])
+                rc = runner.show([bzip2, "-f", img_location])
                 if rc:
                     raise CreatorError("Failed to compress image %s with %s." % (img_location, self.__img_compression_method))
                 for bootimg in glob.glob(os.path.dirname(img_location) + "/*-boot.bin"):
                     msger.info("Compressing %s with bzip2. Please wait..." % bootimg)
-                    rc = msger.run([bzip2, "-f", bootimg])
+                    rc = runner.show([bzip2, "-f", bootimg])
                     if rc:
                         raise CreatorError("Failed to compress image %s with %s." % (bootimg, self.__img_compression_method))
 
@@ -1012,7 +1012,7 @@ class BaseImageCreator(object):
             makedirs(destdir)
 
         # Ensure all data is flushed to _outdir
-        msger.run('sync', True)
+        runner.quiet('sync')
 
         for f in os.listdir(self._outdir):
             shutil.move(os.path.join(self._outdir, f),
index d11f24a..a902f57 100644 (file)
@@ -21,6 +21,7 @@ import os, sys
 
 from baseimager import BaseImageCreator
 from mic import msger
+from mic.utils import runner
 
 class FsImageCreator(BaseImageCreator):
     def __init__(self, cfgmgr = None, pkgmgr = None):
@@ -35,7 +36,7 @@ class FsImageCreator(BaseImageCreator):
             self._save_recording_pkgs(destdir)
 
         msger.info("Copying %s to %s ..." % (self._instroot, fsdir))
-        msger.run(['cp', "-af", self._instroot, fsdir])
+        runner.show(['cp', "-af", self._instroot, fsdir])
 
         for exclude in ["/dev/fd", "/dev/stdin", "/dev/stdout", "/dev/stderr", "/etc/mtab"]:
             if os.path.exists(fsdir + exclude):
index a969ffb..6d7106e 100644 (file)
@@ -22,7 +22,7 @@ import glob
 import shutil
 
 from mic import kickstart, msger
-from mic.utils import fs_related, rpmmisc
+from mic.utils import fs_related, rpmmisc, runner
 from mic.utils.errors import CreatorError
 
 from loop import LoopImageCreator
@@ -220,7 +220,7 @@ class LiveImageCreatorBase(LoopImageCreator):
 
         args.append(isodir)
 
-        if msger.run(args) != 0:
+        if runner.show(args) != 0:
             raise CreatorError("ISO creation failed!")
 
         """ It should be ok still even if you haven't isohybrid """
@@ -232,7 +232,7 @@ class LiveImageCreatorBase(LoopImageCreator):
 
         if isohybrid:
             args = [isohybrid, "-partok", iso ]
-            if msger.run(args) != 0:
+            if runner.show(args) != 0:
                raise CreatorError("Hybrid ISO creation failed!")
 
         self.__implant_md5sum(iso)
@@ -248,7 +248,7 @@ class LiveImageCreatorBase(LoopImageCreator):
             implantisomd5 = ""
             return
 
-        msger.run([implantisomd5, iso])
+        runner.show([implantisomd5, iso])
 
     def _stage_final_image(self):
         try:
index 6ed65ee..2d37457 100644 (file)
@@ -22,7 +22,7 @@ import shutil
 import re
 
 from mic import msger
-from mic.utils import misc, fs_related
+from mic.utils import misc, fs_related, runner
 from mic.utils.errors import CreatorError, MountError
 from mic.utils.partitionedfs import PartitionedMount
 
@@ -87,7 +87,7 @@ class LiveUSBImageCreator(LiveCDImageCreator):
                 overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid)
 
             args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"]
-            rc = msger.run(args)
+            rc = runner.show(args)
             if rc:
                 raise CreatorError("Can't copy isolinux directory %s" % (isodir + "/isolinux/*"))
 
@@ -103,7 +103,7 @@ class LiveUSBImageCreator(LiveCDImageCreator):
                 path = os.path.join(syslinux_path, f)
                 if os.path.isfile(path):
                     args = ['cp', path, usbmnt + "/syslinux/"]
-                    rc = msger.run(args)
+                    rc = runner.show(args)
                     if rc:
                         raise CreatorError("Can't copy syslinux file %s" % (path))
                 else:
@@ -127,7 +127,7 @@ class LiveUSBImageCreator(LiveCDImageCreator):
                     args = ['dd', "if=/dev/zero", "of=" + usbmnt + "/LiveOS/" + overfile, "count=%d" % overlaysizemb, "bs=1M"]
                 else:
                     args = ['dd', "if=/dev/null", "of=" + usbmnt + "/LiveOS/" + overfile, "count=1", "bs=1M", "seek=%d" % overlaysizemb]
-                rc = msger.run(args)
+                rc = runner.show(args)
                 if rc:
                     raise CreatorError("Can't create overlay file")
                 text = text.replace("liveimg", "liveimg overlay=" + usblabel)
@@ -137,11 +137,11 @@ class LiveUSBImageCreator(LiveCDImageCreator):
                 msger.info("Initializing swap file")
                 swapfile = usbmnt + "/LiveOS/" + "swap.img"
                 args = ['dd', "if=/dev/zero", "of=" + swapfile, "count=%d" % swapsizemb, "bs=1M"]
-                rc = msger.run(args)
+                rc = runner.show(args)
                 if rc:
                     raise CreatorError("Can't create swap file")
                 args = ["mkswap", "-f", swapfile]
-                rc = msger.run(args)
+                rc = runner.show(args)
                 if rc:
                     raise CreatorError("Can't mkswap on swap file")
 
@@ -152,7 +152,7 @@ class LiveUSBImageCreator(LiveCDImageCreator):
                     args = ['dd', "if=/dev/zero", "of=" + homefile, "count=%d" % homesizemb, "bs=1M"]
                 else:
                     args = ['dd', "if=/dev/null", "of=" + homefile, "count=1", "bs=1M", "seek=%d" % homesizemb]
-                rc = msger.run(args)
+                rc = runner.show(args)
                 if rc:
                     raise CreatorError("Can't create home file")
 
@@ -161,13 +161,13 @@ class LiveUSBImageCreator(LiveCDImageCreator):
                     args = [mkfscmd, "-F", "-j", homefile]
                 else:
                     args = [mkfscmd, homefile]
-                rc = msger.run(args)
+                rc = runner.show(args)
                 if rc:
                     raise CreatorError("Can't mke2fs home file")
                 if fstype == "ext2" or fstype == "ext3":
                     tune2fs = fs_related.find_binary_path("tune2fs")
                     args = [tune2fs, "-c0", "-i0", "-ouser_xattr,acl", homefile]
-                    rc = msger.run(args)
+                    rc = runner.show(args)
                     if rc:
                          raise CreatorError("Can't tune2fs home file")
 
@@ -186,7 +186,7 @@ class LiveUSBImageCreator(LiveCDImageCreator):
             fd = open(syslinuxcfg, "w")
             fd.write(text)
             fd.close()
-            rc = msger.run(args)
+            rc = runner.show(args)
             if rc:
                 raise CreatorError("Can't install boot loader.")
 
@@ -205,7 +205,7 @@ class LiveUSBImageCreator(LiveCDImageCreator):
         outimg = "%s/%s.usbimg" % (self._outdir, self.name)
 
         args = ['dd', "if=" + mbrfile, "of=" + outimg, "seek=0", "conv=notrunc", "bs=1", "count=%d" % (mbrsize)]
-        rc = msger.run(args)
+        rc = runner.show(args)
         if rc:
             raise CreatorError("Can't set MBR.")
 
index a1d72ef..915a70e 100644 (file)
@@ -24,7 +24,7 @@ import shutil
 from urlgrabber import progress
 
 from mic import kickstart, msger
-from mic.utils import fs_related
+from mic.utils import fs_related, runner
 from mic.utils.partitionedfs import PartitionedMount
 from mic.utils.errors import CreatorError, MountError
 
@@ -271,13 +271,13 @@ class RawImageCreator(BaseImageCreator):
 
         #Set MBR
         mbrsize = os.stat("%s/usr/share/syslinux/mbr.bin" % self._instroot)[stat.ST_SIZE]
-        rc = msger.run(['dd', "if=%s/usr/share/syslinux/mbr.bin" % self._instroot, "of=" + loopdev])
+        rc = runner.show(['dd', "if=%s/usr/share/syslinux/mbr.bin" % self._instroot, "of=" + loopdev])
         if rc != 0:
             raise MountError("Unable to set MBR to %s" % loopdev)
 
         #Set Bootable flag
         parted = fs_related.find_binary_path("parted")
-        rc = msger.run([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"], True)
+        rc = runner.quiet([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"])
         #XXX disabled return code check because parted always fails to
         #reload part table with loop devices. Annoying because we can't
         #distinguish this failure from real partition failures :-(
@@ -285,10 +285,10 @@ class RawImageCreator(BaseImageCreator):
             raise MountError("Unable to set bootable flag to %sp%d" % (loopdev, (bootdevnum + 1)))
 
         #Ensure all data is flushed to disk before doing syslinux install
-        msger.run('sync', True)
+        runner.quiet('sync')
 
         fullpathsyslinux = fs_related.find_binary_path("extlinux")
-        rc = msger.run([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot])
+        rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot])
         if rc != 0:
             raise MountError("Unable to install syslinux bootloader to %sp%d" % (loopdev, (bootdevnum + 1)))
 
index 55da308..1c7a8d4 100644 (file)
@@ -23,10 +23,8 @@ import subprocess
 import time
 import string
 
-from mic.utils import errors
-from mic.utils import misc
-from mic.utils import fs_related as fs
 from mic import msger
+from mic.utils import errors, misc, runner, fs_related as fs
 
 import pykickstart.commands as kscommands
 import pykickstart.constants as ksconstants
@@ -418,7 +416,7 @@ class MoblinRepoConfig(KickstartConfig):
         if repodata:
             for repo in repodata:
                 if repo['repokey']:
-                    msger.run(['rpm', "--root=%s" % self.instroot, "--import", repo['repokey']], True)
+                    runner.quiet(['rpm', "--root=%s" % self.instroot, "--import", repo['repokey']])
 
 class RPMMacroConfig(KickstartConfig):
     """A class to apply the specified rpm macros to the filesystem"""
index d2c4166..d01a47c 100644 (file)
@@ -21,7 +21,7 @@
 import os,sys
 import re
 
-__ALL__ = ['set_mode', 'get_loglevel', 'set_loglevel', 'raw' 'debug', 'verbose', 'info', 'warning', 'error', 'ask', 'pause', 'run']
+__ALL__ = ['set_mode', 'get_loglevel', 'set_loglevel', 'raw' 'debug', 'verbose', 'info', 'warning', 'error', 'ask', 'pause']
 
 # COLORs in ANSI
 INFO_COLOR = 32 # green
@@ -185,26 +185,3 @@ def pause(msg=None):
             msg = 'press <ENTER> to continue ...'
         raw_input(msg)
 
-def run(cmdln_or_args, quiet=False):
-    from subprocess import *
-    if isinstance(cmdln_or_args, list):
-        args = cmdln_or_args
-    else:
-        import shlex
-        args = shlex.split(cmdln_or_args)
-
-    p = Popen(args, stdout=PIPE, stderr=PIPE)
-    out = p.communicate()[0].strip()
-
-    if not quiet:
-        msg =  'running command: "%s"' % ' '.join(args)
-        if out:
-            msg += ', with output::'
-            msg += '\n  +----------------'
-            for line in out.splitlines():
-                msg += '\n  | %s' % line
-            msg += '\n  +----------------'
-
-        verbose(msg)
-
-    return p.returncode
index 6aab7ee..544caca 100644 (file)
@@ -32,6 +32,7 @@ import termios
 from errors import *
 from urlgrabber.grabber import URLGrabber, URLGrabError
 from mic import msger
+import runner
 
 def terminal_width(fd=1):
     """ Get the real terminal width """
@@ -100,13 +101,13 @@ def mksquashfs(in_img, out_img):
     if not sys.stdout.isatty():
         args.append("-no-progress")
 
-    ret = msger.run(args)
+    ret = runner.show(args)
     if ret != 0:
         raise SquashfsError("'%s' exited with error (%d)" % (' '.join(args), ret))
 
 def resize2fs(fs, size):
     resize2fs = find_binary_path("resize2fs")
-    return msger.run([resize2fs, fs, "%sK" % (size / 1024,)], True)
+    return runner.quiet([resize2fs, fs, "%sK" % (size / 1024,)])
 
 def my_fuser(file):
     ret = False
@@ -115,7 +116,7 @@ def my_fuser(file):
         return ret
 
     dev_null = os.open("/dev/null", os.O_WRONLY)
-    rc = msger.run([fuser, "-s", file], True)
+    rc = runner.quiet([fuser, "-s", file])
     if rc == 0:
         fuser_proc = subprocess.Popen([fuser, file], stdout=subprocess.PIPE, stderr=dev_null)
         pids = fuser_proc.communicate()[0].strip().split()
@@ -167,12 +168,12 @@ class BindChrootMount:
             return
 
         makedirs(self.dest)
-        rc = msger.run([self.mountcmd, "--bind", self.src, self.dest])
+        rc = runner.show([self.mountcmd, "--bind", self.src, self.dest])
         if rc != 0:
             raise MountError("Bind-mounting '%s' to '%s' failed" %
                              (self.src, self.dest))
         if self.option:
-            rc = msger.run([self.mountcmd, "--bind", "-o", "remount,%s" % self.option, self.dest])
+            rc = runner.show([self.mountcmd, "--bind", "-o", "remount,%s" % self.option, self.dest])
             if rc != 0:
                 raise MountError("Bind-remounting '%s' failed" % self.dest)
         self.mounted = True
@@ -182,7 +183,7 @@ class BindChrootMount:
             return
 
         if self.ismounted():
-            msger.run([self.umountcmd, "-l", self.dest])
+            runner.show([self.umountcmd, "-l", self.dest])
         self.mounted = False
 
 class LoopbackMount:
@@ -200,7 +201,7 @@ class LoopbackMount:
 
     def lounsetup(self):
         if self.losetup:
-            msger.run([self.losetupcmd, "-d", self.loopdev])
+            runner.show([self.losetupcmd, "-d", self.loopdev])
             self.losetup = False
             self.loopdev = None
 
@@ -218,7 +219,7 @@ class LoopbackMount:
 
         self.loopdev = losetupOutput.split()[0]
 
-        rc = msger.run([self.losetupcmd, self.loopdev, self.lofile])
+        rc = runner.show([self.losetupcmd, self.loopdev, self.lofile])
         if rc != 0:
             raise MountError("Failed to allocate loop device for '%s'" %
                              self.lofile)
@@ -341,7 +342,7 @@ class LoopbackDisk(Disk):
         device = losetupOutput.split()[0]
 
         msger.debug("Losetup add %s mapping to %s"  % (device, self.lofile))
-        rc = msger.run([self.losetupcmd, device, self.lofile])
+        rc = runner.show([self.losetupcmd, device, self.lofile])
         if rc != 0:
             raise MountError("Failed to allocate loop device for '%s'" %
                              self.lofile)
@@ -351,7 +352,7 @@ class LoopbackDisk(Disk):
         if self.device is None:
             return
         msger.debug("Losetup remove %s" % self.device)
-        rc = msger.run([self.losetupcmd, "-d", self.device])
+        rc = runner.show([self.losetupcmd, "-d", self.device])
         self.device = None
 
 class SparseLoopbackDisk(LoopbackDisk):
@@ -431,8 +432,8 @@ class DiskMount(Mount):
     def unmount(self):
         if self.mounted:
             msger.debug("Unmounting directory %s" % self.mountdir)
-            msger.run('sync', True) # sync the data on this mount point
-            rc = msger.run([self.umountcmd, "-l", self.mountdir])
+            runner.quiet('sync') # sync the data on this mount point
+            rc = runner.show([self.umountcmd, "-l", self.mountdir])
             if rc == 0:
                 self.mounted = False
             else:
@@ -468,7 +469,7 @@ class DiskMount(Mount):
         if self.fstype:
             args.extend(["-t", self.fstype])
 
-        rc = msger.run(args)
+        rc = runner.show(args)
         if rc != 0:
             raise MountError("Failed to mount '%s' to '%s' with command '%s'. Retval: %s" %
                              (self.disk.device, self.mountdir, " ".join(args), rc))
@@ -500,10 +501,10 @@ class ExtDiskMount(DiskMount):
             return
 
         msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        rc = msger.run([self.mkfscmd,
-                        "-F", "-L", self.fslabel,
-                        "-m", "1", "-b", str(self.blocksize),
-                        self.disk.device]) # str(self.disk.size / self.blocksize)])
+        rc = runner.show([self.mkfscmd,
+                          "-F", "-L", self.fslabel,
+                          "-m", "1", "-b", str(self.blocksize),
+                          self.disk.device]) # str(self.disk.size / self.blocksize)])
         if rc != 0:
             raise MountError("Error creating %s filesystem on disk %s" % (self.fstype, self.disk.device))
 
@@ -517,7 +518,7 @@ class ExtDiskMount(DiskMount):
 
         self.uuid = self.__parse_field(out, "Filesystem UUID")
         msger.debug("Tuning filesystem on %s" % self.disk.device)
-        msger.run([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
+        runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
 
     def __resize_filesystem(self, size = None):
         current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
@@ -554,7 +555,7 @@ class ExtDiskMount(DiskMount):
 
     def __fsck(self):
         msger.info("Checking filesystem %s" % self.disk.lofile)
-        msger.run(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
+        runner.show(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
 
     def __get_size_from_filesystem(self):
         dev_null = os.open("/dev/null", os.O_WRONLY)
@@ -609,7 +610,7 @@ class VfatDiskMount(DiskMount):
             return
 
         msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        rc = msger.run([self.mkfscmd, "-n", self.fslabel, "-i", self.uuid, self.disk.device])
+        rc = runner.show([self.mkfscmd, "-n", self.fslabel, "-i", self.uuid, self.disk.device])
         if rc != 0:
             raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
 
@@ -650,7 +651,7 @@ class VfatDiskMount(DiskMount):
 
     def __fsck(self):
         msger.debug("Checking filesystem %s" % self.disk.lofile)
-        msger.run([self.fsckcmd, "-y", self.disk.lofile])
+        runner.show([self.fsckcmd, "-y", self.disk.lofile])
 
     def __get_size_from_filesystem(self):
         return self.disk.size
@@ -699,7 +700,7 @@ class BtrfsDiskMount(DiskMount):
 
         # disable selinux, selinux will block write
         if os.path.exists("/usr/sbin/setenforce"):
-            msger.run(["/usr/sbin/setenforce", "0"])
+            runner.show(["/usr/sbin/setenforce", "0"])
 
     def __parse_field(self, output, field):
         for line in output.split(" "):
@@ -714,7 +715,7 @@ class BtrfsDiskMount(DiskMount):
             return
 
         msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        rc = msger.run([self.mkfscmd, "-L", self.fslabel, self.disk.device])
+        rc = runner.show([self.mkfscmd, "-L", self.fslabel, self.disk.device])
         if rc != 0:
             raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
 
@@ -761,7 +762,7 @@ class BtrfsDiskMount(DiskMount):
 
     def __fsck(self):
         msger.debug("Checking filesystem %s" % self.disk.lofile)
-        msger.run([self.btrfsckcmd, self.disk.lofile])
+        runner.show([self.btrfsckcmd, self.disk.lofile])
 
     def __get_size_from_filesystem(self):
         return self.disk.size
@@ -813,7 +814,7 @@ class DeviceMapperSnapshot(object):
                                              self.cowloop.device)
 
         args = [self.dmsetupcmd, "create", self.__name, "--table", table]
-        if msger.run(args) != 0:
+        if runner.show(args) != 0:
             self.cowloop.cleanup()
             self.imgloop.cleanup()
             raise SnapshotError("Could not create snapshot device using: " + ' '.join(args))
@@ -825,7 +826,7 @@ class DeviceMapperSnapshot(object):
             return
 
         time.sleep(2)
-        rc = msger.run([self.dmsetupcmd, "remove", self.__name])
+        rc = runner.show([self.dmsetupcmd, "remove", self.__name])
         if not ignore_errors and rc != 0:
             raise SnapshotError("Could not remove snapshot device")
 
@@ -906,7 +907,7 @@ def load_module(module):
             break
     if not found:
         msger.info("Loading %s..." % module)
-        msger.run(['modprobe', module], True)
+        runner.quiet(['modprobe', module])
 
 def myurlgrab(url, filename, proxies, progress_obj = None):
     g = URLGrabber()
@@ -917,7 +918,7 @@ def myurlgrab(url, filename, proxies, progress_obj = None):
         file = url.replace("file://", "")
         if not os.path.exists(file):
             raise CreatorError("URLGrabber error: can't find file %s" % file)
-        msger.run(['cp', "-f", file, filename])
+        runner.show(['cp', "-f", file, filename])
     else:
         try:
             filename = g.urlgrab(url = url, filename = filename,
index e375f21..2845bce 100644 (file)
@@ -20,6 +20,7 @@
 import os, sys, re
 import rpm
 from mic import msger
+import runner
 
 class RPMInstallCallback:
     """ Command line callback class for callbacks from the RPM library.
@@ -359,8 +360,7 @@ def getBaseArch():
         return basearch
 
 def checkRpmIntegrity(bin_rpm, package):
-    argv = [bin_rpm, "--checksig", "--nogpg", package]
-    return msger.run(argv, True)
+    return runner.quiet([bin_rpm, "--checksig", "--nogpg", package])
 
 def checkSig(ts, package):
     """ Takes a transaction set and a package, check it's sigs,
diff --git a/mic/utils/runner.py b/mic/utils/runner.py
new file mode 100644 (file)
index 0000000..df515c7
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/python -tt
+#
+# Copyright 2011 Intel, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc.
+#
+
+import os
+from subprocess import *
+from mic import msger
+
+def runtool(cmdln_or_args, catch=1):
+    """ wrapper for most of the subprocess calls
+    input:
+        cmdln_or_args: can be both args and cmdln str (shell=True)
+        catch: 0, quitely run
+               1, only STDOUT
+               2, only STDERR
+               3, both STDOUT and STDERR
+    return:
+        (rc, output)
+        if catch==0: the output will always None
+    """
+
+    if catch not in (0, 1, 2, 3):
+        # invalid catch selection, will cause exception, that's good
+        return None
+
+    from subprocess import *
+    if isinstance(cmdln_or_args, list):
+        args = cmdln_or_args
+    else:
+        import shlex
+        args = shlex.split(cmdln_or_args)
+
+    if catch != 3:
+        dev_null = os.open("/dev/null", os.O_WRONLY)
+
+    if catch == 0:
+        sout = dev_null
+        serr = dev_null
+    elif catch == 1:
+        sout = PIPE
+        serr = dev_null
+    elif catch == 2:
+        sout = dev_null
+        serr = PIPE
+    elif catch == 3:
+        sout = PIPE
+        serr = PIPE
+
+    try:
+        p = Popen(args, stdout=sout, stderr=serr)
+        out = p.communicate()[0]
+    except OSError, e:
+        if e.errno == 2:
+            # [Errno 2] No such file or directory
+            msger.error('Cannot run command: %s, lost dependency?' % args[0])
+        else:
+            raise # relay
+    finally:
+        if catch != 3:
+            dev_null = os.open("/dev/null", os.O_WRONLY)
+
+    return (p.returncode, out)
+
+def show(cmdln_or_args):
+    # show all the message using msger.verbose
+
+    rc, out = runtool(cmdln_or_args, catch=3)
+
+    if isinstance(cmdln_or_args, list):
+        cmd = ' '.join(cmdln_or_args)
+    else:
+        cmd = cmdln_or_args
+
+    msg =  'running command: "%s"' % cmd
+    if out: out = out.strip()
+    if out:
+        msg += ', with output::'
+        msg += '\n  +----------------'
+        for line in out.splitlines():
+            msg += '\n  | %s' % line
+        msg += '\n  +----------------'
+
+    msger.verbose(msg)
+    return rc
+
+def outs(cmdln_or_args):
+    # get the outputs of tools
+    return runtool(cmdln_or_args, catch=1)[1].strip()
+
+def quiet(cmdln_or_args):
+    return runtool(cmdln_or_args, catch=0)[0]
+
index 146a7a9..c2b1345 100644 (file)
@@ -23,7 +23,7 @@ import re
 import tempfile
 
 from mic import configmgr, pluginmgr, chroot, msger
-from mic.utils import misc, fs_related, errors
+from mic.utils import misc, fs_related, errors, runner
 from mic.utils.partitionedfs import PartitionedMount
 
 import mic.imager.raw as raw
@@ -191,7 +191,7 @@ class RawPlugin(ImagerPlugin):
         args = ['dd', "if=%s" % srcloop.partitions[0]['device'], "of=%s" % image]
 
         msger.info("`dd` image ...")
-        rc = msger.run(args)
+        rc = runner.show(args)
         srcloop.cleanup()
         shutil.rmtree(srcmnt, ignore_errors = True)
 
index 0b43d8a..cb091e7 100755 (executable)
--- a/tools/mic
+++ b/tools/mic
@@ -56,6 +56,16 @@ class Mic(cmdln.Cmdln):
 
             msger.set_loglevel('debug')
 
+    def help_create(self):
+        cr = creator.Creator()
+        cr.optparser = cr.get_optparser()
+        doc = cr.__doc__
+        doc = cr._help_reindent(doc)
+        doc = cr._help_preprocess(doc, None)
+        doc = doc.replace(cr.name, "${cmd_name}", 1)
+        doc = doc.rstrip() + '\n'
+        return doc
+
     @cmdln.alias("cr")
     def do_create(self, argv):
         try: