[elbe-devel] [PATCH v2 2/4] grubinstaller: enable UEFI (secure) boot with shim

Torben Hohn torben.hohn at linutronix.de
Fri Aug 23 13:56:38 CEST 2019


On Fri, Aug 23, 2019 at 11:03:30AM +0200, bage at linutronix.de wrote:
> From: Bastian Germann <bage at linutronix.de>
> 
> This is a workaround for grub-installer being dependent on the system
> where it is executed. When shim and the signed grub-efi variants are
> installed, it fails to create a usable installation on the loop device.
> 
> Fix the installation by creating a debian boot environment (the name
> does not matter but has to be different from BOOT) and copying the
> signed shim to it.
> 
> The signed grub-efi is also available for other systems than amd64.
> Enable installing them as well.
> 
> Signed-off-by: Bastian Germann <bage at linutronix.de>
> ---
>  elbepack/efilesystem.py |  2 +-
>  elbepack/elbeproject.py | 33 ++++++++++++++++++---------------
>  elbepack/hdimg.py       | 33 +++++++++++++++++++--------------
>  3 files changed, 38 insertions(+), 30 deletions(-)
> 
> diff --git a/elbepack/efilesystem.py b/elbepack/efilesystem.py
> index faa2a183..29ef4526 100644
> --- a/elbepack/efilesystem.py
> +++ b/elbepack/efilesystem.py
> @@ -352,7 +352,7 @@ class TargetFs(ChRootFilesystem):
>                      f.write(fstab.get_str())
>              f.close()
>  
> -    def part_target(self, targetdir, grub_version, grub_fw_type=None):
> +    def part_target(self, targetdir, grub_version, grub_fw_type=[]):

see:
https://stackoverflow.com/questions/366422/what-is-the-pythonic-way-to-avoid-default-parameters-that-are-empty-lists

i am not so happy with the change to a list.

not sure what we we gain there...
but thats ok probably.

maybe we should just drop the default, and allow to specify the
parameter in "elbe hdimg" also.

this will allow us to increase the turnaround time for testing
significantly.




>  
>          # create target images and copy the rfs into them
>          self.images = do_hdimg(
> diff --git a/elbepack/elbeproject.py b/elbepack/elbeproject.py
> index df8a7981..d9690321 100644
> --- a/elbepack/elbeproject.py
> +++ b/elbepack/elbeproject.py
> @@ -615,26 +615,29 @@ class ElbeProject (object):
>          # Use some handwaving to determine grub version
>          #
>          # We might also want support for legacy grub
> -        if (self.get_rpcaptcache().is_installed('grub-pc') and
> -                self.get_rpcaptcache().is_installed('grub-efi-amd64-bin')):
> +        grub_arch = "ia32" if self.arch == "i386" else self.arch
> +        grub_fw_type = []
> +        grub_version = 0
> +        if self.get_rpcaptcache().is_installed('grub-pc'):
>              grub_version = 202
> -            grub_fw_type = "hybrid"
> -        elif self.get_rpcaptcache().is_installed('grub-pc'):
> +            grub_fw_type.append("bios")
> +        if self.get_rpcaptcache().is_installed('grub-efi-%s-bin' % grub_arch):
>              grub_version = 202
> -            grub_fw_type = "bios"
> -        elif self.get_rpcaptcache().is_installed('grub-efi-amd64'):
> +            grub_tgt = "x86_64" if self.arch == "amd64" else self.arch
> +            grub_fw_type.extend(["efi", grub_tgt + "-efi"])
> +        if (self.get_rpcaptcache().is_installed('shim-signed') and
> +                self.get_rpcaptcache().is_installed(
> +                    'grub-efi-%s-signed' % grub_arch)):
>              grub_version = 202
> -            grub_fw_type = "efi"
> -        elif self.get_rpcaptcache().is_installed('grub-legacy'):
> +            grub_fw_type.append("shimfix")
> +        if self.get_rpcaptcache().is_installed('grub-legacy'):
>              self.log.printo("package grub-legacy is installed, "
>                              "this is obsolete, skipping grub")
> -            grub_version = 0
> -            grub_fw_type = ""
> -        else:
> -            self.log.printo("package grub-pc is not installed, skipping grub")
> -            # version 0 == skip_grub
> -            grub_version = 0
> -            grub_fw_type = ""
> +            grub_fw_type = []
> +        elif not grub_fw_type:
> +            self.log.printo("neither package grub-pc nor grub-efi-%s-bin "
> +                            "are installed, skipping grub" % grub_arch)
> +
>          self.targetfs.part_target(self.builddir, grub_version, grub_fw_type)
>  
>          self.build_cdroms(build_bin, build_sources, cdrom_size)
> diff --git a/elbepack/hdimg.py b/elbepack/hdimg.py
> index 98ae5f2b..29dd132e 100644
> --- a/elbepack/hdimg.py
> +++ b/elbepack/hdimg.py
> @@ -144,7 +144,7 @@ def build_image_mtd(outf, mtd, target):
>  
>  
>  class grubinstaller_base(object):
> -    def __init__(self, outf, fw_type=None):
> +    def __init__(self, outf, fw_type=[]):
>          self.outf = outf
>          self.root = None
>          self.boot = None
> @@ -218,13 +218,22 @@ class grubinstaller202(grubinstaller_base):
>              self.outf.do("chroot %s  update-initramfs -u -k all" % imagemnt)
>              self.outf.do("chroot %s  update-grub2" % imagemnt)
>  
> -            if self.fw_type == "efi" or self.fw_type == "hybrid":
> +            if "efi" in self.fw_type:
> +                grub_tgt = next(t for t in self.fw_type if t.endswith("-efi"))
>                  self.outf.do(
> -                    "chroot %s grub-install --target=x86_64-efi --removable "
> +                    "chroot %s grub-install --target=%s --removable "
>                      "--no-floppy /dev/poop0" %
> -                    (imagemnt))
> -            if self.fw_type == "hybrid" or self.fw_type is None:
> -                # when we are in hybrid mode, install grub also into MBR
> +                    (imagemnt, grub_tgt))
> +            if "shimfix" in self.fw_type:
> +                # grub-install is heavily dependent on the running system having
> +                # a BIOS or EFI.  The initvm is BIOS-based, so fix the resulting
> +                # shim installation.
> +                self.outf.do("chroot %s  /bin/bash -c '"
> +                             "cp -r /boot/efi/EFI/BOOT /boot/efi/EFI/debian && "
> +                             "cd /usr/lib/shim && f=( shim*.efi.signed ) && cp "
> +                             "${f[0]} /boot/efi/EFI/debian/${f[0]%%.signed}'"  %
> +                             imagemnt)
> +            if not self.fw_type or "bios" in self.fw_type:
>                  self.outf.do(
>                      "chroot %s grub-install --no-floppy /dev/poop0" %
>                      (imagemnt))
> @@ -381,7 +390,7 @@ def create_logical_partitions(
>          current_sector += lpart.getLength()
>  
>  
> -def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type=None):
> +def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type=[]):
>  
>      # pylint: disable=too-many-arguments
>      # pylint: disable=too-many-locals
> @@ -403,12 +412,8 @@ def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type=None):
>      else:
>          disk = parted.freshDisk(imag, "msdos")
>  
> -    if grub_version == 202 and grub_fw_type == "efi":
> -        grub = grubinstaller202(outf, "efi")
> -    elif grub_version == 202 and grub_fw_type == "hybrid":
> -        grub = grubinstaller202(outf, "hybrid")
> -    elif grub_version == 202:
> -        grub = grubinstaller202(outf)
> +    if grub_version == 202:
> +        grub = grubinstaller202(outf, grub_fw_type)
>      else:
>          grub = grubinstaller_base(outf)
>  
> @@ -481,7 +486,7 @@ def add_binary_blob(outf, hd, target):
>              bs))
>  
>  
> -def do_hdimg(outf, xml, target, rfs, grub_version, grub_fw_type=None):
> +def do_hdimg(outf, xml, target, rfs, grub_version, grub_fw_type=[]):
>  
>      # pylint: disable=too-many-arguments
>      # pylint: disable=too-many-locals
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> elbe-devel mailing list
> elbe-devel at linutronix.de
> https://lists.linutronix.de/mailman/listinfo/elbe-devel

-- 
Torben Hohn
Linutronix GmbH | Bahnhofstrasse 3 | D-88690 Uhldingen-Mühlhofen
Phone: +49 7556 25 999 18; Fax.: +49 7556 25 999 99

Hinweise zum Datenschutz finden Sie hier (Informations on data privacy 
can be found here): https://linutronix.de/kontakt/Datenschutz.php

Linutronix GmbH | Firmensitz (Registered Office): Uhldingen-Mühlhofen | 
Registergericht (Registration Court): Amtsgericht Freiburg i.Br., HRB700 
806 | Geschäftsführer (Managing Directors): Heinz Egger, Thomas Gleixner



More information about the elbe-devel mailing list