CloudAPI: add new /composes/{id}/sboms endpoint

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 <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2024-09-13 16:09:46 +02:00 committed by Tomáš Hozza
parent 102d06774c
commit 6e8f0418a6
3 changed files with 506 additions and 177 deletions

View file

@ -6,6 +6,8 @@ import (
"fmt"
"net/http"
"os"
"slices"
"sort"
"strconv"
"strings"
@ -16,6 +18,7 @@ import (
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/rpmmd"
"github.com/osbuild/images/pkg/sbom"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/target"
@ -888,6 +891,169 @@ func (h *apiHandlers) getComposeManifestsImpl(ctx echo.Context, id string) error
return ctx.JSON(http.StatusOK, resp)
}
// sbomsFromOSBuildJob extracts SBOM documents from dependencies of an OSBuild job.
func sbomsFromOSBuildJob(w *worker.Server, osbuildJobUUID uuid.UUID) ([]ImageSBOM, error) {
var osbuildJobResult worker.OSBuildJobResult
osbuildJobInfo, err := w.OSBuildJobInfo(osbuildJobUUID, &osbuildJobResult)
if err != nil {
return nil, fmt.Errorf("Failed to get results for OSBuild job %q: %v", osbuildJobUUID, err)
}
pipelineNameToPurpose := func(pipelineName string) (ImageSBOMPipelinePurpose, error) {
if slices.Contains(osbuildJobResult.PipelineNames.Payload, pipelineName) {
return ImageSBOMPipelinePurposeImage, nil
}
if slices.Contains(osbuildJobResult.PipelineNames.Build, pipelineName) {
return ImageSBOMPipelinePurposeBuildroot, nil
}
return "", fmt.Errorf("Pipeline %q is not listed as either a payload or build pipeline", pipelineName)
}
// SBOMs are attached to the depsolve job results.
// Depsolve jobs are dependencies of Manifest job.
// Manifest job is a dependency of OSBuild job.
manifesJobInfo, _, err := manifestJobResultsFromJobDeps(w, osbuildJobInfo.Deps)
if err != nil {
return nil, fmt.Errorf("Failed to get manifest job info for OSBuild job %q: %v", osbuildJobUUID, err)
}
var imageSBOMs []ImageSBOM
for _, manifestDepUUID := range manifesJobInfo.Deps {
depJobType, err := w.JobType(manifestDepUUID)
if err != nil {
return nil, fmt.Errorf("Failed to get job type for dependency %q: %v", manifestDepUUID, err)
}
if depJobType != worker.JobTypeDepsolve {
continue
}
var depsolveJobResult worker.DepsolveJobResult
_, err = w.DepsolveJobInfo(manifestDepUUID, &depsolveJobResult)
if err != nil {
return nil, fmt.Errorf("Failed to get results for depsolve job %q: %v", manifestDepUUID, err)
}
if depsolveJobResult.SbomDocs == nil {
return nil, fmt.Errorf("depsolve job %q: missing SBOMs", manifestDepUUID)
}
for pipelineName, sbomDoc := range depsolveJobResult.SbomDocs {
purpose, err := pipelineNameToPurpose(pipelineName)
if err != nil {
return nil, fmt.Errorf("Failed to determine purpose for pipeline %q: %v", pipelineName, err)
}
var sbomType ImageSBOMSbomType
switch sbomDoc.DocType {
case sbom.StandardTypeSpdx:
sbomType = ImageSBOMSbomTypeSpdx
default:
return nil, fmt.Errorf("Unknown SBOM type %q attached to depsolve job %q", sbomDoc.DocType, manifestDepUUID)
}
imageSBOMs = append(imageSBOMs, ImageSBOM{
PipelineName: pipelineName,
PipelinePurpose: purpose,
Sbom: sbomDoc.Document,
SbomType: sbomType,
})
}
// There should be only one depsolve job per OSBuild job
break
}
if len(imageSBOMs) == 0 {
return nil, fmt.Errorf("OSBuild job %q: manifest job dependency is missing depsolve job dependency", osbuildJobUUID)
}
// Sort the SBOMs by pipeline name to ensure consistent ordering.
// The SBOM documents are attached to the depsolve job results, in a map where the key is the pipeline name.
// The order of the keys in the map is not guaranteed to be consistent across different runs.
sort.Slice(imageSBOMs, func(i, j int) bool {
return imageSBOMs[i].PipelineName < imageSBOMs[j].PipelineName
})
return imageSBOMs, nil
}
// GetComposeSBOMs returns the SBOM documents for a given Compose (multiple SBOMs for each image).
func (h *apiHandlers) GetComposeSBOMs(ctx echo.Context, id string) error {
return h.server.EnsureJobChannel(h.getComposeSBOMsImpl)(ctx, id)
}
func (h *apiHandlers) getComposeSBOMsImpl(ctx echo.Context, id string) error {
jobId, err := uuid.Parse(id)
if err != nil {
return HTTPError(ErrorInvalidComposeId)
}
jobType, err := h.server.workers.JobType(jobId)
if err != nil {
return HTTPError(ErrorComposeNotFound)
}
var items [][]ImageSBOM
switch jobType {
// Koji compose
case worker.JobTypeKojiFinalize:
var finalizeResult worker.KojiFinalizeJobResult
finalizeInfo, err := h.server.workers.KojiFinalizeJobInfo(jobId, &finalizeResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
for _, kojiFinalizeDepUUID := range finalizeInfo.Deps {
buildJobType, err := h.server.workers.JobType(kojiFinalizeDepUUID)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
switch buildJobType {
case worker.JobTypeKojiInit:
continue
case worker.JobTypeOSBuild:
imageSBOMs, err := sbomsFromOSBuildJob(h.server.workers, kojiFinalizeDepUUID)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound,
fmt.Errorf("Failed to get SBOMs for OSBuild job %q: %v", kojiFinalizeDepUUID, err))
}
items = append(items, imageSBOMs)
default:
return HTTPErrorWithInternal(ErrorInvalidJobType,
fmt.Errorf("unexpected job type in koji compose dependencies: %q", buildJobType))
}
}
// non-Koji compose
case worker.JobTypeOSBuild:
imageSBOMs, err := sbomsFromOSBuildJob(h.server.workers, jobId)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound,
fmt.Errorf("Failed to get SBOMs for OSBuild job %q: %v", jobId, err))
}
items = append(items, imageSBOMs)
default:
return HTTPError(ErrorInvalidJobType)
}
resp := &ComposeSBOMs{
ObjectReference: ObjectReference{
Href: fmt.Sprintf("/api/image-builder-composer/v2/composes/%v/sboms", jobId),
Id: jobId.String(),
Kind: "ComposeSBOMs",
},
Items: items,
}
return ctx.JSON(http.StatusOK, resp)
}
// Converts repositories in the request to the internal rpmmd.RepoConfig representation
func convertRepos(irRepos, payloadRepositories []Repository, payloadPackageSets []string) ([]rpmmd.RepoConfig, error) {
repos := make([]rpmmd.RepoConfig, 0, len(irRepos)+len(payloadRepositories))

View file

@ -49,6 +49,18 @@ const (
CustomizationsPartitioningModeRaw CustomizationsPartitioningMode = "raw"
)
// Defines values for ImageSBOMPipelinePurpose.
const (
ImageSBOMPipelinePurposeBuildroot ImageSBOMPipelinePurpose = "buildroot"
ImageSBOMPipelinePurposeImage ImageSBOMPipelinePurpose = "image"
)
// Defines values for ImageSBOMSbomType.
const (
ImageSBOMSbomTypeSpdx ImageSBOMSbomType = "spdx"
)
// Defines values for ImageStatusValue.
const (
ImageStatusValueBuilding ImageStatusValue = "building"
@ -470,6 +482,15 @@ type ComposeRequest struct {
Koji *Koji `json:"koji,omitempty"`
}
// ComposeSBOMs defines model for ComposeSBOMs.
type ComposeSBOMs struct {
// Embedded struct due to allOf(#/components/schemas/ObjectReference)
ObjectReference `yaml:",inline"`
// Embedded fields due to inline allOf schema
// The SBOM documents for each image built in the compose.
Items [][]ImageSBOM `json:"items"`
}
// ComposeStatus defines model for ComposeStatus.
type ComposeStatus struct {
// Embedded struct due to allOf(#/components/schemas/ObjectReference)
@ -811,6 +832,36 @@ type ImageRequest struct {
UploadTargets *[]UploadTarget `json:"upload_targets,omitempty"`
}
// ImageSBOM defines model for ImageSBOM.
type ImageSBOM struct {
// The name of the osbuild pipeline which has the packages described
// in the SBOM installed.
PipelineName string `json:"pipeline_name"`
// The purpose of the pipeline. The `buildroot` pipeline was used for
// the build environment dueing the image build. The `image` pipeline
// represents the actual content of the image. Due to the nature of
// some image types, there may be multiple pipelines of the same
// purpose.
PipelinePurpose ImageSBOMPipelinePurpose `json:"pipeline_purpose"`
// The SBOM document in the 'sbom_type' format.
Sbom interface{} `json:"sbom"`
// The type of the SBOM document. Currently only SPDX is supported.
SbomType ImageSBOMSbomType `json:"sbom_type"`
}
// The purpose of the pipeline. The `buildroot` pipeline was used for
// the build environment dueing the image build. The `image` pipeline
// represents the actual content of the image. Due to the nature of
// some image types, there may be multiple pipelines of the same
// purpose.
type ImageSBOMPipelinePurpose string
// The type of the SBOM document. Currently only SPDX is supported.
type ImageSBOMSbomType string
// ImageStatus defines model for ImageStatus.
type ImageStatus struct {
Error *ComposeStatusError `json:"error,omitempty"`
@ -1194,6 +1245,9 @@ type ServerInterface interface {
// Get the metadata for a compose.
// (GET /composes/{id}/metadata)
GetComposeMetadata(ctx echo.Context, id string) error
// Get the SBOMs for a compose.
// (GET /composes/{id}/sboms)
GetComposeSBOMs(ctx echo.Context, id string) error
// Get a list of all possible errors
// (GET /errors)
GetErrorList(ctx echo.Context, params GetErrorListParams) error
@ -1323,6 +1377,22 @@ func (w *ServerInterfaceWrapper) GetComposeMetadata(ctx echo.Context) error {
return err
}
// GetComposeSBOMs converts echo context to params.
func (w *ServerInterfaceWrapper) GetComposeSBOMs(ctx echo.Context) error {
var err error
// ------------- Path parameter "id" -------------
var id string
err = runtime.BindStyledParameterWithLocation("simple", false, "id", runtime.ParamLocationPath, ctx.Param("id"), &id)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err))
}
// Invoke the callback with all the unmarshalled arguments
err = w.Handler.GetComposeSBOMs(ctx, id)
return err
}
// GetErrorList converts echo context to params.
func (w *ServerInterfaceWrapper) GetErrorList(ctx echo.Context) error {
var err error
@ -1414,6 +1484,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
router.GET(baseURL+"/composes/:id/logs", wrapper.GetComposeLogs)
router.GET(baseURL+"/composes/:id/manifests", wrapper.GetComposeManifests)
router.GET(baseURL+"/composes/:id/metadata", wrapper.GetComposeMetadata)
router.GET(baseURL+"/composes/:id/sboms", wrapper.GetComposeSBOMs)
router.GET(baseURL+"/errors", wrapper.GetErrorList)
router.GET(baseURL+"/errors/:id", wrapper.GetError)
router.GET(baseURL+"/openapi", wrapper.GetOpenapi)
@ -1423,183 +1494,189 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
"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",
"IoqHWQfn89f/HwAA//80eIXXl8EAAA==",
"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",
"qo1G0xneTHt/vnxsFHb2H33HnbQbT48ng5fJ2aBLCp/72+/X/ftR76RcPHytDFs7V0f7l0Vy/uXz/l3J",
"C0btz6+doF15OGf7Fa9yHLjCP7s9PD07F17t8KBLSuz4/UuDdkoTf/exVT9vHNgXzebV5KXxwunDXX3n",
"8S5ofi70yAvroNvy+e1Vsz+5bu5sP+zWa/jqvku8Wvtzj98cjHea5XPm2o2L6sVBQCdPpTYWx/CpenZz",
"fi8+dw5hqYr5Y/u4+fJOd64f6/eV06thrdglzuuDUy9fFnpe+fC9vdOpVx4OD3old/RSbbmjN6f1eoac",
"Uun9y+Obxx7bT6enzf7ovf/ZvWxvB2/OSZe8vBVOixP3qXyOe8ds+7jRmFzt3j2wxlN73L4oHlovnfr4",
"sEnehu2DYPLqPYzvR5f7X4LD1n39ClUeu+QC35X6p5d1bu8c+PzorXbx+YtNLshN+/MJe+lcnx1UvAfm",
"Nmxy2BnYj/f1l6eh/zA4mPBKYXcXXXXJYFhk52RSfLkcD2HQL+C7+pW1/WV0MXw5v704dWp3u/dnk9Pg",
"4UG8j7+Ql4vL2sPt0f7rWZU/Ue/iokv6otc5KX2uTXq3D4VGZbTfg2+3D2Wxc/d++WK9o2H76RDD88vd",
"88KJddps3ZZujurb9fKB3XAPj3btLhmWnRv82L5pQHhaPD1tvJ+Mboe3p+fnzln58eYRn1zeT8qicjo5",
"6nMGvdq43Xy46g+uUWtyvt95Ou2SEfMv3ese6vPObm2n0y/vX7YC5/2JNWv3bwfts+GTczso3R+P2q0b",
"0py8D28m24d35ddrHz/UdqWMGly3vjyxM2qdVc7O27sF/H5607l1xctF47cu+e2639npEnW6HF4eLDt6",
"FpS7ogw9c+6mH9I/qx6ufvRnqTv4ox4Bilf/SfW6yPFCx4YuEaSc6jGtCHKp0HCgTK5YRomqPNQlv4aR",
"TJ9SqxDN5RSEZWbphpW2PtaPnnSVgwWe8jVLE5hHQzezq1NVyYZtRxd1oc/VPO8DAzGgDL8jW9kz8/nt",
"a73W02g/YDG8Oqne1XeqhzbfvyMT0av0xqNbxzlxb9ze4xd3h5SKo90FdW5T0+Tv9BtHkfmj86TM46uS",
"pJKOIdvDZHXEN1dBBRJPadbx2pnLH5CBDHqT2Fs6KdVxw2KIdrokIi3dpfQhqckroSF9FbTFNwbGg3y4",
"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",
}
// GetSwagger returns the content of the embedded swagger specification file

View file

@ -215,6 +215,42 @@ paths:
schema:
type: string
'/composes/{id}/sboms':
get:
operationId: getComposeSBOMs
summary: Get the SBOMs for a compose.
parameters:
- in: path
name: id
schema:
type: string
format: uuid
example: 123e4567-e89b-12d3-a456-426655440000
required: true
description: ID of compose for which to get SBOMs
description: |-
Returns a set of SBOM documents for each image in the request.
SBOM documents are in the SPDX format.
responses:
'200':
description: The SBOMs for the given compose.
content:
application/json:
schema:
$ref: '#/components/schemas/ComposeSBOMs'
'400':
description: Invalid compose id
content:
text/plain:
schema:
type: string
'404':
description: Unknown compose id
content:
text/plain:
schema:
type: string
/composes/{id}/clone:
post:
operationId: postCloneCompose
@ -571,6 +607,56 @@ components:
items:
type: object
x-go-type: interface{}
ImageSBOM:
required:
- sbom
- sbom_type
- pipeline_name
- pipeline_purpose
properties:
sbom:
type: object
x-go-type: interface{}
description: |-
The SBOM document in the 'sbom_type' format.
sbom_type:
type: string
enum: ["spdx"]
description: |-
The type of the SBOM document. Currently only SPDX is supported.
pipeline_name:
type: string
description: |-
The name of the osbuild pipeline which has the packages described
in the SBOM installed.
pipeline_purpose:
type: string
enum: ["buildroot", "image"]
description: |-
The purpose of the pipeline. The `buildroot` pipeline was used for
the build environment dueing the image build. The `image` pipeline
represents the actual content of the image. Due to the nature of
some image types, there may be multiple pipelines of the same
purpose.
ComposeSBOMs:
allOf:
- $ref: '#/components/schemas/ObjectReference'
- type: object
required:
- items
properties:
items:
type: array
description: |-
The SBOM documents for each image built in the compose.
items:
type: array
description: |-
The SBOM documents for the given image. Each image usually has
at least two SBOMs, one for the build environment and one for the
actual content of the image.
items:
$ref: '#/components/schemas/ImageSBOM'
ImageStatus:
required:
- status