[meego-commits] 11266: Changes to Trunk:Testing/mic2

Yi Yang no_reply at build.meego.com
Fri Dec 24 08:45:57 UTC 2010


Hi,
I have made the following changes to mic2 in project Trunk:Testing. Please review and accept ASAP.

Thank You,
Yi Yang

[This message was auto-generated]

---

Request #11266:

  submit:   devel:tools:building/mic2(r82) -> Trunk:Testing/mic2


Message:
    Update to 0.22.6

State:   new          2010-12-24T00:45:56 yyang
Comment: None



changes files:
--------------
--- mic2.changes
+++ mic2.changes
@@ -0,0 +1,27 @@
+* Tue Dec 21 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.6
+- Update to 0.22.6 (fix disorder patch hunks resulted in)
+
+* Mon Dec 20 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.5
+- Update to 0.22.5 (fix exit issue ks options introduced)
+
+* Fri Dec 17 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.4
+- Update to 0.22.4 (fix exit issue on openSUSE and Ubuntu)
+
+* Wed Dec 15 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.3
+- Update to 0.22.3 with three fixes
+- Fix bug #BMC 10572
+- readin magic line from ks for cmdln options
+- Print mic2 version and fix an error if config isn't provided
+
+* Fri Nov 26 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.2
+- Fix a build error on Ubuntu 10.10
+
+* Fri Oct 29 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.2
+- Update to 0.22.2 (fixed BMC #9088 and #9108)
+
+* Fri Oct 22 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.1
+- Update to 0.22.1
+
+* Thu Sep 30 2010 Yi Yang <yi.y.yang at intel.com> - 0.22.0
+- Update to 0.22.0
+
@@ -3 +29,0 @@
-  * Fix bmc #6063: btrfs compression and btrfs images for handset

old:
----
  mic2-0.21.1.tar.gz

new:
----
  mic2-0.22.6.tar.gz

spec files:
-----------
--- mic2.spec
+++ mic2.spec
@@ -8,7 +8,7 @@
 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
 Name:       mic2
 Summary:    Tools for building images for MeeGo
-Version:    0.21.1
+Version:    0.22.6
 Release:    1
 Group:      System/Base
 License:    GPLv2

dsc files:
----------
--- mic2.dsc
+++ mic2.dsc
@@ -1,7 +1,7 @@
 Format: 1.0
 Source: mic2
 Binary: mic2
-Version: 0.21.1
+Version: 0.22.6
 Maintainer: Yi Yang <yi.y.yang at intel.com>
 Homepage: http://www.meego.com
 Architecture: all

other changes:
--------------

++++++ debian.changelog
--- debian.changelog
+++ debian.changelog
@@ -1,3 +1,38 @@
+mic2 (0.22.6) unstable; urgency=low
+
+  * Release of version (0.22.6)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Tue, 21 Dec 2010 14:54:42 +0800
+mic2 (0.22.5) unstable; urgency=low
+
+  * Release of version (0.22.5)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Mon, 20 Dec 2010 15:12:42 +0800
+mic2 (0.22.4) unstable; urgency=low
+
+  * Release of version (0.22.4)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Fri, 17 Dec 2010 13:56:42 +0800
+mic2 (0.22.3) unstable; urgency=low
+
+  * Release of version (0.22.3)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Wed, 15 Dec 2010 15:03:42 +0800
+mic2 (0.22.2) unstable; urgency=low
+
+  * Release of version (0.22.2)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Fri, 29 Oct 2010 14:26:42 +0800
+mic2 (0.22.1) unstable; urgency=low
+
+  * Release of version (0.22.1)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Fri, 22 Oct 2010 09:31:30 +0800
+mic2 (0.22.0) unstable; urgency=low
+
+  * Release of version (0.22.0)
+
+ -- Yi Yang <yi.y.yang at intel.com>  Thu, 30 Sep 2010 11:55:34 +0800
 mic2 (0.21.1) unstable; urgency=low
 
   * Release of version (0.21.1)

++++++ debian.tar.gz
--- control
+++ control
@@ -8,8 +8,7 @@
 
 Package: mic2
 Architecture: all
-Depends: ${shlibs:Depends},
-         ${misc:Depends},
+Depends: ${misc:Depends},
          ${python:Depends},
          python-pykickstart (>= 0.96),
          python-iniparse,
@@ -27,7 +26,7 @@
          dmsetup,
          python-urlgrabber,
          btrfs-tools,
-         syslinux (>= 2:3.82) [amd64 i386 lpia],
+         syslinux (>= 2:3.82),
          bzip2
 Description: MeeGo Image Creator
     MeeGo Image Creator or MIC2
--- rules
+++ rules
@@ -34,8 +34,6 @@
 	
 
 binary-indep: build install
-
-binary-arch: build install
 	dh_testdir
 	dh_testroot
 	dh_installchangelogs
@@ -53,5 +51,7 @@
 	dh_md5sums
 	dh_builddeb
 
+binary-arch: build install
+
 binary: binary-indep binary-arch
 .PHONY: build clean binary-indep binary-arch binary install

++++++ mic2-0.21.1.tar.gz -> mic2-0.22.6.tar.gz
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,333 @@
+commit 227907be2a612e3b4de4cf8878b9889e650fb022
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Fri Oct 29 14:11:16 2010 +0800
+
+    Fix comps.xml match issue in repomd.xml
+    
+    Note: fix bug #9108, in MeeGo 1.1 repo, comps.xml is named as
+    comps-1.1.xml so that mic2 considers it as questionable repo.
+
+commit 13dce6b4c1073e29e2aec1ed904dbe517e14e337
+Author: Marko Saukko <marko.saukko at gmail.com>
+Date:   Thu Oct 28 17:11:53 2010 +0300
+
+    If self.target_arch is empty then can't do operations to it.
+
+commit 285dbe20d5b98c6f50115f34f17db648ddcb68b4
+Author: Marko Saukko <marko.saukko at gmail.com>
+Date:   Wed Oct 27 10:38:58 2010 +0300
+
+    Lets not hide the error messages. Eventually we should hide the error messages from users, but if this is hidden it makes debugging in problem cases much harder.
+
+commit 02b2735ad11e4ff9b57ad354ea2d86921d109d10
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Fri Oct 22 09:27:23 2010 +0800
+
+    Cut release 0.22.1
+
+commit 7ce4300ad6b8a3eddb1b5629533a7d53196e7a70
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Fri Oct 22 09:17:55 2010 +0800
+
+    Remove qemu emulator in ARM image
+    
+    Note: qemu emulator is just used on creating image and chrooting,
+    it isn't a part of image, so shouldn't keep it there, fix bug #8667
+
+commit b7599b3533031f6b703b811597be31df96d10f2a
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Tue Oct 19 16:43:58 2010 +0800
+
+    Fix exit issue from mic-chroot env
+    
+    Note: mic-chroot ran '/bin/bash --login', this results in all the
+    chroot instances will exit once any one chroot instance exits,
+    it still can meet MeeGo SDK requirements even if --login is removed.
+
+commit b962fc990da08a240e9e714c7cacd0b141c6aec3
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Oct 18 15:52:25 2010 +0800
+
+    Remove compress-force option for btrfs mount
+    
+    Note: btrfs with old version doesn't support mount option compress-force
+
+commit 735cce0cf52846625d96754b5a4b8aeaed7064e3
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Thu Oct 14 17:01:02 2010 +0800
+
+    Make mic-chroot run profile with correct HOME
+
+commit 8a015b7c80a4f50ae18be1008af82af95b624d42
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Thu Oct 14 16:39:47 2010 +0800
+
+    Print local kernel version
+
+commit 46539b124a962d189775f6949bd3e4d894c4761c
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Thu Oct 14 11:29:02 2010 +0800
+
+    Fix an error in case repo baseurl has password protection
+    
+    Note: fix bug #7926
+
+commit 88163e5ff0d56d4889d73a27d9e26e70bb595cb0
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Tue Oct 12 21:38:39 2010 +0800
+
+    Fix a regression found in mic-chroot
+
+commit c8c971207207d0c1ead33ef8a9bc3acdc447e5a5
+Merge: 30a53a0... 3095af2...
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Mon Oct 11 09:44:02 2010 +0800
+
+    Merge branch 'master' of gitorious.org:meego-developer-tools/image-creator
+
+commit 3095af2848707b7e05e63bd4eb113d3415f92138
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Oct 9 15:50:32 2010 +0800
+
+    Fix proxy caching issue using yum config http_caching
+
+commit 30a53a08ea4c4c90a21db9ebeded768b56c0d1ae
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Sat Oct 9 13:47:49 2010 +0800
+
+    mic-image-writer: codes clean up
+
+commit 6e54ddc1a86eca2e4c9d9bc7fc947a3f3846bc42
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Sat Oct 9 13:41:50 2010 +0800
+
+    mic-image-writer: compatible with UDisks. Fix BMC# 6612
+
+commit e451635730a42f3552d672a8e3dad3eac03c6ec0
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Sat Oct 9 13:31:24 2010 +0800
+
+    Constructed a class to substitute the functions about HAL
+
+commit a0edac043ca4c49ca9cd4dff7822883b5e791785
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Oct 9 09:24:55 2010 +0800
+
+    Check corrupt packages
+
+commit e1a276bb9e3be4b3fb862a8613a5ff933ed483f4
+Author: Marko Saukko <marko.saukko at gmail.com>
+Date:   Thu Sep 30 10:52:51 2010 +0300
+
+    Improved the error message when mount failed.
+
+commit ffd7383e9a5327aaa76682143d66f3a544d68fce
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Thu Sep 30 11:38:40 2010 +0800
+
+    Cut release 0.22.0
+
+commit b934cf15fe501eda8d2500439942509bfe56c396
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Thu Sep 30 11:00:16 2010 +0800
+
+    Also add --include-source to tools/mic
+    
+    Note: also fix full path or ~/ log file name issue
+
+commit 582c140f4820ef107ffec2c75338c7736b4a1556
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Wed Sep 29 16:30:58 2010 +0800
+
+    Redirect stdout and stderr to logfile
+    
+    Note: fix bug #7174, you can use --logfile=/your/path/logfile
+    to save the whole log (including stdout and stderr), in the same
+    time, you still can see these log on your screen.
+
+commit 419038e594af65748c14b290db6a29b543a6c518
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Tue Sep 28 09:42:17 2010 +0800
+
+    Fix typo: fiflesystem->filesystem
+
+commit 37982ed0c75ed6d044893492b2c00de95a409bc2
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Sep 27 21:28:48 2010 +0800
+
+    Remove subdir for virtual machine images on creating release
+    
+    Note: for virtual machine images, a subdir is created under
+    outdir, but for release, it has had its own dir, so we don't
+    need it, in addition, this also ensures release output format
+    isn't broken.
+
+commit 80cb2aa92b5a0e301be3f3aa157e315f2f249d3e
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Sep 27 15:14:27 2010 +0800
+
+    Use find_binary_path to get all the bianry file paths
+    
+    Note: fix bug #3742, also fix virtual image creating
+    issue introduced by commit ac8090d3f282acb8bfeda1600bd52a0ac1b7f6cc
+    in bootstrap mode
+
+commit d8cfd5ad0e79f1e6dcda38e020428613bcd39bdb
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Mon Sep 27 08:32:32 2010 +0800
+
+    New feature: build image with source rpm included
+
+commit 46d61238768b288ec930299f87c12271cec096a0
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Sep 25 15:27:11 2010 +0800
+
+    Fix inconsistent indent in mic/imgcreate/misc.py
+
+commit ca2630f8cc65a3b2defa6714eeb8abdb17322b14
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Sep 25 11:30:45 2010 +0800
+
+    Correct boolean constants
+
+commit 0f73438714795d60e8db95d41d0026b7f3ca6b58
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Sep 25 11:11:27 2010 +0800
+
+    close unused file handle
+
+commit a03a6406e0e10895b82a9b9375884d460f498f1f
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Sep 25 10:26:57 2010 +0800
+
+    Check --force-debian option for rpm and correct 'ubuntu'
+    
+    Note: on debian 5.0, rpm hasn't --force-debian option, but
+    on debian 6.0, rpm has --force-debian option, so we must
+    handle this, dist()[0] python platform module gets on Ubuntu is
+    "Ubuntu" instead of "ubuntu"
+
+commit e153c3083953d8416772ac0da22a6a74c7842f76
+Merge: 482d985... ede790d...
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Sat Sep 25 09:56:08 2010 +0800
+
+    Merge commit 'refs/merge-requests/22' of git://gitorious.org/meego-developer-tools/image-creator into integration
+
+commit 482d985b550502f4cf471555b00cd9a37f0811d8
+Author: Anas Nashif <nashif at linux.intel.com>
+Date:   Thu Sep 23 01:48:54 2010 +0100
+
+    always delete old __version__ file before building, otherwise we will keep old version string
+
+commit ede790de26a8a58a2c9755d51c2975e5440358cd
+Author: Fathi Boudra <fabo at debian.org>
+Date:   Wed Sep 22 11:26:43 2010 +0300
+
+    Clean up copy_mic2(): set sane defaults and treat debian/ubuntu as
+    exceptions.
+
+commit fd889593efe73b25f9aca935542dae1f409ca7da
+Author: Fathi Boudra <fabo at debian.org>
+Date:   Wed Sep 22 10:24:42 2010 +0300
+
+    pass --force-debian option on Ubuntu or Debian
+
+commit b3682e61928a3dee6ed6c5abb2c30006cabaeab9
+Author: Fathi Boudra <fabo at debian.org>
+Date:   Tue Sep 21 13:56:12 2010 +0300
+
+    fix typo
+
+commit fe6e442036350718beb8d2d44cde835ca54928d8
+Author: Fathi Boudra <fabo at debian.org>
+Date:   Tue Sep 21 13:47:23 2010 +0300
+
+    Mic2 package from MeeGo repositories is using /usr/share/python-support/mic2
+    path but not the package from Debian repositories (/usr/share/pyshared)
+
+commit 79039cef9454d968e168f3525f369377719745db
+Author: Fathi Boudra <fabo at debian.org>
+Date:   Tue Sep 21 13:36:10 2010 +0300
+
+    Replace is_debian/is_ubuntu function by get_distribution
+    It's using python platform module
+
+commit fba0584dbeb8cec4bfd34935b7a53de9d31e447a
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Tue Sep 21 16:45:06 2010 +0800
+
+    Fix arch error in .xml for ARM raw image
+    
+    Note: fix bug #6896
+
+commit 8d82752070a81bc6db51ba90615fd475003c3f96
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Tue Sep 21 15:18:48 2010 +0800
+
+    Add a missed change for commit 7089f021672b39e113fe8eb2b0e6b0ab3ec4c74c
+
+commit 7089f021672b39e113fe8eb2b0e6b0ab3ec4c74c
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Tue Sep 21 15:04:47 2010 +0800
+
+    Handle --arch=iX86 case
+    
+    Note: fix bug #6866, X can be 3,4,5,6
+
+commit b56fab9e32b2aad4dc3d6485072c6f7d7f55dd33
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Sep 20 16:50:33 2010 +0800
+
+    Use appropriate message dialog for mic-image-writer
+    
+    Note: fix bug #3919
+
+commit c2da8765369d8456b2d32a99a14045e9c4913268
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Sep 20 16:48:15 2010 +0800
+
+    Handle all the special options using a generic way for bootstrap
+
+commit c1d2506cb3ed1689ae1eb69941eebf8bae16c73e
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Sep 20 16:19:43 2010 +0800
+
+    Don't save yum repo settings any more
+    
+    Note: because we use zypper instead of yum, fix bug #6451
+
+commit 6cefbb3b31fa93cc67997c1b60b8f3422ed41db7
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Mon Sep 20 14:49:42 2010 +0800
+
+    Deliver --package option into bootstrap
+
+commit 583203db9c51e1b800537bcf1eeea1bd11ba6194
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Fri Sep 17 16:47:58 2010 +0800
+
+    Use find_binary_path to check depended binaries
+
+commit 75463d00bddb06f0e5c3d786785804fd53256098
+Merge: 55639ef... 282802f...
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Fri Sep 17 16:46:52 2010 +0800
+
+    Merge branch 'master' of git at gitorious.org:meego-developer-tools/image-creator
+
+commit 282802fd79f481f84a16796b8cc6c6ff23b6797d
+Author: Huaxu Wan <huaxu.wan at intel.com>
+Date:   Fri Sep 17 15:36:40 2010 +0800
+
+    MeeGo installer changed from yum to zypper
+
+commit 55639ef2ac683cc2b8db803eeadb2ff06296dd53
+Author: Yi Yang <yi.y.yang at intel.com>
+Date:   Wed Sep 15 16:01:46 2010 +0800
+
+    Cut release 0.21.1
+
 commit 56486642313543d2e423587ee8a7b712e44787b1
 Author: Yi Yang <yi.y.yang at intel.com>
 Date:   Wed Sep 15 15:55:33 2010 +0800
--- Makefile
+++ Makefile
@@ -24,6 +24,7 @@
 all: build
 
 build: mandoc
+	rm -f mic/__version__.*
 	python setup.py build
 
 install: installman installconf installsymlinks
--- VERSION
+++ VERSION
@@ -1 +1 @@
-0.21.1
\ No newline at end of file
+0.22.6
--- doc/mic-chroot.pod
+++ doc/mic-chroot.pod
@@ -32,7 +32,7 @@
 
 B<-c CONVERTTO, --convert-to=CONVERTTO>       Convert it to the specified type live image on exiting, the allowed value is livecd or liveusb
 
-B<--convert-only>                 Just convert an image, this will skip chroot and directly convert an image/fiflesytem with -c option together
+B<--convert-only>                 Just convert an image, this will skip chroot and directly convert an image/filesytem with -c option together
 
 B<-o OUTDIR, --outdir=OUTDIR>     Output directory to use (default: current work dir)
 
--- doc/mic.1
+++ doc/mic.1
@@ -1,4 +1,4 @@
-.TH MIC "1" "Sep 2010" "mic 0.21.0" "User Commands"
+.TH MIC "1" "Dec 2010" "mic 0.22.6" "User Commands"
 .SH NAME
 mic \- MeeGo image command-line tool.
 .SH SYNOPSIS
@@ -35,7 +35,7 @@
                 Output directory to use (default: current work dir)
     \-\-convert\-only
                 Just convert an image, this will skip chroot and
-                directly convert an image/fiflesytem with \-c option
+                directly convert an image/filesytem with \-c option
                 together
     \-e EXECUTE, \-\-execute=EXECUTE
                 Execute the given command within the chroot instead of
@@ -150,6 +150,8 @@
                 vfat, the default is vfat.
     \-i, \-\-interactive
                 Directly write into a USB disk.
+    \-\-include\-source
+                Generate a image with source rpms included
     \-\-compress\-disk\-image=COMPRESS_DISK_IMAGE
                 Compress the disk image that is created. When using
                 \-\-release option default is bz2, otherwise default is
--- mic/appcreate/appliance.py
+++ mic/appcreate/appliance.py
@@ -62,17 +62,12 @@
         #self.getsource = False
         #self.listpkg = False
 
-        self._dep_checks.extend([
-                            ('/usr/sbin/sync', '/sbin/sync', '/bin/sync', '/usr/bin/sync'),
-                            ('/sbin/kpartx',),
-                            ('/sbin/parted', '/usr/sbin/parted'),
-                            ('/sbin/extlinux', '/usr/sbin/extlinux', '/usr/bin/extlinux')
-                           ])
+        self._dep_checks.extend(["sync", "kpartx", "parted", "extlinux"])
 
         if self.__disk_format == "vmdk":
-            self._dep_checks.append(('/usr/bin/qemu-img',))
+            self._dep_checks.append("qemu-img")
         if self.__disk_format == "vdi":
-            self._dep_checks.append(('/usr/bin/VBoxManage',))
+            self._dep_checks.append("VBoxManage")
 
     def configure(self, repodata = None):
         def chroot():
@@ -282,16 +277,12 @@
 
         # Set MBR
         mbrsize = os.stat("%s/usr/share/syslinux/mbr.bin" % self._instroot)[stat.ST_SIZE]
-        rc = subprocess.call(["/bin/dd", "if=%s/usr/share/syslinux/mbr.bin" % self._instroot, "of=" + loopdev])
+        rc = subprocess.call([ddcmd, "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="/usr/sbin/parted"
-        if not os.path.exists(parted):
-            parted="/sbin/parted"
-            if not os.path.exists(parted):
-                raise CreatorError("Missed parted, please install it.")
+        parted = find_binary_path("parted")
         dev_null = os.open("/dev/null", os.O_WRONLY)
         rc = subprocess.call([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"],
                              stdout = dev_null, stderr = dev_null)
@@ -306,13 +297,7 @@
         # Ensure all data is flushed to disk before doing syslinux install
         subprocess.call(["sync"])
 
-        fullpathsyslinux = "/sbin/extlinux"
-        if not os.path.isfile(fullpathsyslinux):
-            fullpathsyslinux = "/usr/sbin/extlinux"
-            if not os.path.isfile(fullpathsyslinux):
-                fullpathsyslinux = "/usr/bin/extlinux"
-                if not os.path.isfile(fullpathsyslinux):
-                    raise CreatorError("Missed extlinux, please install it.")
+        fullpathsyslinux = find_binary_path("extlinux")
         rc = subprocess.call([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot])
         if rc != 0:
             raise MountError("Unable to install syslinux bootloader to %sp)d" % (loopdev, (bootdevnum + 1)))
@@ -358,11 +343,13 @@
             dst = "%s/%s" % (self._outdir, self._img_name)
             logging.debug("converting %s image to %s" % (self.__disks[name].lofile, dst))
             if self.__disk_format != "vdi":
-                rc = subprocess.call(["/usr/bin/qemu-img", "convert",
+                qemu_img = find_binary_path("qemu-img")
+                rc = subprocess.call([qemu_img, "convert",
                                       "-f", "raw", self.__disks[name].lofile,
                                       "-O", self.__disk_format,  dst])
             else:
-                rc = subprocess.call(["/usr/bin/VBoxManage", "convertfromraw",
+                vboxmanage = find_binary_path("VBoxManage")
+                rc = subprocess.call([vboxmanage, "convertfromraw",
                                       self.__disks[name].lofile, dst,
                                       "--format", "VDI"])
             if rc == 0:
@@ -425,6 +412,9 @@
         vmdkcfg.close()
 
     def _write_image_xml(self):
+        imgarch = "i686"
+        if self.target_arch and self.target_arch.startswith("arm"):
+            imgarch = "arm"
         xml = "<image>\n"
 
         name_attributes = ""
@@ -438,7 +428,7 @@
         # baremetal vs xen
         xml += "    <boot type='hvm'>\n"
         xml += "      <guest>\n"
-        xml += "        <arch>%s</arch>\n" % os.uname()[4]
+        xml += "        <arch>%s</arch>\n" % imgarch
         xml += "      </guest>\n"
         xml += "      <os>\n"
         xml += "        <loader dev='hd'/>\n"
--- mic/appcreate/nand.py
+++ mic/appcreate/nand.py
@@ -143,7 +143,7 @@
         if self.__kernel_url or \
            self.__initrd_url or \
            self.__kernel_rpm_url:
-            self._dep_checks.append(('/usr/bin/curl', '/bin/curl'))
+            self._dep_checks.append("curl")
 
     #
     # Private helper functions
--- mic/appcreate/partitionedfs.py
+++ mic/appcreate/partitionedfs.py
@@ -45,9 +45,9 @@
         self.mapped = False
         self.mountOrder = []
         self.unmountOrder = []
-        self.parted="/usr/sbin/parted"
-        if not os.path.exists(self.parted):
-            self.parted="/sbin/parted"
+        self.parted=find_binary_path("parted")
+        self.kpartx=find_binary_path("kpartx")
+        self.mkswap=find_binary_path("mkswap")
         self.skipformat = skipformat
 
     def add_partition(self, size, disk, mountpoint, fstype = None, boot = False):
@@ -142,7 +142,7 @@
                 continue
 
             logging.debug("Running kpartx on %s" % d['disk'].device )
-            kpartx = subprocess.Popen(["/sbin/kpartx", "-l", "-v", d['disk'].device],
+            kpartx = subprocess.Popen([self.kpartx, "-l", "-v", d['disk'].device],
                                       stdout=subprocess.PIPE, stderr=dev_null)
 
             kpartxOutput = kpartx.communicate()[0].strip().split("\n")
@@ -150,7 +150,7 @@
             if kpartx.returncode:
                 os.close(dev_null)
                 raise MountError("Failed to query partition mapping for '%s'" %
-                                 d.device)
+                                 d['disk'].device)
 
             # Strip trailing blank and mask verbose output
             i = 0
@@ -185,7 +185,7 @@
                 os.symlink(mapperdev, loopdev)
 
             logging.debug("Adding partx mapping for %s" % d['disk'].device)
-            rc = subprocess.call(["/sbin/kpartx","-v", "-a", d['disk'].device],
+            rc = subprocess.call([self.kpartx, "-v", "-a", d['disk'].device],
                                  stdout=dev_null, stderr=dev_null)
             if rc != 0:
                 os.close(dev_null)
@@ -209,7 +209,7 @@
                     self.partitions[pnum]['device'] = None
 
             logging.debug("Unmapping %s" % d['disk'].device)
-            rc = subprocess.call(["/sbin/kpartx", "-d", d['disk'].device],
+            rc = subprocess.call([self.kpartx, "-d", d['disk'].device],
                                  stdout=dev_null, stderr=dev_null)
             if rc != 0:
                 os.close(dev_null)
@@ -274,7 +274,7 @@
                     break
 
             if mp == 'swap':
-                subprocess.call(["/sbin/mkswap", p['device']])
+                subprocess.call([self.mkswap, p['device']])
                 continue
 
             rmmountdir = False
--- mic/chroot/chroot.py
+++ mic/chroot/chroot.py
@@ -33,6 +33,7 @@
 import mic.appcreate as appcreate
 import mic.imgcreate as imgcreate
 import mic.imgconvert as imgconvert
+from mic.imgcreate.fs import *
 
 def perror(msg):
     print >> sys.stderr, "Error: %s" % msg
@@ -156,9 +157,9 @@
     dev_null = os.open("/dev/null", os.O_WRONLY)
     for point in checkpoints:
         print point
-        args = [ "/bin/umount", "-l", chrootdir + point ]
+        args = [ umountcmd, "-l", chrootdir + point ]
         subprocess.call(args, stdout=dev_null, stderr=dev_null)
-    args = [ "/bin/cat", "/proc/mounts" ]
+    args = [ catcmd, "/proc/mounts" ]
     proc_mounts = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
     outputs = proc_mounts.communicate()[0].strip().split("\n")
     for line in outputs:
@@ -167,7 +168,7 @@
                 continue
             point = line.split()[1]
             print point
-            args = [ "/bin/umount", "-l", point ]
+            args = [ umountcmd, "-l", point ]
             ret = subprocess.call(args, stdout=dev_null, stderr=dev_null)
             if ret != 0:
                 print "ERROR: failed to unmount %s" % point
@@ -327,8 +328,9 @@
         os.chdir("/")
 
     """ Register statically-linked qemu-arm if it is an ARM fs """
+    qemu_emulator = None
     dev_null = os.open("/dev/null", os.O_WRONLY)
-    file = subprocess.Popen(["/usr/bin/file", chrootdir + "/sbin/init"], stdout=subprocess.PIPE, stderr=dev_null)
+    file = subprocess.Popen([filecmd, chrootdir + "/sbin/init"], stdout=subprocess.PIPE, stderr=dev_null)
     fileOutput = file.communicate()[0].strip().split("\n")
     os.close(dev_null)
     if file.returncode:
@@ -343,7 +345,7 @@
         i = i + 1
 
     if need_qemu:
-       imgcreate.setup_qemu_emulator(chrootdir, "arm") 
+       qemu_emulator = imgcreate.setup_qemu_emulator(chrootdir, "arm") 
 
     try:
         print "Launching shell. Exit to continue."
@@ -352,5 +354,7 @@
         args = shlex.split(execute)
         subprocess.call(args, preexec_fn = mychroot)
         cleanup_chrootenv(chrootdir, bindmounts, globalmounts)
+        if qemu_emulator:
+            os.unlink(chrootdir + qemu_emulator)
     except OSError, (err, msg):
         raise imgcreate.CreatorError("Failed to chroot: %s" % msg)
--- mic/imgcreate/bootstrap.py
+++ mic/imgcreate/bootstrap.py
@@ -291,25 +291,30 @@
             break
     fd.close()
     return found
-    
-def is_ubuntu():
-    found = find_key_in_file("Ubuntu", "/etc/issue")
-    if found:
-        return found
-
-    for release in glob.glob("/etc/*-release"):
-        found = find_key_in_file("Ubuntu", release)
-        if found:
-            break
 
-    return found
+def get_distribution():
+    import platform
+    try:
+        # Python 2.6
+        dist = platform.linux_distribution()[0]
+    except AttributeError:
+        dist = platform.dist()[0]
 
-def is_debian():
-    return find_key_in_file("Debian", "/etc/issue")
+    return dist
+
+def rpm_has_force_debian_option():
+    rpm = find_binary_path("rpm")
+    dev_null = os.open("/dev/null", os.O_WRONLY)
+    argv = [rpm, "--force-debian"]
+    ret = subprocess.call(argv, stdout = dev_null, stderr = dev_null)
+    os.close(dev_null)
+    if ret != 0:
+        return False
+    return True
 
 def install_rpm(pkgpath, pkgname, rootpath, force = False):
     rpm = find_binary_path("rpm")
-    
+
     rootpath = os.path.abspath(os.path.expanduser(rootpath))
     print "Installing %s..." % pkgname
     dev_null = os.open("/dev/null", os.O_WRONLY)
@@ -317,8 +322,10 @@
         argv = [rpm, "-i", "--ignorearch", "--ignoreos", "--nodigest", "--nosignature", "--root=" + rootpath, pkgpath]
         if force:
             argv.extend(["--force", "--nodeps"])
-        if is_ubuntu():
-            argv.append("--force-debian")
+        dist = get_distribution()
+        if dist == "Ubuntu" or dist == "debian":
+            if rpm_has_force_debian_option():
+                argv.append("--force-debian")
         subprocess.call(argv, stdout = dev_null, stderr = dev_null)
     finally:
         os.close(dev_null)
@@ -373,7 +380,7 @@
     for pkg in pkglist:
         download_and_install(pkg, True)
 
-    pkglist = ["glibc", "passwd", "pam-modules-cracklib", "meego-release", "moblin-release", "fastinit", "nss", "genisoimage", "bzip2", "gzip", "cpio", "perl", "syslinux-extlinux", "btrfs-progs", "make", "mic2"]
+    pkglist = ["glibc", "passwd", "pam-modules-cracklib", "meego-release", "moblin-release", "fastinit", "nss", "genisoimage", "bzip2", "gzip", "cpio", "perl", "syslinux-extlinux", "btrfs-progs", "make", "file", "psmisc", "mic2"]
     pkglist.extend(["isomd5sum", "wget"])
     for pkg in pkglist:
         for node in get_my_all_deps_in_order(pkg, con):
@@ -409,7 +416,7 @@
     f = open(repomd, "r")
     content = f.read()
     f.close()
-    m = re.match(".*href=\"(.*?comps.xml.*?)\"", content, re.M | re.S)
+    m = re.match(".*href=\"(.*?comps.*?\.xml.*?)\"", content, re.M | re.S)
     if not m:
         return False
     sqlitedb = "%s/%s/.tmp.primary.sqlite" % (cachedir, reponame)
@@ -424,11 +431,9 @@
 
 def check_depends(imgfmt):
     if imgfmt == "vmdk":
-        if not os.path.exists('/usr/bin/qemu-img'):
-            raise CreatorError("Needed file: /usr/bin/qemu-img not found, please check your installation.")
+        find_binary_path("qemu-img")
     if imgfmt == "vdi":
-        if not os.path.exists('/usr/bin/VBoxManage'):
-            raise CreatorError("Needed file: /usr/bin/VBoxManage not found, please check your installation..")
+        find_binary_path("VBoxManage")
 
 def save_imginfo(outimage, infofile):
     print "Saving image info..."
@@ -507,11 +512,13 @@
     outimage.append(dst)
     print "converting %s image to %s" % (imgfile, dst)
     if imgfmt == "vmdk":
-        rc = subprocess.call(["/usr/bin/qemu-img", "convert",
+        qemu_img = find_binary_path("qemu-img")
+        rc = subprocess.call([qemu_img, "convert",
                                       "-f", "raw", imgfile,
                                       "-O", imgfmt, dst])
     elif imgfmt == "vdi":
-        rc = subprocess.call(["/usr/bin/VBoxManage", "convertfromraw",
+        vboxmanage = find_binary_path("VBoxManage")
+        rc = subprocess.call([vboxmanage, "convertfromraw",
                                       imgfile, dst,
                                       "--format", "VDI"])
                 
@@ -574,7 +581,7 @@
 def copy_mic2(bootstrap, bin_path = "/usr/bin", python_lib_path = "/usr/lib/python2.6/site-packages"):
         bootstrap_mic = bootstrap + "/usr/lib/python2.6/site-packages/mic"
         shutil.rmtree(bootstrap_mic, ignore_errors = True)
-        subprocess.call(["/bin/cp", "-af", python_lib_path + "/mic", os.path.dirname(bootstrap_mic)])
+        subprocess.call([copycmd, "-af", python_lib_path + "/mic", os.path.dirname(bootstrap_mic)])
         clean_files(".*\.py[co]$", bootstrap_mic)
         for file in glob.glob(bootstrap + "/usr/bin/mic-*"):
             os.unlink(file)
@@ -592,11 +599,10 @@
 def check_mic(bootstrap):
     import distutils.sysconfig
     pythonlib = distutils.sysconfig.get_python_lib()
-    if os.path.exists(pythonlib + "/mic/imgcreate/creator.py"):
-        copy_mic2(bootstrap, bin_path = "/usr/bin", python_lib_path = pythonlib)
-    else:
-        pythonlib = None
-        if is_ubuntu():
+    bin_path = "/usr/bin"
+    if not os.path.exists(pythonlib + "/mic/imgcreate/creator.py"):
+        dist = get_distribution()
+        if dist == 'Ubuntu':
             dev_null = os.open("/dev/null", os.O_WRONLY)
             proc = subprocess.Popen(["/usr/bin/pycentral", "pycentraldir", "mic2"], 
                                     stdout = subprocess.PIPE, stderr = dev_null)
@@ -607,8 +613,9 @@
             pycentraldir = output.split()[0]
             pythonlib = pycentraldir
             bin_path = "/usr/local/bin"
-        elif is_debian():
-            pythonlib = "/usr/share/python-support/mic2"
-            bin_path = "/usr/bin"
-        if pythonlib:
-            copy_mic2(bootstrap, bin_path = bin_path, python_lib_path = pythonlib)
+        elif dist == 'debian':
+            if os.path.exists("/usr/share/python-support/mic2"):
+                pythonlib = "/usr/share/python-support/mic2"
+            elif os.path.exists("/usr/share/pyshared"):
+                pythonlib = "/usr/share/pyshared"
+    copy_mic2(bootstrap, bin_path = bin_path, python_lib_path = pythonlib)
--- mic/imgcreate/creator.py
+++ mic/imgcreate/creator.py
@@ -38,6 +38,7 @@
 from mic.imgcreate.misc import *
 from mic.imgcreate.yuminst import *
 from mic.imgcreate import kickstart
+from mic.imgcreate.srcdownload import SrcDownload
 
 FSLABEL_MAXLEN = 32
 """The maximum string length supported for LoopImageCreator.fslabel."""
@@ -65,7 +66,7 @@
 
         name -- a name for the image; used for e.g. image filenames or
                 filesystem labels
-                
+
         """
         self.ks = ks
         """A pykickstart.KickstartParser instance."""
@@ -97,16 +98,12 @@
         self.__img_compression_method = None
 
         # dependent commands to check
-        self._dep_checks = [('/bin/ls',),
-                            ('/bin/bash',),
-                            ('/bin/cp',),
-                            ('/bin/echo',),
-                            ('/sbin/modprobe',),
-                            ('/usr/bin/passwd',)
-                           ]
+        self._dep_checks = ["ls", "bash", "cp", "echo", "modprobe", "passwd"]
 
         self._recording_pkgs = None
 
+        self._include_src = None
+
         self._local_pkgs_path = None
 
         # available size in root fs, init to 0
@@ -118,12 +115,18 @@
         """ Name of the disk image file that is created. """
         self._img_name = None
 
+        """ Image format """
+        self.image_format = None
+
+        """ Save qemu emulator file name in order to clean up it finally """
+        self.qemu_emulator = None
+
         """ No ks provided when called by convertor, so skip the dependency check """
         if self.ks:
             """ If we have btrfs partition we need to check that we have toosl for those """
             for part in self.ks.handler.partition.partitions:
                 if part.fstype and part.fstype == "btrfs":
-                    self._dep_checks.append(("/sbin/mkfs.btrfs",))
+                    self._dep_checks.append("mkfs.btrfs")
                     break
 
     def set_target_arch(self, arch):
@@ -132,14 +135,14 @@
         self.target_arch = arch
         if self.target_arch.startswith("arm"):
             for dep in self._dep_checks:
-                if "/sbin/extlinux" in dep:
+                if dep == "extlinux":
                     self._dep_checks.remove(dep)
-        
+
             if not os.path.exists("/usr/bin/qemu-arm") or not is_statically_linked("/usr/bin/qemu-arm"):
-                self._dep_checks.append(("/usr/bin/qemu-arm-static",))
+                self._dep_checks.append("qemu-arm-static")
 
         return True
-        
+
 
     def __del__(self):
         self.cleanup()
@@ -237,6 +240,9 @@
         """
         shutil.move(self._instroot, self._outdir + "/" + self.name)
 
+    def get_installed_packages(self):
+        return self._pkgs_content.keys()
+
     def _save_recording_pkgs(self, destdir):
         """Save the list or content of installed packages to file.
         """
@@ -310,7 +316,7 @@
             rpm_name = os.path.basename(rpm_path)
             package_name = rpmUtils.miscutils.splitFilename(rpm_name)[0]
             excluded_packages += [package_name]
-        return excluded_packages	
+        return excluded_packages
 
     def _get_local_packages(self):
         """Return a list of rpm path to be local installed.
@@ -609,9 +615,9 @@
         for d in ("/dev/pts", "/etc", "/boot", "/var/log", "/var/cache/yum", "/sys", "/proc", "/usr/bin"):
             makedirs(self._instroot + d)
 
-        if self.target_arch:
-            setup_qemu_emulator(self._instroot, self.target_arch)
-        
+        if self.target_arch and self.target_arch.startswith("arm"):
+            self.qemu_emulator = setup_qemu_emulator(self._instroot, self.target_arch)
+
         self.get_cachedir(cachedir)
 
         # bind mount system directories into _instroot
@@ -644,6 +650,8 @@
         """
         try:
             os.unlink(self._instroot + "/etc/mtab")
+            if self.qemu_emulator:
+                os.unlink(self._instroot + self.qemu_emulator)
         except OSError:
             pass
 
@@ -762,7 +770,13 @@
 
         yum_conf = self._mktemp(prefix = "yum.conf-")
 
-        ayum = LiveCDYum(self._recording_pkgs, target_arch = self.target_arch)
+        keep_record = None
+        if self._include_src:
+            keep_record = 'include_src'
+        if self._recording_pkgs in ('name', 'contents'):
+            keep_record = self._recording_pkgs
+
+        ayum = LiveCDYum(keep_record, target_arch = self.target_arch)
         ayum.setup(yum_conf, self._instroot)
 
         for repo in kickstart.get_repos(self.ks, repo_urls):
@@ -799,8 +813,9 @@
             except yum.Errors.YumBaseError, e:
                 raise CreatorError("Unable to install: %s" % (e,))
         finally:
-            if self._recording_pkgs:
+            if keep_record:
                 self._pkgs_content = ayum.getAllContent()
+
             ayum.closeRpmDB()
             ayum.close()
             os.unlink(yum_conf)
@@ -839,7 +854,7 @@
             try:
                 try:
                     subprocess.call([s.interp, script],
-                                    preexec_fn = preexec, env = env)
+                                    preexec_fn = preexec, env = env, stdout = sys.stdout, stderr = sys.stderr)
                 except OSError, (err, msg):
                     raise CreatorError("Failed to execute %%post script "
                                        "with '%s' : %s" % (s.interp, msg))
@@ -882,11 +897,12 @@
             kickstart.RPMMacroConfig(self._instroot).apply(self.ks)
             kickstart.DesktopConfig(self._instroot).apply(ksh.desktop)
             self.__save_repo_keys(repodata)
-            kickstart.MoblinRepoConfig(self._instroot).apply(ksh.repo, repodata)        
+            kickstart.MoblinRepoConfig(self._instroot).apply(ksh.repo, repodata)
         except:
-            raise CreatorError("Failed to apply configuration to image")
+            print "Failed to apply configuration to image"
+            raise
 
-        if not self.target_arch:
+        if not self.target_arch or not self.target_arch.startswith("arm"):
             self._create_bootconfig()
 
         self.__run_post_scripts()
@@ -955,6 +971,15 @@
         if self._recording_pkgs:
             self._save_recording_pkgs(destdir)
 
+        """ For image formats with two or multiple image files, it will be better to put them under a directory """
+        if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"):
+            destdir = os.path.join(destdir, "%s-%s" % (self.name, self.image_format))
+            logging.debug("creating destination dir: %s" % destdir)
+            makedirs(destdir)
+
+        # Ensure all data is flushed to _outdir
+        subprocess.call([synccmd])
+
         for f in os.listdir(self._outdir):
             shutil.move(os.path.join(self._outdir, f),
                         os.path.join(destdir, f))
@@ -983,8 +1008,7 @@
 
     def check_depend_tools(self):
         for tool in self._dep_checks:
-            if tool and not any(map(os.path.exists, tool)):
-                raise CreatorError("Needed file: %s not found, please check your installation" % tool[0])
+            find_binary_path(tool)
 
     def package_output(self, image_format, destdir = ".", package="none"):
         if not package or package == "none":
@@ -1002,15 +1026,15 @@
                 dst = "%s/%s-%s.tar" % (destdir, self.name, image_format)
             print "creating %s" % dst
             tar = tarfile.open(dst, "w:" + comp)
-            
-            for file in self.outimage:             
+
+            for file in self.outimage:
                 print "adding %s to %s" % (file, dst)
                 tar.add(file, arcname=os.path.join("%s-%s" % (self.name, image_format), os.path.basename(file)))
                 if os.path.isdir(file):
                     shutil.rmtree(file, ignore_errors = True)
                 else:
                     os.remove(file)
-                    
+
 
             tar.close()
 
@@ -1033,10 +1057,10 @@
         With this you can set the method that is used to compress the disk
         image after it is created.
         """
-        
+
         if compression_method not in ('bz2'):
             raise CreatorError("Given disk image compression method ('%s') is not valid." % (compression_method))
-        
+
         self.__img_compression_method = compression_method
 
 class LoopImageCreator(ImageCreator):
@@ -1077,7 +1101,7 @@
                                                          4096L * 1024 * 1024)
         else:
             self.__image_size = 0
-            
+
         self._img_name = self.name + ".img"
 
     def _set_fstype(self, fstype):
@@ -1224,7 +1248,7 @@
     def _stage_final_image(self):
         self._resparse()
         shutil.move(self._image, self._outdir + "/" + self._img_name)
-        
+
 
 
 class FsImageCreator(ImageCreator):
@@ -1242,7 +1266,7 @@
         print "Moving %s to %s, please be patient to wait (it is slow if they are on different file systems/partitons/disks)" \
                % (self._instroot, destdir + "/" + self.name)
 
-        args = [ "/bin/cp", "-af", self._instroot + "/dev", os.path.dirname(self._instroot) ]
+        args = [ copycmd, "-af", self._instroot + "/dev", os.path.dirname(self._instroot) ]
         subprocess.call(args)
         shutil.rmtree(self._instroot + "/dev", ignore_errors = True)
 
@@ -1253,6 +1277,6 @@
             if os.path.exists(destdir + "/" + self.name + exclude):
                 os.unlink(destdir + "/" + self.name + exclude)
 
-        args = [ "/bin/cp", "-af", os.path.dirname(self._instroot) + "/dev", destdir + "/" + self.name ]
+        args = [ copycmd, "-af", os.path.dirname(self._instroot) + "/dev", destdir + "/" + self.name ]
         subprocess.call(args)
         self.outimage.append(destdir + "/" + self.name)
--- mic/imgcreate/debug.py
+++ mic/imgcreate/debug.py
@@ -21,14 +21,98 @@
 import logging.handlers
 import optparse
 import sys
+import Queue
+import threading
+import time
+import os
+
+real_stdout = sys.stdout
+real_stderr = sys.stderr
+write_log_worker_thread = None
+
+class Worker:
+    def __init__(self, queue, out):
+        self.queue = queue
+        self.out = out
+        self.stopevent = threading.Event()
+        self.stopevent.clear()
+        self.worker_thread = None
+
+    def consumer_queue(self):
+       while True:
+           try:
+               message = self.queue.get_nowait()
+           except Queue.Empty:
+               break 
+           self.queue.task_done()
+           for out in self.out:
+               out.write(message)
+       for out in self.out:
+           out.flush()
+
+    def write_log_worker(self):
+        while True:
+            if self.stopevent.isSet():
+                self.consumer_queue()
+                break
+            self.consumer_queue()
+            time.sleep(1)
+
+    def start_write_log_worker(self, *args, **kwargs):
+        self.worker_thread = threading.Thread(target=self.write_log_worker,
+                                  args=args, kwargs=kwargs,
+                                  name="mic2-worker")
+        self.worker_thread.setDaemon(False)
+        self.worker_thread.start()
+        return self.worker_thread
+
+    def terminate_write_log_worker(self):
+        self.stopevent.set()
+        self.worker_thread.join()
+        self.consumer_queue()
+        for out in self.out:
+            if not out.isatty():
+                out.close()
+
+    def flush_log(self):
+        self.consumer_queue()
+
+class QueueWriter():
+    def __init__(self, queue):
+        self.queue = queue
+        self.myfileno = 1
+        self.mylogworker = None
+
+    def write(self, string):
+        self.queue.put(string)
+
+    def close(self):
+        pass
+
+    def flush(self):
+        if self.mylogworker:
+            self.mylogworker.flush_log()
 
+    def isatty(self):
+        return False
+
+    def fileno(self):
+        return self.myfileno
+
+_logworker = None
+_logfile = None
 
 def handle_logging(option, opt, val, parser, logger, level):
     if level < logger.level:
         logger.setLevel(level)
 
 def handle_logfile(option, opt, val, parser, logger, stream):
+    global _logworker, _logfile
+    if _logworker and _logfile:
+        """ Only need to initialize it once """
+        return
     try:
+        val = os.path.abspath(os.path.expanduser(val))
         logfile = logging.FileHandler(val,"a")
     except IOError, (err, msg):
         raise optparse.OptionValueError("Cannot open file '%s' : %s" %
@@ -37,6 +121,21 @@
 
     logger.removeHandler(stream)
     logger.addHandler(logfile)
+    myout = QueueWriter(Queue.Queue())
+    myout.myfileno = logfile.stream.fileno()
+    sys.stdout = myout
+    sys.stderr = myout
+    _logworker = Worker(myout.queue, [logfile.stream, real_stdout])
+    _logworker.start_write_log_worker()
+    _logfile = val
+    myout.mylogworker = _logworker
+
+def get_logfile():
+    return _logfile
+
+def terminate_log_thread():
+    if _logworker:
+        _logworker.terminate_write_log_worker()
 
 def setup_logging(parser = None):
     """Set up the root logger and add logging options.
--- mic/imgcreate/fs.py
+++ mic/imgcreate/fs.py
@@ -85,9 +85,20 @@
             return bin_path
     raise CreatorError("Command '%s' is not available." % binary)
 
+
+""" Get often-used bianry paths here """
 bunzip2 = find_binary_path('bunzip2')
 gunzip = find_binary_path('gunzip')
 bzip2 = find_binary_path('bzip2')
+copycmd = find_binary_path("cp")
+ddcmd = find_binary_path("dd")
+mountcmd = find_binary_path("mount")
+umountcmd = find_binary_path("umount")
+filecmd = find_binary_path("file")
+catcmd = find_binary_path("cat")
+synccmd = find_binary_path("sync")
+losetupcmd = find_binary_path("losetup")
+modprobecmd = find_binary_path("modprobe")
 
 def makedirs(dirname):
     """A version of os.makedirs() that doesn't throw an
@@ -100,11 +111,7 @@
             raise
 
 def mksquashfs(in_img, out_img):
-    fullpathmksquashfs = "/sbin/mksquashfs"
-    if not os.path.isfile(fullpathmksquashfs):
-        fullpathmksquashfs = "/usr/bin/mksquashfs"
-        if not os.path.isfile(fullpathmksquashfs):
-            raise SquashfsError("Please install squashfs-tools")
+    fullpathmksquashfs = find_binary_path("mksquashfs")
     args = [fullpathmksquashfs, in_img, out_img]
 
     if not sys.stdout.isatty():
@@ -118,16 +125,15 @@
 def resize2fs(fs, size):
     dev_null = os.open("/dev/null", os.O_WRONLY)
     try:
-        return subprocess.call(["/sbin/resize2fs", fs, "%sK" % (size / 1024,)],
+        resize2fs = find_binary_path("resize2fs")
+        return subprocess.call([resize2fs, fs, "%sK" % (size / 1024,)],
                                stdout = dev_null, stderr = dev_null)
     finally:
         os.close(dev_null)
 
 def my_fuser(file):
     ret = False
-    fuser = "/sbin/fuser"
-    if not os.path.exists(fuser):
-        fuser = "/bin/fuser"
+    fuser = find_binary_path("fuser")
     if not os.path.exists(file):
         return ret
     dev_null = os.open("/dev/null", os.O_WRONLY)
@@ -161,7 +167,7 @@
     def ismounted(self):
         ret = False
         dev_null = os.open("/dev/null", os.O_WRONLY)
-        args = [ "/bin/cat", "/proc/mounts" ]
+        args = [ catcmd, "/proc/mounts" ]
         proc_mounts = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
         outputs = proc_mounts.communicate()[0].strip().split("\n")
         for line in outputs:
@@ -180,12 +186,12 @@
             return
 
         makedirs(self.dest)
-        rc = subprocess.call(["/bin/mount", "--bind", self.src, self.dest])
+        rc = subprocess.call([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 = subprocess.call(["/bin/mount", "-o", "remount,%s" % self.option, self.dest])
+            rc = subprocess.call([mountcmd, "-o", "remount,%s" % self.option, self.dest])
             if rc != 0:
                 raise MountError("Bind-remounting '%s' failed" % self.dest)
         self.mounted = True
@@ -195,7 +201,7 @@
             return
 
         if self.ismounted():
-            subprocess.call(["/bin/umount", "-l", self.dest])
+            subprocess.call([umountcmd, "-l", self.dest])
         self.mounted = False
 
 class LoopbackMount:
@@ -212,7 +218,7 @@
 
     def lounsetup(self):
         if self.losetup:
-            rc = subprocess.call(["/sbin/losetup", "-d", self.loopdev])
+            rc = subprocess.call([losetupcmd, "-d", self.loopdev])
             self.losetup = False
             self.loopdev = None
 
@@ -220,7 +226,7 @@
         if self.losetup:
             return
 
-        losetupProc = subprocess.Popen(["/sbin/losetup", "-f"],
+        losetupProc = subprocess.Popen([losetupcmd, "-f"],
                                        stdout=subprocess.PIPE)
         losetupOutput = losetupProc.communicate()[0]
 
@@ -230,7 +236,7 @@
 
         self.loopdev = losetupOutput.split()[0]
 
-        rc = subprocess.call(["/sbin/losetup", self.loopdev, self.lofile])
+        rc = subprocess.call([losetupcmd, self.loopdev, self.lofile])
         if rc != 0:
             raise MountError("Failed to allocate loop device for '%s'" %
                              self.lofile)
@@ -341,7 +347,7 @@
         if self.device is not None:
             return
 
-        losetupProc = subprocess.Popen(["/sbin/losetup", "-f"],
+        losetupProc = subprocess.Popen([losetupcmd, "-f"],
                                        stdout=subprocess.PIPE)
         losetupOutput = losetupProc.communicate()[0]
 
@@ -352,7 +358,7 @@
         device = losetupOutput.split()[0]
 
         logging.debug("Losetup add %s mapping to %s"  % (device, self.lofile))
-        rc = subprocess.call(["/sbin/losetup", device, self.lofile])
+        rc = subprocess.call([losetupcmd, device, self.lofile])
         if rc != 0:
             raise MountError("Failed to allocate loop device for '%s'" %
                              self.lofile)
@@ -362,7 +368,7 @@
         if self.device is None:
             return
         logging.debug("Losetup remove %s" % self.device)
-        rc = subprocess.call(["/sbin/losetup", "-d", self.device])
+        rc = subprocess.call([losetupcmd, "-d", self.device])
         self.device = None
 
 
@@ -430,6 +436,10 @@
 
         self.mounted = False
         self.rmdir   = False
+        if fstype:
+            self.mkfscmd = find_binary_path("mkfs." + self.fstype)
+        else:
+            self.mkfscmd = None
 
     def cleanup(self):
         Mount.cleanup(self)
@@ -438,8 +448,8 @@
     def unmount(self):
         if self.mounted:
             logging.debug("Unmounting directory %s" % self.mountdir)
-            subprocess.call(["/bin/sync"]) # sync the data on this mount point
-            rc = subprocess.call(["/bin/umount", "-l", self.mountdir])
+            subprocess.call([synccmd]) # sync the data on this mount point
+            rc = subprocess.call([umountcmd, "-l", self.mountdir])
             if rc == 0:
                 self.mounted = False
             else:
@@ -469,16 +479,16 @@
 
         logging.debug("Mounting %s at %s" % (self.disk.device, self.mountdir))
         if options:
-            args = [ "/bin/mount", "-o", options, self.disk.device, self.mountdir ]
+            args = [ mountcmd, "-o", options, self.disk.device, self.mountdir ]
         else:
-            args = [ "/bin/mount", self.disk.device, self.mountdir ]
+            args = [ mountcmd, self.disk.device, self.mountdir ]
         if self.fstype:
             args.extend(["-t", self.fstype])
 
         rc = subprocess.call(args)
         if rc != 0:
-            raise MountError("Failed to mount '%s' to '%s'" %
-                             (self.disk.device, self.mountdir))
+            raise MountError("Failed to mount '%s' to '%s' with command '%s'. Retval: %s" %
+                             (self.disk.device, self.mountdir, " ".join(args), rc))
 
         self.mounted = True
 
@@ -490,6 +500,8 @@
         self.fslabel = fslabel.replace("/", "")
         self.uuid  = None
         self.skipformat = skipformat
+        self.dumpe2fs = find_binary_path("dumpe2fs")
+        self.tune2fs = find_binary_path("tune2fs")
 
     def __parse_field(self, output, field):
         for line in output.split("\n"):
@@ -503,7 +515,7 @@
             logging.debug("Skip filesystem format.")
             return
         logging.debug("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        rc = subprocess.call(["/sbin/mkfs." + self.fstype,
+        rc = subprocess.call([self.mkfscmd,
                               "-F", "-L", self.fslabel,
                               "-m", "1", "-b", str(self.blocksize),
                               self.disk.device])
@@ -513,7 +525,7 @@
 
         dev_null = os.open("/dev/null", os.O_WRONLY)
         try:
-            out = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.disk.device],
+            out = subprocess.Popen([self.dumpe2fs, '-h', self.disk.device],
                                    stdout = subprocess.PIPE,
                                    stderr = dev_null).communicate()[0]
         finally:
@@ -521,7 +533,7 @@
 
         self.uuid = self.__parse_field(out, "Filesystem UUID")
         logging.debug("Tuning filesystem on %s" % self.disk.device)
-        subprocess.call(["/sbin/tune2fs", "-c0", "-i0", "-Odir_index",
+        subprocess.call([self.tune2fs, "-c0", "-i0", "-Odir_index",
                          "-ouser_xattr,acl", self.disk.device])
 
     def __resize_filesystem(self, size = None):
@@ -564,7 +576,7 @@
     def __get_size_from_filesystem(self):
         dev_null = os.open("/dev/null", os.O_WRONLY)
         try:
-            out = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.disk.lofile],
+            out = subprocess.Popen([self.dumpe2fs, '-h', self.disk.lofile],
                                    stdout = subprocess.PIPE,
                                    stderr = dev_null).communicate()[0]
         finally:
@@ -605,16 +617,14 @@
         self.fslabel = fslabel.replace("/", "")
         self.uuid = "%08X" % int(time.time())
         self.skipformat = skipformat
+        self.fsckcmd = find_binary_path("fsck." + self.fstype)
 
     def __format_filesystem(self):
         if self.skipformat:
             logging.debug("Skip filesystem format.")
             return
         logging.debug("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        blah = ["/sbin/mkfs." + self.fstype,
-                              "-n", self.fslabel,
-                              "-i", self.uuid,
-                              self.disk.device]
+        blah = [self.mkfscmd, "-n", self.fslabel, "-i", self.uuid, self.disk.device]
         rc = subprocess.call(blah)
         if rc != 0:
             raise MountError("Error creating %s filesystem" % (self.fstype,))
@@ -655,7 +665,7 @@
 
     def __fsck(self):
         logging.debug("Checking filesystem %s" % self.disk.lofile)
-        subprocess.call(["/sbin/fsck." + self.fstype, "-y", self.disk.lofile])
+        subprocess.call([self.fsckcmd, "-y", self.disk.lofile])
 
     def __get_size_from_filesystem(self):
         return self.disk.size
@@ -687,6 +697,8 @@
         self.fslabel = fslabel.replace("/", "")
         self.uuid  = None
         self.skipformat = skipformat
+        self.blkidcmd = find_binary_path("blkid")
+        self.btrfsckcmd = find_binary_path("btrfsck")
 
     def __check_btrfs(self):
         found = False
@@ -723,7 +735,7 @@
 
         dev_null = os.open("/dev/null", os.O_WRONLY)
         try:
-            out = subprocess.Popen(['/sbin/blkid', self.disk.device],
+            out = subprocess.Popen([self.blkidcmd, self.disk.device],
                                    stdout = subprocess.PIPE,
                                    stderr = dev_null).communicate()[0]
         finally:
@@ -761,12 +773,12 @@
     def mount(self, options = None):
         self.__create()
         if not options:
-            options = "compress,compress-force"
+            options = "compress"
         DiskMount.mount(self, options)
 
     def __fsck(self):
         logging.debug("Checking filesystem %s" % self.disk.lofile)
-        subprocess.call(["/sbin/btrfsck", self.disk.lofile])
+        subprocess.call([self.btrfsckcmd, self.disk.lofile])
 
     def __get_size_from_filesystem(self):
         return self.disk.size
@@ -790,6 +802,7 @@
 
         self.__created = False
         self.__name = None
+        self.dmsetupcmd = find_binary_path("dmsetup")
 
         """Load dm_snapshot if it isn't loaded"""
         load_module("dm_snapshot")
@@ -816,7 +829,7 @@
                                              self.imgloop.device,
                                              self.cowloop.device)
 
-        args = ["/sbin/dmsetup", "create", self.__name, "--table", table]
+        args = [self.dmsetupcmd, "create", self.__name, "--table", table]
         if subprocess.call(args) != 0:
             self.cowloop.cleanup()
             self.imgloop.cleanup()
@@ -829,7 +842,7 @@
         if not self.__created:
             return
 
-        rc = subprocess.call(["/sbin/dmsetup", "remove", self.__name])
+        rc = subprocess.call([self.dmsetupcmd, "remove", self.__name])
         if not ignore_errors and rc != 0:
             raise SnapshotError("Could not remove snapshot device")
 
@@ -845,7 +858,7 @@
 
         dev_null = os.open("/dev/null", os.O_WRONLY)
         try:
-            out = subprocess.Popen(["/sbin/dmsetup", "status", self.__name],
+            out = subprocess.Popen([self.dmsetupcmd, "status", self.__name],
                                    stdout = subprocess.PIPE,
                                    stderr = dev_null).communicate()[0]
         finally:
@@ -911,7 +924,7 @@
     if not found:
         print "Loading %s..." % module
         dev_null = os.open("/dev/null", os.O_WRONLY)
-        modprobe = subprocess.Popen(["/sbin/modprobe", module],
+        modprobe = subprocess.Popen([modprobecmd, module],
                      stdout=dev_null, stderr=dev_null)
         os.waitpid(modprobe.pid, 0)
         os.close(dev_null)
@@ -922,7 +935,7 @@
         file = url.replace("file://", "")
         if not os.path.exists(file):
             raise CreatorError("URLGrabber error: can't find file %s" % file)
-        subprocess.call(["/bin/cp", "-f", file, filename])
+        subprocess.call([copycmd, "-f", file, filename])
     else:
         try:
             filename = g.urlgrab(url = url, filename = filename,
--- mic/imgcreate/jffs2.py
+++ mic/imgcreate/jffs2.py
@@ -22,6 +22,7 @@
 
 from mic.imgcreate.errors import *
 from mic.imgcreate.creator import *
+from mic.imgcreate.fs import *
 
 class Jffs2ImageCreator(LoopImageCreator):
     def __init__(self, ks, name, fslabel = None):
@@ -32,8 +33,8 @@
             self.image_size = 0
         self._set_image_size(self.image_size)
         self.img_done = False
-        self._mkjffs2fs = "/usr/sbin/mkfs.jffs2"
-        self._dep_checks.append((self._mkjffs2fs,))
+        self._mkjffs2fs = find_binary_path("mkfs.jffs2")
+        self._dep_checks.append("mkfs.jffs2")
         self._img_name = self.name + ".jffs2"
 
     def _genjffs2img(self):
--- mic/imgcreate/kickstart.py
+++ mic/imgcreate/kickstart.py
@@ -416,7 +416,7 @@
     def apply(self, ksrepo, repodata):
         for repo in ksrepo.repoList:
             if repo.save:
-                self.__create_repo_file(repo, "/etc/yum.repos.d")
+                #self.__create_repo_file(repo, "/etc/yum.repos.d")
                 self.__create_repo_file(repo, "/etc/zypp/repos.d")
         """ Import repo gpg keys """
         if repodata:
--- mic/imgcreate/live.py
+++ mic/imgcreate/live.py
@@ -83,13 +83,7 @@
         if self.ks:
             self.__modules.extend(kickstart.get_modules(self.ks))
 
-        self._dep_checks.extend([
-                            ('/usr/bin/isohybrid',),
-                            ('/usr/sbin/unsquashfs', '/usr/bin/unsquashfs'),
-                            ('/sbin/mksquashfs', '/usr/bin/mksquashfs'),
-                            ('/bin/dd',),
-                            ('/usr/bin/mkisofs',)
-                           ])
+        self._dep_checks.extend(["isohybrid", "unsquashfs", "mksquashfs", "dd", "mkisofs"])
 
     #
     # Hooks for subclasses
@@ -156,15 +150,7 @@
 
     def _uncompress_squashfs(self, squashfsimg, outdir):
         """Uncompress file system from squshfs image"""
-
-        unsquashfs = "/usr/sbin/unsquashfs"
-        if not os.path.exists(unsquashfs):
-            unsquashfs = "/usr/bin/unsquashfs"
-            if not os.path.exists(unsquashfs):
-                unsquashfs = "/sbin/unsquashfs"
-                if not os.path.exists(unsquashfs):
-                    raise CreatorError("You didn't install squashfs-tools.");
-
+        unsquashfs = find_binary_path("unsquashfs")
         args = [unsquashfs, "-d", outdir, squashfsimg ]
         rc = subprocess.call(args)
         if (rc != 0):
@@ -176,7 +162,7 @@
         """Support Image Convertor"""
         if self.actasconvertor:
             if os.path.exists(base_on) and not os.path.isfile(base_on):
-                args = [ "/bin/dd", "if=%s" % base_on, "of=%s" % self._image ]
+                args = [ ddcmd, "if=%s" % base_on, "of=%s" % self._image ]
                 print "dd %s -> %s" % (base_on, self._image)
                 rc = subprocess.call(args)
                 if rc != 0:
@@ -290,8 +276,8 @@
 
     def __create_iso(self, isodir):
         iso = self._outdir + "/" + self.name + ".iso"
-
-        args = ["/usr/bin/mkisofs",
+        mkisofs = find_binary_path("mkisofs")
+        args = [mkisofs,
                 "-J", "-r",
                 "-hide-rr-moved", "-hide-joliet-trans-tbl",
                 "-V", self.fslabel,
@@ -304,9 +290,16 @@
         if subprocess.call(args) != 0:
             raise CreatorError("ISO creation failed!")
 
-        if os.path.exists("/usr/bin/isohybrid"):
-            hybrid = ["/usr/bin/isohybrid", "-partok", iso ]
-            if subprocess.call(hybrid) != 0:
+        """ It should be ok still even if you haven't isohybrid """
+        isohybrid = None
+        try:
+            isohybrid = find_binary_path("isohybrid")
+        except:
+            pass
+
+        if isohybrid:
+            args = [isohybrid, "-partok", iso ]
+            if subprocess.call(args) != 0:
              	raise CreatorError("Hybrid ISO creation failed!")
 
         self.__implant_md5sum(iso)
@@ -919,14 +912,10 @@
     def __init__(self, *args):
         LiveImageCreator.__init__(self, *args)
 
-        self._dep_checks.extend([
-                            ('/sbin/kpartx',),
-                            ('/sbin/parted', '/usr/sbin/parted')
-                           ])
+        self._dep_checks.extend(["kpartx", "parted"])
         # remove dependency of mkisofs in parent class
-        self._dep_checks = filter(lambda item: \
-                                    not any(map(lambda s: \
-                                        'mkisofs' in s, item)), self._dep_checks)
+        if "mkisofs" in self._dep_checks:
+            self._dep_checks.remove("mkisofs")
 
     def _create_usbimg(self, isodir):
         overlaysizemb = self.overlaysizemb
@@ -948,11 +937,11 @@
         livesize = get_file_size(isodir + "/LiveOS")
         if skipcompress:
             tmpmnt = self._mkdtemp("squashfs-mnt")
-            rc = subprocess.call(["/usr/bin/mount", "-o", "loop", isodir + "/LiveOS/squashfs.img", tmpmnt]);
+            rc = subprocess.call([mountcmd, "-o", "loop", isodir + "/LiveOS/squashfs.img", tmpmnt]);
             if rc:
                 raise CreatorError("Can't mount %s" % (isodir + "/LiveOS/squashfs.img"))
             livesize = get_file_size(tmpmnt + "/LiveOS/ext3fs.img")
-            rc = subprocess.call(["/bin/umount", tmpmnt]);
+            rc = subprocess.call([umountcmd, tmpmnt]);
             if rc:
                 raise CreatorError("Can't umount %s" % (tmpmnt))
         usbimgsize = (overlaysizemb + homesizemb + swapsizemb + livesize + plussize) * 1024L * 1024L
@@ -971,11 +960,11 @@
             makedirs(usbmnt + "/LiveOS")
             if skipcompress:
                 if os.path.exists(isodir + "/LiveOS/squashfs.img"):
-                    rc = subprocess.call(["/usr/bin/mount", "-o", "loop", isodir + "/LiveOS/squashfs.img", tmpmnt]);
+                    rc = subprocess.call([mountcmd, "-o", "loop", isodir + "/LiveOS/squashfs.img", tmpmnt]);
                     if rc:
                         raise CreatorError("Can't mount %s" % (isodir + "/LiveOS/squashfs.img"))
                     shutil.copyfile(tmpmnt + "/LiveOS/ext3fs.img", usbmnt + "/LiveOS/ext3fs.img")
-                    rc = subprocess.call(["/bin/umount", tmpmnt]);
+                    rc = subprocess.call([umountcmd, tmpmnt]);
                     if rc:
                         raise CreatorError("Can't umount %s" % (tmpmnt))
                 else:
@@ -999,7 +988,7 @@
                 usblabel = "UUID=%s" % diskmount.uuid
                 overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid)
 
-            args = ["/bin/cp", "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"]
+            args = [copycmd, "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"]
             rc = subprocess.call(args)
             if rc:
                 raise CreatorError("Can't copy isolinux directory %s" % (isodir + "/isolinux/*"))
@@ -1015,7 +1004,7 @@
             for f in ("isolinux.bin", "vesamenu.c32"):
                 path = os.path.join(syslinux_path, f)
                 if os.path.isfile(path):
-                    args = ["/bin/cp", path, usbmnt + "/syslinux/"]
+                    args = [copycmd, path, usbmnt + "/syslinux/"]
                     rc = subprocess.call(args)
                     if rc:
                         raise CreatorError("Can't copy syslinux file %s" % (path))
@@ -1037,9 +1026,9 @@
                 print "Initializing persistent overlay file"
                 overfile = "overlay" + overlaysuffix
                 if fstype == "vfat":
-                    args = ["/bin/dd", "if=/dev/zero", "of=" + usbmnt + "/LiveOS/" + overfile, "count=%d" % overlaysizemb, "bs=1M"]
+                    args = [ddcmd, "if=/dev/zero", "of=" + usbmnt + "/LiveOS/" + overfile, "count=%d" % overlaysizemb, "bs=1M"]
                 else:
-                    args = ["/bin/dd", "if=/dev/null", "of=" + usbmnt + "/LiveOS/" + overfile, "count=1", "bs=1M", "seek=%d" % overlaysizemb]
+                    args = [ddcmd, "if=/dev/null", "of=" + usbmnt + "/LiveOS/" + overfile, "count=1", "bs=1M", "seek=%d" % overlaysizemb]
                 rc = subprocess.call(args)
                 if rc:
                     raise CreatorError("Can't create overlay file")
@@ -1049,7 +1038,7 @@
             if swapsizemb > 0:
                 print "Initializing swap file"
                 swapfile = usbmnt + "/LiveOS/" + "swap.img"
-                args = ["/bin/dd", "if=/dev/zero", "of=" + swapfile, "count=%d" % swapsizemb, "bs=1M"]
+                args = [ddcmd, "if=/dev/zero", "of=" + swapfile, "count=%d" % swapsizemb, "bs=1M"]
                 rc = subprocess.call(args)
                 if rc:
                     raise CreatorError("Can't create swap file")
@@ -1062,32 +1051,36 @@
                 print "Initializing persistent /home"
                 homefile = usbmnt + "/LiveOS/" + homefile
                 if fstype == "vfat":
-                    args = ["/bin/dd", "if=/dev/zero", "of=" + homefile, "count=%d" % homesizemb, "bs=1M"]
+                    args = [ddcmd, "if=/dev/zero", "of=" + homefile, "count=%d" % homesizemb, "bs=1M"]
                 else:
-                    args = ["/bin/dd", "if=/dev/null", "of=" + homefile, "count=1", "bs=1M", "seek=%d" % homesizemb]
+                    args = [ddcmd, "if=/dev/null", "of=" + homefile, "count=1", "bs=1M", "seek=%d" % homesizemb]
                 rc = subprocess.call(args)
                 if rc:
                     raise CreatorError("Can't create home file")
 
+                mkfscmd = find_binary_path("/sbin/mkfs." + fstype)
                 if fstype == "ext2" or fstype == "ext3":
-                    args = ["/sbin/mkfs." + fstype, "-F", "-j", homefile]
+                    args = [mkfscmd, "-F", "-j", homefile]
                 else:
-                    args = ["/sbin/mkfs." + fstype, homefile]
+                    args = [mkfscmd, homefile]
                 rc = subprocess.call(args)
                 if rc:
                     raise CreatorError("Can't mke2fs home file")
                 if fstype == "ext2" or fstype == "ext3":
-                    args = ["/sbin/tune2fs", "-c0", "-i0", "-ouser_xattr,acl", homefile]
+                    tune2fs = find_binary_path("tune2fs")
+                    args = [tune2fs, "-c0", "-i0", "-ouser_xattr,acl", homefile]
                     rc = subprocess.call(args)
                     if rc:
                          raise CreatorError("Can't tune2fs home file")
 
             if fstype == "vfat" or fstype == "msdos":
+                syslinuxcmd = find_binary_path("syslinux")
                 syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg"
-                args = ["/usr/bin/syslinux", "-d", "syslinux", usbloop.partitions[0]["device"]]
+                args = [syslinuxcmd, "-d", "syslinux", usbloop.partitions[0]["device"]]
             elif fstype == "ext2" or fstype == "ext3":
+                extlinuxcmd = find_binary_path("extlinux")
                 syslinuxcfg = usbmnt + "/syslinux/extlinux.conf"
-                args = ["/sbin/extlinux", "-i", usbmnt + "/syslinux"]
+                args = [extlinuxcmd, "-i", usbmnt + "/syslinux"]
             else:
                 raise CreatorError("Invalid file system type: %s" % (fstype))
 
@@ -1111,7 +1104,7 @@
                 d = usbloop.disks[dev]
                 loopdev = d['disk'].device
                 break
-            args = ["/bin/dd", "if=" + mbrfile, "of=" + loopdev, "bs=%d" % (mbrsize), "count=1"]
+            args = [ddcmd, "if=" + mbrfile, "of=" + loopdev, "bs=%d" % (mbrsize), "count=1"]
             rc = subprocess.call(args)
             if rc:
                 raise CreatorError("Can't set MBR.")
@@ -1151,7 +1144,7 @@
         """Support Image Convertor"""
         if self.actasconvertor:
             if os.path.exists(base_on) and not os.path.isfile(base_on):
-                args = [ "/bin/dd", "if=%s" % base_on, "of=%s" % self._image ]
+                args = [ ddcmd, "if=%s" % base_on, "of=%s" % self._image ]
                 print "dd %s -> %s" % (base_on, self._image)
                 rc = subprocess.call(args)
                 if rc != 0:
--- mic/imgcreate/misc.py
+++ mic/imgcreate/misc.py
@@ -68,7 +68,7 @@
         return maptab["vdi"]
 
     dev_null = os.open("/dev/null", os.O_WRONLY)
-    args = [ "/usr/bin/file", path ]
+    args = [ filecmd, path ]
     file = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
     output = file.communicate()[0]
     os.close(dev_null)
@@ -124,16 +124,10 @@
         raise CreatorError("Invalid destination image format: %s" % dstfmt)
     logging.debug("converting %s image to %s" % (srcimg, dstimg))
     if srcfmt == "vmdk":
-        path = "/usr/bin/qemu-img"
-        if not os.path.isfile(path):
-            raise CreatorError("qemu not installed : "
-                               "%s not found" % path)
+        path = find_binary_path("qemu-img")
         argv = [path, "convert", "-f", "vmdk", srcimg, "-O", dstfmt,  dstimg]
     elif srcfmt == "vdi":
-        path = "/usr/bin/VBoxManage"
-        if not os.path.isfile(path):
-            raise CreatorError("VirtualBox not installed : "
-                               "%s not found" % path)
+        path = find_binary_path("VBoxManage")
         argv = [path, "internalcommands", "converttoraw", srcimg, dstimg]
     else:
         raise CreatorError("Invalid soure image format: %s" % srcfmt)
@@ -184,7 +178,7 @@
                 oldmycopytree(srcname, dstname, symlinks)
             elif not os.path.isfile(srcname):
                 if not os.path.exists(dstname):
-                    args = [ "/bin/cp" , "-af", srcname, dstname ]
+                    args = [ copycmd, "-af", srcname, dstname ]
                     subprocess.call(args)
             else:
                 shutil.copy2(srcname, dstname)
@@ -206,16 +200,17 @@
         raise MyError, errors
 
 def mycopytree(src, dst):
+    tarcmd = find_binary_path("tar")
     dev_null = os.open("/dev/null", os.O_WRONLY)
     tmpdir = mkdtemp()
-    args = [ "/bin/tar", "-jcf", tmpdir + "/fs.tar.bz2", "-C", src ]
+    args = [ tarcmd, "-jcf", tmpdir + "/fs.tar.bz2", "-C", src ]
     excludes = []
     ignores = ["dev/fd", "dev/stdin", "dev/stdout", "dev/stderr", "etc/mtab"]
     for exclude in ignores:
         excludes = excludes + ["--exclude", exclude]
     dirnames = os.listdir(src)
     subprocess.call(args + excludes + dirnames, stdout=dev_null, stderr=dev_null)
-    args = [ "/bin/tar", "-jxf", tmpdir + "/fs.tar.bz2", "-C", dst ]
+    args = [ tarcmd, "-jxf", tmpdir + "/fs.tar.bz2", "-C", dst ]
     subprocess.call(args, stdout=dev_null, stderr=dev_null)
     subprocess.call(args)
     os.close(dev_null)
@@ -225,7 +220,7 @@
     dev_null = os.open("/dev/null", os.O_WRONLY)
     dirnames = os.listdir(src)
     for dir in dirnames:
-        args = [ "/bin/cp", "-af", src + "/" + dir, dst ]
+        args = [ copycmd, "-af", src + "/" + dir, dst ]
         subprocess.call(args, stdout=dev_null, stderr=dev_null)
     os.close(dev_null)
     ignores = ["dev/fd", "dev/stdin", "dev/stdout", "dev/stderr", "etc/mtab"]
@@ -235,14 +230,7 @@
 
 def uncompress_squashfs(squashfsimg, outdir):
     """Uncompress file system from squshfs image"""
-    unsquashfs = "/usr/sbin/unsquashfs"
-    if not os.path.exists(unsquashfs):
-        unsquashfs = "/usr/bin/unsquashfs"
-        if not os.path.exists(unsquashfs):
-            unsquashfs = "/sbin/unsquashfs"
-            if not os.path.exists(unsquashfs):
-                raise SquashfsError("%s didn't exist." % unsquashfs)
-
+    unsquashfs = find_binary_path("unsquashfs")
     args = [ unsquashfs, "-d", outdir, squashfsimg ]
     rc = subprocess.call(args)
     if (rc != 0):
@@ -352,7 +340,7 @@
             ip = ip_to_int(needle)
             netmask = 0
             mask = item[item.find("/")+1:].strip()
-         
+
             if mask.isdigit():
                 netmask = int(mask)
                 netmask = ~((1<<(32-netmask)) - 1)
@@ -385,7 +373,7 @@
                 return True
     return False
 
-def set_proxies(proxy = None, no_proxy = None): 
+def set_proxies(proxy = None, no_proxy = None):
     _set_proxies(proxy, no_proxy)
     set_noproxy_list()
 
@@ -427,7 +415,7 @@
                     return repostr
 
     return repostr
-    
+
 
 def get_temp_reponame(baseurl):
     md5obj = hashlib.md5(baseurl)
@@ -486,7 +474,7 @@
 
     if repostr.find("--name=") == -1:
         repostr += " --name=%s" % get_temp_reponame(url)
-            
+
     return repostr
 
 def read_siteconf(siteconf = None):
@@ -678,7 +666,7 @@
                 if elm.attrib["type"] == "primary":
                     primary_type=".xml"
                     break
-        
+
         if not primary_type:
             continue
 
@@ -721,7 +709,7 @@
 
             con.close()
     return archlist
-        
+
 
 def get_package(pkg, repometadata):
     ver = ""
@@ -758,16 +746,74 @@
           pkg = myurlgrab(url, filename, target_repo["proxies"])
           return pkg
     else:
-	return None
+          return None
+
+def get_source_name(pkg, repometadata):
+
+    def get_bin_name(pkg):
+        m = re.match("(.*)-(.*)-(.*)\.(.*)\.rpm", pkg)
+        if m:
+            return m.group(1)
+        return None
+
+    def get_src_name(srpm):
+        m = re.match("(.*)-(\d+.*)-(\d+\.\d+).src.rpm", srpm)
+        if m:
+            return m.group(1)
+        return None
+
+    ver = ""
+    target_repo = None
+
+    pkg_name = get_bin_name(pkg)
+
+    if not pkg_name:
+        return None
+
+    for repo in repometadata:
+        if repo["primary"].endswith(".xml"):
+            root = xmlparse(repo["primary"])
+            ns = root.getroot().tag
+            ns = ns[0:ns.rindex("}")+1]
+            for elm in root.getiterator("%spackage" % ns):
+                if elm.find("%sname" % ns).text == pkg_name:
+                    if elm.find("%sarch" % ns).text != "src":
+                        version = elm.find("%sversion" % ns)
+                        tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
+                        if tmpver > ver:
+                            ver = tmpver
+                            fmt = elm.find("%sformat" % ns)
+                            if fmt:
+                                fns = fmt.getchildren()[0].tag
+                                fns = fns[0:fns.rindex("}")+1]
+                                pkgpath = fmt.find("%ssourcerpm" % fns).text
+                                target_repo = repo
+                        break
+
+        if repo["primary"].endswith(".sqlite"):
+            con = sqlite.connect(repo["primary"])
+            for row in con.execute("select version, release, rpm_sourcerpm from packages where name = \"%s\" and arch != \"src\"" % pkg_name):
+                tmpver = "%s-%s" % (row[0], row[1])
+                if tmpver > ver:
+                    pkgpath = "%s" % row[2]
+                    target_repo = repo
+                break
+            con.close()
+    if target_repo:
+        return get_src_name(pkgpath)
+    else:
+        return None
 
 def get_release_no(repometadata, distro="meego"):
+    cpio = find_binary_path("cpio")
+    rpm2cpio = find_binary_path("rpm2cpio")
     release_pkg = get_package("%s-release" % distro, repometadata)
     if release_pkg:
         tmpdir = mkdtemp()
         oldcwd = os.getcwd()
         os.chdir(tmpdir)
-        p1 = subprocess.Popen(["/usr/bin/rpm2cpio", release_pkg], stdout = subprocess.PIPE)
-        p2 = subprocess.Popen(["/bin/cpio", "-idv"], stdin = p1.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
+        p1 = subprocess.Popen([rpm2cpio, release_pkg], stdout = subprocess.PIPE)
+        p2 = subprocess.Popen([cpio, "-idv"], stdin = p1.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
         p2.communicate()
         f = open("%s/etc/%s-release" % (tmpdir, distro), "r")
         content = f.read()
@@ -777,7 +823,7 @@
         return content.split(" ")[2]
     else:
         return "UNKNOWN"
-        
+
 def get_kickstarts_from_repos(repometadata):
     kickstarts = []
     for repo in repometadata:
@@ -799,9 +845,9 @@
         location = elm.find("%slocation" % ns)
         image_config = str(repo["baseurl"] + "/" + location.attrib["href"])
         filename = str("%s/%s/image-config.xml%s" % (repo["cachedir"], repo["name"], suffix))
-        
+
         image_config = get_uncompressed_data_from_url(image_config,filename,repo["proxies"])
-        
+
         try:
             root = xmlparse(image_config)
         except SyntaxError:
@@ -877,7 +923,7 @@
 def is_statically_linked(binary):
     ret = False
     dev_null = os.open("/dev/null", os.O_WRONLY);
-    args = [ "/usr/bin/file", binary ]
+    args = [ filecmd, binary ]
     file = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
     output = file.communicate()[0]
     os.close(dev_null)
@@ -888,9 +934,11 @@
 def setup_qemu_emulator(rootdir, arch):
     # mount binfmt_misc if it doesn't exist
     if not os.path.exists("/proc/sys/fs/binfmt_misc"):
-        subprocess.call(["/sbin/modprobe", "binfmt_misc"])
+        subprocess.call([modprobecmd, "binfmt_misc"])
     if not os.path.exists("/proc/sys/fs/binfmt_misc/register"):
-        subprocess.call(["/bin/mount", "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"])
+        subprocess.call([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"])
+
+    # qemu_emulator is a special case, we can't use find_binary_path
     # qemu emulator should be a statically-linked executable file
     qemu_emulator = "/usr/bin/qemu-arm"
     if not os.path.exists(qemu_emulator) or not is_statically_linked(qemu_emulator):
@@ -901,9 +949,13 @@
         makedirs(rootdir + "/usr/bin")
     shutil.copy(qemu_emulator, rootdir + qemu_emulator)
 
+    # disable selinux, selinux will block qemu emulator to run
+    if os.path.exists("/usr/sbin/setenforce"):
+        subprocess.call(["/usr/sbin/setenforce", "0"])
+
     node = "/proc/sys/fs/binfmt_misc/arm"
     if is_statically_linked(qemu_emulator) and os.path.exists(node):
-        return
+        return qemu_emulator
 
     # unregister it if it has been registered and is a dynamically-linked executable
     if not is_statically_linked(qemu_emulator) and os.path.exists(node):
@@ -919,21 +971,32 @@
         fd.write(qemu_arm_string)
         fd.close()
 
-    # disable selinux, selinux will block qemu emulator to run
-    if os.path.exists("/usr/sbin/setenforce"):
-        subprocess.call(["/usr/sbin/setenforce", "0"])
+    return qemu_emulator
 
 def create_release(config, destdir, name, outimages):
-    """ TODO: This functionality should really be in creator.py inside the 
+    """ TODO: This functionality should really be in creator.py inside the
     ImageCreator class. """
 
+    # For virtual machine images, we have a subdir for it, this is unnecessary
+    # for release
+    thatsubdir = None
+    for i in range(len(outimages)):
+        file = outimages[i]
+        if not os.path.isdir(file) and os.path.dirname(file) != destdir:
+            thatsubdir = os.path.dirname(file)
+            newfile = os.path.join(destdir, os.path.basename(file))
+            shutil.move(file, newfile)
+            outimages[i] = newfile
+    if thatsubdir:
+        shutil.rmtree(thatsubdir, ignore_errors = True)
+
     """ Create release directory and files """
     os.system ("cp %s %s/%s.ks" % (config, destdir, name))
     outimages.append("%s/%s.ks" % (destdir,name))
-    
+
     os.system ("mv %s/*-pkgs.txt %s/%s.packages" % (destdir, destdir, name))
     outimages.append("%s/%s.packages" % (destdir,name))
-    
+
     d = os.listdir(destdir)
     for f in d:
         if f.endswith(".iso"):
@@ -959,16 +1022,16 @@
             else:
                 md5sum = md5sum.split(" ")[0]
                 fd.write(md5sum+" "+f+"\n")
-                
+
     outimages.append("%s/MANIFEST" % destdir)
     fd.close()
-    
+
     """ Update the file list. """
     updated_list = []
     for file in outimages:
         if os.path.exists("%s" % file):
             updated_list.append(file)
-    
+
     return updated_list
 
 def get_local_distro():
@@ -983,9 +1046,9 @@
         content = fd.read()
         fd.close()
         print content
+    print "Local Kernel version: " + os.uname()[2]
 
 def check_mic_installation(argv):
-    print argv
     creator_name = os.path.basename(argv[0])
     if os.path.exists("/usr/local/bin/" + creator_name) \
         and os.path.exists("/usr/bin/" + creator_name):
--- mic/imgcreate/srcdownload.py
+++ mic/imgcreate/srcdownload.py
+#!/usr/bin/python
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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 Library 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.
+#
+# This program is base on yumdownloader
+#
+
+import sys
+import os
+import yum
+import shutil
+import rpmUtils
+
+from yum.packages import parsePackages
+from yum.Errors import *
+from mic.imgcreate.fs import *
+from mic.imgcreate import kickstart
+
+
+def _best_convert_pkg2srcpkgs(self, pkg):
+    if pkg.arch == 'src':
+        return [pkg]
+
+    (n,v,r,e,a) = rpmUtils.miscutils.splitFilename(pkg.sourcerpm)
+    src = self.pkgSack.searchNevra(name=n, ver=v, rel=r, arch='src')
+    if src == []:
+        self.logger.error('No source RPM found for %s' % str(pkg))
+
+    return src
+
+class SrcDownload(yum.YumBase):
+
+    def __init__(self):
+        yum.YumBase.__init__(self)
+        self.destdir = './'
+        self.cachedir = '/var/tmp/cache'
+
+    def config(self, ks, cachedir, repo_urls = {}):
+
+        self.cachedir = cachedir
+
+        for repo in kickstart.get_repos(ks, repo_urls):
+
+            (name, baseurl, mirrorlist, inc, exc, proxy, proxy_username, proxy_password, debuginfo, source, gpgkey, disable) = repo
+
+            self.addRepository(name, baseurl, mirrorlist, proxy, proxy_username, proxy_password)
+
+        self.setupSourceRepos()
+
+
+    def addRepository(self, name, url = None, mirrorlist = None, proxy = None, proxy_username = None, proxy_password = None):
+        def _varSubstitute(option):
+            # takes a variable and substitutes like yum configs do
+            option = option.replace("$basearch", rpmUtils.arch.getBaseArch())
+            option = option.replace("$arch", rpmUtils.arch.getCanonArch())
+            return option
+
+        repo = yum.yumRepo.YumRepository(name)
+
+        """Set proxy"""
+        repo.proxy = proxy
+        repo.proxy_username = proxy_username
+        repo.proxy_password = proxy_password
+
+        if url:
+            repo.baseurl.append(_varSubstitute(url))
+
+        if mirrorlist:
+            repo.mirrorlist = _varSubstitute(mirrorlist)
+        conf = yum.config.RepoConf()
+        for k, v in conf.iteritems():
+            if v or not hasattr(repo, k):
+                repo.setAttribute(k, v)
+
+        repo.basecachedir = self.cachedir
+        repo.failovermethod = "priority"
+        repo.metadata_expire = 0
+        repo.gpgcheck = 0
+        repo.enable()
+        repo.setCallback(TextProgress())
+        repo.setup(0)
+        self.repos.add(repo)
+        return repo
+
+    def setupSourceRepos(self):
+        # enable the -source repos for enabled primary repos
+        archlist = rpmUtils.arch.getArchList() + ['src']
+        # Ok, we have src and bin repos. What we want to do here is:
+        #
+        # 1. _enable_ source repos for which the bin repos are enabled.
+        # 2. _disable_ the _other_ src repos.
+
+        # Get all src repos.
+        src_repos = {}
+        for repo in self.repos.findRepos('*-source'):
+            src_repos[repo.id] = False
+
+        #  Find the enabled bin repos, and mark their respective *-source repo.
+        # as good.
+        for repo in self.repos.listEnabled():
+            if repo.id not in src_repos:
+                srcrepo = '%s-source' % repo.id
+                if srcrepo in src_repos:
+                    src_repos[srcrepo] = True
+
+        # Toggle src repos that are set the wrong way
+        for repo in self.repos.findRepos('*-source'):
+            if  repo.isEnabled() and src_repos[repo.id]:
+                repo.setup(0)
+                try:
+                    # Setup pkgSack with 'src' in the archlist
+                    self._getSacks(archlist=archlist, thisrepo=repo.id)
+                except yum.Errors.YumBaseError, msg:
+                    self.logger.critical(str(msg))
+                    sys.exit(1)
+        if len(src_repos) == 0:
+            raise ConfigError('No source repo found')
+
+    def get(self, packages, instroot, destdir = None):
+
+        if not destdir:
+            self.destdir = instroot + '/usr/src/SRPMS'
+        else:
+            self.destdir = instroot + destdir
+
+        toDownload = []
+
+        for pkgnames in packages:
+            toActOn = []
+            pos = self.pkgSack.returnPackages(patterns=[pkgnames])
+            exactmatch, matched, unmatched = parsePackages(pos, [pkgnames])
+            installable = yum.misc.unique(exactmatch + matched)
+            if not installable: # doing one at a time, apart from groups
+                self.logger.error('No Match for argument %s' % pkgnames)
+                continue
+            for newpkg in installable:
+                toActOn.extend(_best_convert_pkg2srcpkgs(self, newpkg))
+            if toActOn:
+                pkgGroups = self._groupPackages(toActOn)
+                for group in pkgGroups:
+                    pkgs = pkgGroups[group]
+
+                    toDownload.extend(self.bestPackagesFromList(pkgs, 'src'))
+
+        if len(toDownload) == 0:
+            self.logger.error('Nothing to download')
+            sys.exit(1)
+
+        for pkg in toDownload:
+            n,a,e,v,r = pkg.pkgtup
+            packages =  self.pkgSack.searchNevra(n,e,v,r,a)
+            for download in packages:
+                repo = self.repos.getRepo(download.repoid)
+                remote = download.returnSimple('relativepath')
+                local = os.path.basename(remote)
+                if not os.path.exists(self.destdir):
+                    os.makedirs(self.destdir)
+                local = os.path.join(self.destdir, local)
+                if (os.path.exists(local) and
+                    os.path.getsize(local) == int(download.returnSimple('packagesize'))):
+                    self.logger.error("%s already exists and appears to be complete" % local)
+                    continue
+                # Disable cache otherwise things won't download
+                repo.cache = 0
+                download.localpath = local # Hack: to set the localpath we want.
+                try:
+                    checkfunc = (self.verifyPkg, (download, 1), {})
+                    path = repo.getPackage(download, checkfunc=checkfunc)
+                except IOError, e:
+                    self.logger.error("Cannot write to file %s. Error was: %s" % (local, e))
+                    continue
+                except RepoError, e:
+                    self.logger.error("Could not download/verify pkg %s: %s" % (download, e))
+                    continue
+
+                if not os.path.exists(local) or not os.path.samefile(path, local):
+                    progress = TextMeter()
+                    progress.start(basename=os.path.basename(local),
+                                   size=os.stat(path).st_size)
+                    shutil.copy2(path, local)
+                    progress.end(progress.size)
+
+    def _groupPackages(self,pkglist):
+        pkgGroups = {}
+        for po in pkglist:
+            na = '%s.%s' % (po.name,po.arch)
+            if not na in pkgGroups:
+                pkgGroups[na] = [po]
+            else:
+                pkgGroups[na].append(po)
+        return pkgGroups
--- mic/imgcreate/ubi.py
+++ mic/imgcreate/ubi.py
@@ -31,10 +31,10 @@
             self.image_size = 0
         self._set_image_size(self.image_size)
         self.img_done = False
-        self._mkubifs = "/usr/sbin/mkfs.ubifs"
-        self._ubinize = "/usr/sbin/ubinize"
-        self._dep_checks.append((self._mkubifs,))
-        self._dep_checks.append((self._ubinize,))
+        self._mkubifs = find_binary_path("mkfs.ubifs")
+        self._ubinize = find_binary_path("ubinize")
+        self._dep_checks.append("mkfs.ubifs")
+        self._dep_checks.append("ubinize")
         self._img_name = self.name + ".ubiimg"
 
     def _writeUbiConf(self, configfile, baseimage):
--- mic/imgcreate/yuminst.py
+++ mic/imgcreate/yuminst.py
@@ -75,6 +75,7 @@
         conf += "plugins=0\n"
         conf += "reposdir=\n"
         conf += "failovermethod=priority\n"
+        conf += "http_caching=packages\n"
 
         f = file(confpath, "w+")
         f.write(conf)
@@ -187,6 +188,8 @@
         proxy_username = repo.proxy_username
         proxy_password = repo.proxy_password
 
+        handlers = []
+        auth_handler = u2.HTTPBasicAuthHandler(u2.HTTPPasswordMgrWithDefaultRealm())
         u2opener = None
         if proxy:
             if proxy_username:
@@ -200,20 +203,32 @@
 
             proxy_support = u2.ProxyHandler({'http': proxy_url,
                                              'ftp': proxy_url})
-            u2opener = u2.build_opener(proxy_support)
+            handlers.append(proxy_support)
 
         # download all remote files to one temp dir
         baseurl = None
         repo_lic_dir = tempfile.mkdtemp(prefix = 'repolic')
 
         for url in repo.baseurl:
-            if not url.startswith('http') and \
-               not url.startswith('ftp'):
-               continue
-
             if not url.endswith('/'):
                 url += '/'
-
+            tmphandlers = handlers
+            (scheme, host, path, parm, query, frag) = urlparse.urlparse(url)
+            if scheme not in ("http", "https", "ftp", "ftps", "file"):
+                raise CreateError("Error: invalid url %s" % url)
+            if '@' in host:
+                try:
+                    user_pass, host = host.split('@', 1)
+                    if ':' in user_pass:
+                        user, password = user_pass.split(':', 1)
+                except ValueError, e:
+                    raise CreateError('Bad URL: %s' % url)
+                print "adding HTTP auth: %s, %s" %(user, password)
+                auth_handler.add_password(None, host, user, password)
+                tmphandlers.append(auth_handler)
+                url = scheme + "://" + host + path + parm + query + frag
+            if len(tmphandlers) != 0:
+                u2opener = u2.build_opener(*tmphandlers)
             # try to download
             repo_eula_url = urlparse.urljoin(url, "LICENSE.txt")
             repo_eula_path = self.__checkAndDownloadURL(
@@ -297,8 +312,8 @@
         repo.basecachedir = self.conf.cachedir
         repo.failovermethod = "priority"
         repo.metadata_expire = 0
-        # disable gpg check???
-        repo.gpgcheck = 0
+        # Enable gpg check for verifying corrupt packages
+        repo.gpgcheck = 1
         repo.enable()
         repo.setup(0)
         repo.setCallback(TextProgress())
--- mic2.spec
+++ mic2.spec
@@ -8,7 +8,7 @@
 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
 Name:       mic2
 Summary:    Tools for building images for MeeGo
-Version:    0.21.0
+Version:    0.22.6
 Release:    1
 Group:      System/Base
 License:    GPLv2
@@ -38,7 +38,11 @@
 Requires:   gzip
 Requires:   bzip2
 Requires:   squashfs-tools >= 4.0
+%if 0%{?suse_version}
+Requires:   btrfsprogs
+%else
 Requires:   btrfs-progs
+%endif
 BuildRequires:  python-devel
 BuildRequires:  zlib-devel
 BuildRoot:  %{_tmppath}/%{name}-%{version}-build
@@ -78,6 +82,9 @@
 make DESTDIR=%{buildroot} installman
 make DESTDIR=%{buildroot} installconf
 make DESTDIR=%{buildroot} installsymlinks
+%if 0%{?fedora_version} || 0%{?moblin_version} || 0%{?fedora_version}
+sed -i 's/^run_mode.*$/run_mode=0/g' %{buildroot}/etc/mic2/mic2.conf
+%endif
 # << install post
 
 
--- mic2.yaml
+++ mic2.yaml
@@ -1,6 +1,6 @@
 Name: mic2
 Summary: Tools for building images for MeeGo
-Version: 0.21.0
+Version: 0.22.6
 Release: 1
 Group: System/Base
 License: GPLv2
--- tools/mic
+++ tools/mic
@@ -74,7 +74,8 @@
         changed_opts = {"overlaysizemb":"overlay-size-mb", "cachedir":"cache", "srcimg":"source-image", "dstformat":"target-format",
                         "srcformat":"source-format", "convertto":"convert-to", "give_shell":"shell", "saveto":"save-to",
                         "unpackonly":"unpack-only", "convertonly":"convert-only", "buildbootstrap":"build-bootstrap",
-                        "bindmounts":"bind-mounts","use_comps":"use-comps","run_mode":"run-mode","save_kernel":"save-kernel"
+                        "bindmounts":"bind-mounts", "use_comps":"use-comps", "run_mode":"run-mode", "save_kernel":"save-kernel",
+                        "file":"logfile", "include_src":"include-source"
                        }
 
         argv = [tools[subcmd]]
@@ -194,6 +195,9 @@
                       dest="compress_disk_image", default=None,
                       help="Compress the disk image that is created. When using --release option default is bz2,"
                            " otherwise default is none. Supported compression methods: bz2, none")
+    @cmdln.option("", "--include-source", action="store_true",
+                      dest="include_src", default=False,
+                      help="Generate a image with source rpms included")
 
     @cmdln.option("-i", "--interactive", action="store_true",
                       dest="interactive", default=False,
@@ -336,7 +340,7 @@
     @cmdln.option("", "--convert-only", action="store_true",
                       dest="convertonly", default=False,
                       help="Just convert an image, this will skip chroot and"
-                           " directly convert an image/fiflesytem with -c "
+                           " directly convert an image/filesytem with -c "
                            "option together"
                      )
     @cmdln.option("-o", "--outdir", type="string",
--- tools/mic-check-alldeps
+++ tools/mic-check-alldeps
@@ -78,7 +78,7 @@
 		extrapkgs=("pykickstart" "isomd5sum" "squashfs-tools" "device-mapper" "sqlite" "zlib-devel" "python-devel" "qemu-img" "make")
 		;;
 	 "MeeGo")
-		installer="yum -y install"
+		installer="zypper install"
 		querycmd="rpm -q"
 		qvercmd="rpm -q --qf %{VERSION}"
 		extrapkgs=("pykickstart" "isomd5sum" "squashfs-tools" "device-mapper" "sqlite" "zlib-devel" "python-devel" "make")
--- tools/mic-chroot
+++ tools/mic-chroot
@@ -73,7 +73,7 @@
     parser.add_option("", "--convert-only", action="store_true",
                       dest="convertonly", default=False,
                       help="Just convert an image, this will skip chroot and"
-                           " directly convert an image/fiflesytem with -c "
+                           " directly convert an image/filesytem with -c "
                            "option together"
                      )
     parser.add_option("-o", "--outdir", type="string",
@@ -221,7 +221,7 @@
         if options.execute:
             chroot.chroot(options.saveto, bindmounts = options.bindmounts, execute = options.execute)
         else:
-            chroot.chroot(options.saveto, bindmounts = options.bindmounts)
+            chroot.chroot(options.saveto, bindmounts = options.bindmounts, execute = "/bin/env HOME=/root /bin/bash")
 
     if options.convertto:
         chroot.cleanup_mounts(options.saveto)
--- tools/mic-image-creator
+++ tools/mic-image-creator
@@ -17,6 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
+from __future__ import with_statement
 import os
 import os.path
 import sys
@@ -33,6 +34,7 @@
 import mic.appcreate as appcreate
 import mic.imgcreate as imgcreate
 import mic.chroot as mychroot
+from mic.imgcreate.srcdownload import SrcDownload
 
 import signal
 def sig_interrupt(signum=None, frame=None):
@@ -77,8 +79,10 @@
 
 
 debugger = Debugger()
+parser = None
 
 def parse_options(args):
+    global parser
     parser = optparse.OptionParser(version=version)
 
     commonopt = optparse.OptionGroup(parser, "General options",
@@ -157,6 +161,10 @@
     sysopt.add_option("", "--local-pkgs-path", type="string",
                       dest="local_pkgs_path", default=None,
                       help="Path for local pkgs (rpms) to be installed")
+    sysopt.add_option("", "--include-source", action="store_true",
+                      dest="include_src", default=False,
+                      help="Generate a image with source rpms included")
+
     parser.add_option_group(sysopt)
 
     # options related to live USB
@@ -252,7 +260,9 @@
     globalmounts = mychroot.setup_chrootenv(bootstrap, bindmounts)
     if arch and arch.startswith("arm"):
         imgcreate.setup_qemu_emulator(bootstrap, "arm")
+    sys.stdout.flush()
     ret = subprocess.call(args, preexec_fn = chroot_bootstrap)
+    sys.stdout.flush()
     mychroot.cleanup_chrootenv(bootstrap, bindmounts, globalmounts)
     if ret != 0:
         raise FatalError("Failed to run mic inside bootstrap environment. Return code: %s" % (ret))
@@ -282,8 +292,12 @@
 
     return None
 
-def rebuild_argv(argv, options):
-    blacklist = ["bootstrap", "buildbootstrap", "mainrepo", "repo", "default_ks", "siteconf", "prefix", "ignore_siteconf", "package", "run_mode"]
+def rebuild_argv(argv, options, logfile = None):
+    blacklist = ["bootstrap", "buildbootstrap", "mainrepo", "repo", "default_ks", "siteconf", "prefix", "ignore_siteconf", "run_mode"]
+    changed_opts = {"overlaysizemb":"overlay-size-mb", "cachedir":"cache", "give_shell":"shell",
+                    "use_comps":"use-comps", "run_mode":"run-mode", "save_kernel":"save-kernel",
+                    "file":"logfile", "include_src":"include-source"
+                   }
     myargv = []
     myargv.append("/usr/bin/mic-image-creator")
 
@@ -292,19 +306,56 @@
         if optlist[key]:
             if key in blacklist:
                 continue
-            if key == "cachedir":
-                myargv.append("--%s=%s" % ("cache", optlist[key]))
-            elif optlist[key] == True:
-                myargv.append("--%s" % key.replace("_", "-"))
-            else:
-                myargv.append("--%s=%s" % (key.replace("_", "-"), optlist[key]))
+            value = getattr(options, key)
+            if value == None or (type(value) is bool and value == False) or value == "":
+                continue
+            optstr = "--%s" % key.replace("_", "-")
+            if key in changed_opts.keys():
+                optstr = "--%s" % changed_opts[key]
+            if type(value) is not bool:
+                optstr += "=%s" % value
+            myargv.append(optstr)
 
     if logging.getLogger().level in (logging.DEBUG, logging.INFO, logging.WARN):
         myargv.append("--traceback")
 
+    if logfile:
+        myargv.append("--logfile=%s" % logfile)
+
     return myargv
 
+def get_options_from_ks(ksfile, parser):
+    # readin the firstline of kickstart file for inline options, format as:
+    # -*-mic2-options-*- --format=livecd --arch=arm -*-mic2-options-*-
+    # the priority of different optinos source: cmdln_options >> inline_options
+    # the extra inline args (left part from options) will be ignored
+    first_line = None
+    if ksfile and os.path.exists(ksfile):
+        with open(ksfile) as f:
+            first_line = f.readline()
+    if first_line:
+        m = re.match('^#\s*-\*-mic2-options-\*-\s+(.*)\s+-\*-mic2-options-\*-', first_line)
+        if m:
+            inline_argv = m.group(1).strip().split()
+            if inline_argv:
+                try:
+                    (inline_opts, inline_args) = parser.parse_args(inline_argv)
+                    return inline_opts
+                except (optparse.BadOptionError, optparse.OptionValueError):
+                    raise FatalError("Error: the options '%s' in the magic line of ks are invalid" %  m.group(1).strip())
+    return None
+
+def merge_options(options, options_plus):
+    optlist = options.__dict__
+    for key in optlist.keys():
+        value = getattr(options, key)
+        if value == None or (type(value) is bool and value == False) or value == "":
+            value = getattr(options_plus, key)
+            setattr(options, key, value)
+
 def main():
+    global parser
+    print "MIC2 version: %s" % version
     imgcreate.misc.check_mic_installation(sys.argv)
     options = parse_options(sys.argv[1:])
 
@@ -321,6 +372,12 @@
         siteconf = None
     imgcreate.get_local_distro()
 
+    if not options.config and not options.ignore_siteconf:
+        options.config = get_siteconf_opt(siteconf, "main", "config")
+    options_from_ks = get_options_from_ks(options.config, parser)
+    if options_from_ks:
+        merge_options(options, options_from_ks)
+
     distro_name = get_siteconf_opt(siteconf, "main", "distro_name")
     if not distro_name:
         distro_name = "MeeGo"
@@ -355,7 +412,7 @@
                     else:
                         raise FatalError("Failed to rm %s, please ensure there isn't any other process accessing some directories under %s" % (default_bootstrap_root, default_bootstrap_root))
                 options.buildbootstrap = True
-    
+
     if options.buildbootstrap:
         if not options.bootstrap:
             raise FatalError("Please use -b | --build-bootstrap with -B | --bootstrap together")
@@ -394,7 +451,7 @@
             options.tmpdir = value
         else:
             options.tmpdir = "/var/tmp"
-    
+
     options.tmpdir = os.path.abspath(os.path.expanduser(options.tmpdir))
 
     print "Using %s as tmpdir." % (options.tmpdir)
@@ -412,7 +469,7 @@
     print "Using %s as cache directory." % (options.cachedir)
 
     if not options.outdir:
-        value = get_siteconf_diropt(siteconf, "outdir") 
+        value = get_siteconf_diropt(siteconf, "outdir")
         if value:
             options.outdir = value
         else:
@@ -426,8 +483,8 @@
         kscont = kscont.replace("@BUILD_ID@", options.release)
         base = os.path.basename(options.config)
         options.config = "%s/%s" %(options.tmpdir, base)
-        fd = open(options.config, "w") 
-        fd.write(kscont) 
+        fd = open(options.config, "w")
+        fd.write(kscont)
         fd.close()
 
     releaseksbasename = None
@@ -442,7 +499,7 @@
         base = os.path.basename(options.config)
         ksname = base[:base.rfind(".")]
         ksnamec = ksname.split("-")
-        
+
         """ Accept also the image name prefix in kickstart filename. """
         if ksnamec[0] == options.prefix:
             ksnamec.pop(0)
@@ -450,7 +507,7 @@
         """ Ignore release id in kickstart """
         if re.match("\d+\.\d+.\d+.*$", ksnamec[-1]):
             ksnamec.pop(-1)
-        
+
         """ There might be more than 3 parts in the ksnamec because of the release numbering. """
         if len(ksnamec) < 2 or ksnamec[0] not in meegovert or ksnamec[1] not in meegoarch:
             raise FatalError("Configuration file %s does not follow naming conventions: $VERTICAL-$ARCH-$VARIANT or %s-$VERTICAL-$ARCH-$VARIANT" %(options.config,options.prefix))
@@ -463,7 +520,7 @@
 
     if not os.path.exists(options.outdir):
         imgcreate.fs.makedirs(options.outdir)
-    
+
     print "Using %s as output directory." % (options.outdir)
 
     """ proxy settings from site config override proxy settings from environment variables """
@@ -582,6 +639,8 @@
     name = imgcreate.build_name(ksname, options.prefix, suffix=options.suffix)
 
     if options.arch:
+        if options.arch.strip() in ("i386", "i485", "i586", "i686"):
+            options.arch = "i686"
         arch_set = False
         for target_arch in target_archlist:
             if target_arch.startswith(options.arch.strip()):
@@ -589,7 +648,7 @@
                 print "Target arch: %s" % options.arch
                 arch_set = True
                 break
-   
+
         if not arch_set:
             raise FatalError("Given arch '%s' is not found from the repositories." % options.arch.strip())
 
@@ -638,7 +697,8 @@
         fd.close()
         options.config = "/root/" + os.path.basename(options.config)
 
-        argv = rebuild_argv(sys.argv, options)
+        logfile = imgcreate.get_logfile()
+        argv = rebuild_argv(sys.argv, options, logfile)
         mypipe = tempfile.mktemp(".mic2pipe", ".mic2-", options.outdir)
         argv.append("--pipe=%s" % mypipe)
         if need_convert:
@@ -651,9 +711,13 @@
                 repodir = repo.baseurl.replace("file://", "")
                 if bindmounts.find(repodir) < 0:
                     bindmounts += "%s;" % repodir
-        bindmounts += "%s;%s" % (options.outdir, options.tmpdir)
+        bindmounts += "%s;%s;" % (options.outdir, options.tmpdir)
         if options.cachedir:
-            bindmounts = bindmounts + ";%s" % options.cachedir
+            bindmounts = bindmounts + "%s;" % options.cachedir
+        if logfile:
+            logdir = os.path.dirname(logfile)
+            if bindmounts.find(logdir) < 0:
+                bindmounts += "%s;" % logdir
         run_in_bootstrap(options.bootstrap, argv, bindmounts, arch = options.arch)
         # For the case with release option, destdir is changed, so get it
         for line in open(mypipe).xreadlines():
@@ -678,7 +742,7 @@
             print "Finished."
         # Save original kickstart file
         shutil.copy(oldconfig, options.outdir + "/%s.ks" % name)
-        sys.exit(0)
+        return 0
 
 
     if options.format == "fs":
@@ -748,19 +812,35 @@
     creator.tmpdir = options.tmpdir
     creator._alt_initrd_name = options.alt_initrd_name
     creator._recording_pkgs = options.record_pkgs
+    creator._include_src = options.include_src
     creator._local_pkgs_path = options.local_pkgs_path
     creator._genchecksum = options.genchecksum
     creator.distro_name = distro_name
-    
+    creator.image_format = options.format
+
     if options.arch:
         creator.set_target_arch(options.arch)
-    
+
     imgname = creator.name
 
     try:
         creator.check_depend_tools()
         creator.mount(None, options.cachedir)
+
         creator.install()
+
+        ''' Download the source packages '''
+        if options.include_src and options.format == "fs":
+            installed_pkgs =  creator.get_installed_packages()
+            src_pkgs = set()
+            for pkg in installed_pkgs:
+                src_pkgs.add(imgcreate.misc.get_source_name(pkg, repometadata))
+            print '--------------------------------------------------'
+            print 'Generating the image with source rpms included, %d source packages to be downloaded.' %(len(src_pkgs))
+            src_downloader = SrcDownload()
+            src_downloader.config(ks, options.cachedir)
+            src_downloader.get(list(src_pkgs), creator._instroot)
+
         creator.configure(repometadata)
         if options.save_kernel:
             creator.save_kernel(options.outdir)
@@ -813,9 +893,11 @@
 if __name__ == "__main__":
     try:
         ret = main()
+        imgcreate.terminate_log_thread()
         sys.exit(ret)
     except (imgcreate.CreatorError,FatalError), e:
         print >> sys.stderr, "\n%sError: %s%s\n" % (COLOR_RED, e, COLOR_BLACK)
         debugger.record_callstack()
         debugger.dump_debuginfo()
+        imgcreate.terminate_log_thread()
         sys.exit(1)
--- tools/mic-image-writer
+++ tools/mic-image-writer
@@ -1,7 +1,7 @@
 #!/usr/bin/python -tt
 #
 # mic-image-writer : write an image to usb disk or read to a file
-#                       from usb disk 
+#                       from usb disk
 #
 # Copyright 2009, Intel Inc.
 #
@@ -27,6 +27,7 @@
 import optparse
 import select
 import dbus
+import re
 try:
     from dbus.mainloop.glib import DBusGMainLoop
 except:
@@ -59,31 +60,146 @@
         options.image_file = None
     return options
 
-if os.geteuid () != 0:
-    errmsg("You must run mic-image-writer as root")
-options = parse_options(sys.argv[1:])
-if not options.console or options.gui:
-    try:
-        import pygtk
-        pygtk.require('2.0')
-        import gtk, gobject
-        options.gui = True
-    except:
-        if options.gui:
-            errmsg("Error: failed to run in GUI mode")
-        options.console = True
-if options.console:
-    if not options.image_file:
-        errmsg("Error: please provide image file.")
-
-dbus_loop = DBusGMainLoop(set_as_default=True)
-bus = dbus.SystemBus(mainloop = dbus_loop)
-hal_obj = bus.get_object("org.freedesktop.Hal",
-                         "/org/freedesktop/Hal/Manager")
-hal = dbus.Interface(hal_obj, "org.freedesktop.Hal.Manager")
+class DBus_udisk:
+    def __init__(self):
+        dbus_loop = DBusGMainLoop(set_as_default=True)
+        self.usbdisks = {}
+        self.bus = dbus.SystemBus(mainloop = dbus_loop)
+        self.UDISKS_IFACE = "org.freedesktop.UDisks"
+        self.udisks = self.bus.get_object(self.UDISKS_IFACE, "/org/freedesktop/UDisks")
+
+    def connect_signals(self, callback_add, callback_remove):
+        # Connect with the Added and Removed signals
+        self.udisks.connect_to_signal('DeviceAdded', callback_add)
+        self.udisks.connect_to_signal('DeviceRemoved', callback_remove)
+
+    def get_usb_list(self):
+        ''' Dictionary drives store the info of usb disks with device file path as the key,
+            such as '/dev/sdb'. The element is also dict with following format:
+            { 'vendor': 'String of Vendor',
+              'model': 'String of Model',
+              'partition': list(partitions device object of this drive) }
+        '''
+        drives = {}
+        devices = self.udisks.EnumerateDevices(dbus_interface = self.UDISKS_IFACE)
+        for device in devices:
+            try:
+                dev_obj = self.bus.get_object(self.UDISKS_IFACE, device)
+                dev_iface_p = dbus.Interface(dev_obj, 'org.freedesktop.DBus.Properties')
+
+                if (not dev_iface_p.Get(self.UDISKS_IFACE, "DeviceIsSystemInternal")
+                    and dev_iface_p.Get(self.UDISKS_IFACE, 'DriveConnectionInterface') == 'usb'):
+                    if ( dev_iface_p.Get(self.UDISKS_IFACE, 'DeviceIsDrive')
+                         and dev_iface_p.Get(self.UDISKS_IFACE, 'DeviceIsPartitionTable')):
+                        dev_file = str(dev_iface_p.Get(self.UDISKS_IFACE, 'DeviceFile'))
+
+                        if dev_file not in drives.keys() :
+                            drives[dev_file] = {}
+
+                        drives[dev_file]['vendor'] = dev_iface_p.Get(self.UDISKS_IFACE, 'DriveVendor')
+                        drives[dev_file]['model'] = dev_iface_p.Get(self.UDISKS_IFACE, 'DriveModel')
+
+                    elif dev_iface_p.Get(self.UDISKS_IFACE, 'DeviceIsPartition'):
+                        partition = dev_iface_p.Get(self.UDISKS_IFACE, 'DeviceFile')
+                        m = re.match("(\D+)(\d+)", partition)
+                        if m:
+                            dev_file = m.group(1)
+
+                            if dev_file not in drives.keys() :
+                                drives[dev_file] = {}
+
+                            if 'partition' not in drives[dev_file].keys():
+                                drives[dev_file]['partition'] = []
+
+                            ''' Keep the partition's info in list'''
+                            drives[dev_file]['partition'].append(dev_obj)
+
+            except dbus.DBusException, e:
+                errmsg(e)
+        self.usbdisks = drives
+        return drives
+
+    def unmount(self, device):
+        usbdisk = self.usbdisks[device]
+
+        if 'partition' in usbdisk.keys():
+            for dev_obj in usbdisk['partition']:
+                dev_iface_p = dbus.Interface(dev_obj, 'org.freedesktop.DBus.Properties')
+                dev_iface = dbus.Interface(dev_obj, 'org.freedesktop.UDisks.Device')
+                try:
+                    if dev_iface_p.Get(self.UDISKS_IFACE, 'DeviceIsMounted'):
+                        dev_iface.FilesystemUnmount('')
+                except dbus.exceptions.DBusException, e:
+                    errmsg(e)
+
+class DBus_hal:
+
+    def __init__(self):
+        dbus_loop = DBusGMainLoop(set_as_default=True)
+        bus = dbus.SystemBus(mainloop = dbus_loop)
+        hal_obj = bus.get_object("org.freedesktop.Hal",
+                                 "/org/freedesktop/Hal/Manager")
+        hal = dbus.Interface(hal_obj, "org.freedesktop.Hal.Manager")
+        """Initialize dbus"""
+        self.bus = bus
+        self.hal = hal
+
+    def connect_signals(self, callback_add, callback_remove):
+        # Connect with the Added and Removed signals
+        self.hal.connect_to_signal('DeviceAdded', callback_add)
+        self.hal.connect_to_signal('DeviceRemoved', callback_remove)
+
+    def get_usb_list(self):
+        drives = {}
+        devices = []
+        devices = self.hal.FindDeviceByCapability("storage")
+        for device in devices:
+            try:
+                dev_obj = self.bus.get_object("org.freedesktop.Hal", device)
+                dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
+                if dev.GetProperty("storage.bus") == "usb" and \
+                    dev.GetProperty("storage.removable"):
+                    if not dev.GetProperty("block.is_volume"):
+                        tmpdevice = str(dev.GetProperty('block.device'))
+                        tmpvendor = str(dev.GetProperty('info.vendor'))
+                        tmpproduct = str(dev.GetProperty('info.product'))
+                        drives[tmpdevice]={"vendor":tmpvendor, "model":tmpproduct}
+            except dbus.DBusException, e:
+                continue
+        return drives
+
+    def hal_unmount(self, device):
+        dev_obj = self.bus.get_object("org.freedesktop.Hal", device)
+        dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
+        if dev.GetProperty('volume.is_mounted'):
+            try:
+                dev_obj.Unmount([""], dbus_interface="org.freedesktop.Hal.Device.Volume")
+            except dbus.DBusException, msg:
+                device = str(dev.GetProperty('block.device'))
+                raise IOError("Error: failed to unmount %s, %s" % (device, msg))
+
+    def unmount(self, usbdisk):
+        partitions = self.hal.FindDeviceStringMatch('block.device', usbdisk)
+
+        for partition in partitions:
+            dev_obj = self.bus.get_object("org.freedesktop.Hal", partition)
+            dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
+            if dev.GetProperty("block.is_volume"):
+                device = str(dev.GetProperty('block.device'))
+                self.hal_unmount(partition)
+            else: # iterate over children looking for a volume
+                if dev.GetProperty("storage.bus") == "usb" and \
+                    dev.GetProperty("storage.removable"):
+                    children = self.hal.FindDeviceStringMatch("info.parent",
+                                                              partition)
+                    for child in children:
+                        dev_obj = self.bus.get_object("org.freedesktop.Hal", child)
+                        dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
+                        if dev.GetProperty("block.is_volume"):
+                            self.hal_unmount(child)
 
 class USBWriterWindow:
-    def __init__(self, the_image_file):
+    def __init__(self, the_image_file, usbdevices):
         self.p = None
         self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
         self.window.set_resizable(False)
@@ -96,7 +212,6 @@
         vbox.set_border_width(5)
         self.window.add(vbox)
 
-        #
         self.image_file = gtk.FileChooserButton("Select an Image to write")
         if the_image_file:
             self.image_file.set_filename(the_image_file)
@@ -111,12 +226,12 @@
         image_frame.set_size_request(260, 60)
         image_frame.add(align)
 
-        self.usb_disk = gtk.combo_box_new_text()
-        self.usb_disk.set_size_request(80, -1)
-        
+        self.combobox_disks = gtk.combo_box_new_text()
+        self.combobox_disks.set_size_request(80, -1)
+
         # Create a centering alignment object
         align = gtk.Alignment(0.50, 0.50, 0.9, 0.10)
-        align.add(self.usb_disk)
+        align.add(self.combobox_disks)
 
         usb_frame = gtk.Frame("USB Disk")
         usb_frame.set_shadow_type(gtk.SHADOW_IN)
@@ -125,17 +240,15 @@
 
         hbox = gtk.HBox(False, 2)
         hbox.set_border_width(0)
-       
-        hbox.pack_start(image_frame, True, True, 0) 
-        hbox.pack_start(usb_frame, True, True, 0)
 
+        hbox.pack_start(image_frame, True, True, 0)
+        hbox.pack_start(usb_frame, True, True, 0)
         vbox.pack_start(hbox, True, True, 0)
 
         # Create the ProgressBar
         self.pbar = gtk.ProgressBar()
-        
         progress_frame = gtk.Frame("Progress")
-        
+
         # Create a centering alignment object
         align = gtk.Alignment(0.50, 0.50, 0.9, 0.10)
         progress_frame.add(align)
@@ -165,18 +278,14 @@
         self.write_button.connect("clicked", self.write_image)
         self.read_button.connect("clicked", self.read_image)
         self.exit_button.connect("clicked", self.exit)
-        self.dbus_init()
 
-        self.window.show_all()
+        self.usbdevices = usbdevices
+        self.usbdevices.connect_signals(self.populate_devices, self.populate_devices)
+        usbdisks_list = self.usbdevices.get_usb_list()
 
-    def dbus_init(self):
-        """Initialize dbus"""
-        self.bus = bus
-        self.hal = hal
         self.usb_disks_num = 0
-        self.detect_removable_drives()
-        self.connect_hal_signal()
-        self.refresh_usblist(self.drives)
+        self.refresh_usblist(usbdisks_list)
+        self.window.show_all()
 
     def close(self, widget, event):
         self.exit(widget, event)
@@ -195,66 +304,30 @@
         if self.p and self.p.poll() == None:
             os.kill(self.p.pid, signal.SIGTERM)
 
-    def connect_hal_signal(self):
-        # If we have access to HAL & DBus, intercept some useful signals
-        self.hal.connect_to_signal('DeviceAdded',
-                                            self.populate_devices)
-        self.hal.connect_to_signal('DeviceRemoved',
-                                            self.populate_devices)
-
     def populate_devices(self, *args, **kw):
-        self.detect_removable_drives()
-        self.refresh_usblist(self.drives)
+        self.refresh_usblist(self.usbdevices.get_usb_list())
         pass
 
     def refresh_usblist(self, usblist):
         self.usb_disks = []
         if self.usb_disks_num > 0:
             for i in range(0, self.usb_disks_num):
-                self.usb_disk.remove_text(0)
+                self.combobox_disks.remove_text(0)
 
-        for usb_disk in usblist:
-            self.usb_disk.append_text(usb_disk)
-            self.usb_disks.append(usb_disk)
+        for key in usblist.keys():
+            self.combobox_disks.append_text(key)
+            self.usb_disks.append(key)
 
         self.usb_disks_num = len(usblist)
-        if not self.usb_disk.get_active() >= 0:
-            self.usb_disk.set_active(0)
-        self.usb_disk.show()
-
-    def detect_removable_drives(self):
-        """ Detect all removable USB storage devices using HAL via D-Bus """
-        self.drives = []
-
-        devices = []
-        if False:
-            devices = self.hal.FindDeviceStringMatch('block.device',
-                                                     self.opts.force)
-        else:
-            devices = self.hal.FindDeviceByCapability("storage")
-
-        for device in devices:
-            try:
-                dev = self._get_device(device)
-                if dev.GetProperty("storage.bus") == "usb" and \
-                    dev.GetProperty("storage.removable"):
-                    if not dev.GetProperty("block.is_volume"):
-                        tmpdevice = str(dev.GetProperty('block.device'))
-                        self.drives.append(tmpdevice)
-            except dbus.DBusException, e:
-                continue
-
-        if len(self.drives):
-           self.refresh_usblist(self.drives)
-
-    def _get_device(self, udi):
-        """ Return a dbus Interface to a specific HAL device UDI """
-        dev_obj = self.bus.get_object("org.freedesktop.Hal", udi)
-        return dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
-
-    def msgbox(self, msg):
-        dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, msg)
-        dlg.set_title("Warning")
+        if not self.combobox_disks.get_active() >= 0:
+            self.combobox_disks.set_active(0)
+        self.combobox_disks.show()
+
+    def msgbox(self, msg, type = 0):
+        dlgtypes = [gtk.MESSAGE_WARNING, gtk.MESSAGE_INFO, gtk.MESSAGE_ERROR]
+        dlgtitles = ["Warning", "Info", "Error"]
+        dlg = gtk.MessageDialog(None, 0, dlgtypes[type], gtk.BUTTONS_OK, msg)
+        dlg.set_title(dlgtitles[type])
         dlg.set_default_size(100, 100)
         dlg.set_transient_for(self.window)
         dlg.set_keep_above(True)
@@ -275,7 +348,6 @@
         if self.usb_disks[disk_no]:
             # It's a usb disk
             return True
-
         return False
 
     def set_progress(self):
@@ -286,54 +358,15 @@
         self.pbar.set_text("estimated time: %ds, elapsed time: %ds, progress: %d%%" %
                            (self.total_time, self.elapsed_time, int(percent*100)))
 
-    def _hal_unmount(self, udi):
-        dev = self._get_device(udi)
-        device = str(dev.GetProperty('block.device'))
-        if dev.GetProperty('volume.is_mounted'):
-            try:
-                dev_obj = self.bus.get_object("org.freedesktop.Hal", udi)
-                dev_obj.Unmount([""], dbus_interface="org.freedesktop.Hal.Device.Volume")
-            except dbus.DBusException, msg:
-                self.msgbox(device + ": " + str(msg))
-                return -1
-        return 0
-
-    def unmount_usb(self, usbdisk):
-        partitions = self.hal.FindDeviceStringMatch('block.device', usbdisk)
-
-        for partition in partitions:
-            dev = self._get_device(partition)
-            if dev.GetProperty("block.is_volume"):
-                try:
-                    device = str(dev.GetProperty('block.device'))
-                    ret = self._hal_unmount(partition)
-                    if ret != 0:
-                        return -1
-                except:
-                    pass
-            else: # iterate over children looking for a volume
-                if dev.GetProperty("storage.bus") == "usb" and \
-                   dev.GetProperty("storage.removable"):
-                    children = self.hal.FindDeviceStringMatch("info.parent",
-                                                              partition)
-                    for child in children:
-                        dev = self._get_device(child)
-                        if dev.GetProperty("block.is_volume"):
-                            device = str(dev.GetProperty('block.device'))
-                            ret = self._hal_unmount(child)
-                            if ret != 0:
-                                return -1
-        return 0
-
     def disable_some_widgets(self):
         self.image_file.set_sensitive(False)
-        self.usb_disk.set_sensitive(False)
+        self.combobox_disks.set_sensitive(False)
         self.write_button.set_sensitive(False)
         self.read_button.set_sensitive(False)
 
     def enable_some_widgets(self):
         self.image_file.set_sensitive(True)
-        self.usb_disk.set_sensitive(True)
+        self.combobox_disks.set_sensitive(True)
         self.write_button.set_sensitive(True)
         self.read_button.set_sensitive(True)
 
@@ -346,18 +379,20 @@
         if not os.path.exists(image_file) or not os.path.isfile(image_file):
             self.msgbox("Please specify a valid image file.")
 
-        usb_disk = self.usb_disk.get_active()
+        usb_disk = self.combobox_disks.get_active()
         if not self.__is_usbdisk(usb_disk):
             self.msgbox("Please insert or select a usb disk.")
             return
 
         self.disable_some_widgets()
         argv = ["/bin/dd", "if=%s" % image_file, "bs=1M", "of=%s" % self.usb_disks[usb_disk]]
-        ret = self.unmount_usb(self.usb_disks[usb_disk])
-        if ret != 0:
+
+        try:
+            self.usbdevices.unmount(self.usb_disks[usb_disk])
+        except IOError, e:
+            self.msgbox(str(e))
             self.enable_some_widgets()
             return
-        print argv
         self.p = subprocess.Popen(argv,
                              stdout = subprocess.PIPE,
                              stderr = subprocess.STDOUT,
@@ -378,87 +413,60 @@
         if self.p.returncode != 0:
             for line in stdout.split('\n'):
                 print line
-            self.msgbox("Failed!!!")
+            self.msgbox("Failed!!!", 2)
         else:
             self.set_progress()
-            self.msgbox("Done successfully!!!")
+            self.msgbox("Done successfully!!!", 1)
         self.enable_some_widgets()
 
     def read_image(self, widget):
         pass
 
 
-def get_usb_list():
-    drives = []
-
-    devices = []
-    devices = hal.FindDeviceByCapability("storage")
-    for device in devices:
-        try:
-            dev_obj = bus.get_object("org.freedesktop.Hal", device)
-            dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
-            if dev.GetProperty("storage.bus") == "usb" and \
-                dev.GetProperty("storage.removable"):
-                if not dev.GetProperty("block.is_volume"):
-                    tmpdevice = str(dev.GetProperty('block.device'))
-                    tmpvendor = str(dev.GetProperty('info.vendor'))
-                    tmpproduct = str(dev.GetProperty('info.product'))
-                    drives.append({"device":tmpdevice, "vendor":tmpvendor, "product":tmpproduct})
-        except dbus.DBusException, e:
-            continue
-    return drives
-
-def hal_unmount(device):
-    dev_obj = bus.get_object("org.freedesktop.Hal", device)
-    dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
-    if dev.GetProperty('volume.is_mounted'):
+if __name__ == "__main__":
+    options = parse_options(sys.argv[1:])
+    if not options.console or options.gui:
         try:
-            dev_obj.Unmount([""], dbus_interface="org.freedesktop.Hal.Device.Volume")
-        except dbus.DBusException, msg:
-            device = str(dev.GetProperty('block.device'))
-            errmsg("Error: failed to unmount %s, %s" % (device, msg))
-            
-def unmount_usb(usbdisk):
-    partitions = hal.FindDeviceStringMatch('block.device', usbdisk)
+            import pygtk
+            pygtk.require('2.0')
+            import gtk, gobject
+            options.gui = True
+        except:
+            if options.gui:
+                errmsg("Error: failed to run in GUI mode")
+            options.console = True
+
+    if options.console:
+        if not options.image_file:
+            errmsg("Error: please provide image file.")
 
-    for partition in partitions:
-        dev_obj = bus.get_object("org.freedesktop.Hal", partition)
-        dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
-        if dev.GetProperty("block.is_volume"):
-            try:
-                device = str(dev.GetProperty('block.device'))
-                hal_unmount(partition)
-            except:
-                sys.exit(1)
-        else: # iterate over children looking for a volume
-            if dev.GetProperty("storage.bus") == "usb" and \
-                dev.GetProperty("storage.removable"):
-                children = hal.FindDeviceStringMatch("info.parent",
-                                                     partition)
-                for child in children:
-                    dev_obj = bus.get_object("org.freedesktop.Hal", child)
-                    dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
-                    if dev.GetProperty("block.is_volume"):
-                        try:
-                            hal_unmount(child)
-                        except:
-                            sys.exit(1)
+    if os.geteuid () != 0:
+        errmsg("You must run mic-image-writer as root")
+
+    try:
+        usbdevices = DBus_udisk()
+    except dbus.exceptions.DBusException:
+        usbdevices = DBus_hal()
 
-if __name__ == "__main__":
     if options.gui:
-        USBWriterWindow(options.image_file)
+        USBWriterWindow(options.image_file, usbdevices)
         gtk.main()
     else:
-        usb_list = get_usb_list()
+        usb_list = usbdevices.get_usb_list()
+
         if not usb_list:
             print "Please insert your USB stick..."
         while not usb_list:
             time.sleep(2)
-            usb_list = get_usb_list()
+            usb_list = usbdevices.get_usb_list()
+
         index = 1
-        print "Available usb disk:"
-        for usbdisk in usb_list:
-            print "\t[%d] %s" % (index, "%s: %s %s" % (usbdisk["device"], usbdisk["vendor"], usbdisk["product"]))
+        device_index={}
+
+        print "Available usb disk(s):"
+        for key in usb_list.keys():
+            print "\t[%d] %s %s %s" %(index, key, usb_list[key]["vendor"], usb_list[key]['model'])
+            device_index[index]= key
             index += 1
         while True:
             choice = raw_input("Please choice [1..%d] ? " % (index - 1,))
@@ -467,14 +475,14 @@
                 break
             else:
                 print "Invalid choice"
-        unmount_usb(usb_list[choice-1]["device"])
+        usbdevices.unmount(device_index[choice])
         image_size = os.path.getsize(options.image_file)
         image_size_mb = image_size/1024/1024
         total_time = image_size_mb/10
         elapsed_time = 0
-        argv = ["/bin/dd", "if=%s" % options.image_file, "bs=1M", "of=%s" % usb_list[choice-1]["device"]]
+        argv = ["/bin/dd", "if=%s" % options.image_file, "bs=1M", "of=%s" % device_index[choice]]
         print "Source: %s" % options.image_file
-        print "Target: %s" % usb_list[choice-1]["device"]
+        print "Target: %s" % device_index[choice]
         print "Image size: %d MB" % image_size_mb
         print "Estimated time: %d seconds" % total_time
         p = subprocess.Popen(argv,

++++++ mic2.yaml
--- mic2.yaml
+++ mic2.yaml
@@ -1,6 +1,6 @@
 Name: mic2
 Summary: Tools for building images for MeeGo
-Version: 0.21.1
+Version: 0.22.6
 Release: 1
 Group: System/Base
 License: GPLv2




More information about the MeeGo-commits mailing list