From 297f9750c310682f1a15b16736f293fc4407c77e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Sun, 6 Jun 2021 13:07:18 -0500 Subject: [PATCH] Generate and stage K8s source SBOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commits plugs the generation of the kubernetes source code SBOM into the stage phase of the release process. The source code SBOM is generated on lye once as all versions in a release are cut at the same point in the commit history. After generating the source SBOM, it is customized and tagged with its own namespace before writing the SPDX file. Signed-off-by: Adolfo GarcĂ­a Veytia (Puerco) --- pkg/anago/stage.go | 43 +++++++++++++++++++++++++++++++++++++++++++ pkg/build/push.go | 14 +++++++++----- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/pkg/anago/stage.go b/pkg/anago/stage.go index e11ce8206a6..ba221e82ef7 100644 --- a/pkg/anago/stage.go +++ b/pkg/anago/stage.go @@ -155,6 +155,8 @@ type stageImpl interface { ) error PushContainerImages(options *build.Options) error GenerateVersionArtifactsBOM(options *spdx.DocGenerateOptions) error + GenerateSourceTreeBOM(options *spdx.DocGenerateOptions) (*spdx.Document, error) + WriteSourceBOM(spdxDoc *spdx.Document, version string) error ListArtifacts(version string) (map[string][]string, error) } @@ -632,7 +634,43 @@ func (d *defaultStageImpl) GenerateVersionArtifactsBOM(options *spdx.DocGenerate return errors.Wrap(err, "generating bill of materials") } +func (d *defaultStageImpl) GenerateSourceTreeBOM( + options *spdx.DocGenerateOptions, +) (*spdx.Document, error) { + logrus.Info("Generating Kubernetes source SBOM file") + doc, err := spdx.NewDocBuilder().Generate(options) + return doc, errors.Wrap(err, "Generating kubernetes source code SBOM") +} + +// WriteSourceBOM takes a source code SBOM and writes it into a file, updating +// its Namespace to match the final destination +func (d *defaultStageImpl) WriteSourceBOM( + spdxDoc *spdx.Document, version string, +) error { + spdxDoc.Namespace = fmt.Sprintf("https://k8s.io/sbom/source/%s", version) + spdxDoc.Name = fmt.Sprintf("kubernetes-%s", version) + return errors.Wrap( + spdxDoc.Write(filepath.Join(os.TempDir(), fmt.Sprintf("source-bom-%s.spdx", version))), + "writing the source code SBOM", + ) +} + func (d *DefaultStage) GenerateBillOfMaterials() error { + // For the Kubernetes source, we only generate the SBOM once as both + // versions are cut from the same point in the git history. The + // resulting SPDX document will be customized for each version + // in WriteSourceBOM() before writing the actual files. + spdxDOC, err := d.impl.GenerateSourceTreeBOM(&spdx.DocGenerateOptions{ + ProcessGoModules: true, + OutputFile: "/tmp/kubernetes-source.spdx", + Namespace: "http://k8s.io/sbom/source/REPLACE", + ScanLicenses: true, + Directories: []string{gitRoot}, + }) + if err != nil { + return errors.Wrap(err, "generating the kubernetes source SBOM") + } + // We generate an artifacts sbom for each of the versions // we are building for _, version := range d.state.versions.Ordered() { @@ -654,6 +692,11 @@ func (d *DefaultStage) GenerateBillOfMaterials() error { }); err != nil { return errors.Wrapf(err, "generating SBOM for version %s", version) } + + // Render the common source bom for this version + if err := d.impl.WriteSourceBOM(spdxDOC, version); err != nil { + return errors.Wrapf(err, "writing SBOM for version %s", version) + } } return nil diff --git a/pkg/build/push.go b/pkg/build/push.go index 37c90a8e6b9..b373aa81f29 100644 --- a/pkg/build/push.go +++ b/pkg/build/push.go @@ -342,11 +342,15 @@ func (bi *Instance) StageLocalArtifacts() error { } // Write the bill of materials manifests - if err := util.CopyFileLocal( - filepath.Join(os.TempDir(), fmt.Sprintf("release-bom-%s.spdx", bi.opts.Version)), - filepath.Join(stageDir, "kubernetes-release.spdx"), true, - ); err != nil { - return errors.Wrapf(err, "copying SBOM manifests") + for filename, sbom := range map[string]string{ + "kubernetes-source.spdx": filepath.Join(os.TempDir(), fmt.Sprintf("source-bom-%s.spdx", bi.opts.Version)), + "kubernetes-release.spdx": filepath.Join(os.TempDir(), fmt.Sprintf("release-bom-%s.spdx", bi.opts.Version)), + } { + if err := util.CopyFileLocal( + sbom, filepath.Join(stageDir, filename), true, + ); err != nil { + return errors.Wrapf(err, "copying SBOM manifests") + } } // Write the release checksums