-#!/usr/bin/env python2
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pylint: disable-msg=C0302
"""
"""
-from __future__ import print_function
+
from optparse import OptionParser
from inspect import isroutine, isclass
import datetime
import shutil
# The line following this line is patched by debian/rules and tarball.sh.
-PROG_VERSION = '***UNRELEASED***'
+PROG_VERSION = '***UNKNOWN***'
+
+# when running from inside git, try to report version information via git-describe
+try:
+ git_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
+ with open(os.devnull, 'w') as devnull:
+ PROG_VERSION = subprocess.check_output(["git",
+ "-C",
+ git_dir,
+ "describe",
+ "--always",
+ "--dirty"],
+ stderr=devnull).strip().decode('utf-8', errors='replace') + \
+ " (git)"
+except Exception:
+ pass
# global variables
MOUNTED = set() # register mountpoints
GRML_FLAVOURS = set() # which flavours are being installed?
GRML_DEFAULT = None
UUID = None
-SYSLINUX_LIBS = "/usr/lib/syslinux/"
+SYSLINUX_LIBS = [
+ "/usr/lib/syslinux/modules/bios/", # Debian
+ "/usr/lib/syslinux/bios/", # Arch Linux
+]
GPT_HEADER = b"\x55\xaa\x45\x46\x49\x20\x50\x41\x52\x54" # original GPT header
GRUB_INSTALL = None
help="install syslinux bootloader (deprecated as it's the default)")
parser.add_option("--syslinux-mbr", dest="syslinuxmbr", action="store_true",
help="install syslinux master boot record (MBR) instead of default")
+parser.add_option("--syslinux-libs", dest="syslinuxlibs", action="append", default=[],
+ help="syslinux modules directory path")
parser.add_option("--tmpdir", dest="tmpdir", default="/tmp",
help="directory to be used for temporary files")
parser.add_option("--verbose", dest="verbose", action="store_true",
try:
unmount(device, "")
logging.debug('Unmounted %s' % device)
- except StandardError:
+ except Exception:
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 StandardError:
+ except Exception:
msg = 'RuntimeError while removing temporary %s, ignoring'
logging.debug(msg % tmppath)
return ('', '')
-def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin', lst_return=False):
+def search_file(filename, search_path='/bin' + os.pathsep + '/usr/bin', lst_return=False, required=False):
"""Given a search path, find file
@filename: name of file to search for
retval.append(os.path.abspath(os.path.join(current_dir, filename)))
if not lst_return:
break
+
+ if required and not retval:
+ raise CriticalException("Required file %s not found in %s" % (filename, search_path))
+
if lst_return:
return retval
elif retval:
except ImportError as e:
logging.debug("could not import parted, falling back to old bootflag detection")
- with open(boot_dev, 'r') as image:
+ with open(boot_dev, 'rb') as image:
data = image.read(520)
bootcode = data[440:]
gpt_data = bootcode[70:80]
" (wrong UID/permissions or device/directory not present?)" % partition)
try:
- udev_info = subprocess.Popen(["/sbin/blkid", "-s", "TYPE", "-o", "value", partition],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- filesystem = udev_info.communicate()[0].rstrip()
+ filesystem = subprocess.check_output(["/sbin/blkid", "-s", "TYPE", "-o", "value", partition]).decode().rstrip()
if filesystem != "vfat":
raise CriticalException(
"(Use --fat16 or run mkfs.vfat %s)" % (partition, partition))
except OSError:
- raise CriticalException("Sorry, /sbin/blkid not available (install e2fsprogs?)")
+ raise CriticalException("Sorry, /sbin/blkid not available (install util-linux?)")
def mkdir(directory):
# 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():
+ if flavour in list(iso_versions.keys()):
print(iso_versions.pop(flavour))
else:
print(line.strip())
logging.warn("Warning: could not find flavour directory for %s ", grml_flavour)
-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:
- 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)
-
-
def copy_addons(iso_mount, target):
"""copy grml's addons files (like allinoneimg, bsd4grml,..) to a given target
addons = target + '/boot/addons/'
execute(mkdir, addons)
- # grub all-in-one image
- handle_addon_copy('allinone.img', addons, iso_mount)
-
- # bsd image
- handle_addon_copy('bsd4grml', addons, iso_mount)
-
- # DOS image
- handle_addon_copy('balder10.imz', addons, iso_mount)
-
- # syslinux + pci.ids for hdt
- for expr in '*.c32', 'pci.ids':
- glob_and_copy(iso_mount + '/boot/addons/' + expr, addons)
-
- # memdisk image
- handle_addon_copy('memdisk', addons, iso_mount)
-
- # memtest86+ image
- handle_addon_copy('memtest', 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)
-
- # netboot.xyz
- handle_addon_copy('netboot.xyz.lkrn', addons, iso_mount)
+ for addon_file in glob.glob(iso_mount + '/boot/addons/*'):
+ filename = os.path.basename(addon_file)
+ src_file = iso_mount + "/boot/addons/" + os.path.basename(addon_file)
+ logging.debug("Copying addon file %s" % filename)
+ exec_rsync(src_file, addons)
def build_loopbackcfg(target):
grub_target = target + '/boot/grub/'
execute(mkdir, grub_target)
- logo = search_file('logo.16', iso_mount)
+ logo = search_file('logo.16', iso_mount, required=True)
exec_rsync(logo, syslinux_target + 'logo.16')
bootx64_efi = search_file('bootx64.efi', iso_mount)
'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)
+ for modules_dir in options.syslinuxlibs + SYSLINUX_LIBS:
+ if os.path.isdir(modules_dir):
+ for filename in glob.glob1(syslinux_target, "*.c32"):
+ copy_if_exist(os.path.join(modules_dir, filename), syslinux_target)
+ break
# copy the addons_*.cfg file to the new syslinux directory
glob_and_copy(iso_mount + source_dir + 'addon*.cfg', syslinux_target)
logging.debug('Unmounted %s' % efi_mountpoint)
os.rmdir(efi_mountpoint)
logging.debug('Removed directory %s' % efi_mountpoint)
- except StandardError:
+ except Exception:
logging.critical('RuntimeError while umount %s' % efi_mountpoint)
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 = 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)
mbrcode = mbrpath
break
- if mbrcode is "":
+ if not mbrcode:
str_locations = " or ".join(['"%s"' % l for l in mbr_locations])
logging.error('Cannot find syslinux MBR, install it at %s)',
str_locations)
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 ")
+ f = input("Are you sure you want to format the specified partition with fat16? y/N ")
if f == "y" or f == "Y":
logging.info("Note: you can skip this question using the option --force")
else:
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 ")
+ f = input("Do you really want to continue? y/N ")
if f.lower() != "y":
sys.exit(1)
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 ")
+ f = input("Do you really want to continue? y/N ")
if f.lower() != "y":
sys.exit(1)
def load_loop():
- """Runs modprobe loop and throws away it's output"""
+ """Runs modprobe loop and throws away its output"""
if not which("modprobe"):
logging.critical("Fatal: modprobe not available, can not continue - sorry.")
logging.critical("Hint: is /sbin missing in PATH?")
sys.exit(1)
proc = subprocess.Popen(["modprobe", "loop"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- proc.wait()
+ proc.communicate()
def main():
except Exception as error:
logging.critical("Fatal: %s", str(error))
+ if options.verbose:
+ logging.exception("Exception:")
sys.exit(1)