X-Git-Url: http://git.grml.org/?p=grml2usb.git;a=blobdiff_plain;f=grml2usb;h=bee1012f34422997b39c5025d5355a71dc5ad795;hp=361e6a08107edc256d6f08edcbb4c03f7dd78c11;hb=3330b400c2a0da7762ca5eccc51503cd460db4ae;hpb=3877a01364b2ba0b74fcdb9b9b5ed712a7ac29f7 diff --git a/grml2usb b/grml2usb index 361e6a0..bee1012 100755 --- a/grml2usb +++ b/grml2usb @@ -18,20 +18,27 @@ 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.17-pre1" +PROG_VERSION = "0.9.23" 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\ \n\ @@ -56,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") @@ -218,6 +226,17 @@ def which(program): return None +def get_defaults_file(iso_mount, flavour, name): + """get the default file for syslinux + """ + bootloader_dirs = ['/boot/isolinux/', '/boot/syslinux/'] + for dir in bootloader_dirs: + for name in name, \ + "%s_%s" % (flavour_filename(flavour), name): + if os.path.isfile(iso_mount + dir + name): + return (dir, name) + return ('','') + def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin'): """Given a search path, find file @@ -226,10 +245,18 @@ def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin'): file_found = 0 paths = search_path.split(os.pathsep) current_dir = '' # make pylint happy :) + + def match_file(cwd): + return os.path.exists(os.path.join(cwd, filename)) + for path in paths: + current_dir = path + if match_file(current_dir): + file_found = 1 + break # pylint: disable-msg=W0612 for current_dir, directories, files in os.walk(path): - if os.path.exists(os.path.join(current_dir, filename)): + if match_file(current_dir): file_found = 1 break if file_found: @@ -298,7 +325,7 @@ fi menuentry "%(grml_flavour)s (default)" { set gfxpayload=1024x768x16,1024x768 - linux /boot/release/%(flavour_filename)s/linux26 apm=power-off quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s + 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 } @@ -335,7 +362,7 @@ menuentry "Boot OS of first partition on first disk" { """ % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp, 'flavour_filename': grml_flavour.replace('-', ''), - 'bootoptions': bootoptions } ) + 'uid': UUID, 'bootoptions': bootoptions } ) def generate_flavour_specific_grub2_config(grml_flavour, bootoptions): @@ -350,60 +377,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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s + 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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s + 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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ toram=%(grml_flavour)s.squashfs %(bootoptions)s + 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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug%(bootoptions)s + 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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s + 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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s + 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/%(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 %(bootoptions)s + 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/%(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 %(bootoptions)s + 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, 'flavour_filename': grml_flavour.replace('-', ''), - 'bootoptions': bootoptions } ) + 'uid': UUID, 'bootoptions': bootoptions } ) def generate_flavour_specific_grub1_config(grml_flavour, install_partition, bootoptions): @@ -418,51 +445,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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s +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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet persistent live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s +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/%(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 %(bootoptions)s +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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug initcall_debug%(bootoptions)s +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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s +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/%(flavour_filename)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s +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/%(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 %(bootoptions)s +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/%(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 %(bootoptions)s +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/%(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 %(bootoptions)s +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('-', ''), + 'flavour_filename': grml_flavour.replace('-', ''), 'uid': UUID, 'bootoptions': bootoptions, 'install_partition': install_partition } ) @@ -484,7 +511,7 @@ background = FFCC33 # define entries: title %(grml_flavour)s - Default boot (using 1024x768 framebuffer) -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/ %(bootoptions)s +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+) @@ -502,7 +529,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('-', ''), + 'flavour_filename': grml_flavour.replace('-', ''), 'uid': UUID, 'bootoptions': bootoptions, 'install_partition': install_partition } ) @@ -945,7 +972,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: @@ -983,6 +1010,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 @@ -999,24 +1050,32 @@ def copy_system_files(grml_flavour, iso_mount, target): execute(mkdir, squashfs_target) exec_rsync(squashfs, squashfs_target + grml_flavour + '.squashfs') - filesystem_module = search_file('filesystem.module', iso_mount) + for prefix in grml_flavour + "/", "": + filesystem_module = search_file(prefix + 'filesystem.module', iso_mount) + if filesystem_module: break if filesystem_module is None: logging.critical("Fatal: filesystem.module not found") raise CriticalException("error locating filesystem.module file") else: exec_rsync(filesystem_module, squashfs_target + 'filesystem.module') - release_target = target + '/boot/release/' + grml_flavour.replace('-', '') + + release_path = 'boot/release/' + grml_flavour.replace('-', '') + release_target = target + "/" + release_path execute(mkdir, release_target) - kernel = search_file('linux26', iso_mount) + prefix = "" + if os.path.isdir(iso_mount + '/boot/release'): + prefix = release_path + '/' + + kernel = search_file(prefix + 'linux26', iso_mount) if kernel is None: logging.critical("Fatal kernel not found") raise CriticalException("error locating kernel file") else: exec_rsync(kernel, release_target + '/linux26') - initrd = search_file('initrd.gz', iso_mount) + initrd = search_file(prefix + 'initrd.gz', iso_mount) if initrd is None: logging.critical("Fatal: initrd not found") raise CriticalException("error locating initrd file") @@ -1033,7 +1092,33 @@ def copy_grml_files(iso_mount, target): grml_target = target + '/grml/' execute(mkdir, grml_target) - for myfile in 'grml-cheatcodes.txt', 'grml-version', 'LICENSE.txt', 'md5sums', 'README.txt': + copy_files = [ 'grml-cheatcodes.txt', 'LICENSE.txt', 'md5sums', 'README.txt' ] + # handle grml-version + new_grml_version = search_file('grml-version', grml_target) + if new_grml_version: + orig_grml_version = search_file('grml-version', iso_mount) + if not orig_grml_version: + logging.warn("Warning: %s could not be found - can not install it", orig_grml_version) + else: + try: + new_file = open(new_grml_version, 'a+') + new_flavours = [ get_flavour(l) for l in new_file.readlines() ] + + old_file = open(orig_grml_version, 'r') + old_lines = old_file.readlines() + for line in old_lines: + if not get_flavour(line) in new_flavours: + new_file.write(line) + + except IOError, e: + logging.warn("Warning: Could not write file") + finally: + new_file.close() + old_file.close() + else: + copy_files.append('grml-version') + + for myfile in copy_files: grml_file = search_file(myfile, iso_mount) if grml_file is None: logging.warn("Warning: myfile %s could not be found - can not install it", myfile) @@ -1136,34 +1221,40 @@ def copy_bootloader_files(iso_mount, target): logo = search_file('logo.16', iso_mount) exec_rsync(logo, syslinux_target + 'logo.16') + 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) + loopback_cfg = search_file("loopback.cfg", iso_mount) + if loopback_cfg: + directory = os.path.dirname(loopback_cfg) + directory = directory.replace(iso_mount, "") + if not os.path.isdir(target + "/" + directory): + os.mkdir(target + os.path.sep + directory) + exec_rsync(loopback_cfg, target + os.path.sep + directory) + # avoid the "file is read only, overwrite anyway (y/n) ?" question # of mtools by syslinux ("mmove -D o -D O s:/ldlinux.sys $target_file") if os.path.isfile(syslinux_target + 'ldlinux.sys'): os.unlink(syslinux_target + 'ldlinux.sys') - 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: + source_dir, name = get_defaults_file(iso_mount, GRML_DEFAULT, "default.cfg") + (source_dir,options) = get_defaults_file(iso_mount, GRML_DEFAULT, "grml.cfg") + + if not source_dir: 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 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': + for expr in name, 'distri.cfg', \ + options, 'grml.png', 'hd.cfg', 'isolinux.cfg', 'isolinux.bin', \ + 'isoprompt.cfg', 'options.cfg', \ + 'prompt.cfg', 'vesamenu.c32', 'vesamenu.cfg', 'grml.png', '*.c32': files = glob.glob(iso_mount + source_dir + expr) for path in files: filename = os.path.basename(path) @@ -1219,6 +1310,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: @@ -1256,6 +1349,11 @@ def uninstall_files(device): logging.critical("TODO: uninstalling files from %s not yet implement, sorry.", device) +def get_flavour(str): + """Returns the flavour of a grml version string + """ + return re.match(r'[\w-]*', str).group() + def identify_grml_flavour(mountpath): """Get name of grml flavour @@ -1268,17 +1366,21 @@ def identify_grml_flavour(mountpath): logging.critical("Error: could not find grml-version file.") raise + flavours = [] + tmpfile = None try: tmpfile = open(version_file, 'r') - grml_info = tmpfile.readline() - grml_flavour = re.match(r'[\w-]*', grml_info).group() - except TypeError: + for line in tmpfile.readlines(): + flavours.append(get_flavour(line)) + except TypeError, e: raise except Exception, e: logging.critical("Unexpected error: %s", e) raise + finally: + if tmpfile: tmpfile.close() - return grml_flavour + return flavours def modify_grub_config(filename): @@ -1458,13 +1560,16 @@ def add_entry_if_not_present(filename, entry): data.close() - +def flavour_filename(flavour): + return flavour.replace('-', '_') def adjust_syslinux_bootoptions(src, flavour): - append_re = re.compile("^(\s*append.*)$", re.I) + append_re = re.compile("^(\s*append.*/boot/release.*)$", re.I) boot_re = re.compile("/boot/([a-zA-Z0-9_]+/)+([a-zA-Z0-9._]+)") # flavour_re = re.compile("(label.*)(grml\w+)") default_re = re.compile("(default.cfg)") + bootid_re = re.compile("bootid=[\w_-]+") + live_media_path_re = re.compile("live-media-path=[\w_/-]+") # do NOT write "None" in kernel cmdline if options.bootoptions is None: @@ -1480,12 +1585,16 @@ def adjust_syslinux_bootoptions(src, flavour): 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.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 = live_media_path_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) + 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) @@ -1517,7 +1626,6 @@ def modify_filenames(grml_flavour, target, 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): @@ -1560,13 +1668,14 @@ def handle_syslinux_config(grml_flavour, target): prompt_name.close() initial_syslinux_config(syslinux_target) + flavour_filename = grml_flavour.replace('-', '_') + if search_file('default.cfg', syslinux_target): modify_filenames(grml_flavour, syslinux_target, ['grml.cfg', 'default.cfg']) 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" @@ -1586,10 +1695,10 @@ def handle_syslinux_config(grml_flavour, target): new_default = "%s_default.cfg" % (flavour_filename) entry = 'include %s\n' % new_default defaults_file = '%s/defaults.cfg' % syslinux_target + new_default_with_path = "%s/%s" % (syslinux_target, new_default) + new_grml_cfg = "%s/%s_grml.cfg" % ( syslinux_target, flavour_filename) 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) @@ -1598,6 +1707,9 @@ def handle_syslinux_config(grml_flavour, target): adjust_labels(new_default_with_path, r'\1 %s' % grml_flavour) adjust_labels(new_grml_cfg, r'\1 %s-\2' % grml_flavour) + # always adjust bootoptions + adjust_syslinux_bootoptions(new_default_with_path, grml_flavour) + adjust_syslinux_bootoptions(new_grml_cfg, grml_flavour) add_entry_if_not_present("%s/defaults.cfg" % syslinux_target, entry) @@ -1611,6 +1723,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: @@ -1655,9 +1769,15 @@ def handle_dir(live_image, device): try: try: - grml_flavour = identify_grml_flavour(live_image) - logging.info("Identified grml flavour \"%s\".", grml_flavour) - install_iso_files(grml_flavour, live_image, device, device_mountpoint) + grml_flavours = identify_grml_flavour(live_image) + worked_flavours = [] + for flavour in grml_flavours: + if flavour in worked_flavours: + continue + else: + worked_flavours.append(flavour) + logging.info("Identified grml flavour \"%s\".", flavour) + install_iso_files(flavour, live_image, device, device_mountpoint) except TypeError: logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up") sys.exit(1) @@ -1706,17 +1826,27 @@ 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: - grml_flavour = identify_grml_flavour(iso_mountpoint) - logging.info("Identified grml flavour \"%s\".", grml_flavour) - install_iso_files(grml_flavour, iso_mountpoint, device, device_mountpoint) + grml_flavours = identify_grml_flavour(iso_mountpoint) + worked_flavours = [] + for flavour in grml_flavours: + if flavour in worked_flavours: + continue + else: + worked_flavours.append(flavour) + logging.info("Identified grml flavour \"%s\".", flavour) + install_iso_files(flavour, iso_mountpoint, device, device_mountpoint) except TypeError: logging.critical("Fatal: a critical error happend during execution (not a grml ISO?), giving up") sys.exit(1) @@ -1808,12 +1938,12 @@ 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) - if not os.path.isdir(device) and not check_for_usbdevice(device): + if not os.path.isdir(device) and not check_for_usbdevice(device) and not option.force: print "Warning: the specified device %s does not look like a removable usb device." % device f = raw_input("Do you really want to continue? y/N ") if f == "y" or f == "Y": @@ -1873,6 +2003,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 @@ -1892,6 +2025,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]