Skip to content

Commit

Permalink
feat(cnbBuild): Only use sbom-cataloger with cnb images (#4934)
Browse files Browse the repository at this point in the history
  • Loading branch information
c0d1ngm0nk3y authored May 23, 2024
1 parent a5061f3 commit 77758b3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
10 changes: 9 additions & 1 deletion cmd/cnbBuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,15 @@ func callCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData,
buildSummary.Print()

if config.CreateBOM {
err = syft.GenerateSBOM(config.SyftDownloadURL, filepath.Dir(config.DockerConfigJSON), utils, utils, httpClient, commonPipelineEnvironment.container.registryURL, commonPipelineEnvironment.container.imageNameTags)
log.Entry().Debugf("Creating sbom for %d images\n", len(commonPipelineEnvironment.container.imageNameTags))
syftScanner, err := syft.CreateSyftScanner(config.SyftDownloadURL, utils, httpClient)
if err != nil {
log.SetErrorCategory(log.ErrorCompliance)
return errors.Wrap(err, "failed to create syft scanner file")
}
// images produces with cnb have sboms
syftScanner.AddArgument("--override-default-catalogers=sbom-cataloger")
err = syftScanner.ScanImages(filepath.Dir(config.DockerConfigJSON), utils, commonPipelineEnvironment.container.registryURL, commonPipelineEnvironment.container.imageNameTags)
if err != nil {
log.SetErrorCategory(log.ErrorCompliance)
return errors.Wrap(err, "failed to create BOM file")
Expand Down
44 changes: 34 additions & 10 deletions pkg/syft/syft.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,58 @@ import (
"github.com/pkg/errors"
)

func GenerateSBOM(syftDownloadURL, dockerConfigDir string, execRunner command.ExecRunner, fileUtils piperutils.FileUtils, httpClient piperhttp.Sender, registryURL string, images []string) error {
if registryURL == "" {
return errors.New("syft: regisitry url must not be empty")
}
type SyftScanner struct {
syftFile string
additionalArgs []string
}

if len(images) == 0 {
return errors.New("syft: no images provided")
func GenerateSBOM(syftDownloadURL, dockerConfigDir string, execRunner command.ExecRunner, fileUtils piperutils.FileUtils, httpClient piperhttp.Sender, registryURL string, images []string) error {
scanner, err := CreateSyftScanner(syftDownloadURL, fileUtils, httpClient)
if err != nil {
return err
}
return scanner.ScanImages(dockerConfigDir, execRunner, registryURL, images)
}

execRunner.AppendEnv([]string{fmt.Sprintf("DOCKER_CONFIG=%s", dockerConfigDir)})
func CreateSyftScanner(syftDownloadURL string, fileUtils piperutils.FileUtils, httpClient piperhttp.Sender) (*SyftScanner, error) {

tmpDir, err := fileUtils.TempDir("", "syft")
if err != nil {
return err
return nil, err
}
syftFile := filepath.Join(tmpDir, "syft")

err = install(syftDownloadURL, syftFile, fileUtils, httpClient)
if err != nil {
return errors.Wrap(err, "failed to install syft")
return nil, errors.Wrap(err, "failed to install syft")
}

return &SyftScanner{syftFile: syftFile}, nil
}

func (s *SyftScanner) AddArgument(arg string) {
s.additionalArgs = append(s.additionalArgs, arg)
}

func (s *SyftScanner) ScanImages(dockerConfigDir string, execRunner command.ExecRunner, registryURL string, images []string) error {
if registryURL == "" {
return errors.New("syft: registry url must not be empty")
}

if len(images) == 0 {
return errors.New("syft: no images provided")
}

execRunner.AppendEnv([]string{fmt.Sprintf("DOCKER_CONFIG=%s", dockerConfigDir)})

for index, image := range images {
if image == "" {
return errors.New("syft: image name must not be empty")
}
// TrimPrefix needed as syft needs containerRegistry name only
err = execRunner.RunExecutable(syftFile, "scan", fmt.Sprintf("registry:%s/%s", strings.TrimPrefix(registryURL, "https://"), image), "-o", fmt.Sprintf("cyclonedx-xml=bom-docker-%v.xml", index), "-q")
args := []string{"scan", fmt.Sprintf("registry:%s/%s", strings.TrimPrefix(registryURL, "https://"), image), "-o", fmt.Sprintf("cyclonedx-xml=bom-docker-%v.xml", index), "-q"}
args = append(args, s.additionalArgs...)
err := execRunner.RunExecutable(s.syftFile, args...)
if err != nil {
return fmt.Errorf("failed to generate SBOM: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/syft/syft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestGenerateSBOM(t *testing.T) {
t.Run("error case: no registry", func(t *testing.T) {
err := syft.GenerateSBOM("http://test-syft-gh-release.com/syft.tar.gz", "", &execMock, &fileMock, client, "", []string{"image:latest"})
assert.Error(t, err)
assert.Equal(t, "syft: regisitry url must not be empty", err.Error())
assert.Equal(t, "syft: registry url must not be empty", err.Error())
})

t.Run("error case: no images provided", func(t *testing.T) {
Expand Down

0 comments on commit 77758b3

Please sign in to comment.