mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	Merge pull request #1614 from jedevc/typed-controller-api
controller: strongly type the controller api
This commit is contained in:
		
							
								
								
									
										37
									
								
								bake/bake.go
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								bake/bake.go
									
									
									
									
									
								
							@@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/buildx/bake/hclparser"
 | 
						"github.com/docker/buildx/bake/hclparser"
 | 
				
			||||||
	"github.com/docker/buildx/build"
 | 
						"github.com/docker/buildx/build"
 | 
				
			||||||
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
	"github.com/docker/buildx/util/buildflags"
 | 
						"github.com/docker/buildx/util/buildflags"
 | 
				
			||||||
	"github.com/docker/buildx/util/platformutil"
 | 
						"github.com/docker/buildx/util/platformutil"
 | 
				
			||||||
	"github.com/docker/cli/cli/config"
 | 
						"github.com/docker/cli/cli/config"
 | 
				
			||||||
@@ -978,17 +979,24 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bo.Session = append(bo.Session, secrets)
 | 
						secretAttachment, err := controllerapi.CreateSecrets(secrets)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	sshSpecs := t.SSH
 | 
					 | 
				
			||||||
	if len(sshSpecs) == 0 && buildflags.IsGitSSH(contextPath) {
 | 
					 | 
				
			||||||
		sshSpecs = []string{"default"}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ssh, err := buildflags.ParseSSHSpecs(sshSpecs)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bo.Session = append(bo.Session, ssh)
 | 
						bo.Session = append(bo.Session, secretAttachment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sshSpecs, err := buildflags.ParseSSHSpecs(t.SSH)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(sshSpecs) == 0 && buildflags.IsGitSSH(contextPath) {
 | 
				
			||||||
 | 
							sshSpecs = append(sshSpecs, &controllerapi.SSH{ID: "default"})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sshAttachment, err := controllerapi.CreateSSH(sshSpecs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						bo.Session = append(bo.Session, sshAttachment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if t.Target != nil {
 | 
						if t.Target != nil {
 | 
				
			||||||
		bo.Target = *t.Target
 | 
							bo.Target = *t.Target
 | 
				
			||||||
@@ -998,25 +1006,28 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bo.CacheFrom = cacheImports
 | 
						bo.CacheFrom = controllerapi.CreateCaches(cacheImports)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cacheExports, err := buildflags.ParseCacheEntry(t.CacheTo)
 | 
						cacheExports, err := buildflags.ParseCacheEntry(t.CacheTo)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bo.CacheTo = cacheExports
 | 
						bo.CacheTo = controllerapi.CreateCaches(cacheExports)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outputs, err := buildflags.ParseOutputs(t.Outputs)
 | 
						outputs, err := buildflags.ParseExports(t.Outputs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						bo.Exports, err = controllerapi.CreateExports(outputs)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bo.Exports = outputs
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	attests, err := buildflags.ParseAttests(t.Attest)
 | 
						attests, err := buildflags.ParseAttests(t.Attest)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bo.Attests = attests
 | 
						bo.Attests = controllerapi.CreateAttestations(attests)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return bo, nil
 | 
						return bo, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,19 +77,19 @@ type Options struct {
 | 
				
			|||||||
	CgroupParent  string
 | 
						CgroupParent  string
 | 
				
			||||||
	Exports       []client.ExportEntry
 | 
						Exports       []client.ExportEntry
 | 
				
			||||||
	ExtraHosts    []string
 | 
						ExtraHosts    []string
 | 
				
			||||||
	ImageIDFile   string
 | 
					 | 
				
			||||||
	Labels        map[string]string
 | 
						Labels        map[string]string
 | 
				
			||||||
	NetworkMode   string
 | 
						NetworkMode   string
 | 
				
			||||||
	NoCache       bool
 | 
						NoCache       bool
 | 
				
			||||||
	NoCacheFilter []string
 | 
						NoCacheFilter []string
 | 
				
			||||||
	Platforms     []specs.Platform
 | 
						Platforms     []specs.Platform
 | 
				
			||||||
	Pull          bool
 | 
						Pull          bool
 | 
				
			||||||
	Session       []session.Attachable
 | 
					 | 
				
			||||||
	ShmSize       opts.MemBytes
 | 
						ShmSize       opts.MemBytes
 | 
				
			||||||
	Tags          []string
 | 
						Tags          []string
 | 
				
			||||||
	Target        string
 | 
						Target        string
 | 
				
			||||||
	Ulimits       *opts.UlimitOpt
 | 
						Ulimits       *opts.UlimitOpt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Session []session.Attachable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Linked marks this target as exclusively linked (not requested by the user).
 | 
						// Linked marks this target as exclusively linked (not requested by the user).
 | 
				
			||||||
	Linked    bool
 | 
						Linked    bool
 | 
				
			||||||
	PrintFunc *PrintFunc
 | 
						PrintFunc *PrintFunc
 | 
				
			||||||
@@ -375,13 +375,6 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opt.ImageIDFile != "" {
 | 
					 | 
				
			||||||
		// Avoid leaving a stale file if we eventually fail
 | 
					 | 
				
			||||||
		if err := os.Remove(opt.ImageIDFile); err != nil && !os.IsNotExist(err) {
 | 
					 | 
				
			||||||
			return nil, nil, errors.Wrap(err, "removing image ID file")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// inline cache from build arg
 | 
						// inline cache from build arg
 | 
				
			||||||
	if v, ok := opt.BuildArgs["BUILDKIT_INLINE_CACHE"]; ok {
 | 
						if v, ok := opt.BuildArgs["BUILDKIT_INLINE_CACHE"]; ok {
 | 
				
			||||||
		if v, _ := strconv.ParseBool(v); v {
 | 
							if v, _ := strconv.ParseBool(v); v {
 | 
				
			||||||
@@ -462,11 +455,11 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
 | 
				
			|||||||
			return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
 | 
								return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for k, v := range attests {
 | 
							for k, v := range attests {
 | 
				
			||||||
			so.FrontendAttrs[k] = v
 | 
								so.FrontendAttrs["attest:"+k] = v
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, ok := opt.Attests["attest:provenance"]; !ok && supportsAttestations {
 | 
						if _, ok := opt.Attests["provenance"]; !ok && supportsAttestations {
 | 
				
			||||||
		const noAttestEnv = "BUILDX_NO_DEFAULT_ATTESTATIONS"
 | 
							const noAttestEnv = "BUILDX_NO_DEFAULT_ATTESTATIONS"
 | 
				
			||||||
		var noProv bool
 | 
							var noProv bool
 | 
				
			||||||
		if v, ok := os.LookupEnv(noAttestEnv); ok {
 | 
							if v, ok := os.LookupEnv(noAttestEnv); ok {
 | 
				
			||||||
@@ -530,9 +523,6 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// set up exporters
 | 
						// set up exporters
 | 
				
			||||||
	for i, e := range opt.Exports {
 | 
						for i, e := range opt.Exports {
 | 
				
			||||||
		if (e.Type == "local" || e.Type == "tar") && opt.ImageIDFile != "" {
 | 
					 | 
				
			||||||
			return nil, nil, errors.Errorf("local and tar exporters are incompatible with image ID file")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if e.Type == "oci" && !nodeDriver.Features()[driver.OCIExporter] {
 | 
							if e.Type == "oci" && !nodeDriver.Features()[driver.OCIExporter] {
 | 
				
			||||||
			return nil, nil, notSupported(nodeDriver, driver.OCIExporter)
 | 
								return nil, nil, notSupported(nodeDriver, driver.OCIExporter)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -1154,13 +1144,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
 | 
				
			|||||||
				resp[k] = res[0]
 | 
									resp[k] = res[0]
 | 
				
			||||||
				respMu.Unlock()
 | 
									respMu.Unlock()
 | 
				
			||||||
				if len(res) == 1 {
 | 
									if len(res) == 1 {
 | 
				
			||||||
					dgst := res[0].ExporterResponse[exptypes.ExporterImageDigestKey]
 | 
					 | 
				
			||||||
					if v, ok := res[0].ExporterResponse[exptypes.ExporterImageConfigDigestKey]; ok {
 | 
					 | 
				
			||||||
						dgst = v
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if opt.ImageIDFile != "" {
 | 
					 | 
				
			||||||
						return os.WriteFile(opt.ImageIDFile, []byte(dgst), 0644)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					return nil
 | 
										return nil
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1238,11 +1221,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
 | 
				
			|||||||
							if err != nil {
 | 
												if err != nil {
 | 
				
			||||||
								return err
 | 
													return err
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							if opt.ImageIDFile != "" {
 | 
					 | 
				
			||||||
								if err := os.WriteFile(opt.ImageIDFile, []byte(desc.Digest), 0644); err != nil {
 | 
					 | 
				
			||||||
									return err
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
							itpush := imagetools.New(imageopt)
 | 
												itpush := imagetools.New(imageopt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1259,7 +1237,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
 | 
				
			|||||||
							respMu.Lock()
 | 
												respMu.Lock()
 | 
				
			||||||
							resp[k] = &client.SolveResponse{
 | 
												resp[k] = &client.SolveResponse{
 | 
				
			||||||
								ExporterResponse: map[string]string{
 | 
													ExporterResponse: map[string]string{
 | 
				
			||||||
									"containerimage.digest": desc.Digest.String(),
 | 
														exptypes.ExporterImageDigestKey: desc.Digest.String(),
 | 
				
			||||||
								},
 | 
													},
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							respMu.Unlock()
 | 
												respMu.Unlock()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,9 +24,11 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type bakeOptions struct {
 | 
					type bakeOptions struct {
 | 
				
			||||||
	files     []string
 | 
						files      []string
 | 
				
			||||||
	overrides []string
 | 
						overrides  []string
 | 
				
			||||||
	printOnly bool
 | 
						printOnly  bool
 | 
				
			||||||
 | 
						sbom       string
 | 
				
			||||||
 | 
						provenance string
 | 
				
			||||||
	controllerapi.CommonOptions
 | 
						controllerapi.CommonOptions
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,11 +78,11 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com
 | 
				
			|||||||
	if cFlags.pull != nil {
 | 
						if cFlags.pull != nil {
 | 
				
			||||||
		overrides = append(overrides, fmt.Sprintf("*.pull=%t", *cFlags.pull))
 | 
							overrides = append(overrides, fmt.Sprintf("*.pull=%t", *cFlags.pull))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if in.SBOM != "" {
 | 
						if in.sbom != "" {
 | 
				
			||||||
		overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("sbom", in.SBOM)))
 | 
							overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("sbom", in.sbom)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if in.Provenance != "" {
 | 
						if in.provenance != "" {
 | 
				
			||||||
		overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("provenance", in.Provenance)))
 | 
							overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("provenance", in.provenance)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	contextPathHash, _ := os.Getwd()
 | 
						contextPathHash, _ := os.Getwd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -220,8 +222,8 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
 | 
				
			|||||||
	flags.BoolVar(&options.ExportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`)
 | 
						flags.BoolVar(&options.ExportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`)
 | 
				
			||||||
	flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
 | 
						flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
 | 
				
			||||||
	flags.BoolVar(&options.ExportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`)
 | 
						flags.BoolVar(&options.ExportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`)
 | 
				
			||||||
	flags.StringVar(&options.SBOM, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
 | 
						flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
 | 
				
			||||||
	flags.StringVar(&options.Provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
 | 
						flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
 | 
				
			||||||
	flags.StringArrayVar(&options.overrides, "set", nil, `Override target value (e.g., "targetpattern.key=value")`)
 | 
						flags.StringArrayVar(&options.overrides, "set", nil, `Override target value (e.g., "targetpattern.key=value")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	commonBuildFlags(&cFlags, flags)
 | 
						commonBuildFlags(&cFlags, flags)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
	"encoding/csv"
 | 
						"encoding/csv"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
@@ -19,14 +20,17 @@ import (
 | 
				
			|||||||
	"github.com/docker/buildx/monitor"
 | 
						"github.com/docker/buildx/monitor"
 | 
				
			||||||
	"github.com/docker/buildx/store"
 | 
						"github.com/docker/buildx/store"
 | 
				
			||||||
	"github.com/docker/buildx/store/storeutil"
 | 
						"github.com/docker/buildx/store/storeutil"
 | 
				
			||||||
 | 
						"github.com/docker/buildx/util/buildflags"
 | 
				
			||||||
	"github.com/docker/buildx/util/ioset"
 | 
						"github.com/docker/buildx/util/ioset"
 | 
				
			||||||
 | 
						"github.com/docker/buildx/util/progress"
 | 
				
			||||||
	"github.com/docker/buildx/util/tracing"
 | 
						"github.com/docker/buildx/util/tracing"
 | 
				
			||||||
	"github.com/docker/cli-docs-tool/annotation"
 | 
						"github.com/docker/cli-docs-tool/annotation"
 | 
				
			||||||
	"github.com/docker/cli/cli"
 | 
						"github.com/docker/cli/cli"
 | 
				
			||||||
	"github.com/docker/cli/cli/command"
 | 
						"github.com/docker/cli/cli/command"
 | 
				
			||||||
	dockeropts "github.com/docker/cli/opts"
 | 
						dockeropts "github.com/docker/cli/opts"
 | 
				
			||||||
	"github.com/docker/docker/pkg/ioutils"
 | 
						"github.com/docker/docker/pkg/ioutils"
 | 
				
			||||||
	"github.com/docker/go-units"
 | 
						"github.com/moby/buildkit/client"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/exporter/containerimage/exptypes"
 | 
				
			||||||
	"github.com/moby/buildkit/util/appcontext"
 | 
						"github.com/moby/buildkit/util/appcontext"
 | 
				
			||||||
	"github.com/moby/buildkit/util/grpcerrors"
 | 
						"github.com/moby/buildkit/util/grpcerrors"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
@@ -37,12 +41,127 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type buildOptions struct {
 | 
					type buildOptions struct {
 | 
				
			||||||
 | 
						allow          []string
 | 
				
			||||||
 | 
						buildArgs      []string
 | 
				
			||||||
 | 
						cacheFrom      []string
 | 
				
			||||||
 | 
						cacheTo        []string
 | 
				
			||||||
 | 
						cgroupParent   string
 | 
				
			||||||
 | 
						contextPath    string
 | 
				
			||||||
 | 
						contexts       []string
 | 
				
			||||||
 | 
						dockerfileName string
 | 
				
			||||||
 | 
						extraHosts     []string
 | 
				
			||||||
 | 
						imageIDFile    string
 | 
				
			||||||
 | 
						labels         []string
 | 
				
			||||||
 | 
						networkMode    string
 | 
				
			||||||
 | 
						noCacheFilter  []string
 | 
				
			||||||
 | 
						outputs        []string
 | 
				
			||||||
 | 
						platforms      []string
 | 
				
			||||||
 | 
						printFunc      string
 | 
				
			||||||
 | 
						secrets        []string
 | 
				
			||||||
 | 
						shmSize        dockeropts.MemBytes
 | 
				
			||||||
 | 
						ssh            []string
 | 
				
			||||||
 | 
						tags           []string
 | 
				
			||||||
 | 
						target         string
 | 
				
			||||||
 | 
						ulimits        *dockeropts.UlimitOpt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						invoke string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attests    []string
 | 
				
			||||||
 | 
						sbom       string
 | 
				
			||||||
 | 
						provenance string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	progress string
 | 
						progress string
 | 
				
			||||||
	invoke   string
 | 
						quiet    bool
 | 
				
			||||||
	controllerapi.BuildOptions
 | 
					
 | 
				
			||||||
 | 
						controllerapi.CommonOptions
 | 
				
			||||||
	control.ControlOptions
 | 
						control.ControlOptions
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *buildOptions) toControllerOptions() (controllerapi.BuildOptions, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						opts := controllerapi.BuildOptions{
 | 
				
			||||||
 | 
							Allow:          o.allow,
 | 
				
			||||||
 | 
							BuildArgs:      listToMap(o.buildArgs, true),
 | 
				
			||||||
 | 
							CgroupParent:   o.cgroupParent,
 | 
				
			||||||
 | 
							ContextPath:    o.contextPath,
 | 
				
			||||||
 | 
							DockerfileName: o.dockerfileName,
 | 
				
			||||||
 | 
							ExtraHosts:     o.extraHosts,
 | 
				
			||||||
 | 
							Labels:         listToMap(o.labels, false),
 | 
				
			||||||
 | 
							NetworkMode:    o.networkMode,
 | 
				
			||||||
 | 
							NoCacheFilter:  o.noCacheFilter,
 | 
				
			||||||
 | 
							Platforms:      o.platforms,
 | 
				
			||||||
 | 
							PrintFunc:      o.printFunc,
 | 
				
			||||||
 | 
							ShmSize:        int64(o.shmSize),
 | 
				
			||||||
 | 
							Tags:           o.tags,
 | 
				
			||||||
 | 
							Target:         o.target,
 | 
				
			||||||
 | 
							Ulimits:        dockerUlimitToControllerUlimit(o.ulimits),
 | 
				
			||||||
 | 
							Opts:           &o.CommonOptions,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inAttests := append([]string{}, o.attests...)
 | 
				
			||||||
 | 
						if o.provenance != "" {
 | 
				
			||||||
 | 
							inAttests = append(inAttests, buildflags.CanonicalizeAttest("provenance", o.provenance))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if o.sbom != "" {
 | 
				
			||||||
 | 
							inAttests = append(inAttests, buildflags.CanonicalizeAttest("sbom", o.sbom))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts.Attests, err = buildflags.ParseAttests(inAttests)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.NamedContexts, err = buildflags.ParseContextNames(o.contexts)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.Exports, err = buildflags.ParseExports(o.outputs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, e := range opts.Exports {
 | 
				
			||||||
 | 
							if (e.Type == client.ExporterLocal || e.Type == client.ExporterTar) && o.imageIDFile != "" {
 | 
				
			||||||
 | 
								return controllerapi.BuildOptions{}, errors.Errorf("local and tar exporters are incompatible with image ID file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.CacheFrom, err = buildflags.ParseCacheEntry(o.cacheFrom)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts.CacheTo, err = buildflags.ParseCacheEntry(o.cacheTo)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.Secrets, err = buildflags.ParseSecretSpecs(o.secrets)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts.SSH, err = buildflags.ParseSSHSpecs(o.ssh)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return controllerapi.BuildOptions{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return opts, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *buildOptions) toProgress() (string, error) {
 | 
				
			||||||
 | 
						switch o.progress {
 | 
				
			||||||
 | 
						case progress.PrinterModeAuto, progress.PrinterModeTty, progress.PrinterModePlain, progress.PrinterModeQuiet:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return "", errors.Errorf("progress=%s is not a valid progress option", o.progress)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if o.quiet {
 | 
				
			||||||
 | 
							if o.progress != progress.PrinterModeAuto && o.progress != progress.PrinterModeQuiet {
 | 
				
			||||||
 | 
								return "", errors.Errorf("progress=%s and quiet cannot be used together", o.progress)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return progress.PrinterModeQuiet, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return o.progress, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func runBuild(dockerCli command.Cli, in buildOptions) error {
 | 
					func runBuild(dockerCli command.Cli, in buildOptions) error {
 | 
				
			||||||
	ctx := appcontext.Context()
 | 
						ctx := appcontext.Context()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -54,12 +173,40 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
 | 
				
			|||||||
		end(err)
 | 
							end(err)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = cbuild.RunBuild(ctx, dockerCli, in.BuildOptions, os.Stdin, in.progress, nil)
 | 
						opts, err := in.toControllerOptions()
 | 
				
			||||||
	return err
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						progress, err := in.toProgress()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Avoid leaving a stale file if we eventually fail
 | 
				
			||||||
 | 
						if in.imageIDFile != "" {
 | 
				
			||||||
 | 
							if err := os.Remove(in.imageIDFile); err != nil && !os.IsNotExist(err) {
 | 
				
			||||||
 | 
								return errors.Wrap(err, "removing image ID file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						resp, _, err := cbuild.RunBuild(ctx, dockerCli, opts, os.Stdin, progress, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if in.quiet {
 | 
				
			||||||
 | 
							fmt.Println(resp.ExporterResponse[exptypes.ExporterImageDigestKey])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if in.imageIDFile != "" {
 | 
				
			||||||
 | 
							dgst := resp.ExporterResponse[exptypes.ExporterImageDigestKey]
 | 
				
			||||||
 | 
							if v, ok := resp.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; ok {
 | 
				
			||||||
 | 
								dgst = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return os.WriteFile(in.imageIDFile, []byte(dgst), 0644)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
 | 
					func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
 | 
				
			||||||
	options := newBuildOptions()
 | 
						options := buildOptions{}
 | 
				
			||||||
	cFlags := &commonFlags{}
 | 
						cFlags := &commonFlags{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := &cobra.Command{
 | 
						cmd := &cobra.Command{
 | 
				
			||||||
@@ -68,16 +215,16 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
 | 
				
			|||||||
		Short:   "Start a build",
 | 
							Short:   "Start a build",
 | 
				
			||||||
		Args:    cli.ExactArgs(1),
 | 
							Args:    cli.ExactArgs(1),
 | 
				
			||||||
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
							RunE: func(cmd *cobra.Command, args []string) error {
 | 
				
			||||||
			options.ContextPath = args[0]
 | 
								options.contextPath = args[0]
 | 
				
			||||||
			options.Opts.Builder = rootOpts.builder
 | 
								options.Builder = rootOpts.builder
 | 
				
			||||||
			options.Opts.MetadataFile = cFlags.metadataFile
 | 
								options.MetadataFile = cFlags.metadataFile
 | 
				
			||||||
			options.Opts.NoCache = false
 | 
								options.NoCache = false
 | 
				
			||||||
			if cFlags.noCache != nil {
 | 
								if cFlags.noCache != nil {
 | 
				
			||||||
				options.Opts.NoCache = *cFlags.noCache
 | 
									options.NoCache = *cFlags.noCache
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			options.Opts.Pull = false
 | 
								options.Pull = false
 | 
				
			||||||
			if cFlags.pull != nil {
 | 
								if cFlags.pull != nil {
 | 
				
			||||||
				options.Opts.Pull = *cFlags.pull
 | 
									options.Pull = *cFlags.pull
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			options.progress = cFlags.progress
 | 
								options.progress = cFlags.progress
 | 
				
			||||||
			cmd.Flags().VisitAll(checkWarnedFlags)
 | 
								cmd.Flags().VisitAll(checkWarnedFlags)
 | 
				
			||||||
@@ -95,64 +242,65 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	flags := cmd.Flags()
 | 
						flags := cmd.Flags()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringSliceVar(&options.ExtraHosts, "add-host", []string{}, `Add a custom host-to-IP mapping (format: "host:ip")`)
 | 
						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-host"})
 | 
						flags.SetAnnotation("add-host", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#add-host"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringSliceVar(&options.Allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
 | 
						flags.StringSliceVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.BuildArgs, "build-arg", []string{}, "Set build-time variables")
 | 
						flags.StringArrayVar(&options.buildArgs, "build-arg", []string{}, "Set build-time variables")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.CacheFrom, "cache-from", []string{}, `External cache sources (e.g., "user/app:cache", "type=local,src=path/to/dir")`)
 | 
						flags.StringArrayVar(&options.cacheFrom, "cache-from", []string{}, `External cache sources (e.g., "user/app:cache", "type=local,src=path/to/dir")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.CacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
 | 
						flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringVar(&options.CgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container")
 | 
						flags.StringVar(&options.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container")
 | 
				
			||||||
	flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
 | 
						flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.Contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
 | 
						flags.StringArrayVar(&options.contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringVarP(&options.DockerfileName, "file", "f", "", `Name of the Dockerfile (default: "PATH/Dockerfile")`)
 | 
						flags.StringVarP(&options.dockerfileName, "file", "f", "", `Name of the Dockerfile (default: "PATH/Dockerfile")`)
 | 
				
			||||||
	flags.SetAnnotation("file", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#file"})
 | 
						flags.SetAnnotation("file", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#file"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringVar(&options.ImageIDFile, "iidfile", "", "Write the image ID to the file")
 | 
						flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.Labels, "label", []string{}, "Set metadata for an image")
 | 
						flags.StringArrayVar(&options.labels, "label", []string{}, "Set metadata for an image")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.BoolVar(&options.Opts.ExportLoad, "load", false, `Shorthand for "--output=type=docker"`)
 | 
						flags.BoolVar(&options.ExportLoad, "load", false, `Shorthand for "--output=type=docker"`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringVar(&options.NetworkMode, "network", "default", `Set the networking mode for the "RUN" instructions during build`)
 | 
						flags.StringVar(&options.networkMode, "network", "default", `Set the networking mode for the "RUN" instructions during build`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.NoCacheFilter, "no-cache-filter", []string{}, "Do not cache specified stages")
 | 
						flags.StringArrayVar(&options.noCacheFilter, "no-cache-filter", []string{}, "Do not cache specified stages")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVarP(&options.Outputs, "output", "o", []string{}, `Output destination (format: "type=local,dest=path")`)
 | 
						flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, `Output destination (format: "type=local,dest=path")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.Platforms, "platform", platformsDefault, "Set target platform for build")
 | 
						flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if isExperimental() {
 | 
						if isExperimental() {
 | 
				
			||||||
		flags.StringVar(&options.PrintFunc, "print", "", "Print result of information request (e.g., outline, targets) [experimental]")
 | 
							flags.StringVar(&options.printFunc, "print", "", "Print result of information request (e.g., outline, targets) [experimental]")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.BoolVar(&options.Opts.ExportPush, "push", false, `Shorthand for "--output=type=registry"`)
 | 
						flags.BoolVar(&options.ExportPush, "push", false, `Shorthand for "--output=type=registry"`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.BoolVarP(&options.Quiet, "quiet", "q", false, "Suppress the build output and print image ID on success")
 | 
						flags.BoolVarP(&options.quiet, "quiet", "q", false, "Suppress the build output and print image ID on success")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.Secrets, "secret", []string{}, `Secret to expose to the build (format: "id=mysecret[,src=/local/secret]")`)
 | 
						flags.StringArrayVar(&options.secrets, "secret", []string{}, `Secret to expose to the build (format: "id=mysecret[,src=/local/secret]")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.Var(newShmSize(&options), "shm-size", `Size of "/dev/shm"`)
 | 
						flags.Var(&options.shmSize, "shm-size", `Size of "/dev/shm"`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.SSH, "ssh", []string{}, `SSH agent socket or keys to expose to the build (format: "default|<id>[=<socket>|<key>[,<key>]]")`)
 | 
						flags.StringArrayVar(&options.ssh, "ssh", []string{}, `SSH agent socket or keys to expose to the build (format: "default|<id>[=<socket>|<key>[,<key>]]")`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVarP(&options.Tags, "tag", "t", []string{}, `Name and optionally a tag (format: "name:tag")`)
 | 
						flags.StringArrayVarP(&options.tags, "tag", "t", []string{}, `Name and optionally a tag (format: "name:tag")`)
 | 
				
			||||||
	flags.SetAnnotation("tag", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#tag"})
 | 
						flags.SetAnnotation("tag", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#tag"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringVar(&options.Target, "target", "", "Set the target build stage to build")
 | 
						flags.StringVar(&options.target, "target", "", "Set the target build stage to build")
 | 
				
			||||||
	flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#target"})
 | 
						flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#target"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.Var(newUlimits(&options), "ulimit", "Ulimit options")
 | 
						options.ulimits = dockeropts.NewUlimitOpt(nil)
 | 
				
			||||||
 | 
						flags.Var(options.ulimits, "ulimit", "Ulimit options")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags.StringArrayVar(&options.Attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`)
 | 
						flags.StringArrayVar(&options.attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`)
 | 
				
			||||||
	flags.StringVar(&options.Opts.SBOM, "sbom", "", `Shorthand for "--attest=type=sbom"`)
 | 
						flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--attest=type=sbom"`)
 | 
				
			||||||
	flags.StringVar(&options.Opts.Provenance, "provenance", "", `Shortand for "--attest=type=provenance"`)
 | 
						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]")
 | 
				
			||||||
@@ -317,12 +465,7 @@ func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error {
 | 
				
			|||||||
func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) error {
 | 
					func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) error {
 | 
				
			||||||
	ctx := context.TODO()
 | 
						ctx := context.TODO()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if options.Quiet && options.progress != "auto" && options.progress != "quiet" {
 | 
						if options.invoke != "" && (options.dockerfileName == "-" || options.contextPath == "-") {
 | 
				
			||||||
		return errors.Errorf("progress=%s and quiet cannot be used together", options.progress)
 | 
					 | 
				
			||||||
	} else if options.Quiet {
 | 
					 | 
				
			||||||
		options.progress = "quiet"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if options.invoke != "" && (options.DockerfileName == "-" || options.ContextPath == "-") {
 | 
					 | 
				
			||||||
		// stdin must be usable for monitor
 | 
							// stdin must be usable for monitor
 | 
				
			||||||
		return errors.Errorf("Dockerfile or context from stdin is not supported with invoke")
 | 
							return errors.Errorf("Dockerfile or context from stdin is not supported with invoke")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -354,8 +497,24 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
	f.SetReader(os.Stdin)
 | 
						f.SetReader(os.Stdin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts, err := options.toControllerOptions()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						progress, err := options.toProgress()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Avoid leaving a stale file if we eventually fail
 | 
				
			||||||
 | 
						if options.imageIDFile != "" {
 | 
				
			||||||
 | 
							if err := os.Remove(options.imageIDFile); err != nil && !os.IsNotExist(err) {
 | 
				
			||||||
 | 
								return errors.Wrap(err, "removing image ID file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Start build
 | 
						// Start build
 | 
				
			||||||
	ref, err := c.Build(ctx, options.BuildOptions, pr, os.Stdout, os.Stderr, options.progress)
 | 
						ref, resp, err := c.Build(ctx, opts, pr, os.Stdout, os.Stderr, progress)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.Wrapf(err, "failed to build") // TODO: allow invoke even on error
 | 
							return errors.Wrapf(err, "failed to build") // TODO: allow invoke even on error
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -366,6 +525,17 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er
 | 
				
			|||||||
		logrus.Debug("failed to close stdin pipe reader")
 | 
							logrus.Debug("failed to close stdin pipe reader")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if options.quiet {
 | 
				
			||||||
 | 
							fmt.Println(resp.ExporterResponse[exptypes.ExporterImageDigestKey])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if options.imageIDFile != "" {
 | 
				
			||||||
 | 
							dgst := resp.ExporterResponse[exptypes.ExporterImageDigestKey]
 | 
				
			||||||
 | 
							if v, ok := resp.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; ok {
 | 
				
			||||||
 | 
								dgst = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return os.WriteFile(options.imageIDFile, []byte(dgst), 0644)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// post-build operations
 | 
						// post-build operations
 | 
				
			||||||
	if options.invoke != "" {
 | 
						if options.invoke != "" {
 | 
				
			||||||
		pr2, pw2 := io.Pipe()
 | 
							pr2, pw2 := io.Pipe()
 | 
				
			||||||
@@ -380,7 +550,7 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return errors.Errorf("failed to configure terminal: %v", err)
 | 
								return errors.Errorf("failed to configure terminal: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		err = monitor.RunMonitor(ctx, ref, options.BuildOptions, invokeConfig, c, options.progress, pr2, os.Stdout, os.Stderr)
 | 
							err = monitor.RunMonitor(ctx, ref, opts, invokeConfig, c, options.progress, pr2, os.Stdout, os.Stderr)
 | 
				
			||||||
		con.Reset()
 | 
							con.Reset()
 | 
				
			||||||
		if err := pw2.Close(); err != nil {
 | 
							if err := pw2.Close(); err != nil {
 | 
				
			||||||
			logrus.Debug("failed to close monitor stdin pipe reader")
 | 
								logrus.Debug("failed to close monitor stdin pipe reader")
 | 
				
			||||||
@@ -445,75 +615,37 @@ func parseInvokeConfig(invoke string) (cfg controllerapi.ContainerConfig, err er
 | 
				
			|||||||
	return cfg, nil
 | 
						return cfg, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newBuildOptions() buildOptions {
 | 
					func listToMap(values []string, defaultEnv bool) map[string]string {
 | 
				
			||||||
	return buildOptions{
 | 
						result := make(map[string]string, len(values))
 | 
				
			||||||
		BuildOptions: controllerapi.BuildOptions{
 | 
						for _, value := range values {
 | 
				
			||||||
			Opts: &controllerapi.CommonOptions{},
 | 
							kv := strings.SplitN(value, "=", 2)
 | 
				
			||||||
		},
 | 
							if len(kv) == 1 {
 | 
				
			||||||
	}
 | 
								if defaultEnv {
 | 
				
			||||||
}
 | 
									v, ok := os.LookupEnv(kv[0])
 | 
				
			||||||
 | 
									if ok {
 | 
				
			||||||
func newUlimits(opt *buildOptions) *ulimits {
 | 
										result[kv[0]] = v
 | 
				
			||||||
	ul := make(map[string]*units.Ulimit)
 | 
									}
 | 
				
			||||||
	return &ulimits{opt: opt, org: dockeropts.NewUlimitOpt(&ul)}
 | 
								} else {
 | 
				
			||||||
}
 | 
									result[kv[0]] = ""
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
type ulimits struct {
 | 
							} else {
 | 
				
			||||||
	opt *buildOptions
 | 
								result[kv[0]] = kv[1]
 | 
				
			||||||
	org *dockeropts.UlimitOpt
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u *ulimits) sync() {
 | 
					 | 
				
			||||||
	du := &controllerapi.UlimitOpt{
 | 
					 | 
				
			||||||
		Values: make(map[string]*controllerapi.Ulimit),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, l := range u.org.GetList() {
 | 
					 | 
				
			||||||
		du.Values[l.Name] = &controllerapi.Ulimit{
 | 
					 | 
				
			||||||
			Name: l.Name,
 | 
					 | 
				
			||||||
			Hard: l.Hard,
 | 
					 | 
				
			||||||
			Soft: l.Soft,
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	u.opt.Ulimits = du
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (u *ulimits) String() string {
 | 
					func dockerUlimitToControllerUlimit(u *dockeropts.UlimitOpt) *controllerapi.UlimitOpt {
 | 
				
			||||||
	return u.org.String()
 | 
						if u == nil {
 | 
				
			||||||
}
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
func (u *ulimits) Set(v string) error {
 | 
						values := make(map[string]*controllerapi.Ulimit)
 | 
				
			||||||
	err := u.org.Set(v)
 | 
						for _, u := range u.GetList() {
 | 
				
			||||||
	u.sync()
 | 
							values[u.Name] = &controllerapi.Ulimit{
 | 
				
			||||||
	return err
 | 
								Name: u.Name,
 | 
				
			||||||
}
 | 
								Hard: u.Hard,
 | 
				
			||||||
 | 
								Soft: u.Soft,
 | 
				
			||||||
func (u *ulimits) Type() string {
 | 
							}
 | 
				
			||||||
	return u.org.Type()
 | 
						}
 | 
				
			||||||
}
 | 
						return &controllerapi.UlimitOpt{Values: values}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func newShmSize(opt *buildOptions) *shmSize {
 | 
					 | 
				
			||||||
	return &shmSize{opt: opt}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type shmSize struct {
 | 
					 | 
				
			||||||
	opt *buildOptions
 | 
					 | 
				
			||||||
	org dockeropts.MemBytes
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *shmSize) sync() {
 | 
					 | 
				
			||||||
	s.opt.ShmSize = s.org.Value()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *shmSize) String() string {
 | 
					 | 
				
			||||||
	return s.org.String()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *shmSize) Set(v string) error {
 | 
					 | 
				
			||||||
	err := s.org.Set(v)
 | 
					 | 
				
			||||||
	s.sync()
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *shmSize) Type() string {
 | 
					 | 
				
			||||||
	return s.org.Type()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,6 @@ import (
 | 
				
			|||||||
	"github.com/docker/cli/cli/command"
 | 
						"github.com/docker/cli/cli/command"
 | 
				
			||||||
	"github.com/docker/cli/cli/config"
 | 
						"github.com/docker/cli/cli/config"
 | 
				
			||||||
	dockeropts "github.com/docker/cli/opts"
 | 
						dockeropts "github.com/docker/cli/opts"
 | 
				
			||||||
	"github.com/docker/distribution/reference"
 | 
					 | 
				
			||||||
	"github.com/docker/docker/pkg/ioutils"
 | 
						"github.com/docker/docker/pkg/ioutils"
 | 
				
			||||||
	"github.com/docker/go-units"
 | 
						"github.com/docker/go-units"
 | 
				
			||||||
	"github.com/moby/buildkit/client"
 | 
						"github.com/moby/buildkit/client"
 | 
				
			||||||
@@ -42,25 +41,19 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const defaultTargetName = "default"
 | 
					const defaultTargetName = "default"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progressMode string, statusChan chan *client.SolveStatus) (res *build.ResultContext, err error) {
 | 
					func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progressMode string, statusChan chan *client.SolveStatus) (*client.SolveResponse, *build.ResultContext, error) {
 | 
				
			||||||
	if in.Opts.NoCache && len(in.NoCacheFilter) > 0 {
 | 
						if in.Opts.NoCache && len(in.NoCacheFilter) > 0 {
 | 
				
			||||||
		return nil, errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together")
 | 
							return nil, nil, errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if in.Quiet && progressMode != progress.PrinterModeAuto && progressMode != progress.PrinterModeQuiet {
 | 
						contexts := map[string]build.NamedContext{}
 | 
				
			||||||
		return nil, errors.Errorf("progress=%s and quiet cannot be used together", progressMode)
 | 
						for name, path := range in.NamedContexts {
 | 
				
			||||||
	} else if in.Quiet {
 | 
							contexts[name] = build.NamedContext{Path: path}
 | 
				
			||||||
		progressMode = "quiet"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	contexts, err := parseContextNames(in.Contexts)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printFunc, err := parsePrintFunc(in.PrintFunc)
 | 
						printFunc, err := parsePrintFunc(in.PrintFunc)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts := build.Options{
 | 
						opts := build.Options{
 | 
				
			||||||
@@ -70,10 +63,9 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
 | 
				
			|||||||
			InStream:       inStream,
 | 
								InStream:       inStream,
 | 
				
			||||||
			NamedContexts:  contexts,
 | 
								NamedContexts:  contexts,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		BuildArgs:     listToMap(in.BuildArgs, true),
 | 
							BuildArgs:     in.BuildArgs,
 | 
				
			||||||
		ExtraHosts:    in.ExtraHosts,
 | 
							ExtraHosts:    in.ExtraHosts,
 | 
				
			||||||
		ImageIDFile:   in.ImageIDFile,
 | 
							Labels:        in.Labels,
 | 
				
			||||||
		Labels:        listToMap(in.Labels, false),
 | 
					 | 
				
			||||||
		NetworkMode:   in.NetworkMode,
 | 
							NetworkMode:   in.NetworkMode,
 | 
				
			||||||
		NoCache:       in.Opts.NoCache,
 | 
							NoCache:       in.Opts.NoCache,
 | 
				
			||||||
		NoCacheFilter: in.NoCacheFilter,
 | 
							NoCacheFilter: in.NoCacheFilter,
 | 
				
			||||||
@@ -87,36 +79,36 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	platforms, err := platformutil.Parse(in.Platforms)
 | 
						platforms, err := platformutil.Parse(in.Platforms)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts.Platforms = platforms
 | 
						opts.Platforms = platforms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dockerConfig := config.LoadDefaultConfigFile(os.Stderr)
 | 
						dockerConfig := config.LoadDefaultConfigFile(os.Stderr)
 | 
				
			||||||
	opts.Session = append(opts.Session, authprovider.NewDockerAuthProvider(dockerConfig))
 | 
						opts.Session = append(opts.Session, authprovider.NewDockerAuthProvider(dockerConfig))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	secrets, err := buildflags.ParseSecretSpecs(in.Secrets)
 | 
						secrets, err := controllerapi.CreateSecrets(in.Secrets)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts.Session = append(opts.Session, secrets)
 | 
						opts.Session = append(opts.Session, secrets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sshSpecs := in.SSH
 | 
						sshSpecs := in.SSH
 | 
				
			||||||
	if len(sshSpecs) == 0 && buildflags.IsGitSSH(in.ContextPath) {
 | 
						if len(sshSpecs) == 0 && buildflags.IsGitSSH(in.ContextPath) {
 | 
				
			||||||
		sshSpecs = []string{"default"}
 | 
							sshSpecs = append(sshSpecs, &controllerapi.SSH{ID: "default"})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ssh, err := buildflags.ParseSSHSpecs(sshSpecs)
 | 
						ssh, err := controllerapi.CreateSSH(sshSpecs)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts.Session = append(opts.Session, ssh)
 | 
						opts.Session = append(opts.Session, ssh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outputs, err := buildflags.ParseOutputs(in.Outputs)
 | 
						outputs, err := controllerapi.CreateExports(in.Exports)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if in.Opts.ExportPush {
 | 
						if in.Opts.ExportPush {
 | 
				
			||||||
		if in.Opts.ExportLoad {
 | 
							if in.Opts.ExportLoad {
 | 
				
			||||||
			return nil, errors.Errorf("push and load may not be set together at the moment")
 | 
								return nil, nil, errors.Errorf("push and load may not be set together at the moment")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if len(outputs) == 0 {
 | 
							if len(outputs) == 0 {
 | 
				
			||||||
			outputs = []client.ExportEntry{{
 | 
								outputs = []client.ExportEntry{{
 | 
				
			||||||
@@ -130,7 +122,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
 | 
				
			|||||||
			case "image":
 | 
								case "image":
 | 
				
			||||||
				outputs[0].Attrs["push"] = "true"
 | 
									outputs[0].Attrs["push"] = "true"
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				return nil, errors.Errorf("push and %q output can't be used together", outputs[0].Type)
 | 
									return nil, nil, errors.Errorf("push and %q output can't be used together", outputs[0].Type)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -144,39 +136,20 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
 | 
				
			|||||||
			switch outputs[0].Type {
 | 
								switch outputs[0].Type {
 | 
				
			||||||
			case "docker":
 | 
								case "docker":
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				return nil, errors.Errorf("load and %q output can't be used together", outputs[0].Type)
 | 
									return nil, nil, errors.Errorf("load and %q output can't be used together", outputs[0].Type)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts.Exports = outputs
 | 
						opts.Exports = outputs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inAttests := append([]string{}, in.Attests...)
 | 
						opts.CacheFrom = controllerapi.CreateCaches(in.CacheFrom)
 | 
				
			||||||
	if in.Opts.Provenance != "" {
 | 
						opts.CacheTo = controllerapi.CreateCaches(in.CacheTo)
 | 
				
			||||||
		inAttests = append(inAttests, buildflags.CanonicalizeAttest("provenance", in.Opts.Provenance))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if in.Opts.SBOM != "" {
 | 
					 | 
				
			||||||
		inAttests = append(inAttests, buildflags.CanonicalizeAttest("sbom", in.Opts.SBOM))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	opts.Attests, err = buildflags.ParseAttests(inAttests)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cacheImports, err := buildflags.ParseCacheEntry(in.CacheFrom)
 | 
						opts.Attests = controllerapi.CreateAttestations(in.Attests)
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	opts.CacheFrom = cacheImports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cacheExports, err := buildflags.ParseCacheEntry(in.CacheTo)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	opts.CacheTo = cacheExports
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	allow, err := buildflags.ParseEntitlements(in.Allow)
 | 
						allow, err := buildflags.ParseEntitlements(in.Allow)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts.Allow = allow
 | 
						opts.Allow = allow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -191,29 +164,25 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
 | 
				
			|||||||
		builder.WithContextPathHash(contextPathHash),
 | 
							builder.WithContextPathHash(contextPathHash),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil {
 | 
						if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil {
 | 
				
			||||||
		return nil, errors.Wrapf(err, "failed to update builder last activity time")
 | 
							return nil, nil, errors.Wrapf(err, "failed to update builder last activity time")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	nodes, err := b.LoadNodes(ctx, false)
 | 
						nodes, err := b.LoadNodes(ctx, false)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	imageID, res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progressMode, in.Opts.MetadataFile, statusChan)
 | 
						resp, res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progressMode, in.Opts.MetadataFile, statusChan)
 | 
				
			||||||
	err = wrapBuildError(err, false)
 | 
						err = wrapBuildError(err, false)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return resp, res, nil
 | 
				
			||||||
	if in.Quiet {
 | 
					 | 
				
			||||||
		fmt.Println(imageID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return res, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progressMode string, metadataFile string, statusChan chan *client.SolveStatus) (imageID string, res *build.ResultContext, err error) {
 | 
					func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progressMode string, metadataFile string, statusChan chan *client.SolveStatus) (*client.SolveResponse, *build.ResultContext, error) {
 | 
				
			||||||
	ctx2, cancel := context.WithCancel(context.TODO())
 | 
						ctx2, cancel := context.WithCancel(context.TODO())
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -222,9 +191,10 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou
 | 
				
			|||||||
		fmt.Sprintf("%s:%s", ng.Driver, ng.Name),
 | 
							fmt.Sprintf("%s:%s", ng.Driver, ng.Name),
 | 
				
			||||||
	))
 | 
						))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var res *build.ResultContext
 | 
				
			||||||
	var mu sync.Mutex
 | 
						var mu sync.Mutex
 | 
				
			||||||
	var idx int
 | 
						var idx int
 | 
				
			||||||
	resp, err := build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress.Tee(printer, statusChan), func(driverIndex int, gotRes *build.ResultContext) {
 | 
						resp, err := build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress.Tee(printer, statusChan), func(driverIndex int, gotRes *build.ResultContext) {
 | 
				
			||||||
@@ -239,12 +209,12 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou
 | 
				
			|||||||
		err = err1
 | 
							err = err1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(metadataFile) > 0 && resp != nil {
 | 
						if len(metadataFile) > 0 && resp != nil {
 | 
				
			||||||
		if err := writeMetadataFile(metadataFile, decodeExporterResponse(resp[defaultTargetName].ExporterResponse)); err != nil {
 | 
							if err := writeMetadataFile(metadataFile, decodeExporterResponse(resp[defaultTargetName].ExporterResponse)); err != nil {
 | 
				
			||||||
			return "", nil, err
 | 
								return nil, nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -253,12 +223,12 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou
 | 
				
			|||||||
	for k := range resp {
 | 
						for k := range resp {
 | 
				
			||||||
		if opts[k].PrintFunc != nil {
 | 
							if opts[k].PrintFunc != nil {
 | 
				
			||||||
			if err := printResult(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil {
 | 
								if err := printResult(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil {
 | 
				
			||||||
				return "", nil, err
 | 
									return nil, nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return resp[defaultTargetName].ExporterResponse["containerimage.digest"], res, err
 | 
						return resp[defaultTargetName], res, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func printWarnings(w io.Writer, warnings []client.VertexWarning, mode string) {
 | 
					func printWarnings(w io.Writer, warnings []client.VertexWarning, mode string) {
 | 
				
			||||||
@@ -301,46 +271,6 @@ func printWarnings(w io.Writer, warnings []client.VertexWarning, mode string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func listToMap(values []string, defaultEnv bool) map[string]string {
 | 
					 | 
				
			||||||
	result := make(map[string]string, len(values))
 | 
					 | 
				
			||||||
	for _, value := range values {
 | 
					 | 
				
			||||||
		kv := strings.SplitN(value, "=", 2)
 | 
					 | 
				
			||||||
		if len(kv) == 1 {
 | 
					 | 
				
			||||||
			if defaultEnv {
 | 
					 | 
				
			||||||
				v, ok := os.LookupEnv(kv[0])
 | 
					 | 
				
			||||||
				if ok {
 | 
					 | 
				
			||||||
					result[kv[0]] = v
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				result[kv[0]] = ""
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			result[kv[0]] = kv[1]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func parseContextNames(values []string) (map[string]build.NamedContext, error) {
 | 
					 | 
				
			||||||
	if len(values) == 0 {
 | 
					 | 
				
			||||||
		return nil, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	result := make(map[string]build.NamedContext, len(values))
 | 
					 | 
				
			||||||
	for _, value := range values {
 | 
					 | 
				
			||||||
		kv := strings.SplitN(value, "=", 2)
 | 
					 | 
				
			||||||
		if len(kv) != 2 {
 | 
					 | 
				
			||||||
			return nil, errors.Errorf("invalid context value: %s, expected key=value", value)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		named, err := reference.ParseNormalizedNamed(kv[0])
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, errors.Wrapf(err, "invalid context name %s", kv[0])
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		name := strings.TrimSuffix(reference.FamiliarString(named), ":latest")
 | 
					 | 
				
			||||||
		result[name] = build.NamedContext{Path: kv[1]}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func parsePrintFunc(str string) (*build.PrintFunc, error) {
 | 
					func parsePrintFunc(str string) (*build.PrintFunc, error) {
 | 
				
			||||||
	if str == "" {
 | 
						if str == "" {
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,14 +6,15 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/containerd/console"
 | 
						"github.com/containerd/console"
 | 
				
			||||||
	controllerapi "github.com/docker/buildx/controller/pb"
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/client"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BuildxController interface {
 | 
					type BuildxController interface {
 | 
				
			||||||
	Invoke(ctx context.Context, ref string, options controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error
 | 
						Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (ref string, resp *client.SolveResponse, err error)
 | 
				
			||||||
	Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (ref string, err error)
 | 
						Invoke(ctx context.Context, ref string, options controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) (err error)
 | 
				
			||||||
	Kill(ctx context.Context) error
 | 
						Kill(ctx context.Context) error
 | 
				
			||||||
	Close() error
 | 
						Close() error
 | 
				
			||||||
	List(ctx context.Context) (res []string, _ error)
 | 
						List(ctx context.Context) (refs []string, _ error)
 | 
				
			||||||
	Disconnect(ctx context.Context, ref string) error
 | 
						Disconnect(ctx context.Context, ref string) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ import (
 | 
				
			|||||||
	"github.com/docker/buildx/controller/control"
 | 
						"github.com/docker/buildx/controller/control"
 | 
				
			||||||
	controllerapi "github.com/docker/buildx/controller/pb"
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
	"github.com/docker/cli/cli/command"
 | 
						"github.com/docker/cli/cli/command"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/client"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,6 +27,15 @@ type localController struct {
 | 
				
			|||||||
	resultCtx *build.ResultContext
 | 
						resultCtx *build.ResultContext
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *localController) Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, *client.SolveResponse, error) {
 | 
				
			||||||
 | 
						resp, res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, progressMode, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.resultCtx = res
 | 
				
			||||||
 | 
						return b.ref, resp, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *localController) Invoke(ctx context.Context, ref string, cfg controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error {
 | 
					func (b *localController) Invoke(ctx context.Context, ref string, cfg controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error {
 | 
				
			||||||
	if ref != b.ref {
 | 
						if ref != b.ref {
 | 
				
			||||||
		return errors.Errorf("unknown ref %q", ref)
 | 
							return errors.Errorf("unknown ref %q", ref)
 | 
				
			||||||
@@ -52,15 +62,6 @@ func (b *localController) Invoke(ctx context.Context, ref string, cfg controller
 | 
				
			|||||||
	return build.Invoke(ctx, ccfg)
 | 
						return build.Invoke(ctx, ccfg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *localController) Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, error) {
 | 
					 | 
				
			||||||
	res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, progressMode, nil)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	b.resultCtx = res
 | 
					 | 
				
			||||||
	return b.ref, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (b *localController) Kill(context.Context) error {
 | 
					func (b *localController) Kill(context.Context) error {
 | 
				
			||||||
	return nil // nop
 | 
						return nil // nop
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								controller/pb/attest.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								controller/pb/attest.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					package pb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateAttestations(attests []*Attest) map[string]*string {
 | 
				
			||||||
 | 
						result := map[string]*string{}
 | 
				
			||||||
 | 
						for _, attest := range attests {
 | 
				
			||||||
 | 
							// ignore duplicates
 | 
				
			||||||
 | 
							if _, ok := result[attest.Type]; ok {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if attest.Disabled {
 | 
				
			||||||
 | 
								result[attest.Type] = nil
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							attrs := attest.Attrs
 | 
				
			||||||
 | 
							result[attest.Type] = &attrs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								controller/pb/cache.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								controller/pb/cache.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					package pb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/moby/buildkit/client"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateCaches(entries []*CacheOptionsEntry) []client.CacheOptionsEntry {
 | 
				
			||||||
 | 
						var outs []client.CacheOptionsEntry
 | 
				
			||||||
 | 
						if len(entries) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, entry := range entries {
 | 
				
			||||||
 | 
							out := client.CacheOptionsEntry{
 | 
				
			||||||
 | 
								Type:  entry.Type,
 | 
				
			||||||
 | 
								Attrs: map[string]string{},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for k, v := range entry.Attrs {
 | 
				
			||||||
 | 
								out.Attrs[k] = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							outs = append(outs, out)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return outs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -72,35 +72,32 @@ func (m *BuildRequest) GetOptions() *BuildOptions {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BuildOptions struct {
 | 
					type BuildOptions struct {
 | 
				
			||||||
	ContextPath    string     `protobuf:"bytes,1,opt,name=ContextPath,proto3" json:"ContextPath,omitempty"`
 | 
						ContextPath          string               `protobuf:"bytes,1,opt,name=ContextPath,proto3" json:"ContextPath,omitempty"`
 | 
				
			||||||
	DockerfileName string     `protobuf:"bytes,2,opt,name=DockerfileName,proto3" json:"DockerfileName,omitempty"`
 | 
						DockerfileName       string               `protobuf:"bytes,2,opt,name=DockerfileName,proto3" json:"DockerfileName,omitempty"`
 | 
				
			||||||
	PrintFunc      string     `protobuf:"bytes,3,opt,name=PrintFunc,proto3" json:"PrintFunc,omitempty"`
 | 
						PrintFunc            string               `protobuf:"bytes,3,opt,name=PrintFunc,proto3" json:"PrintFunc,omitempty"`
 | 
				
			||||||
	Allow          []string   `protobuf:"bytes,4,rep,name=Allow,proto3" json:"Allow,omitempty"`
 | 
						NamedContexts        map[string]string    `protobuf:"bytes,4,rep,name=NamedContexts,proto3" json:"NamedContexts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
	Attests        []string   `protobuf:"bytes,5,rep,name=Attests,proto3" json:"Attests,omitempty"`
 | 
						Allow                []string             `protobuf:"bytes,5,rep,name=Allow,proto3" json:"Allow,omitempty"`
 | 
				
			||||||
	BuildArgs      []string   `protobuf:"bytes,6,rep,name=BuildArgs,proto3" json:"BuildArgs,omitempty"`
 | 
						Attests              []*Attest            `protobuf:"bytes,6,rep,name=Attests,proto3" json:"Attests,omitempty"`
 | 
				
			||||||
	CacheFrom      []string   `protobuf:"bytes,7,rep,name=CacheFrom,proto3" json:"CacheFrom,omitempty"`
 | 
						BuildArgs            map[string]string    `protobuf:"bytes,7,rep,name=BuildArgs,proto3" json:"BuildArgs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
	CacheTo        []string   `protobuf:"bytes,8,rep,name=CacheTo,proto3" json:"CacheTo,omitempty"`
 | 
						CacheFrom            []*CacheOptionsEntry `protobuf:"bytes,8,rep,name=CacheFrom,proto3" json:"CacheFrom,omitempty"`
 | 
				
			||||||
	CgroupParent   string     `protobuf:"bytes,9,opt,name=CgroupParent,proto3" json:"CgroupParent,omitempty"`
 | 
						CacheTo              []*CacheOptionsEntry `protobuf:"bytes,9,rep,name=CacheTo,proto3" json:"CacheTo,omitempty"`
 | 
				
			||||||
	Contexts       []string   `protobuf:"bytes,10,rep,name=Contexts,proto3" json:"Contexts,omitempty"`
 | 
						CgroupParent         string               `protobuf:"bytes,10,opt,name=CgroupParent,proto3" json:"CgroupParent,omitempty"`
 | 
				
			||||||
	ExtraHosts     []string   `protobuf:"bytes,11,rep,name=ExtraHosts,proto3" json:"ExtraHosts,omitempty"`
 | 
						Exports              []*ExportEntry       `protobuf:"bytes,11,rep,name=Exports,proto3" json:"Exports,omitempty"`
 | 
				
			||||||
	ImageIDFile    string     `protobuf:"bytes,12,opt,name=ImageIDFile,proto3" json:"ImageIDFile,omitempty"`
 | 
						ExtraHosts           []string             `protobuf:"bytes,12,rep,name=ExtraHosts,proto3" json:"ExtraHosts,omitempty"`
 | 
				
			||||||
	Labels         []string   `protobuf:"bytes,13,rep,name=Labels,proto3" json:"Labels,omitempty"`
 | 
						Labels               map[string]string    `protobuf:"bytes,13,rep,name=Labels,proto3" json:"Labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
	NetworkMode    string     `protobuf:"bytes,14,opt,name=NetworkMode,proto3" json:"NetworkMode,omitempty"`
 | 
						NetworkMode          string               `protobuf:"bytes,14,opt,name=NetworkMode,proto3" json:"NetworkMode,omitempty"`
 | 
				
			||||||
	NoCacheFilter  []string   `protobuf:"bytes,15,rep,name=NoCacheFilter,proto3" json:"NoCacheFilter,omitempty"`
 | 
						NoCacheFilter        []string             `protobuf:"bytes,15,rep,name=NoCacheFilter,proto3" json:"NoCacheFilter,omitempty"`
 | 
				
			||||||
	Outputs        []string   `protobuf:"bytes,16,rep,name=Outputs,proto3" json:"Outputs,omitempty"`
 | 
						Platforms            []string             `protobuf:"bytes,16,rep,name=Platforms,proto3" json:"Platforms,omitempty"`
 | 
				
			||||||
	Platforms      []string   `protobuf:"bytes,17,rep,name=Platforms,proto3" json:"Platforms,omitempty"`
 | 
						Secrets              []*Secret            `protobuf:"bytes,17,rep,name=Secrets,proto3" json:"Secrets,omitempty"`
 | 
				
			||||||
	Quiet          bool       `protobuf:"varint,18,opt,name=Quiet,proto3" json:"Quiet,omitempty"`
 | 
						ShmSize              int64                `protobuf:"varint,18,opt,name=ShmSize,proto3" json:"ShmSize,omitempty"`
 | 
				
			||||||
	Secrets        []string   `protobuf:"bytes,19,rep,name=Secrets,proto3" json:"Secrets,omitempty"`
 | 
						SSH                  []*SSH               `protobuf:"bytes,19,rep,name=SSH,proto3" json:"SSH,omitempty"`
 | 
				
			||||||
	ShmSize        int64      `protobuf:"varint,20,opt,name=ShmSize,proto3" json:"ShmSize,omitempty"`
 | 
						Tags                 []string             `protobuf:"bytes,20,rep,name=Tags,proto3" json:"Tags,omitempty"`
 | 
				
			||||||
	SSH            []string   `protobuf:"bytes,21,rep,name=SSH,proto3" json:"SSH,omitempty"`
 | 
						Target               string               `protobuf:"bytes,21,opt,name=Target,proto3" json:"Target,omitempty"`
 | 
				
			||||||
	Tags           []string   `protobuf:"bytes,22,rep,name=Tags,proto3" json:"Tags,omitempty"`
 | 
						Ulimits              *UlimitOpt           `protobuf:"bytes,22,opt,name=Ulimits,proto3" json:"Ulimits,omitempty"`
 | 
				
			||||||
	Target         string     `protobuf:"bytes,23,opt,name=Target,proto3" json:"Target,omitempty"`
 | 
						Opts                 *CommonOptions       `protobuf:"bytes,24,opt,name=Opts,proto3" json:"Opts,omitempty"`
 | 
				
			||||||
	Ulimits        *UlimitOpt `protobuf:"bytes,24,opt,name=Ulimits,proto3" json:"Ulimits,omitempty"`
 | 
						XXX_NoUnkeyedLiteral struct{}             `json:"-"`
 | 
				
			||||||
	// string Invoke: provided via Invoke API
 | 
						XXX_unrecognized     []byte               `json:"-"`
 | 
				
			||||||
	Opts                 *CommonOptions `protobuf:"bytes,25,opt,name=Opts,proto3" json:"Opts,omitempty"`
 | 
						XXX_sizecache        int32                `json:"-"`
 | 
				
			||||||
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
 | 
					 | 
				
			||||||
	XXX_unrecognized     []byte         `json:"-"`
 | 
					 | 
				
			||||||
	XXX_sizecache        int32          `json:"-"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) Reset()         { *m = BuildOptions{} }
 | 
					func (m *BuildOptions) Reset()         { *m = BuildOptions{} }
 | 
				
			||||||
@@ -148,6 +145,13 @@ func (m *BuildOptions) GetPrintFunc() string {
 | 
				
			|||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *BuildOptions) GetNamedContexts() map[string]string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.NamedContexts
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetAllow() []string {
 | 
					func (m *BuildOptions) GetAllow() []string {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Allow
 | 
							return m.Allow
 | 
				
			||||||
@@ -155,28 +159,28 @@ func (m *BuildOptions) GetAllow() []string {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetAttests() []string {
 | 
					func (m *BuildOptions) GetAttests() []*Attest {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Attests
 | 
							return m.Attests
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetBuildArgs() []string {
 | 
					func (m *BuildOptions) GetBuildArgs() map[string]string {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.BuildArgs
 | 
							return m.BuildArgs
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetCacheFrom() []string {
 | 
					func (m *BuildOptions) GetCacheFrom() []*CacheOptionsEntry {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.CacheFrom
 | 
							return m.CacheFrom
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetCacheTo() []string {
 | 
					func (m *BuildOptions) GetCacheTo() []*CacheOptionsEntry {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.CacheTo
 | 
							return m.CacheTo
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -190,9 +194,9 @@ func (m *BuildOptions) GetCgroupParent() string {
 | 
				
			|||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetContexts() []string {
 | 
					func (m *BuildOptions) GetExports() []*ExportEntry {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Contexts
 | 
							return m.Exports
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -204,14 +208,7 @@ func (m *BuildOptions) GetExtraHosts() []string {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetImageIDFile() string {
 | 
					func (m *BuildOptions) GetLabels() map[string]string {
 | 
				
			||||||
	if m != nil {
 | 
					 | 
				
			||||||
		return m.ImageIDFile
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *BuildOptions) GetLabels() []string {
 | 
					 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Labels
 | 
							return m.Labels
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -232,13 +229,6 @@ func (m *BuildOptions) GetNoCacheFilter() []string {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetOutputs() []string {
 | 
					 | 
				
			||||||
	if m != nil {
 | 
					 | 
				
			||||||
		return m.Outputs
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *BuildOptions) GetPlatforms() []string {
 | 
					func (m *BuildOptions) GetPlatforms() []string {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Platforms
 | 
							return m.Platforms
 | 
				
			||||||
@@ -246,14 +236,7 @@ func (m *BuildOptions) GetPlatforms() []string {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetQuiet() bool {
 | 
					func (m *BuildOptions) GetSecrets() []*Secret {
 | 
				
			||||||
	if m != nil {
 | 
					 | 
				
			||||||
		return m.Quiet
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *BuildOptions) GetSecrets() []string {
 | 
					 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Secrets
 | 
							return m.Secrets
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -267,7 +250,7 @@ func (m *BuildOptions) GetShmSize() int64 {
 | 
				
			|||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildOptions) GetSSH() []string {
 | 
					func (m *BuildOptions) GetSSH() []*SSH {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.SSH
 | 
							return m.SSH
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -302,6 +285,260 @@ func (m *BuildOptions) GetOpts() *CommonOptions {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ExportEntry struct {
 | 
				
			||||||
 | 
						Type                 string            `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"`
 | 
				
			||||||
 | 
						Attrs                map[string]string `protobuf:"bytes,2,rep,name=Attrs,proto3" json:"Attrs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
 | 
						Destination          string            `protobuf:"bytes,3,opt,name=Destination,proto3" json:"Destination,omitempty"`
 | 
				
			||||||
 | 
						XXX_NoUnkeyedLiteral struct{}          `json:"-"`
 | 
				
			||||||
 | 
						XXX_unrecognized     []byte            `json:"-"`
 | 
				
			||||||
 | 
						XXX_sizecache        int32             `json:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ExportEntry) Reset()         { *m = ExportEntry{} }
 | 
				
			||||||
 | 
					func (m *ExportEntry) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*ExportEntry) ProtoMessage()    {}
 | 
				
			||||||
 | 
					func (*ExportEntry) Descriptor() ([]byte, []int) {
 | 
				
			||||||
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{2}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *ExportEntry) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
 | 
						return xxx_messageInfo_ExportEntry.Unmarshal(m, b)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *ExportEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
				
			||||||
 | 
						return xxx_messageInfo_ExportEntry.Marshal(b, m, deterministic)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *ExportEntry) XXX_Merge(src proto.Message) {
 | 
				
			||||||
 | 
						xxx_messageInfo_ExportEntry.Merge(m, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *ExportEntry) XXX_Size() int {
 | 
				
			||||||
 | 
						return xxx_messageInfo_ExportEntry.Size(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *ExportEntry) XXX_DiscardUnknown() {
 | 
				
			||||||
 | 
						xxx_messageInfo_ExportEntry.DiscardUnknown(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var xxx_messageInfo_ExportEntry proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ExportEntry) GetType() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Type
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ExportEntry) GetAttrs() map[string]string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Attrs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ExportEntry) GetDestination() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Destination
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CacheOptionsEntry struct {
 | 
				
			||||||
 | 
						Type                 string            `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"`
 | 
				
			||||||
 | 
						Attrs                map[string]string `protobuf:"bytes,2,rep,name=Attrs,proto3" json:"Attrs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
 | 
						XXX_NoUnkeyedLiteral struct{}          `json:"-"`
 | 
				
			||||||
 | 
						XXX_unrecognized     []byte            `json:"-"`
 | 
				
			||||||
 | 
						XXX_sizecache        int32             `json:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) Reset()         { *m = CacheOptionsEntry{} }
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*CacheOptionsEntry) ProtoMessage()    {}
 | 
				
			||||||
 | 
					func (*CacheOptionsEntry) Descriptor() ([]byte, []int) {
 | 
				
			||||||
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{3}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
 | 
						return xxx_messageInfo_CacheOptionsEntry.Unmarshal(m, b)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
				
			||||||
 | 
						return xxx_messageInfo_CacheOptionsEntry.Marshal(b, m, deterministic)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) XXX_Merge(src proto.Message) {
 | 
				
			||||||
 | 
						xxx_messageInfo_CacheOptionsEntry.Merge(m, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) XXX_Size() int {
 | 
				
			||||||
 | 
						return xxx_messageInfo_CacheOptionsEntry.Size(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) XXX_DiscardUnknown() {
 | 
				
			||||||
 | 
						xxx_messageInfo_CacheOptionsEntry.DiscardUnknown(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var xxx_messageInfo_CacheOptionsEntry proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) GetType() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Type
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *CacheOptionsEntry) GetAttrs() map[string]string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Attrs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Attest struct {
 | 
				
			||||||
 | 
						Type                 string   `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"`
 | 
				
			||||||
 | 
						Disabled             bool     `protobuf:"varint,2,opt,name=Disabled,proto3" json:"Disabled,omitempty"`
 | 
				
			||||||
 | 
						Attrs                string   `protobuf:"bytes,3,opt,name=Attrs,proto3" json:"Attrs,omitempty"`
 | 
				
			||||||
 | 
						XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
				
			||||||
 | 
						XXX_unrecognized     []byte   `json:"-"`
 | 
				
			||||||
 | 
						XXX_sizecache        int32    `json:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Attest) Reset()         { *m = Attest{} }
 | 
				
			||||||
 | 
					func (m *Attest) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*Attest) ProtoMessage()    {}
 | 
				
			||||||
 | 
					func (*Attest) Descriptor() ([]byte, []int) {
 | 
				
			||||||
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{4}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Attest) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
 | 
						return xxx_messageInfo_Attest.Unmarshal(m, b)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Attest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
				
			||||||
 | 
						return xxx_messageInfo_Attest.Marshal(b, m, deterministic)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Attest) XXX_Merge(src proto.Message) {
 | 
				
			||||||
 | 
						xxx_messageInfo_Attest.Merge(m, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Attest) XXX_Size() int {
 | 
				
			||||||
 | 
						return xxx_messageInfo_Attest.Size(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Attest) XXX_DiscardUnknown() {
 | 
				
			||||||
 | 
						xxx_messageInfo_Attest.DiscardUnknown(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var xxx_messageInfo_Attest proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Attest) GetType() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Type
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Attest) GetDisabled() bool {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Disabled
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Attest) GetAttrs() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Attrs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SSH struct {
 | 
				
			||||||
 | 
						ID                   string   `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
 | 
				
			||||||
 | 
						Paths                []string `protobuf:"bytes,2,rep,name=Paths,proto3" json:"Paths,omitempty"`
 | 
				
			||||||
 | 
						XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
				
			||||||
 | 
						XXX_unrecognized     []byte   `json:"-"`
 | 
				
			||||||
 | 
						XXX_sizecache        int32    `json:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *SSH) Reset()         { *m = SSH{} }
 | 
				
			||||||
 | 
					func (m *SSH) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*SSH) ProtoMessage()    {}
 | 
				
			||||||
 | 
					func (*SSH) Descriptor() ([]byte, []int) {
 | 
				
			||||||
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{5}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *SSH) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
 | 
						return xxx_messageInfo_SSH.Unmarshal(m, b)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *SSH) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
				
			||||||
 | 
						return xxx_messageInfo_SSH.Marshal(b, m, deterministic)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *SSH) XXX_Merge(src proto.Message) {
 | 
				
			||||||
 | 
						xxx_messageInfo_SSH.Merge(m, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *SSH) XXX_Size() int {
 | 
				
			||||||
 | 
						return xxx_messageInfo_SSH.Size(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *SSH) XXX_DiscardUnknown() {
 | 
				
			||||||
 | 
						xxx_messageInfo_SSH.DiscardUnknown(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var xxx_messageInfo_SSH proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *SSH) GetID() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ID
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *SSH) GetPaths() []string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Paths
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Secret struct {
 | 
				
			||||||
 | 
						ID                   string   `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
 | 
				
			||||||
 | 
						FilePath             string   `protobuf:"bytes,2,opt,name=FilePath,proto3" json:"FilePath,omitempty"`
 | 
				
			||||||
 | 
						Env                  string   `protobuf:"bytes,3,opt,name=Env,proto3" json:"Env,omitempty"`
 | 
				
			||||||
 | 
						XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
				
			||||||
 | 
						XXX_unrecognized     []byte   `json:"-"`
 | 
				
			||||||
 | 
						XXX_sizecache        int32    `json:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Secret) Reset()         { *m = Secret{} }
 | 
				
			||||||
 | 
					func (m *Secret) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*Secret) ProtoMessage()    {}
 | 
				
			||||||
 | 
					func (*Secret) Descriptor() ([]byte, []int) {
 | 
				
			||||||
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{6}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Secret) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
 | 
						return xxx_messageInfo_Secret.Unmarshal(m, b)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Secret) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
 | 
				
			||||||
 | 
						return xxx_messageInfo_Secret.Marshal(b, m, deterministic)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Secret) XXX_Merge(src proto.Message) {
 | 
				
			||||||
 | 
						xxx_messageInfo_Secret.Merge(m, src)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Secret) XXX_Size() int {
 | 
				
			||||||
 | 
						return xxx_messageInfo_Secret.Size(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (m *Secret) XXX_DiscardUnknown() {
 | 
				
			||||||
 | 
						xxx_messageInfo_Secret.DiscardUnknown(m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var xxx_messageInfo_Secret proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Secret) GetID() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ID
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Secret) GetFilePath() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.FilePath
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Secret) GetEnv() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Env
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UlimitOpt struct {
 | 
					type UlimitOpt struct {
 | 
				
			||||||
	Values               map[string]*Ulimit `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
						Values               map[string]*Ulimit `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
 | 
						XXX_NoUnkeyedLiteral struct{}           `json:"-"`
 | 
				
			||||||
@@ -313,7 +550,7 @@ func (m *UlimitOpt) Reset()         { *m = UlimitOpt{} }
 | 
				
			|||||||
func (m *UlimitOpt) String() string { return proto.CompactTextString(m) }
 | 
					func (m *UlimitOpt) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*UlimitOpt) ProtoMessage()    {}
 | 
					func (*UlimitOpt) ProtoMessage()    {}
 | 
				
			||||||
func (*UlimitOpt) Descriptor() ([]byte, []int) {
 | 
					func (*UlimitOpt) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{2}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{7}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *UlimitOpt) XXX_Unmarshal(b []byte) error {
 | 
					func (m *UlimitOpt) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_UlimitOpt.Unmarshal(m, b)
 | 
						return xxx_messageInfo_UlimitOpt.Unmarshal(m, b)
 | 
				
			||||||
@@ -353,7 +590,7 @@ func (m *Ulimit) Reset()         { *m = Ulimit{} }
 | 
				
			|||||||
func (m *Ulimit) String() string { return proto.CompactTextString(m) }
 | 
					func (m *Ulimit) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*Ulimit) ProtoMessage()    {}
 | 
					func (*Ulimit) ProtoMessage()    {}
 | 
				
			||||||
func (*Ulimit) Descriptor() ([]byte, []int) {
 | 
					func (*Ulimit) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{3}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{8}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *Ulimit) XXX_Unmarshal(b []byte) error {
 | 
					func (m *Ulimit) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_Ulimit.Unmarshal(m, b)
 | 
						return xxx_messageInfo_Ulimit.Unmarshal(m, b)
 | 
				
			||||||
@@ -402,8 +639,6 @@ type CommonOptions struct {
 | 
				
			|||||||
	Pull                 bool     `protobuf:"varint,4,opt,name=Pull,proto3" json:"Pull,omitempty"`
 | 
						Pull                 bool     `protobuf:"varint,4,opt,name=Pull,proto3" json:"Pull,omitempty"`
 | 
				
			||||||
	ExportPush           bool     `protobuf:"varint,5,opt,name=ExportPush,proto3" json:"ExportPush,omitempty"`
 | 
						ExportPush           bool     `protobuf:"varint,5,opt,name=ExportPush,proto3" json:"ExportPush,omitempty"`
 | 
				
			||||||
	ExportLoad           bool     `protobuf:"varint,6,opt,name=ExportLoad,proto3" json:"ExportLoad,omitempty"`
 | 
						ExportLoad           bool     `protobuf:"varint,6,opt,name=ExportLoad,proto3" json:"ExportLoad,omitempty"`
 | 
				
			||||||
	SBOM                 string   `protobuf:"bytes,7,opt,name=SBOM,proto3" json:"SBOM,omitempty"`
 | 
					 | 
				
			||||||
	Provenance           string   `protobuf:"bytes,8,opt,name=Provenance,proto3" json:"Provenance,omitempty"`
 | 
					 | 
				
			||||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
						XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
				
			||||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
						XXX_unrecognized     []byte   `json:"-"`
 | 
				
			||||||
	XXX_sizecache        int32    `json:"-"`
 | 
						XXX_sizecache        int32    `json:"-"`
 | 
				
			||||||
@@ -413,7 +648,7 @@ func (m *CommonOptions) Reset()         { *m = CommonOptions{} }
 | 
				
			|||||||
func (m *CommonOptions) String() string { return proto.CompactTextString(m) }
 | 
					func (m *CommonOptions) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*CommonOptions) ProtoMessage()    {}
 | 
					func (*CommonOptions) ProtoMessage()    {}
 | 
				
			||||||
func (*CommonOptions) Descriptor() ([]byte, []int) {
 | 
					func (*CommonOptions) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{4}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{9}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *CommonOptions) XXX_Unmarshal(b []byte) error {
 | 
					func (m *CommonOptions) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_CommonOptions.Unmarshal(m, b)
 | 
						return xxx_messageInfo_CommonOptions.Unmarshal(m, b)
 | 
				
			||||||
@@ -475,31 +710,18 @@ func (m *CommonOptions) GetExportLoad() bool {
 | 
				
			|||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *CommonOptions) GetSBOM() string {
 | 
					 | 
				
			||||||
	if m != nil {
 | 
					 | 
				
			||||||
		return m.SBOM
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *CommonOptions) GetProvenance() string {
 | 
					 | 
				
			||||||
	if m != nil {
 | 
					 | 
				
			||||||
		return m.Provenance
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type BuildResponse struct {
 | 
					type BuildResponse struct {
 | 
				
			||||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
						ExporterResponse     map[string]string `protobuf:"bytes,1,rep,name=ExporterResponse,proto3" json:"ExporterResponse,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 | 
				
			||||||
	XXX_unrecognized     []byte   `json:"-"`
 | 
						XXX_NoUnkeyedLiteral struct{}          `json:"-"`
 | 
				
			||||||
	XXX_sizecache        int32    `json:"-"`
 | 
						XXX_unrecognized     []byte            `json:"-"`
 | 
				
			||||||
 | 
						XXX_sizecache        int32             `json:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *BuildResponse) Reset()         { *m = BuildResponse{} }
 | 
					func (m *BuildResponse) Reset()         { *m = BuildResponse{} }
 | 
				
			||||||
func (m *BuildResponse) String() string { return proto.CompactTextString(m) }
 | 
					func (m *BuildResponse) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*BuildResponse) ProtoMessage()    {}
 | 
					func (*BuildResponse) ProtoMessage()    {}
 | 
				
			||||||
func (*BuildResponse) Descriptor() ([]byte, []int) {
 | 
					func (*BuildResponse) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{5}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{10}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *BuildResponse) XXX_Unmarshal(b []byte) error {
 | 
					func (m *BuildResponse) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_BuildResponse.Unmarshal(m, b)
 | 
						return xxx_messageInfo_BuildResponse.Unmarshal(m, b)
 | 
				
			||||||
@@ -519,6 +741,13 @@ func (m *BuildResponse) XXX_DiscardUnknown() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var xxx_messageInfo_BuildResponse proto.InternalMessageInfo
 | 
					var xxx_messageInfo_BuildResponse proto.InternalMessageInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *BuildResponse) GetExporterResponse() map[string]string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ExporterResponse
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type DisconnectRequest struct {
 | 
					type DisconnectRequest struct {
 | 
				
			||||||
	Ref                  string   `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
 | 
						Ref                  string   `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
 | 
				
			||||||
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
						XXX_NoUnkeyedLiteral struct{} `json:"-"`
 | 
				
			||||||
@@ -530,7 +759,7 @@ func (m *DisconnectRequest) Reset()         { *m = DisconnectRequest{} }
 | 
				
			|||||||
func (m *DisconnectRequest) String() string { return proto.CompactTextString(m) }
 | 
					func (m *DisconnectRequest) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*DisconnectRequest) ProtoMessage()    {}
 | 
					func (*DisconnectRequest) ProtoMessage()    {}
 | 
				
			||||||
func (*DisconnectRequest) Descriptor() ([]byte, []int) {
 | 
					func (*DisconnectRequest) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{6}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{11}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *DisconnectRequest) XXX_Unmarshal(b []byte) error {
 | 
					func (m *DisconnectRequest) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_DisconnectRequest.Unmarshal(m, b)
 | 
						return xxx_messageInfo_DisconnectRequest.Unmarshal(m, b)
 | 
				
			||||||
@@ -567,7 +796,7 @@ func (m *DisconnectResponse) Reset()         { *m = DisconnectResponse{} }
 | 
				
			|||||||
func (m *DisconnectResponse) String() string { return proto.CompactTextString(m) }
 | 
					func (m *DisconnectResponse) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*DisconnectResponse) ProtoMessage()    {}
 | 
					func (*DisconnectResponse) ProtoMessage()    {}
 | 
				
			||||||
func (*DisconnectResponse) Descriptor() ([]byte, []int) {
 | 
					func (*DisconnectResponse) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{7}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{12}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *DisconnectResponse) XXX_Unmarshal(b []byte) error {
 | 
					func (m *DisconnectResponse) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_DisconnectResponse.Unmarshal(m, b)
 | 
						return xxx_messageInfo_DisconnectResponse.Unmarshal(m, b)
 | 
				
			||||||
@@ -598,7 +827,7 @@ func (m *ListRequest) Reset()         { *m = ListRequest{} }
 | 
				
			|||||||
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
 | 
					func (m *ListRequest) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*ListRequest) ProtoMessage()    {}
 | 
					func (*ListRequest) ProtoMessage()    {}
 | 
				
			||||||
func (*ListRequest) Descriptor() ([]byte, []int) {
 | 
					func (*ListRequest) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{8}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{13}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
 | 
					func (m *ListRequest) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_ListRequest.Unmarshal(m, b)
 | 
						return xxx_messageInfo_ListRequest.Unmarshal(m, b)
 | 
				
			||||||
@@ -636,7 +865,7 @@ func (m *ListResponse) Reset()         { *m = ListResponse{} }
 | 
				
			|||||||
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
 | 
					func (m *ListResponse) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*ListResponse) ProtoMessage()    {}
 | 
					func (*ListResponse) ProtoMessage()    {}
 | 
				
			||||||
func (*ListResponse) Descriptor() ([]byte, []int) {
 | 
					func (*ListResponse) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{9}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{14}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
 | 
					func (m *ListResponse) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_ListResponse.Unmarshal(m, b)
 | 
						return xxx_messageInfo_ListResponse.Unmarshal(m, b)
 | 
				
			||||||
@@ -677,7 +906,7 @@ func (m *InputMessage) Reset()         { *m = InputMessage{} }
 | 
				
			|||||||
func (m *InputMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *InputMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*InputMessage) ProtoMessage()    {}
 | 
					func (*InputMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*InputMessage) Descriptor() ([]byte, []int) {
 | 
					func (*InputMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{10}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{15}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *InputMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *InputMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_InputMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_InputMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -751,7 +980,7 @@ func (m *InputInitMessage) Reset()         { *m = InputInitMessage{} }
 | 
				
			|||||||
func (m *InputInitMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *InputInitMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*InputInitMessage) ProtoMessage()    {}
 | 
					func (*InputInitMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*InputInitMessage) Descriptor() ([]byte, []int) {
 | 
					func (*InputInitMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{11}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{16}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *InputInitMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *InputInitMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_InputInitMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_InputInitMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -790,7 +1019,7 @@ func (m *DataMessage) Reset()         { *m = DataMessage{} }
 | 
				
			|||||||
func (m *DataMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *DataMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*DataMessage) ProtoMessage()    {}
 | 
					func (*DataMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*DataMessage) Descriptor() ([]byte, []int) {
 | 
					func (*DataMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{12}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{17}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *DataMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *DataMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_DataMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_DataMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -834,7 +1063,7 @@ func (m *InputResponse) Reset()         { *m = InputResponse{} }
 | 
				
			|||||||
func (m *InputResponse) String() string { return proto.CompactTextString(m) }
 | 
					func (m *InputResponse) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*InputResponse) ProtoMessage()    {}
 | 
					func (*InputResponse) ProtoMessage()    {}
 | 
				
			||||||
func (*InputResponse) Descriptor() ([]byte, []int) {
 | 
					func (*InputResponse) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{13}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{18}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *InputResponse) XXX_Unmarshal(b []byte) error {
 | 
					func (m *InputResponse) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_InputResponse.Unmarshal(m, b)
 | 
						return xxx_messageInfo_InputResponse.Unmarshal(m, b)
 | 
				
			||||||
@@ -870,7 +1099,7 @@ func (m *Message) Reset()         { *m = Message{} }
 | 
				
			|||||||
func (m *Message) String() string { return proto.CompactTextString(m) }
 | 
					func (m *Message) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*Message) ProtoMessage()    {}
 | 
					func (*Message) ProtoMessage()    {}
 | 
				
			||||||
func (*Message) Descriptor() ([]byte, []int) {
 | 
					func (*Message) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{14}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{19}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *Message) XXX_Unmarshal(b []byte) error {
 | 
					func (m *Message) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_Message.Unmarshal(m, b)
 | 
						return xxx_messageInfo_Message.Unmarshal(m, b)
 | 
				
			||||||
@@ -969,7 +1198,7 @@ func (m *InitMessage) Reset()         { *m = InitMessage{} }
 | 
				
			|||||||
func (m *InitMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *InitMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*InitMessage) ProtoMessage()    {}
 | 
					func (*InitMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*InitMessage) Descriptor() ([]byte, []int) {
 | 
					func (*InitMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{15}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{20}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *InitMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *InitMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_InitMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_InitMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -1021,7 +1250,7 @@ func (m *ContainerConfig) Reset()         { *m = ContainerConfig{} }
 | 
				
			|||||||
func (m *ContainerConfig) String() string { return proto.CompactTextString(m) }
 | 
					func (m *ContainerConfig) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*ContainerConfig) ProtoMessage()    {}
 | 
					func (*ContainerConfig) ProtoMessage()    {}
 | 
				
			||||||
func (*ContainerConfig) Descriptor() ([]byte, []int) {
 | 
					func (*ContainerConfig) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{16}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{21}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *ContainerConfig) XXX_Unmarshal(b []byte) error {
 | 
					func (m *ContainerConfig) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_ContainerConfig.Unmarshal(m, b)
 | 
						return xxx_messageInfo_ContainerConfig.Unmarshal(m, b)
 | 
				
			||||||
@@ -1110,7 +1339,7 @@ func (m *FdMessage) Reset()         { *m = FdMessage{} }
 | 
				
			|||||||
func (m *FdMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *FdMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*FdMessage) ProtoMessage()    {}
 | 
					func (*FdMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*FdMessage) Descriptor() ([]byte, []int) {
 | 
					func (*FdMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{17}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{22}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *FdMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *FdMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_FdMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_FdMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -1163,7 +1392,7 @@ func (m *ResizeMessage) Reset()         { *m = ResizeMessage{} }
 | 
				
			|||||||
func (m *ResizeMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *ResizeMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*ResizeMessage) ProtoMessage()    {}
 | 
					func (*ResizeMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*ResizeMessage) Descriptor() ([]byte, []int) {
 | 
					func (*ResizeMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{18}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{23}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *ResizeMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *ResizeMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_ResizeMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_ResizeMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -1210,7 +1439,7 @@ func (m *SignalMessage) Reset()         { *m = SignalMessage{} }
 | 
				
			|||||||
func (m *SignalMessage) String() string { return proto.CompactTextString(m) }
 | 
					func (m *SignalMessage) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*SignalMessage) ProtoMessage()    {}
 | 
					func (*SignalMessage) ProtoMessage()    {}
 | 
				
			||||||
func (*SignalMessage) Descriptor() ([]byte, []int) {
 | 
					func (*SignalMessage) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{19}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{24}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *SignalMessage) XXX_Unmarshal(b []byte) error {
 | 
					func (m *SignalMessage) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_SignalMessage.Unmarshal(m, b)
 | 
						return xxx_messageInfo_SignalMessage.Unmarshal(m, b)
 | 
				
			||||||
@@ -1248,7 +1477,7 @@ func (m *StatusRequest) Reset()         { *m = StatusRequest{} }
 | 
				
			|||||||
func (m *StatusRequest) String() string { return proto.CompactTextString(m) }
 | 
					func (m *StatusRequest) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*StatusRequest) ProtoMessage()    {}
 | 
					func (*StatusRequest) ProtoMessage()    {}
 | 
				
			||||||
func (*StatusRequest) Descriptor() ([]byte, []int) {
 | 
					func (*StatusRequest) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{20}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{25}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *StatusRequest) XXX_Unmarshal(b []byte) error {
 | 
					func (m *StatusRequest) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_StatusRequest.Unmarshal(m, b)
 | 
						return xxx_messageInfo_StatusRequest.Unmarshal(m, b)
 | 
				
			||||||
@@ -1289,7 +1518,7 @@ func (m *StatusResponse) Reset()         { *m = StatusResponse{} }
 | 
				
			|||||||
func (m *StatusResponse) String() string { return proto.CompactTextString(m) }
 | 
					func (m *StatusResponse) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*StatusResponse) ProtoMessage()    {}
 | 
					func (*StatusResponse) ProtoMessage()    {}
 | 
				
			||||||
func (*StatusResponse) Descriptor() ([]byte, []int) {
 | 
					func (*StatusResponse) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{21}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{26}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
 | 
					func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_StatusResponse.Unmarshal(m, b)
 | 
						return xxx_messageInfo_StatusResponse.Unmarshal(m, b)
 | 
				
			||||||
@@ -1347,7 +1576,7 @@ func (m *InfoRequest) Reset()         { *m = InfoRequest{} }
 | 
				
			|||||||
func (m *InfoRequest) String() string { return proto.CompactTextString(m) }
 | 
					func (m *InfoRequest) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*InfoRequest) ProtoMessage()    {}
 | 
					func (*InfoRequest) ProtoMessage()    {}
 | 
				
			||||||
func (*InfoRequest) Descriptor() ([]byte, []int) {
 | 
					func (*InfoRequest) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{22}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{27}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *InfoRequest) XXX_Unmarshal(b []byte) error {
 | 
					func (m *InfoRequest) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_InfoRequest.Unmarshal(m, b)
 | 
						return xxx_messageInfo_InfoRequest.Unmarshal(m, b)
 | 
				
			||||||
@@ -1378,7 +1607,7 @@ func (m *InfoResponse) Reset()         { *m = InfoResponse{} }
 | 
				
			|||||||
func (m *InfoResponse) String() string { return proto.CompactTextString(m) }
 | 
					func (m *InfoResponse) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*InfoResponse) ProtoMessage()    {}
 | 
					func (*InfoResponse) ProtoMessage()    {}
 | 
				
			||||||
func (*InfoResponse) Descriptor() ([]byte, []int) {
 | 
					func (*InfoResponse) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{23}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{28}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *InfoResponse) XXX_Unmarshal(b []byte) error {
 | 
					func (m *InfoResponse) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_InfoResponse.Unmarshal(m, b)
 | 
						return xxx_messageInfo_InfoResponse.Unmarshal(m, b)
 | 
				
			||||||
@@ -1418,7 +1647,7 @@ func (m *BuildxVersion) Reset()         { *m = BuildxVersion{} }
 | 
				
			|||||||
func (m *BuildxVersion) String() string { return proto.CompactTextString(m) }
 | 
					func (m *BuildxVersion) String() string { return proto.CompactTextString(m) }
 | 
				
			||||||
func (*BuildxVersion) ProtoMessage()    {}
 | 
					func (*BuildxVersion) ProtoMessage()    {}
 | 
				
			||||||
func (*BuildxVersion) Descriptor() ([]byte, []int) {
 | 
					func (*BuildxVersion) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor_ed7f10298fa1d90f, []int{24}
 | 
						return fileDescriptor_ed7f10298fa1d90f, []int{29}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (m *BuildxVersion) XXX_Unmarshal(b []byte) error {
 | 
					func (m *BuildxVersion) XXX_Unmarshal(b []byte) error {
 | 
				
			||||||
	return xxx_messageInfo_BuildxVersion.Unmarshal(m, b)
 | 
						return xxx_messageInfo_BuildxVersion.Unmarshal(m, b)
 | 
				
			||||||
@@ -1462,11 +1691,22 @@ func (m *BuildxVersion) GetRevision() string {
 | 
				
			|||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	proto.RegisterType((*BuildRequest)(nil), "buildx.controller.v1.BuildRequest")
 | 
						proto.RegisterType((*BuildRequest)(nil), "buildx.controller.v1.BuildRequest")
 | 
				
			||||||
	proto.RegisterType((*BuildOptions)(nil), "buildx.controller.v1.BuildOptions")
 | 
						proto.RegisterType((*BuildOptions)(nil), "buildx.controller.v1.BuildOptions")
 | 
				
			||||||
 | 
						proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.BuildOptions.BuildArgsEntry")
 | 
				
			||||||
 | 
						proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.BuildOptions.LabelsEntry")
 | 
				
			||||||
 | 
						proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.BuildOptions.NamedContextsEntry")
 | 
				
			||||||
 | 
						proto.RegisterType((*ExportEntry)(nil), "buildx.controller.v1.ExportEntry")
 | 
				
			||||||
 | 
						proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.ExportEntry.AttrsEntry")
 | 
				
			||||||
 | 
						proto.RegisterType((*CacheOptionsEntry)(nil), "buildx.controller.v1.CacheOptionsEntry")
 | 
				
			||||||
 | 
						proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.CacheOptionsEntry.AttrsEntry")
 | 
				
			||||||
 | 
						proto.RegisterType((*Attest)(nil), "buildx.controller.v1.Attest")
 | 
				
			||||||
 | 
						proto.RegisterType((*SSH)(nil), "buildx.controller.v1.SSH")
 | 
				
			||||||
 | 
						proto.RegisterType((*Secret)(nil), "buildx.controller.v1.Secret")
 | 
				
			||||||
	proto.RegisterType((*UlimitOpt)(nil), "buildx.controller.v1.UlimitOpt")
 | 
						proto.RegisterType((*UlimitOpt)(nil), "buildx.controller.v1.UlimitOpt")
 | 
				
			||||||
	proto.RegisterMapType((map[string]*Ulimit)(nil), "buildx.controller.v1.UlimitOpt.ValuesEntry")
 | 
						proto.RegisterMapType((map[string]*Ulimit)(nil), "buildx.controller.v1.UlimitOpt.ValuesEntry")
 | 
				
			||||||
	proto.RegisterType((*Ulimit)(nil), "buildx.controller.v1.Ulimit")
 | 
						proto.RegisterType((*Ulimit)(nil), "buildx.controller.v1.Ulimit")
 | 
				
			||||||
	proto.RegisterType((*CommonOptions)(nil), "buildx.controller.v1.CommonOptions")
 | 
						proto.RegisterType((*CommonOptions)(nil), "buildx.controller.v1.CommonOptions")
 | 
				
			||||||
	proto.RegisterType((*BuildResponse)(nil), "buildx.controller.v1.BuildResponse")
 | 
						proto.RegisterType((*BuildResponse)(nil), "buildx.controller.v1.BuildResponse")
 | 
				
			||||||
 | 
						proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.BuildResponse.ExporterResponseEntry")
 | 
				
			||||||
	proto.RegisterType((*DisconnectRequest)(nil), "buildx.controller.v1.DisconnectRequest")
 | 
						proto.RegisterType((*DisconnectRequest)(nil), "buildx.controller.v1.DisconnectRequest")
 | 
				
			||||||
	proto.RegisterType((*DisconnectResponse)(nil), "buildx.controller.v1.DisconnectResponse")
 | 
						proto.RegisterType((*DisconnectResponse)(nil), "buildx.controller.v1.DisconnectResponse")
 | 
				
			||||||
	proto.RegisterType((*ListRequest)(nil), "buildx.controller.v1.ListRequest")
 | 
						proto.RegisterType((*ListRequest)(nil), "buildx.controller.v1.ListRequest")
 | 
				
			||||||
@@ -1491,97 +1731,111 @@ func init() {
 | 
				
			|||||||
func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) }
 | 
					func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor_ed7f10298fa1d90f = []byte{
 | 
					var fileDescriptor_ed7f10298fa1d90f = []byte{
 | 
				
			||||||
	// 1436 bytes of a gzipped FileDescriptorProto
 | 
						// 1657 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0xdd, 0x52, 0x1b, 0xc7,
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xdd, 0x6e, 0xdb, 0xc6,
 | 
				
			||||||
	0x12, 0x3e, 0x8b, 0x84, 0x7e, 0x5a, 0x08, 0xe3, 0x39, 0x1c, 0x9f, 0x39, 0x3a, 0x8e, 0x8d, 0x17,
 | 
						0x12, 0x3e, 0x94, 0x64, 0xfd, 0x8c, 0x2c, 0xc7, 0xd9, 0xe3, 0x04, 0x3c, 0x3a, 0x39, 0x89, 0xc3,
 | 
				
			||||||
	0xdb, 0x51, 0x55, 0xaa, 0x84, 0x83, 0x93, 0x72, 0x62, 0x3b, 0x17, 0x20, 0xa0, 0x20, 0xc5, 0x5f,
 | 
						0xfc, 0x1c, 0x01, 0x29, 0xe4, 0xc4, 0x69, 0x9a, 0xdf, 0x02, 0xb5, 0x25, 0x0b, 0x76, 0xe1, 0x3f,
 | 
				
			||||||
	0x16, 0x6c, 0x57, 0x72, 0x11, 0xd7, 0x22, 0x0d, 0x62, 0x4b, 0xab, 0x1d, 0x65, 0x67, 0x24, 0x20,
 | 
						0x50, 0x4e, 0x82, 0xb6, 0x40, 0x03, 0x5a, 0x5a, 0xcb, 0x84, 0x28, 0xae, 0xca, 0x5d, 0xc9, 0x56,
 | 
				
			||||||
	0x57, 0x79, 0x82, 0x5c, 0xe4, 0x2d, 0xf2, 0x0c, 0x79, 0x8d, 0xbc, 0x47, 0xf2, 0x08, 0xa9, 0xee,
 | 
						0xaf, 0x7a, 0xd3, 0xdb, 0xbe, 0x47, 0xd1, 0x47, 0xe8, 0x55, 0xdf, 0xa1, 0x0f, 0xd2, 0x47, 0x28,
 | 
				
			||||||
	0x99, 0x5d, 0x56, 0x58, 0x2b, 0x5f, 0x69, 0xfa, 0x9b, 0xef, 0xeb, 0x99, 0xee, 0xe9, 0xe9, 0x59,
 | 
						0x76, 0x76, 0x49, 0x51, 0x96, 0x28, 0xdb, 0xe8, 0x95, 0x77, 0x86, 0xdf, 0x37, 0xb3, 0x3b, 0x3b,
 | 
				
			||||||
	0xc1, 0x52, 0x47, 0x46, 0x3a, 0x96, 0x61, 0x28, 0xe2, 0xd6, 0x30, 0x96, 0x5a, 0xb2, 0xe5, 0xb3,
 | 
						0x3f, 0x2b, 0xc3, 0x72, 0x8b, 0xf9, 0x22, 0x60, 0x9e, 0x47, 0x83, 0x6a, 0x3f, 0x60, 0x82, 0x91,
 | 
				
			||||||
	0x51, 0x10, 0x76, 0xaf, 0x5a, 0x99, 0x89, 0xf1, 0xe7, 0x8d, 0x57, 0xbd, 0x40, 0x5f, 0x8c, 0xce,
 | 
						0x95, 0xe3, 0x81, 0xeb, 0xb5, 0xcf, 0xab, 0xb1, 0x0f, 0xc3, 0x67, 0xe5, 0xb7, 0x1d, 0x57, 0x9c,
 | 
				
			||||||
	0x5a, 0x1d, 0x39, 0x58, 0x1b, 0xc8, 0xb3, 0xeb, 0x35, 0x62, 0xf5, 0x03, 0xbd, 0xe6, 0x0f, 0x83,
 | 
						0x0e, 0x8e, 0xab, 0x2d, 0xd6, 0x5b, 0xeb, 0xb1, 0xe3, 0xd1, 0x1a, 0xa2, 0xba, 0xae, 0x58, 0x73,
 | 
				
			||||||
	0x35, 0x25, 0xe2, 0x71, 0xd0, 0x11, 0x6a, 0xcd, 0x8a, 0x92, 0x5f, 0xe3, 0xd2, 0xfd, 0x11, 0x16,
 | 
						0xfa, 0xee, 0x1a, 0xa7, 0xc1, 0xd0, 0x6d, 0x51, 0xbe, 0xa6, 0x49, 0xe1, 0x5f, 0x65, 0xd2, 0xfa,
 | 
				
			||||||
	0x36, 0x91, 0xee, 0x89, 0x9f, 0x46, 0x42, 0x69, 0xb6, 0x04, 0x05, 0x4f, 0x9c, 0x73, 0x67, 0xc5,
 | 
						0x1e, 0x16, 0x37, 0x25, 0xdc, 0xa6, 0x3f, 0x0c, 0x28, 0x17, 0x64, 0x19, 0xd2, 0x36, 0x3d, 0x31,
 | 
				
			||||||
	0x69, 0x56, 0x3d, 0x1c, 0xb2, 0xd7, 0x50, 0x3e, 0x1a, 0xea, 0x40, 0x46, 0x8a, 0xcf, 0xad, 0x38,
 | 
						0x8d, 0x55, 0xa3, 0x52, 0xb0, 0xe5, 0x92, 0xbc, 0x83, 0xdc, 0x41, 0x5f, 0xb8, 0xcc, 0xe7, 0x66,
 | 
				
			||||||
	0xcd, 0xda, 0xba, 0xdb, 0x9a, 0xb6, 0x8d, 0x16, 0xb9, 0xb1, 0x4c, 0x2f, 0x91, 0xb8, 0xbf, 0x95,
 | 
						0x6a, 0xd5, 0xa8, 0x14, 0xd7, 0xad, 0xea, 0xac, 0x6d, 0x54, 0xd1, 0x8c, 0x46, 0xda, 0x21, 0xc5,
 | 
				
			||||||
	0xec, 0x02, 0x16, 0x60, 0x2b, 0x50, 0x6b, 0xcb, 0x48, 0x8b, 0x2b, 0x7d, 0xec, 0xeb, 0x0b, 0xbb,
 | 
						0xfa, 0x19, 0xb4, 0x03, 0xad, 0x20, 0xab, 0x50, 0xac, 0x31, 0x5f, 0xd0, 0x73, 0x71, 0xe8, 0x88,
 | 
				
			||||||
	0x50, 0x16, 0x62, 0x4f, 0x61, 0x71, 0x4b, 0x76, 0xfa, 0x22, 0x3e, 0x0f, 0x42, 0x71, 0xe8, 0x0f,
 | 
						0x53, 0xed, 0x28, 0xae, 0x22, 0x8f, 0x61, 0xa9, 0xce, 0x5a, 0x5d, 0x1a, 0x9c, 0xb8, 0x1e, 0xdd,
 | 
				
			||||||
	0x04, 0xad, 0x5b, 0xf5, 0x6e, 0xa1, 0xec, 0x3e, 0x54, 0x8f, 0xe3, 0x20, 0xd2, 0x3b, 0xa3, 0xa8,
 | 
						0x77, 0x7a, 0x14, 0xfd, 0x16, 0xec, 0x0b, 0x5a, 0x72, 0x07, 0x0a, 0x87, 0x81, 0xeb, 0x8b, 0xc6,
 | 
				
			||||||
	0xc3, 0x0b, 0x44, 0xb9, 0x01, 0xd8, 0x32, 0xcc, 0x6f, 0x84, 0xa1, 0xbc, 0xe4, 0xc5, 0x95, 0x42,
 | 
						0xc0, 0x6f, 0x99, 0x69, 0x84, 0x8c, 0x15, 0xe4, 0x3b, 0x28, 0x49, 0x54, 0x5b, 0x5b, 0xe6, 0x66,
 | 
				
			||||||
	0xb3, 0xea, 0x19, 0x83, 0x71, 0x28, 0x6f, 0x68, 0x2d, 0x94, 0x56, 0x7c, 0x9e, 0xf0, 0xc4, 0x44,
 | 
						0x66, 0x35, 0x5d, 0x29, 0xae, 0xbf, 0xb8, 0x7c, 0xf3, 0xd5, 0x09, 0xde, 0x96, 0x2f, 0x82, 0x91,
 | 
				
			||||||
	0x6f, 0xb4, 0xcf, 0x8d, 0xb8, 0xa7, 0x78, 0x89, 0xe6, 0x6e, 0x00, 0x9c, 0x6d, 0xfb, 0x9d, 0x0b,
 | 
						0x3d, 0x69, 0x8b, 0xac, 0xc0, 0xc2, 0x86, 0xe7, 0xb1, 0x33, 0x73, 0x61, 0x35, 0x5d, 0x29, 0xd8,
 | 
				
			||||||
	0xb1, 0x13, 0xcb, 0x01, 0x2f, 0x9b, 0xd9, 0x14, 0x40, 0xaf, 0x64, 0x9c, 0x4a, 0x5e, 0x31, 0x5e,
 | 
						0x4a, 0x20, 0x5f, 0x40, 0x6e, 0x43, 0x08, 0xca, 0x05, 0x37, 0xb3, 0xe8, 0xec, 0xce, 0x6c, 0x67,
 | 
				
			||||||
	0xad, 0xc9, 0x5c, 0x58, 0x68, 0xf7, 0x62, 0x39, 0x1a, 0x1e, 0xfb, 0xb1, 0x88, 0x34, 0xaf, 0xd2,
 | 
						0x0a, 0x64, 0x87, 0x60, 0x72, 0x00, 0x05, 0xf4, 0xbf, 0x11, 0x74, 0xb8, 0x99, 0x43, 0xe6, 0xb3,
 | 
				
			||||||
	0x36, 0x27, 0x30, 0xd6, 0x80, 0x8a, 0x0d, 0x5f, 0x71, 0x20, 0x79, 0x6a, 0xb3, 0x07, 0x00, 0xdb,
 | 
						0x2b, 0x6c, 0x33, 0xe2, 0xa8, 0x2d, 0x8e, 0x6d, 0x90, 0x2d, 0x28, 0xd4, 0x9c, 0xd6, 0x29, 0x6d,
 | 
				
			||||||
	0x57, 0x3a, 0xf6, 0x77, 0x25, 0x6e, 0xb9, 0x46, 0xb3, 0x19, 0x04, 0xb3, 0xb9, 0x37, 0xf0, 0x7b,
 | 
						0x04, 0xac, 0x67, 0xe6, 0xd1, 0xe0, 0xff, 0x67, 0x1b, 0x44, 0x98, 0x36, 0xa8, 0xcd, 0x44, 0x4c,
 | 
				
			||||||
	0x62, 0x6f, 0x6b, 0x27, 0x08, 0x05, 0x5f, 0x30, 0xd9, 0xcc, 0x40, 0xec, 0x1e, 0x94, 0xf6, 0xfd,
 | 
						0xb2, 0x01, 0x39, 0x14, 0x8e, 0x98, 0x59, 0xb8, 0x9e, 0x91, 0x90, 0x47, 0x2c, 0x58, 0xac, 0x75,
 | 
				
			||||||
	0x33, 0x11, 0x2a, 0x5e, 0x27, 0xb5, 0xb5, 0x50, 0x79, 0x28, 0xf4, 0xa5, 0x8c, 0xfb, 0x07, 0xb2,
 | 
						0x02, 0x36, 0xe8, 0x1f, 0x3a, 0x01, 0xf5, 0x85, 0x09, 0x78, 0x4d, 0x13, 0x3a, 0xf2, 0x16, 0x72,
 | 
				
			||||||
	0x2b, 0xf8, 0xa2, 0x51, 0x66, 0x20, 0xf6, 0x18, 0xea, 0x87, 0xd2, 0x04, 0x19, 0x84, 0x5a, 0xc4,
 | 
						0x5b, 0xe7, 0x7d, 0x16, 0x08, 0x6e, 0x16, 0xd1, 0xcd, 0xfd, 0xd9, 0x6e, 0x14, 0x48, 0x3b, 0xd0,
 | 
				
			||||||
	0xfc, 0x0e, 0x39, 0x98, 0x04, 0x31, 0xf6, 0xa3, 0x91, 0x1e, 0x8e, 0xb4, 0xe2, 0x4b, 0x26, 0x76,
 | 
						0x0c, 0x72, 0x17, 0x60, 0xeb, 0x5c, 0x04, 0xce, 0x36, 0x93, 0x61, 0x5f, 0xc4, 0xeb, 0x88, 0x69,
 | 
				
			||||||
	0x6b, 0xd2, 0xf9, 0x84, 0xbe, 0x3e, 0x97, 0xf1, 0x40, 0xf1, 0xbb, 0x26, 0x67, 0x29, 0x80, 0xe7,
 | 
						0x48, 0x03, 0xb2, 0xbb, 0xce, 0x31, 0xf5, 0xb8, 0x59, 0x42, 0xdb, 0xd5, 0x2b, 0x04, 0x56, 0x11,
 | 
				
			||||||
	0xf3, 0xdd, 0x28, 0x10, 0x9a, 0xb3, 0x15, 0xa7, 0x59, 0xf1, 0x8c, 0x81, 0xde, 0x4e, 0x44, 0x27,
 | 
						0x94, 0x23, 0xcd, 0x96, 0x69, 0xbb, 0x4f, 0xc5, 0x19, 0x0b, 0xba, 0x7b, 0xac, 0x4d, 0xcd, 0x25,
 | 
				
			||||||
	0x16, 0x5a, 0xf1, 0x7f, 0x1b, 0x6f, 0xd6, 0xa4, 0x99, 0x8b, 0xc1, 0x49, 0xf0, 0xb3, 0xe0, 0xcb,
 | 
						0x95, 0xb6, 0x31, 0x15, 0x79, 0x08, 0xa5, 0x7d, 0xa6, 0x82, 0xe7, 0x7a, 0x82, 0x06, 0xe6, 0x0d,
 | 
				
			||||||
	0x2b, 0x4e, 0xb3, 0xe0, 0x25, 0x26, 0x96, 0xec, 0xc9, 0xc9, 0x2e, 0xff, 0x0f, 0xf1, 0x71, 0xc8,
 | 
						0xdc, 0xcc, 0xa4, 0x12, 0x93, 0xd6, 0x73, 0xc4, 0x09, 0x0b, 0x7a, 0xdc, 0x5c, 0x46, 0xc4, 0x58,
 | 
				
			||||||
	0x18, 0x14, 0x4f, 0xfd, 0x9e, 0xe2, 0xf7, 0x08, 0xa2, 0x31, 0xe6, 0xe1, 0xd4, 0x8f, 0x7b, 0x42,
 | 
						0x21, 0x33, 0xa8, 0x49, 0x5b, 0x01, 0x15, 0xdc, 0xbc, 0x39, 0x2f, 0x83, 0x14, 0xc8, 0x0e, 0xc1,
 | 
				
			||||||
	0xf3, 0xff, 0x52, 0xa8, 0xd6, 0x62, 0x5f, 0x43, 0xf9, 0x4d, 0x18, 0x0c, 0x02, 0xad, 0x38, 0xa7,
 | 
						0xc4, 0x84, 0x5c, 0xf3, 0xb4, 0xd7, 0x74, 0x7f, 0xa4, 0x26, 0x59, 0x35, 0x2a, 0x69, 0x3b, 0x14,
 | 
				
			||||||
	0xf2, 0x7e, 0x38, 0xbd, 0xbc, 0x0d, 0xe9, 0x68, 0xa8, 0xbd, 0x84, 0xcf, 0x5e, 0x40, 0xf1, 0x68,
 | 
						0xc9, 0x13, 0x48, 0x37, 0x9b, 0xdb, 0xe6, 0xbf, 0xd1, 0xda, 0x7f, 0x12, 0xac, 0x35, 0xb7, 0x6d,
 | 
				
			||||||
	0xa8, 0x15, 0xff, 0x1f, 0xe9, 0x56, 0xa7, 0xeb, 0xda, 0x72, 0x30, 0x90, 0x51, 0x72, 0x2f, 0x48,
 | 
						0x89, 0x22, 0x04, 0x32, 0x47, 0x4e, 0x87, 0x9b, 0x2b, 0xb8, 0x2f, 0x5c, 0x93, 0xdb, 0x90, 0x3d,
 | 
				
			||||||
	0xe0, 0xfe, 0xee, 0x40, 0x35, 0xf5, 0xc7, 0xda, 0x50, 0x1a, 0xfb, 0xe1, 0x48, 0x28, 0xee, 0xac,
 | 
						0x72, 0x82, 0x0e, 0x15, 0xe6, 0x2d, 0x3c, 0xb3, 0x96, 0xc8, 0x6b, 0xc8, 0xbd, 0xf7, 0xdc, 0x9e,
 | 
				
			||||||
	0x14, 0x9a, 0xb5, 0xf5, 0xcf, 0x3e, 0xb2, 0x81, 0xd6, 0x5b, 0x62, 0x6f, 0x47, 0x3a, 0xbe, 0xf6,
 | 
						0x2b, 0xb8, 0x79, 0x1b, 0xdb, 0xc2, 0xbd, 0xd9, 0xc6, 0x15, 0xe8, 0xa0, 0x2f, 0xec, 0x10, 0x4f,
 | 
				
			||||||
	0xac, 0xb4, 0xf1, 0x0e, 0x6a, 0x19, 0x18, 0x73, 0xd2, 0x17, 0xd7, 0xc9, 0x35, 0xee, 0x8b, 0x6b,
 | 
						0x5e, 0x42, 0xe6, 0xa0, 0x2f, 0xb8, 0x69, 0x22, 0xef, 0x41, 0x42, 0x52, 0xb1, 0x5e, 0x8f, 0xf9,
 | 
				
			||||||
	0xb6, 0x0e, 0xf3, 0x44, 0xb5, 0x97, 0xf8, 0xfe, 0xac, 0x45, 0x3c, 0x43, 0x7d, 0x39, 0xf7, 0x95,
 | 
						0x61, 0x3f, 0x41, 0x42, 0xf9, 0x2b, 0x20, 0xd3, 0xb5, 0x29, 0x5b, 0x56, 0x97, 0x8e, 0xc2, 0x96,
 | 
				
			||||||
	0xe3, 0x6e, 0x41, 0xc9, 0x80, 0x98, 0x55, 0xba, 0x8d, 0xc6, 0x29, 0x8d, 0x11, 0xdb, 0xf5, 0xe3,
 | 
						0xd5, 0xa5, 0x23, 0x59, 0x9e, 0x43, 0xc7, 0x1b, 0x84, 0x8d, 0x43, 0x09, 0x6f, 0x52, 0xaf, 0x8c,
 | 
				
			||||||
	0x2e, 0x39, 0x2d, 0x78, 0x34, 0x46, 0xec, 0x44, 0x9e, 0x6b, 0xba, 0x92, 0x05, 0x8f, 0xc6, 0xee,
 | 
						0xf2, 0x3b, 0x58, 0x9a, 0x2c, 0x9b, 0x6b, 0xb1, 0x5f, 0x43, 0x31, 0x96, 0x1b, 0xd7, 0xa1, 0x5a,
 | 
				
			||||||
	0x5f, 0x0e, 0xd4, 0x27, 0x32, 0x81, 0xe7, 0x49, 0xd7, 0x4b, 0xc4, 0xd6, 0x61, 0x62, 0xe2, 0x9d,
 | 
						0x7f, 0x18, 0x50, 0x8c, 0x25, 0x30, 0x86, 0x7a, 0xd4, 0xa7, 0x9a, 0x8c, 0x6b, 0xb2, 0x09, 0x0b,
 | 
				
			||||||
	0x39, 0x10, 0xda, 0xef, 0xfa, 0xda, 0xa7, 0xa2, 0x36, 0xb7, 0x7f, 0x02, 0x43, 0xb5, 0x2d, 0x43,
 | 
						0x1b, 0x42, 0x04, 0xb2, 0xcf, 0xca, 0xdb, 0xfa, 0xec, 0xd2, 0x32, 0xa8, 0x22, 0x5c, 0x25, 0xaa,
 | 
				
			||||||
	0x5a, 0xa6, 0xe2, 0x25, 0x26, 0xae, 0x7e, 0x3c, 0x0a, 0x43, 0x5e, 0x24, 0x98, 0xc6, 0xe6, 0x16,
 | 
						0xa2, 0xca, 0x3c, 0xad, 0x53, 0x2e, 0x5c, 0xdf, 0x91, 0x81, 0xd3, 0x6d, 0x31, 0xae, 0x2a, 0xbf,
 | 
				
			||||||
	0x0d, 0x65, 0xac, 0x8f, 0x47, 0xea, 0x82, 0xcf, 0xd3, 0x4c, 0x06, 0xb9, 0x99, 0xdf, 0x97, 0x7e,
 | 
						0x02, 0x18, 0xd3, 0xae, 0x75, 0x86, 0xdf, 0x0c, 0xb8, 0x39, 0x55, 0xeb, 0x33, 0x4f, 0xb2, 0x3d,
 | 
				
			||||||
	0x97, 0x97, 0xb2, 0xf3, 0x88, 0x50, 0x44, 0x9b, 0x47, 0x07, 0xbc, 0x6c, 0x22, 0xc7, 0x31, 0x6a,
 | 
						0x79, 0x92, 0xf5, 0x2b, 0xf6, 0x8d, 0xe9, 0xf3, 0xfc, 0x83, 0xdd, 0xee, 0x43, 0x56, 0x35, 0xd8,
 | 
				
			||||||
	0x8e, 0x63, 0x39, 0x16, 0x91, 0x1f, 0x75, 0x04, 0xaf, 0xd0, 0x4c, 0x06, 0x71, 0xef, 0x40, 0xdd,
 | 
						0x99, 0x3b, 0x2c, 0x43, 0xbe, 0xee, 0x72, 0xe7, 0xd8, 0xa3, 0x6d, 0xa4, 0xe6, 0xed, 0x48, 0xc6,
 | 
				
			||||||
	0x36, 0x56, 0x35, 0x94, 0x91, 0x12, 0xee, 0x13, 0xb8, 0xbb, 0x15, 0xa8, 0x8e, 0x8c, 0x22, 0xd1,
 | 
						0xee, 0x8e, 0xbb, 0x57, 0xd1, 0x53, 0x82, 0xa5, 0x2a, 0x89, 0x2c, 0x41, 0x6a, 0xa7, 0xae, 0x4d,
 | 
				
			||||||
	0xd1, 0xb9, 0xed, 0xd6, 0x5d, 0x06, 0x96, 0xa5, 0x59, 0xf1, 0x43, 0xa8, 0xed, 0x07, 0x6a, 0x86,
 | 
						0xa5, 0x76, 0xea, 0x12, 0x2c, 0xa7, 0x96, 0x3a, 0x6a, 0xc1, 0x56, 0x82, 0xd5, 0x80, 0xac, 0xaa,
 | 
				
			||||||
	0xcc, 0x85, 0x05, 0x43, 0x30, 0x02, 0xdc, 0x72, 0x5f, 0x5c, 0x9b, 0x92, 0xaa, 0x7a, 0x34, 0x76,
 | 
						0xcd, 0x29, 0x7c, 0x19, 0xf2, 0x0d, 0xd7, 0xa3, 0x38, 0xfc, 0xd4, 0x9e, 0x23, 0x59, 0x1e, 0x6f,
 | 
				
			||||||
	0x7f, 0x75, 0x60, 0x61, 0x2f, 0x1a, 0x8e, 0xf4, 0x81, 0x50, 0xca, 0xef, 0x09, 0xf6, 0x1a, 0x8a,
 | 
						0xcb, 0x1f, 0x6a, 0xb7, 0x72, 0x69, 0xfd, 0x6a, 0x40, 0x21, 0xaa, 0x20, 0x52, 0x83, 0x2c, 0x9e,
 | 
				
			||||||
	0x7b, 0x51, 0xa0, 0xc9, 0x4f, 0x6d, 0xfd, 0xe9, 0xf4, 0x92, 0x20, 0x05, 0xd2, 0xac, 0x6a, 0xf7,
 | 
						0x8f, 0x9b, 0x06, 0xc6, 0xf5, 0xc9, 0x25, 0x25, 0x57, 0xfd, 0x80, 0x68, 0xdd, 0xc9, 0x14, 0xb5,
 | 
				
			||||||
	0x5f, 0x1e, 0xa9, 0xb0, 0xfc, 0xb7, 0x7c, 0xed, 0xdb, 0x82, 0x7a, 0x34, 0x5d, 0x8d, 0x8c, 0x8c,
 | 
						0xfc, 0x11, 0x8a, 0x31, 0xf5, 0x8c, 0x90, 0xae, 0xc7, 0x43, 0x9a, 0xd8, 0x82, 0x94, 0x93, 0x78,
 | 
				
			||||||
	0x10, 0xcd, 0xcd, 0x32, 0xcc, 0x93, 0x53, 0xf7, 0x31, 0x2c, 0xdd, 0xf6, 0x3e, 0x25, 0xb4, 0xe7,
 | 
						0xc0, 0xeb, 0x90, 0x55, 0x4a, 0x19, 0x70, 0x9c, 0xdb, 0x3a, 0xe0, 0x38, 0xad, 0x09, 0x64, 0xb6,
 | 
				
			||||||
	0x50, 0xcb, 0x78, 0x41, 0xc2, 0xf6, 0xd1, 0x0e, 0x11, 0x2a, 0x1e, 0x0e, 0x31, 0xd6, 0x74, 0x23,
 | 
						0x9d, 0x40, 0x05, 0x3b, 0x6d, 0xe3, 0x5a, 0xea, 0x9a, 0xec, 0x44, 0xe0, 0x81, 0xd3, 0x36, 0xae,
 | 
				
			||||||
	0x0b, 0x66, 0x0d, 0x4c, 0x3f, 0xb9, 0x4e, 0x33, 0xf8, 0xcb, 0x1c, 0x94, 0x13, 0x17, 0x2f, 0x26,
 | 
						0xad, 0xdf, 0x0d, 0x28, 0x4d, 0xd4, 0xbe, 0x6c, 0x6e, 0x58, 0xb3, 0x34, 0xd0, 0x06, 0x43, 0x51,
 | 
				
			||||||
	0xe2, 0x7e, 0x94, 0x17, 0xf7, 0x87, 0x21, 0x7f, 0x09, 0xc5, 0xb4, 0x24, 0x73, 0x3b, 0xc5, 0x4e,
 | 
						0x4e, 0x97, 0x3d, 0x2a, 0x9c, 0xb6, 0x23, 0x1c, 0x19, 0x43, 0x1d, 0xcf, 0x09, 0x9d, 0x64, 0xeb,
 | 
				
			||||||
	0x37, 0x23, 0xa3, 0x6a, 0xfd, 0x06, 0x4a, 0x9e, 0x50, 0xd8, 0xba, 0x0a, 0xb3, 0x5a, 0x85, 0xe1,
 | 
						0x0e, 0x8c, 0x6e, 0xf2, 0x76, 0x28, 0x4a, 0xef, 0x87, 0x03, 0xcf, 0x33, 0x33, 0xa8, 0xc6, 0xb5,
 | 
				
			||||||
	0xdc, 0x88, 0xad, 0x08, 0xe5, 0x27, 0x41, 0x2f, 0xf2, 0x4d, 0x51, 0xe7, 0xca, 0x0d, 0x27, 0x23,
 | 
						0x1a, 0x27, 0xb2, 0xbe, 0x0e, 0x07, 0xfc, 0xd4, 0x5c, 0xc0, 0x2f, 0x31, 0xcd, 0xf8, 0xfb, 0x2e,
 | 
				
			||||||
	0x37, 0xc0, 0x4d, 0xba, 0x87, 0x50, 0x9b, 0x99, 0x69, 0x76, 0x04, 0x77, 0xf0, 0xe5, 0xf1, 0x83,
 | 
						0x73, 0xda, 0x66, 0x36, 0xfe, 0x5d, 0x6a, 0x70, 0xf7, 0xfa, 0x3d, 0xc5, 0xfb, 0xcc, 0xe7, 0x94,
 | 
				
			||||||
	0x48, 0xc4, 0x6d, 0x19, 0x9d, 0x07, 0x3d, 0x1b, 0xe9, 0x93, 0xbc, 0xde, 0x36, 0x41, 0xf6, 0x6e,
 | 
						0x50, 0x58, 0x56, 0xdf, 0x69, 0x10, 0xea, 0xf4, 0xed, 0xbd, 0x9e, 0x33, 0x8a, 0x42, 0x68, 0xf5,
 | 
				
			||||||
	0xab, 0xdd, 0x3f, 0x9c, 0x0f, 0x3c, 0xd2, 0x65, 0xc3, 0x1e, 0x35, 0x94, 0x41, 0xa4, 0x6d, 0x7d,
 | 
						0x22, 0x57, 0xdd, 0xe5, 0x94, 0xc9, 0x72, 0x0d, 0x6e, 0xcd, 0x84, 0x5e, 0xab, 0x64, 0x1e, 0xc1,
 | 
				
			||||||
	0x66, 0x10, 0xdc, 0x56, 0x7b, 0x80, 0x1d, 0x85, 0xda, 0x79, 0x7b, 0xd0, 0xa5, 0x13, 0x8f, 0xc6,
 | 
						0xcd, 0xba, 0xcb, 0x5b, 0xcc, 0xf7, 0x69, 0x4b, 0x24, 0xbe, 0x08, 0xad, 0x15, 0x20, 0x71, 0x98,
 | 
				
			||||||
	0xbc, 0x60, 0x90, 0xed, 0x68, 0x8c, 0x27, 0xfe, 0x46, 0x89, 0x98, 0xf2, 0x51, 0xf5, 0x68, 0x8c,
 | 
						0xf2, 0x66, 0xdd, 0x83, 0xe2, 0xae, 0xcb, 0xe7, 0xd0, 0x2c, 0x58, 0x54, 0x00, 0x1d, 0x19, 0x02,
 | 
				
			||||||
	0x0d, 0xfe, 0x50, 0x12, 0x6a, 0x2e, 0xb8, 0xb5, 0xc8, 0xdf, 0xa5, 0xb9, 0xd5, 0xe8, 0xef, 0xb2,
 | 
						0x99, 0x2e, 0x1d, 0xa9, 0x5c, 0x2e, 0xd8, 0xb8, 0xb6, 0x7e, 0x31, 0x60, 0x71, 0xc7, 0xef, 0x0f,
 | 
				
			||||||
	0x8b, 0x4f, 0xcf, 0xa1, 0x44, 0xac, 0x6c, 0x9e, 0x1e, 0x32, 0x90, 0x77, 0xaa, 0xaf, 0xe9, 0x26,
 | 
						0xc4, 0x1e, 0xe5, 0xdc, 0xe9, 0x50, 0xf2, 0x0e, 0x32, 0x3b, 0xbe, 0x2b, 0xd0, 0x4e, 0x71, 0xfd,
 | 
				
			||||||
	0x57, 0x3c, 0x1c, 0xba, 0x1b, 0x50, 0x4d, 0xcf, 0x92, 0x2d, 0xc2, 0xdc, 0x4e, 0x97, 0x92, 0x55,
 | 
						0xf1, 0xec, 0x90, 0x21, 0x43, 0xc2, 0x34, 0x6b, 0xfb, 0x5f, 0x36, 0xb2, 0xe4, 0xa4, 0xa9, 0x3b,
 | 
				
			||||||
	0xf7, 0xe6, 0x76, 0xba, 0x49, 0x19, 0xce, 0x7d, 0x58, 0x86, 0x85, 0x4c, 0x19, 0xbe, 0x80, 0xfa,
 | 
						0xc2, 0xd1, 0x99, 0x9c, 0xf0, 0xae, 0x90, 0x88, 0x18, 0x51, 0x8a, 0x9b, 0x39, 0x58, 0x40, 0xa3,
 | 
				
			||||||
	0xc4, 0xa9, 0x22, 0xc9, 0x93, 0x97, 0xca, 0x3a, 0xa2, 0x31, 0x62, 0x6d, 0x19, 0x9a, 0xcf, 0xab,
 | 
						0xd6, 0x43, 0x58, 0xbe, 0x68, 0x7d, 0xc6, 0xd1, 0x9e, 0x43, 0x31, 0x66, 0x05, 0xeb, 0xf8, 0xa0,
 | 
				
			||||||
	0xba, 0x47, 0x63, 0x77, 0x15, 0xea, 0x13, 0xe7, 0x39, 0xad, 0xfb, 0xba, 0x8f, 0xa0, 0x7e, 0xa2,
 | 
						0x81, 0x80, 0xbc, 0x2d, 0x97, 0xf2, 0xac, 0xd1, 0x46, 0x16, 0x95, 0x0f, 0xeb, 0x06, 0x94, 0xd0,
 | 
				
			||||||
	0x7d, 0x3d, 0x52, 0xf9, 0x7d, 0xe1, 0x6f, 0x07, 0x16, 0x13, 0x8e, 0x6d, 0x0d, 0x5f, 0x40, 0x65,
 | 
						0x74, 0x14, 0xc1, 0x9f, 0x52, 0x90, 0x0b, 0x4d, 0xbc, 0x9c, 0x38, 0xf7, 0xfd, 0xa4, 0x73, 0x4f,
 | 
				
			||||||
	0x2c, 0x62, 0x2d, 0xae, 0xd2, 0x17, 0x87, 0xb7, 0xf0, 0xbb, 0xb1, 0x95, 0x7c, 0x37, 0xe2, 0xd1,
 | 
						0x1f, 0xf9, 0x05, 0x64, 0xa2, 0x5a, 0x48, 0x1c, 0xca, 0x8d, 0x76, 0x8c, 0x86, 0x65, 0xf2, 0x25,
 | 
				
			||||||
	0xbe, 0x25, 0x86, 0x97, 0x32, 0xd9, 0x4b, 0xa8, 0x28, 0xf2, 0x23, 0x14, 0x9d, 0x4d, 0x6d, 0xfd,
 | 
						0x64, 0x6d, 0xca, 0xe5, 0x03, 0x22, 0x3d, 0x6f, 0x2a, 0x2b, 0xcc, 0x98, 0xac, 0x49, 0x92, 0xde,
 | 
				
			||||||
	0x41, 0x9e, 0xca, 0xae, 0x97, 0xf2, 0xd9, 0x1a, 0x14, 0x43, 0xd9, 0x53, 0x74, 0x82, 0xb5, 0xf5,
 | 
						0x74, 0x3b, 0xbe, 0xa3, 0xaa, 0x29, 0x91, 0xae, 0x30, 0x31, 0xba, 0x52, 0x8c, 0xc3, 0xdd, 0x87,
 | 
				
			||||||
	0xff, 0xe7, 0xe9, 0xf6, 0x65, 0xcf, 0x23, 0x22, 0x7b, 0x05, 0x95, 0x4b, 0x3f, 0x8e, 0x82, 0xa8,
 | 
						0xe2, 0xdc, 0x48, 0x93, 0x03, 0xb8, 0x21, 0xa7, 0xbf, 0xe3, 0xfa, 0x34, 0xa8, 0x31, 0xff, 0xc4,
 | 
				
			||||||
	0xa7, 0xe8, 0xfb, 0x0d, 0xef, 0x5a, 0x8e, 0xe8, 0x9d, 0xe1, 0x79, 0xa9, 0xc0, 0xad, 0x63, 0x99,
 | 
						0xed, 0xe8, 0x93, 0x3e, 0x4a, 0x7a, 0x46, 0x4c, 0x80, 0xed, 0x8b, 0x6c, 0x59, 0xb1, 0x17, 0x75,
 | 
				
			||||||
	0x9f, 0x4b, 0x9b, 0x13, 0xf7, 0x7b, 0x6c, 0x7a, 0x68, 0xda, 0xf0, 0xf7, 0xa0, 0x6e, 0x8a, 0xf9,
 | 
						0x58, 0xe5, 0xb2, 0x78, 0xfa, 0xcc, 0xf5, 0x85, 0xce, 0xcf, 0x98, 0x46, 0x6e, 0xab, 0xd6, 0x6b,
 | 
				
			||||||
	0xad, 0x88, 0x55, 0x20, 0x23, 0xdb, 0x05, 0x56, 0x67, 0x7c, 0xd5, 0x26, 0x54, 0x6f, 0x52, 0xe9,
 | 
						0xeb, 0x8e, 0x2f, 0x97, 0xe3, 0xce, 0x9d, 0xd6, 0x9d, 0x5b, 0xde, 0xf8, 0x7b, 0x4e, 0x03, 0x8c,
 | 
				
			||||||
	0xbe, 0xb7, 0x3d, 0x3e, 0x01, 0xf0, 0x59, 0x1a, 0xfa, 0x9d, 0xbe, 0xdf, 0x4b, 0xce, 0x29, 0x31,
 | 
						0x47, 0xc1, 0xc6, 0xb5, 0x7c, 0x4b, 0xed, 0x33, 0xd4, 0xaa, 0xce, 0xa2, 0x25, 0xb4, 0x77, 0xa6,
 | 
				
			||||||
	0x71, 0x66, 0x6c, 0xd7, 0x33, 0xef, 0x59, 0x62, 0xe2, 0xe7, 0x5f, 0x2c, 0xc6, 0x01, 0x4d, 0x99,
 | 
						0xda, 0x89, 0xb4, 0x77, 0x86, 0x23, 0x68, 0x9f, 0x49, 0x5d, 0x0e, 0x81, 0x4a, 0x90, 0xb8, 0x23,
 | 
				
			||||||
	0xaf, 0xd8, 0xd4, 0x5e, 0xff, 0xb3, 0x08, 0xd0, 0x4e, 0xf7, 0xc3, 0x8e, 0x61, 0x9e, 0xd6, 0x63,
 | 
						0x31, 0x32, 0xf3, 0x2a, 0xaf, 0x8e, 0xc4, 0xc8, 0xda, 0x80, 0x42, 0x74, 0x97, 0x72, 0xd4, 0x34,
 | 
				
			||||||
	0xb3, 0x3e, 0xc1, 0x6d, 0xdc, 0x8d, 0xd5, 0x99, 0x1c, 0x9b, 0x8c, 0x37, 0x50, 0x32, 0xa7, 0xc5,
 | 
						0xda, 0x18, 0xac, 0x92, 0x9d, 0x6a, 0xb4, 0xc3, 0x34, 0x4c, 0x4d, 0xa7, 0x61, 0x3a, 0x96, 0x86,
 | 
				
			||||||
	0xf2, 0x9a, 0x4a, 0xb6, 0xbe, 0x1a, 0x8f, 0x67, 0x93, 0x8c, 0xd3, 0x67, 0x0e, 0xf3, 0x6c, 0xcb,
 | 
						0x2f, 0xa1, 0x34, 0x71, 0xab, 0x12, 0x64, 0xb3, 0x33, 0xae, 0x0d, 0xe1, 0x5a, 0xea, 0x6a, 0xcc,
 | 
				
			||||||
	0xc9, 0xdb, 0x68, 0xf6, 0x15, 0xca, 0xdb, 0xe8, 0x44, 0xfb, 0x6e, 0x3a, 0xec, 0x5b, 0x28, 0xed,
 | 
						0x53, 0xbf, 0x00, 0x4b, 0x36, 0xae, 0xad, 0x07, 0x50, 0x9a, 0xb8, 0xcf, 0x59, 0x6d, 0xdf, 0xba,
 | 
				
			||||||
	0x45, 0x63, 0xd9, 0x17, 0xec, 0x93, 0xe9, 0x82, 0xc4, 0xdf, 0xec, 0xe9, 0xa6, 0xf3, 0xcc, 0x61,
 | 
						0x0f, 0xa5, 0xa6, 0x70, 0xc4, 0x80, 0x27, 0xf7, 0x85, 0xbf, 0x0c, 0x58, 0x0a, 0x31, 0xba, 0x35,
 | 
				
			||||||
	0x07, 0x50, 0xc4, 0xd7, 0x92, 0xe5, 0xb4, 0xfe, 0xcc, 0x53, 0xdb, 0x70, 0x67, 0x51, 0x6c, 0x16,
 | 
						0x7c, 0x0e, 0xf9, 0x21, 0x0d, 0x04, 0x3d, 0x8f, 0x46, 0x9d, 0x59, 0x95, 0x3f, 0x6d, 0xab, 0xe1,
 | 
				
			||||||
	0xdf, 0x03, 0xdc, 0xbc, 0xd9, 0xec, 0xd3, 0x9c, 0x97, 0xf0, 0xf6, 0xe3, 0xdf, 0x68, 0x7e, 0x9c,
 | 
						0x4f, 0x5b, 0x79, 0xb5, 0x1f, 0x10, 0x61, 0x47, 0x48, 0xf2, 0x06, 0xf2, 0x1c, 0xed, 0xd0, 0xf0,
 | 
				
			||||||
	0x68, 0x17, 0x38, 0xc0, 0x07, 0xeb, 0x5c, 0xb2, 0xdc, 0xa7, 0x2a, 0x2d, 0xf7, 0x86, 0x3b, 0x8b,
 | 
						0xe1, 0x71, 0x37, 0x89, 0xa5, 0xfd, 0x45, 0x78, 0xb2, 0x06, 0x19, 0x8f, 0x75, 0x38, 0xde, 0x60,
 | 
				
			||||||
	0x62, 0xdc, 0x6d, 0x16, 0x7f, 0x98, 0x1b, 0x9e, 0x9d, 0x95, 0xe8, 0x1f, 0xe0, 0xf3, 0x7f, 0x02,
 | 
						0x71, 0xfd, 0xbf, 0x49, 0xbc, 0x5d, 0xd6, 0xb1, 0x11, 0x48, 0xde, 0x42, 0xfe, 0xcc, 0x09, 0x7c,
 | 
				
			||||||
	0x00, 0x00, 0xff, 0xff, 0x10, 0xcd, 0x98, 0x21, 0x68, 0x0e, 0x00, 0x00,
 | 
						0xd7, 0xef, 0x84, 0x3f, 0x2d, 0xef, 0x25, 0x91, 0x3e, 0x2a, 0x9c, 0x1d, 0x11, 0xac, 0x92, 0x4c,
 | 
				
			||||||
 | 
						0xf3, 0x13, 0xa6, 0x63, 0x62, 0x7d, 0x23, 0x9b, 0x9e, 0x14, 0xf5, 0xf1, 0x77, 0xa0, 0xa4, 0x92,
 | 
				
			||||||
 | 
						0xf9, 0x03, 0x0d, 0xb8, 0x7c, 0xc6, 0x19, 0xf3, 0x8a, 0x6a, 0x33, 0x0e, 0xb5, 0x27, 0x99, 0xd6,
 | 
				
			||||||
 | 
						0x27, 0x3d, 0x8f, 0x42, 0x85, 0x9c, 0x87, 0x7d, 0xa7, 0xd5, 0x75, 0x3a, 0xe1, 0x3d, 0x85, 0xa2,
 | 
				
			||||||
 | 
						0xfc, 0x32, 0xd4, 0xfe, 0xd4, 0x64, 0x08, 0x45, 0xf9, 0x66, 0x09, 0xe8, 0xd0, 0xe5, 0xe3, 0x17,
 | 
				
			||||||
 | 
						0x65, 0x24, 0xaf, 0xff, 0x99, 0x01, 0xa8, 0x45, 0xfb, 0x21, 0x87, 0xb0, 0x80, 0xfe, 0x88, 0x35,
 | 
				
			||||||
 | 
						0x77, 0xba, 0xe1, 0xb9, 0xcb, 0x0f, 0xae, 0x30, 0x01, 0xc9, 0x7b, 0xc8, 0xaa, 0xdb, 0x22, 0x49,
 | 
				
			||||||
 | 
						0x4d, 0x25, 0x9e, 0x5f, 0xe5, 0x87, 0xf3, 0x41, 0xca, 0xe8, 0x53, 0x83, 0xd8, 0xba, 0xe5, 0x24,
 | 
				
			||||||
 | 
						0x6d, 0x34, 0x3e, 0x85, 0x92, 0x36, 0x3a, 0xd1, 0xbe, 0x2b, 0x06, 0xf9, 0x1a, 0xb2, 0x3b, 0xfe,
 | 
				
			||||||
 | 
						0x90, 0x75, 0x29, 0xf9, 0xdf, 0x6c, 0x42, 0x68, 0x6f, 0xfe, 0xe7, 0x8a, 0xf1, 0xd4, 0x20, 0x7b,
 | 
				
			||||||
 | 
						0x90, 0x91, 0xd3, 0x92, 0x24, 0xb4, 0xfe, 0xd8, 0xa8, 0x2d, 0x5b, 0xf3, 0x20, 0x3a, 0x8a, 0x9f,
 | 
				
			||||||
 | 
						0x00, 0xc6, 0x33, 0x9b, 0x24, 0xfc, 0x90, 0x9f, 0x1a, 0xfe, 0xe5, 0xca, 0xe5, 0x40, 0xed, 0x60,
 | 
				
			||||||
 | 
						0x4f, 0x0e, 0xac, 0x13, 0x46, 0x12, 0x47, 0x55, 0x94, 0xee, 0x65, 0x6b, 0x1e, 0x44, 0x99, 0xdb,
 | 
				
			||||||
 | 
						0xcc, 0x7c, 0x9b, 0xea, 0x1f, 0x1f, 0x67, 0xf1, 0x9f, 0x54, 0xcf, 0xff, 0x0e, 0x00, 0x00, 0xff,
 | 
				
			||||||
 | 
						0xff, 0xf4, 0x2e, 0xaa, 0xc4, 0x0b, 0x13, 0x00, 0x00,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Reference imports to suppress errors if they are not otherwise used.
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,30 +25,56 @@ message BuildOptions {
 | 
				
			|||||||
  string ContextPath = 1;
 | 
					  string ContextPath = 1;
 | 
				
			||||||
  string DockerfileName = 2;
 | 
					  string DockerfileName = 2;
 | 
				
			||||||
  string PrintFunc = 3;
 | 
					  string PrintFunc = 3;
 | 
				
			||||||
 | 
					  map<string, string> NamedContexts = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  repeated string Allow = 4;
 | 
					  repeated string Allow = 5;
 | 
				
			||||||
  repeated string Attests = 5; // TODO
 | 
					  repeated Attest Attests = 6;
 | 
				
			||||||
  repeated string BuildArgs = 6;
 | 
					  map<string, string> BuildArgs = 7;
 | 
				
			||||||
  repeated string CacheFrom = 7;
 | 
					  repeated CacheOptionsEntry CacheFrom = 8;
 | 
				
			||||||
  repeated string CacheTo = 8;
 | 
					  repeated CacheOptionsEntry CacheTo = 9;
 | 
				
			||||||
  string CgroupParent = 9;
 | 
					  string CgroupParent = 10;
 | 
				
			||||||
  repeated string Contexts = 10;
 | 
					  repeated ExportEntry Exports = 11;
 | 
				
			||||||
  repeated string ExtraHosts = 11;
 | 
					  repeated string ExtraHosts = 12;
 | 
				
			||||||
  string ImageIDFile = 12;
 | 
					  map<string, string> Labels = 13;
 | 
				
			||||||
  repeated string Labels = 13;
 | 
					 | 
				
			||||||
  string NetworkMode = 14;
 | 
					  string NetworkMode = 14;
 | 
				
			||||||
  repeated string NoCacheFilter = 15;
 | 
					  repeated string NoCacheFilter = 15;
 | 
				
			||||||
  repeated string Outputs = 16;
 | 
					  repeated string Platforms = 16;
 | 
				
			||||||
  repeated string Platforms = 17;
 | 
					  repeated Secret Secrets = 17;
 | 
				
			||||||
  bool Quiet = 18;
 | 
					  int64 ShmSize = 18;
 | 
				
			||||||
  repeated string Secrets = 19;
 | 
					  repeated SSH SSH = 19;
 | 
				
			||||||
  int64 ShmSize = 20;
 | 
					  repeated string Tags = 20;
 | 
				
			||||||
  repeated string SSH = 21;
 | 
					  string Target = 21;
 | 
				
			||||||
  repeated string Tags = 22;
 | 
					  UlimitOpt Ulimits = 22;
 | 
				
			||||||
  string Target = 23;
 | 
					
 | 
				
			||||||
  UlimitOpt Ulimits = 24;
 | 
					  CommonOptions Opts = 24;
 | 
				
			||||||
  // string Invoke: provided via Invoke API
 | 
					}
 | 
				
			||||||
  CommonOptions Opts = 25;
 | 
					
 | 
				
			||||||
 | 
					message ExportEntry {
 | 
				
			||||||
 | 
					  string Type = 1;
 | 
				
			||||||
 | 
					  map<string, string> Attrs = 2;
 | 
				
			||||||
 | 
					  string Destination = 3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					message CacheOptionsEntry {
 | 
				
			||||||
 | 
					  string Type = 1;
 | 
				
			||||||
 | 
					  map<string, string> Attrs = 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					message Attest {
 | 
				
			||||||
 | 
					  string Type = 1;
 | 
				
			||||||
 | 
					  bool Disabled = 2;
 | 
				
			||||||
 | 
					  string Attrs = 3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					message SSH {
 | 
				
			||||||
 | 
					  string ID = 1;
 | 
				
			||||||
 | 
					  repeated string Paths = 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					message Secret {
 | 
				
			||||||
 | 
					  string ID = 1;
 | 
				
			||||||
 | 
					  string FilePath = 2;
 | 
				
			||||||
 | 
					  string Env = 3;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message UlimitOpt {
 | 
					message UlimitOpt {
 | 
				
			||||||
@@ -69,11 +95,11 @@ message CommonOptions {
 | 
				
			|||||||
  bool Pull = 4;
 | 
					  bool Pull = 4;
 | 
				
			||||||
  bool ExportPush = 5;
 | 
					  bool ExportPush = 5;
 | 
				
			||||||
  bool ExportLoad = 6;
 | 
					  bool ExportLoad = 6;
 | 
				
			||||||
  string SBOM       = 7; // TODO
 | 
					 | 
				
			||||||
  string Provenance = 8; // TODO
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message BuildResponse {}
 | 
					message BuildResponse {
 | 
				
			||||||
 | 
						map<string, string> ExporterResponse = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message DisconnectRequest {
 | 
					message DisconnectRequest {
 | 
				
			||||||
  string Ref = 1;
 | 
					  string Ref = 1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,66 +1,31 @@
 | 
				
			|||||||
package buildflags
 | 
					package pb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/csv"
 | 
					 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/containerd/console"
 | 
						"github.com/containerd/console"
 | 
				
			||||||
	"github.com/moby/buildkit/client"
 | 
						"github.com/moby/buildkit/client"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseOutputs(inp []string) ([]client.ExportEntry, error) {
 | 
					func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) {
 | 
				
			||||||
	var outs []client.ExportEntry
 | 
						var outs []client.ExportEntry
 | 
				
			||||||
	if len(inp) == 0 {
 | 
						if len(entries) == 0 {
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, s := range inp {
 | 
						for _, entry := range entries {
 | 
				
			||||||
		csvReader := csv.NewReader(strings.NewReader(s))
 | 
							if entry.Type == "" {
 | 
				
			||||||
		fields, err := csvReader.Read()
 | 
								return nil, errors.Errorf("type is required for output")
 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		out := client.ExportEntry{
 | 
							out := client.ExportEntry{
 | 
				
			||||||
 | 
								Type:  entry.Type,
 | 
				
			||||||
			Attrs: map[string]string{},
 | 
								Attrs: map[string]string{},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if len(fields) == 1 && fields[0] == s && !strings.HasPrefix(s, "type=") {
 | 
							for k, v := range entry.Attrs {
 | 
				
			||||||
			if s != "-" {
 | 
								out.Attrs[k] = v
 | 
				
			||||||
				outs = append(outs, client.ExportEntry{
 | 
					 | 
				
			||||||
					Type:      client.ExporterLocal,
 | 
					 | 
				
			||||||
					OutputDir: s,
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			out = client.ExportEntry{
 | 
					 | 
				
			||||||
				Type: client.ExporterTar,
 | 
					 | 
				
			||||||
				Attrs: map[string]string{
 | 
					 | 
				
			||||||
					"dest": s,
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if out.Type == "" {
 | 
					 | 
				
			||||||
			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":
 | 
					 | 
				
			||||||
					out.Type = value
 | 
					 | 
				
			||||||
				default:
 | 
					 | 
				
			||||||
					out.Attrs[key] = value
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if out.Type == "" {
 | 
					 | 
				
			||||||
			return nil, errors.Errorf("type is required for output")
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		supportFile := false
 | 
							supportFile := false
 | 
				
			||||||
@@ -79,56 +44,49 @@ func ParseOutputs(inp []string) ([]client.ExportEntry, error) {
 | 
				
			|||||||
			supportDir = !tar
 | 
								supportDir = !tar
 | 
				
			||||||
		case "registry":
 | 
							case "registry":
 | 
				
			||||||
			out.Type = client.ExporterImage
 | 
								out.Type = client.ExporterImage
 | 
				
			||||||
			if _, ok := out.Attrs["push"]; !ok {
 | 
					 | 
				
			||||||
				out.Attrs["push"] = "true"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dest, ok := out.Attrs["dest"]
 | 
					 | 
				
			||||||
		if supportDir {
 | 
							if supportDir {
 | 
				
			||||||
			if !ok {
 | 
								if entry.Destination == "" {
 | 
				
			||||||
				return nil, errors.Errorf("dest is required for %s exporter", out.Type)
 | 
									return nil, errors.Errorf("dest is required for %s exporter", out.Type)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if dest == "-" {
 | 
								if entry.Destination == "-" {
 | 
				
			||||||
				return nil, errors.Errorf("dest cannot be stdout for %s exporter", out.Type)
 | 
									return nil, errors.Errorf("dest cannot be stdout for %s exporter", out.Type)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			fi, err := os.Stat(dest)
 | 
								fi, err := os.Stat(entry.Destination)
 | 
				
			||||||
			if err != nil && !os.IsNotExist(err) {
 | 
								if err != nil && !os.IsNotExist(err) {
 | 
				
			||||||
				return nil, errors.Wrapf(err, "invalid destination directory: %s", dest)
 | 
									return nil, errors.Wrapf(err, "invalid destination directory: %s", entry.Destination)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err == nil && !fi.IsDir() {
 | 
								if err == nil && !fi.IsDir() {
 | 
				
			||||||
				return nil, errors.Errorf("destination directory %s is a file", dest)
 | 
									return nil, errors.Errorf("destination directory %s is a file", entry.Destination)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			out.OutputDir = dest
 | 
								out.OutputDir = entry.Destination
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if supportFile {
 | 
							if supportFile {
 | 
				
			||||||
			if !ok && out.Type != client.ExporterDocker {
 | 
								if entry.Destination == "" && out.Type != client.ExporterDocker {
 | 
				
			||||||
				dest = "-"
 | 
									entry.Destination = "-"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if dest == "-" {
 | 
								if entry.Destination == "-" {
 | 
				
			||||||
				if _, err := console.ConsoleFromFile(os.Stdout); err == nil {
 | 
									if _, err := console.ConsoleFromFile(os.Stdout); err == nil {
 | 
				
			||||||
					return nil, errors.Errorf("dest file is required for %s exporter. refusing to write to console", out.Type)
 | 
										return nil, errors.Errorf("dest file is required for %s exporter. refusing to write to console", out.Type)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				out.Output = wrapWriteCloser(os.Stdout)
 | 
									out.Output = wrapWriteCloser(os.Stdout)
 | 
				
			||||||
			} else if dest != "" {
 | 
								} else if entry.Destination != "" {
 | 
				
			||||||
				fi, err := os.Stat(dest)
 | 
									fi, err := os.Stat(entry.Destination)
 | 
				
			||||||
				if err != nil && !os.IsNotExist(err) {
 | 
									if err != nil && !os.IsNotExist(err) {
 | 
				
			||||||
					return nil, errors.Wrapf(err, "invalid destination file: %s", dest)
 | 
										return nil, errors.Wrapf(err, "invalid destination file: %s", entry.Destination)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if err == nil && fi.IsDir() {
 | 
									if err == nil && fi.IsDir() {
 | 
				
			||||||
					return nil, errors.Errorf("destination file %s is a directory", dest)
 | 
										return nil, errors.Errorf("destination file %s is a directory", entry.Destination)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				f, err := os.Create(dest)
 | 
									f, err := os.Create(entry.Destination)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, errors.Errorf("failed to open %s", err)
 | 
										return nil, errors.Errorf("failed to open %s", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				out.Output = wrapWriteCloser(f)
 | 
									out.Output = wrapWriteCloser(f)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if supportFile || supportDir {
 | 
					 | 
				
			||||||
			delete(out.Attrs, "dest")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		outs = append(outs, out)
 | 
							outs = append(outs, out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
							
								
								
									
										22
									
								
								controller/pb/secrets.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								controller/pb/secrets.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					package pb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/session"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/session/secrets/secretsprovider"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateSecrets(secrets []*Secret) (session.Attachable, error) {
 | 
				
			||||||
 | 
						fs := make([]secretsprovider.Source, 0, len(secrets))
 | 
				
			||||||
 | 
						for _, secret := range secrets {
 | 
				
			||||||
 | 
							fs = append(fs, secretsprovider.Source{
 | 
				
			||||||
 | 
								ID:       secret.ID,
 | 
				
			||||||
 | 
								FilePath: secret.FilePath,
 | 
				
			||||||
 | 
								Env:      secret.Env,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						store, err := secretsprovider.NewStore(fs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return secretsprovider.NewSecretProvider(store), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								controller/pb/ssh.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								controller/pb/ssh.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					package pb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/session"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/session/sshforward/sshprovider"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func CreateSSH(ssh []*SSH) (session.Attachable, error) {
 | 
				
			||||||
 | 
						configs := make([]sshprovider.AgentConfig, 0, len(ssh))
 | 
				
			||||||
 | 
						for _, ssh := range ssh {
 | 
				
			||||||
 | 
							cfg := sshprovider.AgentConfig{
 | 
				
			||||||
 | 
								ID:    ssh.ID,
 | 
				
			||||||
 | 
								Paths: append([]string{}, ssh.Paths...),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							configs = append(configs, cfg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sshprovider.NewSSHAgentProvider(configs)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -91,18 +91,21 @@ func (c *Client) Invoke(ctx context.Context, ref string, containerConfig pb.Cont
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, error) {
 | 
					func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, *client.SolveResponse, error) {
 | 
				
			||||||
	ref := identity.NewID()
 | 
						ref := identity.NewID()
 | 
				
			||||||
	pw, err := progress.NewPrinter(context.TODO(), w, out, progressMode)
 | 
						pw, err := progress.NewPrinter(context.TODO(), w, out, progressMode)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return "", nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	statusChan := make(chan *client.SolveStatus)
 | 
						statusChan := make(chan *client.SolveStatus)
 | 
				
			||||||
	statusDone := make(chan struct{})
 | 
						statusDone := make(chan struct{})
 | 
				
			||||||
	eg, egCtx := errgroup.WithContext(ctx)
 | 
						eg, egCtx := errgroup.WithContext(ctx)
 | 
				
			||||||
 | 
						var resp *client.SolveResponse
 | 
				
			||||||
	eg.Go(func() error {
 | 
						eg.Go(func() error {
 | 
				
			||||||
		defer close(statusChan)
 | 
							defer close(statusChan)
 | 
				
			||||||
		return c.build(egCtx, ref, options, in, statusChan)
 | 
							var err error
 | 
				
			||||||
 | 
							resp, err = c.build(egCtx, ref, options, in, statusChan)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	eg.Go(func() error {
 | 
						eg.Go(func() error {
 | 
				
			||||||
		defer close(statusDone)
 | 
							defer close(statusDone)
 | 
				
			||||||
@@ -116,20 +119,27 @@ func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadC
 | 
				
			|||||||
		<-statusDone
 | 
							<-statusDone
 | 
				
			||||||
		return pw.Wait()
 | 
							return pw.Wait()
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	return ref, eg.Wait()
 | 
						return ref, resp, eg.Wait()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, statusChan chan *client.SolveStatus) error {
 | 
					func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, statusChan chan *client.SolveStatus) (*client.SolveResponse, error) {
 | 
				
			||||||
	eg, egCtx := errgroup.WithContext(ctx)
 | 
						eg, egCtx := errgroup.WithContext(ctx)
 | 
				
			||||||
	done := make(chan struct{})
 | 
						done := make(chan struct{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var resp *client.SolveResponse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eg.Go(func() error {
 | 
						eg.Go(func() error {
 | 
				
			||||||
		defer close(done)
 | 
							defer close(done)
 | 
				
			||||||
		if _, err := c.client().Build(egCtx, &pb.BuildRequest{
 | 
							pbResp, err := c.client().Build(egCtx, &pb.BuildRequest{
 | 
				
			||||||
			Ref:     ref,
 | 
								Ref:     ref,
 | 
				
			||||||
			Options: &options,
 | 
								Options: &options,
 | 
				
			||||||
		}); err != nil {
 | 
							})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							resp = &client.SolveResponse{
 | 
				
			||||||
 | 
								ExporterResponse: pbResp.ExporterResponse,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	eg.Go(func() error {
 | 
						eg.Go(func() error {
 | 
				
			||||||
@@ -254,7 +264,7 @@ func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions,
 | 
				
			|||||||
			return eg2.Wait()
 | 
								return eg2.Wait()
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return eg.Wait()
 | 
						return resp, eg.Wait()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Client) client() pb.ControllerClient {
 | 
					func (c *Client) client() pb.ControllerClient {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,7 +141,7 @@ func serveCmd(dockerCli command.Cli) *cobra.Command {
 | 
				
			|||||||
			}()
 | 
								}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// prepare server
 | 
								// prepare server
 | 
				
			||||||
			b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (res *build.ResultContext, err error) {
 | 
								b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (*client.SolveResponse, *build.ResultContext, error) {
 | 
				
			||||||
				return cbuild.RunBuild(ctx, dockerCli, *options, stdin, "quiet", statusChan)
 | 
									return cbuild.RunBuild(ctx, dockerCli, *options, stdin, "quiet", statusChan)
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
			defer b.Close()
 | 
								defer b.Close()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"golang.org/x/sync/errgroup"
 | 
						"golang.org/x/sync/errgroup"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (res *build.ResultContext, err error)
 | 
					type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (resp *client.SolveResponse, res *build.ResultContext, err error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewServer(buildFunc BuildFunc) *Server {
 | 
					func NewServer(buildFunc BuildFunc) *Server {
 | 
				
			||||||
	return &Server{
 | 
						return &Server{
 | 
				
			||||||
@@ -150,7 +150,7 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
 | 
				
			|||||||
	// Build the specified request
 | 
						// Build the specified request
 | 
				
			||||||
	ctx, cancel := context.WithCancel(ctx)
 | 
						ctx, cancel := context.WithCancel(ctx)
 | 
				
			||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	res, err := m.buildFunc(ctx, req.Options, inR, statusChan)
 | 
						resp, res, err := m.buildFunc(ctx, req.Options, inR, statusChan)
 | 
				
			||||||
	m.sessionMu.Lock()
 | 
						m.sessionMu.Lock()
 | 
				
			||||||
	if s, ok := m.session[ref]; ok {
 | 
						if s, ok := m.session[ref]; ok {
 | 
				
			||||||
		s.result = res
 | 
							s.result = res
 | 
				
			||||||
@@ -162,7 +162,12 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	m.sessionMu.Unlock()
 | 
						m.sessionMu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &pb.BuildResponse{}, err
 | 
						if resp == nil {
 | 
				
			||||||
 | 
							resp = &client.SolveResponse{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &pb.BuildResponse{
 | 
				
			||||||
 | 
							ExporterResponse: resp.ExporterResponse,
 | 
				
			||||||
 | 
						}, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer) error {
 | 
					func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer) error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -121,7 +121,7 @@ func RunMonitor(ctx context.Context, curRef string, options controllerapi.BuildO
 | 
				
			|||||||
							fmt.Println("disconnect error", err)
 | 
												fmt.Println("disconnect error", err)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					ref, err := c.Build(ctx, options, nil, stdout, stderr, progressMode) // TODO: support stdin, hold build ref
 | 
										ref, _, err := c.Build(ctx, options, nil, stdout, stderr, progressMode) // TODO: support stdin, hold build ref
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						fmt.Printf("failed to reload: %v\n", err)
 | 
											fmt.Printf("failed to reload: %v\n", err)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,66 +15,66 @@ func CanonicalizeAttest(attestType string, in string) string {
 | 
				
			|||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if b, err := strconv.ParseBool(in); err == nil {
 | 
						if b, err := strconv.ParseBool(in); err == nil {
 | 
				
			||||||
		return fmt.Sprintf("type=%s,enabled=%t", attestType, b)
 | 
							return fmt.Sprintf("type=%s,disabled=%t", attestType, !b)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return fmt.Sprintf("type=%s,%s", attestType, in)
 | 
						return fmt.Sprintf("type=%s,%s", attestType, in)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseAttests(in []string) (map[string]*string, error) {
 | 
					func ParseAttests(in []string) ([]*controllerapi.Attest, error) {
 | 
				
			||||||
	out := map[string]*string{}
 | 
						out := []*controllerapi.Attest{}
 | 
				
			||||||
 | 
						found := map[string]struct{}{}
 | 
				
			||||||
	for _, in := range in {
 | 
						for _, in := range in {
 | 
				
			||||||
		in := in
 | 
							in := in
 | 
				
			||||||
		attestType, enabled, err := parseAttest(in)
 | 
							attest, err := parseAttest(in)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		k := "attest:" + attestType
 | 
							if _, ok := found[attest.Type]; ok {
 | 
				
			||||||
		if _, ok := out[k]; ok {
 | 
								return nil, errors.Errorf("duplicate attestation field %s", attest.Type)
 | 
				
			||||||
			return nil, errors.Errorf("duplicate attestation field %s", attestType)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if enabled {
 | 
					 | 
				
			||||||
			out[k] = &in
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			out[k] = nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							found[attest.Type] = struct{}{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							out = append(out, attest)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return out, nil
 | 
						return out, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseAttest(in string) (string, bool, error) {
 | 
					func parseAttest(in string) (*controllerapi.Attest, error) {
 | 
				
			||||||
	if in == "" {
 | 
						if in == "" {
 | 
				
			||||||
		return "", false, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	csvReader := csv.NewReader(strings.NewReader(in))
 | 
						csvReader := csv.NewReader(strings.NewReader(in))
 | 
				
			||||||
	fields, err := csvReader.Read()
 | 
						fields, err := csvReader.Read()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", false, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	attestType := ""
 | 
						attest := controllerapi.Attest{
 | 
				
			||||||
	enabled := true
 | 
							Attrs: in,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	for _, field := range fields {
 | 
						for _, field := range fields {
 | 
				
			||||||
		key, value, ok := strings.Cut(field, "=")
 | 
							key, value, ok := strings.Cut(field, "=")
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			return "", false, errors.Errorf("invalid value %s", field)
 | 
								return nil, errors.Errorf("invalid value %s", field)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		key = strings.TrimSpace(strings.ToLower(key))
 | 
							key = strings.TrimSpace(strings.ToLower(key))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch key {
 | 
							switch key {
 | 
				
			||||||
		case "type":
 | 
							case "type":
 | 
				
			||||||
			attestType = value
 | 
								attest.Type = value
 | 
				
			||||||
		case "enabled":
 | 
							case "disabled":
 | 
				
			||||||
			enabled, err = strconv.ParseBool(value)
 | 
								disabled, err := strconv.ParseBool(value)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return "", false, err
 | 
									return nil, errors.Wrapf(err, "invalid value %s", field)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								attest.Disabled = disabled
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if attestType == "" {
 | 
						if attest.Type == "" {
 | 
				
			||||||
		return "", false, errors.Errorf("attestation type not specified")
 | 
							return nil, errors.Errorf("attestation type not specified")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return attestType, enabled, nil
 | 
						return &attest, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,12 +7,12 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	awsconfig "github.com/aws/aws-sdk-go-v2/config"
 | 
						awsconfig "github.com/aws/aws-sdk-go-v2/config"
 | 
				
			||||||
	"github.com/moby/buildkit/client"
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) {
 | 
					func ParseCacheEntry(in []string) ([]*controllerapi.CacheOptionsEntry, error) {
 | 
				
			||||||
	imports := make([]client.CacheOptionsEntry, 0, len(in))
 | 
						outs := make([]*controllerapi.CacheOptionsEntry, 0, len(in))
 | 
				
			||||||
	for _, in := range in {
 | 
						for _, in := range in {
 | 
				
			||||||
		csvReader := csv.NewReader(strings.NewReader(in))
 | 
							csvReader := csv.NewReader(strings.NewReader(in))
 | 
				
			||||||
		fields, err := csvReader.Read()
 | 
							fields, err := csvReader.Read()
 | 
				
			||||||
@@ -21,14 +21,15 @@ func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		if isRefOnlyFormat(fields) {
 | 
							if isRefOnlyFormat(fields) {
 | 
				
			||||||
			for _, field := range fields {
 | 
								for _, field := range fields {
 | 
				
			||||||
				imports = append(imports, client.CacheOptionsEntry{
 | 
									outs = append(outs, &controllerapi.CacheOptionsEntry{
 | 
				
			||||||
					Type:  "registry",
 | 
										Type:  "registry",
 | 
				
			||||||
					Attrs: map[string]string{"ref": field},
 | 
										Attrs: map[string]string{"ref": field},
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		im := client.CacheOptionsEntry{
 | 
					
 | 
				
			||||||
 | 
							out := controllerapi.CacheOptionsEntry{
 | 
				
			||||||
			Attrs: map[string]string{},
 | 
								Attrs: map[string]string{},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, field := range fields {
 | 
							for _, field := range fields {
 | 
				
			||||||
@@ -40,21 +41,21 @@ func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) {
 | 
				
			|||||||
			value := parts[1]
 | 
								value := parts[1]
 | 
				
			||||||
			switch key {
 | 
								switch key {
 | 
				
			||||||
			case "type":
 | 
								case "type":
 | 
				
			||||||
				im.Type = value
 | 
									out.Type = value
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				im.Attrs[key] = value
 | 
									out.Attrs[key] = value
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if im.Type == "" {
 | 
							if out.Type == "" {
 | 
				
			||||||
			return nil, errors.Errorf("type required form> %q", in)
 | 
								return nil, errors.Errorf("type required form> %q", in)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if !addGithubToken(&im) {
 | 
							if !addGithubToken(&out) {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		addAwsCredentials(&im)
 | 
							addAwsCredentials(&out)
 | 
				
			||||||
		imports = append(imports, im)
 | 
							outs = append(outs, &out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return imports, nil
 | 
						return outs, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func isRefOnlyFormat(in []string) bool {
 | 
					func isRefOnlyFormat(in []string) bool {
 | 
				
			||||||
@@ -66,7 +67,7 @@ func isRefOnlyFormat(in []string) bool {
 | 
				
			|||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addGithubToken(ci *client.CacheOptionsEntry) bool {
 | 
					func addGithubToken(ci *controllerapi.CacheOptionsEntry) bool {
 | 
				
			||||||
	if ci.Type != "gha" {
 | 
						if ci.Type != "gha" {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -83,7 +84,7 @@ func addGithubToken(ci *client.CacheOptionsEntry) bool {
 | 
				
			|||||||
	return ci.Attrs["token"] != "" && ci.Attrs["url"] != ""
 | 
						return ci.Attrs["token"] != "" && ci.Attrs["url"] != ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addAwsCredentials(ci *client.CacheOptionsEntry) {
 | 
					func addAwsCredentials(ci *controllerapi.CacheOptionsEntry) {
 | 
				
			||||||
	if ci.Type != "s3" {
 | 
						if ci.Type != "s3" {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								util/buildflags/context.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								util/buildflags/context.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					package buildflags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/docker/distribution/reference"
 | 
				
			||||||
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ParseContextNames(values []string) (map[string]string, error) {
 | 
				
			||||||
 | 
						if len(values) == 0 {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result := make(map[string]string, len(values))
 | 
				
			||||||
 | 
						for _, value := range values {
 | 
				
			||||||
 | 
							kv := strings.SplitN(value, "=", 2)
 | 
				
			||||||
 | 
							if len(kv) != 2 {
 | 
				
			||||||
 | 
								return nil, errors.Errorf("invalid context value: %s, expected key=value", value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							named, err := reference.ParseNormalizedNamed(kv[0])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, errors.Wrapf(err, "invalid context name %s", kv[0])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							name := strings.TrimSuffix(reference.FamiliarString(named), ":latest")
 | 
				
			||||||
 | 
							result[name] = kv[1]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								util/buildflags/export.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								util/buildflags/export.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					package buildflags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/csv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/client"
 | 
				
			||||||
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ParseExports(inp []string) ([]*controllerapi.ExportEntry, error) {
 | 
				
			||||||
 | 
						var outs []*controllerapi.ExportEntry
 | 
				
			||||||
 | 
						if len(inp) == 0 {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, s := range inp {
 | 
				
			||||||
 | 
							csvReader := csv.NewReader(strings.NewReader(s))
 | 
				
			||||||
 | 
							fields, err := csvReader.Read()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							out := controllerapi.ExportEntry{
 | 
				
			||||||
 | 
								Attrs: map[string]string{},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(fields) == 1 && fields[0] == s && !strings.HasPrefix(s, "type=") {
 | 
				
			||||||
 | 
								if s != "-" {
 | 
				
			||||||
 | 
									outs = append(outs, &controllerapi.ExportEntry{
 | 
				
			||||||
 | 
										Type:        client.ExporterLocal,
 | 
				
			||||||
 | 
										Destination: s,
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								out = controllerapi.ExportEntry{
 | 
				
			||||||
 | 
									Type:        client.ExporterTar,
 | 
				
			||||||
 | 
									Destination: s,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if out.Type == "" {
 | 
				
			||||||
 | 
								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":
 | 
				
			||||||
 | 
										out.Type = value
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										out.Attrs[key] = value
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if out.Type == "" {
 | 
				
			||||||
 | 
								return nil, errors.Errorf("type is required for output")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if out.Type == "registry" {
 | 
				
			||||||
 | 
								out.Type = client.ExporterImage
 | 
				
			||||||
 | 
								if _, ok := out.Attrs["push"]; !ok {
 | 
				
			||||||
 | 
									out.Attrs["push"] = "true"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if dest, ok := out.Attrs["dest"]; ok {
 | 
				
			||||||
 | 
								out.Destination = dest
 | 
				
			||||||
 | 
								delete(out.Attrs, "dest")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							outs = append(outs, &out)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return outs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,35 +4,30 @@ import (
 | 
				
			|||||||
	"encoding/csv"
 | 
						"encoding/csv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/moby/buildkit/session"
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
	"github.com/moby/buildkit/session/secrets/secretsprovider"
 | 
					 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseSecretSpecs(sl []string) (session.Attachable, error) {
 | 
					func ParseSecretSpecs(sl []string) ([]*controllerapi.Secret, error) {
 | 
				
			||||||
	fs := make([]secretsprovider.Source, 0, len(sl))
 | 
						fs := make([]*controllerapi.Secret, 0, len(sl))
 | 
				
			||||||
	for _, v := range sl {
 | 
						for _, v := range sl {
 | 
				
			||||||
		s, err := parseSecret(v)
 | 
							s, err := parseSecret(v)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fs = append(fs, *s)
 | 
							fs = append(fs, s)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	store, err := secretsprovider.NewStore(fs)
 | 
						return fs, nil
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return secretsprovider.NewSecretProvider(store), nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseSecret(value string) (*secretsprovider.Source, error) {
 | 
					func parseSecret(value string) (*controllerapi.Secret, error) {
 | 
				
			||||||
	csvReader := csv.NewReader(strings.NewReader(value))
 | 
						csvReader := csv.NewReader(strings.NewReader(value))
 | 
				
			||||||
	fields, err := csvReader.Read()
 | 
						fields, err := csvReader.Read()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, errors.Wrap(err, "failed to parse csv secret")
 | 
							return nil, errors.Wrap(err, "failed to parse csv secret")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fs := secretsprovider.Source{}
 | 
						fs := controllerapi.Secret{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var typ string
 | 
						var typ string
 | 
				
			||||||
	for _, field := range fields {
 | 
						for _, field := range fields {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,32 +3,27 @@ package buildflags
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/moby/buildkit/session"
 | 
						controllerapi "github.com/docker/buildx/controller/pb"
 | 
				
			||||||
	"github.com/moby/buildkit/session/sshforward/sshprovider"
 | 
					 | 
				
			||||||
	"github.com/moby/buildkit/util/gitutil"
 | 
						"github.com/moby/buildkit/util/gitutil"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseSSHSpecs(sl []string) (session.Attachable, error) {
 | 
					func ParseSSHSpecs(sl []string) ([]*controllerapi.SSH, error) {
 | 
				
			||||||
	configs := make([]sshprovider.AgentConfig, 0, len(sl))
 | 
						var outs []*controllerapi.SSH
 | 
				
			||||||
	for _, v := range sl {
 | 
						if len(sl) == 0 {
 | 
				
			||||||
		c, err := parseSSH(v)
 | 
							return nil, nil
 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		configs = append(configs, *c)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sshprovider.NewSSHAgentProvider(configs)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseSSH(value string) (*sshprovider.AgentConfig, error) {
 | 
						for _, s := range sl {
 | 
				
			||||||
	parts := strings.SplitN(value, "=", 2)
 | 
							parts := strings.SplitN(s, "=", 2)
 | 
				
			||||||
	cfg := sshprovider.AgentConfig{
 | 
							out := controllerapi.SSH{
 | 
				
			||||||
		ID: parts[0],
 | 
								ID: parts[0],
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(parts) > 1 {
 | 
				
			||||||
 | 
								out.Paths = strings.Split(parts[1], ",")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							outs = append(outs, &out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(parts) > 1 {
 | 
						return outs, nil
 | 
				
			||||||
		cfg.Paths = strings.Split(parts[1], ",")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &cfg, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsGitSSH returns true if the given repo URL is accessed over ssh
 | 
					// IsGitSSH returns true if the given repo URL is accessed over ssh
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user