grml2usb
~~~~~~~~
-This script installs a grml system (either a running system or ISO[s]) to a USB device
+This script installs a Grml system (either a running system or ISO[s]) to a USB device
:copyright: (c) 2009, 2010, 2011 by Michael Prokop <mika@grml.org>
:license: GPL v2 or any later version
"""
+from __future__ import print_function
from optparse import OptionParser
from inspect import isroutine, isclass
import datetime
UUID = None
SYSLINUX_LIBS = "/usr/lib/syslinux/"
GPT_HEADER = "\x55\xaa\x45\x46\x49\x20\x50\x41\x52\x54" # original GPT header
+GRUB_INSTALL = None
RE_PARTITION = re.compile(r'([a-z/]*?)(\d+)$')
RE_P_PARTITION = re.compile(r'(.*?\d+)p(\d+)$')
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)")
"""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
try:
unmount(device, "")
logging.debug('Unmounted %s' % device)
- except RuntimeError:
+ except StandardError:
logging.debug('RuntimeError while umount %s, ignoring' % device)
for tmppath in TMPFILES.copy():
os.unlink(tmppath)
logging.debug('temporary file %s deleted' % tmppath)
unregister_tmpfile(tmppath)
- except RuntimeError:
+ except StandardError:
msg = 'RuntimeError while removing temporary %s, ignoring'
logging.debug(msg % tmppath)
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.getFlag(parted.PARTITION_BOOT):
+ logging.debug("bootflag is enabled on %s" % device)
+ return
+ 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:]
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):
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, 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",
+ "--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)
if options.grub:
try:
install_grub(device)
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Fatal: %s", error)
cleanup()
sys.exit(1)
else:
try:
install_syslinux(device)
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Fatal: %s", error)
cleanup()
sys.exit(1)
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
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)
+ print(iso_versions.pop(flavour))
else:
- print line.strip()
+ print(line.strip())
fileinput.close()
target_file = open(target_grml_version_file, 'a')
try:
copy_system_files(grml_flavour, iso_mount, target)
copy_grml_files(grml_flavour, iso_mount, target)
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Execution failed: %s", error)
sys.exit(1)
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
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)
tmpfile = open(version_file, 'r')
for line in tmpfile.readlines():
flavours.append(get_flavour(line))
- except TypeError, e:
- raise
- except Exception, e:
- raise
finally:
if tmpfile:
tmpfile.close()
line = line.rstrip() + r' bootid=%s %s ' % (UUID, bootopt)
for regex in remove_regexes:
line = regex.sub(' ', line)
- print line
+ print(line)
fileinput.close()
else:
try:
handle_syslinux_config(grml_flavour, target)
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Fatal: %s", error)
sys.exit(1)
else:
try:
handle_grub_config(grml_flavour, device, target)
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Fatal: %s", error)
sys.exit(1)
if options.force or os.path.exists(os.path.join(image, 'live')):
logging.info("Using %s as install base", image)
else:
- q = raw_input("%s does not look like a grml system. "
+ q = raw_input("%s does not look like a Grml system. "
"Do you really want to use this image? y/N " % image)
if q.lower() == 'y':
logging.info("Using %s as install base", image)
remove_image_mountpoint = True
try:
mount(image, iso_mountpoint, ["-o", "loop,ro", "-t", "iso9660"])
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Fatal: %s", error)
sys.exit(1)
if remove_image_mountpoint:
try:
remove_mountpoint(iso_mountpoint)
- except CriticalException, error:
+ except CriticalException as error:
cleanup()
raise
def install_grml(mountpoint, device):
- """Main logic for copying files of the currently running grml system.
+ """Main logic for copying files of the currently running Grml system.
@mountpoint: directory where currently running live system resides (usually /lib/live/mount/medium)
@device: partition where the specified ISO should be installed to"""
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, error:
- raise
- except CriticalException, error:
+ except CriticalException as error:
mount(device, device_mountpoint, "")
try:
grml_flavours = identify_grml_flavour(mountpoint)
if os.path.isdir(mountpoint):
os.rmdir(mountpoint)
unregister_tmpfile(mountpoint)
- except CriticalException, error:
+ except CriticalException as error:
cleanup()
raise
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):
try:
install_mbr(mbrcode, mbr_device, partition_number, True)
- except IOError, error:
- logging.critical("Execution failed: %s", error)
- sys.exit(1)
- except Exception, error:
+ except (IOError, Exception) as error:
logging.critical("Execution failed: %s", error)
sys.exit(1)
sys.exit(1)
if options.force:
- print "Forcing mkfs.fat16 on %s as requested via option --force." % device
+ print("Forcing mkfs.fat16 on %s as requested via option --force." % device)
else:
# make sure the user is aware of what he is doing
f = raw_input("Are you sure you want to format the specified partition with fat16? y/N ")
sys.exit(1)
try:
mkfs_fat16(device)
- except CriticalException, error:
+ except CriticalException as error:
logging.critical("Execution failed: %s", error)
sys.exit(1)
if device is not None and not os.path.isdir(device) and options.syslinux:
try:
check_for_fat(device)
- except CriticalException, error:
+ except CriticalException as error:
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
+ 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)
# make sure we can replace old grml2usb script and warn user when using old way of life:
if device.startswith("/mnt/external") or device.startswith("/mnt/usb") and not options.force:
- print "Warning: the semantics of grml2usb has changed."
- print "Instead of using grml2usb /path/to/iso %s you might" % device
- print "want to use grml2usb /path/to/iso /dev/... instead."
- print "Please check out the grml2usb manpage for details."
+ print("Warning: the semantics of grml2usb has changed.")
+ print("Instead of using grml2usb /path/to/iso %s you might" % 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)
def check_programs():
"""check if all needed programs are installed"""
if options.grub:
- if not which("grub-install"):
+ 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 "
+ "grub package or drop the --grub option)")
sys.exit(1)
try:
if options.version:
- print os.path.basename(sys.argv[0]) + " " + PROG_VERSION
+ print(os.path.basename(sys.argv[0]) + " " + PROG_VERSION)
sys.exit(0)
if len(args) < 2:
logging.info("Note: you can boot flavour %s using '%s' on the commandline.", flavour, flavour)
# finally be polite :)
- logging.info("Finished execution of grml2usb (%s). Have fun with your grml system.", PROG_VERSION)
+ logging.info("Finished execution of grml2usb (%s). Have fun with your Grml system.", PROG_VERSION)
- except Exception, error:
+ except Exception as error:
logging.critical("Fatal: %s", str(error))
sys.exit(1)