imgcreate/creator.py | 14 +++- imgcreate/live.py | 131 ++++++++++++++++++++++++++++---------------- tools/livecd-creator | 9 ++- tools/livecd-iso-to-disk.sh | 26 +++++--- 4 files changed, 120 insertions(+), 60 deletions(-)
New commits: commit 7b2cb0aa6233b881d3d97f78f48d4ff3cba66d3c Author: Brian C. Lane bcl@redhat.com Date: Wed Sep 5 15:47:49 2012 -0700
fix extra-kernel-args (#853570)
diff --git a/tools/livecd-iso-to-disk.sh b/tools/livecd-iso-to-disk.sh index cd9a89c..c681e37 100755 --- a/tools/livecd-iso-to-disk.sh +++ b/tools/livecd-iso-to-disk.sh @@ -1192,9 +1192,9 @@ echo "Updating boot config file" # adjust label and fstype sed -i -e "s/CDLABEL=[^ ]*/$TGTLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$TGTFS/" -e "s/LABEL=[^ ]*/$TGTLABEL/" $BOOTCONFIG $BOOTCONFIG_EFI if [ -n "$kernelargs" ]; then - sed -i -e "s;initrd.img;initrd.img ${kernelargs};" $BOOTCONFIG + sed -i -e "s;initrd.?.img;& ${kernelargs};" $BOOTCONFIG if [ -n "$efi" ]; then - sed -i -e "s;vmlinuz;vmlinuz ${kernelargs};" $BOOTCONFIG_EFI + sed -i -e "s;vmlinuz.?;& ${kernelargs} ;" $BOOTCONFIG_EFI fi fi if [ "$LIVEOS" != "LiveOS" ]; then
commit 0e88402b4418e1edb4a4a7622e0dbac335ae1be0 Author: Brian C. Lane bcl@redhat.com Date: Wed Sep 5 14:58:59 2012 -0700
New location for GRUB2 config on UEFI (#851220)
With Secure Boot and shim the GRUB2 config is no grub.cfg
diff --git a/tools/livecd-iso-to-disk.sh b/tools/livecd-iso-to-disk.sh index 71fb288..cd9a89c 100755 --- a/tools/livecd-iso-to-disk.sh +++ b/tools/livecd-iso-to-disk.sh @@ -1089,14 +1089,20 @@ BOOTCONFIG=$TGTMNT/$SYSLINUXPATH/isolinux.cfg BOOTCONFIG_EFI= if [ -n "$efi" ]; then echo "Setting up $EFI_BOOT" - cp $SRCMNT$EFI_BOOT/* $TGTMNT$EFI_BOOT - - # FIXME - # There is a problem here. On older LiveCD's the files are boot?*.conf - # They really should be renamed to BOOT?*.conf - - # this is a little ugly, but it gets the "interesting" named config file - BOOTCONFIG_EFI=$TGTMNT$EFI_BOOT/+(BOOT|boot)?*.conf + cp -a $SRCMNT$EFI_BOOT/* $TGTMNT$EFI_BOOT + + # The GRUB EFI config file can be one of: + # boot?*.conf + # BOOT?*.conf + # grub.cfg + if [ -e $TGTMNT$EFI_BOOT/grub.cfg ]; then + BOOTCONFIG_EFI=$TGTMNT$EFI_BOOT/grub.cfg + elif [ -e $TGTMNT$EFI_BOOT/+(BOOT|boot)?*.conf ]; then + BOOTCONFIG_EFI=$TGTMNT$EFI_BOOT/+(BOOT|boot)?*.conf + else + echo "Unable to find EFI config file." + exitclean + fi rm -f $TGTMNT$EFI_BOOT/grub.conf
# On some images (RHEL) the BOOT*.efi file isn't in $EFI_BOOT, but is in
commit c7743ab6ed95b743bbeba2738e197726dfc9c043 Author: Brian C. Lane bcl@redhat.com Date: Wed Aug 29 10:04:02 2012 -0700
Add nocleanup option to retain temp files
diff --git a/imgcreate/creator.py b/imgcreate/creator.py index 77b6e56..891d6ef 100644 --- a/imgcreate/creator.py +++ b/imgcreate/creator.py @@ -51,7 +51,8 @@ class ImageCreator(object):
"""
- def __init__(self, ks, name, releasever=None, tmpdir="/tmp", useplugins=False, cacheonly=False): + def __init__(self, ks, name, releasever=None, tmpdir="/tmp", useplugins=False, + cacheonly=False, docleanup=True): """Initialize an ImageCreator instance.
ks -- a pykickstart.KickstartParser instance; this instance will be @@ -82,6 +83,7 @@ class ImageCreator(object): makedirs(self.tmpdir)
self.cacheonly = cacheonly + self.docleanup = docleanup
self.__builddir = None self.__bindmounts = [] @@ -557,6 +559,10 @@ class ImageCreator(object): creator.cleanup()
""" + if not self.docleanup: + logging.warn("Skipping cleanup of temporary files") + return + if not self.__builddir: return
@@ -784,7 +790,8 @@ class LoopImageCreator(ImageCreator):
"""
- def __init__(self, ks, name, fslabel=None, releasever=None, tmpdir="/tmp", useplugins=False, cacheonly=False): + def __init__(self, ks, name, fslabel=None, releasever=None, tmpdir="/tmp", + useplugins=False, cacheonly=False, docleanup=True): """Initialize a LoopImageCreator instance.
This method takes the same arguments as ImageCreator.__init__() with @@ -793,7 +800,8 @@ class LoopImageCreator(ImageCreator): fslabel -- A string used as a label for any filesystems created.
""" - ImageCreator.__init__(self, ks, name, releasever=releasever, tmpdir=tmpdir, useplugins=useplugins, cacheonly=cacheonly) + ImageCreator.__init__(self, ks, name, releasever=releasever, tmpdir=tmpdir, + useplugins=useplugins, cacheonly=cacheonly, docleanup=docleanup)
self.__fslabel = None self.fslabel = fslabel diff --git a/imgcreate/live.py b/imgcreate/live.py index 67f53af..73e3466 100755 --- a/imgcreate/live.py +++ b/imgcreate/live.py @@ -16,6 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+import sys import os import os.path import glob @@ -40,7 +41,8 @@ class LiveImageCreatorBase(LoopImageCreator): """
def __init__(self, ks, name, fslabel=None, releasever=None, tmpdir="/tmp", - title="Linux", product="Linux", useplugins=False, cacheonly=False): + title="Linux", product="Linux", useplugins=False, cacheonly=False, + docleanup=True): """Initialise a LiveImageCreator instance.
This method takes the same arguments as LoopImageCreator.__init__(). @@ -50,7 +52,9 @@ class LiveImageCreatorBase(LoopImageCreator): fslabel=fslabel, releasever=releasever, tmpdir=tmpdir, - useplugins=useplugins, cacheonly=cacheonly) + useplugins=useplugins, + cacheonly=cacheonly, + docleanup=docleanup)
self.compress_type = "xz" """mksquashfs compressor to use.""" diff --git a/tools/livecd-creator b/tools/livecd-creator index e9be1e5..44d07a1 100755 --- a/tools/livecd-creator +++ b/tools/livecd-creator @@ -78,6 +78,9 @@ def parse_options(args): sysopt.add_option("", "--cacheonly", action="store_true", dest="cacheonly", default=False, help="Work offline from cache, use together with --cache (default: False)") + sysopt.add_option("", "--nocleanup", action="store_true", + dest="nocleanup", default=False, + help="Skip cleanup of temporary files")
parser.add_option_group(sysopt)
@@ -180,14 +183,16 @@ def main(): tmpdir=os.path.abspath(options.tmpdir), useplugins=options.plugins, title=title, product=product, - cacheonly=options.cacheonly) + cacheonly=options.cacheonly, + docleanup=not options.nocleanup) elif options.image_type == 'image': creator = imgcreate.LoopImageCreator(ks, name, fslabel=fslabel, releasever=options.releasever, useplugins=options.plugins, tmpdir=os.path.abspath(options.tmpdir), - cacheonly=options.cacheonly) + cacheonly=options.cacheonly, + docleanup=not options.nocleanup) else: # Cannot happen, we validate this when parsing options. logging.error(u"'%s' is not a valid image type" % options.image_type)
commit bc47ee3f54445acce090554b9ea2aaa80631d2e0 Author: Brian C. Lane bcl@redhat.com Date: Tue Aug 28 15:19:46 2012 -0700
Update imgcreate for UEFI Secure Boot
diff --git a/imgcreate/live.py b/imgcreate/live.py index 4aa220e..67f53af 100755 --- a/imgcreate/live.py +++ b/imgcreate/live.py @@ -1,7 +1,7 @@ # # live.py : LiveImageCreator class for creating Live CD images # -# Copyright 2007, Red Hat Inc. +# Copyright 2007-2012, 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 @@ -117,7 +117,7 @@ class LiveImageCreatorBase(LoopImageCreator): if os.path.exists(self._instroot + "/usr/bin/plymouth"): r += " rhgb" return r - + def _get_mkisofs_options(self, isodir): """Return the architecture specific mkisosfs options.
@@ -230,8 +230,11 @@ class LiveImageCreatorBase(LoopImageCreator):
def _generate_efiboot(self, isodir): """Generate EFI boot images.""" - if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"): - return False + if not glob.glob(self._instroot+"/boot/efi/EFI/*/shim.efi"): + logging.error("Missing shim.efi, skipping efiboot.img creation.") + return + + # XXX-BCL: does this need --label? subprocess.call(["mkefiboot", isodir + "/EFI/BOOT", isodir + "/isolinux/efiboot.img"]) subprocess.call(["mkefiboot", "-a", isodir + "/EFI/BOOT", @@ -297,7 +300,7 @@ class LiveImageCreatorBase(LoopImageCreator): f = open(path, "a") f.write('filesystems+="' + self.__extra_filesystems() + ' "\n') f.write('drivers+="' + self.__extra_drivers() + ' "\n') - f.write('add_dracutmodules+=" dmsquash-live "') + f.write('add_dracutmodules+=" dmsquash-live pollcdrom "') f.close()
def __create_iso(self, isodir): @@ -335,7 +338,7 @@ class LiveImageCreatorBase(LoopImageCreator): else: logging.warn("isomd5sum not installed; not setting up mediacheck") return - + subprocess.call([implantisomd5, iso])
def _stage_final_image(self): @@ -374,6 +377,10 @@ class LiveImageCreatorBase(LoopImageCreator):
class x86LiveImageCreator(LiveImageCreatorBase): """ImageCreator for x86 machines""" + def __init__(self, *args, **kwargs): + LiveImageCreatorBase.__init__(self, *args, **kwargs) + self._efiarch = None + def _get_mkisofs_options(self, isodir): options = [ "-b", "isolinux/isolinux.bin", "-c", "isolinux/boot.cat", @@ -389,7 +396,8 @@ class x86LiveImageCreator(LiveImageCreatorBase): return options
def _get_required_packages(self): - return ["syslinux"] + LiveImageCreatorBase._get_required_packages(self) + return ["syslinux", "grub2-efi", "shim"] \ + + LiveImageCreatorBase._get_required_packages(self)
def _get_isolinux_stanzas(self, isodir): return "" @@ -690,26 +698,65 @@ menu end cfgf.write(cfg) cfgf.close()
- def __copy_efi_files(self, isodir): - if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"): - return False - shutil.copy(self._instroot + "/boot/efi/EFI/redhat/grub.efi", - isodir + "/EFI/BOOT/grub.efi") + @property + def efiarch(self): + if not self._efiarch: + # for most things, we want them named boot$efiarch + efiarch = {"i386": "IA32", "x86_64": "X64"} + self._efiarch = efiarch[rpmUtils.arch.getBaseArch()] + return self._efiarch
- # Should exist, but if it doesn't we should fail - if os.path.exists(self._instroot + "/boot/grub/splash.xpm.gz"): - shutil.copy(self._instroot + "/boot/grub/splash.xpm.gz", - isodir + "/EFI/BOOT/splash.xpm.gz") - - return True + def __copy_efi_files(self, isodir): + """ Copy the efi files into /EFI/BOOT/ + If any of them are missing, return False. + requires: + shim.efi + gcdx64.efi + fonts/unicode.pf2 + grub/splash.xpm.gz + """ + fail = False + missing = [] + files = [("/boot/efi/EFI/*/shim.efi", "/EFI/BOOT/BOOT%s.efi" % (self.efiarch,)), + ("/boot/efi/EFI/*/gcdx64.efi", "/EFI/BOOT/grubx64.efi"), + ("/boot/efi/EFI/*/fonts/unicode.pf2", "/EFI/BOOT/fonts/"), + ("/boot/grub/splash.xpm.gz", "/EFI/BOOT"), + ] + makedirs(isodir+"/EFI/BOOT/fonts/") + for src, dest in files: + src_glob = glob.glob(self._instroot+src) + if not src_glob: + missing.append("Missing EFI file (%s)" % (src,)) + fail = True + else: + shutil.copy(src_glob[0], isodir+dest) + map(logging.error, missing) + return fail
def __get_basic_efi_config(self, **args): return """ -default=0 -splashimage=/EFI/BOOT/splash.xpm.gz -timeout %(timeout)d -hiddenmenu +set default="0" + +function load_video { + insmod efi_gop + insmod efi_uga + insmod video_bochs + insmod video_cirrus + insmod all_video +} + +load_video +set gfxpayload=keep +insmod gzio +insmod part_gpt +insmod ext2 + +set timeout=%(timeout)d +### END /etc/grub.d/00_header ### + +search --no-floppy --set=root -l '%(isolabel)s'
+### BEGIN /etc/grub.d/10_linux ### """ %args
def __get_efi_image_stanza(self, **args): @@ -717,10 +764,10 @@ hiddenmenu args["rootlabel"] = "live:LABEL=%(fslabel)s" % args else: args["rootlabel"] = "CDLABEL=%(fslabel)s" % args - return """title %(long)s - findiso - kernel /isolinux/vmlinuz%(index)s root=%(rootlabel)s rootfstype=%(isofstype)s %(liveargs)s %(extra)s - initrd /isolinux/initrd%(index)s.img + return """menuentry '%(long)s' --class fedora --class gnu-linux --class gnu --class os { + linuxefi /isolinux/vmlinuz%(index)s root=%(rootlabel)s %(liveargs)s %(extra)s + initrdefi /isolinux/initrd%(index)s.img +} """ %args
def __get_efi_image_stanzas(self, isodir, name): @@ -736,13 +783,11 @@ hiddenmenu if os.path.exists("%s/EFI/BOOT/xen%d.gz" %(isodir, index)): continue cfg += self.__get_efi_image_stanza(fslabel = self.fslabel, - isofstype = "auto", liveargs = kernel_options, long = name, extra = "", index = index) if checkisomd5: cfg += self.__get_efi_image_stanza(fslabel = self.fslabel, - isofstype = "auto", liveargs = kernel_options, long = "Verify and Boot " + name, extra = "rd.live.check", @@ -753,30 +798,22 @@ hiddenmenu
def _configure_efi_bootloader(self, isodir): """Set up the configuration for an EFI bootloader""" - makedirs(isodir + "/EFI/BOOT") - - if not self.__copy_efi_files(isodir): + if self.__copy_efi_files(isodir): shutil.rmtree(isodir + "/EFI") - return + raise CreatorError("Failed to copy EFI files")
- cfg = self.__get_basic_efi_config(name = self.name, + cfg = self.__get_basic_efi_config(isolabel = self.fslabel, timeout = self._timeout) cfg += self.__get_efi_image_stanzas(isodir, self.name)
- cfgf = open(isodir + "/EFI/BOOT/grub.conf", "w") + cfgf = open(isodir + "/EFI/BOOT/grub.cfg", "w") cfgf.write(cfg) cfgf.close()
# first gen mactel machines get the bootloader name wrong apparently if rpmUtils.arch.getBaseArch() == "i386": - os.link(isodir + "/EFI/BOOT/grub.efi", isodir + "/EFI/BOOT/BOOT.efi") - os.link(isodir + "/EFI/BOOT/grub.conf", isodir + "/EFI/BOOT/BOOT.conf") - - # for most things, we want them named boot$efiarch - efiarch = {"i386": "IA32", "x86_64": "X64"} - efiname = efiarch[rpmUtils.arch.getBaseArch()] - os.rename(isodir + "/EFI/BOOT/grub.efi", isodir + "/EFI/BOOT/BOOT%s.efi" %(efiname,)) - os.link(isodir + "/EFI/BOOT/grub.conf", isodir + "/EFI/BOOT/BOOT%s.conf" %(efiname,)) + os.link(isodir + "/EFI/BOOT/BOOT%s.efi" % (self.efiarch), + isodir + "/EFI/BOOT/BOOT.efi")
def _configure_bootloader(self, isodir): @@ -805,7 +842,7 @@ class ppcLiveImageCreator(LiveImageCreatorBase): path = self._instroot + dir + "/" + file if not os.path.exists(path): continue - + makedirs(destdir) shutil.copy(path, destdir) return
livecd@lists.fedoraproject.org