rauc / meta-rauc

Yocto/Open Embedded meta layer for RAUC, the embedded Linux update framework
MIT License
165 stars 91 forks source link

Yocto: No instructions for creating a bundle with a Post-install Hook #185

Closed alexanderwwagner closed 4 months ago

alexanderwwagner commented 3 years ago

Hello together,

at the moment I am trying to create a bundle with a post-install hook. But there I can not find any example for this purpose in the documentation...

That is my actual try: My update-bundle.bb:

`DESCRIPTION = "RAUC bundle generator"

inherit bundle

RAUC_BUNDLE_COMPATIBLE = "RaspberryPi4"
RAUC_BUNDLE_VERSION = "v20200703"
RAUC_BUNDLE_DESCRIPTION = "RAUC Demo Bundle"
RAUC_BUNDLE_SLOTS = "rootfs" 
RAUC_SLOT_rootfs = "core-image-minimal"
RAUC_SLOT_rootfs[fstype] = "ext4"

RAUC_KEY_FILE = "${THISDIR}/files/development-1.key.pem"
RAUC_CERT_FILE = "${THISDIR}/files/development-1.cert.pem"

RAUC_BUNDLE_HOOKS[file] = "${THISDIR}/files/hook.sh"
RAUC_BUNDLE_HOOKS[hooks] = "post-install"`

bitbake update-bundle fails now with:

FileNotFoundError: [Errno 2] No such file or directory: '/home/xxx/poky-gatesgarth/build-dir/tmp/work/raspberrypi3-poky-linux-gnueabi/update-bundle/1.0-r0//home/xxx/poky-gatesgarth/customlayers/meta-smarthome/meta-rauc-raspberrypi/recipes-core/bundles/files/hook.sh'

The update with rauc generally works for me. But I can not get work a hook.sh file after the update. => I need it to copy configuration files from the currently active slot to the new active slot

Can you give me a link to an example? Or give me some advice what I have to do here?

Thank you very much!

Alex

ejoerns commented 3 years ago

@Test4564 Where is your hook file currently placed in the BSP?

An option is to use simple fetcher handling here and do

SRC_URI += "file://hooks.sh"
RAUC_BUNDLE_HOOKS[file] = "hook.sh"
alexanderwwagner commented 3 years ago

Hello ejoerns,

I started with this tutorial: https://www.konsulko.com/getting-started-with-rauc-on-raspberry-pi-2/

So I used the meta-rauc-community layer and modified the contents of the layer for my usecase. => I added the hook.sh file in the recipes-core/bundles/files => I modified the update-bundle.bb file (see my first post)

My custom meta-rauc-community layer => Named meta-rauc-smarthome directory: LayerTree

If I add your suggested line to the update-bundle.bb file: => SRC_URI += "file://hooks.sh" RAUC_BUNDLE_HOOKS[file] = "hook.sh"

DESCRIPTION = "RAUC bundle generator"

inherit bundle

RAUC_BUNDLE_COMPATIBLE = "RaspberryPi4"
RAUC_BUNDLE_VERSION = "v20200703"
RAUC_BUNDLE_DESCRIPTION = "RAUC Demo Bundle"
RAUC_BUNDLE_SLOTS = "rootfs" 
RAUC_SLOT_rootfs = "core-image-minimal"
RAUC_SLOT_rootfs[fstype] = "ext4"

RAUC_KEY_FILE = "${THISDIR}/files/development-1.key.pem"
RAUC_CERT_FILE = "${THISDIR}/files/development-1.cert.pem"

SRC_URI += "file://hook.sh"
RAUC_BUNDLE_HOOKS[file] = "hook.sh"
RAUC_BUNDLE_HOOKS[hooks] = "post-install"

Then I have a license error: ERROR: update-bundle-1.0-r0 do_populate_lic: QA Issue: update-bundle: Recipe file fetches files and does not have license file information (LIC_FILES_CHKSUM) [license-checksum] ERROR: update-bundle-1.0-r0 do_populate_lic: Fatal QA errors found, failing task. ERROR: Logfile of failure stored in: /home/alexander/poky-gatesgarth/greencube-build/tmp/work/raspberrypi3-poky-linux-gnueabi/update-bundle/1.0-r0/temp/log.do_populate_lic.533 ERROR: Task (/home/alexander/poky-gatesgarth/customlayers/meta-smarthome/meta-rauc-raspberrypi/recipes-core/bundles/update-bundle.bb:do_populate_lic) failed with exit code '1'

Is this line right? => SRC_URI += "file://hooks.sh" => or do I have to write: SRC_URI += "${THISDIR}/files/hook.sh"

alexanderwwagner commented 3 years ago

I solved the problem with the license. I try tomorrow if your suggested lines work!

ejoerns commented 3 years ago

@Test4564 bitbake wants you to have a license when you include files as one can assume that this file is under a certain license. The simples case is to put it under MIT and do

LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"

Since #178 you are also free to chose a different one. But then you need to set LIC_FILES_CHKSUM to the appropriate one of ${COREBASE}/meta/files/common-licenses/ or ad a custom file.

alexanderwwagner commented 3 years ago

Thank you! Yes I solved it in this way.

My update-bundle.bb:

DESCRIPTION = "RAUC bundle generator"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

inherit bundle

RAUC_BUNDLE_COMPATIBLE = "RaspberryPi4"
RAUC_BUNDLE_VERSION = "v20200703"
RAUC_BUNDLE_DESCRIPTION = "RAUC Demo Bundle"
RAUC_BUNDLE_SLOTS = "rootfs" 
RAUC_SLOT_rootfs = "core-image-minimal"
RAUC_SLOT_rootfs[fstype] = "ext4"

RAUC_KEY_FILE = "${THISDIR}/files/development-1.key.pem"
RAUC_CERT_FILE = "${THISDIR}/files/development-1.cert.pem"

SRC_URI += " file://hook.sh"
RAUC_BUNDLE_HOOKS[file] = "hook.sh"
RAUC_BUNDLE_HOOKS[hooks] = "post-install"

My hook.sh:

#!/bin/sh

case "$1" in
        slot-post-install)
                # only rootfs needs to be handled
                test "$RAUC_SLOT_CLASS" = "rootfs" || exit 0

                touch "$RAUC_SLOT_MOUNT_POINT/extra-file"
                ;;
        *)
                exit 1
                ;;
esac

exit 0

My generated manifest.raucm

[update]
compatible=RaspberryPi4
version=v20200703
description=RAUC Demo Bundle
build=20210325063351

[hooks]
filename=hook.sh

[image.rootfs]
sha256=aeb8fa180acb027d62ea566749956b5809f6ff850c3f8f1539e5ce46d666190d
size=176160768
filename=core-image-minimal-raspberrypi3.ext4

If I update my raspberry with this bundle. I can not see any effect of the hook.sh... I would have expected that I can see after the update a file named "extra-file" in the root directory. What is my failure here? => I wonder that in the generated manifest.raucm is nothing to see about the "post-install" ...?

Extract from the documentation: Bildschirmfoto von 2021-03-25 11-27-36

alexanderwwagner commented 3 years ago

Do you know whats wrong with my configuration? Why is my post-install hook not working?

Do I misunderstand the example out of the documentation?

ejoerns commented 3 years ago

@Test4564 instead of

RAUC_BUNDLE_HOOKS[hooks] = "post-install"

which is for speciying 'Install Hooks' [1], you want to specify a 'Slot Hook' [2]:

RAUC_SLOT_rootfs[hooks] = "post-install"

You should at least see any warning anywhere when doing this wrong. Don't you?

ejoerns commented 3 years ago

@alexanderwwagner did this resolve your issue? I also hope the added sanity checks will even better prevent from running into hook issues in future RAUC releases.

alexanderwwagner commented 3 years ago

@ejoerns thank you very much I changed the line like you said and now it works. Unfortunately I could not read this out of the documentation. I did not see any warning that I used it false... But maybe I have overlooked it.

My update-bundle.bb

DESCRIPTION = "RAUC bundle generator"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

inherit bundle

RAUC_BUNDLE_COMPATIBLE = "RaspberryPi4"
RAUC_BUNDLE_VERSION = "v20200703"
RAUC_BUNDLE_DESCRIPTION = "RAUC Demo Bundle"
RAUC_BUNDLE_SLOTS = "rootfs" 
RAUC_SLOT_rootfs = "core-image-minimal"
RAUC_SLOT_rootfs[fstype] = "ext4"

RAUC_KEY_FILE = "${THISDIR}/files/development-1.key.pem"
RAUC_CERT_FILE = "${THISDIR}/files/development-1.cert.pem"

SRC_URI += " file://hook.sh"
RAUC_BUNDLE_HOOKS[file] = "hook.sh"
#RAUC_BUNDLE_HOOKS[hooks] = "post-install"
RAUC_SLOT_rootfs[hooks] = "post-install"

Directory of the bundle:

.
├── files
│   ├── development-1.cert.pem
│   ├── development-1.key.pem
│   └── hook.sh
└── update-bundle.bb

1 directory, 4 files
alexanderwwagner commented 3 years ago

@ejoerns one more question please. Is there any chapter in the documentation where is described, how to update the kernel through a rauc bundle? Or is that given by the default configuration of rauc?

Thank you and have a nice day!

ejoerns commented 3 years ago

@alexanderwwagner Glad it works for you now

@ejoerns one more question please. Is there any chapter in the documentation where is described, how to update the kernel through a rauc bundle? Or is that given by the default configuration of rauc?

From your question, I assume that you have your kernel in a separate partition, right?

In general, our advice would be to just pack the kernel into the rootfs. All common bootloader have the ability to read standard file systems and can thus access it from there. This avoids prevents complexity, potential incompatibilities between rootfs and kernel etc.

In case you have a separate partition, I would assume that the kernel lies just plain in it (so no file system). I hope that your kernel partition is redundant as well.

In this case, you can simply create distinct raw kernel partition slots and connect each of them to the respective rootfs slot (by a parent relation).

[slot.kernel.0]
parent=rootfs.0
type=raw
device=/dev/mmcblkXpY
alexanderwwagner commented 3 years ago

Yes I have one boot partition (kernel + bootloader) and one rootfs partition. (Thats the default configuration of yocto for this system.)

Okay I am going to research about this topic. Maybe I change it to your suggestion and put the kernel in the rootfs but I have to get some informations about this. At the moment I do not have any idea what I have to do, that yocto is doing this.

Thank you!

ejoerns commented 3 years ago

Okay I am going to research about this topic. Maybe I change it to your suggestion and put the kernel in the rootfs but I have to get some informations about this.

@alexanderwwagner It should be as easy as putting kernel-image and kernel-devicetree into IMAGE_INSTALL

What we then additionally use here (but this needs to be supported by the bootloader) is the Bootloader Specification for booting the right combination of kernel + dtb (see https://systemd.io/BOOT_LOADER_SPECIFICATION/) with the spec file created using this class. This needs to be supported by the bootloader (as it is in barebox), but you can also simply tell the bootloder explicitly which kernel + dtb to boot from the rootfs.