Re: [OE-core][PATCH 1/6] classes-recipe/image: Add image file manifest

Martin Hundebøll
2024-06-11T08:50:35Z

Hi Joshua,

Two minor nits below.

On Mon, 2024-06-10 at 15:41 -0600, Joshua Watt wrote:
> Downstream tasks may want to know what image files were written by
> the
> do_image family of tasks (e.g. SPDX) so have each task write out a
> manifest file that describes the files it produced, then aggregate
> them
> in do_image_complete
>
> Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
> ---
>  meta/classes-recipe/image.bbclass | 61
> +++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
>
> diff --git a/meta/classes-recipe/image.bbclass b/meta/classes-
> recipe/image.bbclass
> index 28be6c63623..122af2b0328 100644
> --- a/meta/classes-recipe/image.bbclass
> +++ b/meta/classes-recipe/image.bbclass
> @@ -88,6 +88,11 @@ PACKAGE_INSTALL_ATTEMPTONLY ?=
> "${FEATURE_INSTALL_OPTIONAL}"
>
>  IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-image-complete"
>
> +IMGMANIFESTDIR = "${WORKDIR}/image-task-manifest"
> +
> +IMAGE_FILE_MANIFEST_DIR = "${WORKDIR}/deploy-image-file-manifest"
> +IMAGE_FILE_MANIFEST = "${IMAGE_FILE_MANIFEST_DIR}/manifest.json"
> +
>  # Images are generally built explicitly, do not need to be part of
> world.
>  EXCLUDE_FROM_WORLD = "1"
>
> @@ -277,14 +282,31 @@ fakeroot python do_image () {
>      execute_pre_post_process(d, pre_process_cmds)
>  }
>  do_image[dirs] = "${TOPDIR}"
> +do_image[cleandirs] = "${IMGMANIFESTDIR}"

Should this be an append (i.e. +=) to avoid conflicting with recipes ?

>  addtask do_image after do_rootfs
>
>  fakeroot python do_image_complete () {
>      from oe.utils import execute_pre_post_process
> +    from pathlib import Path
> +    import json
>
>      post_process_cmds = d.getVar("IMAGE_POSTPROCESS_COMMAND")
>
>      execute_pre_post_process(d, post_process_cmds)
> +
> +    image_manifest_dir = Path(d.getVar('IMGMANIFESTDIR'))
> +
> +    data = []
> +
> +    for taskname in bb.build.preceedtask("do_image_complete", False,
> d):
> +        manifest_path = image_manifest_dir / (taskname + ".json")
> +        if not manifest_path.exists():
> +            continue
> +        with manifest_path.open("r") as f:
> +            data.extend(json.load(f))
> +
> +    with open(d.getVar("IMAGE_FILE_MANIFEST"), "w") as f:
> +        json.dump(data, f)
>  }
>  do_image_complete[dirs] = "${TOPDIR}"
>  SSTATETASKS += "do_image_complete"
> @@ -292,6 +314,8 @@ SSTATE_SKIP_CREATION:task-image-complete = '1'
>  do_image_complete[sstate-inputdirs] = "${IMGDEPLOYDIR}"
>  do_image_complete[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
>  do_image_complete[stamp-extra-info] = "${MACHINE_ARCH}"
> +do_image_complete[sstate-plaindirs] =  "${IMAGE_FILE_MANIFEST_DIR}"
> +do_image_complete[dirs] = "${IMAGE_FILE_MANIFEST_DIR}"

Same here...

Thanks,
Martin

>  addtask do_image_complete after do_image before do_build
>  python do_image_complete_setscene () {
>      sstate_setscene(d)
> @@ -513,6 +537,8 @@ python () {
>          d.appendVarFlag(task, 'subimages', ' ' + '
> '.join(subimages))
>          d.appendVarFlag(task, 'vardeps', ' ' + ' '.join(vardeps))
>          d.appendVarFlag(task, 'vardepsexclude', ' DATETIME DATE ' +
> ' '.join(vardepsexclude))
> +        d.appendVarFlag(task, 'postfuncs', '
> write_image_file_manifest')
> +        d.appendVarFlag(task, 'dirs', ' ' +
> d.getVar('IMGMANIFESTDIR'))
>
>          bb.debug(2, "Adding task %s before %s, after %s" % (task,
> 'do_image_complete', after))
>          bb.build.addtask(task, 'do_image_complete', after, d)
> @@ -610,6 +636,41 @@ python create_symlinks() {
>              bb.note("Skipping symlink, source does not exist: %s ->
> %s" % (dst, src))
>  }
>
> +python write_image_file_manifest() {
> +    import json
> +    from pathlib import Path
> +
> +    taskname = d.getVar("BB_CURRENTTASK")
> +    image_deploy_dir = Path(d.getVar('IMGDEPLOYDIR'))
> +    image_manifest_dir = Path(d.getVar('IMGMANIFESTDIR'))
> +    manifest_path = image_manifest_dir / ("do_" +
> d.getVar("BB_CURRENTTASK") + ".json")
> +
> +    image_name = d.getVar("IMAGE_NAME")
> +    image_basename = d.getVar("IMAGE_BASENAME")
> +    machine = d.getVar("MACHINE")
> +
> +    subimages = (d.getVarFlag("do_" + taskname, 'subimages', False)
> or "").split()
> +    imagetype = d.getVarFlag("do_" + taskname, 'imagetype', False)
> +
> +    data = {
> +        "taskname": taskname,
> +        "imagetype": imagetype,
> +        "images": []
> +    }
> +
> +    for type in subimages:
> +        image_filename = image_name + "." + type
> +        image_path = image_deploy_dir / image_filename
> +        if not image_path.exists():
> +            continue
> +        data["images"].append({
> +            "filename": image_filename,
> +        })
> +
> +    with manifest_path.open("w") as f:
> +        json.dump([data], f)
> +}
> +
>  MULTILIBRE_ALLOW_REP += "${base_bindir} ${base_sbindir} ${bindir}
> ${sbindir} ${libexecdir} ${sysconfdir} ${nonarch_base_libdir}/udev
> /lib/modules/[^/]*/modules.*"
>  MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py"
>  MULTILIB_TEMP_ROOTFS = "${WORKDIR}/multilib"
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#200485):
> https://lists.openembedded.org/g/openembedded-core/message/200485
> Mute This Topic: https://lists.openembedded.org/mt/106602515/3618414
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe:
> https://lists.openembedded.org/g/openembedded-core/unsub [
> martin@geanix.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>