Skip to content

Commit

Permalink
build: add --sbom and --provenance shorthands
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Chadwell <me@jedevc.com>
  • Loading branch information
jedevc committed Nov 24, 2022
1 parent a633277 commit 884ef62
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 24 deletions.
24 changes: 22 additions & 2 deletions commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ type buildOptions struct {
noCacheFilter []string
outputs []string
platforms []string
provenance string
quiet bool
sbom string
secrets []string
shmSize dockeropts.MemBytes
ssh []string
Expand Down Expand Up @@ -217,6 +219,22 @@ func runBuild(dockerCli command.Cli, in buildOptions) (err error) {
if err != nil {
return err
}
sbomAttests, err := buildflags.ParseAttest("sbom", in.sbom)
if err != nil {
return err
}
provenanceAttests, err := buildflags.ParseAttest("provenance", in.provenance)
if err != nil {
return err
}
for _, extraAttests := range []map[string]string{sbomAttests, provenanceAttests} {
for k, v := range extraAttests {
if _, ok := attests[k]; ok {
return errors.Errorf("duplicate attestation options %s", k)
}
attests[k] = v
}
}
opts.Attests = attests

cacheImports, err := buildflags.ParseCacheEntry(in.cacheFrom)
Expand Down Expand Up @@ -446,8 +464,6 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {

flags := cmd.Flags()

flags.StringArrayVar(&options.attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`)

flags.StringSliceVar(&options.extraHosts, "add-host", []string{}, `Add a custom host-to-IP mapping (format: "host:ip")`)
flags.SetAnnotation("add-host", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host"})

Expand Down Expand Up @@ -503,6 +519,10 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {

flags.Var(options.ulimits, "ulimit", "Ulimit options")

flags.StringArrayVar(&options.attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`)
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--attest=type=sbom"`)
flags.StringVar(&options.provenance, "provenance", "", `Shortand for "--attest=type=provenance"`)

if isExperimental() {
flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build [experimental]")
}
Expand Down
67 changes: 45 additions & 22 deletions util/buildflags/attests.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,65 @@ package buildflags

import (
"encoding/csv"
"strconv"
"strings"

"github.com/pkg/errors"
)

func ParseAttests(in []string) (map[string]string, error) {
out := map[string]string{}
for _, s := range in {
csvReader := csv.NewReader(strings.NewReader(s))
fields, err := csvReader.Read()
for _, in := range in {
res, err := parseAttest("", in)
if err != nil {
return nil, err
}
for k, v := range res {
out[k] = v
}
}
return out, nil
}

var attestType string
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) != 2 {
return nil, errors.Errorf("invalid value %s", field)
}
key := strings.TrimSpace(strings.ToLower(parts[0]))
value := parts[1]
switch key {
case "type":
func ParseAttest(attestType string, in string) (map[string]string, error) {
if in == "" {
return nil, nil
}
if b, err := strconv.ParseBool(in); err == nil && b {
return map[string]string{
"attest:" + attestType: "",
}, nil
}

return parseAttest(attestType, in)
}

func parseAttest(attestType string, in string) (map[string]string, error) {
csvReader := csv.NewReader(strings.NewReader(in))
fields, err := csvReader.Read()
if err != nil {
return nil, err
}

for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) != 2 {
return nil, errors.Errorf("invalid value %s", field)
}
key := strings.TrimSpace(strings.ToLower(parts[0]))
value := parts[1]
switch key {
case "type":
if attestType == "" {
attestType = value
}
}
if attestType == "" {
return nil, errors.Errorf("attestation type not specified")
}

out["attest:"+attestType] = s
}

if len(out) == 0 {
return nil, nil
if attestType == "" {
return nil, errors.Errorf("attestation type not specified")
}
return out, nil

return map[string]string{
"attest:" + attestType: in,
}, nil
}

0 comments on commit 884ef62

Please sign in to comment.