diff mbox series

[isar-cip-core,RFC,v3,3/5] swupdate: Extend sw-description to update efibootguard

Message ID 20231229123111.400555-4-Quirin.Gylstorff@siemens.com (mailing list archive)
State Changes Requested
Headers show
Series Add Bootloader to sw-description | expand

Commit Message

Gylstorff Quirin Dec. 29, 2023, 12:30 p.m. UTC
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

If the variable `SWU_EBG_UPDATE` is set to `1` an additional file
element is added to the sw-description to replace the ebg.

Use python as newlines are part of the sw-description syntax an
therefore cannot be hold in a bitbake variable, see note in[1].

The efibootguard binary has the property 'atomic-install' which
copies the file to a tempory location before replacing the original with
new file[2].

IMPORTANT: Even if the property 'atomic-install' is set FAT does not
support atomic writes or renames so a powercut can still corrupt the
system[3].

[1]: https://docs.yoctoproject.org/bitbake/2.2/bitbake-user-manual/bitbake-user-manual-metadata.html#line-joining
[2]: https://sbabic.github.io/swupdate/sw-description.html#files
[3]: https://lore.kernel.org/linux-fsdevel/20191022105413.pj6i3ydetnfgnkzh@pali/

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 classes/swupdate.bbclass                    | 39 ++++++++++++++++++++-
 recipes-core/images/swu/sw-description.tmpl |  2 +-
 2 files changed, 39 insertions(+), 2 deletions(-)

Comments

Jan Kiszka Jan. 2, 2024, 12:38 p.m. UTC | #1
On 29.12.23 13:30, Quirin Gylstorff wrote:
> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> 
> If the variable `SWU_EBG_UPDATE` is set to `1` an additional file
> element is added to the sw-description to replace the ebg.
> 
> Use python as newlines are part of the sw-description syntax an
> therefore cannot be hold in a bitbake variable, see note in[1].
> 
> The efibootguard binary has the property 'atomic-install' which
> copies the file to a tempory location before replacing the original with
> new file[2].
> 
> IMPORTANT: Even if the property 'atomic-install' is set FAT does not
> support atomic writes or renames so a powercut can still corrupt the
> system[3].
> 
> [1]: https://docs.yoctoproject.org/bitbake/2.2/bitbake-user-manual/bitbake-user-manual-metadata.html#line-joining
> [2]: https://sbabic.github.io/swupdate/sw-description.html#files
> [3]: https://lore.kernel.org/linux-fsdevel/20191022105413.pj6i3ydetnfgnkzh@pali/
> 
> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> ---
>  classes/swupdate.bbclass                    | 39 ++++++++++++++++++++-
>  recipes-core/images/swu/sw-description.tmpl |  2 +-
>  2 files changed, 39 insertions(+), 2 deletions(-)
> 
> diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
> index dfe8ef1..f9dab33 100644
> --- a/classes/swupdate.bbclass
> +++ b/classes/swupdate.bbclass
> @@ -22,6 +22,9 @@ SWU_NAME ?= "cip software update"
>  # space separated list of supported hw. Leave empty to leave out
>  SWU_HW_COMPAT ?= ""
>  
> +SWU_EBG_UPDATE ?= ""
> +SWU_EFI_BOOT_DEVICE ?= "/dev/disk/by-uuid/4321-DCBA"
> +
>  SWU_IMAGE_FILE ?= "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.swu"
>  SWU_DESCRIPTION_FILE ?= "sw-description"
>  SWU_ADDITIONAL_FILES ?= "linux.efi ${SWU_ROOTFS_PARTITION_NAME}"
> @@ -47,7 +50,21 @@ IMAGE_TEMPLATE_VARS:swu = " \
>      SWU_HW_COMPAT_NODE \
>      SWU_COMPRESSION_NODE \
>      SWU_VERSION \
> -    SWU_NAME"
> +    SWU_NAME \
> +    SWU_FILE_NODES \
> +    "
> +
> +# Add the bootloader file
> +def efi_bootloader_name(d):
> +    distro_arch = d.getVar('DISTRO_ARCH')
> +    distro_to_efi_arch = {
> +            "amd64": "x64",
> +            "arm64": "aa64",
> +            "armhf": "arm",
> +            "i386": "ia32",
> +            "riscv64": "riscv64"
> +    }

That's now the third time we have this mapping in our code. Maybe worth
the think about having it only once?

> +    return "boot{}.efi".format(distro_to_efi_arch[distro_arch])
>  
>  # TARGET_IMAGE_UUID needs to be generated before completing the template
>  addtask do_transform_template after do_generate_image_uuid
> @@ -83,6 +100,26 @@ python add_swu_compression(){
>          d.setVar('SWU_COMPRESSION_NODE', '')
>  }
>  
> +SWU_EXTEND_SW_DESCRIPTION += "${@ 'add_ebg_update' if d.getVar('SWU_EBG_UPDATE') == '1' else ''}"
> +python add_ebg_update(){
> +   efi_boot_loader_file = efi_bootloader_name(d)
> +   efi_boot_device = d.getVar('SWU_EFI_BOOT_DEVICE')
> +   swu_ebg_update_node = f""",
> +   {{
> +          filename = "{efi_boot_loader_file}";
> +          path = "EFI/BOOT/{efi_boot_loader_file}";
> +          device = "{efi_boot_device}";
> +          filesystem = "vfat";
> +          sha256 = "{efi_boot_loader_file}-sha256";
> +          properties: {{
> +               atomic-install = "true";
> +          }};
> +   }}
> +   """
> +   d.appendVar('SWU_FILE_NODES', swu_ebg_update_node)
> +   d.appendVar('SWU_ADDITIONAL_FILES', " " + efi_boot_loader_file)
> +}

I still wonder if the EBG update shouldn't simply be a separate SWU,
thus there would be also no need to perform any append operations on
existing ones.

> +
>  
>  # convert between swupdate compressor name and imagetype extension
>  def get_swu_compression_type(d):
> diff --git a/recipes-core/images/swu/sw-description.tmpl b/recipes-core/images/swu/sw-description.tmpl
> index 6b53a3c..c52372c 100644
> --- a/recipes-core/images/swu/sw-description.tmpl
> +++ b/recipes-core/images/swu/sw-description.tmpl
> @@ -34,5 +34,5 @@ software =
>                          subtype = "kernel";
>              };
>              sha256 = "linux.efi-sha256";
> -    });
> +    }${SWU_FILE_NODES});
>  }

Jan
Gylstorff Quirin Jan. 2, 2024, 1:22 p.m. UTC | #2
On 1/2/24 13:38, Jan Kiszka wrote:
> On 29.12.23 13:30, Quirin Gylstorff wrote:
>> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>>
>> If the variable `SWU_EBG_UPDATE` is set to `1` an additional file
>> element is added to the sw-description to replace the ebg.
>>
>> Use python as newlines are part of the sw-description syntax an
>> therefore cannot be hold in a bitbake variable, see note in[1].
>>
>> The efibootguard binary has the property 'atomic-install' which
>> copies the file to a tempory location before replacing the original with
>> new file[2].
>>
>> IMPORTANT: Even if the property 'atomic-install' is set FAT does not
>> support atomic writes or renames so a powercut can still corrupt the
>> system[3].
>>
>> [1]: https://docs.yoctoproject.org/bitbake/2.2/bitbake-user-manual/bitbake-user-manual-metadata.html#line-joining
>> [2]: https://sbabic.github.io/swupdate/sw-description.html#files
>> [3]: https://lore.kernel.org/linux-fsdevel/20191022105413.pj6i3ydetnfgnkzh@pali/
>>
>> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
>> ---
>>   classes/swupdate.bbclass                    | 39 ++++++++++++++++++++-
>>   recipes-core/images/swu/sw-description.tmpl |  2 +-
>>   2 files changed, 39 insertions(+), 2 deletions(-)
>>
>> diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
>> index dfe8ef1..f9dab33 100644
>> --- a/classes/swupdate.bbclass
>> +++ b/classes/swupdate.bbclass
>> @@ -22,6 +22,9 @@ SWU_NAME ?= "cip software update"
>>   # space separated list of supported hw. Leave empty to leave out
>>   SWU_HW_COMPAT ?= ""
>>   
>> +SWU_EBG_UPDATE ?= ""
>> +SWU_EFI_BOOT_DEVICE ?= "/dev/disk/by-uuid/4321-DCBA"
>> +
>>   SWU_IMAGE_FILE ?= "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.swu"
>>   SWU_DESCRIPTION_FILE ?= "sw-description"
>>   SWU_ADDITIONAL_FILES ?= "linux.efi ${SWU_ROOTFS_PARTITION_NAME}"
>> @@ -47,7 +50,21 @@ IMAGE_TEMPLATE_VARS:swu = " \
>>       SWU_HW_COMPAT_NODE \
>>       SWU_COMPRESSION_NODE \
>>       SWU_VERSION \
>> -    SWU_NAME"
>> +    SWU_NAME \
>> +    SWU_FILE_NODES \
>> +    "
>> +
>> +# Add the bootloader file
>> +def efi_bootloader_name(d):
>> +    distro_arch = d.getVar('DISTRO_ARCH')
>> +    distro_to_efi_arch = {
>> +            "amd64": "x64",
>> +            "arm64": "aa64",
>> +            "armhf": "arm",
>> +            "i386": "ia32",
>> +            "riscv64": "riscv64"
>> +    }
> 
> That's now the third time we have this mapping in our code. Maybe worth
> the think about having it only once?

We have it in the wic plugins and now in swupdate I can move it to a 
seperate class in to a variable BOOTLOADER_BINARY and use that variable 
in the wic files.

This would also allow other binary not from efibootguard to be used.



> 
>> +    return "boot{}.efi".format(distro_to_efi_arch[distro_arch])
>>   
>>   # TARGET_IMAGE_UUID needs to be generated before completing the template
>>   addtask do_transform_template after do_generate_image_uuid
>> @@ -83,6 +100,26 @@ python add_swu_compression(){
>>           d.setVar('SWU_COMPRESSION_NODE', '')
>>   }
>>   
>> +SWU_EXTEND_SW_DESCRIPTION += "${@ 'add_ebg_update' if d.getVar('SWU_EBG_UPDATE') == '1' else ''}"
>> +python add_ebg_update(){
>> +   efi_boot_loader_file = efi_bootloader_name(d)
>> +   efi_boot_device = d.getVar('SWU_EFI_BOOT_DEVICE')
>> +   swu_ebg_update_node = f""",
>> +   {{
>> +          filename = "{efi_boot_loader_file}";
>> +          path = "EFI/BOOT/{efi_boot_loader_file}";
>> +          device = "{efi_boot_device}";
>> +          filesystem = "vfat";
>> +          sha256 = "{efi_boot_loader_file}-sha256";
>> +          properties: {{
>> +               atomic-install = "true";
>> +          }};
>> +   }}
>> +   """
>> +   d.appendVar('SWU_FILE_NODES', swu_ebg_update_node)
>> +   d.appendVar('SWU_ADDITIONAL_FILES', " " + efi_boot_loader_file)
>> +}
> 
> I still wonder if the EBG update shouldn't simply be a separate SWU,
> thus there would be also no need to perform any append operations on
> existing ones.
> 
I think both variants should be possible one only to update the 
bootloader and another for a whole system update.


>> +
>>   
>>   # convert between swupdate compressor name and imagetype extension
>>   def get_swu_compression_type(d):
>> diff --git a/recipes-core/images/swu/sw-description.tmpl b/recipes-core/images/swu/sw-description.tmpl
>> index 6b53a3c..c52372c 100644
>> --- a/recipes-core/images/swu/sw-description.tmpl
>> +++ b/recipes-core/images/swu/sw-description.tmpl
>> @@ -34,5 +34,5 @@ software =
>>                           subtype = "kernel";
>>               };
>>               sha256 = "linux.efi-sha256";
>> -    });
>> +    }${SWU_FILE_NODES});
>>   }
> 
> Jan
> 
Quirin
diff mbox series

Patch

diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
index dfe8ef1..f9dab33 100644
--- a/classes/swupdate.bbclass
+++ b/classes/swupdate.bbclass
@@ -22,6 +22,9 @@  SWU_NAME ?= "cip software update"
 # space separated list of supported hw. Leave empty to leave out
 SWU_HW_COMPAT ?= ""
 
+SWU_EBG_UPDATE ?= ""
+SWU_EFI_BOOT_DEVICE ?= "/dev/disk/by-uuid/4321-DCBA"
+
 SWU_IMAGE_FILE ?= "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.swu"
 SWU_DESCRIPTION_FILE ?= "sw-description"
 SWU_ADDITIONAL_FILES ?= "linux.efi ${SWU_ROOTFS_PARTITION_NAME}"
@@ -47,7 +50,21 @@  IMAGE_TEMPLATE_VARS:swu = " \
     SWU_HW_COMPAT_NODE \
     SWU_COMPRESSION_NODE \
     SWU_VERSION \
-    SWU_NAME"
+    SWU_NAME \
+    SWU_FILE_NODES \
+    "
+
+# Add the bootloader file
+def efi_bootloader_name(d):
+    distro_arch = d.getVar('DISTRO_ARCH')
+    distro_to_efi_arch = {
+            "amd64": "x64",
+            "arm64": "aa64",
+            "armhf": "arm",
+            "i386": "ia32",
+            "riscv64": "riscv64"
+    }
+    return "boot{}.efi".format(distro_to_efi_arch[distro_arch])
 
 # TARGET_IMAGE_UUID needs to be generated before completing the template
 addtask do_transform_template after do_generate_image_uuid
@@ -83,6 +100,26 @@  python add_swu_compression(){
         d.setVar('SWU_COMPRESSION_NODE', '')
 }
 
+SWU_EXTEND_SW_DESCRIPTION += "${@ 'add_ebg_update' if d.getVar('SWU_EBG_UPDATE') == '1' else ''}"
+python add_ebg_update(){
+   efi_boot_loader_file = efi_bootloader_name(d)
+   efi_boot_device = d.getVar('SWU_EFI_BOOT_DEVICE')
+   swu_ebg_update_node = f""",
+   {{
+          filename = "{efi_boot_loader_file}";
+          path = "EFI/BOOT/{efi_boot_loader_file}";
+          device = "{efi_boot_device}";
+          filesystem = "vfat";
+          sha256 = "{efi_boot_loader_file}-sha256";
+          properties: {{
+               atomic-install = "true";
+          }};
+   }}
+   """
+   d.appendVar('SWU_FILE_NODES', swu_ebg_update_node)
+   d.appendVar('SWU_ADDITIONAL_FILES', " " + efi_boot_loader_file)
+}
+
 
 # convert between swupdate compressor name and imagetype extension
 def get_swu_compression_type(d):
diff --git a/recipes-core/images/swu/sw-description.tmpl b/recipes-core/images/swu/sw-description.tmpl
index 6b53a3c..c52372c 100644
--- a/recipes-core/images/swu/sw-description.tmpl
+++ b/recipes-core/images/swu/sw-description.tmpl
@@ -34,5 +34,5 @@  software =
                         subtype = "kernel";
             };
             sha256 = "linux.efi-sha256";
-    });
+    }${SWU_FILE_NODES});
 }