|
|
|
@ -211,48 +211,53 @@ def write_to_file(file_path, _strings):
|
|
|
|
|
gen.log('Error writing to %s...' % file_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extract_kernel_line(search_text, match_line, isolinux_dir):
|
|
|
|
|
def kernel_search_path(isolinux_dir):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
def locate_kernel_file(subpath, isolinux_dir):
|
|
|
|
|
for d in [
|
|
|
|
|
'',
|
|
|
|
|
os.path.join('multibootusb',
|
|
|
|
|
iso.iso_basename(config.image_path), isolinux_dir),
|
|
|
|
|
# Down below are dire attemps to find.
|
|
|
|
|
os.path.join('multibootusb',
|
|
|
|
|
iso.iso_basename(config.image_path)),
|
|
|
|
|
os.path.join('multibootusb',
|
|
|
|
|
iso.iso_basename(config.image_path), 'arch'),
|
|
|
|
|
]:
|
|
|
|
|
if os.path.exists(os.path.join(config.usb_mount, d, subpath)):
|
|
|
|
|
unix_style_path = os.path.join(d, subpath).\
|
|
|
|
|
replace('\\', '/').\
|
|
|
|
|
lstrip('/')
|
|
|
|
|
return ('/' + unix_style_path)
|
|
|
|
|
return subpath
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def tweak_bootfile_path(img_file_spec, isolinux_dir):
|
|
|
|
|
"""
|
|
|
|
|
Function to check if kernel/linux line present in isolinux.cfg file is valid.
|
|
|
|
|
If valid, then convert them in to grub accepted format
|
|
|
|
|
:param search_text: Type of text is to be searched. Typically kernel or linux
|
|
|
|
|
:param match_line: Line containing kernel ot linux from isolinux supported .cfg files
|
|
|
|
|
Function to find image files to boot and return them concatinated
|
|
|
|
|
with a space. Return the spec untouched if no locations are found.
|
|
|
|
|
:param kernel_file_spec: Image path specification lead by kernel/linux keyword within isolinux supported .cfg files.
|
|
|
|
|
:param isolinux_dir: Path to isolinux directory of an ISO
|
|
|
|
|
:return: Valid grub2 accepted kernel/linux line after conversion. If nothing found return ''.
|
|
|
|
|
:return: Converted file paths joined by a space. If no files can be located, img_file_spec is returned unmodified.
|
|
|
|
|
"""
|
|
|
|
|
kernel_line = ''
|
|
|
|
|
|
|
|
|
|
# Remove '=' from linux/kernel parameter
|
|
|
|
|
if (search_text + '=') in match_line:
|
|
|
|
|
kernel_path = match_line.replace((search_text + '='), '').strip()
|
|
|
|
|
search_text = search_text.replace('=', '')
|
|
|
|
|
else:
|
|
|
|
|
kernel_path = match_line.replace(search_text, '', 1).strip()
|
|
|
|
|
|
|
|
|
|
# Check if kernel/linux exist using absolute path (kernel_path)
|
|
|
|
|
if os.path.exists(os.path.join(config.usb_mount, kernel_path)):
|
|
|
|
|
kernel_line = search_text.lower().replace('kernel', 'linux') + ' ' + kernel_path.strip()
|
|
|
|
|
|
|
|
|
|
# Check if path to kernel/linux exist in isolinux directory and return absolute path
|
|
|
|
|
elif os.path.exists(os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), isolinux_dir, kernel_path)):
|
|
|
|
|
kernel_line = search_text.lower().replace('kernel', 'linux') + ' /multibootusb/' + \
|
|
|
|
|
iso.iso_basename(config.image_path) + '/' + isolinux_dir + '/' + kernel_path.strip()
|
|
|
|
|
|
|
|
|
|
# Check if multiple kernel/linux exist and convert it to grub accepted line
|
|
|
|
|
# Found such entries in manjaro and slitaz
|
|
|
|
|
elif ',/' in kernel_path:
|
|
|
|
|
kernel_line = search_text.lower().replace('kernel', 'linux') + ' ' + kernel_path.strip()
|
|
|
|
|
kernel_line = kernel_line.replace(',/', ' /')
|
|
|
|
|
|
|
|
|
|
# Same as above but I found this only in dban
|
|
|
|
|
elif 'z,' in kernel_path:
|
|
|
|
|
kernel_line = search_text.lower().replace('kernel', 'linux') + ' ' + kernel_path.strip()
|
|
|
|
|
kernel_line = kernel_line.replace('z,', ' /multibootusb/' + iso.iso_basename(config.image_path) + '/'
|
|
|
|
|
+ iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/')
|
|
|
|
|
else:
|
|
|
|
|
kernel_line = ''
|
|
|
|
|
raw_paths = img_file_spec.split(',')
|
|
|
|
|
converted_paths = [locate_kernel_file(p, isolinux_dir) for p in raw_paths]
|
|
|
|
|
if raw_paths != converted_paths: # Tweaked the paths successfully?
|
|
|
|
|
return ' '.join(converted_paths)
|
|
|
|
|
|
|
|
|
|
return kernel_line.replace('\\', '/').replace('//', '/')
|
|
|
|
|
if 'z,' in img_file_spec:
|
|
|
|
|
# Fallback to legacy code.
|
|
|
|
|
# "... I found this only in dban"
|
|
|
|
|
iso_dir = iso.isolinux_bin_dir(config.image_path)
|
|
|
|
|
replacement = ' /multibootusb/' + iso.iso_basename(config.image_path) \
|
|
|
|
|
+ '/' \
|
|
|
|
|
+ iso_dir.replace('\\', '/') + '/'
|
|
|
|
|
return img_file_spec.replace('z,', replacement)
|
|
|
|
|
# Give up and return the original with replaced delimeters.
|
|
|
|
|
return ' '.join(img_file_spec.split(','))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extract_initrd_param(value, isolinux_dir):
|
|
|
|
@ -268,16 +273,8 @@ def extract_initrd_param(value, isolinux_dir):
|
|
|
|
|
if not paramdef.lower().startswith('initrd='):
|
|
|
|
|
others.append(paramdef)
|
|
|
|
|
continue
|
|
|
|
|
paths = []
|
|
|
|
|
for path in paramdef[len('initrd='):].split(','):
|
|
|
|
|
# try to find the specified kernel
|
|
|
|
|
for d in kernel_search_path:
|
|
|
|
|
if os.path.exists(os.path.join(config.usb_mount, d, path)):
|
|
|
|
|
paths.append(os.path.join(d, path))
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
# Give up and use the specified kernel as is.
|
|
|
|
|
paths.append(path)
|
|
|
|
|
paths = [locate_kernel_file(s, isolinux_dir) for s
|
|
|
|
|
in paramdef[len('initrd='):].split(',')]
|
|
|
|
|
initrd_line = 'initrd ' + ' '.join(paths)
|
|
|
|
|
return initrd_line, ' '.join(others)
|
|
|
|
|
|
|
|
|
@ -321,32 +318,54 @@ def iso2grub2(install_dir, loopback_cfg_path, wrote_custom_cfg):
|
|
|
|
|
# we will use only files containing strings which can be converted to grub2 cfg style
|
|
|
|
|
with open(cfg_file_path, "r", errors='ignore') as f:
|
|
|
|
|
data = f.read()
|
|
|
|
|
# Make sure that lines with menu label, kernel and append are available for processing
|
|
|
|
|
matching_blocks = re.finditer(
|
|
|
|
|
'^(menu label|label)(.*?)(?=^(menu label|label|$))',
|
|
|
|
|
data, re.I|re.DOTALL|re.MULTILINE)
|
|
|
|
|
# materialize the list.
|
|
|
|
|
matching_blocks = [s for s in matching_blocks]
|
|
|
|
|
|
|
|
|
|
# Make sure that lines with 'label' available for processing.
|
|
|
|
|
# Do nothing otherwise.
|
|
|
|
|
matching_blocks_re = [m for m in re.finditer(
|
|
|
|
|
'^(label)(.*?)(?=(^label))',
|
|
|
|
|
data, re.I|re.DOTALL|re.MULTILINE)]
|
|
|
|
|
|
|
|
|
|
if matching_blocks_re:
|
|
|
|
|
matching_blocks = [m.group() for m in matching_blocks_re]
|
|
|
|
|
# Append the block after the last matching position
|
|
|
|
|
matching_blocks.append(data[matching_blocks_re[-1].span()[1]:])
|
|
|
|
|
else:
|
|
|
|
|
m = re.match('^(label)(.*?)',
|
|
|
|
|
data, re.I|re.DOTALL|re.MULTILINE)
|
|
|
|
|
matching_blocks = m and [data[m.start():]] or []
|
|
|
|
|
|
|
|
|
|
if not matching_blocks:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
#if not cfg_file_path.endswith('archiso_pxe64.cfg'):
|
|
|
|
|
# continue
|
|
|
|
|
gen.log("Probing '%s'" % cfg_file_path)
|
|
|
|
|
out_lines = []
|
|
|
|
|
for match in matching_blocks:
|
|
|
|
|
matched_block = match.group()
|
|
|
|
|
|
|
|
|
|
for matching_block in matching_blocks:
|
|
|
|
|
#print ('------------ block begins here ------------')
|
|
|
|
|
#print (matching_block)
|
|
|
|
|
#print ('------------ block ends here ------------')
|
|
|
|
|
# Extract 'menu label or 'label' line.
|
|
|
|
|
matches = re.findall(
|
|
|
|
|
r'^\s*(menu label|label)\s+(.*)$',
|
|
|
|
|
matched_block, re.I|re.MULTILINE)
|
|
|
|
|
if 0 == len(matches):
|
|
|
|
|
matching_block, re.I|re.MULTILINE)
|
|
|
|
|
labels = [v for v in matches if v[0].lower()=='label']
|
|
|
|
|
menu_labels = [v for v in matches if v[0].lower()=='menu label']
|
|
|
|
|
if 0 == len(labels) + len(menu_labels):
|
|
|
|
|
gen.log('Warning: found a block without menu-entry.')
|
|
|
|
|
menu_line = 'menuentry "Anonymous"'
|
|
|
|
|
menu_label = 'Unlabeled'
|
|
|
|
|
else:
|
|
|
|
|
if 2 <= len(matches):
|
|
|
|
|
gen.log('Warning: found a block with more than one '
|
|
|
|
|
'menu entries.')
|
|
|
|
|
keyword, value = matches[0]
|
|
|
|
|
for vec, name in [ (labels, 'label'),
|
|
|
|
|
(menu_labels, 'menu label') ]:
|
|
|
|
|
if 2 <= len(vec):
|
|
|
|
|
gen.log("warning: found a block with more than "
|
|
|
|
|
"one '%s' entries." % name)
|
|
|
|
|
# Prefer 'menu label' over 'label'.
|
|
|
|
|
if 0<len(menu_labels):
|
|
|
|
|
value = menu_labels[0][1].replace('^', '')
|
|
|
|
|
else:
|
|
|
|
|
value = labels[0][1]
|
|
|
|
|
menu_line = 'menuentry ' + gen.quote(value)
|
|
|
|
|
menu_label = value
|
|
|
|
|
|
|
|
|
@ -356,9 +375,7 @@ def iso2grub2(install_dir, loopback_cfg_path, wrote_custom_cfg):
|
|
|
|
|
appends = []
|
|
|
|
|
for keyword, value in re.findall(
|
|
|
|
|
r'^\s*(kernel|linux|initrd|append)[= ](.*)$',
|
|
|
|
|
matched_block, re.I|re.MULTILINE):
|
|
|
|
|
# Ensure that we do not have caps label in the menuentry.
|
|
|
|
|
value = value.replace(keyword.upper(), '') # Essencial?
|
|
|
|
|
matching_block, re.I|re.MULTILINE):
|
|
|
|
|
kw = keyword.lower()
|
|
|
|
|
if kw in ['kernel', 'linux']:
|
|
|
|
|
if linux_line:
|
|
|
|
@ -366,23 +383,24 @@ def iso2grub2(install_dir, loopback_cfg_path, wrote_custom_cfg):
|
|
|
|
|
"'kernel/linux' lines in block '%s'."
|
|
|
|
|
% menu_label)
|
|
|
|
|
continue
|
|
|
|
|
linux_line = extract_kernel_line(
|
|
|
|
|
keyword, '%s %s' % (keyword, value), iso_bin_dir)
|
|
|
|
|
linux_line = 'linux ' + \
|
|
|
|
|
tweak_bootfile_path(value, iso_bin_dir)
|
|
|
|
|
elif kw == 'initrd':
|
|
|
|
|
if initrd_line:
|
|
|
|
|
gen.log("Warning: found more than one "
|
|
|
|
|
"'initrd' specifications in block '%s'."
|
|
|
|
|
% menu_label)
|
|
|
|
|
continue
|
|
|
|
|
initrd_line = extract_kernel_line(
|
|
|
|
|
keyword, '%s %s' % (keyword, value), iso_bin_dir)
|
|
|
|
|
initrd_line = 'initrd ' + \
|
|
|
|
|
tweak_bootfile_path(value, iso_bin_dir)
|
|
|
|
|
elif kw== 'append':
|
|
|
|
|
if initrd_line:
|
|
|
|
|
gen.log("Warning: found both 'append initrd=...' "
|
|
|
|
|
"and 'initrd ...' line")
|
|
|
|
|
new_initrd_line, new_value = extract_initrd_param(
|
|
|
|
|
value, iso_bin_dir)
|
|
|
|
|
if new_initrd_line:
|
|
|
|
|
if initrd_line:
|
|
|
|
|
gen.log("Warning: found more than one initrd "
|
|
|
|
|
"specifications in block '%s'."
|
|
|
|
|
% menu_label)
|
|
|
|
|
initrd_line = new_initrd_line
|
|
|
|
|
appends.append(new_value)
|
|
|
|
|
|
|
|
|
@ -404,7 +422,8 @@ def iso2grub2(install_dir, loopback_cfg_path, wrote_custom_cfg):
|
|
|
|
|
"menu item '%s'." % menu_label)
|
|
|
|
|
|
|
|
|
|
with open(loopback_cfg_path, 'a') as f:
|
|
|
|
|
f.write('# Extracted from %s\n' % cfg_file_path)
|
|
|
|
|
f.write('# Extracted from %s\n' %
|
|
|
|
|
cfg_file_path.replace('\\', '/'))
|
|
|
|
|
f.write('\n'.join(out_lines) + '\n')
|
|
|
|
|
f.write('\n')
|
|
|
|
|
|
|
|
|
|