X-Git-Url: http://git.grml.org/?p=grml2usb.git;a=blobdiff_plain;f=grml2usb;h=2f63ce148a9db528e164115e2db2979114dea065;hp=b7f1207d7aa9dd52dd30331efddb59cee6cc1074;hb=745f09771c1a7cfd9607d3300a55ee8ddbd59fac;hpb=f434e19e7be373a15faa990d34e85253ef7168c3 diff --git a/grml2usb b/grml2usb index b7f1207..2f63ce1 100755 --- a/grml2usb +++ b/grml2usb @@ -105,12 +105,16 @@ 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-bootflag", dest="skipbootflag", action="store_true", + help="do not try to check whether the destination has the bootflag set") parser.add_option("--skip-grub-config", dest="skipgrubconfig", action="store_true", help="skip generation of grub configuration files") 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("--skip-usb-check", dest="skipusbcheck", action="store_true", + help="skip check to verify whether given device is removable") parser.add_option("--syslinux", dest="syslinux", action="callback", default=True, callback=syslinux_warning, help="install syslinux bootloader (deprecated as it's the default)") @@ -130,18 +134,22 @@ if not os.path.isdir(GRML2USB_BASE): GRML2USB_BASE = os.path.dirname(os.path.realpath(__file__)) +class HodorException(Exception): + """Throw exception if the exact error is not known and not fatal. + + @Exception: message""" + + class CriticalException(Exception): """Throw critical exception if the exact error is not known but fatal. @Exception: message""" - pass class VerifyException(Exception): """Throw critical exception if there is an fatal error when verifying something. @Exception: message""" - pass # The following two functions help to operate on strings as @@ -337,9 +345,33 @@ def check_uid_root(): raise CriticalException("please run this script with uid 0 (root).") +# for usage inside check_boot_flag +def get_partition_for_path(path): + import parted + + boot_dev, x = get_device_from_partition(path) + + d = parted.getDevice(boot_dev) + disk = parted.Disk(d) + return disk.getPartitionByPath(path) + + def check_boot_flag(device): boot_dev, x = get_device_from_partition(device) + try: + import parted + part = get_partition_for_path(device) + if part is None: + raise HodorException("parted could not find partition") + if part.getFlag(parted.PARTITION_BOOT): + logging.debug("bootflag is enabled on %s" % device) + return + except HodorException, e: + logging.info("%s, falling back to old bootflag detection", e) + except ImportError, e: + logging.debug("could not import parted, falling back to old bootflag detection") + with open(boot_dev, 'r') as image: data = image.read(520) bootcode = data[440:] @@ -352,7 +384,7 @@ def check_boot_flag(device): else: logging.debug("bootflag is NOT enabled") raise VerifyException("Device %s does not have the bootflag set. " - "Please enable it to be able to boot." % boot_dev) + "Please enable it to be able to boot." % device) def mkfs_fat16(device): @@ -458,40 +490,39 @@ def install_grub(device): device_mountpoint = tempfile.mkdtemp(prefix="grml2usb") register_tmpfile(device_mountpoint) try: - try: - mount(device, device_mountpoint, "") + mount(device, device_mountpoint, "") - # If using --grub-mbr then make sure we install grub in MBR instead of PBR - if options.grubmbr: - logging.debug("Using option --grub-mbr ...") - grub_device, x = get_device_from_partition(device) - else: - grub_device = device - - logging.info("Installing grub as bootloader") - 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 " - + "(please check the grml2usb FAQ or drop the --grub option)") - logging.critical("Note: if using grub2 consider using " - + "the --grub-mbr option as grub considers PBR problematic.") - cleanup() - sys.exit(1) - except CriticalException as error: - logging.critical("Fatal: %s", error) + # If using --grub-mbr then make sure we install grub in MBR instead of PBR + if options.grubmbr: + logging.debug("Using option --grub-mbr ...") + grub_device, x = get_device_from_partition(device) + else: + grub_device = device + + logging.info("Installing grub as bootloader") + 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", "--target=i386-pc", + "--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 " + + "(please check the grml2usb FAQ or drop the --grub option)") + logging.critical("Note: if using grub2 consider using " + + "the --grub-mbr option as grub considers PBR problematic.") cleanup() sys.exit(1) - + except CriticalException as error: + logging.critical("Fatal: %s", error) + cleanup() + sys.exit(1) finally: unmount(device_mountpoint, "") os.rmdir(device_mountpoint) @@ -625,6 +656,10 @@ def install_mbr(mbrtemplate, device, partition, ismirbsdmbr=True): raise Exception("error executing dd (third run)") del tmpf + # make sure we sync filesystems before returning + proc = subprocess.Popen(["sync"]) + proc.wait() + def is_writeable(device): """Check if the device is writeable for the current user @@ -1144,9 +1179,7 @@ def get_device_from_partition(partition): device = partition partition_number = None if partition[-1].isdigit() and not RE_LOOP_DEVICE.match(partition): - m = RE_P_PARTITION.match(partition) - if not m: - m = RE_PARTITION.match(partition) + m = RE_P_PARTITION.match(partition) or RE_PARTITION.match(partition) if m: device = m.group(1) partition_number = int(m.group(2)) - 1 @@ -1172,12 +1205,10 @@ def identify_grml_flavour(mountpath): logging.critical("Error: could not find grml-version file.") logging.critical("Looks like your system is running from RAM but required files are not available.") logging.critical("Please either boot without toram=... or use boot option toram instead of toram=...") - cleanup() - sys.exit(1) else: logging.critical("Error: could not find grml-version file.") - cleanup() - sys.exit(1) + cleanup() + sys.exit(1) flavours = [] logging.debug("version_files = %s", version_files) @@ -1187,10 +1218,6 @@ def identify_grml_flavour(mountpath): tmpfile = open(version_file, 'r') for line in tmpfile.readlines(): flavours.append(get_flavour(line)) - except TypeError as e: - raise - except Exception as e: - raise finally: if tmpfile: tmpfile.close() @@ -1275,7 +1302,7 @@ def initial_syslinux_config(target): def add_entry_if_not_present(filename, entry): """Write entry into filename if entry is not already in the file - @filanme: name of the file + @filename: name of the file @entry: data to write to the file """ data = open(filename, "a+") @@ -1542,10 +1569,9 @@ def install_grml(mountpoint, device): remove_device_mountpoint = True try: check_for_fat(device) - check_boot_flag(device) + if not options.skipbootflag: + check_boot_flag(device) mount(device, device_mountpoint, ['-o', 'utf8,iocharset=iso8859-1']) - except VerifyException as error: - raise except CriticalException as error: mount(device, device_mountpoint, "") try: @@ -1598,6 +1624,7 @@ def handle_mbr(device): if options.syslinuxmbr: mbrcode = "" mbr_locations = ('/usr/lib/syslinux/mbr.bin', + '/usr/lib/syslinux/bios/mbr.bin', '/usr/share/syslinux/mbr.bin') for mbrpath in mbr_locations: if os.path.isfile(mbrpath): @@ -1615,10 +1642,7 @@ def handle_mbr(device): try: install_mbr(mbrcode, mbr_device, partition_number, True) - except IOError as error: - logging.critical("Execution failed: %s", error) - sys.exit(1) - except Exception as error: + except (IOError, Exception) as error: logging.critical("Execution failed: %s", error) sys.exit(1) @@ -1658,12 +1682,14 @@ def handle_vfat(device): logging.critical("Execution failed: %s", error) sys.exit(1) + if options.skipusbcheck: + logging.info("Not checking for removable USB device as requested via option --skip-usb-check.") + return + if not os.path.isdir(device) and not check_for_usbdevice(device) and not options.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": - pass - else: + if f.lower() != "y": sys.exit(1) @@ -1679,9 +1705,7 @@ def handle_compat_warning(device): print("want to use grml2usb /path/to/iso /dev/... instead.") print("Please check out the grml2usb manpage for details.") f = raw_input("Do you really want to continue? y/N ") - if f == "y" or f == "Y": - pass - else: + if f.lower() != "y": sys.exit(1) @@ -1723,10 +1747,14 @@ def check_options(opts): if opts.grubmbr and not opts.grub: raise CriticalException("--grub-mbr requires --grub option.") + if opts.copyonly and opts.grub: + raise CriticalException("Cannot use --copy-only and --grub at the same time.") + def check_programs(): """check if all needed programs are installed""" if options.grub: + global GRUB_INSTALL GRUB_INSTALL = which("grub-install") or which("grub2-install") if not GRUB_INSTALL: logging.critical("Fatal: grub-install not available (please install the "