Skip to content

Commit 12e14c2

Browse files
Added way to configure SBOM scanner
Signed-off-by: Laurent Goderre <[email protected]>
1 parent 185751b commit 12e14c2

File tree

6 files changed

+109
-22
lines changed

6 files changed

+109
-22
lines changed

control/control.go

+16-9
Original file line numberDiff line numberDiff line change
@@ -460,15 +460,22 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
460460
var procs []llbsolver.Processor
461461

462462
if attrs, ok := attests["sbom"]; ok {
463-
src := attrs["generator"]
464-
if src == "" {
465-
return nil, errors.Errorf("sbom generator cannot be empty")
466-
}
467-
ref, err := reference.ParseNormalizedNamed(src)
468-
if err != nil {
469-
return nil, errors.Wrapf(err, "failed to parse sbom generator %s", src)
463+
var ref reference.Named
464+
params := make(map[string]string)
465+
for k, v := range attrs {
466+
if k == "generator" {
467+
if v == "" {
468+
return nil, errors.Errorf("sbom generator cannot be empty")
469+
}
470+
ref, err = reference.ParseNormalizedNamed(v)
471+
if err != nil {
472+
return nil, errors.Wrapf(err, "failed to parse sbom generator %s", v)
473+
}
474+
ref = reference.TagNameOnly(ref)
475+
} else {
476+
params[k] = v
477+
}
470478
}
471-
ref = reference.TagNameOnly(ref)
472479

473480
useCache := true
474481
if v, ok := req.FrontendAttrs["no-cache"]; ok && v == "" {
@@ -480,7 +487,7 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
480487
resolveMode = v
481488
}
482489

483-
procs = append(procs, proc.SBOMProcessor(ref.String(), useCache, resolveMode))
490+
procs = append(procs, proc.SBOMProcessor(ref.String(), useCache, resolveMode, params))
484491
}
485492

486493
if attrs, ok := attests["provenance"]; ok {

frontend/attestations/parse_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package attestations
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestParse(t *testing.T) {
11+
for _, tc := range []struct {
12+
name string
13+
values map[string]string
14+
expected map[string]map[string]string
15+
}{
16+
{
17+
name: "simple",
18+
values: map[string]string{
19+
"attest:sbom": "generator=docker.io/foo/bar",
20+
"attest:provenance": "mode=max",
21+
},
22+
expected: map[string]map[string]string{
23+
"sbom": {
24+
"generator": "docker.io/foo/bar",
25+
},
26+
"provenance": {
27+
"mode": "max",
28+
},
29+
},
30+
},
31+
{
32+
name: "extra params",
33+
values: map[string]string{
34+
"attest:sbom": "generator=docker.io/foo/bar,param1=foo,param2=bar",
35+
},
36+
expected: map[string]map[string]string{
37+
"sbom": {
38+
"generator": "docker.io/foo/bar",
39+
"param1": "foo",
40+
"param2": "bar",
41+
},
42+
},
43+
},
44+
{
45+
name: "extra params (complex)",
46+
values: map[string]string{
47+
"attest:sbom": "\"generator=docker.io/foo/bar\",\"param1=foo\",\"param2=bar\",\"param3=abc,def\"",
48+
},
49+
expected: map[string]map[string]string{
50+
"sbom": {
51+
"generator": "docker.io/foo/bar",
52+
"param1": "foo",
53+
"param2": "bar",
54+
"param3": "abc,def",
55+
},
56+
},
57+
},
58+
} {
59+
t.Run(tc.name, func(t *testing.T) {
60+
attests, err := Parse(tc.values)
61+
require.NoError(t, err)
62+
_ = attests
63+
assert.Equal(t, tc.expected, attests)
64+
})
65+
}
66+
}

frontend/attestations/sbom/sbom.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const (
3434
// attestation.
3535
type Scanner func(ctx context.Context, name string, ref llb.State, extras map[string]llb.State, opts ...llb.ConstraintsOpt) (result.Attestation[*llb.State], error)
3636

37-
func CreateSBOMScanner(ctx context.Context, resolver sourceresolver.MetaResolver, scanner string, resolveOpt sourceresolver.Opt) (Scanner, error) {
37+
func CreateSBOMScanner(ctx context.Context, resolver sourceresolver.MetaResolver, scanner string, resolveOpt sourceresolver.Opt, params map[string]string) (Scanner, error) {
3838
if scanner == "" {
3939
return nil, nil
4040
}
@@ -66,6 +66,10 @@ func CreateSBOMScanner(ctx context.Context, resolver sourceresolver.MetaResolver
6666
env = append(env, "BUILDKIT_SCAN_SOURCE_EXTRAS="+path.Join(srcDir, "extras/"))
6767
}
6868

69+
for k, v := range params {
70+
env = append(env, "BUILDKIT_SCAN_"+k+"="+v)
71+
}
72+
6973
runOpts := []llb.RunOption{
7074
llb.WithCustomName(fmt.Sprintf("[%s] generating sbom using %s", name, scanner)),
7175
}

frontend/dockerfile/builder/build.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func Build(ctx context.Context, c client.Client) (_ *client.Result, err error) {
118118
ImageOpt: &sourceresolver.ResolveImageOpt{
119119
ResolveMode: opts["image-resolve-mode"],
120120
},
121-
})
121+
}, bc.SBOM.Parameters)
122122
if err != nil {
123123
return nil, err
124124
}

frontend/dockerui/config.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ type Client struct {
8989
}
9090

9191
type SBOM struct {
92-
Generator string
92+
Generator string
93+
Parameters map[string]string
9394
}
9495

9596
type Source struct {
@@ -257,17 +258,26 @@ func (bc *Client) init() error {
257258
return err
258259
}
259260
if attrs, ok := attests[attestations.KeyTypeSbom]; ok {
260-
src, ok := attrs["generator"]
261-
if !ok {
262-
return errors.Errorf("sbom scanner cannot be empty")
261+
params := make(map[string]string)
262+
var ref reference.Named
263+
for k, v := range attrs {
264+
if k == "generator" {
265+
ref, err = reference.ParseNormalizedNamed(v)
266+
if err != nil {
267+
return errors.Wrapf(err, "failed to parse sbom scanner %s", v)
268+
}
269+
ref = reference.TagNameOnly(ref)
270+
} else {
271+
params[k] = v
272+
}
263273
}
264-
ref, err := reference.ParseNormalizedNamed(src)
265-
if err != nil {
266-
return errors.Wrapf(err, "failed to parse sbom scanner %s", src)
274+
if ref == nil {
275+
return errors.Errorf("sbom scanner cannot be empty")
267276
}
268-
ref = reference.TagNameOnly(ref)
277+
269278
bc.SBOM = &SBOM{
270-
Generator: ref.String(),
279+
Generator: ref.String(),
280+
Parameters: params,
271281
}
272282
}
273283

solver/llbsolver/proc/sbom.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
"github.com/pkg/errors"
1717
)
1818

19-
func SBOMProcessor(scannerRef string, useCache bool, resolveMode string) llbsolver.Processor {
19+
func SBOMProcessor(scannerRef string, useCache bool, resolveMode string, params map[string]string) llbsolver.Processor {
2020
return func(ctx context.Context, res *llbsolver.Result, s *llbsolver.Solver, j *solver.Job, usage *resources.SysSampler) (*llbsolver.Result, error) {
2121
// skip sbom generation if we already have an sbom
2222
if sbom.HasSBOM(res.Result) {
@@ -35,7 +35,7 @@ func SBOMProcessor(scannerRef string, useCache bool, resolveMode string) llbsolv
3535
ImageOpt: &sourceresolver.ResolveImageOpt{
3636
ResolveMode: resolveMode,
3737
},
38-
})
38+
}, params)
3939
if err != nil {
4040
return nil, err
4141
}

0 commit comments

Comments
 (0)