File grub-use-disk-password.patch of Package python-kiwi
This patch adds a new attribute to the <bootloader> element, called
use_disk_password (true/false). If set to true, the cryptomount command
in the EFI grub.cfg file will explicitly specify the LUKS password.
This is useful when shipping images with a LUKS root partition, allowing
them to come up on firstboot without the user having to enter a well-known
"secret".
Index: kiwi-9.24.47/kiwi/bootloader/config/grub2.py
===================================================================
--- kiwi-9.24.47.orig/kiwi/bootloader/config/grub2.py
+++ kiwi-9.24.47/kiwi/bootloader/config/grub2.py
@@ -120,6 +120,7 @@ class BootLoaderConfigGrub2(BootLoaderCo
Defaults.get_volume_id()
self.install_volid = self.xml_state.build_type.get_volid() or \
Defaults.get_install_volume_id()
+ self.use_disk_password = self.xml_state.get_build_type_bootloader_use_disk_password()
self.live_boot_options = [
'root=live:CDLABEL={0}'.format(self.volume_id),
Index: kiwi-9.24.47/kiwi/bootloader/install/grub2.py
===================================================================
--- kiwi-9.24.47.orig/kiwi/bootloader/install/grub2.py
+++ kiwi-9.24.47/kiwi/bootloader/install/grub2.py
@@ -272,6 +272,31 @@ class BootLoaderInstallGrub2(BootLoaderI
# restore the grub installer noop
self._enable_grub2_install(self.root_mount.mountpoint)
+ def set_disk_password(self, password):
+ log.debug(f'set_disk_password({password})')
+ if password is None:
+ return
+
+ config_file = f'{self.root_mount.mountpoint}/boot/efi/EFI/BOOT/grub.cfg'
+ if not os.path.exists(config_file):
+ log.debug(f'{config_file} does not exist')
+ return
+
+ with open(config_file) as config:
+ import re
+
+ grub_config = config.read()
+ grub_config = re.sub(
+ r'cryptomount',
+ f'cryptomount -p "{password}"',
+ grub_config
+ )
+
+ with open(config_file, 'w') as grub_config_file:
+ grub_config_file.write(grub_config)
+
+ log.debug(f'<<< {grub_config} >>>')
+
def _mount_device_and_volumes(self):
if self.root_mount is None:
self.root_mount = MountManager(
Index: kiwi-9.24.47/kiwi/builder/disk.py
===================================================================
--- kiwi-9.24.47.orig/kiwi/builder/disk.py
+++ kiwi-9.24.47/kiwi/builder/disk.py
@@ -1497,6 +1497,11 @@ class DiskBuilder:
if self.bootloader != 'custom':
# create bootloader config prior bootloader installation
+ disk_password = None
+ if self.bootloader_config.use_disk_password and self.luks:
+ disk_password = self.luks
+ log.debug(f'Passing disk encryption password "{disk_password}" to boot loader')
+
try:
self.bootloader_config.setup_disk_image_config(
boot_options=custom_install_arguments
@@ -1519,6 +1524,9 @@ class DiskBuilder:
bootloader.install()
bootloader.secure_boot_install()
+ if disk_password:
+ bootloader.set_disk_password(disk_password)
+
self.system_setup.call_edit_boot_install_script(
self.diskname, boot_device.get_device()
)
Index: kiwi-9.24.47/kiwi/schema/kiwi.rnc
===================================================================
--- kiwi-9.24.47.orig/kiwi/schema/kiwi.rnc
+++ kiwi-9.24.47/kiwi/schema/kiwi.rnc
@@ -2673,6 +2673,11 @@ div {
sch:param [ name = "attr" value = "targettype" ]
sch:param [ name = "types" value = "grub2_s390x_emu" ]
]
+ k.bootloader.use_disk_password.attribute =
+ ## When /boot is encrypted, make the boot loader store the
+ ## password in its configuration file (in cleartext). This
+ ## is useful for full disk encryption images
+ attribute use_disk_password { xsd:boolean }
k.bootloader.attlist =
k.bootloader.name.attribute &
k.bootloader.console.attribute? &
@@ -2680,6 +2685,7 @@ div {
k.bootloader.timeout.attribute? &
k.bootloader.timeout_style.attribute? &
k.bootloader.targettype.attribute? &
+ k.bootloader.use_disk_password.attribute? &
k.bootloader.grub_template.attribute?
k.bootloader =
Index: kiwi-9.24.47/kiwi/schema/kiwi.rng
===================================================================
--- kiwi-9.24.47.orig/kiwi/schema/kiwi.rng
+++ kiwi-9.24.47/kiwi/schema/kiwi.rng
@@ -3996,6 +3996,14 @@ for 4k DASD devices use CDL</a:documenta
<sch:param name="types" value="grub2_s390x_emu"/>
</sch:pattern>
</define>
+ <define name="k.bootloader.use_disk_password.attribute">
+ <attribute name="use_disk_password">
+ <a:documentation>When /boot is encrypted, make the boot loader store the
+password in its configuration file (in cleartext). This
+is useful for full disk encryption images</a:documentation>
+ <data type="boolean"/>
+ </attribute>
+ </define>
<define name="k.bootloader.attlist">
<interleave>
<ref name="k.bootloader.name.attribute"/>
@@ -4015,6 +4023,9 @@ for 4k DASD devices use CDL</a:documenta
<ref name="k.bootloader.targettype.attribute"/>
</optional>
<optional>
+ <ref name="k.bootloader.use_disk_password.attribute"/>
+ </optional>
+ <optional>
<ref name="k.bootloader.grub_template.attribute"/>
</optional>
</interleave>
Index: kiwi-9.24.47/kiwi/xml_parse.py
===================================================================
--- kiwi-9.24.47.orig/kiwi/xml_parse.py
+++ kiwi-9.24.47/kiwi/xml_parse.py
@@ -16,10 +16,10 @@
# kiwi/schema/kiwi_for_generateDS.xsd
#
# Command line:
-# /home/ms/Project/kiwi/.tox/3.6/bin/generateDS.py -f --external-encoding="utf-8" --no-dates --no-warnings -o "kiwi/xml_parse.py" kiwi/schema/kiwi_for_generateDS.xsd
+# /home/okir/.local/bin/generateDS.py -f --external-encoding="utf-8" --no-dates --no-warnings -o "kiwi/xml_parse.py" kiwi/schema/kiwi_for_generateDS.xsd
#
# Current working directory (os.getcwd()):
-# kiwi
+# kiwi-9.24.41
#
import sys
@@ -5214,7 +5214,7 @@ class bootloader(GeneratedsSuper):
provide configuration parameters for it"""
subclass = None
superclass = None
- def __init__(self, name=None, console=None, serial_line=None, timeout=None, timeout_style=None, targettype=None, grub_template=None):
+ def __init__(self, name=None, console=None, serial_line=None, timeout=None, timeout_style=None, targettype=None, use_disk_password=None, grub_template=None):
self.original_tagname_ = None
self.name = _cast(None, name)
self.console = _cast(None, console)
@@ -5222,6 +5222,7 @@ class bootloader(GeneratedsSuper):
self.timeout = _cast(int, timeout)
self.timeout_style = _cast(None, timeout_style)
self.targettype = _cast(None, targettype)
+ self.use_disk_password = _cast(bool, use_disk_password)
self.grub_template = _cast(None, grub_template)
def factory(*args_, **kwargs_):
if CurrentSubclassModule_ is not None:
@@ -5246,6 +5247,8 @@ class bootloader(GeneratedsSuper):
def set_timeout_style(self, timeout_style): self.timeout_style = timeout_style
def get_targettype(self): return self.targettype
def set_targettype(self, targettype): self.targettype = targettype
+ def get_use_disk_password(self): return self.use_disk_password
+ def set_use_disk_password(self, use_disk_password): self.use_disk_password = use_disk_password
def get_grub_template(self): return self.grub_template
def set_grub_template(self, grub_template): self.grub_template = grub_template
def validate_grub_console(self, value):
@@ -5301,6 +5304,9 @@ class bootloader(GeneratedsSuper):
if self.targettype is not None and 'targettype' not in already_processed:
already_processed.add('targettype')
outfile.write(' targettype=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.targettype), input_name='targettype')), ))
+ if self.use_disk_password is not None and 'use_disk_password' not in already_processed:
+ already_processed.add('use_disk_password')
+ outfile.write(' use_disk_password="%s"' % self.gds_format_boolean(self.use_disk_password, input_name='use_disk_password'))
if self.grub_template is not None and 'grub_template' not in already_processed:
already_processed.add('grub_template')
outfile.write(' grub_template=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.grub_template), input_name='grub_template')), ))
@@ -5348,6 +5354,15 @@ class bootloader(GeneratedsSuper):
already_processed.add('targettype')
self.targettype = value
self.targettype = ' '.join(self.targettype.split())
+ value = find_attr_value_('use_disk_password', node)
+ if value is not None and 'use_disk_password' not in already_processed:
+ already_processed.add('use_disk_password')
+ if value in ('true', '1'):
+ self.use_disk_password = True
+ elif value in ('false', '0'):
+ self.use_disk_password = False
+ else:
+ raise_parse_error(node, 'Bad boolean attribute')
value = find_attr_value_('grub_template', node)
if value is not None and 'grub_template' not in already_processed:
already_processed.add('grub_template')
Index: kiwi-9.24.47/kiwi/xml_state.py
===================================================================
--- kiwi-9.24.47.orig/kiwi/xml_state.py
+++ kiwi-9.24.47/kiwi/xml_state.py
@@ -1026,6 +1026,20 @@ class XMLState:
return bootloader.get_targettype()
return None
+ def get_build_type_bootloader_use_disk_password(self) -> bool:
+ """
+ Indicate whether the bootloader configuration should use the
+ password protecting the encrypted root volume.
+
+ :return: True|False
+
+ :rtype: bool
+ """
+ bootloader = self.get_build_type_bootloader_section()
+ if bootloader:
+ return bootloader.get_use_disk_password()
+ return False
+
def get_build_type_oemconfig_section(self) -> Any:
"""
First oemconfig section from the build type section