import datetime, logging, os, re, subprocess, sys, tempfile, time
# global variables
-PROG_VERSION = "0.9.2"
+PROG_VERSION = "0.9.4"
MOUNTED = set() # register mountpoints
TMPFILES = set() # register tmpfiles
DATESTAMP = time.mktime(datetime.datetime.now().timetuple()) # unique identifier for syslinux.cfg
Make sure you have at least one grml ISO or a running grml system (/live/image),\n\
grub or syslinux and root access.\n\
\n\
-Execute %prog --help for usage hints, further information can be found in: man grml2usb"
+Run %prog --help for usage hints, further information via: man grml2usb"
# pylint: disable-msg=C0103
parser = OptionParser(usage=USAGE)
# help="install specified kernel instead of the default [TODO - not implemented yet]")
parser.add_option("--lilo-binary", dest="lilobin", action="store", type="string",
help="lilo executable to be used for installing MBR")
-parser.add_option("--mbr-manager", dest="mbrmgr", action="store_true",
- help="enable interactive boot manager menu in MBR")
+parser.add_option("--mbr-menu", dest="mbrmenu", action="store_true",
+ help="enable interactive boot menu in MBR")
parser.add_option("--quiet", dest="quiet", action="store_true",
help="do not output anything but just errors on console")
parser.add_option("--skip-addons", dest="skipaddons", action="store_true",
menuentry "%(grml_flavour)s (default)" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26 apm=power-off lang=us vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
initrd /boot/release/%(grml_flavour)s/initrd.gz
}
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
menuentry "%(grml_flavour)s-debug" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26
- initrd /boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug boot=live initcall_debug%(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ debug boot=live initcall_debug%(bootoptions)s
+ initrd /boot/release/%(grml_flavour)s/initrd.gz
}
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
menuentry "%(grml_flavour)s-x" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26
- initrd /boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ startx=wm-ng %(bootoptions)s
+ initrd /boot/release/%(grml_flavour)s/initrd.gz
}
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
menuentry "%(grml_flavour)s-nofb" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26
- initrd /boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=ofonly %(bootoptions)s
+ initrd /boot/release/%(grml_flavour)s/initrd.gz
}
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
menuentry "%(grml_flavour)s-failsafe" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26
- initrd /boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal lang=us boot=live noautoconfig atapicd noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia maxcpus=1 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm %(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal boot=live noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off %(bootoptions)s
+ initrd /boot/release/%(grml_flavour)s/initrd.gz
}
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
menuentry "%(grml_flavour)s-forensic" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26
- initrd /boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect %(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce vga=791 quiet live-media-path=/live/%(grml_flavour)s/ nofstab noraid nolvm noautoconfig noswap raid=noautodetect %(bootoptions)s
+ initrd /boot/release/%(grml_flavour)s/initrd.gz
}
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
menuentry "%(grml_flavour)s-serial" {
set root=(hd0,%(install_partition)s)
- linux /boot/release/%(grml_flavour)s/linux26
- initrd /boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 %(bootoptions)s
+ linux /boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal video=vesafb:off console=tty1 console=ttyS0,9600n8 %(bootoptions)s
+ initrd /boot/release/%(grml_flavour)s/initrd.gz
}
""" % {'grml_flavour': grml_flavour, 'local_datestamp': local_datestamp,
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
title %(grml_flavour)s-failsafe
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal lang=us boot=live noautoconfig atapicd noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia maxcpus=1 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm %(bootoptions)s
+kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal boot=live noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off %(bootoptions)s
initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
## flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
# define entries:
title %(grml_flavour)s - Default boot (using 1024x768 framebuffer)
-kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off lang=us vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/
+kernel (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/linux26 apm=power-off vga=791 quiet boot=live nomce live-media-path=/live/%(grml_flavour)s/ %(bootoptions)s
initrd (hd0,%(install_partition)s)/boot/release/%(grml_flavour)s/initrd.gz
title Memory test (memtest86+)
# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
LABEL %(grml_flavour)s-failsafe
KERNEL /boot/release/%(grml_flavour)s/linux26
-APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal lang=us boot=live noautoconfig atapicd noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia maxcpus=1 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm %(bootoptions)s
+APPEND initrd=/boot/release/%(grml_flavour)s/initrd.gz apm=power-off boot=live nomce quiet live-media-path=/live/%(grml_flavour)s/ vga=normal boot=live noautoconfig atapicd noapic noacpi acpi=off nomodules nofirewire noudev nousb nohotplug noapm nopcmcia nosmp maxcpus=0 noscsi noagp nodma ide=nodma noswap nofstab nosound nogpm nosyslog nodhcp nocpu nodisc nomodem xmodule=vesa noraid nolvm noresume selinux=0 edd=off %(bootoptions)s
# flavour specific configuration for %(grml_flavour)s [grml2usb for %(grml_flavour)s: %(local_datestamp)s]
LABEL %(grml_flavour)s-forensic
def install_mir_mbr(mbrtemplate, device, partition, ismirbsdmbr=True):
"""install 'mbr' master boot record (MBR) on a device
- Retrieve the partition table from "device", install an MBR from
- the "mbrtemplate" file, set the "partition" (0..3) active, and
- install the result back to "device".
+ Retrieve the partition table from "device", install an MBR from the
+ "mbrtemplate" file, set the "partition" (0..3) active, and install the
+ result back to "device".
@mbrtemplate: default MBR file
- @device: name of a file assumed to be a hard disc (or USB stick) image,
- or something like "/dev/sdb"
+ @device: name of a file assumed to be a hard disc (or USB stick) image, or
+ something like "/dev/sdb"
+
@partition: must be a number between 0 and 3, inclusive
- @mbrtemplate: must be a valid MBR file of at least 440 (or 439
- if ismirbsdmbr) bytes.
+ @mbrtemplate: must be a valid MBR file of at least 440 (or 439 if
+ ismirbsdmbr) bytes.
- @ismirbsdmbr: if set the partitions' active flags are not changed.
- Instead, the MBR's default value is set accordingly."""
+ @ismirbsdmbr: if true then ignore the active flag, set the mirbsdmbr
+ specific flag to 0/1/2/3 and set the MBR's default value accordingly. If
+ false then leave the mirbsdmbr specific flag set to FFh, set all
+ active flags to 0 and set the active flag of the partition to 80h. Note:
+ behaviour of mirbsdmbr: if flag = 0/1/2/3 then use it, otherwise search for
+ the active flag."""
logging.info("Installing default MBR")
"""
usbdevice = re.match(r'/dev/(.*?)\d*$', device).group(1)
- usbdevice = os.path.realpath('/sys/class/block/' + usbdevice + '/removable')
- if os.path.isfile(usbdevice):
- is_usb = open(usbdevice).readline()
- if is_usb == "1":
+ # newer systems:
+ usbdev = os.path.realpath('/sys/class/block/' + usbdevice + '/removable')
+ if not os.path.isfile(usbdev):
+ # Ubuntu with kernel 2.6.24 for example:
+ usbdev = os.path.realpath('/sys/block/' + usbdevice + '/removable')
+
+ if os.path.isfile(usbdev):
+ is_usb = open(usbdev).readline()
+ if is_usb.find("1"):
return 0
- else:
- return 1
+
+ return 1
def check_for_fat(partition):
# grub all-in-one image
allinoneimg = search_file('allinone.img', iso_mount)
if allinoneimg is None:
- logging.warn("Warning: allinone.img not found - can not install it...")
- logging.warn(" |-> that's fine if you don't need it")
+ logging.warn("Warning: allinone.img not found (that's fine if you don't need it")
else:
logging.debug("cp %s %s" % (allinoneimg, addons + '/allinone.img'))
proc = subprocess.Popen(["cp", allinoneimg, addons + 'allinone.img'])
# bsd imag
bsdimg = search_file('bsd4grml', iso_mount)
if bsdimg is None:
- logging.warn("Warning: bsd4grml not found - can not install it...")
- logging.warn(" |-> that's fine if you don't need it")
+ logging.warn("Warning: bsd4grml not found (that's fine if you don't need it")
else:
logging.debug("cp -a %s %s" % (bsdimg, addons + '/'))
proc = subprocess.Popen(["cp", "-a", bsdimg, addons + '/'])
# freedos image
balderimg = search_file('balder10.imz', iso_mount)
if balderimg is None:
- logging.warn("Warning: balder10.imz not found - can not install it...")
- logging.warn(" |-> that's fine if you don't need it")
+ logging.warn("Warning: balder10.imz not found (that's fine if you don't need it")
else:
logging.debug("cp %s %s" % (balderimg, addons + '/balder10.imz'))
proc = subprocess.Popen(["cp", balderimg, addons + 'balder10.imz'])
# memdisk image
memdiskimg = search_file('memdisk', iso_mount)
if memdiskimg is None:
- logging.warn("Warning: memdisk not found - can not install it...")
- logging.warn(" |-> that's fine if you don't need it")
+ logging.warn("Warning: memdisk not found (that's fine if you don't need it")
else:
logging.debug("cp %s %s" % (memdiskimg, addons + '/memdisk'))
proc = subprocess.Popen(["cp", memdiskimg, addons + 'memdisk'])
# memtest86+ image
memtestimg = search_file('memtest', iso_mount)
if memtestimg is None:
- logging.warn("Warning: memtest not found - can not install it...")
- logging.warn(" |-> that's fine if you don't need it")
+ logging.warn("Warning: memtest not found (that's fine if you don't need it")
else:
logging.debug("cp %s %s" % (memtestimg, addons + '/memtest'))
proc = subprocess.Popen(["cp", memtestimg, addons + 'memtest'])
if not os.path.isfile("/usr/share/grml2usb/grub/splash.xpm.gz"):
logging.critical("Error: /usr/share/grml2usb/grub/splash.xpm.gz can not be read.")
+ logging.critical("Please make sure you've the grml2usb Debian package installed!")
raise
else:
logging.debug("cp /usr/share/grml2usb/grub/splash.xpm.gz %s" % grub_target + 'splash.xpm.gz')
if not options.skipaddons:
if grml_flavour.endswith('-small'):
- logging.info("grml-small doesn't provide any addons, not installing them therefor.")
+ logging.info("Note: grml-small doesn't provide any addons, not installing them therefor.")
else:
copy_addons(iso_mount, target)
if grub_flavour_config:
grub1_config_file = open(grub1_cfg, 'a')
grub1_config_file.write(generate_flavour_specific_grub1_config(grml_flavour, install_partition, bootopt))
- grub1_config_file.close( )
+ grub1_config_file.close()
def handle_grub2_config(grml_flavour, install_partition, grub_target, bootopt):
logging.debug("Creating grub2 configuration file (grub.lst)")
# install main configuration only *once*, no matter how many ISOs we have:
+ grub_flavour_is_default = False
if os.path.isfile(grub2_cfg):
string = open(grub2_cfg).readline()
main_identifier = re.compile(".*main config generated at: %s.*" % re.escape(str(DATESTAMP)))
else:
grub2_config_file = open(grub2_cfg, 'w')
logging.info("Note: grml flavour %s is being installed as the default booting system." % grml_flavour)
+ grub_flavour_is_default = True
grub2_config_file.write(generate_main_grub2_config(grml_flavour, install_partition, bootopt))
grub2_config_file.close()
+ # install flavour specific configuration only *once* as well
grub_flavour_config = True
if os.path.isfile(grub2_cfg):
string = open(grub2_cfg).readlines()
if not grub_flavour_is_default:
logging.info("Note: you can boot flavour %s using '%s' on the commandline." % (grml_flavour, grml_flavour))
grub2_config_file.write(generate_flavour_specific_grub2_config(grml_flavour, install_partition, bootopt))
- grub2_config_file.close( )
+ grub2_config_file.close()
def handle_grub_config(grml_flavour, device, target):
syslinux_cfg = syslinux_target + 'syslinux.cfg'
# install main configuration only *once*, no matter how many ISOs we have:
+ syslinux_flavour_is_default = False
if os.path.isfile(syslinux_cfg):
string = open(syslinux_cfg).readline()
main_identifier = re.compile(".*main config generated at: %s.*" % re.escape(str(DATESTAMP)))
if not re.match(main_identifier, string):
syslinux_config_file = open(syslinux_cfg, 'w')
logging.info("Note: grml flavour %s is being installed as the default booting system." % grml_flavour)
+ syslinux_flavour_is_default = True
syslinux_config_file.write(generate_main_syslinux_config(grml_flavour, bootopt))
syslinux_config_file.close()
else:
syslinux_config_file = open(syslinux_cfg, 'w')
+ logging.info("Note: grml flavour %s is being installed as the default booting system." % grml_flavour)
+ syslinux_flavour_is_default = True
syslinux_config_file.write(generate_main_syslinux_config(grml_flavour, bootopt))
syslinux_config_file.close()
# install flavour specific configuration only *once* as well
- # kind of ugly - I'm pretty sure this could be smoother...
syslinux_flavour_config = True
if os.path.isfile(syslinux_cfg):
string = open(syslinux_cfg).readlines()
- logging.info("Note: you can boot flavour %s using '%s' on the commandline." % (grml_flavour, grml_flavour))
flavour = re.compile("grml2usb for %s: %s" % (re.escape(grml_flavour), re.escape(str(DATESTAMP))))
for line in string:
if flavour.match(line):
if syslinux_flavour_config:
syslinux_config_file = open(syslinux_cfg, 'a')
+ # display only if the grml flavour isn't the default
+ if not syslinux_flavour_is_default:
+ logging.info("Note: you can boot flavour %s using '%s' on the commandline." % (grml_flavour, grml_flavour))
syslinux_config_file.write(generate_flavour_specific_syslinux_config(grml_flavour, bootopt))
- syslinux_config_file.close( )
+ syslinux_config_file.close()
logging.debug("Generating isolinux/syslinux splash %s" % syslinux_target + 'boot.msg')
isolinux_splash = open(syslinux_target + 'boot.msg', 'w')
isolinux_splash.write(generate_isolinux_splash(grml_flavour))
- isolinux_splash.close( )
+ isolinux_splash.close()
def handle_bootloader_config(grml_flavour, device, target):
os.rmdir(iso_mountpoint)
unregister_tmpfile(iso_mountpoint)
if remove_device_mountpoint:
- unmount(device_mountpoint, "")
- if os.path.isdir(device_mountpoint):
- os.rmdir(device_mountpoint)
- unregister_tmpfile(device_mountpoint)
+ try:
+ unmount(device_mountpoint, "")
+ if os.path.isdir(device_mountpoint):
+ os.rmdir(device_mountpoint)
+ unregister_tmpfile(device_mountpoint)
+ except CriticalException, error:
+ logging.critical("Fatal: %s" % error)
+ cleanup()
def handle_mbr(device):
if options.syslinuxmbr:
handle_syslinux_mbr(mbr_device)
else:
- if options.mbrmgr:
+ if options.mbrmenu:
install_mir_mbr('/usr/share/grml2usb/mbr/mbrmgr', mbr_device, partition_number, True)
else:
- install_mir_mbr('/usr/share/grml2usb/mbr/mbrldr', mbr_device, partition_number, True)
+ install_mir_mbr('/usr/share/grml2usb/mbr/mbrldr', mbr_device, partition_number, False)
except IOError, error:
logging.critical("Execution failed: %s", error)
sys.exit(1)
def handle_logging():
"""Log handling and configuration"""
+ if options.verbose and options.quiet:
+ parser.error("please use either verbose (--verbose) or quiet (--quiet) option")
+
if options.verbose:
FORMAT = "Debug: %(asctime)-15s %(message)s"
logging.basicConfig(level=logging.DEBUG, format=FORMAT)