@@ -13,7 +13,6 @@ This script installs a Grml system (either a running system or ISO[s]) to a USB
1313"""
1414
1515import argparse
16- import fileinput
1716import functools
1817import glob
1918import logging
@@ -134,6 +133,7 @@ parser.add_argument(
134133 "--remove-bootoption" ,
135134 dest = "removeoption" ,
136135 action = "append" ,
136+ default = [],
137137 help = "regex for removing existing bootoptions" ,
138138)
139139parser .add_argument (
@@ -1132,7 +1132,11 @@ def copy_bootloader_files(iso_mount: str, target: str, grml_flavour: str):
11321132 glob_and_copy (iso_mount + "/boot/grub/*" , grub_target )
11331133 # finally (after all GRUB files have been installed) build static loopback.cfg
11341134 build_grub_loopbackcfg (target )
1135- handle_grub_config (grml_flavour , grub_target , bootid )
1135+ if options .skipgrubconfig :
1136+ logging .info ("Skipping generation of grub configuration as requested." )
1137+ else :
1138+ bootoptions = get_bootoptions (grml_flavour )
1139+ handle_grub_config (grml_flavour , grub_target , bootid , options .removeoption , bootoptions )
11361140
11371141
11381142def copy_and_configure_isolinux (iso_mount : str , syslinux_target : str , grml_flavour : str , bootid : str ) -> None :
@@ -1292,51 +1296,52 @@ def get_bootoptions(grml_flavour: str) -> str:
12921296 return bootopt
12931297
12941298
1295- def handle_grub_config (grml_flavour : str , grub_target : str , bootid : str ) -> None :
1299+ def handle_grub_config (
1300+ grml_flavour : str ,
1301+ grub_target : str ,
1302+ bootid : str ,
1303+ removeoptions : list [str ],
1304+ bootoptions : str ,
1305+ ) -> None :
12961306 """Main handler for generating grub (v1 and v2) configuration
12971307
12981308 @grml_flavour: name of grml flavour the configuration should be generated for
12991309 @target: path of grub's configuration files
13001310 @bootid: unique id of the target usb key
13011311 """
1302- assert options is not None
1303-
1304- if options .skipgrubconfig :
1305- logging .info ("Skipping generation of grub configuration as requested." )
1306- return
1307-
13081312 logging .debug ("Updating grub configuration" )
13091313
13101314 bootid_re = re .compile (r"bootid=[\w_-]+" )
13111315 live_media_path_re = re .compile (r"live-media-path=[\w_/-]+" )
13121316
1313- bootopt = get_bootoptions (grml_flavour )
1314-
13151317 remove_regexes = []
13161318 option_re = re .compile (r"(.*/boot/.*vmlinuz.*)" )
13171319
1318- if options .removeoption :
1319- for regex in options .removeoption :
1320- remove_regexes .append (re .compile (regex ))
1320+ for regex in removeoptions :
1321+ remove_regexes .append (re .compile (regex ))
13211322
13221323 shortname = get_shortname (grml_flavour )
13231324 for filename in glob .glob (grub_target + "*.cfg" ):
1324- for line in fileinput .input (filename , inplace = True ):
1325- line = line .rstrip ("\r \n " )
1326- if option_re .search (line ):
1327- line = bootid_re .sub ("" , line )
1328- if shortname in filename :
1329- line = live_media_path_re .sub ("" , line )
1330- line = line .rstrip () + f" live-media-path=/live/{ grml_flavour } / "
1331- if bootopt .strip ():
1332- line = line .replace (f" { bootopt .strip ()} " , " " )
1333- if line .endswith (bootopt ):
1334- line = line [: - len (bootopt )]
1335- line = line .rstrip () + f" bootid={ bootid } { bootopt } "
1336- for regex in remove_regexes :
1337- line = regex .sub (" " , line )
1338- print (line )
1339- fileinput .close ()
1325+ new_lines = []
1326+ with open (filename , "r+" ) as fh :
1327+ for line in fh .read ().split ("\n " ):
1328+ line = line .rstrip ("\r \n " )
1329+ if option_re .search (line ):
1330+ line = bootid_re .sub (f"bootid={ bootid } " , line )
1331+ if shortname in filename :
1332+ line = live_media_path_re .sub (f"live-media-path=/live/{ grml_flavour } /" , line )
1333+ if bootoptions .strip ():
1334+ line = line .replace (f" { bootoptions .strip ()} " , " " )
1335+ if line .endswith (bootoptions ):
1336+ line = line [: - len (bootoptions )]
1337+ line = line .rstrip () + f" { bootoptions } "
1338+ for regex in remove_regexes :
1339+ line = regex .sub (" " , line )
1340+ new_lines .append (line )
1341+
1342+ fh .seek (0 )
1343+ fh .truncate ()
1344+ fh .write ("\n " .join (new_lines ))
13401345
13411346
13421347def initial_syslinux_config (target : str | Path ) -> None :
@@ -1392,44 +1397,56 @@ def adjust_syslinux_bootoptions(
13921397 @flavour: grml flavour
13931398 @bootid: unique id of the target usb key
13941399 """
1395- append_re = re .compile (r"^(\s*append.*/boot/.*)$" , re .I )
13961400 # flavour_re = re.compile("(label.*)(grml\w+)")
13971401 default_re = re .compile (r"(default.cfg)" )
1398- bootid_re = re .compile (r"bootid=[\w_-]+" )
1399- live_media_path_re = re .compile (r"live-media-path=[\w_/-]+" )
14001402
1401- regexe = []
1402- option_re = None
1403- if removeoptions :
1404- option_re = re .compile (r"/boot/.*/(initrd.gz|initrd.img)" )
1405-
1406- for regex in removeoptions :
1407- regexe .append (re .compile (r"%s" % regex ))
1408-
1409- for line in fileinput .input (src , inplace = True ):
1410- # line = flavour_re.sub(r'\1 %s-\2' % flavour, line)
1411- line = default_re .sub (r"%s-\1" % grml_flavour , line )
1412- line = bootid_re .sub ("" , line )
1413- line = live_media_path_re .sub ("" , line )
1414- line = append_re .sub (r"\1 live-media-path=/live/%s/ " % grml_flavour , line )
1415- line = append_re .sub (r"\1 boot=live %s " % bootoptions , line )
1416- line = append_re .sub (r"\1 bootid=%s " % bootid , line )
1417- if option_re and option_re .search (line ):
1418- for regex in regexe :
1419- line = regex .sub (" " , line )
1420- sys .stdout .write (line )
1421- fileinput .close ()
1403+ remove_options_regexes = []
1404+ for regex in removeoptions :
1405+ remove_options_regexes .append (re .compile (regex ))
1406+
1407+ new_lines = []
1408+ with open (src , "r+" ) as fh :
1409+ for line in fh .read ().split ("\n " ):
1410+ # line = flavour_re.sub(r'\1 %s-\2' % flavour, line)
1411+ line = default_re .sub (r"%s-\1" % grml_flavour , line )
1412+
1413+ # Rebuild kernel parameter line ("append")
1414+ if line .lstrip ().startswith ("append " ):
1415+ # we expect " append initrd=/path.img opt1=bar opt2=baz"
1416+ prefix , opts = line .split ("append " , 1 )
1417+ opts = opts .split (" " ) # does not support quoting
1418+ new_options = []
1419+ for option in opts :
1420+ if option .startswith ("live-media-path=" ):
1421+ option = f"live-media-path=/live/{ grml_flavour } /"
1422+ elif option .startswith ("boot=" ):
1423+ option = "boot=live"
1424+ elif option .startswith ("bootid=" ):
1425+ option = f"bootid={ bootid } "
1426+ if any (regex .match (option ) for regex in remove_options_regexes ):
1427+ continue
1428+ new_options .append (option )
1429+ if bootoptions :
1430+ new_options .append (bootoptions )
1431+ line = "" .join ([prefix , "append " ]) + " " .join (new_options ) + " "
1432+
1433+ new_lines .append (line )
1434+
1435+ fh .seek (0 )
1436+ fh .truncate ()
1437+ fh .write ("\n " .join (new_lines ))
14221438
14231439
14241440def adjust_labels (src : str , replacement : str ) -> None :
14251441 """Adjust the specified labels in the syslinux config file src with
14261442 specified replacement
14271443 """
1428- label_re = re .compile (r"^(\s*label\s*) ([a-zA-Z0-9_-]+)" , re .I )
1429- for line in fileinput .input (src , inplace = True ):
1430- line = label_re .sub (replacement , line )
1431- sys .stdout .write (line )
1432- fileinput .close ()
1444+ label_re = re .compile (r"^(\s*label\s*) ([a-zA-Z0-9_-]+)" , re .I | re .MULTILINE )
1445+ with open (src , "r+" ) as fh :
1446+ contents = fh .read ()
1447+ fh .seek (0 )
1448+ fh .truncate ()
1449+ fh .write (label_re .sub (replacement , contents ))
14331450
14341451
14351452def add_syslinux_entry (syslinux_target : str | Path , filename : str | Path , grml_flavour ) -> None :
@@ -1465,12 +1482,16 @@ def remove_default_entry(filename: str) -> None:
14651482
14661483 @filename: syslinux config file
14671484 """
1468- default_re = re .compile (r"^(\s*menu\s*default\s*)$" , re .I )
1469- for line in fileinput .input (filename , inplace = True ):
1470- if default_re .match (line ):
1471- continue
1472- sys .stdout .write (line )
1473- fileinput .close ()
1485+ default_re = re .compile (r"^(\s*menu\s*default\s*)$" , re .I | re .MULTILINE )
1486+ lines = []
1487+ with open (filename , "r+" ) as fh :
1488+ for line in fh .read ().split ("\n " ):
1489+ if default_re .match (line ):
1490+ continue
1491+ lines .append (line )
1492+ fh .seek (0 )
1493+ fh .truncate ()
1494+ fh .write ("\n " .join (lines ))
14741495
14751496
14761497def handle_syslinux_config (
0 commit comments