From 34d5faa68fef7161dad1c5e9a247dffab8ac80ce Mon Sep 17 00:00:00 2001 From: Sergii Shapar Date: Thu, 16 Mar 2023 14:09:19 -0400 Subject: [PATCH 1/4] Run SBOM for 'context' mode Change-Id: Idf989734e10c4329d703fb9295c18efe39043ae3 --- pkg/build/build.go | 4 +-- pkg/build/sbom.go | 79 +++++++++++++++++++++++++++++----------------- pkg/manifest.go | 1 + pkg/model/model.go | 14 +++++--- 4 files changed, 61 insertions(+), 37 deletions(-) diff --git a/pkg/build/build.go b/pkg/build/build.go index da551409..6b5d5051 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -88,9 +88,7 @@ func Build(manifest model.Manifest) error { return fmt.Errorf("failed to package license file: %v", err) } - if manifest.DockerOutput == model.DockerOutputContext { - log.Warnf("Docker output in 'context' mode; will not produce SBOM.") - } else if manifest.SkipGenerateBillOfMaterials { + if manifest.SkipGenerateBillOfMaterials { log.Warnf("Input manifest set SkipGenerateBillOfMaterials; will not produce SBOM.") } else { if err := GenerateBillOfMaterials(manifest); err != nil { diff --git a/pkg/build/sbom.go b/pkg/build/sbom.go index 1360017b..b622201c 100644 --- a/pkg/build/sbom.go +++ b/pkg/build/sbom.go @@ -26,42 +26,40 @@ import ( "istio.io/release-builder/pkg/util" ) -// Sbom generates Software Bill Of Materials for istio repo in an SPDX readable format. +const ( + sourceSpdx string = "istio-source.spdx" + releaseSpdx string = "istio-release.spdx" + sbomOutputURI string = "https://storage.googleapis.com/istio-release/releases" +) + +// GenerateBillOfMaterials generates Software Bill Of Materials for istio repo in an SPDX readable format. func GenerateBillOfMaterials(manifest model.Manifest) error { // Retrieve istio repository path to run the sbom generator istioRepoDir := manifest.RepoDir("istio") - sourceSbomFile := path.Join(manifest.OutDir(), "istio-source.spdx") - sourceSbomNamespace := fmt.Sprintf("https://storage.googleapis.com/istio-release/releases/%s/istio-source.spdx", - manifest.Version) - releaseSbomFile := path.Join(manifest.OutDir(), "istio-release.spdx") - releaseSbomNamespace := fmt.Sprintf("https://storage.googleapis.com/istio-release/releases/%s/istio-release.spdx", - manifest.Version) - - // construct all the docker image tarball names as bom currently cannot accept directory as input - dockerDir := path.Join(manifest.OutDir(), "docker") - dockerImages := []string{} - if err := filepath.Walk(dockerDir, func(path string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - if fi == nil { - return fmt.Errorf("failed to get fileinfo for file at path %s", path) - } - if fi.IsDir() { - return nil - } - dockerImages = append(dockerImages, path) - return nil - }); err != nil { - return fmt.Errorf("failed to walk directory %s: %v", dockerDir, err) + nameSpaceURI := sbomOutputURI + if manifest.BillOfMaterialsURI != "" { + nameSpaceURI = manifest.BillOfMaterialsURI } + sourceSbomFile := path.Join(manifest.OutDir(), sourceSpdx) + sourceSbomNamespace := path.Join(nameSpaceURI, manifest.Version, sourceSpdx) + + releaseSbomFile := path.Join(manifest.OutDir(), releaseSpdx) + releaseSbomNamespace := path.Join(nameSpaceURI, manifest.Version, releaseSpdx) // Run bom generator to generate the software bill of materials(SBOM) for istio. log.Infof("Generating Software Bill of Materials for istio release artifacts") - if err := util.VerboseCommand("bom", "--log-level", "error", "generate", "--name", "Istio Release "+manifest.Version, - "--namespace", releaseSbomNamespace, "--ignore", "licenses,'*.sha256',docker", "--dirs", manifest.OutDir(), - "--image-archive", strings.Join(dockerImages, ","), "--output", releaseSbomFile).Run(); err != nil { - return fmt.Errorf("couldn't generate sbom for istio release artifacts: %v", err) + // For Docker output in 'context' mode we will not produce SBOM. + // `bom` can produce bill only for tar and remote images. + if manifest.DockerOutput == model.DockerOutputTar { + dockerDir := path.Join(manifest.OutDir(), "docker") + // construct all the docker image tarball names as bom currently cannot accept directory as input + dockerImages := DockerTarPaths(dockerDir) + if err := util.VerboseCommand("bom", "--log-level", "error", + "generate", "--name", "Istio Release "+manifest.Version, + "--namespace", releaseSbomNamespace, "--ignore", "licenses,'*.sha256',docker", "--dirs", manifest.OutDir(), + "--image-archive", strings.Join(dockerImages, ","), "--output", releaseSbomFile).Run(); err != nil { + return fmt.Errorf("couldn't generate sbom for istio release artifacts: %v", err) + } } // Run bom generator to generate the software bill of materials(SBOM) for istio. @@ -72,3 +70,26 @@ func GenerateBillOfMaterials(manifest model.Manifest) error { } return nil } + +// DockerTarPaths construct all the docker image tarball names as bom currently +// cannot accept directory as input +func DockerTarPaths(dockerDir string) []string { + var dockerImages []string + err := filepath.Walk(dockerDir, func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + if fi == nil { + return fmt.Errorf("failed to get fileinfo for file at path %s", path) + } + if fi.IsDir() { + return nil + } + dockerImages = append(dockerImages, path) + return nil + }) + if err != nil { + return nil + } + return dockerImages +} \ No newline at end of file diff --git a/pkg/manifest.go b/pkg/manifest.go index 1dbd296e..437d9348 100644 --- a/pkg/manifest.go +++ b/pkg/manifest.go @@ -81,6 +81,7 @@ func InputManifestToManifest(in model.InputManifest) (model.Manifest, error) { ProxyOverride: in.ProxyOverride, GrafanaDashboards: in.GrafanaDashboards, SkipGenerateBillOfMaterials: in.SkipGenerateBillOfMaterials, + BillOfMaterialsURI: in.BillOfMaterialsURI, Architectures: arch, }, nil } diff --git a/pkg/model/model.go b/pkg/model/model.go index 0d6bce1a..8937c900 100644 --- a/pkg/model/model.go +++ b/pkg/model/model.go @@ -127,7 +127,7 @@ const ( DockerOutputContext DockerOutput = "context" ) -// Manifest defines what is in a release +// InputManifest defines what is in a release type InputManifest struct { // Dependencies declares all git repositories used to build this release Dependencies IstioDependencies `json:"dependencies"` @@ -151,9 +151,11 @@ type InputManifest struct { BuildOutputs []string `json:"outputs"` // GrafanaDashboards defines a mapping of dashboard name -> ID of the dashboard on grafana.com GrafanaDashboards map[string]int `json:"dashboards"` - // BillOfMaterials flag determines if a Bill of Materials should be produced - // by the build. + // SkipGenerateBillOfMaterials flag determines if a Bill of Materials should + // be produced by the build. SkipGenerateBillOfMaterials bool `json:"skipGenerateBillOfMaterials"` + // BillOfMaterialsURI flag sets URI for bill of materials. + BillOfMaterialsURI string `json:"billOfMaterialsURI"` } // Manifest defines what is in a release @@ -181,9 +183,11 @@ type Manifest struct { // GrafanaDashboards defines a mapping of dashboard name -> ID of the dashboard on grafana.com // Note: this tool is not yet smart enough to create dashboards that do not already exist, it can only update dashboards. GrafanaDashboards map[string]int `json:"dashboards"` - // BillOfMaterials flag determines if a Bill of Materials should be produced - // by the build. + // SkipGenerateBillOfMaterials flag determines if a Bill of Materials should + // be produced by the build. SkipGenerateBillOfMaterials bool `json:"skipGenerateBillOfMaterials"` + // BillOfMaterialsURI flag sets URI for bill of materials. + BillOfMaterialsURI string `json:"billOfMaterialsURI"` } // RepoDir is a helper to return the working directory for a repo From c4467a354d4987fcccb8c00d16002f9c9582c8f4 Mon Sep 17 00:00:00 2001 From: Sergii Shapar Date: Thu, 16 Mar 2023 16:13:10 -0400 Subject: [PATCH 2/4] fix lint Change-Id: If2c6a41b38c6b387f48be7b500770f05e61057e6 --- pkg/build/sbom.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/build/sbom.go b/pkg/build/sbom.go index b622201c..6f36acad 100644 --- a/pkg/build/sbom.go +++ b/pkg/build/sbom.go @@ -92,4 +92,4 @@ func DockerTarPaths(dockerDir string) []string { return nil } return dockerImages -} \ No newline at end of file +} From ea2981124a6b2f34eacaea420455b6e5096bcee8 Mon Sep 17 00:00:00 2001 From: Sergii Shapar Date: Thu, 16 Mar 2023 16:58:45 -0400 Subject: [PATCH 3/4] Add version prefix Change-Id: I2e22fb501ff2e44fdc1fcfb561b509f292613a37 --- pkg/build/sbom.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pkg/build/sbom.go b/pkg/build/sbom.go index 6f36acad..6f2e234c 100644 --- a/pkg/build/sbom.go +++ b/pkg/build/sbom.go @@ -27,8 +27,6 @@ import ( ) const ( - sourceSpdx string = "istio-source.spdx" - releaseSpdx string = "istio-release.spdx" sbomOutputURI string = "https://storage.googleapis.com/istio-release/releases" ) @@ -40,11 +38,11 @@ func GenerateBillOfMaterials(manifest model.Manifest) error { if manifest.BillOfMaterialsURI != "" { nameSpaceURI = manifest.BillOfMaterialsURI } - sourceSbomFile := path.Join(manifest.OutDir(), sourceSpdx) - sourceSbomNamespace := path.Join(nameSpaceURI, manifest.Version, sourceSpdx) + sourceSbomFile := path.Join(manifest.OutDir(), fmt.Sprintf("istio-source-%s.spdx", manifest.Version)) + sourceSbomNamespace := path.Join(nameSpaceURI, manifest.Version, fmt.Sprintf("istio-source-%s.spdx", manifest.Version)) - releaseSbomFile := path.Join(manifest.OutDir(), releaseSpdx) - releaseSbomNamespace := path.Join(nameSpaceURI, manifest.Version, releaseSpdx) + releaseSbomFile := path.Join(manifest.OutDir(), fmt.Sprintf("istio-source-%s.spdx", manifest.Version)) + releaseSbomNamespace := path.Join(nameSpaceURI, manifest.Version, fmt.Sprintf("istio-source-%s.spdx", manifest.Version)) // Run bom generator to generate the software bill of materials(SBOM) for istio. log.Infof("Generating Software Bill of Materials for istio release artifacts") From d9d505f46a3607241fd0b581838f78b9d6070f55 Mon Sep 17 00:00:00 2001 From: Sergii Shapar Date: Fri, 24 Mar 2023 15:46:34 -0400 Subject: [PATCH 4/4] Add sbom uri to build.sh Change-Id: I2d3b13b82e23dd80d46898d9a0e48c05e66b8e39 --- release/build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/build.sh b/release/build.sh index 328ce43c..002caee2 100755 --- a/release/build.sh +++ b/release/build.sh @@ -36,6 +36,7 @@ fi PRERELEASE_DOCKER_HUB=${PRERELEASE_DOCKER_HUB:-gcr.io/istio-prerelease-testing} GCS_BUCKET=${GCS_BUCKET:-istio-prerelease/prerelease} +SBOM_OUTPUT_URI="https://storage.googleapis.com/${GCS_BUCKET}/releases" HELM_BUCKET=${HELM_BUCKET:-istio-prerelease/charts} COSIGN_KEY=${COSIGN_KEY:-} GITHUB_ORG=${GITHUB_ORG:-istio} @@ -62,6 +63,7 @@ version: "${VERSION}" docker: "${DOCKER_HUB}" directory: "${WORK_DIR}" architectures: ${ARCHS} +billOfMaterialsURI: ${SBOM_OUTPUT_URI} dependencies: ${DEPENDENCIES:-$(cat <