X-Git-Url: https://git.grml.org/?p=grml2usb.git;a=blobdiff_plain;f=grml2usb;h=89874503f4ba2456dd59d7f336b201a35dc828e2;hp=9cca9d72240f1938bfa9a2aee12fb1c042758d7b;hb=c021230b57ee91d9b44f42e97ec7c28404ce77c1;hpb=cd204ee745d8af1fcf732fa6fc1a58d0646b424c diff --git a/grml2usb b/grml2usb index 9cca9d7..8987450 100755 --- a/grml2usb +++ b/grml2usb @@ -7,7 +7,7 @@ grml2usb This script installs a grml system (either a running system or ISO[s]) to a USB device -:copyright: (c) 2009 by Michael Prokop +:copyright: (c) 2009, 2010, 2011 by Michael Prokop :license: GPL v2 or any later version :bugreports: http://grml.org/bugs/ @@ -22,13 +22,14 @@ import uuid import struct # global variables -PROG_VERSION = "0.9.27~git" +PROG_VERSION = "0.9.31" 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? GRML_DEFAULT = None UUID = None +SYSLINUX_LIBS = "/usr/lib/syslinux/" def syslinux_warning(option, opt, value, opt_parser): """A helper function for printing a warning about deprecated option @@ -59,7 +60,7 @@ Run %prog --help for usage hints, further information via: man grml2usb" # pylint: disable-msg=W0603 parser = OptionParser(usage=USAGE) parser.add_option("--bootoptions", dest="bootoptions", - action="store", type="string", + action="append", type="string", help="use specified bootoptions as default") parser.add_option("--bootloader-only", dest="bootloaderonly", action="store_true", help="do not copy files but just install a bootloader") @@ -323,7 +324,7 @@ if loadfont /boot/grub/ascii.pf2 ; then set gfxmode=640x480 insmod gfxterm insmod vbe - if terminal_output.gfxterm ; then true ; else + if terminal_output gfxterm ; then true ; else # For backward compatibility with versions of terminal.mod that don't # understand terminal_output terminal gfxterm @@ -358,17 +359,48 @@ menuentry "Boot FreeDOS" { initrd /boot/addons/balder10.imz } -menuentry "Boot MirOS bsd4grml" { - multiboot /boot/addons/bsd4grml/ldbsd.com - module /boot/addons/bsd4grml/bsd.rd - module /boot/addons/bsd4grml/boot.1 - module /boot/addons/bsd4grml/boot.2 - module /boot/addons/bsd4grml/boot.3 - module /boot/addons/bsd4grml/boot.4 - module /boot/addons/bsd4grml/boot.5 - module /boot/addons/bsd4grml/boot.6 - module /boot/addons/bsd4grml/boot.cfg -} +if [ ${iso_path} ] ; then + # assume loopback.cfg boot + if [ -e /boot/addons/bsd4grml/loopback.0 ] ; then + # bsd4grml 20100815 and later + menuentry "Boot MirOS bsd4grml" { + multiboot /boot/addons/bsd4grml/ldbsd.com + module /boot/addons/bsd4grml/bsd.rd bsd + module /boot/addons/bsd4grml/loopback.0 boot.cfg + module /boot/addons/bsd4grml/loopback.1 boot.1 + module /boot/addons/bsd4grml/loopback.2 boot.2 + module /boot/addons/bsd4grml/loopback.3 boot.3 + module /boot/addons/bsd4grml/loopback.4 boot.4 + module /boot/addons/bsd4grml/loopback.5 boot.5 + module /boot/addons/bsd4grml/loopback.6 boot.6 + } + else + # old bsd4grml + menuentry "Boot MirOS bsd4grml" { + multiboot /boot/addons/bsd4grml/ldbsd.com + module /boot/addons/bsd4grml/bsd.rd bsd.rd + module /boot/addons/bsd4grml/boot.cfg boot.cfg + module /boot/addons/bsd4grml/boot.1 boot.1 + module /boot/addons/bsd4grml/boot.2 boot.2 + module /boot/addons/bsd4grml/boot.3 boot.3 + module /boot/addons/bsd4grml/boot.4 boot.4 + module /boot/addons/bsd4grml/boot.5 boot.5 + } + fi +else + # assume grub.cfg boot + menuentry "Boot MirOS bsd4grml" { + multiboot /boot/addons/bsd4grml/ldbsd.com + module /boot/addons/bsd4grml/bsd.rd bsd.rd + module /boot/addons/bsd4grml/boot.cfg boot.cfg + module /boot/addons/bsd4grml/boot.1 boot.1 + module /boot/addons/bsd4grml/boot.2 boot.2 + module /boot/addons/bsd4grml/boot.3 boot.3 + module /boot/addons/bsd4grml/boot.4 boot.4 + module /boot/addons/bsd4grml/boot.5 boot.5 + module /boot/addons/bsd4grml/boot.6 boot.6 + } +fi menuentry "Boot OS of first partition on first disk" { set root=(hd0,1) @@ -649,12 +681,16 @@ def install_grub(device): grub_device = device logging.info("Installing grub as bootloader") - logging.debug("grub-install --recheck --force --no-floppy --root-directory=%s %s", - device_mountpoint, grub_device) - proc = subprocess.Popen(["grub-install", "--recheck", "--force", "--no-floppy", - "--root-directory=%s" % device_mountpoint, grub_device], - stdout=file(os.devnull, "r+")) - proc.wait() + for opt in ["", "--force" ]: + logging.debug("grub-install --recheck %s --no-floppy --root-directory=%s %s", + opt, device_mountpoint, grub_device) + proc = subprocess.Popen(["grub-install", "--recheck", opt, "--no-floppy", + "--root-directory=%s" % device_mountpoint, grub_device], + stdout=file(os.devnull, "r+")) + proc.wait() + if proc.returncode == 0: + break + if proc.returncode != 0: # raise Exception("error executing grub-install") logging.critical("Fatal: error executing grub-install " @@ -1066,7 +1102,8 @@ def copy_system_files(grml_flavour, iso_mount, target): squashfs = search_file(grml_flavour + '.squashfs', iso_mount) if squashfs is None: - logging.critical("Fatal: squashfs file not found") + logging.critical("Fatal: squashfs file not found" + ", please check that your iso is not corrupt") raise CriticalException("error locating squashfs file") else: squashfs_target = target + '/live/' + grml_flavour + '/' @@ -1116,26 +1153,37 @@ def update_grml_versions(iso_mount, target): @target: path of the target mount point """ grml_target = target + '/grml/' - 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) + target_grml_version_file = search_file('grml-version', grml_target) + if target_grml_version_file: + iso_grml_version_file = search_file('grml-version', iso_mount) + if not iso_grml_version_file: + logging.warn("Warning: %s could not be found - can not install it", iso_grml_version_file) return False 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) + # read the flavours from the iso image + iso_versions = {} + iso_file = open(iso_grml_version_file, 'r') + for line in iso_file: + iso_versions[get_flavour(line)] = line.strip() + + # update the existing flavours on the target + for line in fileinput.input([target_grml_version_file], inplace=1): + flavour = get_flavour(line) + if flavour in iso_versions.keys(): + print iso_versions.pop(flavour) + else: + print line.strip() + fileinput.close() + + target_file = open(target_grml_version_file, 'a') + # add the new flavours from the current iso + for flavour in iso_versions: + target_file.write("%s\n" % iso_versions[flavour]) except IOError: logging.warn("Warning: Could not write file") finally: - new_file.close() - old_file.close() + iso_file.close() + target_file.close() return True else: return False @@ -1182,18 +1230,20 @@ def copy_grml_files(iso_mount, target): exec_rsync(grml_file, grml_webimg_target + myfile) -def handle_addon_copy(filename, dst, iso_mount): +def handle_addon_copy(filename, dst, iso_mount, ignore_errors=False): """handle copy of optional addons @filename: filename of the addon @dst: destination directory @iso_mount: location of the iso mount + @ignore_errors: don't report missing files """ file_location = search_file(filename, iso_mount) if file_location is None: - logging.warn("Warning: %s not found (that's fine if you don't need it)", filename) + if not ignore_errors: + logging.warn("Warning: %s not found (that's fine if you don't need it)", filename) else: - exec_rsync(file_location, dst + filename) + exec_rsync(file_location, dst) def copy_addons(iso_mount, target): @@ -1231,9 +1281,11 @@ def copy_addons(iso_mount, target): # memtest86+ image handle_addon_copy('memtest', addons, iso_mount) - # gpxe.lkrn - handle_addon_copy('gpxe.lkrn', addons, iso_mount) + # gpxe.lkrn: got replaced by ipxe + handle_addon_copy('gpxe.lkrn', addons, iso_mount, ignore_errors=True) + # ipxe.lkrn + handle_addon_copy('ipxe.lkrn', addons, iso_mount) def glob_and_copy(filepattern, dst): """Glob on specified filepattern and copy the result to dst @@ -1310,9 +1362,13 @@ def copy_bootloader_files(iso_mount, target, grml_flavour): for expr in name, 'distri.cfg', \ defaults_file, 'grml.png', 'hd.cfg', 'isolinux.cfg', 'isolinux.bin', \ 'isoprompt.cfg', 'options.cfg', \ - 'prompt.cfg', 'vesamenu.c32', 'vesamenu.cfg', 'grml.png', '*.c32': + 'prompt.cfg', 'vesamenu.cfg', 'grml.png', '*.c32': glob_and_copy(iso_mount + source_dir + expr, syslinux_target) + for filename in glob.glob1(syslinux_target, "*.c32"): + copy_if_exist(os.path.join(SYSLINUX_LIBS, filename), syslinux_target) + + # copy the addons_*.cfg file to the new syslinux directory glob_and_copy(iso_mount + source_dir + 'addon*.cfg', syslinux_target) @@ -1493,7 +1549,7 @@ def handle_grub2_config(grml_flavour, grub_target, bootopt): # grub2 config grub2_cfg = grub_target + 'grub.cfg' - logging.debug("Creating grub2 configuration file (grub.lst)") + logging.debug("Creating grub2 configuration file (grub.cfg)") global GRML_DEFAULT @@ -1541,10 +1597,10 @@ def get_bootoptions(grml_flavour): @grml_flavour: name of the grml_flavour """ # do NOT write "None" in kernel cmdline - if options.bootoptions is None: + if not options.bootoptions: bootopt = "" else: - bootopt = options.bootoptions + bootopt = " ".join(options.bootoptions) bootopt = bootopt.replace("%flavour", grml_flavour) return bootopt @@ -1868,10 +1924,11 @@ def install_grml(mountpoint, device): except CriticalException, error: logging.critical("Fatal: %s", error) raise - global GRML_FLAVOURS try: grml_flavours = identify_grml_flavour(mountpoint) for flavour in set(grml_flavours): + if not flavour: + logging.warning("No valid flavour found, please check your iso") logging.info("Identified grml flavour \"%s\".", flavour) install_iso_files(flavour, mountpoint, device, device_mountpoint) GRML_FLAVOURS.add(flavour) @@ -2032,6 +2089,24 @@ def check_options(opts): sys.exit(1) +def check_programs(): + """check if all needed programs are installed""" + if options.grub: + if not which("grub-install"): + logging.critical("Fatal: grub-install not available (please install the " + + "grub package or drop the --grub option)") + sys.exit(1) + + if options.syslinux: + if not which("syslinux"): + logging.critical("Fatal: syslinux not available (please install the " + + "syslinux package or use the --grub option)") + sys.exit(1) + + if not which("rsync"): + logging.critical("Fatal: rsync not available, can not continue - sorry.") + sys.exit(1) + def main(): """Main function [make pylint happy :)]""" @@ -2055,6 +2130,8 @@ def main(): if options.dryrun: logging.info("Running in simulation mode as requested via option dry-run.") + check_programs() + # specified arguments device = args[len(args) - 1] isos = args[0:len(args) - 1] @@ -2068,21 +2145,6 @@ def main(): logging.critical("Fatal: installation on raw device not supported. (BIOS won't support it.)") sys.exit(1) - if options.grub: - if not which("grub-install"): - logging.critical("Fatal: grub-install not available (please install the " - + "grub package or drop the --grub option)") - sys.exit(1) - - if options.syslinux: - if not which("syslinux"): - logging.critical("Fatal: syslinux not available (please install the " - + "syslinux package or use the --grub option)") - sys.exit(1) - - if not which("rsync"): - logging.critical("Fatal: rsync not available, can not continue - sorry.") - sys.exit(1) # provide upgrade path handle_compat_warning(device)