Skip to content

Commit

Permalink
Merge pull request #95 from dmikusa-pivotal/bom-rfc-95
Browse files Browse the repository at this point in the history
Adds a convenience method for getting the build, launch and layer BOM file paths
  • Loading branch information
sambhav authored Nov 18, 2021
2 parents 50e1696 + c06fd64 commit 6aa81e5
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 5 deletions.
6 changes: 6 additions & 0 deletions application.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ type LaunchTOML struct {
Slices []Slice `toml:"slices"`

// BOM is a collection of entries for the bill of materials.
//
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
BOM []BOMEntry `toml:"bom"`
}

Expand All @@ -83,6 +85,8 @@ func (l LaunchTOML) isEmpty() bool {
// BuildTOML represents the contents of build.toml.
type BuildTOML struct {
// BOM contains the build-time bill of materials.
//
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
BOM []BOMEntry `toml:"bom"`

// Unmet is a collection of buildpack plan entries that should be passed through to subsequent providers.
Expand All @@ -94,6 +98,8 @@ func (b BuildTOML) isEmpty() bool {
}

// BOMEntry contains a bill of materials entry.
//
// Deprecated: as of Buildpack API 0.7, BOM should use standard formats like CycloneDX going forward
type BOMEntry struct {
// Name represents the name of the entry.
Name string `toml:"name"`
Expand Down
5 changes: 5 additions & 0 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ type BuildContext struct {
// BuildResult contains the results of detection.
type BuildResult struct {
// BOM contains entries to be appended to the app image Bill of Materials and/or build Bill of Materials.
//
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
BOM *BOM

// Labels are the image labels contributed by the buildpack.
Expand All @@ -81,6 +83,8 @@ type BuildResult struct {
}

// BOM contains all Bill of Materials entries
//
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
type BOM struct {
Entries []BOMEntry
}
Expand Down Expand Up @@ -302,6 +306,7 @@ func Build(builder Builder, options ...Option) {
}
}

// Deprecated: as of Buildpack API 0.7, to be removed in a future version
var launchBOM, buildBOM []BOMEntry
if result.BOM != nil {
for _, entry := range result.BOM.Entries {
Expand Down
33 changes: 28 additions & 5 deletions layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (

// Exec represents the exec.d layer location
type Exec struct {

// Path is the path to the exec.d directory.
Path string
}
Expand Down Expand Up @@ -68,9 +67,21 @@ func (p Profile) ProcessAddf(processType string, name string, format string, a .
p.Addf(filepath.Join(processType, name), format, a...)
}

// Contribute represents a layer managed by the buildpack.
type Layer struct {
// BOMFormat indicates the format of the SBOM entry
type SBOMFormat int

const (
CycloneDXJSON SBOMFormat = iota
SPDXJSON
SyftJSON
)

func (b SBOMFormat) String() string {
return []string{"cdx.json", "spdx.json", "syft.json"}[b]
}

// Layer represents a layer managed by the buildpack.
type Layer struct {
// LayerTypes indicates the type of layer
LayerTypes `toml:"types"`

Expand Down Expand Up @@ -99,6 +110,10 @@ type Layer struct {
Exec Exec `toml:"-"`
}

func (l Layer) SBOMPath(bt SBOMFormat) string {
return filepath.Join(filepath.Dir(l.Path), fmt.Sprintf("%s.sbom.%s", l.Name, bt))
}

// LayerTypes describes which types apply to a given layer. A layer may have any combination of Launch, Build, and
// Cache types.
type LayerTypes struct {
Expand All @@ -116,7 +131,6 @@ type LayerTypes struct {

// LayerContributor is an interface for types that create layers.
type LayerContributor interface {

// Contribute accepts a layer and transforms it, returning a layer.
Contribute(layer Layer) (Layer, error)

Expand All @@ -126,7 +140,6 @@ type LayerContributor interface {

// Layers represents the layers part of the specification.
type Layers struct {

// Path is the layers filesystem location.
Path string
}
Expand Down Expand Up @@ -162,3 +175,13 @@ func (l *Layers) Layer(name string) (Layer, error) {

return layer, nil
}

// BOMBuildPath returns the full path to the build SBoM file for the buildpack
func (l Layers) BuildSBOMPath(bt SBOMFormat) string {
return filepath.Join(l.Path, fmt.Sprintf("build.sbom.%s", bt))
}

// BOMLaunchPath returns the full path to the launch SBoM file for the buildpack
func (l Layers) LaunchSBOMPath(bt SBOMFormat) string {
return filepath.Join(l.Path, fmt.Sprintf("launch.sbom.%s", bt))
}
12 changes: 12 additions & 0 deletions layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ func testLayer(t *testing.T, context spec.G, it spec.S) {
Expect(l.Profile).To(Equal(libcnb.Profile{}))
})

it("generates BOM paths", func() {
l, err := layers.Layer("test-name")
Expect(err).NotTo(HaveOccurred())

Expect(l.Path).To(Equal(filepath.Join(path, "test-name")))
Expect(layers.BuildSBOMPath(libcnb.CycloneDXJSON)).To(Equal(filepath.Join(path, "build.sbom.cdx.json")))
Expect(layers.BuildSBOMPath(libcnb.SPDXJSON)).To(Equal(filepath.Join(path, "build.sbom.spdx.json")))
Expect(layers.BuildSBOMPath(libcnb.SyftJSON)).To(Equal(filepath.Join(path, "build.sbom.syft.json")))
Expect(layers.LaunchSBOMPath(libcnb.SyftJSON)).To(Equal(filepath.Join(path, "launch.sbom.syft.json")))
Expect(l.SBOMPath(libcnb.SyftJSON)).To(Equal(filepath.Join(path, "test-name.sbom.syft.json")))
})

it("reads existing 0.5 metadata", func() {
Expect(ioutil.WriteFile(
filepath.Join(path, "test-name.toml"),
Expand Down
1 change: 1 addition & 0 deletions platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (

// EnvCNBBindings is the name of the environment variable that contains the path to the CNB bindings directory.
// See the CNB bindings extension spec for more details - https://github.com/buildpacks/spec/blob/main/extensions/bindings.md
//
// Deprecated: Use the Service Binding Specification for Kubernetes instead -
// https://github.com/buildpacks/rfcs/blob/main/text/0055-deprecate-service-bindings.md.
EnvCNBBindings = "CNB_BINDINGS"
Expand Down

0 comments on commit 6aa81e5

Please sign in to comment.