Avoid custom boot options getting duplicated when used with multiple ISOs
authorMichael Prokop <mika@grml.org>
Tue, 4 Jun 2019 08:39:28 +0000 (10:39 +0200)
committerMichael Prokop <mika@grml.org>
Tue, 4 Jun 2019 08:55:56 +0000 (10:55 +0200)
grml2usb can be invoked with multiple ISOs *and* custom boot options, like:

  % sudo grml2usb --bootoption="ssh=foobar mikawashere" grml32-small_2018.12.iso grml64-small_2018.12.iso /dev/sdb1

Then grml2usb appends the custom boot options in the GRUB
(boot/grub/*.cfg) + isolinux/syslinux (boot/syslinux/*.cfg)
configuration files of files that have been installed by the underlying
grml32-small ISO.

But when hitting the grml64-small ISO then, it continues to replace the
files with the boot options once again. Therefore we end up with
duplicate boot options in the grml32-small_2018.12.iso specific files
(boot/grub/grml32small_default.cfg, boot/grub/grml32small_options.cfg,
boot/syslinux/grml32_small_default.cfg, boot/syslinux/grml32_small_grml.cfg +
boot/syslinux/hidden.cfg).

We could actually ensure to only touch the ISO specific files, but
we don't have version information included in the file names and also
have shared files like boot/syslinux/hidden.cfg, so this might unexpected
side effects as well. So instead let's explicitly check for the provided
custom boot options.

Notes regarding the implementation:

* If boot options are whitespace-only or empty, nothing will happen. This
  prevents str.replace to do unintended things.

* otherwise consider string "PRE some-boot-options POST". Then we should find
  'some-boot-options' and remove them. Why the delimiter handling? Consider
  some-boot-options is 'ssh'. If we replace line.replace(bootopt, '') then some
  fictitious boot option like 'service.ssh=autostart' would be broken. Thus the
  space delimiters are necessary.

* However, the space delimiters might not exist if the boot options occur at the
  end of the string. Thus special handling is required for this case.

Thanks: Ralf Moll for the bug report and Lukas Prokop for providing the bug fix

grml2usb

index 1c906ab..ac700f1 100755 (executable)
--- a/grml2usb
+++ b/grml2usb
@@ -1300,6 +1300,10 @@ def handle_grub_config(grml_flavour, device, target):
                 if shortname in filename:
                     line = live_media_path_re.sub('', line)
                     line = line.rstrip() + ' live-media-path=/live/%s/ ' % (grml_flavour)
+                if bootopt.strip():
+                    line = line.replace(' {} '.format(bootopt.strip()), ' ')
+                    if line.endswith(bootopt):
+                        line = line[:-len(bootopt)]
                 line = line.rstrip() + r' bootid=%s %s ' % (UUID, bootopt)
                 for regex in remove_regexes:
                     line = regex.sub(' ', line)