Makefile | 4 - imgcreate/debug.py | 14 ++++-- imgcreate/fs.py | 76 +++++++++++++++++++------------------ imgcreate/util.py | 39 +++++++++++++++++++ imgcreate/yuminst.py | 16 ++++++- tools/image-creator | 75 ------------------------------------ tools/livecd-creator | 51 ++++++++++++++++++++---- tools/livecd-iso-to-disk.sh | 90 ++++++++++++++++++++++++++++++-------------- 8 files changed, 208 insertions(+), 157 deletions(-)
New commits: commit 48504157c52bcec63a5b884b045a86034c1bc48f Author: Brian C. Lane bcl@redhat.com Date: Tue Nov 30 09:40:16 2010 -0800
Bump version to 15.1
diff --git a/Makefile b/Makefile index be14e32..2fd0549 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@
-VERSION = 15.0 +VERSION = 15.1
INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL}
commit 056955d01f7ab8b430c5fffd6f2e05d969f80d8b Author: Brian C. Lane bcl@redhat.com Date: Tue Nov 30 15:14:53 2010 -0800
Create tmpdir if it doesn't exist (#658632)
If the directory passed to --tmpdir doesn't exist, create it and its parent directories.
diff --git a/tools/livecd-creator b/tools/livecd-creator index 4ec5fc3..afe592f 100755 --- a/tools/livecd-creator +++ b/tools/livecd-creator @@ -25,6 +25,7 @@ import optparse import logging
import imgcreate +from imgcreate.fs import makedirs
class Usage(Exception): def __init__(self, msg = None, no_error = False): @@ -146,6 +147,8 @@ def main(): return 1
creator.tmpdir = os.path.abspath(options.tmpdir) + if not os.path.exists(creator.tmpdir): + makedirs(creator.tmpdir) creator.compress_type = options.compress_type creator.skip_compression = options.skip_compression creator.skip_minimize = options.skip_minimize
commit 4423f6816f9146658d83f8fc7dec2f612dc4cf78 Author: James Laska jlaska@redhat.com Date: Wed Nov 24 12:21:34 2010 -0500
Wrap subprocess.call() so we can capture all command output for debugging.
Also create imgcreate/util.py so other methods can benefit from the subprocess.call() wrapper.
diff --git a/imgcreate/fs.py b/imgcreate/fs.py index 9f9d8ea..f0e0885 100644 --- a/imgcreate/fs.py +++ b/imgcreate/fs.py @@ -27,6 +27,7 @@ import string import logging import tempfile import time +from util import call
from imgcreate.errors import *
@@ -50,7 +51,7 @@ def mksquashfs(in_img, out_img, compress_type): if not sys.stdout.isatty(): args.append("-no-progress")
- ret = subprocess.call(args) + ret = call(args) if ret != 0: raise SquashfsError("'%s' exited with error (%d)" % (string.join(args, " "), ret)) @@ -64,14 +65,14 @@ def resize2fs(fs, size = None, minimal = False): e2fsck(fs) (fd, saved_image) = tempfile.mkstemp("", "resize-image-", "/tmp") os.close(fd) - subprocess.call(["/sbin/e2image", "-r", fs, saved_image]) + call(["/sbin/e2image", "-r", fs, saved_image])
args = ["/sbin/resize2fs", fs] if minimal: args.append("-M") else: args.append("%sK" %(size / 1024,)) - ret = subprocess.call(args) + ret = call(args) if ret != 0: raise ResizeError("resize2fs returned an error (%d)! image to debug at %s" %(ret, saved_image))
@@ -81,8 +82,8 @@ def resize2fs(fs, size = None, minimal = False): return 0
def e2fsck(fs): - logging.debug("Checking filesystem %s" % fs) - rc = subprocess.call(["/sbin/e2fsck", "-f", "-y", fs]) + logging.info("Checking filesystem %s" % fs) + rc = call(["/sbin/e2fsck", "-f", "-y", fs]) return rc
class BindChrootMount: @@ -102,7 +103,7 @@ class BindChrootMount: return
makedirs(self.dest) - rc = subprocess.call(["/bin/mount", "--bind", self.src, self.dest]) + rc = call(["/bin/mount", "--bind", self.src, self.dest]) if rc != 0: raise MountError("Bind-mounting '%s' to '%s' failed" % (self.src, self.dest)) @@ -112,14 +113,14 @@ class BindChrootMount: if not self.mounted: return
- rc = subprocess.call(["/bin/umount", self.dest]) + rc = call(["/bin/umount", self.dest]) if rc != 0: - logging.debug("Unable to unmount %s normally, using lazy unmount" % self.dest) - rc = subprocess.call(["/bin/umount", "-l", self.dest]) + logging.info("Unable to unmount %s normally, using lazy unmount" % self.dest) + rc = call(["/bin/umount", "-l", self.dest]) if rc != 0: raise MountError("Unable to unmount fs at %s" % self.dest) else: - logging.debug("lazy umount succeeded on %s" % self.dest) + logging.info("lazy umount succeeded on %s" % self.dest) print >> sys.stdout, "lazy umount succeeded on %s" % self.dest
self.mounted = False @@ -138,7 +139,7 @@ class LoopbackMount:
def lounsetup(self): if self.losetup: - rc = subprocess.call(["/sbin/losetup", "-d", self.loopdev]) + rc = call(["/sbin/losetup", "-d", self.loopdev]) self.losetup = False self.loopdev = None
@@ -156,7 +157,7 @@ class LoopbackMount:
self.loopdev = losetupOutput.split()[0]
- rc = subprocess.call(["/sbin/losetup", self.loopdev, self.lofile]) + rc = call(["/sbin/losetup", self.loopdev, self.lofile]) if rc != 0: raise MountError("Failed to allocate loop device for '%s'" % self.lofile) @@ -277,8 +278,8 @@ class LoopbackDisk(Disk):
device = losetupOutput.split()[0]
- logging.debug("Losetup add %s mapping to %s" % (device, self.lofile)) - rc = subprocess.call(["/sbin/losetup", device, self.lofile]) + logging.info("Losetup add %s mapping to %s" % (device, self.lofile)) + rc = call(["/sbin/losetup", device, self.lofile]) if rc != 0: raise MountError("Failed to allocate loop device for '%s'" % self.lofile) @@ -287,8 +288,8 @@ class LoopbackDisk(Disk): def cleanup(self): if self.device is None: return - logging.debug("Losetup remove %s" % self.device) - rc = subprocess.call(["/sbin/losetup", "-d", self.device]) + logging.info("Losetup remove %s" % self.device) + rc = call(["/sbin/losetup", "-d", self.device]) self.device = None
@@ -307,7 +308,7 @@ class SparseLoopbackDisk(LoopbackDisk): if size is None: size = self.size
- logging.debug("Extending sparse file %s to %d" % (self.lofile, size)) + logging.info("Extending sparse file %s to %d" % (self.lofile, size)) fd = os.open(self.lofile, flags)
if size <= 0: @@ -320,7 +321,7 @@ class SparseLoopbackDisk(LoopbackDisk): if size is None: size = self.size
- logging.debug("Truncating sparse file %s to %d" % (self.lofile, size)) + logging.info("Truncating sparse file %s to %d" % (self.lofile, size)) fd = os.open(self.lofile, os.O_WRONLY) os.ftruncate(fd, size) os.close(fd) @@ -361,18 +362,18 @@ class DiskMount(Mount):
def unmount(self): if self.mounted: - logging.debug("Unmounting directory %s" % self.mountdir) - rc = subprocess.call(["/bin/umount", self.mountdir]) + logging.info("Unmounting directory %s" % self.mountdir) + rc = call(["/bin/umount", self.mountdir]) if rc == 0: self.mounted = False else: - logging.debug("Unmounting directory %s failed, using lazy umount" % self.mountdir) + logging.warn("Unmounting directory %s failed, using lazy umount" % self.mountdir) print >> sys.stdout, "Unmounting directory %s failed, using lazy umount" %self.mountdir - rc = subprocess.call(["/bin/umount", "-l", self.mountdir]) + rc = call(["/bin/umount", "-l", self.mountdir]) if rc != 0: raise MountError("Unable to unmount filesystem at %s" % self.mountdir) else: - logging.debug("lazy umount succeeded on %s" % self.mountdir) + logging.info("lazy umount succeeded on %s" % self.mountdir) print >> sys.stdout, "lazy umount succeeded on %s" % self.mountdir self.mounted = False
@@ -393,18 +394,18 @@ class DiskMount(Mount): return
if not os.path.isdir(self.mountdir): - logging.debug("Creating mount point %s" % self.mountdir) + logging.info("Creating mount point %s" % self.mountdir) os.makedirs(self.mountdir) self.rmdir = self.rmmountdir
self.__create()
- logging.debug("Mounting %s at %s" % (self.disk.device, self.mountdir)) + logging.info("Mounting %s at %s" % (self.disk.device, self.mountdir)) args = [ "/bin/mount", self.disk.device, self.mountdir ] if self.fstype: args.extend(["-t", self.fstype])
- rc = subprocess.call(args) + rc = call(args) if rc != 0: raise MountError("Failed to mount '%s' to '%s'" % (self.disk.device, self.mountdir)) @@ -419,17 +420,18 @@ class ExtDiskMount(DiskMount): self.fslabel = "_" + fslabel
def __format_filesystem(self): - logging.debug("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) - rc = subprocess.call(["/sbin/mkfs." + self.fstype, - "-F", "-L", self.fslabel, - "-m", "1", "-b", str(self.blocksize), - self.disk.device]) - # str(self.disk.size / self.blocksize)]) + logging.info("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) + rc = call(["/sbin/mkfs." + self.fstype, + "-F", "-L", self.fslabel, + "-m", "1", "-b", str(self.blocksize), + self.disk.device]) + # str(self.disk.size / self.blocksize)]) + if rc != 0: raise MountError("Error creating %s filesystem" % (self.fstype,)) - logging.debug("Tuning filesystem on %s" % self.disk.device) - subprocess.call(["/sbin/tune2fs", "-c0", "-i0", "-Odir_index", - "-ouser_xattr,acl", self.disk.device]) + logging.info("Tuning filesystem on %s" % self.disk.device) + call(["/sbin/tune2fs", "-c0", "-i0", "-Odir_index", + "-ouser_xattr,acl", self.disk.device])
def __resize_filesystem(self, size = None): current_size = os.stat(self.disk.lofile)[stat.ST_SIZE] @@ -526,7 +528,7 @@ class DeviceMapperSnapshot(object): self.cowloop.device)
args = ["/sbin/dmsetup", "create", self.__name, "--table", table] - if subprocess.call(args) != 0: + if call(args) != 0: self.cowloop.cleanup() self.imgloop.cleanup() raise SnapshotError("Could not create snapshot device using: " + @@ -540,7 +542,7 @@ class DeviceMapperSnapshot(object):
# sleep to try to avoid any dm shenanigans time.sleep(2) - rc = subprocess.call(["/sbin/dmsetup", "remove", self.__name]) + rc = call(["/sbin/dmsetup", "remove", self.__name]) if not ignore_errors and rc != 0: raise SnapshotError("Could not remove snapshot device")
diff --git a/imgcreate/util.py b/imgcreate/util.py new file mode 100644 index 0000000..7ff80e8 --- /dev/null +++ b/imgcreate/util.py @@ -0,0 +1,39 @@ +# +# util.py : Various utility methods +# +# Copyright 2010, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU 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. + +import subprocess +import logging + +def call(*popenargs, **kwargs): + ''' + Calls subprocess.Popen() with the provided arguments. All stdout and + stderr output is sent to logging.debug(). The return value is the exit + code of the command. + ''' + p = subprocess.Popen(*popenargs, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs) + rc = p.wait() + + # Log output using logging module + while True: + # FIXME choose a more appropriate buffer size + buf = p.stdout.read(4096) + if not buf: + break + logging.debug("%s", buf) + + return rc
commit 102fb4e8e3828a7d274bdabf1a77d0c9147a260e Author: James Laska jlaska@redhat.com Date: Wed Nov 24 11:33:41 2010 -0500
Work with the logging settings when emitting progress.
diff --git a/imgcreate/yuminst.py b/imgcreate/yuminst.py index 5f3333b..92b8f45 100644 --- a/imgcreate/yuminst.py +++ b/imgcreate/yuminst.py @@ -28,13 +28,21 @@ import pykickstart.parser from imgcreate.errors import *
class TextProgress(object): + logger = logging.getLogger() + def emit(self, lvl, msg): + '''play nice with the logging module''' + for hdlr in self.logger.handlers: + if lvl >= self.logger.level: + hdlr.stream.write(msg) + hdlr.stream.flush() + def start(self, filename, url, *args, **kwargs): - sys.stdout.write("Retrieving %s " % (url,)) + self.emit(logging.INFO, "Retrieving %s " % (url,)) self.url = url def update(self, *args): pass def end(self, *args): - sys.stdout.write("...OK\n") + self.emit(logging.INFO, "...OK\n")
class LiveCDYum(yum.YumBase): def __init__(self):
commit 0f58f5a77744948b1d1b9be6873d93ae0af84c88 Author: James Laska jlaska@redhat.com Date: Wed Nov 24 11:33:40 2010 -0500
Add a quiet option to surpress stdout. Adjust handle_logfile to not surpress stdout.
diff --git a/imgcreate/debug.py b/imgcreate/debug.py index 84b8d30..a3c5cb9 100644 --- a/imgcreate/debug.py +++ b/imgcreate/debug.py @@ -27,16 +27,17 @@ 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): +def handle_logfile(option, opt, val, parser, logger): + try: logfile = logging.FileHandler(val,"a") except IOError, e: raise optparse.OptionValueError("Cannot open file '%s' : %s" % (val, e.strerror)) + logger.addHandler(logfile)
- +def handle_quiet(option, opt, val, parser, logger, stream): logger.removeHandler(stream) - logger.addHandler(logfile)
def setup_logging(parser = None): """Set up the root logger and add logging options. @@ -78,9 +79,14 @@ def setup_logging(parser = None): callback_args = (logger, logging.INFO), help = "Output verbose progress information")
+ group.add_option("-q", "--quiet", + action = "callback", callback = handle_quiet, + callback_args = (logger, stream), + help = "Supress stdout") + group.add_option("", "--logfile", type="string", action = "callback", callback = handle_logfile, - callback_args = (logger, stream), + callback_args = (logger,), help = "Save debug information to FILE", metavar = "FILE")
parser.add_option_group(group)
commit 3bb07677c50d4f7aa70b8d4244d2e9f01869cb0a Author: Frederick Grose fgrose@gmail.com Date: Mon Nov 29 17:15:09 2010 -0800
Fix partition number selection for MMC bus devices (#587411)
Enable detection of partition number prefixes.
diff --git a/tools/livecd-iso-to-disk.sh b/tools/livecd-iso-to-disk.sh index cc2c012..628822c 100755 --- a/tools/livecd-iso-to-disk.sh +++ b/tools/livecd-iso-to-disk.sh @@ -68,6 +68,13 @@ getdisk() { partnum=${p##$device} }
+getpartition() { + DEV=$1 + pa=$( < /proc/partitions ) + pa=${pa##*$DEV} + partnum=${pa%% *} +} + resetMBR() { if isdevloop "$DEV"; then return @@ -166,11 +173,12 @@ createGPTLayout() { partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:) size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//') /sbin/parted --script $device unit b mkpart '"EFI System Partition"' fat32 17408 $(($size - 17408)) set 1 boot on - USBDEV=${device}1 # Sometimes automount can be _really_ annoying. echo "Waiting for devices to settle..." /sbin/udevadm settle sleep 5 + getpartition ${device#/dev/} + USBDEV=${device}${partnum} umount $USBDEV &> /dev/null /sbin/mkdosfs -n LIVE $USBDEV USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)" @@ -188,15 +196,16 @@ createMSDOSLayout() { partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:) size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//') /sbin/parted --script $device unit b mkpart primary fat32 17408 $(($size - 17408)) set 1 boot on - if ! isdevloop "$DEV"; then - USBDEV=${device}1 - else - USBDEV=${device} - fi # Sometimes automount can be _really_ annoying. echo "Waiting for devices to settle..." /sbin/udevadm settle sleep 5 + if ! isdevloop "$DEV"; then + getpartition ${device#/dev/} + USBDEV=${device}${partnum} + else + USBDEV=${device} + fi umount $USBDEV &> /dev/null /sbin/mkdosfs -n LIVE $USBDEV USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)" @@ -214,11 +223,12 @@ createEXTFSLayout() { partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit b print" |grep ^$device:) size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//') /sbin/parted --script $device unit b mkpart primary ext2 17408 $(($size - 17408)) set 1 boot on - USBDEV=${device}1 # Sometimes automount can be _really_ annoying. echo "Waiting for devices to settle..." /sbin/udevadm settle sleep 5 + getpartition ${device#/dev/} + USBDEV=${device}${partnum} umount $USBDEV &> /dev/null /sbin/mkfs.ext4 -L LIVE $USBDEV USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
commit 5c26c27c99af9a7721540c2a00fe06957da5991b Author: Frederick Grose fgrose@gmail.com Date: Mon Nov 29 17:11:03 2010 -0800
Fix disk space estimation errors (#656154)
Include /syslinux and /EFI/boot folders in the estimate, use du --apparent-size for the --skipcompression install option, protect df from failing due to mountpoints with '\n' in their name, and format the size report for better readability.
diff --git a/tools/livecd-iso-to-disk.sh b/tools/livecd-iso-to-disk.sh index d3f0ba7..cc2c012 100755 --- a/tools/livecd-iso-to-disk.sh +++ b/tools/livecd-iso-to-disk.sh @@ -571,18 +571,27 @@ if [ -d $CDMNT/LiveOS ]; then else check=$CDMNT fi -if [ -d $USBMNT/$LIVEOS ]; then - tbd=$(du -s -B 1M $USBMNT/$LIVEOS | awk {'print $1;'}) - [ -f $USBMNT/$LIVEOS/$HOMEFILE ] && homesz=$(du -s -B 1M $USBMNT/$LIVEOS/$HOMEFILE | awk {'print $1;'}) - [ -n "$homesz" -a -n "$keephome" ] && tbd=$(($tbd - $homesz)) +if [[ -d $USBMNT/$LIVEOS ]]; then + tbd=($(du -B 1M $USBMNT/$LIVEOS)) + [[ -s $USBMNT/$LIVEOS/$HOMEFILE ]] && \ + homesize=($(du -B 1M $USBMNT/$LIVEOS/$HOMEFILE)) + ((homesize > 0)) && [[ -n $keephome ]] && ((tbd -= homesize)) else tbd=0 fi -livesize=$(du -s -B 1M $check | awk {'print $1;'}) -if [ -n "$skipcompress" ]; then - if [ -e $CDMNT/LiveOS/squashfs.img ]; then +targets="$USBMNT/$SYSLINUXPATH" +if [[ -n $efi ]]; then + targets+=" $USBMNT/EFI/boot" +fi +duTable=($(du -c -B 1M $targets 2> /dev/null)) +((tbd += ${duTable[*]: -2:1})) + +sources="$CDMNT/isolinux" +[[ -n $efi ]] && sources+=" $CDMNT/EFI/boot" +if [[ -n $skipcompress ]]; then + if [[ -s $CDMNT/LiveOS/squashfs.img ]]; then if mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT; then - livesize=$(du -s -B 1M $CDMNT/LiveOS/ext3fs.img | awk {'print $1;'}) + livesize=($(du -B 1M --apparent-size $CDMNT/LiveOS/ext3fs.img)) umount $CDMNT else echo "WARNING: --skipcompress or --xo was specified but the currently" @@ -591,22 +600,37 @@ if [ -n "$skipcompress" ]; then skipcompress="" fi fi + duTable=($(du -c -B 1M $sources 2> /dev/null)) + ((livesize += ${duTable[*]: -2:1})) +else + sources+=" $check/osmin.img $check/squashfs.img" + duTable=($(du -c -B 1M $sources 2> /dev/null)) + livesize=${duTable[*]: -2:1} fi -free=$(df -B1M $USBDEV |tail -n 1 |awk {'print $4;'}) + +freespace=($(df -B 1M --total $USBDEV)) +freespace=${freespace[*]: -2:1}
if [ "$isotype" = "live" ]; then - tba=$(($overlaysizemb + $homesizemb + $livesize + $swapsizemb)) - if [ $tba -gt $(($free + $tbd)) ]; then - echo "Unable to fit live image + overlay on available space on USB stick" - echo "+ Size of live image: $livesize" - [ "$overlaysizemb" -gt 0 ] && echo "+ Overlay size: $overlaysizemb" - [ "$homesizemb" -gt 0 ] && echo "+ Home overlay size: $homesizemb" - [ "$swapsizemb" -gt 0 ] && echo "+ Swap overlay size: $swapsizemb" - echo "---------------------------" - echo "= Requested: $tba" - echo "- Available: $(($free + $tbd))" - echo "---------------------------" - echo "= To fit, free or decrease requested size total by: $(($tba - $free - $tbd))" + tba=$((overlaysizemb + homesizemb + livesize + swapsizemb)) + if ((tba > freespace + tbd)); then + needed=$((tba - freespace - tbd)) + printf "\n The live image + overlay, home, & swap space, if requested, + \r will NOT fit in the space available on the target device.\n + \r + Size of live image: %10s MiB\n" $livesize + (($overlaysizemb > 0)) && \ + printf " + Overlay size: %16s\n" $overlaysizemb + (($homesizemb > 0)) && \ + printf " + Home directory size: %9s\n" $homesizemb + (($swapsizemb > 0)) && \ + printf " + Swap overlay size: %11s\n" $swapsizemb + printf " = Total requested space: %6s MiB\n" $tba + printf " - Space available: %12s\n" $(($free + $tbd)) + printf " ==============================\n" + printf " Space needed: %15s MiB\n\n" $needed + printf " To fit the installation on this device, + \r free space on the target, or decrease the + \r requested size total by: %s MiB\n\n" $needed exitclean fi fi
commit 0f7be207cb23f99d4c2bda4fdc98aa06e8d2c56c Author: Lubomir Rintel lkundrak@v3.sk Date: Sat Nov 20 13:01:24 2010 +0100
Tolerate empty transactions
It can be useful when rebuilding the image without adding or removing a package.
diff --git a/imgcreate/yuminst.py b/imgcreate/yuminst.py index 9e54982..5f3333b 100644 --- a/imgcreate/yuminst.py +++ b/imgcreate/yuminst.py @@ -171,6 +171,10 @@ class LiveCDYum(yum.YumBase): (res, resmsg) = self.buildTransaction() except yum.Errors.RepoError, e: raise CreatorError("Unable to download from repo : %s" %(e,)) + # Empty transactions are generally fine, we might be rebuilding an + # existing image with no packages added + if resmsg and resmsg[0].endswith(" - empty transaction"): + return res if res != 2: raise CreatorError("Failed to build transaction : %s" % str.join("\n", resmsg))
commit 55ae23d6231a2c7e7df29600feb659d9b9652778 Author: Lubomir Rintel lkundrak@v3.sk Date: Sat Nov 20 13:01:07 2010 +0100
Merge livecd-creator and image-creator
image-creator was duplicating a lot of code, while still failing to stay in sync with livecd-creator (not providing useful options, such as tmpdir or cachedir). Make it a link to livecd-creator and determine the image packaging by argv[0].
diff --git a/Makefile b/Makefile index 83880ef..be14e32 100644 --- a/Makefile +++ b/Makefile @@ -22,8 +22,8 @@ man:
install: man $(INSTALL_PROGRAM) -D tools/livecd-creator $(DESTDIR)/usr/bin/livecd-creator + ln $(DESTDIR)/usr/bin/livecd-creator $(DESTDIR)/usr/bin/image-creator $(INSTALL_PROGRAM) -D tools/liveimage-mount $(DESTDIR)/usr/bin/liveimage-mount - $(INSTALL_PROGRAM) -D tools/image-creator $(DESTDIR)/usr/bin/image-creator $(INSTALL_PROGRAM) -D tools/livecd-iso-to-disk.sh $(DESTDIR)/usr/bin/livecd-iso-to-disk $(INSTALL_PROGRAM) -D tools/livecd-iso-to-pxeboot.sh $(DESTDIR)/usr/bin/livecd-iso-to-pxeboot $(INSTALL_PROGRAM) -D tools/mkbiarch.py $(DESTDIR)/usr/bin/mkbiarch diff --git a/tools/image-creator b/tools/image-creator deleted file mode 100755 index 6f2604c..0000000 --- a/tools/image-creator +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/python -tt -# -# image-creator: Create an ext3 system image -# -# Copyright 2007, Red Hat Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU 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. - -import os -import sys -import shutil -import optparse -import logging - -import imgcreate - -def parse_options(args): - parser = optparse.OptionParser(usage = "%prog [--name=<name>] <kickstart>") - - parser.add_option("-n", "--name", type="string", dest="name", - help="Image name and filesystem label") - - imgcreate.setup_logging(parser) - - (options, args) = parser.parse_args() - - if len(args) != 1: - parser.print_usage() - sys.exit(1) - - return (args[0], options) - -def main(): - (kscfg, options) = parse_options(sys.argv[1:]) - - if os.geteuid () != 0: - print >> sys.stderr, "You must run image-creator as root" - return 1 - - try: - ks = imgcreate.read_kickstart(kscfg) - except imgcreate.CreatorError, e: - logging.error("Unable to load kickstart file '%s' : %s" % (kscfg, e)) - return 1 - - if options.name: - name = options.name - else: - name = imgcreate.build_name(kscfg) - - creator = imgcreate.LoopImageCreator(ks, name) - - try: - creator.create() - except imgcreate.CreatorError, e: - logging.error("Unable to create image : %s" % e) - return 1 - finally: - creator.cleanup() - - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/livecd-creator b/tools/livecd-creator index d352d74..4ec5fc3 100755 --- a/tools/livecd-creator +++ b/tools/livecd-creator @@ -41,6 +41,11 @@ def parse_options(args): help="Add packages to an existing live CD iso9660 image.") imgopt.add_option("-f", "--fslabel", type="string", dest="fs_label", help="File system label (default based on config name)") + # Provided for img-create compatibility + imgopt.add_option("-n", "--name", type="string", dest="fs_label", + help=optparse.SUPPRESS_HELP) + imgopt.add_option("", "--image-type", type="string", dest="image_type", + help=optparse.SUPPRESS_HELP) imgopt.add_option("", "--compression-type", type="string", dest="compress_type", help="Compression type recognized by mksquashfs (default gzip, lzma needs custom kernel, lzo needs a 2.6.36+ kernel)", default="gzip") @@ -70,14 +75,31 @@ def parse_options(args): help=optparse.SUPPRESS_HELP)
(options, args) = parser.parse_args() + + # Pretend to be a image-creator if called with that name + if not options.image_type: + if sys.argv[0].endswith('image-creator'): + options.image_type = 'image' + else: + options.image_type = 'livecd' + if options.image_type not in ('livecd', 'image'): + raise Usage("'%s' is a recognized image type" % options.image_type) + + # image-create compatibility: Last argument is kickstart file + if len(args) == 1: + options.kscfg = args.pop() + if len(args): + raise Usage("Extra arguments given") + if not options.kscfg: raise Usage("Kickstart file must be provided") if options.base_on and not os.path.isfile(options.base_on): - raise Usage("Live CD ISO '%s' does not exist" %(options.base_on,)) - if options.fs_label and len(options.fs_label) > imgcreate.FSLABEL_MAXLEN: - raise Usage("CD labels are limited to 32 characters") - if options.fs_label and options.fs_label.find(" ") != -1: - raise Usage("CD labels cannot contain spaces.") + raise Usage("Image file '%s' does not exist" %(options.base_on,)) + if options.image_type == 'livecd': + if options.fs_label and len(options.fs_label) > imgcreate.FSLABEL_MAXLEN: + raise Usage("CD labels are limited to 32 characters") + if options.fs_label and options.fs_label.find(" ") != -1: + raise Usage("CD labels cannot contain spaces.")
return options
@@ -96,17 +118,17 @@ def main(): return ret
if os.geteuid () != 0: - print >> sys.stderr, "You must run livecd-creator as root" + print >> sys.stderr, "You must run %s as root" % sys.argv[0] return 1
if options.fs_label: fs_label = options.fs_label name = fs_label else: - name = imgcreate.build_name(options.kscfg, "livecd-") + name = imgcreate.build_name(options.kscfg, options.image_type + "-")
fs_label = imgcreate.build_name(options.kscfg, - "livecd-", + options.image_type + "-", maxlen = imgcreate.FSLABEL_MAXLEN, suffix = "%s-%s" %(os.uname()[4], time.strftime("%Y%m%d%H%M")))
@@ -114,7 +136,15 @@ def main():
ks = imgcreate.read_kickstart(options.kscfg)
- creator = imgcreate.LiveImageCreator(ks, name, fs_label) + if options.image_type == 'livecd': + creator = imgcreate.LiveImageCreator(ks, name, fs_label) + elif options.image_type == 'image': + creator = imgcreate.LoopImageCreator(ks, name, fs_label) + else: + # Cannot happen, we validate this when parsing options. + logging.error(u"'%s' is not a valid image type" % options.image_type) + return 1 + creator.tmpdir = os.path.abspath(options.tmpdir) creator.compress_type = options.compress_type creator.skip_compression = options.skip_compression