From patchwork Fri Dec 29 12:30:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gylstorff Quirin X-Patchwork-Id: 13506487 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8833DC4706F for ; Fri, 29 Dec 2023 12:31:26 +0000 (UTC) Received: from mta-64-226.siemens.flowmailer.net (mta-64-226.siemens.flowmailer.net [185.136.64.226]) by mx.groups.io with SMTP id smtpd.web10.145898.1703853077093461463 for ; Fri, 29 Dec 2023 04:31:18 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=Quirin.Gylstorff@siemens.com header.s=fm1 header.b=n2q00QfM; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.226, mailfrom: fm-51332-20231229123114a97976f4c570fcf3a0-ivoq25@rts-flowmailer.siemens.com) Received: by mta-64-226.siemens.flowmailer.net with ESMTPSA id 20231229123114a97976f4c570fcf3a0 for ; Fri, 29 Dec 2023 13:31:14 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=Quirin.Gylstorff@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:References:In-Reply-To; bh=jhHsiL5Guja4r0mVF0qMGAYx2iqpSAoeGtDQ7B1yTvY=; b=n2q00QfM/TIufXulb8RF0l/KYdyKJoGTR3Nbho11ptkTTi3F1WwCAwdfyuSL7weMbqZo/n uBMLT//uexziEfQTEzshXMgLBx6k1GO+1jmlSuMabXuqQHDRWURh4jqSALCwr16TU5TI7TPD tiDpmI2TXhGq2+rZt/qu3nLTouwJ4=; From: Quirin Gylstorff To: felix.moessbauer@siemens.com, jan.kiszka@siemens.com, cip-dev@lists.cip-project.org Subject: [cip-dev][isar-cip-core][RFC v3 1/5] efibootguard-efi.py: copy signed ebg binary to DEPLOY_DIR Date: Fri, 29 Dec 2023 13:30:39 +0100 Message-ID: <20231229123111.400555-2-Quirin.Gylstorff@siemens.com> In-Reply-To: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> References: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-51332:519-21489:flowmailer List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 29 Dec 2023 12:31:26 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/14217 From: Quirin Gylstorff This allows to add the signed ebg binary to a swu file for updating the bootloader. Signed-off-by: Quirin Gylstorff --- scripts/lib/wic/plugins/source/efibootguard-efi.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/lib/wic/plugins/source/efibootguard-efi.py b/scripts/lib/wic/plugins/source/efibootguard-efi.py index 86a22e0..f40b706 100644 --- a/scripts/lib/wic/plugins/source/efibootguard-efi.py +++ b/scripts/lib/wic/plugins/source/efibootguard-efi.py @@ -68,6 +68,12 @@ class EfibootguardEFIPlugin(SourcePlugin): "riscv64": "riscv64-linux-gnu", } + deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") + if not deploy_dir: + msger.error("DEPLOY_DIR_IMAGE not set, exiting\n") + exit(1) + creator.deploy_dir = deploy_dir + distro_arch = get_bitbake_var("DISTRO_ARCH") bootloader = "/usr/lib/{libpath}/efibootguard/efibootguard{efiarch}.efi".format( libpath=distro_to_lib_arch[distro_arch], @@ -90,6 +96,13 @@ class EfibootguardEFIPlugin(SourcePlugin): part_rootfs_dir, name) exec_cmd(cp_cmd, True) + msger.debug("copy {signed_bootloader} to deploy") + cp_to_deploy_cmd = "cp %s/%s %s/%s" % (cr_workdir, + signed_bootloader, + deploy_dir, + name) + exec_cmd(cp_to_deploy_cmd, True) + du_cmd = "du --apparent-size -ks %s" % part_rootfs_dir blocks = int(exec_cmd(du_cmd).split()[0]) From patchwork Fri Dec 29 12:30:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gylstorff Quirin X-Patchwork-Id: 13506489 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79BC2C46CD4 for ; Fri, 29 Dec 2023 12:31:26 +0000 (UTC) Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net [185.136.64.228]) by mx.groups.io with SMTP id smtpd.web10.145900.1703853077149302998 for ; Fri, 29 Dec 2023 04:31:18 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=Quirin.Gylstorff@siemens.com header.s=fm1 header.b=oyBRBs4w; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.228, mailfrom: fm-51332-2023122912311505452c4c83a0977127-mmn_1a@rts-flowmailer.siemens.com) Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 2023122912311505452c4c83a0977127 for ; Fri, 29 Dec 2023 13:31:15 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=Quirin.Gylstorff@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:References:In-Reply-To; bh=7gHnhlyNKtrsuS4aR2Oo096eNq55FBb/1ZuK5H7AZSw=; b=oyBRBs4w4+9/IhrOsnocxOYJDT1OZ+KVmFNxd6sBs3v+nOcROkQXAGAYuWObpY0mRq6Iy6 DyLJGY0v7Pmmd6hjrgzAH2rS309FovavLlH2H7Qx0xc3pziLNbGrZIVWXYkimoKjHtYTZmox Jahd5O+lO04y7bgzU08XgshVjuZ5k=; From: Quirin Gylstorff To: felix.moessbauer@siemens.com, jan.kiszka@siemens.com, cip-dev@lists.cip-project.org Subject: [cip-dev][isar-cip-core][RFC v3 2/5] swupdate.bbclass: Add SWU_EXTEND_SW_DESCRIPTION Date: Fri, 29 Dec 2023 13:30:40 +0100 Message-ID: <20231229123111.400555-3-Quirin.Gylstorff@siemens.com> In-Reply-To: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> References: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-51332:519-21489:flowmailer List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 29 Dec 2023 12:31:26 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/14216 From: Quirin Gylstorff The elements of the new variable are called as functions. This allows the user to extend the sw-description file with new template variables and new entries. Signed-off-by: Quirin Gylstorff --- classes/swupdate.bbclass | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass index 117f9fe..dfe8ef1 100644 --- a/classes/swupdate.bbclass +++ b/classes/swupdate.bbclass @@ -53,6 +53,16 @@ IMAGE_TEMPLATE_VARS:swu = " \ addtask do_transform_template after do_generate_image_uuid python(){ + cmds = d.getVar("SWU_EXTEND_SW_DESCRIPTION") + if cmds is None or not cmds.strip(): + return + cmds = cmds.split() + for cmd in cmds: + bb.build.exec_func(cmd, d) +} + +SWU_EXTEND_SW_DESCRIPTION += "add_swu_hw_compat" +python add_swu_hw_compat(){ # create SWU_HW_COMPAT_NODE based on list of supported hw hw_compat = d.getVar('SWU_HW_COMPAT') if hw_compat: @@ -61,7 +71,10 @@ python(){ 'hardware-compatibility: [ ' + hw_entries +' ];') else: d.setVar('SWU_HW_COMPAT_NODE', '') +} +SWU_EXTEND_SW_DESCRIPTION += "add_swu_compression" +python add_swu_compression(){ # create SWU_COMPRESSION_NODE node if compression is enabled calgo = d.getVar('SWU_COMPRESSION_TYPE') if calgo: From patchwork Fri Dec 29 12:30:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gylstorff Quirin X-Patchwork-Id: 13506490 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0008C47079 for ; Fri, 29 Dec 2023 12:31:26 +0000 (UTC) Received: from mta-64-225.siemens.flowmailer.net (mta-64-225.siemens.flowmailer.net [185.136.64.225]) by mx.groups.io with SMTP id smtpd.web11.145486.1703853077764358984 for ; Fri, 29 Dec 2023 04:31:19 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=Quirin.Gylstorff@siemens.com header.s=fm1 header.b=XeBrtt5E; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.225, mailfrom: fm-51332-202312291231158fe160f2bead5f477f-cb970f@rts-flowmailer.siemens.com) Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 202312291231158fe160f2bead5f477f for ; Fri, 29 Dec 2023 13:31:15 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=Quirin.Gylstorff@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:References:In-Reply-To; bh=7mXSRKjKjBTxeAx54i/Kq2LyfVCmXlZB/F4kLcaNcMo=; b=XeBrtt5EgEdSEc2Xn/1xUFUC0KOFp0gbDG8jXdRLHN9H9MC7++I9iBkJldtGPpdxov7QFJ FAqV/jCCzS9AMuK9QJWbRHy+jdpZYmddC4AAKwhg8Kk8D+y0jj4wSbp9qMQj181jwjgFKiFY Ayf1WVfcHEdzhYFXaQkkRj2FjDfds=; From: Quirin Gylstorff To: felix.moessbauer@siemens.com, jan.kiszka@siemens.com, cip-dev@lists.cip-project.org Subject: [cip-dev][isar-cip-core][RFC v3 3/5] swupdate: Extend sw-description to update efibootguard Date: Fri, 29 Dec 2023 13:30:41 +0100 Message-ID: <20231229123111.400555-4-Quirin.Gylstorff@siemens.com> In-Reply-To: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> References: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-51332:519-21489:flowmailer List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 29 Dec 2023 12:31:26 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/14219 From: Quirin Gylstorff 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 --- 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" + } + 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}); } From patchwork Fri Dec 29 12:30:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gylstorff Quirin X-Patchwork-Id: 13506491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8447FC47074 for ; Fri, 29 Dec 2023 12:31:26 +0000 (UTC) Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by mx.groups.io with SMTP id smtpd.web11.145487.1703853078463353453 for ; Fri, 29 Dec 2023 04:31:19 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=Quirin.Gylstorff@siemens.com header.s=fm1 header.b=THjge/5n; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.225, mailfrom: fm-51332-202312291231165fe5ae272540efe3a0-oyqqz_@rts-flowmailer.siemens.com) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 202312291231165fe5ae272540efe3a0 for ; Fri, 29 Dec 2023 13:31:16 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=Quirin.Gylstorff@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:References:In-Reply-To; bh=iSo11YgGKfF26Tu508+zrphdN34J1DYOP5aRMP0zbbc=; b=THjge/5nA6udNt9mg9Omre4gR8cXP/9KXGDX5TzBSE5CZBH6GzVH715Klkg/l1k8cauhfy V4ftgeRCsTh83M+v/SD+T7Di9kngsAz7bbpynORpDnj7s6W0aKY9udwPM9VQkAl37jJGWR51 j2Z2m1Tt0TFEHs3DW3Ox3lH2D6V8Q=; From: Quirin Gylstorff To: felix.moessbauer@siemens.com, jan.kiszka@siemens.com, cip-dev@lists.cip-project.org Subject: [cip-dev][isar-cip-core][RFC v3 4/5] classes: Generate sw-description from bitbake variables Date: Fri, 29 Dec 2023 13:30:42 +0100 Message-ID: <20231229123111.400555-5-Quirin.Gylstorff@siemens.com> In-Reply-To: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> References: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-51332:519-21489:flowmailer List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 29 Dec 2023 12:31:26 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/14220 From: Quirin Gylstorff This adds the possibility to generate the sw-description files from the following variables: - SWU_IMAGES: Contains the flags to install a image file - SWU_FILES: Contains the flags for single files - SWU_SCRIPTS: Contains the flags for installation scripts To generate the sw-description add the following lines to the image recipe: ``` inherit swupdate inherit sw-description-generator.bbclass SWU_IMAGES += "rootfs" SWU_IMAGE_rootfs[filename] = "${SWU_ROOTFS_PARTITION_NAME}" SWU_IMAGE_rootfs[device] = "C:BOOT0:linux.efi->${ABROOTFS_PART_UUID_A},C:BOOT1:linux.efi->${ABROOTFS_PART_UUID_B}" SWU_IMAGE_rootfs[type] = "roundrobin" SWU_IMAGE_rootfs[properties] += "subtype:image" SWU_IMAGE_rootfs[properties] += "configfilecheck:/etc/os-release@not_match@IMAGE_UUID=${TARGET_IMAGE_UUID}" SWU_FILES += "kernel" SWU_FILE_kernel[filename] = "linux.efi" SWU_FILE_kernel[path] = "linux.efi" SWU_FILE_kernel[type] = "roundrobin" SWU_FILE_kernel[device] = "C:BOOT0:linux.efi->BOOT0,C:BOOT1:linux.efi->BOOT1" SWU_FILE_kernel[filesystem] = "vfat" SWU_FILE_kernel[properties] = "subtype:kernel" ``` Signed-off-by: Quirin Gylstorff --- classes/sw-description-generator.bbclass | 200 ++++++++++++++++++ .../jsontolibconf/files/jsontolibconf | 54 +++++ .../jsontolibconf/jsontolibconf_0.1.bb | 22 ++ 3 files changed, 276 insertions(+) create mode 100644 classes/sw-description-generator.bbclass create mode 100644 recipes-devtools/jsontolibconf/files/jsontolibconf create mode 100644 recipes-devtools/jsontolibconf/jsontolibconf_0.1.bb diff --git a/classes/sw-description-generator.bbclass b/classes/sw-description-generator.bbclass new file mode 100644 index 0000000..2e9f5e9 --- /dev/null +++ b/classes/sw-description-generator.bbclass @@ -0,0 +1,200 @@ +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2020-2023 +# +# Authors: +# Quirin Gylstorff +# +# SPDX-License-Identifier: MIT + +# This class generates the sw-description from the variables: +SWU_IMAGES ??= "" +SWU_FILES ??= "" +SWU_SCRIPTS ??= "" + +# Each image/file/script added by these variables needs to be specified in +# the following format. See also +# https://sbabic.github.io/swupdate/sw-description.html + +# EXAMPLE configuration +# the following configuration installs a new rootfs,kernel and +# bootloader to the target +# +# Add the root filesystem image: +# SWU_IMAGES += "rootfs" +# SWU_IMAGE_rootfs[filename] = "${SWU_ROOTFS_PARTITION_NAME}" +# SWU_IMAGE_rootfs[device] = "C:BOOT0:linux.efi->${ABROOTFS_PART_UUID_A},C:BOOT1:linux.efi->${ABROOTFS_PART_UUID_B}" +# SWU_IMAGE_rootfs[type] = "roundrobin" +# SWU_IMAGE_rootfs[compressed] = "zlib" +# SWU_IMAGE_rootfs[properties] += "subtype:image" +# SWU_IMAGE_rootfs[properties] += "configfilecheck:/etc/os-release@not_match@IMAGE_UUID=${TARGET_IMAGE_UUID}" +# +# Add the kernel file +# SWU_FILES += "kernel" +# SWU_FILE_kernel[filename] = "linux.efi" +# SWU_FILE_kernel[path] = "linux.efi" +# SWU_FILE_kernel[type] = "roundrobin" +# SWU_FILE_kernel[device] = "C:BOOT0:linux.efi->BOOT0,C:BOOT1:linux.efi->BOOT1" +# SWU_FILE_kernel[filesystem] = "vfat" +# SWU_FILE_kernel[properties] = "subtype:kernel" +# +# Add the bootloader file +# SWU_FILES += "ebg" +# SWU_FILE_ebg[filename] = "bootx64.efi" +# SWU_FILE_ebg[path] = "EFI/BOOT/bootx64.efi" +# SWU_FILE_ebg[device] = "/dev/disk/by-uuid/4321-DCBA" +# SWU_FILE_ebg[filesystem] = "vfat" +# +# Add some preinstallation script +# SWU_SCRIPTS += "preinstall" +# SWU_SCRIPT_preinstall[filename] = "preinstall.sh" +# SWU_SCRIPT_preinstall[type] = "preinstall.sh" + +def add_flag_to_dict(d, var, flagname, dictionary): + flag = d.getVarFlag(var, flagname) or "" + if flag: + dictionary.update({flagname: flag}) + + +def add_list_to_dict(d, var_entry, flagname, dictionary): + flag = d.getVarFlag(var_entry, flagname) or "" + if flag: + entries = flag.split() + result = {} + for entry in entries: + key, value = entry.split(':') + result.update({key: value}) + dictionary.update({flagname: result}) + + +def get_entries_from_var(d, entries_var, entry_var): + entries = (d.getVar(entries_var) or "").split() + if not entries: + return None + # see https://sbabic.github.io/swupdate/sw-description.html + # sha256 is added directly + # data, encrypted and hook are currently not supported + possible_image_flags = ("filename", "type", + "device", + "compressed", "name", "version", + "install-if-different", + "install-if-higher", + "installed-directly", + "offset", ) + possible_file_flags = ("filename", "type", + "device", + "compressed", "name", "version", + "install-if-different", + "install-if-higher", + "filesystem", "path", "preserve-attributes") + possible_script_flags = ("filename", "type") + entry_var_to_flags = { + "SWU_IMAGE": possible_image_flags, + "SWU_FILE": possible_file_flags, + "SWU_SCRIPT": possible_script_flags, + } + + entry_list = [] + for entry in entries: + elem = {} + var_entry = f"{entry_var}_{entry}" + for flag in entry_var_to_flags[entry_var]: + add_flag_to_dict(d, var_entry, flag, elem) + if flag == "filename": + # filename handling + filename = elem.get("filename") + if not filename: + bb.warn(f"No filename for {var_entry}. Entry will not be added to sw-description") + continue + elem.update({ "sha256": f"{filename}-sha256" }) + + add_list_to_dict(d, var_entry, "properties", elem) + entry_list.append(elem) + # we return a tuple as this allow to generate json or libconfig + # swuconfigurations + return tuple(entry_list) + + +def generate_sw_description(d): + sw_description = {} + # in theory we can have multiple boards + # this is currently not support + board = {} + hw_compat = d.getVar('SWU_HW_COMPAT') + if hw_compat: + hw_entries = ', '. join(['"' + h + '"' for h in hw_compat.split()]) + board.update({"hardware-compatibility": hw_entries}) + # Images + sw_images = get_entries_from_var(d, "SWU_IMAGES", "SWU_IMAGE") + if sw_images: + board.update({"images": sw_images}) + # Files + sw_files = get_entries_from_var(d, "SWU_FILES", "SWU_FILE") + if sw_files: + board.update({"files": sw_files}) + # Scripts + sw_scripts = get_entries_from_var(d, "SWU_SCRIPTS", "SWU_SCRIPT") + if sw_scripts: + board.update({"scripts": sw_scripts}) + + boardname = d.getVar("SWU_BOARD_NAME") + if boardname and hw_compat: + software.update({boardname: board}) + else: + software = board + + swu_version = d.getVar('SWU_VERSION') + name = d.getVar('SWU_NAME') + reboot = d.getVar('SWU_REBOOT') + transition_marker = d.get('SWU_BOOTLOADER_TRANSITION_MARKER') + + software.update({'version': swu_version, 'name': name}) + if reboot: + software.update({'reboot': reboot, }) + if transition_marker: + software.update({'bootloader_transaction_marker': transition_marker, }) + + + sw_description.update({"software": software}) + + return sw_description + + +covert_to_libconfig () { + if [ -e '${WORKDIR}/${SWU_DESCRIPTION_FILE}.json' ]; then + rm -f '${WORKDIR}/${SWU_DESCRIPTION_FILE}' + imager_run -p -d ${PP_WORK} -u root <<'EOIMAGER' + jsontolibconf '${PP_WORK}/${SWU_DESCRIPTION_FILE}.json' --output_file '${PP_WORK}/${SWU_DESCRIPTION_FILE}' +EOIMAGER + fi + sudo chown -R $(id -u):$(id -g) '${WORKDIR}/${SWU_DESCRIPTION_FILE}' +} + +IMAGER_BUILD_DEPS += "jsontolibconf" +INSTALL_write_sw_description += "jsontolibconf" + +do_write_sw_description[network] = "${TASK_USE_SUDO}" +python do_write_sw_description () { + import json + import os + workdir = d.getVar("WORKDIR") + sw_desc_file = d.getVar("SWU_DESCRIPTION_FILE") + swu_files = (d.getVar('SWU_IMAGES'), d.getVar('SWU_FILES'), d.getVar('SWU_SCRIPTS')) + if os.path.exists(f"{workdir}/{sw_desc_file}.tmpl") and \ + [x for x in swu_files if x is not None]: + bb.warn(f"{sw_desc_file}.tmpl template exists. \ + sw-description will not be be generate from variables \ + SWU_IMAGES, SWU_FILES and SWU_SCRIPTS") + pass + sw_description = generate_sw_description(d) + + with open(f"{workdir}/{sw_desc_file}.json","w") as sw_desc_fd: + json.dump(sw_description, sw_desc_fd, indent=2) + bb.build.exec_func("covert_to_libconfig", d) +} + +IMAGE_SRC_URI:swu:remove = "file://${SWU_DESCRIPTION_FILE}.tmpl" +IMAGE_TEMPLATE_FILES:swu:remove = "${SWU_DESCRIPTION_FILE}.tmpl" + +addtask do_write_sw_description after do_generate_image_uuid before do_transform_template diff --git a/recipes-devtools/jsontolibconf/files/jsontolibconf b/recipes-devtools/jsontolibconf/files/jsontolibconf new file mode 100644 index 0000000..897daa3 --- /dev/null +++ b/recipes-devtools/jsontolibconf/files/jsontolibconf @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2023 +# +# Authors: +# Quirin Gylstorff +# +# SPDX-License-Identifier: MIT + +import json +import libconf +import argparse +from os import path +from sys import exit + + +def convert_lists_to_tuples(obj): + if isinstance(obj, list): + return tuple(obj) + elif isinstance(obj, dict): + return {key: convert_lists_to_tuples(value) for key, value in obj.items()} + else: + return obj + + +def convert_json_to_libconfig(input_file, output_file): + if not path.exists(input_file): + print(f"Error: The file {input_file} does not exists. Abort!") + exit(1) + + with open(input_file, "r") as json_fd: + json_obj = json.load(json_fd) + + converted_json_obj = convert_lists_to_tuples(json_obj) + + libconf_data = libconf.dumps(converted_json_obj) + if output_file: + with open(output_file, "w") as libconf_fd: + libconf_fd.write(libconf_data) + else: + print(libconf_data) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Convert a json file to a libconfig file" + ) + parser.add_argument("input_file", help="Input JSON file name") + parser.add_argument("--output_file", help="Output libconfig file name") + + args = parser.parse_args() + convert_json_to_libconfig(args.input_file, args.output_file) diff --git a/recipes-devtools/jsontolibconf/jsontolibconf_0.1.bb b/recipes-devtools/jsontolibconf/jsontolibconf_0.1.bb new file mode 100644 index 0000000..97a5d5f --- /dev/null +++ b/recipes-devtools/jsontolibconf/jsontolibconf_0.1.bb @@ -0,0 +1,22 @@ +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2023 +# +# Authors: +# Quirin Gylstorff +# +# SPDX-License-Identifier: MIT + +inherit dpkg-raw + +SRC_URI = "file://jsontolibconf" + +DEBIAN_DEPENDS = "python3-libconf" + +DPKG_ARCH = "all" + +do_install[cleandirs] = "${D}/usr/bin" +do_install() { + install -m 755 ${WORKDIR}/jsontolibconf ${D}/usr/bin/ +} From patchwork Fri Dec 29 12:30:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gylstorff Quirin X-Patchwork-Id: 13506486 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78439C46CD3 for ; Fri, 29 Dec 2023 12:31:26 +0000 (UTC) Received: from mta-65-226.siemens.flowmailer.net (mta-65-226.siemens.flowmailer.net [185.136.65.226]) by mx.groups.io with SMTP id smtpd.web10.145902.1703853079325226472 for ; Fri, 29 Dec 2023 04:31:19 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=Quirin.Gylstorff@siemens.com header.s=fm1 header.b=hXWg09BK; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.226, mailfrom: fm-51332-20231229123116abb5ee574515380dc0-fetfwh@rts-flowmailer.siemens.com) Received: by mta-65-226.siemens.flowmailer.net with ESMTPSA id 20231229123116abb5ee574515380dc0 for ; Fri, 29 Dec 2023 13:31:17 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=Quirin.Gylstorff@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:References:In-Reply-To; bh=5Ck8bLWRwsiXEYgeXqX6i/eKzbq5fQTsHfuVwGCwgyY=; b=hXWg09BKrpe8QncaSB9ld7oPpyV5Csz/u8UtOm/K4PIy82mVuy+Sj2TRHSJSLgThZ/34aL OOkAt8bjhZKr3kSz3mbMzqBs+LwlA6c57cR2zrsIIebulR5AbvywAgu2C+Yl6b6Ok5dU15s9 N4Fcpn2ubNQWWooEUA9MK9TMssaXA=; From: Quirin Gylstorff To: felix.moessbauer@siemens.com, jan.kiszka@siemens.com, cip-dev@lists.cip-project.org Subject: [cip-dev][isar-cip-core][RFC v3 5/5] images/swupdate.inc: Add variables to generate the sw-description Date: Fri, 29 Dec 2023 13:30:43 +0100 Message-ID: <20231229123111.400555-6-Quirin.Gylstorff@siemens.com> In-Reply-To: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> References: <20231229123111.400555-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-51332:519-21489:flowmailer List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 29 Dec 2023 12:31:26 -0000 X-Groupsio-URL: https://lists.cip-project.org/g/cip-dev/message/14221 From: Quirin Gylstorff This done for all distributions except Debian buster. Signed-off-by: Quirin Gylstorff --- recipes-core/images/swupdate.inc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/recipes-core/images/swupdate.inc b/recipes-core/images/swupdate.inc index 4983f7c..388faad 100644 --- a/recipes-core/images/swupdate.inc +++ b/recipes-core/images/swupdate.inc @@ -11,6 +11,33 @@ inherit image_uuid inherit read-only-rootfs +inherit ${@'' if d.getVar('BASE_DISTRO_CODENAME') == 'buster' else 'sw-description-generator'} + +SWU_IMAGES += "rootfs" +SWU_IMAGE_rootfs[filename] = "${SWU_ROOTFS_PARTITION_NAME}" +SWU_IMAGE_rootfs[device] = "C:BOOT0:linux.efi->${ABROOTFS_PART_UUID_A},C:BOOT1:linux.efi->${ABROOTFS_PART_UUID_B}" +SWU_IMAGE_rootfs[type] = "roundrobin" +SWU_IMAGE_rootfs[compressed] = "zlib" +SWU_IMAGE_rootfs[properties] += "subtype:image" +SWU_IMAGE_rootfs[properties] += "configfilecheck:/etc/os-release@not_match@IMAGE_UUID=${TARGET_IMAGE_UUID}" + +SWU_FILES += "kernel" +SWU_FILE_kernel[filename] = "linux.efi" +SWU_FILE_kernel[path] = "linux.efi" +SWU_FILE_kernel[type] = "roundrobin" +SWU_FILE_kernel[device] = "C:BOOT0:linux.efi->BOOT0,C:BOOT1:linux.efi->BOOT1" +SWU_FILE_kernel[filesystem] = "vfat" +SWU_FILE_kernel[properties] = "subtype:kernel" + +EFI_BOOTLOADER_NAME = "${@efi_bootloader_name(d)}" +SWU_ADDITIONAL_FILES += "${@d.getVar('EFI_BOOTLOADER_NAME') if bb.utils.to_boolean(d.getVar('SWU_EBG_UPDATE')) else ''}" + +SWU_FILES += "${@'ebg' if bb.utils.to_boolean(d.getVar('SWU_EBG_UPDATE')) else ''}" +SWU_FILE_ebg[filename] = "${EFI_BOOTLOADER_NAME}" +SWU_FILE_ebg[path] = "EFI/BOOT/${EFI_BOOTLOADER_NAME}" +SWU_FILE_ebg[device] = "${SWU_EFI_BOOT_DEVICE}" +SWU_FILE_ebg[filesystem] = "vfat" +SWU_FILE_kernel[properties] = "atomic-install:true" SWU_SIGNED ?= "1"