mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-31 16:13:45 +08:00 
			
		
		
		
	build: add attests flag and sbom/provenance shorthands
Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
		| @@ -53,6 +53,7 @@ type buildOptions struct { | |||||||
| 	printFunc      string | 	printFunc      string | ||||||
|  |  | ||||||
| 	allow         []string | 	allow         []string | ||||||
|  | 	attests       []string | ||||||
| 	buildArgs     []string | 	buildArgs     []string | ||||||
| 	cacheFrom     []string | 	cacheFrom     []string | ||||||
| 	cacheTo       []string | 	cacheTo       []string | ||||||
| @@ -85,6 +86,9 @@ type commonOptions struct { | |||||||
|  |  | ||||||
| 	exportPush bool | 	exportPush bool | ||||||
| 	exportLoad bool | 	exportLoad bool | ||||||
|  |  | ||||||
|  | 	sbom       string | ||||||
|  | 	provenance string | ||||||
| } | } | ||||||
|  |  | ||||||
| func runBuild(dockerCli command.Cli, in buildOptions) (err error) { | func runBuild(dockerCli command.Cli, in buildOptions) (err error) { | ||||||
| @@ -212,9 +216,20 @@ func runBuild(dockerCli command.Cli, in buildOptions) (err error) { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	opts.Exports = outputs | 	opts.Exports = outputs | ||||||
|  |  | ||||||
|  | 	inAttests := append([]string{}, in.attests...) | ||||||
|  | 	if in.provenance != "" { | ||||||
|  | 		inAttests = append(inAttests, buildflags.CanonicalizeAttest("provenance", in.provenance)) | ||||||
|  | 	} | ||||||
|  | 	if in.sbom != "" { | ||||||
|  | 		inAttests = append(inAttests, buildflags.CanonicalizeAttest("sbom", in.sbom)) | ||||||
|  | 	} | ||||||
|  | 	opts.Attests, err = buildflags.ParseAttests(inAttests) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	cacheImports, err := buildflags.ParseCacheEntry(in.cacheFrom) | 	cacheImports, err := buildflags.ParseCacheEntry(in.cacheFrom) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -504,6 +519,10 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { | |||||||
|  |  | ||||||
| 	flags.Var(options.ulimits, "ulimit", "Ulimit options") | 	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() { | 	if isExperimental() { | ||||||
| 		flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build [experimental]") | 		flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build [experimental]") | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ Start a build | |||||||
| | --- | --- | --- | --- | | | --- | --- | --- | --- | | ||||||
| | [`--add-host`](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) | `stringSlice` |  | Add a custom host-to-IP mapping (format: `host:ip`) | | | [`--add-host`](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) | `stringSlice` |  | Add a custom host-to-IP mapping (format: `host:ip`) | | ||||||
| | [`--allow`](#allow) | `stringSlice` |  | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) | | | [`--allow`](#allow) | `stringSlice` |  | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) | | ||||||
|  | | `--attest` | `stringArray` |  | Attestation parameters (format: `type=sbom,generator=image`) | | ||||||
| | [`--build-arg`](#build-arg) | `stringArray` |  | Set build-time variables | | | [`--build-arg`](#build-arg) | `stringArray` |  | Set build-time variables | | ||||||
| | [`--build-context`](#build-context) | `stringArray` |  | Additional build contexts (e.g., name=path) | | | [`--build-context`](#build-context) | `stringArray` |  | Additional build contexts (e.g., name=path) | | ||||||
| | [`--builder`](#builder) | `string` |  | Override the configured builder instance | | | [`--builder`](#builder) | `string` |  | Override the configured builder instance | | ||||||
| @@ -36,9 +37,11 @@ Start a build | |||||||
| | [`--platform`](#platform) | `stringArray` |  | Set target platform for build | | | [`--platform`](#platform) | `stringArray` |  | Set target platform for build | | ||||||
| | `--print` | `string` |  | Print result of information request (e.g., outline, targets) [experimental] | | | `--print` | `string` |  | Print result of information request (e.g., outline, targets) [experimental] | | ||||||
| | [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output | | | [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output | | ||||||
|  | | `--provenance` | `string` |  | Shortand for `--attest=type=provenance` | | ||||||
| | `--pull` |  |  | Always attempt to pull all referenced images | | | `--pull` |  |  | Always attempt to pull all referenced images | | ||||||
| | [`--push`](#push) |  |  | Shorthand for `--output=type=registry` | | | [`--push`](#push) |  |  | Shorthand for `--output=type=registry` | | ||||||
| | `-q`, `--quiet` |  |  | Suppress the build output and print image ID on success | | | `-q`, `--quiet` |  |  | Suppress the build output and print image ID on success | | ||||||
|  | | `--sbom` | `string` |  | Shorthand for `--attest=type=sbom` | | ||||||
| | [`--secret`](#secret) | `stringArray` |  | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) | | | [`--secret`](#secret) | `stringArray` |  | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) | | ||||||
| | [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` | | | [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` | | ||||||
| | [`--ssh`](#ssh) | `stringArray` |  | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) | | | [`--ssh`](#ssh) | `stringArray` |  | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) | | ||||||
|   | |||||||
							
								
								
									
										76
									
								
								util/buildflags/attests.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								util/buildflags/attests.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | package buildflags | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/csv" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/pkg/errors" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func CanonicalizeAttest(attestType string, in string) string { | ||||||
|  | 	if in == "" { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	if b, err := strconv.ParseBool(in); err == nil { | ||||||
|  | 		return fmt.Sprintf("type=%s,enabled=%t", attestType, b) | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("type=%s,%s", attestType, in) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ParseAttests(in []string) (map[string]*string, error) { | ||||||
|  | 	out := map[string]*string{} | ||||||
|  | 	for _, in := range in { | ||||||
|  | 		in := in | ||||||
|  | 		attestType, enabled, err := parseAttest(in) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		k := "attest:" + attestType | ||||||
|  | 		if enabled { | ||||||
|  | 			out[k] = &in | ||||||
|  | 		} else { | ||||||
|  | 			out[k] = nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func parseAttest(in string) (string, bool, error) { | ||||||
|  | 	if in == "" { | ||||||
|  | 		return "", false, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	csvReader := csv.NewReader(strings.NewReader(in)) | ||||||
|  | 	fields, err := csvReader.Read() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", false, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	attestType := "" | ||||||
|  | 	enabled := true | ||||||
|  | 	for _, field := range fields { | ||||||
|  | 		key, value, ok := strings.Cut(field, "=") | ||||||
|  | 		if !ok { | ||||||
|  | 			return "", false, errors.Errorf("invalid value %s", field) | ||||||
|  | 		} | ||||||
|  | 		key = strings.TrimSpace(strings.ToLower(key)) | ||||||
|  |  | ||||||
|  | 		switch key { | ||||||
|  | 		case "type": | ||||||
|  | 			attestType = value | ||||||
|  | 		case "enabled": | ||||||
|  | 			enabled, err = strconv.ParseBool(value) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return "", false, err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if attestType == "" { | ||||||
|  | 		return "", false, errors.Errorf("attestation type not specified") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return attestType, enabled, nil | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Justin Chadwell
					Justin Chadwell