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
import tempfile
import time
import uuid
+import shutil
# The line following this line is patched by debian/rules and tarball.sh.
PROG_VERSION = '***UNRELEASED***'
GRML_DEFAULT = None
UUID = None
SYSLINUX_LIBS = "/usr/lib/syslinux/"
-GPT_HEADER = "\x55\xaa\x45\x46\x49\x20\x50\x41\x52\x54" # original GPT header
+GPT_HEADER = "\x55\xaa\x45\x46\x49\x20\x50\x41\x52\x54" # original GPT header
RE_PARTITION = re.compile(r'([a-z/]*?)(\d+)$')
RE_P_PARTITION = re.compile(r'(.*?\d+)p(\d+)$')
RE_LOOP_DEVICE = re.compile(r'/dev/loop\d+$')
+
def syslinux_warning(option, opt, value, opt_parser):
"""A helper function for printing a warning about deprecated option
"""
@Exception: message"""
pass
+
class VerifyException(Exception):
"""Throw critical exception if there is an fatal error when verifying something.
def cleanup():
"""Cleanup function to make sure there aren't any mounted devices left behind.
"""
+ def del_failed(fn, filepath, exc):
+ msg = "Deletion of %s failed in temporary folder %s"
+ logging.warn(msg % (filepath, path))
logging.info("Cleaning up before exiting...")
proc = subprocess.Popen(["sync"])
proc.wait()
- try:
- for device in MOUNTED:
+ for device in MOUNTED.copy():
+ try:
unmount(device, "")
- for tmpfile in TMPFILES:
- os.unlink(tmpfile)
- # ignore: RuntimeError: Set changed size during iteration
- except RuntimeError:
- logging.debug('caught exception RuntimeError, ignoring')
+ logging.debug('Unmounted %s' % device)
+ except StandardError:
+ logging.debug('RuntimeError while umount %s, ignoring' % device)
+
+ for tmppath in TMPFILES.copy():
+ try:
+ if os.path.isdir(tmppath) and not os.path.islink(tmppath):
+ # symbolic links to directories are ignored
+ # without the check it will throw an OSError
+ shutil.rmtree(tmppath, onerror=del_failed)
+ logging.debug('temporary directory %s deleted' % tmppath)
+ unregister_tmpfile(tmppath)
+ elif os.path.isfile:
+ os.unlink(tmppath)
+ logging.debug('temporary file %s deleted' % tmppath)
+ unregister_tmpfile(tmppath)
+ except StandardError:
+ msg = 'RuntimeError while removing temporary %s, ignoring'
+ logging.debug(msg % tmppath)
def register_tmpfile(path):
@cwd: current working directory
"""
- return os.path.exists(os.path.join(cwd, filename))
+ return os.path.exists(os.path.join(cwd, filename))
for path in paths:
current_dir = path
squashfs = search_file(grml_flavour + '.squashfs', iso_mount)
if squashfs is None:
logging.error("error locating squashfs file")
- raise CriticalException("squashfs file not found"
- ", please check that your iso is not corrupt")
+ raise CriticalException("squashfs file not found, please check that your iso is not corrupt")
else:
squashfs_target = target + '/live/' + grml_flavour + '/'
execute(mkdir, squashfs_target)
logging.debug("Found source file" + sourcefile)
os.path.isfile(ops) and f.write("source " + sourcefile + "\n")
- f.write("source /boot/grub/adddons.cfg\n")
+ f.write("source /boot/grub/addons.cfg\n")
f.write("source /boot/grub/footer.cfg\n")
f.close()
# install main configuration only *once*, no matter how many ISOs we have:
syslinux_config_file = open(syslinux_cfg, 'w')
- syslinux_config_file.write("TIMEOUT 300\n")
+ syslinux_config_file.write("timeout 300\n")
syslinux_config_file.write("include vesamenu.cfg\n")
syslinux_config_file.close()
iso_mountpoint = image
remove_image_mountpoint = False
if os.path.isdir(image):
- logging.info("Using %s as install base", image)
+ 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. "
+ "Do you really want to use this image? y/N " % image)
+ if q.lower() == 'y':
+ logging.info("Using %s as install base", image)
+ else:
+ logging.info("Skipping install base %s", image)
else:
logging.info("Using ISO %s", image)
iso_mountpoint = tempfile.mkdtemp(prefix="grml2usb", dir=os.path.abspath(options.tmpdir))
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"""
mbrcode = GRML2USB_BASE + '/mbr/mbrldr'
if options.syslinuxmbr:
- mbrcode = '/usr/lib/syslinux/mbr.bin'
+ mbrcode = ""
+ mbr_locations = ('/usr/lib/syslinux/mbr.bin',
+ '/usr/share/syslinux/mbr.bin')
+ for mbrpath in mbr_locations:
+ if os.path.isfile(mbrpath):
+ mbrcode = mbrpath
+ break
+
+ if mbrcode is "":
+ str_locations = " or ".join(['"%s"' % l for l in mbr_locations])
+ logging.error('Cannot find syslinux MBR, install it at %s)',
+ str_locations)
+ raise CriticalException("syslinux MBR can not be found at %s."
+ % str_locations)
elif options.mbrmenu:
mbrcode = GRML2USB_BASE + '/mbr/mbrldr'
for flavour in GRML_FLAVOURS:
logging.info("Note: you can boot flavour %s using '%s' on the commandline.", flavour, flavour)
- # finally be politely :)
- logging.info("Finished execution of grml2usb (%s). Have fun with your grml system.", PROG_VERSION)
+ # finally be polite :)
+ logging.info("Finished execution of grml2usb (%s). Have fun with your Grml system.", PROG_VERSION)
except Exception, error:
logging.critical("Fatal: %s", str(error))