diff mbox series

[3/3] utils/generate-cyclonedx: include external tree in package properties

Message ID 20250505160327.3422096-4-fiona.klute@gmx.de
State New
Headers show
Series Add external tree information to CycloneDX SBOM | expand

Commit Message

Fiona Klute May 5, 2025, 4:03 p.m. UTC
From: "Fiona Klute (WIWA)" <fiona.klute@gmx.de>

For packages from external trees, the bom-ref of the external tree is
listed in the BR_EXTERNAL_TREE property. The external tree is
identified based on its path and the new "package_dir" property in
show-info output. If the package directory is not part of the main
Buildroot repository or a known external tree, an exception is raised.

Signed-off-by: Fiona Klute (WIWA) <fiona.klute@gmx.de>
---
 utils/generate-cyclonedx | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

Comments

Titouan Christophe May 16, 2025, 4:51 p.m. UTC | #1
Hello,

On 5/05/25 18:03, Fiona Klute via buildroot wrote:
> From: "Fiona Klute (WIWA)" <fiona.klute@gmx.de>
>
> For packages from external trees, the bom-ref of the external tree is
> listed in the BR_EXTERNAL_TREE property. The external tree is
> identified based on its path and the new "package_dir" property in
> show-info output. If the package directory is not part of the main
> Buildroot repository or a known external tree, an exception is raised.
>
> Signed-off-by: Fiona Klute (WIWA) <fiona.klute@gmx.de>
Tested-by: Titouan Christophe <titouan.christophe@mind.be>
> ---
>   utils/generate-cyclonedx | 31 +++++++++++++++++++++++++------
>   1 file changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/utils/generate-cyclonedx b/utils/generate-cyclonedx
> index cbb7ef630e..7d7adb2ce4 100755
> --- a/utils/generate-cyclonedx
> +++ b/utils/generate-cyclonedx
> @@ -206,16 +206,32 @@ def cyclonedx_patches(patch_list):
>       }
>   
>   
> -def cyclonedx_component(name, comp):
> +def cyclonedx_component(name, comp, ext_trees: list[ExternalTree]):
>       """Translate a component from the show-info output, to a component entry in CycloneDX format.
>   
>       Args:
>           name (str): Key used for the package in the show-info output.
>           comp (dict): Data about the package as a Python dictionary.
> +        ext_trees (list): External trees that were used in the build.
>   
>       Returns:
>           dict: Component information in CycloneDX format.
>       """
> +    pkg_dir = Path(comp["package_dir"])
> +    ext_tree_info = None
> +    if pkg_dir.is_absolute():
> +        # the package is from an external tree, find it
> +        for ext in ext_trees:
> +            if pkg_dir.is_relative_to(ext.path):
> +                ext_tree_info = {
> +                    "name": "BR_EXTERNAL_TREE",
> +                    "value": ext.bom_ref,
> +                }
> +                break
> +        if ext_tree_info is None:
> +            raise Exception(
> +                f'package "{name}" is from an unknown external tree at {pkg_dir!s}, use "-e" to provide external tree data')
> +
>       return {
>           "bom-ref": name,
>           "type": "library",
> @@ -230,10 +246,13 @@ def cyclonedx_component(name, comp):
>               "cpe": comp["cpe-id"],
>           } if "cpe-id" in comp else {}),
>           **(cyclonedx_patches(comp["patches"]) if comp.get("patches") else {}),
> -        "properties": [{
> -            "name": "BR_TYPE",
> -            "value": comp["type"],
> -        }],
> +        "properties": [
> +            {
> +                "name": "BR_TYPE",
> +                "value": comp["type"],
> +            },
> +            *((ext_tree_info,) if ext_tree_info else ()),
> +        ],
>       }
>   
>   
> @@ -351,7 +370,7 @@ def main():
>           "$schema": f"http://cyclonedx.org/schema/bom-{CYCLONEDX_VERSION}.schema.json",
>           "specVersion": f"{CYCLONEDX_VERSION}",
>           "components": [
> -            cyclonedx_component(name, comp) for name, comp in filtered_show_info_dict.items()
> +            cyclonedx_component(name, comp, external_trees) for name, comp in filtered_show_info_dict.items()
>           ],
>           "dependencies": [
>               cyclonedx_dependency("buildroot", list(filtered_show_info_dict)),
diff mbox series

Patch

diff --git a/utils/generate-cyclonedx b/utils/generate-cyclonedx
index cbb7ef630e..7d7adb2ce4 100755
--- a/utils/generate-cyclonedx
+++ b/utils/generate-cyclonedx
@@ -206,16 +206,32 @@  def cyclonedx_patches(patch_list):
     }
 
 
-def cyclonedx_component(name, comp):
+def cyclonedx_component(name, comp, ext_trees: list[ExternalTree]):
     """Translate a component from the show-info output, to a component entry in CycloneDX format.
 
     Args:
         name (str): Key used for the package in the show-info output.
         comp (dict): Data about the package as a Python dictionary.
+        ext_trees (list): External trees that were used in the build.
 
     Returns:
         dict: Component information in CycloneDX format.
     """
+    pkg_dir = Path(comp["package_dir"])
+    ext_tree_info = None
+    if pkg_dir.is_absolute():
+        # the package is from an external tree, find it
+        for ext in ext_trees:
+            if pkg_dir.is_relative_to(ext.path):
+                ext_tree_info = {
+                    "name": "BR_EXTERNAL_TREE",
+                    "value": ext.bom_ref,
+                }
+                break
+        if ext_tree_info is None:
+            raise Exception(
+                f'package "{name}" is from an unknown external tree at {pkg_dir!s}, use "-e" to provide external tree data')
+
     return {
         "bom-ref": name,
         "type": "library",
@@ -230,10 +246,13 @@  def cyclonedx_component(name, comp):
             "cpe": comp["cpe-id"],
         } if "cpe-id" in comp else {}),
         **(cyclonedx_patches(comp["patches"]) if comp.get("patches") else {}),
-        "properties": [{
-            "name": "BR_TYPE",
-            "value": comp["type"],
-        }],
+        "properties": [
+            {
+                "name": "BR_TYPE",
+                "value": comp["type"],
+            },
+            *((ext_tree_info,) if ext_tree_info else ()),
+        ],
     }
 
 
@@ -351,7 +370,7 @@  def main():
         "$schema": f"http://cyclonedx.org/schema/bom-{CYCLONEDX_VERSION}.schema.json",
         "specVersion": f"{CYCLONEDX_VERSION}",
         "components": [
-            cyclonedx_component(name, comp) for name, comp in filtered_show_info_dict.items()
+            cyclonedx_component(name, comp, external_trees) for name, comp in filtered_show_info_dict.items()
         ],
         "dependencies": [
             cyclonedx_dependency("buildroot", list(filtered_show_info_dict)),