[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