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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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