@ -9,6 +9,8 @@
import os
import re
import shutil
from functools import partial
from . usb import *
from . gen import *
from . iso import *
@ -16,42 +18,83 @@ from . import config
from . import grub
from . import menus
from . param_rewrite import add_tokens , remove_tokens , replace_token , \
add_or_replace_kv , replace_kv , remove_keys , \
always , contains_token , contains_all_tokens , contains_any_token , \
contains_key , contains_all_keys , contains_any_key , starter_is_either , _not
def dont_require_tweaking ( fname , content , match_start , match_end ) :
return fname . startswith ( ( ' cdrom/ ' , ' dev/ ' ) ) or \
( 4 < = match_start and # Don't write an arg of 'init=' param.
content [ match_start - 4 : match_start + 1 ] == ' init= ' )
def fix_abspath_r ( pattern , string , install_dir , iso_name ) :
def fix_abspath_r ( pattern , string , install_dir , iso_name , config_fname ):
""" Return a list of tuples consisting of ' string ' with replaced path and a bool representing if /boot/ was prepended in the expression. """
m = pattern . search ( string )
if not m :
return [ ( string , False ) ]
start , end = m . span ( )
prologue , specified_path = m . group ( 1 ) , m . group ( 2 )
if dont_require_tweaking ( specified_path , string , start , end ) :
return [ ( string [ : start ] + prologue + ' / ' + specified_path ,
' / %s is kept as is. ' % specified_path ) ] \
+ fix_abspath_r ( pattern , string [ end : ] , install_dir , iso_name ,
config_fname )
# See if a path that has 'boot/' prepended is a better choice.
# E.g. Debian debian-live-9.4.0-amd64-cinnamon has a loopback.cfg
# which contains "source /grub/grub.cfg".
if os . path . exists ( os . path . join ( install_dir , ' boot ' , specified_path ) ) \
and not os . path . exists ( os . path . join ( install_dir , specified_path ) ) :
selected_path , fixed = ' boot/ ' + specified_path , True
specified_path_exists = os . path . exists (
os . path . join ( install_dir , specified_path ) )
if specified_path_exists :
# Confidently accept what is specified.
selected_path , fixed = specified_path , False
elif os . path . exists ( os . path . join ( install_dir , ' boot ' , specified_path ) ) :
selected_path , fixed = ' boot/ ' + specified_path , " Prepended ' /boot/ ' "
# A path specified by 'preseed/file=' or 'file=' is utilized
# after OS boots up. Doing this for grub is moot.
#elif specified_path.startswith('cdrom/') and \
# os.path.exists(os.path.join(install_dir, # len('cdrom/') => 6
# specified_path[6:])):
# # See /boot/grub/loopback.cfg in
# # ubuntu-14.04.5-desktop-amd64.iso for an example of this case.
# selected_path, fixed = specified_path[6:], "Removed '/cdrom/'"
elif specified_path . endswith ( ' .efi ' ) and \
os . path . exists ( os . path . join ( install_dir , specified_path [ : - 4 ] ) ) :
# Avira-RS provides boot/grub/loopback.cfg which points
# to non-existent /boot/grub/vmlinuz.efi.
selected_path , fixed = specified_path [ : - 4 ] , " Removed ' .efi ' "
else :
# Reluctantly accept what is specified.
log ( " Keeping path [ %s ] in ' %s ' though it does not exist. " % (
specified_path , config_fname ) )
selected_path , fixed = specified_path , False
out = string [ : start ] + prologue + ' /multibootusb/ ' + iso_name + ' / ' \
+ selected_path . replace ( ' \\ ' , ' / ' )
return [ ( out , fixed ) ] \
+ fix_abspath_r ( pattern , string [ end : ] , install_dir , iso_name )
+ fix_abspath_r ( pattern , string [ end : ] , install_dir , iso_name ,
config_fname )
def fix_abspath ( string , install_dir , iso_name ) :
def fix_abspath ( string , install_dir , iso_name , config_fname ):
""" Rewrite what appear to be a path within ' string ' . If a file does not exist with specified path, one with ' /boot ' prepended is tried. """
path_expression = re . compile ( r ' ([ \ t=])/(.*?)((?=[ \ s*])|$) ' )
chunks = fix_abspath_r (
path_expression , string , install_dir , iso_name )
num_boot_prefixing = len ( [ c for c in chunks if c [ 1 ] is True ] )
if num_boot_prefixing == 0 :
path_expression , string , install_dir , iso_name , config_fname )
tweaked_chunks = [ c for c in chunks if c [ 1 ] ]
if len ( tweaked_chunks ) == 0 :
# Fallback to the legacy implementation so that
# this tweak brings as little breakage as possible.
replace_text = r ' \ 1/multibootusb/ ' + iso_name + ' / '
return re . sub ( r ' ([ \ t =,])/ ' , replace_text , string )
else :
log ( " Prepended ' /boot ' to %s . " %
( num_boot_prefixing == 1 and ' a path ' or
( ' %d paths ' % num_boot_prefixing ) ) )
log ( " Applied %s on ' %s ' as shown below: " %
( len ( tweaked_chunks ) == 1 and ' a tweak ' or
( ' %d tweaks ' % len ( tweaked_chunks ) ) , config_fname ) )
for path , op_desc in tweaked_chunks :
log ( " %s " % op_desc )
return ' ' . join ( [ c [ 0 ] for c in chunks ] )
def update_distro_cfg_files ( iso_link , usb_disk , distro , persistence = 0 ) :
@ -67,7 +110,20 @@ def update_distro_cfg_files(iso_link, usb_disk, distro, persistence=0):
config . status_text = " Updating config files... "
_iso_name = iso_basename ( iso_link )
install_dir = os . path . join ( usb_mount , " multibootusb " , _iso_name )
install_dir_for_grub = ' /multibootusb/ %s ' % _iso_name
log ( ' Updating distro specific config files... ' )
tweaker_params = ConfigTweakerParam (
distro , ' /multibootusb/ %s ' % iso_basename ( iso_link ) ,
persistence , usb_uuid , usb_mount , usb_disk )
tweaker_class_dict = {
' ubuntu ' : UbuntuConfigTweaker ,
' debian ' : DebianConfigTweaker ,
' debian-install ' : DebianConfigTweaker ,
' gentoo ' : GentooConfigTweaker ,
}
tweaker_class = tweaker_class_dict . get ( distro )
for dirpath , dirnames , filenames in os . walk ( install_dir ) :
for f in filenames :
if f . endswith ( " .cfg " ) or f . endswith ( ' .CFG ' ) or f . endswith ( ' .lst ' ) or f . endswith ( ' .conf ' ) :
@ -78,28 +134,14 @@ def update_distro_cfg_files(iso_link, usb_disk, distro, persistence=0):
log ( " Unable to read %s " % cfg_file )
else :
if not distro == " generic " :
string = fix_abspath ( string , install_dir , _iso_name )
string = fix_abspath ( string , install_dir , _iso_name ,
os . path . join ( dirpath , f ) )
string = re . sub ( r ' linuxefi ' , ' linux ' , string )
string = re . sub ( r ' initrdefi ' , ' initrd ' , string )
if distro == " ubuntu " :
string = re . sub ( r ' boot=casper ' ,
' boot=casper cdrom-detect/try-usb=true floppy.allowed_drive_mask=0 ignore_uuid '
' ignore_bootid root=UUID= ' + usb_uuid + ' live-media-path=/multibootusb/ '
+ iso_basename ( iso_link ) + ' /casper ' , string )
# Point to correct .seed file
string = re . sub ( r ' /cdrom/preseed ' , ' /preseed ' , string )
string = re . sub ( r ' live-media= \ S* ' , ' live-media=/dev/disk/by-uuid/ ' + usb_uuid , string )
string = re . sub ( r ' ui gfxboot ' , ' #ui gfxboot ' , string )
if persistence != 0 :
string = re . sub ( r ' boot=casper ' , ' boot=casper persistent persistent-path=/multibootusb/ ' +
iso_basename ( iso_link ) + " / " , string )
if tweaker_class :
tweaker = tweaker_class ( tweaker_params )
string = tweaker . tweak ( string )
elif distro in [ " debian " , " debian-install " ] :
string = re . sub ( r ' boot=live ' , ' boot=live ignore_bootid live-media-path=/multibootusb/ ' +
iso_basename ( iso_link ) + ' /live ' , string )
if persistence != 0 :
string = re . sub ( r ' boot=live ' , ' boot=live persistent persistent-path=/multibootusb/ ' +
iso_basename ( iso_link ) + " / " , string )
elif distro == ' grml ' :
string = re . sub ( r ' live-media-path= ' , ' ignore_bootid live-media-path= ' , string )
elif distro == " ubuntu-server " :
@ -178,14 +220,6 @@ def update_distro_cfg_files(iso_link, usb_disk, distro, persistence=0):
r ' finnixdir=/multibootusb/ ' + iso_basename ( iso_link ) + ' /finnix initrd= ' , string )
elif distro == " knoppix " :
string = re . sub ( r ' initrd= ' , ' knoppix_dir=/multibootusb/ ' + iso_basename ( iso_link ) + ' /KNOPPIX initrd= ' , string )
elif distro == " gentoo " :
string = re . sub ( r ' append ' ,
' append real_root= ' + usb_disk + ' slowusb subdir=/multibootusb/ ' +
iso_basename ( iso_link ) + ' / ' , string , flags = re . I )
string = re . sub ( r ' slowusb ' , ' slowusb loop=/multibootusb/ ' +
iso_basename ( iso_link ) + ' /liberte/boot/root-x86.sfs ' , string , flags = re . I )
string = re . sub ( r ' cdroot_hash= \ S* ' , ' ' , string , flags = re . I )
elif distro == " systemrescuecd " :
rows = [ ]
subdir = ' /multibootusb/ ' + iso_basename ( iso_link )
@ -292,18 +326,59 @@ def update_distro_cfg_files(iso_link, usb_disk, distro, persistence=0):
update_mbusb_cfg_file ( iso_link , usb_uuid , usb_mount , distro )
grub . mbusb_update_grub_cfg ( )
# Ensure that isolinux.cfg file is copied as syslinux.cfg to boot correctly.
# copy isolinux.cfg file to syslinux.cfg for grub to boot.
def copy_to_syslinux_cfg_callback ( dir_ , fname ) :
if not fname . lower ( ) . endswith ( ' isolinux.cfg ' ) :
return
isolinux_cfg_path = os . path . join ( dir_ , fname )
syslinux_cfg_fname = fname . replace ( ' isolinux.cfg ' , ' syslinux.cfg ' )
syslinux_cfg_path = os . path . join ( dir_ , syslinux_cfg_fname )
if os . path . exists ( syslinux_cfg_path ) :
return # don't overwrite.
try :
shutil . copyfile ( isolinux_cfg_path , syslinux_cfg_path )
except Exception as e :
log ( ' Copying %s %s to %s failed... ' % (
fname , dir_ , syslinux_cfg_fname ) )
log ( e )
def fix_desktop_image_in_thema_callback ( install_dir_for_grub ,
dir_ , fname ) :
if fname . lower ( ) != ' theme.txt ' :
return
log ( " Probing ' %s ' ! " % fname )
theme_file = os . path . join ( dir_ , fname )
with open ( theme_file , ' r ' ) as f :
lines = [ ]
pattern = re . compile ( r ' ^desktop-image \ s*: \ s*(.*)$ ' )
for line in f . readlines ( ) :
line = line . strip ( )
m = pattern . match ( line )
if m :
log ( " Updating ' %s ' " % line )
partial_path = m . group ( 1 ) . strip ( ' " ' ) . lstrip ( ' / ' )
line = ' desktop-image: " %s / %s " ' % \
( install_dir_for_grub , partial_path )
lines . append ( line )
with open ( theme_file , ' w ' ) as f :
f . write ( ' \n ' . join ( lines ) )
visitor_callbacks = [
# Ensure that isolinux.cfg file is copied as syslinux.cfg
# to boot correctly.
copy_to_syslinux_cfg_callback ,
# Rewrite 'desktop-image: ...' line in a theme definition file
# so that a background image is displaymed during boot item selection.
# This tweak was first introduced for kali-linux-light-2018-1.
partial ( fix_desktop_image_in_thema_callback , install_dir_for_grub ) ,
]
# Now visit the tree.
for dirpath , dirnames , filenames in os . walk ( install_dir ) :
for f in filenames :
if f . lower ( ) . endswith ( " isolinux.cfg " ) :
if not os . path . exists ( os . path . join ( dirpath , " syslinux.cfg " ) ) :
try :
shutil . copyfile ( os . path . join ( dirpath , f ) , os . path . join ( dirpath , " syslinux.cfg " ) )
except Exception as e :
log ( ' Copying isolinux to syslinux failed... ' )
log ( e )
else :
continue
for callback in visitor_callbacks :
callback ( dirpath , f )
# Assertain if the entry is made..
sys_cfg_file = os . path . join ( config . usb_mount , " multibootusb " , " syslinux.cfg " )
@ -419,7 +494,6 @@ def update_mbusb_cfg_file(iso_link, usb_uuid, usb_mount, distro):
elif distro == ' grub2only ' :
config_file . write ( menus . grub2only ( ) )
elif distro == ' memdisk_iso ' :
print ( menus . memdisk_iso_cfg ( syslinux = True , grub = False ) )
config_file . write ( menus . memdisk_iso_cfg ( syslinux = True , grub = False ) )
elif distro == ' memdisk_img ' :
config_file . write ( menus . memdisk_img_cfg ( syslinux = True , grub = False ) )
@ -484,8 +558,10 @@ def update_menu_lst():
def update_grub4dos_iso_menu ( ) :
sys_cfg_file = os . path . join ( config . usb_mount , " multibootusb " , " syslinux.cfg " )
install_dir = os . path . join ( config . usb_mount , " multibootusb " , iso_basename ( config . image_path ) )
sys_cfg_file = os . path . join ( config . usb_mount , " multibootusb " ,
" syslinux.cfg " )
install_dir = os . path . join ( config . usb_mount , " multibootusb " ,
iso_basename ( config . image_path ) )
menu_lst_file = os . path . join ( install_dir , ' menu.lst ' )
with open ( menu_lst_file , " w " ) as f :
f . write ( " title Boot " + iso_name ( config . image_path ) + " \n " )
@ -503,3 +579,369 @@ def update_grub4dos_iso_menu():
f . write ( " KERNEL grub.exe " + " \n " )
f . write ( ' APPEND --config-file=/multibootusb/ ' + iso_basename ( config . image_path ) + ' /menu.lst ' + " \n " )
f . write ( " #end " + iso_basename ( config . image_path ) + " \n " )
class ConfigTweakerParam :
def __init__ ( self , distro_name , distro_path , persistence_size ,
usb_uuid , usb_mount , usb_disk ) :
self . distro_name = distro_name
self . distro_path = distro_path # drive relative
self . persistence_size = persistence_size
self . usb_uuid = usb_uuid
self . usb_mount = usb_mount
self . usb_disk = usb_disk
class ConfigTweaker :
BOOT_PARAMS_STARTER = ' kernel|append|linux '
def __init__ ( self , setup_params ) :
self . setup_params = setup_params
def config_is_persistence_aware ( self , content ) :
""" Used to restrict update of boot parameters to persistent-aware
menu entries if the distribution provides any .
"""
return self . persistence_awareness_checking_re . search ( content ) \
is not None
def tweak_first_match ( self , content , kernel_param_line_pattern ,
apply_persistence_to_all_lines ,
param_operations ,
param_operations_for_persistence ) :
""" Perofrm specified parameter modification to the first maching
line and return the concatination of the string leading up to the
match and the tweaked paramer line . If no match is found ,
unmodified ' content ' is returned .
"""
m = kernel_param_line_pattern . search ( content )
if m is None :
return content
start , end = m . span ( )
upto_match , rest_of_content = content [ : start ] , content [ end : ]
starter_part , starter_token , params_part = [ m . group ( i ) for i in [ 1 , 2 , 3 ] ]
params = params_part . split ( ' ' )
if apply_persistence_to_all_lines or self . has_persistency_param ( params ) :
param_operations = param_operations + \
param_operations_for_persistence
for op_or_op_list , precondition in param_operations :
if not precondition ( starter_token , params ) :
continue
try :
iter ( op_or_op_list )
op_list = op_or_op_list
except TypeError :
op_list = [ op_or_op_list ]
for op in op_list :
params = op ( params )
# I see something special about this param. Place it at the end.
three_dashes = ' --- '
if three_dashes in params :
params . remove ( three_dashes )
params . append ( three_dashes )
return upto_match + starter_part + ' ' . join ( params ) + \
self . tweak_first_match (
rest_of_content , kernel_param_line_pattern ,
apply_persistence_to_all_lines ,
param_operations , param_operations_for_persistence )
def tweak ( self , content ) :
apply_persistence_to_all_lines = \
0 < self . setup_params . persistence_size and \
not self . config_is_persistence_aware ( content )
matching_re = r ' ^( \ s*( %s ) \ s*)(.*)$ ' % self . BOOT_PARAMS_STARTER
kernel_parameter_line_pattern = re . compile (
matching_re ,
flags = re . I | re . MULTILINE )
out = self . tweak_first_match (
content ,
kernel_parameter_line_pattern ,
apply_persistence_to_all_lines ,
self . param_operations ( ) ,
self . param_operations_for_persistence ( ) )
return self . post_process ( out )
def on_liveboot_params ( self , starter , params ) :
return self . LIVE_BOOT_DETECT_PARAM in params
def post_process ( self , entire_string ) :
return entire_string
def add_op_if_file_exists ( self , op_list , op_creator_func , key ,
candidate_relative_path_list , predicate ) :
for candidate in candidate_relative_path_list :
relpath = os . path . join ( self . setup_params . distro_path , candidate )
if os . path . exists ( os . path . join (
self . setup_params . usb_mount , relpath ) ) :
normalized_relpath = relpath . replace ( ' \\ ' , ' / ' )
op_list . append ( ( op_creator_func ( key , normalized_relpath ) ,
predicate ) )
break
class ConfigTweakerWithDebianStylePersistenceParam ( ConfigTweaker ) :
def __init__ ( self , * args , * * kw ) :
super ( ConfigTweakerWithDebianStylePersistenceParam ,
self ) . __init__ ( * args , * * kw )
self . persistence_awareness_checking_re = re . compile (
r ' ^ \ s*( %s ).*? \ s %s ( \ s.*|)$ ' % \
( self . BOOT_PARAMS_STARTER , self . PERSISTENCY_TOKEN ) ,
flags = re . I | re . MULTILINE )
def has_persistency_param ( self , params ) :
return self . PERSISTENCY_TOKEN in params
def param_operations_for_persistence ( self ) :
return [
( [ add_tokens ( self . PERSISTENCY_TOKEN ) ,
add_or_replace_kv ( ' %s -path= ' % self . PERSISTENCY_TOKEN ,
self . setup_params . distro_path ) ] ,
self . on_liveboot_params ) ]
class UbuntuConfigTweaker ( ConfigTweakerWithDebianStylePersistenceParam ) :
LIVE_BOOT_DETECT_PARAM = ' boot=casper '
PERSISTENCY_TOKEN = ' persistent '
def param_operations ( self ) :
return [
( [ add_tokens ( ' ignore_bootid ' ) ,
add_or_replace_kv ( ' live-media-path= ' ,
' %s /casper ' % self . setup_params . distro_path ) ,
add_or_replace_kv ( ' cdrom-detect/try-usb= ' , ' true ' ) ,
# Recently, correct param seems to be 'floppy=0,allowed_driver_mask
add_or_replace_kv ( ' floppy.allowed_drive_mask= ' , ' 0 ' ) ,
add_tokens ( ' ignore_uuid ' ) ,
add_or_replace_kv ( ' root=UUID= ' , self . setup_params . usb_uuid ) ,
] ,
self . on_liveboot_params ) ,
( replace_kv ( ' live-media= ' ,
' /dev/disk/by-uuid/ %s ' % self . setup_params . usb_uuid ) ,
always ) ,
]
def post_process ( self , entire_string ) :
return entire_string . replace ( r ' ui gfxboot ' , ' #ui gfxboot ' )
class DebianConfigTweaker ( ConfigTweakerWithDebianStylePersistenceParam ) :
LIVE_BOOT_DETECT_PARAM = ' boot=live '
PERSISTENCY_TOKEN = ' persistence '
def param_operations ( self ) :
return [
( add_tokens ( ' ignore_bootid ' ) , self . on_liveboot_params ) ,
( add_or_replace_kv ( ' live-media-path= ' ,
' %s /live ' % self . setup_params . distro_path ) ,
self . on_liveboot_params ) ,
]
class NoPersistenceTweaker ( ConfigTweaker ) :
def config_is_persistence_aware ( self , content ) :
return False
def param_operations_for_persistence ( self ) :
return [ ]
def has_persistency_param ( self , params ) :
return False
class GentooConfigTweaker ( NoPersistenceTweaker ) :
def param_operations ( self ) :
ops = [
( [ add_or_replace_kv ( ' real_root= ' , self . setup_params . usb_disk ) ,
add_tokens ( ' slowusb ' ) ,
add_or_replace_kv ( ' subdir= ' , self . setup_params . distro_path ) ,
remove_keys ( ' cdroot_hash= ' ) ,
# Without this, pentoo-amd64-hardened-2018.0_RC5.8_pre20180305/
# stucks at "copying read-write image contents to tmpfs"
add_tokens ( ' overlayfs ' ) ,
# Said distro fails to mount root device if this param is given
remove_tokens ( ' aufs ' ) ,
] ,
starter_is_either ( ' append ' , ' linux ' ) ) ,
]
sfs_path = os . path . join ( self . setup_params . distro_path ,
' liberte ' , ' boot ' , ' root-x86.sfs ' )
self . add_op_if_file_exists (
ops , add_or_replace_kv ,
' loop= ' , [ ' liberte/boot/root-x86.sfs ' , ' image.squashfs ' ] ,
starter_is_either ( ' append ' , ' linux ' ) )
return ops
def test_tweak_objects ( ) :
usb_mount = ' L: '
usb_disk = ' L: '
setup_params_no_persistence = ConfigTweakerParam (
' debian ' , ' /multibootusb/debian ' , 0 , ' { usb-uuid} ' , usb_mount , usb_disk )
debian_tweaker = DebianConfigTweaker ( setup_params_no_persistence )
ubuntu_tweaker = UbuntuConfigTweaker ( setup_params_no_persistence )
# Test awareness on 'persistent'
content = """
append boot = live foo baz = 1 double - spaced ignore_bootid persistent more stuff """ .lstrip()
print ( " Testing awareness on ' persistent ' of ubuntu tweaker. " )
assert ubuntu_tweaker . config_is_persistence_aware ( content )
print ( " Testing awareness on ' persistent ' of debian tweaker. " )
assert not debian_tweaker . config_is_persistence_aware ( content )
content = """
append boot = live foo baz = 1 double - spaced ignore_bootid persistence more stuff """ .lstrip()
print ( " Testing awareness on ' persistence ' of ubuntu tweaker. " )
assert not ubuntu_tweaker . config_is_persistence_aware ( content )
print ( " Testing awareness on ' persistence ' of debian tweaker. " )
assert debian_tweaker . config_is_persistence_aware ( content )
print ( " Testing if ' persistence ' token is left at the original place. " )
content = " \t linux \t foo persistence boot=live in the middle "
assert debian_tweaker . tweak ( content ) == " \t linux \t foo persistence boot=live in the middle ignore_bootid live-media-path=/multibootusb/debian/live persistence-path=/multibootusb/debian " " "
print ( " Testing if ' boot=live ' at the very end is recognized. " )
content = " menu \n \t linux \t foo persistence in the middle boot=live "
assert debian_tweaker . tweak ( content ) == " menu \n \t linux \t foo persistence in the middle boot=live ignore_bootid live-media-path=/multibootusb/debian/live persistence-path=/multibootusb/debian " " "
print ( " Testing if ' boot=live ' at a line end is recognized. " )
content = """ append zoo
\tappend \tfoo persistence in the middle boot = live
append foo """
assert debian_tweaker . tweak ( content ) == """ append zoo
\tappend \tfoo persistence in the middle boot = live ignore_bootid live - media - path = / multibootusb / debian / live persistence - path = / multibootusb / debian
append foo """
print ( " Testing if replacement of ' live-media= ' happens on non-boot lines. " )
content = " \t \t linux live-media=/tobe/replaced "
assert ubuntu_tweaker . tweak ( content ) == \
" \t \t linux live-media=/dev/disk/by-uuid/ { usb-uuid} "
print ( " Testing if \\ tappend is recognized as a starter. " )
content = """ \t append foo boot=live ignore_bootid persistence in the middle live-media-path=/foo/bar """
assert debian_tweaker . tweak ( content ) == """ \t append foo boot=live ignore_bootid persistence in the middle live-media-path=/multibootusb/debian/live persistence-path=/multibootusb/debian """
print ( " Testing if debian tweaker does not get tickled by ' persistent ' . " )
content = """ \t append boot=live foo ignore_bootid persistent in the middle live-media-path=/foo/bar """
assert debian_tweaker . tweak ( content ) == """ \t append boot=live foo ignore_bootid persistent in the middle live-media-path=/multibootusb/debian/live """
print ( " Testing replacement of ' live-media-path ' value. " )
content = " append boot=live foo live-media-path=/foo/bar more "
assert debian_tweaker . tweak ( content ) == """ append boot=live foo live-media-path=/multibootusb/debian/live more ignore_bootid """
print ( " Testing rewriting of ' file= ' param by debian_tweaker. " )
content = " kernel file=/cdrom/preseed/ubuntu.seed boot=live "
setup_params_persistent = ConfigTweakerParam (
' debian ' , ' /multibootusb/debian ' , 128 * 1024 * 1024 , ' { usb-uuid} ' ,
usb_mount , usb_disk )
debian_persistence_tweaker = DebianConfigTweaker (
setup_params_persistent )
ubuntu_persistence_tweaker = UbuntuConfigTweaker (
setup_params_persistent )
print ( " Testing if debian tweaker appends persistence parameters. " )
content = """ label foo
kernel foo bar
append boot = live foo live - media - path = / foo / bar more
"""
assert debian_persistence_tweaker . tweak ( content ) == """ label foo
kernel foo bar
append boot = live foo live - media - path = / multibootusb / debian / live more ignore_bootid persistence persistence - path = / multibootusb / debian
"""
print ( " Testing if ubuntu tweaker selectively appends persistence params. " )
content = """ label foo
kernel foo bar
append boot = casper foo live - media - path = / foo / bar more
"""
assert ubuntu_persistence_tweaker . tweak ( content ) == """ label foo
kernel foo bar
append boot = casper foo live - media - path = / multibootusb / debian / casper more ignore_bootid cdrom - detect / try - usb = true floppy . allowed_drive_mask = 0 ignore_uuid root = UUID = { usb - uuid } persistent persistent - path = / multibootusb / debian
"""
# Test rewrite of persistence-aware configuration.
# Only 'live-persistence' line should receive 'persistence-path'
# parameter.
print ( " Testing if debian tweaker appends persistence params "
" to relevant lines only. " )
content = """ label live-forensic
menu label Live ( ^ forensic mode )
linux / live / vmlinuz
initrd / live / initrd . img
append boot = live noconfig = sudo username = root hostname = kali noswap noautomount
label live - persistence
menu label ^ Live USB Persistence ( check kali . org / prst )
linux / live / vmlinuz
initrd / live / initrd . img
append boot = live noconfig = sudo username = root hostname = kali persistence
"""
assert debian_persistence_tweaker . tweak ( content ) == """ label live-forensic
menu label Live ( ^ forensic mode )
linux / live / vmlinuz
initrd / live / initrd . img
append boot = live noconfig = sudo username = root hostname = kali noswap noautomount ignore_bootid live - media - path = / multibootusb / debian / live
label live - persistence
menu label ^ Live USB Persistence ( check kali . org / prst )
linux / live / vmlinuz
initrd / live / initrd . img
append boot = live noconfig = sudo username = root hostname = kali persistence ignore_bootid live - media - path = / multibootusb / debian / live persistence - path = / multibootusb / debian
"""
setup_params = ConfigTweakerParam (
' debian ' , ' /multibootusb/pentoo-amd64-hardened-2018.0_RC5.8_pre20180305/ ' , 0 , ' { usb-uuid} ' , usb_mount , usb_disk )
gentoo_tweaker = GentooConfigTweaker ( setup_params )
print ( " Testing Gentoo-tweaker on syslinux config. " )
content = """ label pentoo
menu label Pentoo Defaults ( verify )
kernel / isolinux / pentoo
append initrd = / isolinux / pentoo . igz root = / dev / ram0 init = / linuxrc nox nodhcp overlayfs max_loop = 256 dokeymap looptype = squashfs loop = / image . squashfs cdroot video = uvesafb : mtrr : 3 , ywrap , 1024 x768 - 16 usbcore . autosuspend = 1 console = tty0 net . ifnames = 0 scsi_mod . use_blk_mq = 1 ipv6 . autoconf = 0 verify
"""
# Note that you'll have pentoo installed on the flash drive
# for this test to succeed.
assert gentoo_tweaker . tweak ( content ) == """ label pentoo
menu label Pentoo Defaults ( verify )
kernel / isolinux / pentoo
append initrd = / isolinux / pentoo . igz root = / dev / ram0 init = / linuxrc nox nodhcp overlayfs max_loop = 256 dokeymap looptype = squashfs loop = / multibootusb / pentoo - amd64 - hardened - 2018.0 _RC5 .8 _pre20180305 / image . squashfs cdroot video = uvesafb : mtrr : 3 , ywrap , 1024 x768 - 16 usbcore . autosuspend = 1 console = tty0 net . ifnames = 0 scsi_mod . use_blk_mq = 1 ipv6 . autoconf = 0 verify real_root = % s slowusb subdir = / multibootusb / pentoo - amd64 - hardened - 2018.0 _RC5 .8 _pre20180305 /
""" % u sb_disk
print ( " Testing Gentoo-tweaker on grub config. " )
content = """ insmod all_video
menuentry ' Boot LiveCD (kernel: pentoo) ' - - class gnu - linux - - class os {
linux / isolinux / pentoo root = / dev / ram0 init = / linuxrc nox aufs max_loop = 256 dokeymap looptype = squashfs loop = / image . squashfs cdroot cdroot_hash = xxx
initrd / isolinux / pentoo . igz
}
"""
assert gentoo_tweaker . tweak ( content ) == """ insmod all_video
menuentry ' Boot LiveCD (kernel: pentoo) ' - - class gnu - linux - - class os {
linux / isolinux / pentoo root = / dev / ram0 init = / linuxrc nox max_loop = 256 dokeymap looptype = squashfs loop = / multibootusb / pentoo - amd64 - hardened - 2018.0 _RC5 .8 _pre20180305 / image . squashfs cdroot real_root = % s slowusb subdir = / multibootusb / pentoo - amd64 - hardened - 2018.0 _RC5 .8 _pre20180305 / overlayfs
initrd / isolinux / pentoo . igz
}
""" % u sb_disk
def test_abspath_rewrite ( ) :
content = """ menuentry " Install Ubuntu " {
linux / casper / vmlinuz . efi file = / cdrom / preseed / ubuntu . seed boot = casper only - ubiquity init = / linuxrc iso - scan / filename = $ { iso_path } quiet splash - - -
initrd / casper / initrd . lz
} """
print ( fix_abspath (
content , ' g:/multibootusb/ubuntu-14.04.5-desktop-amd64 ' ,
' ubuntu-14.04.5-desktop-amd64 ' , ' test_abspath_rewrite ' ) )
assert fix_abspath (
content , ' g:/multibootusb/ubuntu-14.04.5-desktop-amd64 ' ,
' ubuntu-14.04.5-desktop-amd64 ' , ' test_abspath_rewrite ' ) == \
""" menuentry " Install Ubuntu " {
linux / multibootusb / ubuntu - 14.04 .5 - desktop - amd64 / casper / vmlinuz . efi file = / cdrom / preseed / ubuntu . seed boot = casper only - ubiquity init = / linuxrc iso - scan / filename = $ { iso_path } quiet splash - - -
initrd / multibootusb / ubuntu - 14.04 .5 - desktop - amd64 / casper / initrd . lz
} """