#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Name: update_cfg_file.py
# Purpose: Module to manipulate distro specific and main config files.
# Authors: Sundar
# Licence: This file is a part of multibootusb package. You can redistribute it or modify
# under the terms of GNU General Public License, v.2 or above
import os
import re
import shutil
from functools import partial
from . usb import *
from . gen import *
from . iso import *
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 ) :
# Avoid fixing a path on a comment line
beginning_of_line = content . rfind ( ' \n ' , 0 , match_start )
if beginning_of_line < 0 :
beginning_of_line = 0
if content [ beginning_of_line : match_start ] . lstrip ( ) [ : 1 ] == ' # ' :
return True
if fname . startswith ( ( ' cdrom/ ' , ' dev/ ' ) ) :
return True
if ( 4 < = match_start and # Don't write an arg of 'init=' param.
content [ match_start - 4 : match_start + 1 ] == ' init= ' ) :
return True
def fix_abspath_r ( pattern , string , install_dir , iso_name , kept_paths ) :
""" 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 ,
kept_paths )
# 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".
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/ ' to %s " % specified_path )
# 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 ' from %s " % specified_path )
else :
# Reluctantly accept what is specified.
if specified_path not in kept_paths :
kept_paths . append ( specified_path )
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 ,
kept_paths )
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*])|$) ' )
kept_paths = [ ]
chunks = fix_abspath_r (
path_expression , string , install_dir , iso_name , kept_paths )
if len ( kept_paths ) == 1 :
log ( " In ' %s ' , ' / %s ' is kept as is though it does not exist. "
% ( config_fname , kept_paths [ 0 ] ) )
elif 2 < = len ( kept_paths ) :
log ( " In ' %s ' , "
" following paths are used as they are though they don ' t exist. "
% config_fname )
for kept_path in kept_paths :
log ( ' / ' + kept_path )
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 ( " Applied %s on ' %s ' as shown below: " %
( len ( tweaked_chunks ) == 1 and ' a rewrite exception ' or
( ' %d rewrite exceptions ' % len ( tweaked_chunks ) ) , config_fname ) )
count_dict = { }
for path , op_desc in tweaked_chunks :
count_dict . setdefault ( op_desc , [ ] ) . append ( ( path , op_desc ) )
for op_desc , sub_chunks in count_dict . items ( ) :
log ( " %s [ %d ] " % ( op_desc , len ( sub_chunks ) ) )
return ' ' . join ( [ c [ 0 ] for c in chunks ] )
def update_distro_cfg_files ( iso_link , usb_disk , distro , persistence = 0 ) :
"""
Main function to modify / update distro specific strings on distro config files .
: return :
"""
try :
usb_details = details ( config . usb_disk )
except PartitionNotMounted as e :
log ( str ( e ) )
return
usb_mount = usb_details [ ' mount_point ' ]
usb_uuid = usb_details [ ' uuid ' ]
usb_label = usb_details [ ' label ' ]
usb_fs_type = usb_details [ ' file_system ' ]
# iso_cfg_ext_dir = os.path.join(multibootusb_host_dir(), "iso_cfg_ext_dir")
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 (
iso_link , install_dir_for_grub ,
persistence , usb_uuid , usb_mount , usb_disk , usb_fs_type )
tweaker_class_dict = {
' ubuntu ' : UbuntuConfigTweaker ,
' debian ' : DebianConfigTweaker ,
' debian-install ' : DebianConfigTweaker ,
' gentoo ' : GentooConfigTweaker ,
' centos ' : FedoraConfigTweaker ,
' centos-install ' : FedoraConfigTweaker ,
' fedora ' : FedoraConfigTweaker ,
' antix ' : AntixConfigTweaker ,
' salix-live ' : SalixConfigTweaker ,
' wifislax ' : WifislaxConfigTweaker ,
}
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 ' ) :
cfg_file = os . path . join ( dirpath , f )
try :
string = open ( cfg_file , errors = ' ignore ' ) . read ( )
except IOError :
log ( " Unable to read %s " % cfg_file )
else :
if not distro == " generic " :
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 tweaker_class :
tweaker = tweaker_class ( distro , tweaker_params )
string = tweaker . tweak ( string )
elif distro == ' grml ' :
string = re . sub ( r ' live-media-path= ' , ' ignore_bootid live-media-path= ' , string )
elif distro == " ubuntu-server " :
string = re . sub ( r ' file ' ,
' cdrom-detect/try-usb=true floppy.allowed_drive_mask=0 ignore_uuid ignore_bootid root=UUID= ' +
usb_uuid + ' file ' , string )
elif distro == ' kaspersky ' :
if not os . path . exists ( os . path . join ( usb_mount , ' multibootusb ' , iso_basename ( iso_link ) , ' kaspersky.cfg ' ) ) :
shutil . copyfile ( resource_path ( os . path . join ( ' data ' , ' multibootusb ' , ' syslinux.cfg ' ) ) ,
os . path . join ( usb_mount , ' multibootusb ' , iso_basename ( iso_link ) , ' kaspersky.cfg ' ) )
config_string = kaspersky_config ( ' kaspersky ' )
config_string = config_string . replace ( ' $INSTALL_DIR ' , ' /multibootusb/ ' + iso_basename ( iso_link ) )
config_string = re . sub ( r ' root=live:UUID= ' , ' root=live:UUID= ' + usb_uuid , config_string )
with open ( os . path . join ( usb_mount , ' multibootusb ' , iso_basename ( iso_link ) , ' kaspersky.cfg ' ) , " a " ) as f :
f . write ( config_string )
elif distro == " parted-magic " :
if re . search ( r ' append ' , string , re . I ) :
string = re . sub ( r ' append ' , ' append directory=/multibootusb/ ' + iso_basename ( iso_link ) , string ,
flags = re . I )
string = re . sub ( r ' initrd= ' , ' directory=/multibootusb/ ' + iso_basename ( iso_link ) + ' / initrd= ' ,
string )
string = re . sub ( r ' linux_64= \ " ' , ' linux_64= \" /multibootusb/ ' + iso_basename ( iso_link ) , string ,
flags = re . I )
string = re . sub ( r ' linux_32= \ " ' , ' linux_32= \" /multibootusb/ ' + iso_basename ( iso_link ) , string ,
flags = re . I )
string = re . sub ( r ' initrd_img= \ " ' , ' initrd_img= \" /multibootusb/ ' + iso_basename ( iso_link ) , string ,
flags = re . I )
string = re . sub ( r ' initrd_img32= \ " ' , ' initrd_img32= \" /multibootusb/ ' + iso_basename ( iso_link ) , string ,
flags = re . I )
string = re . sub ( r ' default_settings= \ " ' , ' default_settings= \" directory=/multibootusb/ ' + iso_basename ( iso_link ) + ' ' , string ,
flags = re . I )
string = re . sub ( r ' live_settings= \ " ' , ' live_settings= \" directory=/multibootusb/ ' + iso_basename ( iso_link ) + ' ' , string ,
flags = re . I )
elif distro == " ubcd " :
string = re . sub ( r ' iso_filename= \ S* ' , ' directory=/multibootusb/ ' + iso_basename ( iso_link ) ,
string , flags = re . I )
elif distro == ' f4ubcd ' :
if not ' multibootusb ' in string :
string = re . sub ( r ' /HBCD ' , ' /multibootusb/ ' + iso_basename ( iso_link ) + ' /HBCD ' , string )
if not ' multibootusb ' in string :
string = re . sub ( r ' /F4UBCD ' , ' /multibootusb/ ' + iso_basename ( iso_link ) + ' /F4UBCD ' , string )
elif distro == " ipcop " :
string = re . sub ( r ' ipcopboot=cdrom \ S* ' , ' ipcopboot=usb ' , string )
elif distro == " puppy " :
if ' pmedia=cd ' in string :
string = re . sub ( r ' pmedia=cd \ S* ' ,
' pmedia=usbflash psubok=TRUE psubdir=/multibootusb/ ' + iso_basename ( iso_link ) + ' / ' ,
string )
elif ' rootfstype ' in string :
string = re . sub ( r ' rootfstype ' ,
' pmedia=usbflash psubok=TRUE psubdir=/multibootusb/ ' + iso_basename ( iso_link ) + ' / rootfstype ' ,
string )
elif distro == " slax " :
string = re . sub ( r ' initrd= ' ,
r ' from=/multibootusb/ ' + iso_basename ( iso_link ) + ' /slax changes=/multibootusb/ ' + iso_basename ( iso_link ) + ' /slax fromusb initrd= ' , string )
elif distro == " finnix " :
string = re . sub ( r ' initrd= ' ,
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 == " systemrescuecd " :
rows = [ ]
subdir = ' /multibootusb/ ' + iso_basename ( iso_link )
for line in string . splitlines ( True ) :
addline = True
if re . match ( r ' append.*--.* ' , line , flags = re . I ) :
line = re . sub ( r ' (append)(.*)--(.*) ' , r ' \ 1 \ 2subdir= ' + subdir + r ' -- \ 3 subdir= ' + subdir ,
line , flags = re . I )
elif re . match ( r ' append ' , line , flags = re . I ) :
line = re . sub ( r ' (append) ' , r ' \ 1 subdir= ' + subdir , line , flags = re . I )
elif re . match ( r ' label rescue(32|64)_1 ' , line , flags = re . I ) :
rows . append ( line )
rows . append ( ' append subdir= %s \n ' % ( subdir , ) )
addline = False
if addline :
rows . append ( line )
string = ' ' . join ( rows )
elif distro in [ " arch " , " chakra " ] :
string = re . sub ( r ' isolabel= \ S* ' ,
' isodevice=/dev/disk/by-uuid/ ' + usb_uuid , string , flags = re . I )
string = re . sub ( r ' isobasedir= ' ,
' isobasedir=/multibootusb/ ' + iso_basename ( iso_link ) + ' / ' , string , flags = re . I )
string = commentout_gfxboot ( string )
string = string . replace ( ' % INSTALL_DIR % ' , ' arch ' )
if ' manjaro ' in string :
if not os . path . exists ( os . path . join ( usb_mount , ' .miso ' ) ) :
with open ( os . path . join ( usb_mount , ' .miso ' ) , " w " ) as f :
f . write ( ' ' )
elif distro == " kaos " :
string = re . sub ( r ' kdeosisolabel= \ S* ' ,
' kdeosisodevice=/dev/disk/by-uuid/ ' + usb_uuid , string , flags = re . I )
string = re . sub ( r ' append ' ,
' append kdeosisobasedir=/multibootusb/ ' + iso_basename ( iso_link ) + ' /kdeos/ ' , string , flags = re . I )
string = commentout_gfxboot ( string )
elif distro in [ " suse " , " opensuse " ] :
if re . search ( r ' opensuse_12 ' , string , re . I ) :
string = re . sub ( r ' append ' ,
' append loader=syslinux isofrom_system=/dev/disk/by-uuid/ ' + usb_uuid + " :/ " +
iso_name ( iso_link ) , string , flags = re . I )
else :
string = re . sub ( r ' append ' ,
' append loader=syslinux isofrom_device=/dev/disk/by-uuid/ ' + usb_uuid +
' isofrom_system=/multibootusb/ ' + iso_basename ( iso_link ) + ' / ' + iso_name ( iso_link ) ,
string , flags = re . I )
elif distro == ' opensuse-install ' :
string = re . sub ( r ' splash=silent ' , ' splash=silent install=hd:/dev/disk/by-uuid/ '
+ config . usb_uuid + ' /multibootusb/ ' + iso_basename ( iso_link ) , string )
elif distro == " pclinuxos " :
string = re . sub ( r ' livecd= ' ,
' fromusb livecd= ' + ' /multibootusb/ ' + iso_basename ( iso_link ) + ' / ' ,
string )
string = re . sub ( r ' prompt ' , ' #prompt ' , string )
string = commentout_gfxboot ( string )
string = re . sub ( r ' timeout ' , ' #timeout ' , string )
elif distro == " wifislax " :
string = re . sub ( r ' vmlinuz ' ,
' vmlinuz from=multibootusb/ ' + iso_basename ( iso_link ) + ' noauto ' , string )
string = re . sub ( r ' vmlinuz2 ' ,
' vmlinuz2 from=multibootusb/ ' + iso_basename ( iso_link ) + ' noauto ' , string )
elif distro == " porteus " :
string = re . sub ( r ' APPEND ' ,
' APPEND from=/multibootusb/ ' + iso_basename ( iso_link ) + ' noauto ' , string )
string = re . sub ( r ' vmlinuz2 ' ,
' vmlinuz2 from=multibootusb/ ' + iso_basename ( iso_link ) + ' noauto ' , string )
elif distro == " hbcd " :
if not ' multibootusb ' in string :
string = re . sub ( r ' /HBCD ' , ' /multibootusb/ ' + iso_basename ( iso_link ) + ' /HBCD ' , string )
elif distro == " zenwalk " :
string = re . sub ( r ' initrd= ' ,
' from=/multibootusb/ ' + iso_basename ( iso_link ) + ' / ' + iso_name ( iso_link ) + ' initrd= ' ,
string )
elif distro == " mageialive " :
string = re . sub ( r ' LABEL= \ S* ' , ' UUID= ' + usb_uuid + ' mgalive.basedir=/multibootusb/ ' + iso_basename ( iso_link ) ,
string )
elif distro == " solydx " :
string = re . sub ( r ' live-media-path= ' , ' live-media-path=/multibootusb/ ' + iso_basename ( iso_link ) ,
string )
elif distro == ' alt-linux ' :
string = re . sub ( r ' :cdrom ' , ' :disk ' , string )
elif distro == ' fsecure ' :
string = re . sub ( r ' APPEND ramdisk_size ' , ' APPEND noprompt ' + ' knoppix_dir=/multibootusb/ ' + iso_basename ( iso_link )
+ ' /KNOPPIX ramdisk_size ' , string )
elif distro == ' alpine ' :
string = re . sub ( r ' modules ' , ' alpine_dev=usbdisk:vfat modules ' , string )
elif config . distro == ' trinity-rescue ' :
# USB disk must have volume label to work properly
string = re . sub ( r ' initrd= ' , ' vollabel= ' + config . usb_label + ' initrd= ' , string )
string = re . sub ( r ' root= \ S* ' , ' root=/dev/ram0 ' , string , flags = re . I )
config_file = open ( cfg_file , " w " )
config_file . write ( string )
config_file . close ( )
update_mbusb_cfg_file ( iso_link , usb_uuid , usb_mount , distro )
grub . mbusb_update_grub_cfg ( )
# 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 . lower ( ) . 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 not fname . lower ( ) . endswith ( ' .txt ' ) :
return
theme_file = os . path . join ( dir_ , fname )
updated = False
with open ( theme_file , ' r ' , encoding = ' utf-8 ' ) as f :
pattern = re . compile ( r ' ^desktop-image \ s*: \ s*(.*)$ ' )
try :
src_lines = f . readlines ( )
except UnicodeDecodeError :
log ( " Unexpected encoding in %s " % theme_file )
return
lines = [ ]
for line in src_lines :
line = line . rstrip ( )
m = pattern . match ( line )
if m and m . group ( 1 ) . startswith ( ( ' / ' , ' " / ' ) ) :
log ( " Updating ' %s ' in %s " % ( line , theme_file ) )
updated = True
partial_path = m . group ( 1 ) . strip ( ' " ' ) . lstrip ( ' / ' )
line = ' desktop-image: " %s / %s " ' % \
( install_dir_for_grub , partial_path )
lines . append ( line )
if updated :
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 :
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 " )
if gen . check_text_in_file ( sys_cfg_file , iso_basename ( config . image_path ) ) :
log ( ' Updated entry in syslinux.cfg... ' )
else :
log ( ' Unable to update entry in syslinux.cfg... ' )
# Check if bootx64.efi is replaced by distro
efi_grub_img = os . path . join ( config . usb_mount , ' EFI ' , ' BOOT ' , ' bootx64.efi ' )
if not os . path . exists ( efi_grub_img ) :
gen . log ( ' EFI image does not exist. Copying now... ' )
shutil . copy2 ( resource_path ( os . path . join ( " data " , " EFI " , " BOOT " , " bootx64.efi " ) ) ,
os . path . join ( config . usb_mount , ' EFI ' , ' BOOT ' ) )
elif gen . grub_efi_exist ( efi_grub_img ) is False :
if distro == " Windows " :
gen . log ( ' EFI image overwritten by Windows install. Moving it now... ' )
dst = os . path . join ( config . usb_mount , ' EFI ' , ' BOOT_WINDOWS ' )
os . makedirs ( dst )
shutil . move ( efi_grub_img , dst )
else :
gen . log ( ' EFI image overwritten by distro install. Replacing it now... ' )
shutil . copy2 ( resource_path ( os . path . join ( " data " , " EFI " , " BOOT " , " bootx64.efi " ) ) ,
os . path . join ( config . usb_mount , ' EFI ' , ' BOOT ' ) )
else :
gen . log ( ' multibootusb EFI image already exist. Not copying... ' )
# Bug in the isolinux package
def commentout_gfxboot ( input_text ) :
return re . sub ( r ' (ui \ s+.*?gfxboot \ .c32.*)$ ' , r ' # \ 1 ' , input_text ,
flags = re . I | re . MULTILINE )
def update_mbusb_cfg_file ( iso_link , usb_uuid , usb_mount , distro ) :
"""
Update main multibootusb syslinux . cfg file after distro is installed .
: return :
"""
log ( ' Updating multibootusb config file... ' )
name_from_iso = iso_basename ( iso_link )
name_of_iso = iso_name ( iso_link )
_isolinux_bin_exists = isolinux_bin_exist ( config . image_path )
_isolinux_bin_dir = isolinux_bin_dir ( iso_link )
sys_cfg_file = os . path . join ( usb_mount , " multibootusb " , " syslinux.cfg " )
install_dir = os . path . join ( usb_mount , " multibootusb " , name_from_iso )
label = name_from_iso + ( ' ' if _isolinux_bin_exists else ' via GRUB ' )
if os . path . exists ( sys_cfg_file ) :
if distro == " hbcd " :
if os . path . exists ( os . path . join ( usb_mount , " multibootusb " , " menu.lst " ) ) :
_config_file = os . path . join ( usb_mount , " multibootusb " , " menu.lst " )
config_file = open ( _config_file , " w " )
string = re . sub ( r ' /HBCD ' , ' /multibootusb/ ' + name_from_iso + ' /HBCD ' , _config_file )
config_file . write ( string )
config_file . close ( )
with open ( sys_cfg_file , " a " ) as f :
f . write ( " #start " + iso_basename ( config . image_path ) + " \n " )
f . write ( " LABEL " + label + " \n " )
f . write ( " MENU LABEL " + label + " \n " )
f . write ( " BOOT " + ' /multibootusb/ ' + name_from_iso + ' / ' + _isolinux_bin_dir . replace ( " \\ " , " / " ) + ' / ' + distro + ' .bs ' + " \n " )
f . write ( " #end " + iso_basename ( config . image_path ) + " \n " )
elif distro == " Windows " :
if os . path . exists ( sys_cfg_file ) :
config_file = open ( sys_cfg_file , " a " )
config_file . write ( " #start " + name_from_iso + " \n " )
config_file . write ( " LABEL " + label + " \n " )
config_file . write ( " MENU LABEL " + label + " \n " )
config_file . write ( " KERNEL chain.c32 hd0 1 ntldr=/bootmgr " + " \n " )
config_file . write ( " #end " + name_from_iso + " \n " )
config_file . close ( )
elif distro == ' f4ubcd ' :
if os . path . exists ( sys_cfg_file ) :
config_file = open ( sys_cfg_file , " a " )
config_file . write ( " #start " + name_from_iso + " \n " )
config_file . write ( " LABEL " + label + " \n " )
config_file . write ( " MENU LABEL " + label + " \n " )
config_file . write ( " KERNEL grub.exe " + " \n " )
config_file . write ( ' APPEND --config-file=/multibootusb/ ' + iso_basename ( config . image_path ) + ' /menu.lst ' + " \n " )
config_file . write ( " #end " + name_from_iso + " \n " )
config_file . close ( )
elif distro == ' kaspersky ' :
if os . path . exists ( sys_cfg_file ) :
config_file = open ( sys_cfg_file , " a " )
config_file . write ( " #start " + name_from_iso + " \n " )
config_file . write ( " LABEL " + label + " \n " )
config_file . write ( " MENU LABEL " + label + " \n " )
config_file . write ( " CONFIG " + ' /multibootusb/ ' + iso_basename ( config . image_path ) + ' /kaspersky.cfg ' + " \n " )
config_file . write ( " #end " + name_from_iso + " \n " )
config_file . close ( )
elif distro == ' grub4dos ' :
update_menu_lst ( )
elif distro == ' grub4dos_iso ' :
update_grub4dos_iso_menu ( )
else :
config_file = open ( sys_cfg_file , " a " )
config_file . write ( " #start " + name_from_iso + " \n " )
config_file . write ( " LABEL " + label + " \n " )
config_file . write ( " MENU LABEL " + label + " \n " )
if distro == " salix-live " :
if os . path . exists (
os . path . join ( install_dir , ' boot ' , ' grub2-linux.img ' ) ) :
config_file . write (
" LINUX " + ' /multibootusb/ ' + name_from_iso +
' /boot/grub2-linux.img ' + " \n " )
else :
config_file . write ( " BOOT " + ' /multibootusb/ ' + name_from_iso + ' / ' + _isolinux_bin_dir . replace ( " \\ " , " / " ) + ' / ' + distro + ' .bs ' + " \n " )
elif distro == " pclinuxos " :
config_file . write ( " kernel " + ' /multibootusb/ ' + name_from_iso
+ ' /isolinux/vmlinuz ' + " \n " )
config_file . write ( " append livecd=livecd root=/dev/rd/3 acpi=on vga=788 keyb=us vmalloc=256M nokmsboot "
" fromusb root=UUID= " + usb_uuid + " bootfromiso=/multibootusb/ " +
name_from_iso + " / " + name_of_iso + " initrd=/multibootusb/ "
+ name_from_iso + ' /isolinux/initrd.gz ' + " \n " )
elif distro == " memtest " :
config_file . write ( " kernel " + ' /multibootusb/ ' + name_from_iso + ' /BOOT/MEMTEST.IMG \n ' )
elif distro == " sgrubd2 " or config . distro == ' raw_iso ' :
config_file . write ( " LINUX memdisk \n " )
config_file . write ( " INITRD " + " /multibootusb/ " + name_from_iso + ' / ' + name_of_iso + ' \n ' )
config_file . write ( " APPEND iso \n " )
elif distro == ' ReactOS ' :
config_file . write ( " COM32 mboot.c32 " + ' \n ' )
config_file . write ( " APPEND /loader/setupldr.sys " + ' \n ' )
elif distro == ' pc-unlocker ' :
config_file . write ( " kernel ../ldntldr " + ' \n ' )
config_file . write ( " append initrd=../ntldr " + ' \n ' )
elif distro == ' pc-tool ' :
config_file . write ( menus . pc_tool_config ( syslinux = True , grub = False ) )
elif distro == ' grub2only ' :
config_file . write ( menus . grub2only ( ) )
elif distro == ' memdisk_iso ' :
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 ) )
else :
if _isolinux_bin_exists is True :
if distro == " generic " :
distro_syslinux_install_dir = _isolinux_bin_dir
if _isolinux_bin_dir != " / " :
distro_sys_install_bs = os . path . join ( usb_mount , _isolinux_bin_dir ) + ' / ' + distro + ' .bs '
else :
distro_sys_install_bs = ' / ' + distro + ' .bs '
else :
distro_syslinux_install_dir = install_dir
distro_syslinux_install_dir = distro_syslinux_install_dir . replace ( usb_mount , ' ' )
distro_sys_install_bs = distro_syslinux_install_dir + ' / ' + _isolinux_bin_dir + ' / ' + distro + ' .bs '
distro_sys_install_bs = " / " + distro_sys_install_bs . replace ( " \\ " , " / " ) # Windows path issue.
if config . syslinux_version == ' 3 ' :
config_file . write ( " CONFIG /multibootusb/ " + name_from_iso + ' / ' + _isolinux_bin_dir . replace ( " \\ " , " / " ) + ' /isolinux.cfg \n ' )
config_file . write ( " APPEND /multibootusb/ " + name_from_iso + ' / ' + _isolinux_bin_dir . replace ( " \\ " , " / " ) + ' \n ' )
config_file . write ( " # Delete or comment above two lines using # and remove # from below line if "
" you get not a COM module error. \n " )
config_file . write ( " #BOOT " + distro_sys_install_bs . replace ( " // " , " / " ) + " \n " )
else :
config_file . write ( " BOOT " + distro_sys_install_bs . replace ( " // " , " / " ) + " \n " )
else :
# isolinux_bin does not exist.
config_file . write ( ' Linux /multibootusb/grub/lnxboot.img \n ' )
config_file . write ( ' INITRD /multibootusb/grub/core.img \n ' )
config_file . write ( ' TEXT HELP \n ' )
config_file . write ( ' Booting via syslinux is not supported. '
' Please boot via GRUB \n ' )
config_file . write ( ' ENDTEXT \n ' )
config_file . write ( " #end " + name_from_iso + " \n " )
config_file . close ( )
# Update extlinux.cfg file by copying updated syslinux.cfg
shutil . copy ( os . path . join ( usb_mount , ' multibootusb ' , ' syslinux.cfg ' ) ,
os . path . join ( usb_mount , ' multibootusb ' , ' extlinux.cfg ' ) )
def kaspersky_config ( distro ) :
if distro == ' kaspersky ' :
return """
menu label Kaspersky Rescue Disk
kernel $ INSTALL_DIR / boot / rescue
append root = live : UUID = live_dir = $ INSTALL_DIR / rescue / LiveOS / subdir = $ INSTALL_DIR / rescue / LiveOS / looptype = squashfs rootfstype = auto vga = 791 init = / linuxrc loop = $ INSTALL_DIR / rescue / LiveOS / squashfs . img initrd = $ INSTALL_DIR / boot / rescue . igz lang = en udev liveimg splash quiet doscsi nomodeset
label text
menu label Kaspersky Rescue Disk - Text Mode
kernel $ INSTALL_DIR / boot / rescue
append root = live : UUID = live_dir = $ INSTALL_DIR / rescue / LiveOS / subdir = $ INSTALL_DIR / rescue / LiveOS / rootfstype = auto vga = 791 init = / linuxrc loop = / multiboot / rescue / LiveOS / squashfs . img initrd = $ INSTALL_DIR / boot / rescue . igz SLUG_lang = en udev liveimg quiet nox shell noresume doscsi nomodeset
label hwinfo
menu label Kaspersky Hardware Info
kernel $ INSTALL_DIR / boot / rescue
append root = live : UUID = live_dir = $ INSTALL_DIR / rescue / LiveOS / subdir = $ INSTALL_DIR / rescue / LiveOS / rootfstype = auto vga = 791 init = / linuxrc loop = $ INSTALL_DIR / rescue / LiveOS / squashfs . img initrd = $ INSTALL_DIR / boot / rescue . igz SLUG_lang = en udev liveimg quiet softlevel = boot nox hwinfo noresume doscsi nomodeset """
def update_menu_lst ( ) :
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 = iso_menu_lst_path ( config . image_path ) . replace ( " \\ " , " / " )
with open ( sys_cfg_file , " a " ) as f :
f . write ( " #start " + iso_basename ( config . image_path ) + " \n " )
f . write ( " LABEL " + iso_basename ( config . image_path ) + " \n " )
f . write ( " MENU LABEL " + iso_basename ( config . image_path ) + " \n " )
f . write ( " KERNEL grub.exe " + " \n " )
f . write ( ' APPEND --config-file=/ ' + menu_lst + " \n " )
f . write ( " #end " + iso_basename ( config . image_path ) + " \n " )
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 ) )
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 " )
f . write ( " find --set-root --ignore-floppies --ignore-cd /multibootusb/ " + iso_basename ( config . image_path ) + ' / '
+ iso_name ( config . image_path ) + " \n " )
f . write ( " map --heads=0 --sectors-per-track=0 /multibootusb/ " + iso_basename ( config . image_path )
+ ' / ' + iso_name ( config . image_path ) + ' (hd32) ' + " \n " )
f . write ( " map --hook " + " \n " )
f . write ( " chainloader (hd32) " )
with open ( sys_cfg_file , " a " ) as f :
f . write ( " #start " + iso_basename ( config . image_path ) + " \n " )
f . write ( " LABEL " + iso_basename ( config . image_path ) + " \n " )
f . write ( " MENU LABEL " + iso_basename ( config . image_path ) + " \n " )
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 :
# 'iso_link' is also known as 'image_path'
def __init__ ( self , iso_link , distro_path , persistence_size ,
usb_uuid , usb_mount , usb_disk , usb_fs_type ) :
self . iso_fname = os . path . split ( iso_link ) [ 1 ]
self . distro_name = os . path . splitext ( self . iso_fname ) [ 0 ]
assert distro_path [ 0 ] == ' / '
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
self . usb_fs_type = usb_fs_type
class ConfigTweaker :
BOOT_PARAMS_STARTER = ' kernel|append|linux '
def __init__ ( self , distro_type , setup_params ) :
self . disto_type = distro_type
self . setup_params = setup_params
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 ) :
ops_to_apply = param_operations + \
param_operations_for_persistence
else :
ops_to_apply = param_operations
for op_or_op_list , precondition in ops_to_apply :
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 legacy_tweak ( self , content ) :
return None
def tweak ( self , content ) :
tweaked = self . legacy_tweak ( content )
if tweaked :
return tweaked
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 [ 1 : ] ,
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
def fullpath ( self , subpath ) :
p = self . setup_params
return os . path . join ( p . usb_mount , p . distro_path [ 1 : ] ,
subpath ) . replace ( ' / ' , os . sep )
def file_is_installed ( self , subpath ) :
return os . path . exists ( self . fullpath ( subpath ) )
def file_content ( self , subpath ) :
fp = self . fullpath ( subpath )
if not os . path . exists ( fp ) :
return None
with open ( fp , errors = ' ignore ' ) as f :
return f . read ( )
def extract_distroinfo_from_file ( self , subpath , regex , distro_group ,
version_group ) :
content = self . file_content ( subpath )
if not content :
return None
m = re . compile ( regex , re . I ) . search ( content )
if not m :
return None
return ( m . group ( distro_group ) ,
[ int ( x ) for x in m . group ( version_group ) . split ( ' . ' ) ] )
def extract_distroinfo_from_fname ( self , which_dir , regex , distro_group ,
version_group ) :
p = re . compile ( regex , re . I )
for fname in os . listdir ( self . fullpath ( which_dir ) ) :
m = p . match ( fname )
if m :
return ( m . group ( distro_group ) ,
[ int ( x ) for x in m . group ( version_group ) . split ( ' . ' ) ] )
return None
class PersistenceConfigTweaker ( ConfigTweaker ) :
def __init__ ( self , pac_re , * args , * * kw ) :
self . persistence_awareness_checking_re = pac_re
super ( PersistenceConfigTweaker , self ) . __init__ ( * args , * * kw )
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
class ConfigTweakerWithDebianStylePersistenceParam ( PersistenceConfigTweaker ) :
def __init__ ( self , * args , * * kw ) :
persistence_awareness_checking_re = re . compile (
r ' ^ \ s*( %s ).*? \ s %s ( \ s.*|)$ ' % \
( self . BOOT_PARAMS_STARTER , self . PERSISTENCY_TOKEN ) ,
flags = re . I | re . MULTILINE )
super ( ConfigTweakerWithDebianStylePersistenceParam ,
self ) . __init__ ( persistence_awareness_checking_re , * args , * * kw )
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 ) :
uuid_spec = ' UUID= %s ' % self . setup_params . usb_uuid
ops = [
( [ add_or_replace_kv ( ' real_root= ' , uuid_spec ) ,
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 ' ) ) ,
]
fs_type = self . setup_params . usb_fs_type
if fs_type == ' vfat ' :
ops . append ( ( add_or_replace_kv ( ' cdroot_type= ' , fs_type ) ,
always ) )
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
class FedoraConfigTweaker ( PersistenceConfigTweaker ) :
def __init__ ( self , * args , * * kw ) :
persistence_awareness_checking_re = re . compile (
r ' ^ \ s*( %s ).*? \ s(rd.live.overlay|overlay)=.+? ' %
self . BOOT_PARAMS_STARTER , flags = re . I | re . MULTILINE )
super ( FedoraConfigTweaker , self ) . __init__ (
persistence_awareness_checking_re , * args , * * kw )
def has_persistency_param ( self , params ) :
return any ( p . startswith ( ( ' overlay= ' , ' rd.live.overlay= ' ) )
for p in params )
def param_operations ( self ) :
uuid_spec = ' UUID= %s ' % self . setup_params . usb_uuid
escaped_distro_path = self . setup_params . distro_path \
. replace ( ' ' , ' \\ 0x20 ' )
live_path = escaped_distro_path + ' /LiveOS '
ops = [ ( replace_kv ( ' inst.stage2= ' , ' hd: %s : %s ' %
( uuid_spec , escaped_distro_path ) ) , always ) ,
( add_or_replace_kv ( ' inst.repo= ' ,
' http://mirror.centos.org '
' /centos/7/os/x86_64/ ' ) ,
contains_key ( ' inst.stage2= ' ) ) ,
( replace_kv ( ' root= ' , ' live: ' + uuid_spec ) , always ) ,
( add_or_replace_kv ( ' rd.live.dir= ' , live_path ) ,
contains_any_token ( ' rd.live.image ' , ' Solus ' ) ) ,
( add_or_replace_kv ( ' live_dir= ' , live_path ) ,
contains_token ( ' liveimage ' ) ) , ]
if self . file_is_installed ( ' .treeinfo ' ) :
# Add or replace value of 'inst.repo=' with reference
# to the copied iso.
ops . append (
( add_or_replace_kv (
' inst.repo= ' ,
' hd:UUID= %s : %s ' % (
self . setup_params . usb_uuid ,
self . setup_params . distro_path + ' / ' +
self . setup_params . iso_fname ) ) ,
starter_is_either ( ' append ' , ' linux ' ) ) )
return ops
def param_operations_for_persistence ( self ) :
uuid_spec = ' UUID= %s ' % self . setup_params . usb_uuid
return [
( remove_tokens ( ' ro ' ) , always ) ,
( add_or_replace_kv ( ' overlay= ' , uuid_spec ) ,
contains_token ( ' liveimage ' ) ) ,
( [ add_tokens ( ' rw ' ) ,
add_or_replace_kv ( ' rd.live.overlay= ' , uuid_spec ) ] ,
contains_token ( ' rd.live.image ' ) )
]
class AntixConfigTweaker ( NoPersistenceTweaker ) :
def param_operations ( self ) :
dinfo = self . extract_distroinfo_from_file (
' version ' , r ' (antiX|MX)-( \ d+ \ . \ d+) ' , 1 , 2 )
if not dinfo :
dinfo = self . extract_distroinfo_from_file (
' boot/isolinux/isolinux.cfg ' , r ' (antiX|MX)-( \ d+ \ . \ d+) ' , 1 , 2 )
if not dinfo :
dinfo = self . extract_distroinfo_from_fname (
' ' , r ' (MX)-( \ d+ \ . \ d+).* ' , 1 , 2 )
if dinfo and 17 < = dinfo [ 1 ] [ 0 ] :
ops = [
add_or_replace_kv ( ' buuid= ' , self . setup_params . usb_uuid ) ,
add_or_replace_kv ( ' bdir= ' ,
self . setup_params . distro_path + ' /antiX ' ) ]
else :
ops = add_or_replace_kv ( ' image_dir= ' ,
self . setup_params . distro_path )
return [ ( ops , starter_is_either ( ' append ' , ' APPEND ' , ' linux ' ) ) ]
def post_process ( self , s ) :
s = re . sub ( r ' ^( \ s*UI \ s+(.*?gfxboot( \ .c32|))) \ s+(.*?) \ s+(.*)$ ' ,
r ' # \ 1 \ 4.renamed-to-avoid-lockup \ 5 ' , s ,
flags = re . I + re . MULTILINE )
return s
class SalixConfigTweaker ( NoPersistenceTweaker ) :
def legacy_tweak ( self , content ) :
if content . find ( ' iso_path ' ) < 0 :
return None
p = self . setup_params
for replacee , replacer in [
( ' iso_path ' , " %s / %s " % ( p . distro_path , p . iso_fname ) ) ,
( ' initrd= ' , ' fromiso= %s / %s initrd= ' % (
p . distro_path , p . iso_fname ) ) ,
] :
content = content . replace ( replacee , replacer )
return content
# salixlive-xfce-14.2.1 assumes that the installation media is
# labeled "LIVE" and the file tree is exploded at the root.
# (See /init for details.) Supporing it in harmony with installation
# of other distros is very hard to impossible. Do nothing here.
def param_operations ( self ) :
return [ ]
class WifislaxConfigTweaker ( NoPersistenceTweaker ) :
def param_operations ( self ) :
ops = [
( add_or_replace_kv ( ' livemedia= ' , ' %s : %s / %s ' % (
self . setup_params . usb_uuid , self . setup_params . distro_path ,
self . setup_params . iso_fname ) ) ,
starter_is_either ( ' append ' , ' linux ' ) ) ]
return ops
def post_process ( self , entire_string ) :
return entire_string . replace ( ' ($root) ' , self . setup_params . distro_path )
def test_tweak_objects ( ) :
def os_path_exists ( f ) :
if f . endswith ( ' liberte/boot/root-x86.sfs ' ) :
return False
if f . endswith ( ' image.squashfs ' ) :
return True
return False
saved = os . path . exists
os . path . exists = os_path_exists
try :
_test_tweak_objects ( )
finally :
os . path . exists = saved
def _test_tweak_objects ( ) :
usb_mount = ' L: '
usb_disk = ' L: '
setup_params_no_persistence = ConfigTweakerParam (
' { iso-name} ' , ' /multibootusb/ { iso-name} ' , 0 ,
' { usb-uuid} ' , usb_mount , usb_disk )
debian_tweaker = DebianConfigTweaker ( ' debian ' , setup_params_no_persistence )
ubuntu_tweaker = UbuntuConfigTweaker ( ' ubuntu ' , setup_params_no_persistence )
centos_tweaker = FedoraConfigTweaker ( ' centos ' , setup_params_no_persistence )
salix_tweaker = SalixConfigTweaker ( ' centos ' , 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 awareness on ' overlay= ' of centos tweaker. " )
content = """
append boot = live foo baz = 1 overlay = UUID : 2234 - 1224 double - spaced ignore_bootid persistence more stuff """ .lstrip()
assert centos_tweaker . config_is_persistence_aware ( content )
print ( " Testing awareness on ' rd.live.overlay= ' of centos tweaker. " )
content = """
append boot = live foo baz = 1 rd . live . overlay = UUID : 2234 - 1224 double - spaced ignore_bootid persistence more stuff """ .lstrip()
assert centos_tweaker . config_is_persistence_aware ( content )
print ( " Testing indefference on persistence keys of centos tweaker. " )
content = """
append boot = live foo baz = 1 double - spaced ignore_bootid persistence more stuff """ .lstrip()
assert not centos_tweaker . config_is_persistence_aware ( content )
print ( " Testing awareness on ' overlay= ' of centos tweaker. " )
content = """
append boot = live foo baz = 1 double - spaced ignore_bootid persistence more stuff """ .lstrip()
assert not centos_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/ { iso-name}/live persistence-path=/multibootusb/ { iso-name} " " "
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/ { iso-name}/live persistence-path=/multibootusb/ { iso-name} " " "
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 / { iso - name } / live persistence - path = / multibootusb / { iso - name }
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/ { iso-name}/live persistence-path=/multibootusb/ { iso-name} """
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/ { iso-name}/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/ { iso-name}/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/ { iso-name} ' , 128 * 1024 * 1024 , ' { usb-uuid} ' ,
usb_mount , usb_disk )
debian_persistence_tweaker = DebianConfigTweaker (
' debian ' , setup_params_persistent )
ubuntu_persistence_tweaker = UbuntuConfigTweaker (
' ubuntu ' , setup_params_persistent )
centos_persistence_tweaker = FedoraConfigTweaker (
' centos ' , 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 / { iso - name } / live more ignore_bootid persistence persistence - path = / multibootusb / { iso - name }
"""
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 / { iso - name } / casper more ignore_bootid cdrom - detect / try - usb = true floppy . allowed_drive_mask = 0 ignore_uuid root = UUID = { usb - uuid } persistent persistent - path = / multibootusb / { iso - name }
"""
# 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 / { iso - name } / 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 / { iso - name } / live persistence - path = / multibootusb / { iso - name }
"""
setup_params = ConfigTweakerParam (
' { iso-name} ' , ' /multibootusb/ { iso-name} ' ,
0 , ' { usb-uuid} ' , usb_mount , usb_disk )
gentoo_tweaker = GentooConfigTweaker ( ' gentoo ' , 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
"""
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 / { iso - name } / 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 / { iso - name }
""" % 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 / { iso - name } / image . squashfs cdroot real_root = % s slowusb subdir = / multibootusb / { iso - name } overlayfs
initrd / isolinux / pentoo . igz
}
""" % u sb_disk
print ( " Testing centos tweaker on DVD-installer " )
saved = os . path . exists
os . path . exists = lambda f : f . endswith ( ( ' /.treeinfo ' , ' \\ .treeinfo ' ) ) \
or saved ( f )
try :
content = r """ label linux
menu label ^ Install CentOS 7
kernel vmlinuz
append initrd = initrd . img inst . stage2 = hd : LABEL = CentOS \x207 \x20x86_64 quiet
"""
assert centos_tweaker . tweak ( content ) == """ label linux
menu label ^ Install CentOS 7
kernel vmlinuz
append initrd = initrd . img inst . stage2 = hd : UUID = { usb - uuid } : / multibootusb / { iso - name } quiet inst . repo = hd : UUID = { usb - uuid } : / multibootusb / { iso - name } / { iso - name } . iso
"""
finally :
os . path . exists = saved
print ( " Testing centos tweaker on Net-installer " )
assert centos_tweaker . tweak ( content ) == """ label linux
menu label ^ Install CentOS 7
kernel vmlinuz
append initrd = initrd . img inst . stage2 = hd : UUID = { usb - uuid } : / multibootusb / { iso - name } quiet inst . repo = http : / / mirror . centos . org / centos / 7 / os / x86_64 /
"""
content = r """ label linux0
menu label ^ Start CentOS
kernel vmlinuz0
append initrd = initrd0 . img root = live : CDLABEL = CentOS - 7 - x86_64 - LiveGNOME - 1708 rootfstype = auto ro rd . live . image quiet rhgb rd . luks = 0 rd . md = 0 rd . dm = 0
menu default
"""
print ( " Testing centos tweaker on Live " )
assert centos_tweaker . tweak ( content ) == """ label linux0
menu label ^ Start CentOS
kernel vmlinuz0
append initrd = initrd0 . img root = live : UUID = { usb - uuid } rootfstype = auto ro rd . live . image quiet rhgb rd . luks = 0 rd . md = 0 rd . dm = 0 rd . live . dir = / multibootusb / { iso - name } / LiveOS
menu default
"""
print ( " Testing persistent centos tweaker on non-persistence config. " )
content = r """ label linux0
menu label ^ Start CentOS
kernel vmlinuz0
append initrd = initrd0 . img root = live : CDLABEL = CentOS - 7 - x86_64 - LiveGNOME - 1708 rootfstype = auto ro rd . live . image quiet rhgb rd . luks = 0 rd . md = 0 rd . dm = 0
menu default
"""
assert centos_persistence_tweaker . tweak ( content ) == """ label linux0
menu label ^ Start CentOS
kernel vmlinuz0
append initrd = initrd0 . img root = live : UUID = { usb - uuid } rootfstype = auto rd . live . image quiet rhgb rd . luks = 0 rd . md = 0 rd . dm = 0 rd . live . dir = / multibootusb / { iso - name } / LiveOS rw rd . live . overlay = UUID = { usb - uuid }
menu default
"""
print ( " Testing persistent centos tweaker not touching "
" non-persistent line " )
content = r """ label linux0
menu label ^ Start CentOS
append kenel = vmlinuz0
append rd . live . overlay = UUID : 2234 - 2223 ro rd . live . image
append initrd = initrd0 . img root = live : CDLABEL = CentOS - 7 - x86_64 - LiveGNOME - 1708 rootfstype = auto ro rd . live . image quiet rhgb rd . luks = 0 rd . md = 0 rd . dm = 0
menu default
"""
assert centos_persistence_tweaker . tweak ( content ) == """ label linux0
menu label ^ Start CentOS
append kenel = vmlinuz0
append rd . live . overlay = UUID = { usb - uuid } rd . live . image rd . live . dir = / multibootusb / { iso - name } / LiveOS rw
append initrd = initrd0 . img root = live : UUID = { usb - uuid } rootfstype = auto ro rd . live . image quiet rhgb rd . luks = 0 rd . md = 0 rd . dm = 0 rd . live . dir = / multibootusb / { iso - name } / LiveOS
menu default
"""
print ( " Testing salix tweaker on legacy tweaking " )
content = """ menu Old Salix
append initrd = / boot / initrd . img foobar = iso_path tail - param
"""
assert salix_tweaker . tweak ( content ) == """ menu Old Salix
append fromiso = / multibootusb / { iso - name } / { iso - name } . iso initrd = / boot / initrd . img foobar = / multibootusb / { iso - name } / { iso - name } . iso tail - param
"""
print ( " Testing salix tweaker on new tweaking " )
content = """ menu New Salix
append initrd = / boot / initrd . img tail - param
"""
assert salix_tweaker . tweak ( content ) == """ menu New Salix
append initrd = / boot / initrd . img tail - param livemedia = { usb - uuid } : / multibootusb / { iso - name } / { iso - name } . iso
"""
def do_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 grub = / grub / grub . cfg - - -
initrd / casper / initrd . lz
} """
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 file = / cdrom / preseed / ubuntu . seed boot = casper only - ubiquity init = / linuxrc iso - scan / filename = $ { iso_path } quiet splash grub = / multibootusb / ubuntu - 14.04 .5 - desktop - amd64 / boot / grub / grub . cfg - - -
initrd / multibootusb / ubuntu - 14.04 .5 - desktop - amd64 / casper / initrd . lz
} """
def test_abspath_rewrite ( ) :
def os_path_exists ( path ) :
path = path . replace ( ' \\ ' , ' / ' )
if path . endswith ( ' .efi ' ) :
return False
if path . startswith ( ' g:/multibootusb/ubuntu-14.04.5-desktop-amd64 '
' /boot ' ) :
return True
if path . endswith ( ' /boot/grub/grub.cfg ' ) :
return True
if path == ' /grub/grub.cfg ' :
return False
if path . endswith ( ' casper/vmlinuz ' ) :
return True
if path . endswith ( ' /casper/initrd.lz ' ) :
return True
return False
saved = os . path . exists
try :
os . path . exists = os_path_exists
do_test_abspath_rewrite ( )
finally :
os . path . exists = saved