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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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


--
livecd mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/livecd

Reply via email to