Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for generating SPDX SBOM documents (COMPOSER-2274) #4359

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

thozza
Copy link
Member

@thozza thozza commented Sep 11, 2024

Depends on:

  • Add initial support for generating SPDX SBOM documents (COMPOSER-2274) osbuild#1818

  • Add initial support for generating SPDX SBOM documents (COMPOSER-2274) images#930

  • Extend the worker Depsolve job to allow requesting an SBOM document for each transaction. The SBOM documents are returned in the DepsolveJobResult.

  • CloudAPI:

    • Unconditionally request SBOM documents for every Depsolve job.
    • Add new /composes/{id}/sboms API endpoint for requesting SBOM documents for composes.
    • Extend the non-Koji and Koji compose unit tests to verify the newly added /composes/{id}/sboms API endpoint.
  • There's no support for SBOMs added to Weldr API.

  • Koji:

    • Extend the Koji target result to include SBOM documents uploaded to the Koji build.
    • Extend the KojiFinalize job to import all SBOM documents uploaded to the Koji build and listed in the Koji target result.
    • Extend the Koji target handling in the OSBuild job, to upload all SBOM documents, related to the OSBuild job, to the Koji build and list them in the Koji target result. Uploaded SBOM documents use the following filenames: <image_filename>.<pipeline_purpose>-<pipeline_name>.spdx.json.
    • Extend the koji.sh test case to verify the uploaded SBOM documents in Koji builds.
    • Update the tested scenarios for koji.sh. Specifically, test the main scenario on RHEL-9 and in addition, test building of RHEL-8 and RHEL-10 on RHEL-9.

Details

SBOM documents are attached to DepsolveJobResult. For each package set that was depsolved, there will be a corresponding SBOM document. DepsolveJob usually contains at least two package sets for any image type - for the at least one image pipeline and for the buildroot pipeline.

Koji composes may contain multiple image builds as part of a single compose request. Therefore the /composes/{id}/sboms endpoint returns multiple SBOM documents for each image build. The returned value may look as follows for a Koji compose that consists of two image builds:

{
	"href": "/api/image-builder-composer/v2/composes/356f4620-c03e-3830-b013-ddbfee6665aa/sboms",
	"id": "356f4620-c03e-3830-b013-ddbfee6665aa",
	"kind": "ComposeSBOMs",
	"items": [
		[
			{
				"pipeline_name": "build",
				"pipeline_purpose": "buildroot",
				"sbom": <sbom_doc>,
				"sbom_type": "spdx"
			},
			{
				"pipeline_name": "os",
				"pipeline_purpose": "image",
				"sbom": <sbom_doc>,
				"sbom_type": "spdx"
			}
		],
		[
			{
				"pipeline_name": "build",
				"pipeline_purpose": "buildroot",
				"sbom": <sbom_doc>,
				"sbom_type": "spdx"
			},
			{
				"pipeline_name": "os",
				"pipeline_purpose": "image",
				"sbom": <sbom_doc>,
				"sbom_type": "spdx"
			}
		]
	]
}

pipeline_purpose describes the purpose of a pipeline. image means that the content described in the SBOM document is installed in the actual image. buildroot means that the content described in the SBOM document was installed in the environment used to build the image. This terminology is consistent with how we name thing internally.

pipeline_name is the actual name of the osbuild pipeline, in which the described content got installed.

sbom is the actual SBOM document.

sbom_type describes the SBOM standard / type of the SBOM document. Currently, it will be always spdx.

@thozza thozza added the WIP+test Work in progress but run Gitlab CI. label Sep 11, 2024
@thozza thozza marked this pull request as draft September 11, 2024 08:55
@thozza thozza force-pushed the sbom-poc branch 3 times, most recently from f5da6bb to 4d44504 Compare September 11, 2024 14:19
@thozza thozza changed the title [WIP] Add initial support for generating SPDX SBOM documents (COMPOSER-2274) Add initial support for generating SPDX SBOM documents (COMPOSER-2274) Sep 13, 2024
@thozza thozza force-pushed the sbom-poc branch 6 times, most recently from d7945ea to 16a0b40 Compare September 18, 2024 08:27
Update the ref to the v129, which supports SBOM documents.

Signed-off-by: Tomáš Hozza <[email protected]>
This is needed to be able to install osbuild RPM builds, because that
repo uses newer snapshots.

Signed-off-by: Tomáš Hozza <[email protected]>
@thozza thozza marked this pull request as ready for review September 19, 2024 13:00
@thozza thozza removed the WIP+test Work in progress but run Gitlab CI. label Sep 19, 2024
Adjust all paces that call `Solver.Depsolve()`, to cope with the changes
that enabled SBOM support.

Fix loading of testing repositories in the CloudAPI unit tests.

Signed-off-by: Tomáš Hozza <[email protected]>
This is needed for the SBOM support

Signed-off-by: Tomáš Hozza <[email protected]>
Add support to the `DepsolveJob` for requesting SBOM documents and
returning the results from the job.

Signed-off-by: Tomáš Hozza <[email protected]>
For Koji composes, all files are uploaded to Koji as part of the osbuild
job (specifically as part of handling the Koji target). So in order to
be able to upload SBOM documents to Koji as part of Koji compose, the
osbuild job needs to to be able to access the depsolve job result, which
contains the SBOM documents. For this, the osbuild job must depend on
the depsolve job.

For Koji composes, make sure that osbuild job depends on the depsolve
job and set the DepsolveDynArgsIdx.

Signed-off-by: Tomáš Hozza <[email protected]>
Extend the Koji target result struct with an optional slice for uploaded
SBOM documents.

Signed-off-by: Tomáš Hozza <[email protected]>
If the Koji target result contains information about any uploaded SBOM
documents, import them to Koji as part of the finalize task.

Signed-off-by: Tomáš Hozza <[email protected]>
Extend the Koji target handling in the osbuild job, to also upload SBOM
documents attached to the related depsolve job result.

Signed-off-by: Tomáš Hozza <[email protected]>
Adjust the test case to cope with the SPDX SBOM documents uploaded to
the Koji. Also explicitly check that there is the expected number of
SBOM documents uploaded as the image build output.

Signed-off-by: Tomáš Hozza <[email protected]>
We have been testing builds of RHEL-9 on RHEL-8 for the Koji use case.
However, all of our workers are now running the latest GA RHEL-9
version. Therefore we should flip the test and test building of RHEL-8
on RHEL-9.

Signed-off-by: Tomáš Hozza <[email protected]>
This is what is currently happening on our Brew workers.

Signed-off-by: Tomáš Hozza <[email protected]>
None of our worker is running RHEL-8 any more. There's no value in
testing the Koji scenario on RHEL-8, RHEL-9 is fully sufficient.

Signed-off-by: Tomáš Hozza <[email protected]>
Extend the `manifestJobResultsFromJobDeps()` function to also return the
manifest `JobInfo`. This will be useful to inspect the job dependencies
and eliminate the need to add a specialized function for getting only
the `JobInfo`.

Signed-off-by: Tomáš Hozza <[email protected]>
Add a new /sboms API endpoint, for getting SBOM documents for a given
compose ID. The endpoint returns an array of SBOM documents for each
image built as part of the compose. For each image, there is an SBOM
document for each osbuild pipeline, which installs RPM packages. This is
usually one 'buildroot' and one 'image' pipeline.

Signed-off-by: Tomáš Hozza <[email protected]>
 Extend the unit test for regular (non-Koji) composes, to verify that
 the newly added /sboms endpoint works correctly.

Signed-off-by: Tomáš Hozza <[email protected]>
Extend the API unit test for Koji composes, to verify that the newly
added /sboms endpoint works correctly.

Signed-off-by: Tomáš Hozza <[email protected]>
This is needed for GPG key import to work on RHEL-9, because the key
uses SHA-1. This results in the following error when importing the key
during the build of the build container:

"Signature not supported. Hash algorithm SHA1 not available."

We do not need the AUX key in our RHEL-8 repo definitions used for
testing.

Signed-off-by: Tomáš Hozza <[email protected]>
Copy link
Member

@achilleas-k achilleas-k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work. This is a lot.

Couple of notes and nitpicks. I think there's a bug in the sbomsFromOSBuildJob() function (noted below) but I'm not entirely sure if I'm reading it right so not Requesting changes.

return nil, fmt.Errorf("Failed to get job type for dependency %q: %v", manifestDepUUID, err)
}

if depJobType == worker.JobTypeDepsolve {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NITPICK: Flipping the condition with continue would decrease the indentation for the largest part of the loop body, which is nicer IMO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't see any problem with it.

}

// There should be only one depsolve job per OSBuild job
break
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this break be inside the depJobType == worker.JobTypeDepsolve block? The way it is now, only one the first manifestJobInfo.Deps element is considered. Is that always a depsolve job and nothing else? I guess no, otherwise we'd just be using manifestJobInfo.Deps[0] right?

Copy link
Member Author

@thozza thozza Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this break be inside the depJobType == worker.JobTypeDepsolve block?

It actually is inside block as far as I can tell 🤔

So the break is at the correct place, but this is a bit of a premature optimization based on the current implementation. Let me explain.

I implemented sbomsFromOSBuildJob() in a way, so that it uses the same approach to get SBOMs from OSBuildJob, regardless if it is from a Koji or non-Koji compose.

Just for the completeness, for Koji composes, the DepsolveJob is a dependency of the OSBuildJob, so that it can access SBOMs and upload them to Koji. For non-Koji composes, the DepsolveJob is not a direct dependency of the OSBuildJob and one must go through the ManifestJob as to get to DepsolveJob.

There's always only a single DepsolveJob in the compose job chain, thus the break. But there may be more than one item in manifestJobInfo.Deps and DepsolveJob does not have a fixed index.

required: true
description: ID of compose SBOMs to get
description: |-
Get the manifests of a running or finished compose.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy-paste leftover?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes.

format: uuid
example: 123e4567-e89b-12d3-a456-426655440000
required: true
description: ID of compose SBOMs to get
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NITPICK: This is a bit awkwardly phrased and might be misunderstood as "ID of SBOMs". In other words, it kinda sounds like "compose-SBOM" is the object being fetched, so it wants the ID of that, but instead it's the compose ID it needs.

Maybe something like:

ID of compose for which to get SBOMs

though I'm not too happy about that one either.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this is not great by any means 😄 I'll happily use your suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants