diff --git a/bake/bake.go b/bake/bake.go index c3cf8ee5..1abf5f1b 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -14,6 +14,7 @@ import ( "github.com/docker/buildx/bake/hclparser" "github.com/docker/buildx/build" + controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/platformutil" "github.com/docker/cli/cli/config" @@ -978,17 +979,24 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { if err != nil { return nil, err } - bo.Session = append(bo.Session, secrets) + secretAttachment, err := controllerapi.CreateSecrets(secrets) + if err != nil { + return nil, err + } + bo.Session = append(bo.Session, secretAttachment) - sshSpecs := t.SSH + sshSpecs, err := buildflags.ParseSSHSpecs(t.SSH) + if err != nil { + return nil, err + } if len(sshSpecs) == 0 && buildflags.IsGitSSH(contextPath) { - sshSpecs = []string{"default"} + sshSpecs = append(sshSpecs, &controllerapi.SSH{ID: "default"}) } - ssh, err := buildflags.ParseSSHSpecs(sshSpecs) + sshAttachment, err := controllerapi.CreateSSH(sshSpecs) if err != nil { return nil, err } - bo.Session = append(bo.Session, ssh) + bo.Session = append(bo.Session, sshAttachment) if t.Target != nil { bo.Target = *t.Target @@ -998,25 +1006,28 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { if err != nil { return nil, err } - bo.CacheFrom = cacheImports + bo.CacheFrom = controllerapi.CreateCaches(cacheImports) cacheExports, err := buildflags.ParseCacheEntry(t.CacheTo) if err != nil { 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 { return nil, err } - bo.Exports = outputs attests, err := buildflags.ParseAttests(t.Attest) if err != nil { return nil, err } - bo.Attests = attests + bo.Attests = controllerapi.CreateAttestations(attests) return bo, nil } diff --git a/build/build.go b/build/build.go index 1e2df04c..aec66172 100644 --- a/build/build.go +++ b/build/build.go @@ -77,19 +77,19 @@ type Options struct { CgroupParent string Exports []client.ExportEntry ExtraHosts []string - ImageIDFile string Labels map[string]string NetworkMode string NoCache bool NoCacheFilter []string Platforms []specs.Platform Pull bool - Session []session.Attachable ShmSize opts.MemBytes Tags []string Target string Ulimits *opts.UlimitOpt + Session []session.Attachable + // Linked marks this target as exclusively linked (not requested by the user). Linked bool 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 if v, ok := opt.BuildArgs["BUILDKIT_INLINE_CACHE"]; ok { 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") } 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" var noProv bool 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 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] { 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] respMu.Unlock() 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 } @@ -1238,11 +1221,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s if err != nil { return err } - if opt.ImageIDFile != "" { - if err := os.WriteFile(opt.ImageIDFile, []byte(desc.Digest), 0644); err != nil { - return err - } - } itpush := imagetools.New(imageopt) @@ -1259,7 +1237,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s respMu.Lock() resp[k] = &client.SolveResponse{ ExporterResponse: map[string]string{ - "containerimage.digest": desc.Digest.String(), + exptypes.ExporterImageDigestKey: desc.Digest.String(), }, } respMu.Unlock() diff --git a/commands/bake.go b/commands/bake.go index 23ac82ed..c7f1461e 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -24,9 +24,11 @@ import ( ) type bakeOptions struct { - files []string - overrides []string - printOnly bool + files []string + overrides []string + printOnly bool + sbom string + provenance string controllerapi.CommonOptions } @@ -76,11 +78,11 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com if cFlags.pull != nil { overrides = append(overrides, fmt.Sprintf("*.pull=%t", *cFlags.pull)) } - if in.SBOM != "" { - overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("sbom", in.SBOM))) + if in.sbom != "" { + overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("sbom", in.sbom))) } - if in.Provenance != "" { - overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("provenance", in.Provenance))) + if in.provenance != "" { + overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("provenance", in.provenance))) } 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.printOnly, "print", false, "Print the options without building") 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.Provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`) + flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`) + 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")`) commonBuildFlags(&cFlags, flags) diff --git a/commands/build.go b/commands/build.go index 9cf8334b..90ce152f 100644 --- a/commands/build.go +++ b/commands/build.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/csv" "encoding/json" + "fmt" "io" "os" "runtime" @@ -19,14 +20,17 @@ import ( "github.com/docker/buildx/monitor" "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" + "github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/ioset" + "github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/tracing" "github.com/docker/cli-docs-tool/annotation" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" dockeropts "github.com/docker/cli/opts" "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/grpcerrors" "github.com/pkg/errors" @@ -37,12 +41,127 @@ import ( ) 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 - invoke string - controllerapi.BuildOptions + quiet bool + + controllerapi.CommonOptions 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 { ctx := appcontext.Context() @@ -54,12 +173,40 @@ func runBuild(dockerCli command.Cli, in buildOptions) error { end(err) }() - _, err = cbuild.RunBuild(ctx, dockerCli, in.BuildOptions, os.Stdin, in.progress, nil) - return err + opts, err := in.toControllerOptions() + 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 { - options := newBuildOptions() + options := buildOptions{} cFlags := &commonFlags{} cmd := &cobra.Command{ @@ -68,16 +215,16 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { Short: "Start a build", Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - options.ContextPath = args[0] - options.Opts.Builder = rootOpts.builder - options.Opts.MetadataFile = cFlags.metadataFile - options.Opts.NoCache = false + options.contextPath = args[0] + options.Builder = rootOpts.builder + options.MetadataFile = cFlags.metadataFile + options.NoCache = false if cFlags.noCache != nil { - options.Opts.NoCache = *cFlags.noCache + options.NoCache = *cFlags.noCache } - options.Opts.Pull = false + options.Pull = false if cFlags.pull != nil { - options.Opts.Pull = *cFlags.pull + options.Pull = *cFlags.pull } options.progress = cFlags.progress cmd.Flags().VisitAll(checkWarnedFlags) @@ -95,64 +242,65 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { 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.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.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.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() { - 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|[=|[,]]")`) + flags.StringArrayVar(&options.ssh, "ssh", []string{}, `SSH agent socket or keys to expose to the build (format: "default|[=|[,]]")`) - 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.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.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.StringVar(&options.Opts.SBOM, "sbom", "", `Shorthand for "--attest=type=sbom"`) - flags.StringVar(&options.Opts.Provenance, "provenance", "", `Shortand for "--attest=type=provenance"`) + flags.StringArrayVar(&options.attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`) + flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--attest=type=sbom"`) + flags.StringVar(&options.provenance, "provenance", "", `Shortand for "--attest=type=provenance"`) if isExperimental() { flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build [experimental]") @@ -317,12 +465,7 @@ func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error { func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) error { ctx := context.TODO() - if options.Quiet && options.progress != "auto" && options.progress != "quiet" { - 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 == "-") { + if options.invoke != "" && (options.dockerfileName == "-" || options.contextPath == "-") { // stdin must be usable for monitor 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) + 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 - 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 { 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") } + 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 if options.invoke != "" { 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) } - 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() if err := pw2.Close(); err != nil { 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 } -func newBuildOptions() buildOptions { - return buildOptions{ - BuildOptions: controllerapi.BuildOptions{ - Opts: &controllerapi.CommonOptions{}, - }, +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 newUlimits(opt *buildOptions) *ulimits { - ul := make(map[string]*units.Ulimit) - return &ulimits{opt: opt, org: dockeropts.NewUlimitOpt(&ul)} -} - -type ulimits struct { - opt *buildOptions - org *dockeropts.UlimitOpt -} - -func (u *ulimits) sync() { - du := &controllerapi.UlimitOpt{ - Values: make(map[string]*controllerapi.Ulimit), +func dockerUlimitToControllerUlimit(u *dockeropts.UlimitOpt) *controllerapi.UlimitOpt { + if u == nil { + return nil } - for _, l := range u.org.GetList() { - du.Values[l.Name] = &controllerapi.Ulimit{ - Name: l.Name, - Hard: l.Hard, - Soft: l.Soft, + values := make(map[string]*controllerapi.Ulimit) + for _, u := range u.GetList() { + values[u.Name] = &controllerapi.Ulimit{ + Name: u.Name, + Hard: u.Hard, + Soft: u.Soft, } } - u.opt.Ulimits = du -} - -func (u *ulimits) String() string { - return u.org.String() -} - -func (u *ulimits) Set(v string) error { - err := u.org.Set(v) - u.sync() - return err -} - -func (u *ulimits) Type() string { - return u.org.Type() -} - -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() + return &controllerapi.UlimitOpt{Values: values} } diff --git a/controller/build/build.go b/controller/build/build.go index f9c659cc..12fa8580 100644 --- a/controller/build/build.go +++ b/controller/build/build.go @@ -26,7 +26,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config" dockeropts "github.com/docker/cli/opts" - "github.com/docker/distribution/reference" "github.com/docker/docker/pkg/ioutils" "github.com/docker/go-units" "github.com/moby/buildkit/client" @@ -42,25 +41,19 @@ import ( 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 { - 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 { - return nil, errors.Errorf("progress=%s and quiet cannot be used together", progressMode) - } else if in.Quiet { - progressMode = "quiet" - } - - contexts, err := parseContextNames(in.Contexts) - if err != nil { - return nil, err + contexts := map[string]build.NamedContext{} + for name, path := range in.NamedContexts { + contexts[name] = build.NamedContext{Path: path} } printFunc, err := parsePrintFunc(in.PrintFunc) if err != nil { - return nil, err + return nil, nil, err } opts := build.Options{ @@ -70,10 +63,9 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build InStream: inStream, NamedContexts: contexts, }, - BuildArgs: listToMap(in.BuildArgs, true), + BuildArgs: in.BuildArgs, ExtraHosts: in.ExtraHosts, - ImageIDFile: in.ImageIDFile, - Labels: listToMap(in.Labels, false), + Labels: in.Labels, NetworkMode: in.NetworkMode, NoCache: in.Opts.NoCache, NoCacheFilter: in.NoCacheFilter, @@ -87,36 +79,36 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build platforms, err := platformutil.Parse(in.Platforms) if err != nil { - return nil, err + return nil, nil, err } opts.Platforms = platforms dockerConfig := config.LoadDefaultConfigFile(os.Stderr) opts.Session = append(opts.Session, authprovider.NewDockerAuthProvider(dockerConfig)) - secrets, err := buildflags.ParseSecretSpecs(in.Secrets) + secrets, err := controllerapi.CreateSecrets(in.Secrets) if err != nil { - return nil, err + return nil, nil, err } opts.Session = append(opts.Session, secrets) sshSpecs := in.SSH 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 { - return nil, err + return nil, nil, err } opts.Session = append(opts.Session, ssh) - outputs, err := buildflags.ParseOutputs(in.Outputs) + outputs, err := controllerapi.CreateExports(in.Exports) if err != nil { - return nil, err + return nil, nil, err } if in.Opts.ExportPush { 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 { outputs = []client.ExportEntry{{ @@ -130,7 +122,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build case "image": outputs[0].Attrs["push"] = "true" 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 { case "docker": 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 - inAttests := append([]string{}, in.Attests...) - if in.Opts.Provenance != "" { - 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) - if err != nil { - return nil, err - } - opts.CacheFrom = cacheImports + opts.CacheFrom = controllerapi.CreateCaches(in.CacheFrom) + opts.CacheTo = controllerapi.CreateCaches(in.CacheTo) - cacheExports, err := buildflags.ParseCacheEntry(in.CacheTo) - if err != nil { - return nil, err - } - opts.CacheTo = cacheExports + opts.Attests = controllerapi.CreateAttestations(in.Attests) allow, err := buildflags.ParseEntitlements(in.Allow) if err != nil { - return nil, err + return nil, nil, err } opts.Allow = allow @@ -191,29 +164,25 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build builder.WithContextPathHash(contextPathHash), ) if err != nil { - return nil, err + return nil, nil, err } 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) 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) if err != nil { - return nil, err - } - - if in.Quiet { - fmt.Println(imageID) + return nil, nil, err } - return res, nil + return resp, 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()) 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), )) if err != nil { - return "", nil, err + return nil, nil, err } + var res *build.ResultContext var mu sync.Mutex 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) { @@ -239,12 +209,12 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou err = err1 } if err != nil { - return "", nil, err + return nil, nil, err } if len(metadataFile) > 0 && resp != 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 { if opts[k].PrintFunc != 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) { @@ -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) { if str == "" { return nil, nil diff --git a/controller/control/controller.go b/controller/control/controller.go index 343f2bbf..eb9b83a9 100644 --- a/controller/control/controller.go +++ b/controller/control/controller.go @@ -6,14 +6,15 @@ import ( "github.com/containerd/console" controllerapi "github.com/docker/buildx/controller/pb" + "github.com/moby/buildkit/client" ) 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, err 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) + 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 Close() error - List(ctx context.Context) (res []string, _ error) + List(ctx context.Context) (refs []string, _ error) Disconnect(ctx context.Context, ref string) error } diff --git a/controller/local/controller.go b/controller/local/controller.go index cdcfd75a..3ec8a177 100644 --- a/controller/local/controller.go +++ b/controller/local/controller.go @@ -10,6 +10,7 @@ import ( "github.com/docker/buildx/controller/control" controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/cli/cli/command" + "github.com/moby/buildkit/client" "github.com/pkg/errors" ) @@ -26,6 +27,15 @@ type localController struct { 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 { if ref != b.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) } -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 { return nil // nop } diff --git a/controller/pb/attest.go b/controller/pb/attest.go new file mode 100644 index 00000000..06a7c945 --- /dev/null +++ b/controller/pb/attest.go @@ -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 +} diff --git a/controller/pb/cache.go b/controller/pb/cache.go new file mode 100644 index 00000000..4b7c2b75 --- /dev/null +++ b/controller/pb/cache.go @@ -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 +} diff --git a/controller/pb/controller.pb.go b/controller/pb/controller.pb.go index 7641cfb1..55c0a737 100644 --- a/controller/pb/controller.pb.go +++ b/controller/pb/controller.pb.go @@ -72,35 +72,32 @@ func (m *BuildRequest) GetOptions() *BuildOptions { } type BuildOptions struct { - ContextPath string `protobuf:"bytes,1,opt,name=ContextPath,proto3" json:"ContextPath,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"` - Allow []string `protobuf:"bytes,4,rep,name=Allow,proto3" json:"Allow,omitempty"` - Attests []string `protobuf:"bytes,5,rep,name=Attests,proto3" json:"Attests,omitempty"` - BuildArgs []string `protobuf:"bytes,6,rep,name=BuildArgs,proto3" json:"BuildArgs,omitempty"` - CacheFrom []string `protobuf:"bytes,7,rep,name=CacheFrom,proto3" json:"CacheFrom,omitempty"` - CacheTo []string `protobuf:"bytes,8,rep,name=CacheTo,proto3" json:"CacheTo,omitempty"` - CgroupParent string `protobuf:"bytes,9,opt,name=CgroupParent,proto3" json:"CgroupParent,omitempty"` - Contexts []string `protobuf:"bytes,10,rep,name=Contexts,proto3" json:"Contexts,omitempty"` - ExtraHosts []string `protobuf:"bytes,11,rep,name=ExtraHosts,proto3" json:"ExtraHosts,omitempty"` - ImageIDFile string `protobuf:"bytes,12,opt,name=ImageIDFile,proto3" json:"ImageIDFile,omitempty"` - Labels []string `protobuf:"bytes,13,rep,name=Labels,proto3" json:"Labels,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"` - Outputs []string `protobuf:"bytes,16,rep,name=Outputs,proto3" json:"Outputs,omitempty"` - Platforms []string `protobuf:"bytes,17,rep,name=Platforms,proto3" json:"Platforms,omitempty"` - Quiet bool `protobuf:"varint,18,opt,name=Quiet,proto3" json:"Quiet,omitempty"` - Secrets []string `protobuf:"bytes,19,rep,name=Secrets,proto3" json:"Secrets,omitempty"` - ShmSize int64 `protobuf:"varint,20,opt,name=ShmSize,proto3" json:"ShmSize,omitempty"` - SSH []string `protobuf:"bytes,21,rep,name=SSH,proto3" json:"SSH,omitempty"` - Tags []string `protobuf:"bytes,22,rep,name=Tags,proto3" json:"Tags,omitempty"` - Target string `protobuf:"bytes,23,opt,name=Target,proto3" json:"Target,omitempty"` - Ulimits *UlimitOpt `protobuf:"bytes,24,opt,name=Ulimits,proto3" json:"Ulimits,omitempty"` - // string Invoke: provided via Invoke API - Opts *CommonOptions `protobuf:"bytes,25,opt,name=Opts,proto3" json:"Opts,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ContextPath string `protobuf:"bytes,1,opt,name=ContextPath,proto3" json:"ContextPath,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"` + 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"` + Allow []string `protobuf:"bytes,5,rep,name=Allow,proto3" json:"Allow,omitempty"` + Attests []*Attest `protobuf:"bytes,6,rep,name=Attests,proto3" json:"Attests,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"` + CacheFrom []*CacheOptionsEntry `protobuf:"bytes,8,rep,name=CacheFrom,proto3" json:"CacheFrom,omitempty"` + CacheTo []*CacheOptionsEntry `protobuf:"bytes,9,rep,name=CacheTo,proto3" json:"CacheTo,omitempty"` + CgroupParent string `protobuf:"bytes,10,opt,name=CgroupParent,proto3" json:"CgroupParent,omitempty"` + Exports []*ExportEntry `protobuf:"bytes,11,rep,name=Exports,proto3" json:"Exports,omitempty"` + ExtraHosts []string `protobuf:"bytes,12,rep,name=ExtraHosts,proto3" json:"ExtraHosts,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"` + NoCacheFilter []string `protobuf:"bytes,15,rep,name=NoCacheFilter,proto3" json:"NoCacheFilter,omitempty"` + Platforms []string `protobuf:"bytes,16,rep,name=Platforms,proto3" json:"Platforms,omitempty"` + Secrets []*Secret `protobuf:"bytes,17,rep,name=Secrets,proto3" json:"Secrets,omitempty"` + ShmSize int64 `protobuf:"varint,18,opt,name=ShmSize,proto3" json:"ShmSize,omitempty"` + SSH []*SSH `protobuf:"bytes,19,rep,name=SSH,proto3" json:"SSH,omitempty"` + Tags []string `protobuf:"bytes,20,rep,name=Tags,proto3" json:"Tags,omitempty"` + Target string `protobuf:"bytes,21,opt,name=Target,proto3" json:"Target,omitempty"` + Ulimits *UlimitOpt `protobuf:"bytes,22,opt,name=Ulimits,proto3" json:"Ulimits,omitempty"` + Opts *CommonOptions `protobuf:"bytes,24,opt,name=Opts,proto3" json:"Opts,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BuildOptions) Reset() { *m = BuildOptions{} } @@ -148,6 +145,13 @@ func (m *BuildOptions) GetPrintFunc() string { return "" } +func (m *BuildOptions) GetNamedContexts() map[string]string { + if m != nil { + return m.NamedContexts + } + return nil +} + func (m *BuildOptions) GetAllow() []string { if m != nil { return m.Allow @@ -155,28 +159,28 @@ func (m *BuildOptions) GetAllow() []string { return nil } -func (m *BuildOptions) GetAttests() []string { +func (m *BuildOptions) GetAttests() []*Attest { if m != nil { return m.Attests } return nil } -func (m *BuildOptions) GetBuildArgs() []string { +func (m *BuildOptions) GetBuildArgs() map[string]string { if m != nil { return m.BuildArgs } return nil } -func (m *BuildOptions) GetCacheFrom() []string { +func (m *BuildOptions) GetCacheFrom() []*CacheOptionsEntry { if m != nil { return m.CacheFrom } return nil } -func (m *BuildOptions) GetCacheTo() []string { +func (m *BuildOptions) GetCacheTo() []*CacheOptionsEntry { if m != nil { return m.CacheTo } @@ -190,9 +194,9 @@ func (m *BuildOptions) GetCgroupParent() string { return "" } -func (m *BuildOptions) GetContexts() []string { +func (m *BuildOptions) GetExports() []*ExportEntry { if m != nil { - return m.Contexts + return m.Exports } return nil } @@ -204,14 +208,7 @@ func (m *BuildOptions) GetExtraHosts() []string { return nil } -func (m *BuildOptions) GetImageIDFile() string { - if m != nil { - return m.ImageIDFile - } - return "" -} - -func (m *BuildOptions) GetLabels() []string { +func (m *BuildOptions) GetLabels() map[string]string { if m != nil { return m.Labels } @@ -232,13 +229,6 @@ func (m *BuildOptions) GetNoCacheFilter() []string { return nil } -func (m *BuildOptions) GetOutputs() []string { - if m != nil { - return m.Outputs - } - return nil -} - func (m *BuildOptions) GetPlatforms() []string { if m != nil { return m.Platforms @@ -246,14 +236,7 @@ func (m *BuildOptions) GetPlatforms() []string { return nil } -func (m *BuildOptions) GetQuiet() bool { - if m != nil { - return m.Quiet - } - return false -} - -func (m *BuildOptions) GetSecrets() []string { +func (m *BuildOptions) GetSecrets() []*Secret { if m != nil { return m.Secrets } @@ -267,7 +250,7 @@ func (m *BuildOptions) GetShmSize() int64 { return 0 } -func (m *BuildOptions) GetSSH() []string { +func (m *BuildOptions) GetSSH() []*SSH { if m != nil { return m.SSH } @@ -302,6 +285,260 @@ func (m *BuildOptions) GetOpts() *CommonOptions { 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 { 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:"-"` @@ -313,7 +550,7 @@ func (m *UlimitOpt) Reset() { *m = UlimitOpt{} } func (m *UlimitOpt) String() string { return proto.CompactTextString(m) } func (*UlimitOpt) ProtoMessage() {} func (*UlimitOpt) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{2} + return fileDescriptor_ed7f10298fa1d90f, []int{7} } func (m *UlimitOpt) XXX_Unmarshal(b []byte) error { 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 (*Ulimit) ProtoMessage() {} func (*Ulimit) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{3} + return fileDescriptor_ed7f10298fa1d90f, []int{8} } func (m *Ulimit) XXX_Unmarshal(b []byte) error { 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"` ExportPush bool `protobuf:"varint,5,opt,name=ExportPush,proto3" json:"ExportPush,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_unrecognized []byte `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 (*CommonOptions) ProtoMessage() {} func (*CommonOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{4} + return fileDescriptor_ed7f10298fa1d90f, []int{9} } func (m *CommonOptions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommonOptions.Unmarshal(m, b) @@ -475,31 +710,18 @@ func (m *CommonOptions) GetExportLoad() bool { 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 { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `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_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BuildResponse) Reset() { *m = BuildResponse{} } func (m *BuildResponse) String() string { return proto.CompactTextString(m) } func (*BuildResponse) ProtoMessage() {} func (*BuildResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{5} + return fileDescriptor_ed7f10298fa1d90f, []int{10} } func (m *BuildResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BuildResponse.Unmarshal(m, b) @@ -519,6 +741,13 @@ func (m *BuildResponse) XXX_DiscardUnknown() { var xxx_messageInfo_BuildResponse proto.InternalMessageInfo +func (m *BuildResponse) GetExporterResponse() map[string]string { + if m != nil { + return m.ExporterResponse + } + return nil +} + type DisconnectRequest struct { Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -530,7 +759,7 @@ func (m *DisconnectRequest) Reset() { *m = DisconnectRequest{} } func (m *DisconnectRequest) String() string { return proto.CompactTextString(m) } func (*DisconnectRequest) ProtoMessage() {} func (*DisconnectRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{6} + return fileDescriptor_ed7f10298fa1d90f, []int{11} } func (m *DisconnectRequest) XXX_Unmarshal(b []byte) error { 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 (*DisconnectResponse) ProtoMessage() {} func (*DisconnectResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{7} + return fileDescriptor_ed7f10298fa1d90f, []int{12} } func (m *DisconnectResponse) XXX_Unmarshal(b []byte) error { 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 (*ListRequest) ProtoMessage() {} func (*ListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{8} + return fileDescriptor_ed7f10298fa1d90f, []int{13} } func (m *ListRequest) XXX_Unmarshal(b []byte) error { 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 (*ListResponse) ProtoMessage() {} func (*ListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{9} + return fileDescriptor_ed7f10298fa1d90f, []int{14} } func (m *ListResponse) XXX_Unmarshal(b []byte) error { 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 (*InputMessage) ProtoMessage() {} func (*InputMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{10} + return fileDescriptor_ed7f10298fa1d90f, []int{15} } func (m *InputMessage) XXX_Unmarshal(b []byte) error { 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 (*InputInitMessage) ProtoMessage() {} func (*InputInitMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{11} + return fileDescriptor_ed7f10298fa1d90f, []int{16} } func (m *InputInitMessage) XXX_Unmarshal(b []byte) error { 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 (*DataMessage) ProtoMessage() {} func (*DataMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{12} + return fileDescriptor_ed7f10298fa1d90f, []int{17} } func (m *DataMessage) XXX_Unmarshal(b []byte) error { 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 (*InputResponse) ProtoMessage() {} func (*InputResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{13} + return fileDescriptor_ed7f10298fa1d90f, []int{18} } func (m *InputResponse) XXX_Unmarshal(b []byte) error { 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 (*Message) ProtoMessage() {} func (*Message) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{14} + return fileDescriptor_ed7f10298fa1d90f, []int{19} } func (m *Message) XXX_Unmarshal(b []byte) error { 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 (*InitMessage) ProtoMessage() {} func (*InitMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{15} + return fileDescriptor_ed7f10298fa1d90f, []int{20} } func (m *InitMessage) XXX_Unmarshal(b []byte) error { 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 (*ContainerConfig) ProtoMessage() {} func (*ContainerConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{16} + return fileDescriptor_ed7f10298fa1d90f, []int{21} } func (m *ContainerConfig) XXX_Unmarshal(b []byte) error { 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 (*FdMessage) ProtoMessage() {} func (*FdMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{17} + return fileDescriptor_ed7f10298fa1d90f, []int{22} } func (m *FdMessage) XXX_Unmarshal(b []byte) error { 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 (*ResizeMessage) ProtoMessage() {} func (*ResizeMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{18} + return fileDescriptor_ed7f10298fa1d90f, []int{23} } func (m *ResizeMessage) XXX_Unmarshal(b []byte) error { 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 (*SignalMessage) ProtoMessage() {} func (*SignalMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{19} + return fileDescriptor_ed7f10298fa1d90f, []int{24} } func (m *SignalMessage) XXX_Unmarshal(b []byte) error { 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 (*StatusRequest) ProtoMessage() {} func (*StatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{20} + return fileDescriptor_ed7f10298fa1d90f, []int{25} } func (m *StatusRequest) XXX_Unmarshal(b []byte) error { 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 (*StatusResponse) ProtoMessage() {} func (*StatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{21} + return fileDescriptor_ed7f10298fa1d90f, []int{26} } func (m *StatusResponse) XXX_Unmarshal(b []byte) error { 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 (*InfoRequest) ProtoMessage() {} func (*InfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{22} + return fileDescriptor_ed7f10298fa1d90f, []int{27} } func (m *InfoRequest) XXX_Unmarshal(b []byte) error { 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 (*InfoResponse) ProtoMessage() {} func (*InfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{23} + return fileDescriptor_ed7f10298fa1d90f, []int{28} } func (m *InfoResponse) XXX_Unmarshal(b []byte) error { 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 (*BuildxVersion) ProtoMessage() {} func (*BuildxVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{24} + return fileDescriptor_ed7f10298fa1d90f, []int{29} } func (m *BuildxVersion) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BuildxVersion.Unmarshal(m, b) @@ -1462,11 +1691,22 @@ func (m *BuildxVersion) GetRevision() string { func init() { proto.RegisterType((*BuildRequest)(nil), "buildx.controller.v1.BuildRequest") 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.RegisterMapType((map[string]*Ulimit)(nil), "buildx.controller.v1.UlimitOpt.ValuesEntry") proto.RegisterType((*Ulimit)(nil), "buildx.controller.v1.Ulimit") proto.RegisterType((*CommonOptions)(nil), "buildx.controller.v1.CommonOptions") 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((*DisconnectResponse)(nil), "buildx.controller.v1.DisconnectResponse") proto.RegisterType((*ListRequest)(nil), "buildx.controller.v1.ListRequest") @@ -1491,97 +1731,111 @@ func init() { func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) } var fileDescriptor_ed7f10298fa1d90f = []byte{ - // 1436 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0xdd, 0x52, 0x1b, 0xc7, - 0x12, 0x3e, 0x8b, 0x84, 0x7e, 0x5a, 0x08, 0xe3, 0x39, 0x1c, 0x9f, 0x39, 0x3a, 0x8e, 0x8d, 0x17, - 0xdb, 0x51, 0x55, 0xaa, 0x84, 0x83, 0x93, 0x72, 0x62, 0x3b, 0x17, 0x20, 0xa0, 0x20, 0xc5, 0x5f, - 0x16, 0x6c, 0x57, 0x72, 0x11, 0xd7, 0x22, 0x0d, 0x62, 0x4b, 0xab, 0x1d, 0x65, 0x67, 0x24, 0x20, - 0x57, 0x79, 0x82, 0x5c, 0xe4, 0x2d, 0xf2, 0x0c, 0x79, 0x8d, 0xbc, 0x47, 0xf2, 0x08, 0xa9, 0xee, - 0x99, 0x5d, 0x56, 0x58, 0x2b, 0x5f, 0x69, 0xfa, 0x9b, 0xef, 0xeb, 0x99, 0xee, 0xe9, 0xe9, 0x59, - 0xc1, 0x52, 0x47, 0x46, 0x3a, 0x96, 0x61, 0x28, 0xe2, 0xd6, 0x30, 0x96, 0x5a, 0xb2, 0xe5, 0xb3, - 0x51, 0x10, 0x76, 0xaf, 0x5a, 0x99, 0x89, 0xf1, 0xe7, 0x8d, 0x57, 0xbd, 0x40, 0x5f, 0x8c, 0xce, - 0x5a, 0x1d, 0x39, 0x58, 0x1b, 0xc8, 0xb3, 0xeb, 0x35, 0x62, 0xf5, 0x03, 0xbd, 0xe6, 0x0f, 0x83, - 0x35, 0x25, 0xe2, 0x71, 0xd0, 0x11, 0x6a, 0xcd, 0x8a, 0x92, 0x5f, 0xe3, 0xd2, 0xfd, 0x11, 0x16, - 0x36, 0x91, 0xee, 0x89, 0x9f, 0x46, 0x42, 0x69, 0xb6, 0x04, 0x05, 0x4f, 0x9c, 0x73, 0x67, 0xc5, - 0x69, 0x56, 0x3d, 0x1c, 0xb2, 0xd7, 0x50, 0x3e, 0x1a, 0xea, 0x40, 0x46, 0x8a, 0xcf, 0xad, 0x38, - 0xcd, 0xda, 0xba, 0xdb, 0x9a, 0xb6, 0x8d, 0x16, 0xb9, 0xb1, 0x4c, 0x2f, 0x91, 0xb8, 0xbf, 0x95, - 0xec, 0x02, 0x16, 0x60, 0x2b, 0x50, 0x6b, 0xcb, 0x48, 0x8b, 0x2b, 0x7d, 0xec, 0xeb, 0x0b, 0xbb, - 0x50, 0x16, 0x62, 0x4f, 0x61, 0x71, 0x4b, 0x76, 0xfa, 0x22, 0x3e, 0x0f, 0x42, 0x71, 0xe8, 0x0f, - 0x04, 0xad, 0x5b, 0xf5, 0x6e, 0xa1, 0xec, 0x3e, 0x54, 0x8f, 0xe3, 0x20, 0xd2, 0x3b, 0xa3, 0xa8, - 0xc3, 0x0b, 0x44, 0xb9, 0x01, 0xd8, 0x32, 0xcc, 0x6f, 0x84, 0xa1, 0xbc, 0xe4, 0xc5, 0x95, 0x42, - 0xb3, 0xea, 0x19, 0x83, 0x71, 0x28, 0x6f, 0x68, 0x2d, 0x94, 0x56, 0x7c, 0x9e, 0xf0, 0xc4, 0x44, - 0x6f, 0xb4, 0xcf, 0x8d, 0xb8, 0xa7, 0x78, 0x89, 0xe6, 0x6e, 0x00, 0x9c, 0x6d, 0xfb, 0x9d, 0x0b, - 0xb1, 0x13, 0xcb, 0x01, 0x2f, 0x9b, 0xd9, 0x14, 0x40, 0xaf, 0x64, 0x9c, 0x4a, 0x5e, 0x31, 0x5e, - 0xad, 0xc9, 0x5c, 0x58, 0x68, 0xf7, 0x62, 0x39, 0x1a, 0x1e, 0xfb, 0xb1, 0x88, 0x34, 0xaf, 0xd2, - 0x36, 0x27, 0x30, 0xd6, 0x80, 0x8a, 0x0d, 0x5f, 0x71, 0x20, 0x79, 0x6a, 0xb3, 0x07, 0x00, 0xdb, - 0x57, 0x3a, 0xf6, 0x77, 0x25, 0x6e, 0xb9, 0x46, 0xb3, 0x19, 0x04, 0xb3, 0xb9, 0x37, 0xf0, 0x7b, - 0x62, 0x6f, 0x6b, 0x27, 0x08, 0x05, 0x5f, 0x30, 0xd9, 0xcc, 0x40, 0xec, 0x1e, 0x94, 0xf6, 0xfd, - 0x33, 0x11, 0x2a, 0x5e, 0x27, 0xb5, 0xb5, 0x50, 0x79, 0x28, 0xf4, 0xa5, 0x8c, 0xfb, 0x07, 0xb2, - 0x2b, 0xf8, 0xa2, 0x51, 0x66, 0x20, 0xf6, 0x18, 0xea, 0x87, 0xd2, 0x04, 0x19, 0x84, 0x5a, 0xc4, - 0xfc, 0x0e, 0x39, 0x98, 0x04, 0x31, 0xf6, 0xa3, 0x91, 0x1e, 0x8e, 0xb4, 0xe2, 0x4b, 0x26, 0x76, - 0x6b, 0xd2, 0xf9, 0x84, 0xbe, 0x3e, 0x97, 0xf1, 0x40, 0xf1, 0xbb, 0x26, 0x67, 0x29, 0x80, 0xe7, - 0xf3, 0xdd, 0x28, 0x10, 0x9a, 0xb3, 0x15, 0xa7, 0x59, 0xf1, 0x8c, 0x81, 0xde, 0x4e, 0x44, 0x27, - 0x16, 0x5a, 0xf1, 0x7f, 0x1b, 0x6f, 0xd6, 0xa4, 0x99, 0x8b, 0xc1, 0x49, 0xf0, 0xb3, 0xe0, 0xcb, - 0x2b, 0x4e, 0xb3, 0xe0, 0x25, 0x26, 0x96, 0xec, 0xc9, 0xc9, 0x2e, 0xff, 0x0f, 0xf1, 0x71, 0xc8, - 0x18, 0x14, 0x4f, 0xfd, 0x9e, 0xe2, 0xf7, 0x08, 0xa2, 0x31, 0xe6, 0xe1, 0xd4, 0x8f, 0x7b, 0x42, - 0xf3, 0xff, 0x52, 0xa8, 0xd6, 0x62, 0x5f, 0x43, 0xf9, 0x4d, 0x18, 0x0c, 0x02, 0xad, 0x38, 0xa7, - 0xf2, 0x7e, 0x38, 0xbd, 0xbc, 0x0d, 0xe9, 0x68, 0xa8, 0xbd, 0x84, 0xcf, 0x5e, 0x40, 0xf1, 0x68, - 0xa8, 0x15, 0xff, 0x1f, 0xe9, 0x56, 0xa7, 0xeb, 0xda, 0x72, 0x30, 0x90, 0x51, 0x72, 0x2f, 0x48, - 0xe0, 0xfe, 0xee, 0x40, 0x35, 0xf5, 0xc7, 0xda, 0x50, 0x1a, 0xfb, 0xe1, 0x48, 0x28, 0xee, 0xac, - 0x14, 0x9a, 0xb5, 0xf5, 0xcf, 0x3e, 0xb2, 0x81, 0xd6, 0x5b, 0x62, 0x6f, 0x47, 0x3a, 0xbe, 0xf6, - 0xac, 0xb4, 0xf1, 0x0e, 0x6a, 0x19, 0x18, 0x73, 0xd2, 0x17, 0xd7, 0xc9, 0x35, 0xee, 0x8b, 0x6b, - 0xb6, 0x0e, 0xf3, 0x44, 0xb5, 0x97, 0xf8, 0xfe, 0xac, 0x45, 0x3c, 0x43, 0x7d, 0x39, 0xf7, 0x95, - 0xe3, 0x6e, 0x41, 0xc9, 0x80, 0x98, 0x55, 0xba, 0x8d, 0xc6, 0x29, 0x8d, 0x11, 0xdb, 0xf5, 0xe3, - 0x2e, 0x39, 0x2d, 0x78, 0x34, 0x46, 0xec, 0x44, 0x9e, 0x6b, 0xba, 0x92, 0x05, 0x8f, 0xc6, 0xee, - 0x5f, 0x0e, 0xd4, 0x27, 0x32, 0x81, 0xe7, 0x49, 0xd7, 0x4b, 0xc4, 0xd6, 0x61, 0x62, 0xe2, 0x9d, - 0x39, 0x10, 0xda, 0xef, 0xfa, 0xda, 0xa7, 0xa2, 0x36, 0xb7, 0x7f, 0x02, 0x43, 0xb5, 0x2d, 0x43, - 0x5a, 0xa6, 0xe2, 0x25, 0x26, 0xae, 0x7e, 0x3c, 0x0a, 0x43, 0x5e, 0x24, 0x98, 0xc6, 0xe6, 0x16, - 0x0d, 0x65, 0xac, 0x8f, 0x47, 0xea, 0x82, 0xcf, 0xd3, 0x4c, 0x06, 0xb9, 0x99, 0xdf, 0x97, 0x7e, - 0x97, 0x97, 0xb2, 0xf3, 0x88, 0x50, 0x44, 0x9b, 0x47, 0x07, 0xbc, 0x6c, 0x22, 0xc7, 0x31, 0x6a, - 0x8e, 0x63, 0x39, 0x16, 0x91, 0x1f, 0x75, 0x04, 0xaf, 0xd0, 0x4c, 0x06, 0x71, 0xef, 0x40, 0xdd, - 0x36, 0x56, 0x35, 0x94, 0x91, 0x12, 0xee, 0x13, 0xb8, 0xbb, 0x15, 0xa8, 0x8e, 0x8c, 0x22, 0xd1, - 0xd1, 0xb9, 0xed, 0xd6, 0x5d, 0x06, 0x96, 0xa5, 0x59, 0xf1, 0x43, 0xa8, 0xed, 0x07, 0x6a, 0x86, - 0xcc, 0x85, 0x05, 0x43, 0x30, 0x02, 0xdc, 0x72, 0x5f, 0x5c, 0x9b, 0x92, 0xaa, 0x7a, 0x34, 0x76, - 0x7f, 0x75, 0x60, 0x61, 0x2f, 0x1a, 0x8e, 0xf4, 0x81, 0x50, 0xca, 0xef, 0x09, 0xf6, 0x1a, 0x8a, - 0x7b, 0x51, 0xa0, 0xc9, 0x4f, 0x6d, 0xfd, 0xe9, 0xf4, 0x92, 0x20, 0x05, 0xd2, 0xac, 0x6a, 0xf7, - 0x5f, 0x1e, 0xa9, 0xb0, 0xfc, 0xb7, 0x7c, 0xed, 0xdb, 0x82, 0x7a, 0x34, 0x5d, 0x8d, 0x8c, 0x8c, - 0x10, 0xcd, 0xcd, 0x32, 0xcc, 0x93, 0x53, 0xf7, 0x31, 0x2c, 0xdd, 0xf6, 0x3e, 0x25, 0xb4, 0xe7, - 0x50, 0xcb, 0x78, 0x41, 0xc2, 0xf6, 0xd1, 0x0e, 0x11, 0x2a, 0x1e, 0x0e, 0x31, 0xd6, 0x74, 0x23, - 0x0b, 0x66, 0x0d, 0x4c, 0x3f, 0xb9, 0x4e, 0x33, 0xf8, 0xcb, 0x1c, 0x94, 0x13, 0x17, 0x2f, 0x26, - 0xe2, 0x7e, 0x94, 0x17, 0xf7, 0x87, 0x21, 0x7f, 0x09, 0xc5, 0xb4, 0x24, 0x73, 0x3b, 0xc5, 0x4e, - 0x37, 0x23, 0xa3, 0x6a, 0xfd, 0x06, 0x4a, 0x9e, 0x50, 0xd8, 0xba, 0x0a, 0xb3, 0x5a, 0x85, 0xe1, - 0xdc, 0x88, 0xad, 0x08, 0xe5, 0x27, 0x41, 0x2f, 0xf2, 0x4d, 0x51, 0xe7, 0xca, 0x0d, 0x27, 0x23, - 0x37, 0xc0, 0x4d, 0xba, 0x87, 0x50, 0x9b, 0x99, 0x69, 0x76, 0x04, 0x77, 0xf0, 0xe5, 0xf1, 0x83, - 0x48, 0xc4, 0x6d, 0x19, 0x9d, 0x07, 0x3d, 0x1b, 0xe9, 0x93, 0xbc, 0xde, 0x36, 0x41, 0xf6, 0x6e, - 0xab, 0xdd, 0x3f, 0x9c, 0x0f, 0x3c, 0xd2, 0x65, 0xc3, 0x1e, 0x35, 0x94, 0x41, 0xa4, 0x6d, 0x7d, - 0x66, 0x10, 0xdc, 0x56, 0x7b, 0x80, 0x1d, 0x85, 0xda, 0x79, 0x7b, 0xd0, 0xa5, 0x13, 0x8f, 0xc6, - 0xbc, 0x60, 0x90, 0xed, 0x68, 0x8c, 0x27, 0xfe, 0x46, 0x89, 0x98, 0xf2, 0x51, 0xf5, 0x68, 0x8c, - 0x0d, 0xfe, 0x50, 0x12, 0x6a, 0x2e, 0xb8, 0xb5, 0xc8, 0xdf, 0xa5, 0xb9, 0xd5, 0xe8, 0xef, 0xb2, - 0x8b, 0x4f, 0xcf, 0xa1, 0x44, 0xac, 0x6c, 0x9e, 0x1e, 0x32, 0x90, 0x77, 0xaa, 0xaf, 0xe9, 0x26, - 0x57, 0x3c, 0x1c, 0xba, 0x1b, 0x50, 0x4d, 0xcf, 0x92, 0x2d, 0xc2, 0xdc, 0x4e, 0x97, 0x92, 0x55, - 0xf7, 0xe6, 0x76, 0xba, 0x49, 0x19, 0xce, 0x7d, 0x58, 0x86, 0x85, 0x4c, 0x19, 0xbe, 0x80, 0xfa, - 0xc4, 0xa9, 0x22, 0xc9, 0x93, 0x97, 0xca, 0x3a, 0xa2, 0x31, 0x62, 0x6d, 0x19, 0x9a, 0xcf, 0xab, - 0xba, 0x47, 0x63, 0x77, 0x15, 0xea, 0x13, 0xe7, 0x39, 0xad, 0xfb, 0xba, 0x8f, 0xa0, 0x7e, 0xa2, - 0x7d, 0x3d, 0x52, 0xf9, 0x7d, 0xe1, 0x6f, 0x07, 0x16, 0x13, 0x8e, 0x6d, 0x0d, 0x5f, 0x40, 0x65, - 0x2c, 0x62, 0x2d, 0xae, 0xd2, 0x17, 0x87, 0xb7, 0xf0, 0xbb, 0xb1, 0x95, 0x7c, 0x37, 0xe2, 0xd1, - 0xbe, 0x25, 0x86, 0x97, 0x32, 0xd9, 0x4b, 0xa8, 0x28, 0xf2, 0x23, 0x14, 0x9d, 0x4d, 0x6d, 0xfd, - 0x41, 0x9e, 0xca, 0xae, 0x97, 0xf2, 0xd9, 0x1a, 0x14, 0x43, 0xd9, 0x53, 0x74, 0x82, 0xb5, 0xf5, - 0xff, 0xe7, 0xe9, 0xf6, 0x65, 0xcf, 0x23, 0x22, 0x7b, 0x05, 0x95, 0x4b, 0x3f, 0x8e, 0x82, 0xa8, - 0xa7, 0xe8, 0xfb, 0x0d, 0xef, 0x5a, 0x8e, 0xe8, 0x9d, 0xe1, 0x79, 0xa9, 0xc0, 0xad, 0x63, 0x99, - 0x9f, 0x4b, 0x9b, 0x13, 0xf7, 0x7b, 0x6c, 0x7a, 0x68, 0xda, 0xf0, 0xf7, 0xa0, 0x6e, 0x8a, 0xf9, - 0xad, 0x88, 0x55, 0x20, 0x23, 0xdb, 0x05, 0x56, 0x67, 0x7c, 0xd5, 0x26, 0x54, 0x6f, 0x52, 0xe9, - 0xbe, 0xb7, 0x3d, 0x3e, 0x01, 0xf0, 0x59, 0x1a, 0xfa, 0x9d, 0xbe, 0xdf, 0x4b, 0xce, 0x29, 0x31, - 0x71, 0x66, 0x6c, 0xd7, 0x33, 0xef, 0x59, 0x62, 0xe2, 0xe7, 0x5f, 0x2c, 0xc6, 0x01, 0x4d, 0x99, - 0xaf, 0xd8, 0xd4, 0x5e, 0xff, 0xb3, 0x08, 0xd0, 0x4e, 0xf7, 0xc3, 0x8e, 0x61, 0x9e, 0xd6, 0x63, - 0xb3, 0x3e, 0xc1, 0x6d, 0xdc, 0x8d, 0xd5, 0x99, 0x1c, 0x9b, 0x8c, 0x37, 0x50, 0x32, 0xa7, 0xc5, - 0xf2, 0x9a, 0x4a, 0xb6, 0xbe, 0x1a, 0x8f, 0x67, 0x93, 0x8c, 0xd3, 0x67, 0x0e, 0xf3, 0x6c, 0xcb, - 0xc9, 0xdb, 0x68, 0xf6, 0x15, 0xca, 0xdb, 0xe8, 0x44, 0xfb, 0x6e, 0x3a, 0xec, 0x5b, 0x28, 0xed, - 0x45, 0x63, 0xd9, 0x17, 0xec, 0x93, 0xe9, 0x82, 0xc4, 0xdf, 0xec, 0xe9, 0xa6, 0xf3, 0xcc, 0x61, - 0x07, 0x50, 0xc4, 0xd7, 0x92, 0xe5, 0xb4, 0xfe, 0xcc, 0x53, 0xdb, 0x70, 0x67, 0x51, 0x6c, 0x16, - 0xdf, 0x03, 0xdc, 0xbc, 0xd9, 0xec, 0xd3, 0x9c, 0x97, 0xf0, 0xf6, 0xe3, 0xdf, 0x68, 0x7e, 0x9c, - 0x68, 0x17, 0x38, 0xc0, 0x07, 0xeb, 0x5c, 0xb2, 0xdc, 0xa7, 0x2a, 0x2d, 0xf7, 0x86, 0x3b, 0x8b, - 0x62, 0xdc, 0x6d, 0x16, 0x7f, 0x98, 0x1b, 0x9e, 0x9d, 0x95, 0xe8, 0x1f, 0xe0, 0xf3, 0x7f, 0x02, - 0x00, 0x00, 0xff, 0xff, 0x10, 0xcd, 0x98, 0x21, 0x68, 0x0e, 0x00, 0x00, + // 1657 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xdd, 0x6e, 0xdb, 0xc6, + 0x12, 0x3e, 0x94, 0x64, 0xfd, 0x8c, 0x2c, 0xc7, 0xd9, 0xe3, 0x04, 0x3c, 0x3a, 0x39, 0x89, 0xc3, + 0xfc, 0x1c, 0x01, 0x29, 0xe4, 0xc4, 0x69, 0x9a, 0xdf, 0x02, 0xb5, 0x25, 0x0b, 0x76, 0xe1, 0x3f, + 0x50, 0x4e, 0x82, 0xb6, 0x40, 0x03, 0x5a, 0x5a, 0xcb, 0x84, 0x28, 0xae, 0xca, 0x5d, 0xc9, 0x56, + 0xaf, 0x7a, 0xd3, 0xdb, 0xbe, 0x47, 0xd1, 0x47, 0xe8, 0x55, 0xdf, 0xa1, 0x0f, 0xd2, 0x47, 0x28, + 0x76, 0x76, 0x49, 0x51, 0x96, 0x28, 0xdb, 0xe8, 0x95, 0x77, 0x86, 0xdf, 0x37, 0xb3, 0x3b, 0x3b, + 0x3f, 0x2b, 0xc3, 0x72, 0x8b, 0xf9, 0x22, 0x60, 0x9e, 0x47, 0x83, 0x6a, 0x3f, 0x60, 0x82, 0x91, + 0x95, 0xe3, 0x81, 0xeb, 0xb5, 0xcf, 0xab, 0xb1, 0x0f, 0xc3, 0x67, 0xe5, 0xb7, 0x1d, 0x57, 0x9c, + 0x0e, 0x8e, 0xab, 0x2d, 0xd6, 0x5b, 0xeb, 0xb1, 0xe3, 0xd1, 0x1a, 0xa2, 0xba, 0xae, 0x58, 0x73, + 0xfa, 0xee, 0x1a, 0xa7, 0xc1, 0xd0, 0x6d, 0x51, 0xbe, 0xa6, 0x49, 0xe1, 0x5f, 0x65, 0xd2, 0xfa, + 0x1e, 0x16, 0x37, 0x25, 0xdc, 0xa6, 0x3f, 0x0c, 0x28, 0x17, 0x64, 0x19, 0xd2, 0x36, 0x3d, 0x31, + 0x8d, 0x55, 0xa3, 0x52, 0xb0, 0xe5, 0x92, 0xbc, 0x83, 0xdc, 0x41, 0x5f, 0xb8, 0xcc, 0xe7, 0x66, + 0x6a, 0xd5, 0xa8, 0x14, 0xd7, 0xad, 0xea, 0xac, 0x6d, 0x54, 0xd1, 0x8c, 0x46, 0xda, 0x21, 0xc5, + 0xfa, 0x19, 0xb4, 0x03, 0xad, 0x20, 0xab, 0x50, 0xac, 0x31, 0x5f, 0xd0, 0x73, 0x71, 0xe8, 0x88, + 0x53, 0xed, 0x28, 0xae, 0x22, 0x8f, 0x61, 0xa9, 0xce, 0x5a, 0x5d, 0x1a, 0x9c, 0xb8, 0x1e, 0xdd, + 0x77, 0x7a, 0x14, 0xfd, 0x16, 0xec, 0x0b, 0x5a, 0x72, 0x07, 0x0a, 0x87, 0x81, 0xeb, 0x8b, 0xc6, + 0xc0, 0x6f, 0x99, 0x69, 0x84, 0x8c, 0x15, 0xe4, 0x3b, 0x28, 0x49, 0x54, 0x5b, 0x5b, 0xe6, 0x66, + 0x66, 0x35, 0x5d, 0x29, 0xae, 0xbf, 0xb8, 0x7c, 0xf3, 0xd5, 0x09, 0xde, 0x96, 0x2f, 0x82, 0x91, + 0x3d, 0x69, 0x8b, 0xac, 0xc0, 0xc2, 0x86, 0xe7, 0xb1, 0x33, 0x73, 0x61, 0x35, 0x5d, 0x29, 0xd8, + 0x4a, 0x20, 0x5f, 0x40, 0x6e, 0x43, 0x08, 0xca, 0x05, 0x37, 0xb3, 0xe8, 0xec, 0xce, 0x6c, 0x67, + 0x0a, 0x64, 0x87, 0x60, 0x72, 0x00, 0x05, 0xf4, 0xbf, 0x11, 0x74, 0xb8, 0x99, 0x43, 0xe6, 0xb3, + 0x2b, 0x6c, 0x33, 0xe2, 0xa8, 0x2d, 0x8e, 0x6d, 0x90, 0x2d, 0x28, 0xd4, 0x9c, 0xd6, 0x29, 0x6d, + 0x04, 0xac, 0x67, 0xe6, 0xd1, 0xe0, 0xff, 0x67, 0x1b, 0x44, 0x98, 0x36, 0xa8, 0xcd, 0x44, 0x4c, + 0xb2, 0x01, 0x39, 0x14, 0x8e, 0x98, 0x59, 0xb8, 0x9e, 0x91, 0x90, 0x47, 0x2c, 0x58, 0xac, 0x75, + 0x02, 0x36, 0xe8, 0x1f, 0x3a, 0x01, 0xf5, 0x85, 0x09, 0x78, 0x4d, 0x13, 0x3a, 0xf2, 0x16, 0x72, + 0x5b, 0xe7, 0x7d, 0x16, 0x08, 0x6e, 0x16, 0xd1, 0xcd, 0xfd, 0xd9, 0x6e, 0x14, 0x48, 0x3b, 0xd0, + 0x0c, 0x72, 0x17, 0x60, 0xeb, 0x5c, 0x04, 0xce, 0x36, 0x93, 0x61, 0x5f, 0xc4, 0xeb, 0x88, 0x69, + 0x48, 0x03, 0xb2, 0xbb, 0xce, 0x31, 0xf5, 0xb8, 0x59, 0x42, 0xdb, 0xd5, 0x2b, 0x04, 0x56, 0x11, + 0x94, 0x23, 0xcd, 0x96, 0x69, 0xbb, 0x4f, 0xc5, 0x19, 0x0b, 0xba, 0x7b, 0xac, 0x4d, 0xcd, 0x25, + 0x95, 0xb6, 0x31, 0x15, 0x79, 0x08, 0xa5, 0x7d, 0xa6, 0x82, 0xe7, 0x7a, 0x82, 0x06, 0xe6, 0x0d, + 0xdc, 0xcc, 0xa4, 0x12, 0x93, 0xd6, 0x73, 0xc4, 0x09, 0x0b, 0x7a, 0xdc, 0x5c, 0x46, 0xc4, 0x58, + 0x21, 0x33, 0xa8, 0x49, 0x5b, 0x01, 0x15, 0xdc, 0xbc, 0x39, 0x2f, 0x83, 0x14, 0xc8, 0x0e, 0xc1, + 0xc4, 0x84, 0x5c, 0xf3, 0xb4, 0xd7, 0x74, 0x7f, 0xa4, 0x26, 0x59, 0x35, 0x2a, 0x69, 0x3b, 0x14, + 0xc9, 0x13, 0x48, 0x37, 0x9b, 0xdb, 0xe6, 0xbf, 0xd1, 0xda, 0x7f, 0x12, 0xac, 0x35, 0xb7, 0x6d, + 0x89, 0x22, 0x04, 0x32, 0x47, 0x4e, 0x87, 0x9b, 0x2b, 0xb8, 0x2f, 0x5c, 0x93, 0xdb, 0x90, 0x3d, + 0x72, 0x82, 0x0e, 0x15, 0xe6, 0x2d, 0x3c, 0xb3, 0x96, 0xc8, 0x6b, 0xc8, 0xbd, 0xf7, 0xdc, 0x9e, + 0x2b, 0xb8, 0x79, 0x1b, 0xdb, 0xc2, 0xbd, 0xd9, 0xc6, 0x15, 0xe8, 0xa0, 0x2f, 0xec, 0x10, 0x4f, + 0x5e, 0x42, 0xe6, 0xa0, 0x2f, 0xb8, 0x69, 0x22, 0xef, 0x41, 0x42, 0x52, 0xb1, 0x5e, 0x8f, 0xf9, + 0x61, 0x3f, 0x41, 0x42, 0xf9, 0x2b, 0x20, 0xd3, 0xb5, 0x29, 0x5b, 0x56, 0x97, 0x8e, 0xc2, 0x96, + 0xd5, 0xa5, 0x23, 0x59, 0x9e, 0x43, 0xc7, 0x1b, 0x84, 0x8d, 0x43, 0x09, 0x6f, 0x52, 0xaf, 0x8c, + 0xf2, 0x3b, 0x58, 0x9a, 0x2c, 0x9b, 0x6b, 0xb1, 0x5f, 0x43, 0x31, 0x96, 0x1b, 0xd7, 0xa1, 0x5a, + 0x7f, 0x18, 0x50, 0x8c, 0x25, 0x30, 0x86, 0x7a, 0xd4, 0xa7, 0x9a, 0x8c, 0x6b, 0xb2, 0x09, 0x0b, + 0x1b, 0x42, 0x04, 0xb2, 0xcf, 0xca, 0xdb, 0xfa, 0xec, 0xd2, 0x32, 0xa8, 0x22, 0x5c, 0x25, 0xaa, + 0xa2, 0xca, 0x3c, 0xad, 0x53, 0x2e, 0x5c, 0xdf, 0x91, 0x81, 0xd3, 0x6d, 0x31, 0xae, 0x2a, 0xbf, + 0x02, 0x18, 0xd3, 0xae, 0x75, 0x86, 0xdf, 0x0c, 0xb8, 0x39, 0x55, 0xeb, 0x33, 0x4f, 0xb2, 0x3d, + 0x79, 0x92, 0xf5, 0x2b, 0xf6, 0x8d, 0xe9, 0xf3, 0xfc, 0x83, 0xdd, 0xee, 0x43, 0x56, 0x35, 0xd8, + 0x99, 0x3b, 0x2c, 0x43, 0xbe, 0xee, 0x72, 0xe7, 0xd8, 0xa3, 0x6d, 0xa4, 0xe6, 0xed, 0x48, 0xc6, + 0xee, 0x8e, 0xbb, 0x57, 0xd1, 0x53, 0x82, 0xa5, 0x2a, 0x89, 0x2c, 0x41, 0x6a, 0xa7, 0xae, 0x4d, + 0xa5, 0x76, 0xea, 0x12, 0x2c, 0xa7, 0x96, 0x3a, 0x6a, 0xc1, 0x56, 0x82, 0xd5, 0x80, 0xac, 0xaa, + 0xcd, 0x29, 0x7c, 0x19, 0xf2, 0x0d, 0xd7, 0xa3, 0x38, 0xfc, 0xd4, 0x9e, 0x23, 0x59, 0x1e, 0x6f, + 0xcb, 0x1f, 0x6a, 0xb7, 0x72, 0x69, 0xfd, 0x6a, 0x40, 0x21, 0xaa, 0x20, 0x52, 0x83, 0x2c, 0x9e, + 0x8f, 0x9b, 0x06, 0xc6, 0xf5, 0xc9, 0x25, 0x25, 0x57, 0xfd, 0x80, 0x68, 0xdd, 0xc9, 0x14, 0xb5, + 0xfc, 0x11, 0x8a, 0x31, 0xf5, 0x8c, 0x90, 0xae, 0xc7, 0x43, 0x9a, 0xd8, 0x82, 0x94, 0x93, 0x78, + 0xc0, 0xeb, 0x90, 0x55, 0x4a, 0x19, 0x70, 0x9c, 0xdb, 0x3a, 0xe0, 0x38, 0xad, 0x09, 0x64, 0xb6, + 0x9d, 0x40, 0x05, 0x3b, 0x6d, 0xe3, 0x5a, 0xea, 0x9a, 0xec, 0x44, 0xe0, 0x81, 0xd3, 0x36, 0xae, + 0xad, 0xdf, 0x0d, 0x28, 0x4d, 0xd4, 0xbe, 0x6c, 0x6e, 0x58, 0xb3, 0x34, 0xd0, 0x06, 0x43, 0x51, + 0x4e, 0x97, 0x3d, 0x2a, 0x9c, 0xb6, 0x23, 0x1c, 0x19, 0x43, 0x1d, 0xcf, 0x09, 0x9d, 0x64, 0xeb, + 0x0e, 0x8c, 0x6e, 0xf2, 0x76, 0x28, 0x4a, 0xef, 0x87, 0x03, 0xcf, 0x33, 0x33, 0xa8, 0xc6, 0xb5, + 0x1a, 0x27, 0xb2, 0xbe, 0x0e, 0x07, 0xfc, 0xd4, 0x5c, 0xc0, 0x2f, 0x31, 0xcd, 0xf8, 0xfb, 0x2e, + 0x73, 0xda, 0x66, 0x36, 0xfe, 0x5d, 0x6a, 0x70, 0xf7, 0xfa, 0x3d, 0xc5, 0xfb, 0xcc, 0xe7, 0x94, + 0x50, 0x58, 0x56, 0xdf, 0x69, 0x10, 0xea, 0xf4, 0xed, 0xbd, 0x9e, 0x33, 0x8a, 0x42, 0x68, 0xf5, + 0x22, 0x57, 0xdd, 0xe5, 0x94, 0xc9, 0x72, 0x0d, 0x6e, 0xcd, 0x84, 0x5e, 0xab, 0x64, 0x1e, 0xc1, + 0xcd, 0xba, 0xcb, 0x5b, 0xcc, 0xf7, 0x69, 0x4b, 0x24, 0xbe, 0x08, 0xad, 0x15, 0x20, 0x71, 0x98, + 0xf2, 0x66, 0xdd, 0x83, 0xe2, 0xae, 0xcb, 0xe7, 0xd0, 0x2c, 0x58, 0x54, 0x00, 0x1d, 0x19, 0x02, + 0x99, 0x2e, 0x1d, 0xa9, 0x5c, 0x2e, 0xd8, 0xb8, 0xb6, 0x7e, 0x31, 0x60, 0x71, 0xc7, 0xef, 0x0f, + 0xc4, 0x1e, 0xe5, 0xdc, 0xe9, 0x50, 0xf2, 0x0e, 0x32, 0x3b, 0xbe, 0x2b, 0xd0, 0x4e, 0x71, 0xfd, + 0xf1, 0xec, 0x90, 0x21, 0x43, 0xc2, 0x34, 0x6b, 0xfb, 0x5f, 0x36, 0xb2, 0xe4, 0xa4, 0xa9, 0x3b, + 0xc2, 0xd1, 0x99, 0x9c, 0xf0, 0xae, 0x90, 0x88, 0x18, 0x51, 0x8a, 0x9b, 0x39, 0x58, 0x40, 0xa3, + 0xd6, 0x43, 0x58, 0xbe, 0x68, 0x7d, 0xc6, 0xd1, 0x9e, 0x43, 0x31, 0x66, 0x05, 0xeb, 0xf8, 0xa0, + 0x81, 0x80, 0xbc, 0x2d, 0x97, 0xf2, 0xac, 0xd1, 0x46, 0x16, 0x95, 0x0f, 0xeb, 0x06, 0x94, 0xd0, + 0x74, 0x14, 0xc1, 0x9f, 0x52, 0x90, 0x0b, 0x4d, 0xbc, 0x9c, 0x38, 0xf7, 0xfd, 0xa4, 0x73, 0x4f, + 0x1f, 0xf9, 0x05, 0x64, 0xa2, 0x5a, 0x48, 0x1c, 0xca, 0x8d, 0x76, 0x8c, 0x86, 0x65, 0xf2, 0x25, + 0x64, 0x6d, 0xca, 0xe5, 0x03, 0x22, 0x3d, 0x6f, 0x2a, 0x2b, 0xcc, 0x98, 0xac, 0x49, 0x92, 0xde, + 0x74, 0x3b, 0xbe, 0xa3, 0xaa, 0x29, 0x91, 0xae, 0x30, 0x31, 0xba, 0x52, 0x8c, 0xc3, 0xdd, 0x87, + 0xe2, 0xdc, 0x48, 0x93, 0x03, 0xb8, 0x21, 0xa7, 0xbf, 0xe3, 0xfa, 0x34, 0xa8, 0x31, 0xff, 0xc4, + 0xed, 0xe8, 0x93, 0x3e, 0x4a, 0x7a, 0x46, 0x4c, 0x80, 0xed, 0x8b, 0x6c, 0x59, 0xb1, 0x17, 0x75, + 0x58, 0xe5, 0xb2, 0x78, 0xfa, 0xcc, 0xf5, 0x85, 0xce, 0xcf, 0x98, 0x46, 0x6e, 0xab, 0xd6, 0x6b, + 0xeb, 0x8e, 0x2f, 0x97, 0xe3, 0xce, 0x9d, 0xd6, 0x9d, 0x5b, 0xde, 0xf8, 0x7b, 0x4e, 0x03, 0x8c, + 0x47, 0xc1, 0xc6, 0xb5, 0x7c, 0x4b, 0xed, 0x33, 0xd4, 0xaa, 0xce, 0xa2, 0x25, 0xb4, 0x77, 0xa6, + 0xda, 0x89, 0xb4, 0x77, 0x86, 0x23, 0x68, 0x9f, 0x49, 0x5d, 0x0e, 0x81, 0x4a, 0x90, 0xb8, 0x23, + 0x31, 0x32, 0xf3, 0x2a, 0xaf, 0x8e, 0xc4, 0xc8, 0xda, 0x80, 0x42, 0x74, 0x97, 0x72, 0xd4, 0x34, + 0xda, 0x18, 0xac, 0x92, 0x9d, 0x6a, 0xb4, 0xc3, 0x34, 0x4c, 0x4d, 0xa7, 0x61, 0x3a, 0x96, 0x86, + 0x2f, 0xa1, 0x34, 0x71, 0xab, 0x12, 0x64, 0xb3, 0x33, 0xae, 0x0d, 0xe1, 0x5a, 0xea, 0x6a, 0xcc, + 0x53, 0xbf, 0x00, 0x4b, 0x36, 0xae, 0xad, 0x07, 0x50, 0x9a, 0xb8, 0xcf, 0x59, 0x6d, 0xdf, 0xba, + 0x0f, 0xa5, 0xa6, 0x70, 0xc4, 0x80, 0x27, 0xf7, 0x85, 0xbf, 0x0c, 0x58, 0x0a, 0x31, 0xba, 0x35, + 0x7c, 0x0e, 0xf9, 0x21, 0x0d, 0x04, 0x3d, 0x8f, 0x46, 0x9d, 0x59, 0x95, 0x3f, 0x6d, 0xab, 0xe1, + 0x4f, 0x5b, 0x79, 0xb5, 0x1f, 0x10, 0x61, 0x47, 0x48, 0xf2, 0x06, 0xf2, 0x1c, 0xed, 0xd0, 0xf0, + 0xe1, 0x71, 0x37, 0x89, 0xa5, 0xfd, 0x45, 0x78, 0xb2, 0x06, 0x19, 0x8f, 0x75, 0x38, 0xde, 0x60, + 0x71, 0xfd, 0xbf, 0x49, 0xbc, 0x5d, 0xd6, 0xb1, 0x11, 0x48, 0xde, 0x42, 0xfe, 0xcc, 0x09, 0x7c, + 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. diff --git a/controller/pb/controller.proto b/controller/pb/controller.proto index c8498125..cd380732 100644 --- a/controller/pb/controller.proto +++ b/controller/pb/controller.proto @@ -25,30 +25,56 @@ message BuildOptions { string ContextPath = 1; string DockerfileName = 2; string PrintFunc = 3; - - repeated string Allow = 4; - repeated string Attests = 5; // TODO - repeated string BuildArgs = 6; - repeated string CacheFrom = 7; - repeated string CacheTo = 8; - string CgroupParent = 9; - repeated string Contexts = 10; - repeated string ExtraHosts = 11; - string ImageIDFile = 12; - repeated string Labels = 13; + map NamedContexts = 4; + + repeated string Allow = 5; + repeated Attest Attests = 6; + map BuildArgs = 7; + repeated CacheOptionsEntry CacheFrom = 8; + repeated CacheOptionsEntry CacheTo = 9; + string CgroupParent = 10; + repeated ExportEntry Exports = 11; + repeated string ExtraHosts = 12; + map Labels = 13; string NetworkMode = 14; repeated string NoCacheFilter = 15; - repeated string Outputs = 16; - repeated string Platforms = 17; - bool Quiet = 18; - repeated string Secrets = 19; - int64 ShmSize = 20; - repeated string SSH = 21; - repeated string Tags = 22; - string Target = 23; - UlimitOpt Ulimits = 24; - // string Invoke: provided via Invoke API - CommonOptions Opts = 25; + repeated string Platforms = 16; + repeated Secret Secrets = 17; + int64 ShmSize = 18; + repeated SSH SSH = 19; + repeated string Tags = 20; + string Target = 21; + UlimitOpt Ulimits = 22; + + CommonOptions Opts = 24; +} + +message ExportEntry { + string Type = 1; + map Attrs = 2; + string Destination = 3; +} + +message CacheOptionsEntry { + string Type = 1; + map 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 { @@ -69,11 +95,11 @@ message CommonOptions { bool Pull = 4; bool ExportPush = 5; bool ExportLoad = 6; - string SBOM = 7; // TODO - string Provenance = 8; // TODO } -message BuildResponse {} +message BuildResponse { + map ExporterResponse = 1; +} message DisconnectRequest { string Ref = 1; diff --git a/util/buildflags/output.go b/controller/pb/export.go similarity index 56% rename from util/buildflags/output.go rename to controller/pb/export.go index fa1adfaa..93392a43 100644 --- a/util/buildflags/output.go +++ b/controller/pb/export.go @@ -1,66 +1,31 @@ -package buildflags +package pb import ( - "encoding/csv" "io" "os" "strconv" - "strings" "github.com/containerd/console" "github.com/moby/buildkit/client" "github.com/pkg/errors" ) -func ParseOutputs(inp []string) ([]client.ExportEntry, error) { +func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) { var outs []client.ExportEntry - if len(inp) == 0 { + if len(entries) == 0 { return nil, nil } - for _, s := range inp { - csvReader := csv.NewReader(strings.NewReader(s)) - fields, err := csvReader.Read() - if err != nil { - return nil, err + for _, entry := range entries { + if entry.Type == "" { + return nil, errors.Errorf("type is required for output") } out := client.ExportEntry{ + Type: entry.Type, Attrs: map[string]string{}, } - if len(fields) == 1 && fields[0] == s && !strings.HasPrefix(s, "type=") { - if s != "-" { - 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") + for k, v := range entry.Attrs { + out.Attrs[k] = v } supportFile := false @@ -79,56 +44,49 @@ func ParseOutputs(inp []string) ([]client.ExportEntry, error) { supportDir = !tar case "registry": out.Type = client.ExporterImage - if _, ok := out.Attrs["push"]; !ok { - out.Attrs["push"] = "true" - } } - dest, ok := out.Attrs["dest"] if supportDir { - if !ok { + if entry.Destination == "" { 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) } - fi, err := os.Stat(dest) + fi, err := os.Stat(entry.Destination) 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() { - 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 !ok && out.Type != client.ExporterDocker { - dest = "-" + if entry.Destination == "" && out.Type != client.ExporterDocker { + entry.Destination = "-" } - if dest == "-" { + if entry.Destination == "-" { 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) } out.Output = wrapWriteCloser(os.Stdout) - } else if dest != "" { - fi, err := os.Stat(dest) + } else if entry.Destination != "" { + fi, err := os.Stat(entry.Destination) 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() { - 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 { return nil, errors.Errorf("failed to open %s", err) } out.Output = wrapWriteCloser(f) } } - if supportFile || supportDir { - delete(out.Attrs, "dest") - } outs = append(outs, out) } diff --git a/controller/pb/secrets.go b/controller/pb/secrets.go new file mode 100644 index 00000000..c85b55d1 --- /dev/null +++ b/controller/pb/secrets.go @@ -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 +} diff --git a/controller/pb/ssh.go b/controller/pb/ssh.go new file mode 100644 index 00000000..3d026ebb --- /dev/null +++ b/controller/pb/ssh.go @@ -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) +} diff --git a/controller/remote/client.go b/controller/remote/client.go index 68921fcb..8898c7f0 100644 --- a/controller/remote/client.go +++ b/controller/remote/client.go @@ -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() pw, err := progress.NewPrinter(context.TODO(), w, out, progressMode) if err != nil { - return "", err + return "", nil, err } statusChan := make(chan *client.SolveStatus) statusDone := make(chan struct{}) eg, egCtx := errgroup.WithContext(ctx) + var resp *client.SolveResponse eg.Go(func() error { 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 { defer close(statusDone) @@ -116,20 +119,27 @@ func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadC <-statusDone 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) done := make(chan struct{}) + + var resp *client.SolveResponse + eg.Go(func() error { defer close(done) - if _, err := c.client().Build(egCtx, &pb.BuildRequest{ + pbResp, err := c.client().Build(egCtx, &pb.BuildRequest{ Ref: ref, Options: &options, - }); err != nil { + }) + if err != nil { return err } + resp = &client.SolveResponse{ + ExporterResponse: pbResp.ExporterResponse, + } return nil }) eg.Go(func() error { @@ -254,7 +264,7 @@ func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, return eg2.Wait() }) } - return eg.Wait() + return resp, eg.Wait() } func (c *Client) client() pb.ControllerClient { diff --git a/controller/remote/controller.go b/controller/remote/controller.go index 3e3303a6..97508992 100644 --- a/controller/remote/controller.go +++ b/controller/remote/controller.go @@ -141,7 +141,7 @@ func serveCmd(dockerCli command.Cli) *cobra.Command { }() // 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) }) defer b.Close() diff --git a/controller/remote/server.go b/controller/remote/server.go index 1f27c603..072b5225 100644 --- a/controller/remote/server.go +++ b/controller/remote/server.go @@ -17,7 +17,7 @@ import ( "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 { return &Server{ @@ -150,7 +150,7 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp // Build the specified request ctx, cancel := context.WithCancel(ctx) defer cancel() - res, err := m.buildFunc(ctx, req.Options, inR, statusChan) + resp, res, err := m.buildFunc(ctx, req.Options, inR, statusChan) m.sessionMu.Lock() if s, ok := m.session[ref]; ok { s.result = res @@ -162,7 +162,12 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp } 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 { diff --git a/monitor/monitor.go b/monitor/monitor.go index da551389..0e2b62cb 100644 --- a/monitor/monitor.go +++ b/monitor/monitor.go @@ -121,7 +121,7 @@ func RunMonitor(ctx context.Context, curRef string, options controllerapi.BuildO 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 { fmt.Printf("failed to reload: %v\n", err) } else { diff --git a/util/buildflags/attests.go b/util/buildflags/attests.go index ab1b163a..c14c9f4e 100644 --- a/util/buildflags/attests.go +++ b/util/buildflags/attests.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + controllerapi "github.com/docker/buildx/controller/pb" "github.com/pkg/errors" ) @@ -14,66 +15,66 @@ func CanonicalizeAttest(attestType string, in string) string { return "" } 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) } -func ParseAttests(in []string) (map[string]*string, error) { - out := map[string]*string{} +func ParseAttests(in []string) ([]*controllerapi.Attest, error) { + out := []*controllerapi.Attest{} + found := map[string]struct{}{} for _, in := range in { in := in - attestType, enabled, err := parseAttest(in) + attest, err := parseAttest(in) if err != nil { return nil, err } - k := "attest:" + attestType - if _, ok := out[k]; ok { - return nil, errors.Errorf("duplicate attestation field %s", attestType) - } - if enabled { - out[k] = &in - } else { - out[k] = nil + if _, ok := found[attest.Type]; ok { + return nil, errors.Errorf("duplicate attestation field %s", attest.Type) } + found[attest.Type] = struct{}{} + + out = append(out, attest) } return out, nil } -func parseAttest(in string) (string, bool, error) { +func parseAttest(in string) (*controllerapi.Attest, error) { if in == "" { - return "", false, nil + return nil, nil } csvReader := csv.NewReader(strings.NewReader(in)) fields, err := csvReader.Read() if err != nil { - return "", false, err + return nil, err } - attestType := "" - enabled := true + attest := controllerapi.Attest{ + Attrs: in, + } for _, field := range fields { key, value, ok := strings.Cut(field, "=") if !ok { - return "", false, errors.Errorf("invalid value %s", field) + return nil, errors.Errorf("invalid value %s", field) } key = strings.TrimSpace(strings.ToLower(key)) switch key { case "type": - attestType = value - case "enabled": - enabled, err = strconv.ParseBool(value) + attest.Type = value + case "disabled": + disabled, err := strconv.ParseBool(value) if err != nil { - return "", false, err + return nil, errors.Wrapf(err, "invalid value %s", field) } + attest.Disabled = disabled } } - if attestType == "" { - return "", false, errors.Errorf("attestation type not specified") + if attest.Type == "" { + return nil, errors.Errorf("attestation type not specified") } - return attestType, enabled, nil + return &attest, nil } diff --git a/util/buildflags/cache.go b/util/buildflags/cache.go index 9b44f66f..061614db 100644 --- a/util/buildflags/cache.go +++ b/util/buildflags/cache.go @@ -7,12 +7,12 @@ import ( "strings" 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" ) -func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) { - imports := make([]client.CacheOptionsEntry, 0, len(in)) +func ParseCacheEntry(in []string) ([]*controllerapi.CacheOptionsEntry, error) { + outs := make([]*controllerapi.CacheOptionsEntry, 0, len(in)) for _, in := range in { csvReader := csv.NewReader(strings.NewReader(in)) fields, err := csvReader.Read() @@ -21,14 +21,15 @@ func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) { } if isRefOnlyFormat(fields) { for _, field := range fields { - imports = append(imports, client.CacheOptionsEntry{ + outs = append(outs, &controllerapi.CacheOptionsEntry{ Type: "registry", Attrs: map[string]string{"ref": field}, }) } continue } - im := client.CacheOptionsEntry{ + + out := controllerapi.CacheOptionsEntry{ Attrs: map[string]string{}, } for _, field := range fields { @@ -40,21 +41,21 @@ func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) { value := parts[1] switch key { case "type": - im.Type = value + out.Type = value default: - im.Attrs[key] = value + out.Attrs[key] = value } } - if im.Type == "" { + if out.Type == "" { return nil, errors.Errorf("type required form> %q", in) } - if !addGithubToken(&im) { + if !addGithubToken(&out) { continue } - addAwsCredentials(&im) - imports = append(imports, im) + addAwsCredentials(&out) + outs = append(outs, &out) } - return imports, nil + return outs, nil } func isRefOnlyFormat(in []string) bool { @@ -66,7 +67,7 @@ func isRefOnlyFormat(in []string) bool { return true } -func addGithubToken(ci *client.CacheOptionsEntry) bool { +func addGithubToken(ci *controllerapi.CacheOptionsEntry) bool { if ci.Type != "gha" { return true } @@ -83,7 +84,7 @@ func addGithubToken(ci *client.CacheOptionsEntry) bool { return ci.Attrs["token"] != "" && ci.Attrs["url"] != "" } -func addAwsCredentials(ci *client.CacheOptionsEntry) { +func addAwsCredentials(ci *controllerapi.CacheOptionsEntry) { if ci.Type != "s3" { return } diff --git a/util/buildflags/context.go b/util/buildflags/context.go new file mode 100644 index 00000000..e67fb97c --- /dev/null +++ b/util/buildflags/context.go @@ -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 +} diff --git a/util/buildflags/export.go b/util/buildflags/export.go new file mode 100644 index 00000000..8f1b73cf --- /dev/null +++ b/util/buildflags/export.go @@ -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 +} diff --git a/util/buildflags/secrets.go b/util/buildflags/secrets.go index 390f1476..25112085 100644 --- a/util/buildflags/secrets.go +++ b/util/buildflags/secrets.go @@ -4,35 +4,30 @@ import ( "encoding/csv" "strings" - "github.com/moby/buildkit/session" - "github.com/moby/buildkit/session/secrets/secretsprovider" + controllerapi "github.com/docker/buildx/controller/pb" "github.com/pkg/errors" ) -func ParseSecretSpecs(sl []string) (session.Attachable, error) { - fs := make([]secretsprovider.Source, 0, len(sl)) +func ParseSecretSpecs(sl []string) ([]*controllerapi.Secret, error) { + fs := make([]*controllerapi.Secret, 0, len(sl)) for _, v := range sl { s, err := parseSecret(v) if err != nil { return nil, err } - fs = append(fs, *s) + fs = append(fs, s) } - store, err := secretsprovider.NewStore(fs) - if err != nil { - return nil, err - } - return secretsprovider.NewSecretProvider(store), nil + return fs, nil } -func parseSecret(value string) (*secretsprovider.Source, error) { +func parseSecret(value string) (*controllerapi.Secret, error) { csvReader := csv.NewReader(strings.NewReader(value)) fields, err := csvReader.Read() if err != nil { return nil, errors.Wrap(err, "failed to parse csv secret") } - fs := secretsprovider.Source{} + fs := controllerapi.Secret{} var typ string for _, field := range fields { diff --git a/util/buildflags/ssh.go b/util/buildflags/ssh.go index bb9e1152..255f1117 100644 --- a/util/buildflags/ssh.go +++ b/util/buildflags/ssh.go @@ -3,32 +3,27 @@ package buildflags import ( "strings" - "github.com/moby/buildkit/session" - "github.com/moby/buildkit/session/sshforward/sshprovider" + controllerapi "github.com/docker/buildx/controller/pb" "github.com/moby/buildkit/util/gitutil" ) -func ParseSSHSpecs(sl []string) (session.Attachable, error) { - configs := make([]sshprovider.AgentConfig, 0, len(sl)) - for _, v := range sl { - c, err := parseSSH(v) - if err != nil { - return nil, err - } - configs = append(configs, *c) +func ParseSSHSpecs(sl []string) ([]*controllerapi.SSH, error) { + var outs []*controllerapi.SSH + if len(sl) == 0 { + return nil, nil } - return sshprovider.NewSSHAgentProvider(configs) -} -func parseSSH(value string) (*sshprovider.AgentConfig, error) { - parts := strings.SplitN(value, "=", 2) - cfg := sshprovider.AgentConfig{ - ID: parts[0], - } - if len(parts) > 1 { - cfg.Paths = strings.Split(parts[1], ",") + for _, s := range sl { + parts := strings.SplitN(s, "=", 2) + out := controllerapi.SSH{ + ID: parts[0], + } + if len(parts) > 1 { + out.Paths = strings.Split(parts[1], ",") + } + outs = append(outs, &out) } - return &cfg, nil + return outs, nil } // IsGitSSH returns true if the given repo URL is accessed over ssh