X-Git-Url: http://git.grml.org/?p=grml2usb.git;a=blobdiff_plain;f=grml2usb;h=479f590f36302d0837925b56c798089dac639148;hp=eb13a0717cc07b41a44ec10fa1d53ea23578cb47;hb=a985bb5b68d8520bc22e35f247e4afbe7bb0c1f4;hpb=189791042c86bda34541e773b056ee00fcd2e0f8 diff --git a/grml2usb b/grml2usb index eb13a07..479f590 100755 --- a/grml2usb +++ b/grml2usb @@ -17,14 +17,27 @@ from optparse import OptionParser from inspect import isroutine, isclass import datetime, logging, os, re, subprocess, sys, tempfile, time, os.path import fileinput +import glob +import uuid # global variables -PROG_VERSION = "0.9.13-pre1" +PROG_VERSION = "0.9.22" MOUNTED = set() # register mountpoints TMPFILES = set() # register tmpfiles DATESTAMP = time.mktime(datetime.datetime.now().timetuple()) # unique identifier for syslinux.cfg GRML_FLAVOURS = set() # which flavours are being installed? -global GRML_DEFAULT +GRML_DEFAULT = None +UUID = None + +def syslinux_warning(option, opt, value, parser): + sys.stderr.write("Note: the --syslinux option is deprecated as syslinux " + + "is grml2usb's default. Continuing anyway.\n") + setattr(parser.values, option.dest, True) + +# if grub option is set, unset syslinux option +def grub_option(option, opt, value, parser): + setattr(parser.values, option.dest, True) + setattr(parser.values, 'syslinux', False) # cmdline parsing USAGE = "Usage: %prog [options] <[ISO[s] | /live/image]> \n\ @@ -50,7 +63,8 @@ parser.add_option("--fat16", dest="fat16", action="store_true", help="format specified partition with FAT16") parser.add_option("--force", dest="force", action="store_true", help="force any actions requiring manual interaction") -parser.add_option("--grub", dest="grub", action="store_true", +parser.add_option("--grub", dest="grub", action="callback", + callback=grub_option, help="install grub bootloader instead of (default) syslinux") parser.add_option("--grub-mbr", dest="grubmbr", action="store_true", help="install grub into MBR instead of (default) PBR") @@ -60,6 +74,8 @@ parser.add_option("--mbr-menu", dest="mbrmenu", action="store_true", help="enable interactive boot menu in MBR") parser.add_option("--quiet", dest="quiet", action="store_true", help="do not output anything but just errors on console") +parser.add_option("--remove-bootoption", dest="removeoption", action="append", + help="regex for removing existing bootoptions") parser.add_option("--skip-addons", dest="skipaddons", action="store_true", help="do not install /boot/addons/ files") parser.add_option("--skip-grub-config", dest="skipgrubconfig", action="store_true", @@ -68,7 +84,8 @@ parser.add_option("--skip-mbr", dest="skipmbr", action="store_true", help="do not install a master boot record (MBR) on the device") parser.add_option("--skip-syslinux-config", dest="skipsyslinuxconfig", action="store_true", help="skip generation of syslinux configuration files") -parser.add_option("--syslinux", dest="syslinux", action="store_true", +parser.add_option("--syslinux", dest="syslinux", action="callback", default=True, + callback=syslinux_warning, help="install syslinux bootloader (deprecated as it's the default)") parser.add_option("--syslinux-mbr", dest="syslinuxmbr", action="store_true", help="install syslinux master boot record (MBR) instead of default") @@ -289,8 +306,8 @@ fi menuentry "%(grml_flavour)s (default)" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } menuentry "Memory test (memtest86+)" { @@ -325,7 +342,8 @@ menuentry "Boot OS of first partition on first disk" { } """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, - 'bootoptions': bootoptions } ) + 'flavour_filename': grml_flavour.replace('-', ''), + 'uid': UUID, 'bootoptions': bootoptions } ) def generate_flavour_specific_grub2_config(grml_flavour, bootoptions): @@ -340,59 +358,60 @@ def generate_flavour_specific_grub2_config(grml_flavour, bootoptions): ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s - boot in default mode" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s-persistent - enable persistency feature" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet persistent live-media-path=/live/%(grml_flavour)s/ bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s2ram - copy compressed grml file to RAM" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s-debug - enable debugging options" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug%(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ debug bootid=%(uid)s initcall_debug %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s-x - start X Window System" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s-nofb - disable framebuffer" { - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s-failsafe - disable hardware detection" { - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] menuentry "%(grml_flavour)s-forensic - do not touch harddisks during hw recognition" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s - initrd /boot/release/%(grml_flavour)s/initrd.gz + linux /boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly bootid=%(uid)s %(bootoptions)s + initrd /boot/release/%(flavour_filename)s/initrd.gz } """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, - 'bootoptions': bootoptions } ) + 'flavour_filename': grml_flavour.replace('-', ''), + 'uid': UUID, 'bootoptions': bootoptions } ) def generate_flavour_specific_grub1_config(grml_flavour, install_partition, bootoptions): @@ -407,50 +426,51 @@ def generate_flavour_specific_grub1_config(grml_flavour, install_partition, boot return("""\ ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-persistent -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet persistent live-media-path=/live/%(grml_flavour)s/ bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s2ram -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-debug -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug%(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-x -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-nofb -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-failsafe -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off pci=nomsi bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-forensic -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect forensic readonly bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz ## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s] title %(grml_flavour)s-serial -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, + 'flavour_filename': grml_flavour.replace('-', ''), 'uid': UUID, 'bootoptions': bootoptions, 'install_partition': install_partition } ) @@ -472,8 +492,8 @@ background = FFCC33 # define entries: title %(grml_flavour)s - Default boot (using 1024x768 framebuffer) -kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s -initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz +kernel (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/linux26 apm=power-off vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ bootid=%(uid)s %(bootoptions)s +initrd (hd0,%(install_partition)s)/boot/release/%(flavour_filename)s/initrd.gz title Memory test (memtest86+) kernel (hd0,%(install_partition)s)/boot/addons/memtest @@ -490,6 +510,7 @@ title MirOS BSD kernel (hd0,%(install_partition)s)/boot/addons/bsd4grml/ldbsd.com """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, + 'flavour_filename': grml_flavour.replace('-', ''), 'uid': UUID, 'bootoptions': bootoptions, 'install_partition': install_partition } ) @@ -532,8 +553,21 @@ menu label Additional boot entries for: menu disable include additional.cfg +menu separator include options.cfg include addons.cfg + +label help + include promptname.cfg + config prompt.cfg + text help + Jump to old style isolinux prompt + featuring further information + regarding available boot options. + endtext + + +include hiddens.cfg """) @@ -545,16 +579,16 @@ def generate_flavour_specific_syslinux_config(grml_flavour): return("""\ menu begin grml %(grml_flavour)s - menu title %(grml_flavour)s + menu title %(display_name)s label mainmenu menu label ^Back to main menu... menu exit menu separator # include config for boot parameters from disk - include %(grml_flavour)s-grml.cfg + include %(grml_flavour)s_grml.cfg menu hide menu end -""" % {'grml_flavour': grml_flavour } ) +""" % {'grml_flavour': grml_flavour, 'display_name' : grml_flavour.replace('_', '-') } ) def install_grub(device): @@ -630,9 +664,6 @@ def install_bootloader(device): @device: partition where bootloader should be installed to""" # by default we use grub, so install syslinux only on request - if options.syslinux: - logging.info("Note: the --syslinux option is deprecated as syslinux is grml2usb's default. Continuing anyway.") - if options.grub: if not which("grub-install"): logging.critical("Fatal: grub-install not available (please install the grub package or use the --syslinux option)") @@ -922,7 +953,7 @@ def check_for_fat(partition): raise CriticalException("Failed to read device %s" " (wrong UID/permissions or device/directory not present?)" % partition) - if options.syslinux and filesystem != "vfat": + if filesystem != "vfat": raise CriticalException("Partition %s does not contain a FAT16 filesystem. (Use --fat16 or run mkfs.vfat %s)" % (partition, partition)) except OSError: @@ -960,6 +991,30 @@ def exec_rsync(source, target): sys.exit(1) +def write_uuid(target_file): + file = open(target_file, 'w') + uid = str(uuid.uuid4()) + file.write(uid) + file.close() + return uid + + +def get_uuid(target): + conf_target = target + "/conf/" + uuid_file_name = conf_target + "/bootid.txt" + if os.path.isdir(conf_target): + if os.path.isfile(uuid_file_name): + uuid_file = open(uuid_file_name, 'r') + uid = uuid_file.readline().strip() + uuid_file.close() + return uid + else: + return write_uuid(uuid_file_name) + else: + execute(mkdir, conf_target) + return write_uuid(uuid_file_name) + + def copy_system_files(grml_flavour, iso_mount, target): """copy grml's main files (like squashfs, kernel and initrd) to a given target @@ -983,7 +1038,8 @@ def copy_system_files(grml_flavour, iso_mount, target): else: exec_rsync(filesystem_module, squashfs_target + 'filesystem.module') - release_target = target + '/boot/release/' + grml_flavour + + release_target = target + '/boot/release/' + grml_flavour.replace('-', '') execute(mkdir, release_target) kernel = search_file('linux26', iso_mount) @@ -1094,6 +1150,12 @@ def copy_addons(iso_mount, target): else: exec_rsync(memtestimg, addons + 'memtest') + # gpxe.lkrn + gpxeimg = search_file('gpxe.lkrn', iso_mount) + if gpxeimg is None: + logging.warn("Warning: gpxe.lkrn not found (that's fine if you don't need it)") + else: + exec_rsync(gpxeimg, addons + 'gpxe.lkrn') def copy_bootloader_files(iso_mount, target): """copy grml's bootloader files to a given target @@ -1107,8 +1169,10 @@ def copy_bootloader_files(iso_mount, target): logo = search_file('logo.16', iso_mount) exec_rsync(logo, syslinux_target + 'logo.16') - for ffile in 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10': + for ffile in ['f%d' % number for number in range(1,11) ]: bootsplash = search_file(ffile, iso_mount) + if not bootsplash: + continue exec_rsync(bootsplash, syslinux_target + ffile) # avoid the "file is read only, overwrite anyway (y/n) ?" question @@ -1116,17 +1180,36 @@ def copy_bootloader_files(iso_mount, target): if os.path.isfile(syslinux_target + 'ldlinux.sys'): os.unlink(syslinux_target + 'ldlinux.sys') - if not search_file('default.cfg', iso_mount + '/boot/isolinux/'): + bootloader_dirs = ['/boot/isolinux/', '/boot/syslinux/'] + source_dir = None + for dir in bootloader_dirs: + if glob.glob(iso_mount + dir + '*default.cfg'): + source_dir = dir + break + else: logging.critical("Fatal: file default.cfg could not be found.") logging.critical("Note: this grml2usb version requires an ISO generated by grml-live >=0.9.24 ...") logging.critical(" ... either use grml releases >=2009.10 or switch to an older grml2usb version.") + logging.critical(" Please visit http://grml.org/grml2usb/#grml2usb-compat for further information.") raise - for filename in 'addons.cfg', 'default.cfg', 'distri.cfg', 'hidden.cfg', \ - 'grml.cfg', 'grml.png', 'hd.cfg', 'isoprompt.cfg', 'options.cfg', \ - 'vesamenu.c32', 'vesamenu.cfg', 'grml.png': - path = search_file(filename, iso_mount + '/boot/isolinux/') - exec_rsync(path, syslinux_target + filename) + for expr in '*default.cfg', 'distri.cfg', \ + '*grml.cfg', 'grml.png', 'hd.cfg', 'isolinux.cfg', 'isolinux.bin', \ + 'isoprompt.cfg', 'options.cfg', \ + 'prompt.cfg', 'vesamenu.c32', 'vesamenu.cfg', 'grml.png': + files = glob.glob(iso_mount + source_dir + expr) + for path in files: + filename = os.path.basename(path) + exec_rsync(path, syslinux_target + filename) + + # copy the addons_*.cfg file to the new syslinux directory + for filename in glob.glob(iso_mount + source_dir + 'addon*.cfg'): + exec_rsync(filename, syslinux_target) + + path = search_file('hidden.cfg', iso_mount + source_dir) + if path: + exec_rsync(path, syslinux_target + "new_" + 'hidden.cfg') + grub_target = target + '/boot/grub/' execute(mkdir, grub_target) @@ -1146,6 +1229,15 @@ def copy_bootloader_files(iso_mount, target): if os.path.isfile("/usr/share/grub/ascii.pf2"): exec_rsync('/usr/share/grub/ascii.pf2', grub_target + 'ascii.pf2') + # always copy grub content as it might be useful + for file in glob.glob(iso_mount + '/boot/grub/*.mod'): + exec_rsync(file, grub_target) + + for file in glob.glob(iso_mount + '/boot/grub/*.img'): + exec_rsync(file, grub_target) + + for file in glob.glob(iso_mount + '/boot/grub/stage*'): + exec_rsync(file, grub_target) def install_iso_files(grml_flavour, iso_mount, device, target): """Copy files from ISO to given target @@ -1160,6 +1252,8 @@ def install_iso_files(grml_flavour, iso_mount, device, target): # * provide alternative search_file() if file information is stored in a config.ini file? # * catch "install: .. No space left on device" & CO + global GRML_DEFAULT + GRML_DEFAULT = grml_flavour if options.dryrun: return 0 elif not options.bootloaderonly: @@ -1172,8 +1266,8 @@ def install_iso_files(grml_flavour, iso_mount, device, target): sys.exit(1) if not options.skipaddons: - if grml_flavour.endswith('-small'): - logging.info("Note: grml-small doesn't provide any addons, not installing them therefore.") + if not search_file('addons', iso_mount): + logging.info("Could not find addons, therefore not installing.") else: copy_addons(iso_mount, target) @@ -1222,6 +1316,23 @@ def identify_grml_flavour(mountpath): return grml_flavour +def modify_grub_config(filename): + if options.removeoption: + regexe = [] + for regex in options.removeoption: + regexe.append(re.compile(r'%s' % regex)) + + option_re = re.compile(r'(.*/boot/release/.*linux26.*)') + + for line in fileinput.input(filename, inplace=1): + if regexe and option_re.search(line): + for regex in regexe: + line = regex.sub(' ', line) + + sys.stdout.write(line) + + fileinput.close() + def handle_grub1_config(grml_flavour, install_partition, grub_target, bootopt): """Main handler for generating grub1 configuration @@ -1260,6 +1371,8 @@ def handle_grub1_config(grml_flavour, install_partition, grub_target, bootopt): grub1_config_file.write(generate_flavour_specific_grub1_config(grml_flavour, install_partition, bootopt)) grub1_config_file.close() + modify_grub_config(grub1_cfg) + # make sure grub.conf isn't a symlink but a plain file instead, # otherwise it will break on FAT16 filesystems # this works around grub-install of (at least) Fedora 10 @@ -1317,6 +1430,8 @@ def handle_grub2_config(grml_flavour, grub_target, bootopt): grub2_config_file.write(generate_flavour_specific_grub2_config(grml_flavour, bootopt)) grub2_config_file.close() + modify_grub_config(grub2_cfg) + def handle_grub_config(grml_flavour, device, target): """Main handler for generating grub (v1 and v2) configuration @@ -1363,12 +1478,29 @@ def initial_syslinux_config(target): data.write(generate_main_syslinux_config()) data.close + filename = target + "hiddens.cfg" + data = open(filename, "w") + data.write("include hidden.cfg\n") + data.close() + +def add_entry_if_not_present(filename, entry): + data = open(filename, "a+") + for line in data: + if line == entry: + break + else: + data.write(entry) + + data.close() + + def adjust_syslinux_bootoptions(src, flavour): append_re = re.compile("^(\s*append.*)$", re.I) boot_re = re.compile("/boot/([a-zA-Z0-9_]+/)+([a-zA-Z0-9._]+)") - flavour_re = re.compile("(label.*)(grml\w+)") + # flavour_re = re.compile("(label.*)(grml\w+)") default_re = re.compile("(default.cfg)") + bootid_re = re.compile("(bootid)=[\w_-]+") # do NOT write "None" in kernel cmdline if options.bootoptions is None: @@ -1376,32 +1508,64 @@ def adjust_syslinux_bootoptions(src, flavour): else: bootopt = options.bootoptions + regexe = [] + option_re = None + if options.removeoption: + option_re = re.compile(r'/boot/release/.*/initrd.gz') + + for regex in options.removeoption: + regexe.append(re.compile(r'%s' % regex)) + + global UUID for line in fileinput.input(src, inplace=1): - line = boot_re.sub(r'/boot/release/%s/\2 ' % flavour, line) - line = flavour_re.sub(r'\1 %s-\2' % flavour, line) + line = boot_re.sub(r'/boot/release/%s/\2 ' % flavour.replace('-', ''), line) + # line = flavour_re.sub(r'\1 %s-\2' % flavour, line) line = default_re.sub(r'%s-\1' % flavour, line) + line = bootid_re.sub(' ', line) line = append_re.sub(r'\1 live-media-path=/live/%s/ ' % flavour, line) line = append_re.sub(r'\1 boot=live %s ' % bootopt, line) - print line + line = append_re.sub(r'\1 %s=%s ' % ("bootid", UUID), line) + if option_re and option_re.search(line): + for regex in regexe: + line = regex.sub(' ', line) + sys.stdout.write(line) + fileinput.close() + +def adjust_labels(src, replacement): + label_re = re.compile("^(\s*label\s*) ([a-zA-Z0-9_-]+)", re.I) + for line in fileinput.input(src, inplace=1): + line = label_re.sub(replacement, line) + sys.stdout.write(line) fileinput.close() def add_syslinux_entry(filename, grml_flavour): - data = open(filename, "a+") - entry_filename = "option-%s.cfg" % grml_flavour + entry_filename = "option_%s.cfg" % grml_flavour entry = "include %s\n" % entry_filename + + add_entry_if_not_present(filename, entry) path = os.path.dirname(filename) - for line in data: - if line == entry: - break - else: - data.write(entry) - data.close() data = open(path + "/" + entry_filename, "w") data.write(generate_flavour_specific_syslinux_config(grml_flavour)) data.close() +def modify_filenames(grml_flavour, target, filenames): + grml_filename = grml_flavour.replace('-', '_') + for filename in filenames: + old_filename = "%s/%s" % (target, filename) + new_filename = "%s/%s_%s" % (target, grml_filename, filename) + os.rename(old_filename, new_filename) + adjust_syslinux_bootoptions(new_filename, grml_flavour) + + +def remove_default_entry(filename): + default_re = re.compile("^(\s*menu\s*default\s*)$", re.I) + for line in fileinput.input(filename, inplace=1): + if default_re.match(line): continue + sys.stdout.write(line) + fileinput.close() + def handle_syslinux_config(grml_flavour, target): """Main handler for generating syslinux configuration @@ -1426,28 +1590,57 @@ def handle_syslinux_config(grml_flavour, target): # install main configuration only *once*, no matter how many ISOs we have: syslinux_flavour_is_default = False syslinux_config_file = open(syslinux_cfg, 'w') - syslinux_config_file.write("include vesamenu.cfg") + syslinux_config_file.write("TIMEOUT 300\n") + syslinux_config_file.write("include vesamenu.cfg\n") syslinux_config_file.close() + prompt_name = open(syslinux_target + 'promptname.cfg', 'w') + prompt_name.write('menu label S^yslinux prompt\n') + prompt_name.close() + initial_syslinux_config(syslinux_target) - for filename in 'grml.cfg', 'default.cfg', 'hidden.cfg': - old_filename = "%s/%s" % (syslinux_target, filename) - new_filename = "%s/%s-%s" % (syslinux_target, grml_flavour, filename) - os.rename(old_filename, new_filename) - adjust_syslinux_bootoptions(new_filename, grml_flavour) + if search_file('default.cfg', syslinux_target): + modify_filenames(grml_flavour, syslinux_target, ['grml.cfg', 'default.cfg']) - new_hidden = "%s-hidden.cfg" % (grml_flavour) - new_default = "%s-default.cfg" % (grml_flavour) - default_file = open("%s/defaults.cfg" % syslinux_target, "a+") - entry = "include %s\n" % new_default - for line in default_file: - if line == entry: - break + filename = search_file("new_hidden.cfg", syslinux_target) + + + flavour_filename = grml_flavour.replace('-', '_') + # process hidden file + if not search_file("hidden.cfg", syslinux_target): + new_hidden = syslinux_target + "hidden.cfg" + os.rename(filename, new_hidden) + adjust_syslinux_bootoptions(new_hidden, grml_flavour) else: - default_file.write("include %s\n" % new_default) + new_hidden = "%s_hidden.cfg" % (flavour_filename) + new_hidden_file = "%s/%s" % (syslinux_target, new_hidden) + os.rename(filename, new_hidden_file) + adjust_labels(new_hidden_file, r'\1 %s-\2' % grml_flavour) + adjust_syslinux_bootoptions(new_hidden_file, grml_flavour) + entry = 'include %s\n' % new_hidden + add_entry_if_not_present("%s/hiddens.cfg" % syslinux_target, entry) + - default_file.close() - add_syslinux_entry("%s/additional.cfg" % syslinux_target, grml_flavour) + + new_default = "%s_default.cfg" % (flavour_filename) + entry = 'include %s\n' % new_default + defaults_file = '%s/defaults.cfg' % syslinux_target + + if os.path.isfile(defaults_file): + new_default_with_path = "%s/%s" % (syslinux_target, new_default) + new_grml_cfg = "%s/%s_grml.cfg" % ( syslinux_target, flavour_filename) + + # remove default menu entry in menu + remove_default_entry(new_default_with_path) + + # adjust all labels for additional isos + adjust_labels(new_default_with_path, r'\1 %s' % grml_flavour) + adjust_labels(new_grml_cfg, r'\1 %s-\2' % grml_flavour) + + + add_entry_if_not_present("%s/defaults.cfg" % syslinux_target, entry) + + add_syslinux_entry("%s/additional.cfg" % syslinux_target, flavour_filename) def handle_bootloader_config(grml_flavour, device, target): @@ -1457,6 +1650,8 @@ def handle_bootloader_config(grml_flavour, device, target): @device: device/partition where bootloader should be installed to @target: path of bootloader's configuration files""" + global UUID + UUID = get_uuid(target) if options.skipsyslinuxconfig: logging.info("Skipping generation of syslinux configuration as requested.") else: @@ -1552,11 +1747,15 @@ def handle_iso(iso, device): register_tmpfile(device_mountpoint) remove_device_mountpoint = True try: - mount(device, device_mountpoint, "") + check_for_fat(device) + mount(device, device_mountpoint, ['-o', 'utf8,iocharset=iso8859-1']) except CriticalException, error: - logging.critical("Fatal: %s", error) - cleanup() - sys.exit(1) + try: + mount(device, device_mountpoint, "") + except CriticalException, error: + logging.critical("Fatal: %s", error) + cleanup() + sys.exit(1) try: try: @@ -1654,7 +1853,7 @@ def handle_vfat(device): # check for vfat filesystem if device is not None and not os.path.isdir(device): try: - check_for_fat(device) + if options.syslinux: check_for_fat(device) except CriticalException, error: logging.critical("Execution failed: %s", error) sys.exit(1) @@ -1719,6 +1918,9 @@ def handle_bootloader(device): def main(): """Main function [make pylint happy :)]""" + global GRML_FLAVOURS + global GRML_DEFAULT + global PROG_VERSION if options.version: print os.path.basename(sys.argv[0]) + " " + PROG_VERSION @@ -1738,6 +1940,10 @@ def main(): if options.dryrun: logging.info("Running in simulation mode as requested via option dry-run.") + if options.grubmbr and not options.grub: + logging.critical("Error: --grub-mbr requires --grub option.") + sys.exit(1) + # specified arguments device = args[len(args) - 1] isos = args[0:len(args) - 1] @@ -1784,6 +1990,7 @@ def main(): # finally be politely :) logging.info("Finished execution of grml2usb (%s). Have fun with your grml system.", PROG_VERSION) + if __name__ == "__main__": try: main()