diff --git a/commands/bake.go b/commands/bake.go index c7f1461e..60fdb457 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -10,7 +10,6 @@ import ( "github.com/docker/buildx/bake" "github.com/docker/buildx/build" "github.com/docker/buildx/builder" - controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/dockerutil" @@ -29,7 +28,11 @@ type bakeOptions struct { printOnly bool sbom string provenance string - controllerapi.CommonOptions + + builder string + metadataFile string + exportPush bool + exportLoad bool } func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags commonFlags) (err error) { @@ -64,12 +67,12 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com } overrides := in.overrides - if in.ExportPush { - if in.ExportLoad { + if in.exportPush { + if in.exportLoad { return errors.Errorf("push and load may not be set together at the moment") } overrides = append(overrides, "*.push=true") - } else if in.ExportLoad { + } else if in.exportLoad { overrides = append(overrides, "*.output=type=docker") } if cFlags.noCache != nil { @@ -97,7 +100,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com // instance only needed for reading remote bake files or building if url != "" || !in.printOnly { b, err := builder.New(dockerCli, - builder.WithName(in.Builder), + builder.WithName(in.builder), builder.WithContextPathHash(contextPathHash), ) if err != nil { @@ -180,12 +183,12 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com return wrapBuildError(err, true) } - if len(in.MetadataFile) > 0 { + if len(in.metadataFile) > 0 { dt := make(map[string]interface{}) for t, r := range resp { dt[t] = decodeExporterResponse(r.ExporterResponse) } - if err := writeMetadataFile(in.MetadataFile, dt); err != nil { + if err := writeMetadataFile(in.metadataFile, dt); err != nil { return err } } @@ -209,8 +212,8 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { if !cmd.Flags().Lookup("pull").Changed { cFlags.pull = nil } - options.Builder = rootOpts.builder - options.MetadataFile = cFlags.metadataFile + options.builder = rootOpts.builder + options.metadataFile = cFlags.metadataFile // Other common flags (noCache, pull and progress) are processed in runBake function. return runBake(dockerCli, args, options, cFlags) }, @@ -219,9 +222,9 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { flags := cmd.Flags() flags.StringArrayVarP(&options.files, "file", "f", []string{}, "Build definition file") - flags.BoolVar(&options.ExportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`) + flags.BoolVar(&options.exportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`) flags.BoolVar(&options.printOnly, "print", false, "Print the options without building") - flags.BoolVar(&options.ExportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`) + flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`) flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`) flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`) flags.StringArrayVar(&options.overrides, "set", nil, `Override target value (e.g., "targetpattern.key=value")`) diff --git a/commands/build.go b/commands/build.go index 3d33ab65..50cbe4d4 100644 --- a/commands/build.go +++ b/commands/build.go @@ -14,6 +14,7 @@ import ( "strings" "github.com/containerd/console" + "github.com/docker/buildx/build" "github.com/docker/buildx/controller" cbuild "github.com/docker/buildx/controller/build" "github.com/docker/buildx/controller/control" @@ -35,6 +36,7 @@ import ( "github.com/moby/buildkit/exporter/containerimage/exptypes" "github.com/moby/buildkit/util/appcontext" "github.com/moby/buildkit/util/grpcerrors" + "github.com/moby/buildkit/util/progress/progressui" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -75,7 +77,13 @@ type buildOptions struct { progress string quiet bool - controllerapi.CommonOptions + builder string + metadataFile string + noCache bool + pull bool + exportPush bool + exportLoad bool + control.ControlOptions } @@ -97,7 +105,12 @@ func (o *buildOptions) toControllerOptions() (controllerapi.BuildOptions, error) Tags: o.tags, Target: o.target, Ulimits: dockerUlimitToControllerUlimit(o.ulimits), - Opts: &o.CommonOptions, + Builder: o.builder, + MetadataFile: o.metadataFile, + NoCache: o.noCache, + Pull: o.pull, + ExportPush: o.exportPush, + ExportLoad: o.exportLoad, } inAttests := append([]string{}, o.attests...) @@ -179,7 +192,7 @@ func runBuild(dockerCli command.Cli, in buildOptions) error { if err != nil { return err } - progress, err := in.toProgress() + progressMode, err := in.toProgress() if err != nil { return err } @@ -190,7 +203,20 @@ func runBuild(dockerCli command.Cli, in buildOptions) error { return errors.Wrap(err, "removing image ID file") } } - resp, _, err := cbuild.RunBuild(ctx, dockerCli, opts, os.Stdin, progress, nil) + resp, _, err := cbuild.RunBuild(ctx, dockerCli, opts, os.Stdin, cbuild.ProgressConfig{ + Printer: func(ctx2 context.Context, ng *store.NodeGroup) (*progress.Printer, error) { + return progress.NewPrinter(ctx2, os.Stderr, os.Stderr, progressMode, progressui.WithDesc( + fmt.Sprintf("building with %q instance using %s driver", ng.Name, ng.Driver), + fmt.Sprintf("%s:%s", ng.Driver, ng.Name), + )) + }, + PrintWarningsFunc: func(warnings []client.VertexWarning) { + cbuild.PrintWarnings(os.Stderr, warnings, progressMode) + }, + PrintResultFunc: func(f *build.PrintFunc, res map[string]string) error { + return cbuild.PrintResult(os.Stdout, f, res) + }, + }) if err != nil { return err } @@ -218,15 +244,15 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { options.contextPath = args[0] - options.Builder = rootOpts.builder - options.MetadataFile = cFlags.metadataFile - options.NoCache = false + options.builder = rootOpts.builder + options.metadataFile = cFlags.metadataFile + options.noCache = false if cFlags.noCache != nil { - options.NoCache = *cFlags.noCache + options.noCache = *cFlags.noCache } - options.Pull = false + options.pull = false if cFlags.pull != nil { - options.Pull = *cFlags.pull + options.pull = *cFlags.pull } options.progress = cFlags.progress cmd.Flags().VisitAll(checkWarnedFlags) @@ -267,7 +293,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { flags.StringArrayVar(&options.labels, "label", []string{}, "Set metadata for an image") - flags.BoolVar(&options.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`) @@ -281,7 +307,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { flags.StringVar(&options.printFunc, "print", "", "Print result of information request (e.g., outline, targets) [experimental]") } - flags.BoolVar(&options.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") @@ -523,7 +549,7 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er return err } opts = *optsP - ref, resp, err := c.Build(ctx, opts, pr, os.Stdout, os.Stderr, progress) + ref, resp, err := control.Build(ctx, c, opts, pr, os.Stdout, os.Stderr, progress) if err != nil { return errors.Wrapf(err, "failed to build") // TODO: allow invoke even on error } @@ -805,8 +831,8 @@ func resolvePaths(options *controllerapi.BuildOptions) (_ *controllerapi.BuildOp } options.SSH = ssh - if options.Opts != nil && options.Opts.MetadataFile != "" { - options.Opts.MetadataFile, err = filepath.Abs(options.Opts.MetadataFile) + if options.MetadataFile != "" { + options.MetadataFile, err = filepath.Abs(options.MetadataFile) if err != nil { return nil, err } diff --git a/commands/build_test.go b/commands/build_test.go index 1a7f335e..43643aa0 100644 --- a/commands/build_test.go +++ b/commands/build_test.go @@ -228,14 +228,10 @@ func TestResolvePaths(t *testing.T) { { name: "metadatafile", options: controllerapi.BuildOptions{ - Opts: &controllerapi.CommonOptions{ - MetadataFile: "test1", - }, + MetadataFile: "test1", }, want: controllerapi.BuildOptions{ - Opts: &controllerapi.CommonOptions{ - MetadataFile: filepath.Join(tmpwd, "test1"), - }, + MetadataFile: filepath.Join(tmpwd, "test1"), }, }, } diff --git a/controller/build/build.go b/controller/build/build.go index 12fa8580..4202d6f8 100644 --- a/controller/build/build.go +++ b/controller/build/build.go @@ -1,12 +1,10 @@ package build import ( - "bytes" "context" "encoding/base64" "encoding/csv" "encoding/json" - "fmt" "io" "os" "path/filepath" @@ -30,19 +28,23 @@ import ( "github.com/docker/go-units" "github.com/moby/buildkit/client" "github.com/moby/buildkit/session/auth/authprovider" - "github.com/moby/buildkit/solver/errdefs" "github.com/moby/buildkit/util/grpcerrors" - "github.com/moby/buildkit/util/progress/progressui" - "github.com/morikuni/aec" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" ) const defaultTargetName = "default" -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 { +// ProgressConfig is configuration about how the progress information is printed. +type ProgressConfig struct { + Printer func(ctx context.Context, ng *store.NodeGroup) (*progress.Printer, error) + PrintWarningsFunc func(warnings []client.VertexWarning) + PrintResultFunc func(f *build.PrintFunc, res map[string]string) error +} + +// RunBuild builds the specified build with providing the build status information through ProgressConfig. +func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progressConfig ProgressConfig) (*client.SolveResponse, *build.ResultContext, error) { + if in.NoCache && len(in.NoCacheFilter) > 0 { return nil, nil, errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together") } @@ -67,9 +69,9 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build ExtraHosts: in.ExtraHosts, Labels: in.Labels, NetworkMode: in.NetworkMode, - NoCache: in.Opts.NoCache, + NoCache: in.NoCache, NoCacheFilter: in.NoCacheFilter, - Pull: in.Opts.Pull, + Pull: in.Pull, ShmSize: dockeropts.MemBytes(in.ShmSize), Tags: in.Tags, Target: in.Target, @@ -106,8 +108,8 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build if err != nil { return nil, nil, err } - if in.Opts.ExportPush { - if in.Opts.ExportLoad { + if in.ExportPush { + if in.ExportLoad { return nil, nil, errors.Errorf("push and load may not be set together at the moment") } if len(outputs) == 0 { @@ -126,7 +128,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build } } } - if in.Opts.ExportLoad { + if in.ExportLoad { if len(outputs) == 0 { outputs = []client.ExportEntry{{ Type: "docker", @@ -160,7 +162,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build } b, err := builder.New(dockerCli, - builder.WithName(in.Opts.Builder), + builder.WithName(in.Builder), builder.WithContextPathHash(contextPathHash), ) if err != nil { @@ -174,7 +176,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build return nil, nil, err } - resp, 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}, progressConfig, in.MetadataFile) err = wrapBuildError(err, false) if err != nil { return nil, nil, err @@ -182,14 +184,11 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build 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) (*client.SolveResponse, *build.ResultContext, error) { +func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progressConfig ProgressConfig, metadataFile string) (*client.SolveResponse, *build.ResultContext, error) { ctx2, cancel := context.WithCancel(context.TODO()) defer cancel() - printer, err := progress.NewPrinter(ctx2, os.Stderr, os.Stderr, progressMode, progressui.WithDesc( - fmt.Sprintf("building with %q instance using %s driver", ng.Name, ng.Driver), - fmt.Sprintf("%s:%s", ng.Driver, ng.Name), - )) + printer, err := progressConfig.Printer(ctx2, ng) if err != nil { return nil, nil, err } @@ -197,7 +196,7 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou 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) { + resp, err := build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), printer, func(driverIndex int, gotRes *build.ResultContext) { mu.Lock() defer mu.Unlock() if res == nil || driverIndex < idx { @@ -218,11 +217,13 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou } } - printWarnings(os.Stderr, printer.Warnings(), progressMode) + if f := progressConfig.PrintWarningsFunc; f != nil { + f(printer.Warnings()) + } for k := range resp { if opts[k].PrintFunc != nil { - if err := printResult(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil { + if err := progressConfig.PrintResultFunc(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil { return nil, nil, err } } @@ -231,46 +232,6 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou return resp[defaultTargetName], res, err } -func printWarnings(w io.Writer, warnings []client.VertexWarning, mode string) { - if len(warnings) == 0 || mode == progress.PrinterModeQuiet { - return - } - fmt.Fprintf(w, "\n ") - sb := &bytes.Buffer{} - if len(warnings) == 1 { - fmt.Fprintf(sb, "1 warning found") - } else { - fmt.Fprintf(sb, "%d warnings found", len(warnings)) - } - if logrus.GetLevel() < logrus.DebugLevel { - fmt.Fprintf(sb, " (use --debug to expand)") - } - fmt.Fprintf(sb, ":\n") - fmt.Fprint(w, aec.Apply(sb.String(), aec.YellowF)) - - for _, warn := range warnings { - fmt.Fprintf(w, " - %s\n", warn.Short) - if logrus.GetLevel() < logrus.DebugLevel { - continue - } - for _, d := range warn.Detail { - fmt.Fprintf(w, "%s\n", d) - } - if warn.URL != "" { - fmt.Fprintf(w, "More info: %s\n", warn.URL) - } - if warn.SourceInfo != nil && warn.Range != nil { - src := errdefs.Source{ - Info: warn.SourceInfo, - Ranges: warn.Range, - } - src.Print(w) - } - fmt.Fprintf(w, "\n") - - } -} - func parsePrintFunc(str string) (*build.PrintFunc, error) { if str == "" { return nil, nil diff --git a/controller/build/print.go b/controller/build/print.go index 6817e5e9..789a6578 100644 --- a/controller/build/print.go +++ b/controller/build/print.go @@ -1,29 +1,35 @@ package build import ( + "bytes" "fmt" "io" "log" - "os" "github.com/docker/buildx/build" + "github.com/docker/buildx/util/progress" "github.com/docker/docker/api/types/versions" + "github.com/moby/buildkit/client" "github.com/moby/buildkit/frontend/subrequests" "github.com/moby/buildkit/frontend/subrequests/outline" "github.com/moby/buildkit/frontend/subrequests/targets" + "github.com/moby/buildkit/solver/errdefs" + "github.com/morikuni/aec" + "github.com/sirupsen/logrus" ) -func printResult(f *build.PrintFunc, res map[string]string) error { +// PrintResult writes the result information to the specified writer. +func PrintResult(w io.Writer, f *build.PrintFunc, res map[string]string) error { switch f.Name { case "outline": - return printValue(outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version, f.Format, res) + return printValue(outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version, f.Format, res, w) case "targets": - return printValue(targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version, f.Format, res) + return printValue(targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version, f.Format, res, w) case "subrequests.describe": - return printValue(subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version, f.Format, res) + return printValue(subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version, f.Format, res, w) default: if dt, ok := res["result.txt"]; ok { - fmt.Print(dt) + fmt.Fprint(w, dt) } else { log.Printf("%s %+v", f, res) } @@ -33,16 +39,57 @@ func printResult(f *build.PrintFunc, res map[string]string) error { type printFunc func([]byte, io.Writer) error -func printValue(printer printFunc, version string, format string, res map[string]string) error { +func printValue(printer printFunc, version string, format string, res map[string]string, w io.Writer) error { if format == "json" { - fmt.Fprintln(os.Stdout, res["result.json"]) + fmt.Fprintln(w, res["result.json"]) return nil } if res["version"] != "" && versions.LessThan(version, res["version"]) && res["result.txt"] != "" { // structure is too new and we don't know how to print it - fmt.Fprint(os.Stdout, res["result.txt"]) + fmt.Fprint(w, res["result.txt"]) return nil } - return printer([]byte(res["result.json"]), os.Stdout) + return printer([]byte(res["result.json"]), w) +} + +// PrintWarnings writes the warning information to the specified writer. +func PrintWarnings(w io.Writer, warnings []client.VertexWarning, mode string) { + if len(warnings) == 0 || mode == progress.PrinterModeQuiet { + return + } + fmt.Fprintf(w, "\n ") + sb := &bytes.Buffer{} + if len(warnings) == 1 { + fmt.Fprintf(sb, "1 warning found") + } else { + fmt.Fprintf(sb, "%d warnings found", len(warnings)) + } + if logrus.GetLevel() < logrus.DebugLevel { + fmt.Fprintf(sb, " (use --debug to expand)") + } + fmt.Fprintf(sb, ":\n") + fmt.Fprint(w, aec.Apply(sb.String(), aec.YellowF)) + + for _, warn := range warnings { + fmt.Fprintf(w, " - %s\n", warn.Short) + if logrus.GetLevel() < logrus.DebugLevel { + continue + } + for _, d := range warn.Detail { + fmt.Fprintf(w, "%s\n", d) + } + if warn.URL != "" { + fmt.Fprintf(w, "More info: %s\n", warn.URL) + } + if warn.SourceInfo != nil && warn.Range != nil { + src := errdefs.Source{ + Info: warn.SourceInfo, + Ranges: warn.Range, + } + src.Print(w) + } + fmt.Fprintf(w, "\n") + + } } diff --git a/controller/control/controller.go b/controller/control/controller.go index 177e770a..0c637e8c 100644 --- a/controller/control/controller.go +++ b/controller/control/controller.go @@ -2,15 +2,25 @@ package control import ( "context" + "fmt" "io" + "os" "github.com/containerd/console" + "github.com/docker/buildx/build" + cbuild "github.com/docker/buildx/controller/build" controllerapi "github.com/docker/buildx/controller/pb" + "github.com/docker/buildx/store" + "github.com/docker/buildx/util/progress" + controlapi "github.com/moby/buildkit/api/services/control" "github.com/moby/buildkit/client" + "github.com/moby/buildkit/util/progress/progressui" + "github.com/pkg/errors" + "golang.org/x/sync/errgroup" ) type BuildxController interface { - Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (ref string, resp *client.SolveResponse, err error) + Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, statusChan chan *controllerapi.StatusResponse) (ref string, resp *client.SolveResponse, err error) // Invoke starts an IO session into the specified process. // If pid doesn't matche to any running processes, it starts a new process with the specified config. // If there is no container running or InvokeConfig.Rollback is speicfied, the process will start in a newly created container. @@ -29,3 +39,205 @@ type ControlOptions struct { Root string Detach bool } + +// Build is a helper function that builds the build and prints the status using the controller. +func Build(ctx context.Context, c BuildxController, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (ref string, resp *client.SolveResponse, err error) { + pwCh := make(chan *progress.Printer) + statusChan := make(chan *controllerapi.StatusResponse) + statusDone := make(chan struct{}) + eg, egCtx := errgroup.WithContext(ctx) + eg.Go(func() error { + defer close(statusChan) + var err error + ref, resp, err = c.Build(egCtx, options, in, statusChan) + return err + }) + var resultInfo []*controllerapi.ResultInfoMessage + eg.Go(func() error { + defer close(statusDone) + var pw *progress.Printer + for s := range statusChan { + st := s + switch m := st.GetStatus().(type) { + case *controllerapi.StatusResponse_NodeInfo: + if pw != nil { + return errors.Errorf("node info is already registered") + } + ng := m.NodeInfo + pw, err = progress.NewPrinter(context.TODO(), w, out, progressMode, progressui.WithDesc( + fmt.Sprintf("building with %q instance using %s driver", ng.Name, ng.Driver), + fmt.Sprintf("%s:%s", ng.Driver, ng.Name), + )) + if err != nil { + return err + } + pwCh <- pw + case *controllerapi.StatusResponse_SolveStatus: + if pw != nil { + pw.Write(toSolveStatus(m.SolveStatus)) + } + case *controllerapi.StatusResponse_ResultInfo: + resultInfo = append(resultInfo, m.ResultInfo) + } + } + return nil + }) + eg.Go(func() error { + pw := <-pwCh + <-statusDone + if err := pw.Wait(); err != nil { + return err + } + cbuild.PrintWarnings(w, pw.Warnings(), progressMode) + return nil + }) + if err := eg.Wait(); err != nil { + return ref, resp, err + } + for _, ri := range resultInfo { + cbuild.PrintResult(w, &build.PrintFunc{Name: ri.Name, Format: ri.Format}, ri.Result) + } + return ref, resp, nil +} + +// ForwardProgress creates a progress printer backed by Status API. +func ForwardProgress(statusChan chan *controllerapi.StatusResponse) cbuild.ProgressConfig { + return cbuild.ProgressConfig{ + Printer: func(ctx context.Context, ng *store.NodeGroup) (*progress.Printer, error) { + statusChan <- &controllerapi.StatusResponse{ + Status: &controllerapi.StatusResponse_NodeInfo{ + NodeInfo: &controllerapi.NodeInfoMessage{Name: ng.Name, Driver: ng.Driver}, + }, + } + pw, err := progress.NewPrinter(ctx, io.Discard, os.Stderr, "quiet") + if err != nil { + return nil, err + } + return progress.Tee(pw, forwardStatus(statusChan)), nil + }, + PrintResultFunc: func(f *build.PrintFunc, res map[string]string) error { + statusChan <- &controllerapi.StatusResponse{ + Status: &controllerapi.StatusResponse_ResultInfo{ + ResultInfo: &controllerapi.ResultInfoMessage{ + Result: res, + Name: f.Name, + Format: f.Format, + }, + }, + } + return nil + }, + // PrintWarningsFunc: printed on the client side + } +} + +func forwardStatus(statusChan chan *controllerapi.StatusResponse) chan *client.SolveStatus { + ch := make(chan *client.SolveStatus) + go func() { + for st := range ch { + st2 := toControlStatus(st) + statusChan <- &controllerapi.StatusResponse{ + Status: &controllerapi.StatusResponse_SolveStatus{ + SolveStatus: st2, + }, + } + } + }() + return ch +} + +func toControlStatus(s *client.SolveStatus) *controllerapi.SolveStatusMessage { + resp := controllerapi.SolveStatusMessage{} + for _, v := range s.Vertexes { + resp.Vertexes = append(resp.Vertexes, &controlapi.Vertex{ + Digest: v.Digest, + Inputs: v.Inputs, + Name: v.Name, + Started: v.Started, + Completed: v.Completed, + Error: v.Error, + Cached: v.Cached, + ProgressGroup: v.ProgressGroup, + }) + } + for _, v := range s.Statuses { + resp.Statuses = append(resp.Statuses, &controlapi.VertexStatus{ + ID: v.ID, + Vertex: v.Vertex, + Name: v.Name, + Total: v.Total, + Current: v.Current, + Timestamp: v.Timestamp, + Started: v.Started, + Completed: v.Completed, + }) + } + for _, v := range s.Logs { + resp.Logs = append(resp.Logs, &controlapi.VertexLog{ + Vertex: v.Vertex, + Stream: int64(v.Stream), + Msg: v.Data, + Timestamp: v.Timestamp, + }) + } + for _, v := range s.Warnings { + resp.Warnings = append(resp.Warnings, &controlapi.VertexWarning{ + Vertex: v.Vertex, + Level: int64(v.Level), + Short: v.Short, + Detail: v.Detail, + Url: v.URL, + Info: v.SourceInfo, + Ranges: v.Range, + }) + } + return &resp +} + +func toSolveStatus(resp *controllerapi.SolveStatusMessage) *client.SolveStatus { + s := client.SolveStatus{} + for _, v := range resp.Vertexes { + s.Vertexes = append(s.Vertexes, &client.Vertex{ + Digest: v.Digest, + Inputs: v.Inputs, + Name: v.Name, + Started: v.Started, + Completed: v.Completed, + Error: v.Error, + Cached: v.Cached, + ProgressGroup: v.ProgressGroup, + }) + } + for _, v := range resp.Statuses { + s.Statuses = append(s.Statuses, &client.VertexStatus{ + ID: v.ID, + Vertex: v.Vertex, + Name: v.Name, + Total: v.Total, + Current: v.Current, + Timestamp: v.Timestamp, + Started: v.Started, + Completed: v.Completed, + }) + } + for _, v := range resp.Logs { + s.Logs = append(s.Logs, &client.VertexLog{ + Vertex: v.Vertex, + Stream: int(v.Stream), + Data: v.Msg, + Timestamp: v.Timestamp, + }) + } + for _, v := range resp.Warnings { + s.Warnings = append(s.Warnings, &client.VertexWarning{ + Vertex: v.Vertex, + Level: int(v.Level), + Short: v.Short, + Detail: v.Detail, + URL: v.Url, + SourceInfo: v.Info, + Range: v.Ranges, + }) + } + return &s +} diff --git a/controller/local/controller.go b/controller/local/controller.go index 4c462d7d..144d8d8f 100644 --- a/controller/local/controller.go +++ b/controller/local/controller.go @@ -5,7 +5,6 @@ import ( "io" "sync/atomic" - "github.com/containerd/console" "github.com/docker/buildx/build" cbuild "github.com/docker/buildx/controller/build" "github.com/docker/buildx/controller/control" @@ -34,13 +33,13 @@ type localController struct { buildOnGoing atomic.Bool } -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) { +func (b *localController) Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, statusChan chan *controllerapi.StatusResponse) (string, *client.SolveResponse, error) { if !b.buildOnGoing.CompareAndSwap(false, true) { return "", nil, errors.New("build ongoing") } defer b.buildOnGoing.Store(false) - resp, res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, progressMode, nil) + resp, res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, control.ForwardProgress(statusChan)) if err != nil { return "", nil, err } diff --git a/controller/pb/controller.pb.go b/controller/pb/controller.pb.go index ec675210..d6220598 100644 --- a/controller/pb/controller.pb.go +++ b/controller/pb/controller.pb.go @@ -292,7 +292,12 @@ type BuildOptions struct { 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"` + Builder string `protobuf:"bytes,23,opt,name=Builder,proto3" json:"Builder,omitempty"` + MetadataFile string `protobuf:"bytes,24,opt,name=MetadataFile,proto3" json:"MetadataFile,omitempty"` + NoCache bool `protobuf:"varint,25,opt,name=NoCache,proto3" json:"NoCache,omitempty"` + Pull bool `protobuf:"varint,26,opt,name=Pull,proto3" json:"Pull,omitempty"` + ExportPush bool `protobuf:"varint,27,opt,name=ExportPush,proto3" json:"ExportPush,omitempty"` + ExportLoad bool `protobuf:"varint,28,opt,name=ExportLoad,proto3" json:"ExportLoad,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -476,11 +481,46 @@ func (m *BuildOptions) GetUlimits() *UlimitOpt { return nil } -func (m *BuildOptions) GetOpts() *CommonOptions { +func (m *BuildOptions) GetBuilder() string { if m != nil { - return m.Opts + return m.Builder } - return nil + return "" +} + +func (m *BuildOptions) GetMetadataFile() string { + if m != nil { + return m.MetadataFile + } + return "" +} + +func (m *BuildOptions) GetNoCache() bool { + if m != nil { + return m.NoCache + } + return false +} + +func (m *BuildOptions) GetPull() bool { + if m != nil { + return m.Pull + } + return false +} + +func (m *BuildOptions) GetExportPush() bool { + if m != nil { + return m.ExportPush + } + return false +} + +func (m *BuildOptions) GetExportLoad() bool { + if m != nil { + return m.ExportLoad + } + return false } type ExportEntry struct { @@ -829,85 +869,6 @@ func (m *Ulimit) GetSoft() int64 { return 0 } -type CommonOptions struct { - Builder string `protobuf:"bytes,1,opt,name=Builder,proto3" json:"Builder,omitempty"` - MetadataFile string `protobuf:"bytes,2,opt,name=MetadataFile,proto3" json:"MetadataFile,omitempty"` - NoCache bool `protobuf:"varint,3,opt,name=NoCache,proto3" json:"NoCache,omitempty"` - // string Progress: no progress view on server side - 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"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -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{14} -} -func (m *CommonOptions) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CommonOptions.Unmarshal(m, b) -} -func (m *CommonOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CommonOptions.Marshal(b, m, deterministic) -} -func (m *CommonOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommonOptions.Merge(m, src) -} -func (m *CommonOptions) XXX_Size() int { - return xxx_messageInfo_CommonOptions.Size(m) -} -func (m *CommonOptions) XXX_DiscardUnknown() { - xxx_messageInfo_CommonOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_CommonOptions proto.InternalMessageInfo - -func (m *CommonOptions) GetBuilder() string { - if m != nil { - return m.Builder - } - return "" -} - -func (m *CommonOptions) GetMetadataFile() string { - if m != nil { - return m.MetadataFile - } - return "" -} - -func (m *CommonOptions) GetNoCache() bool { - if m != nil { - return m.NoCache - } - return false -} - -func (m *CommonOptions) GetPull() bool { - if m != nil { - return m.Pull - } - return false -} - -func (m *CommonOptions) GetExportPush() bool { - if m != nil { - return m.ExportPush - } - return false -} - -func (m *CommonOptions) GetExportLoad() bool { - if m != nil { - return m.ExportLoad - } - return false -} - type BuildResponse struct { 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:"-"` @@ -919,7 +880,7 @@ 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{15} + return fileDescriptor_ed7f10298fa1d90f, []int{14} } func (m *BuildResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BuildResponse.Unmarshal(m, b) @@ -957,7 +918,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{16} + return fileDescriptor_ed7f10298fa1d90f, []int{15} } func (m *DisconnectRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DisconnectRequest.Unmarshal(m, b) @@ -994,7 +955,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{17} + return fileDescriptor_ed7f10298fa1d90f, []int{16} } func (m *DisconnectResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DisconnectResponse.Unmarshal(m, b) @@ -1025,7 +986,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{18} + return fileDescriptor_ed7f10298fa1d90f, []int{17} } func (m *ListRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRequest.Unmarshal(m, b) @@ -1063,7 +1024,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{19} + return fileDescriptor_ed7f10298fa1d90f, []int{18} } func (m *ListResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListResponse.Unmarshal(m, b) @@ -1104,7 +1065,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{20} + return fileDescriptor_ed7f10298fa1d90f, []int{19} } func (m *InputMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InputMessage.Unmarshal(m, b) @@ -1178,7 +1139,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{21} + return fileDescriptor_ed7f10298fa1d90f, []int{20} } func (m *InputInitMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InputInitMessage.Unmarshal(m, b) @@ -1217,7 +1178,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{22} + return fileDescriptor_ed7f10298fa1d90f, []int{21} } func (m *DataMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DataMessage.Unmarshal(m, b) @@ -1261,7 +1222,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{23} + return fileDescriptor_ed7f10298fa1d90f, []int{22} } func (m *InputResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InputResponse.Unmarshal(m, b) @@ -1297,7 +1258,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{24} + return fileDescriptor_ed7f10298fa1d90f, []int{23} } func (m *Message) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Message.Unmarshal(m, b) @@ -1399,7 +1360,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{25} + return fileDescriptor_ed7f10298fa1d90f, []int{24} } func (m *InitMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMessage.Unmarshal(m, b) @@ -1459,7 +1420,7 @@ func (m *InvokeConfig) Reset() { *m = InvokeConfig{} } func (m *InvokeConfig) String() string { return proto.CompactTextString(m) } func (*InvokeConfig) ProtoMessage() {} func (*InvokeConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{26} + return fileDescriptor_ed7f10298fa1d90f, []int{25} } func (m *InvokeConfig) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InvokeConfig.Unmarshal(m, b) @@ -1555,7 +1516,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{27} + return fileDescriptor_ed7f10298fa1d90f, []int{26} } func (m *FdMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FdMessage.Unmarshal(m, b) @@ -1608,7 +1569,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{28} + return fileDescriptor_ed7f10298fa1d90f, []int{27} } func (m *ResizeMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResizeMessage.Unmarshal(m, b) @@ -1655,7 +1616,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{29} + return fileDescriptor_ed7f10298fa1d90f, []int{28} } func (m *SignalMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SignalMessage.Unmarshal(m, b) @@ -1693,7 +1654,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{30} + return fileDescriptor_ed7f10298fa1d90f, []int{29} } func (m *StatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatusRequest.Unmarshal(m, b) @@ -1721,20 +1682,22 @@ func (m *StatusRequest) GetRef() string { } type StatusResponse struct { - Vertexes []*control.Vertex `protobuf:"bytes,1,rep,name=vertexes,proto3" json:"vertexes,omitempty"` - Statuses []*control.VertexStatus `protobuf:"bytes,2,rep,name=statuses,proto3" json:"statuses,omitempty"` - Logs []*control.VertexLog `protobuf:"bytes,3,rep,name=logs,proto3" json:"logs,omitempty"` - Warnings []*control.VertexWarning `protobuf:"bytes,4,rep,name=warnings,proto3" json:"warnings,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + // Types that are valid to be assigned to Status: + // + // *StatusResponse_SolveStatus + // *StatusResponse_NodeInfo + // *StatusResponse_ResultInfo + Status isStatusResponse_Status `protobuf_oneof:"Status"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } 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{31} + return fileDescriptor_ed7f10298fa1d90f, []int{30} } func (m *StatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatusResponse.Unmarshal(m, b) @@ -1754,34 +1717,223 @@ func (m *StatusResponse) XXX_DiscardUnknown() { var xxx_messageInfo_StatusResponse proto.InternalMessageInfo -func (m *StatusResponse) GetVertexes() []*control.Vertex { +type isStatusResponse_Status interface { + isStatusResponse_Status() +} + +type StatusResponse_SolveStatus struct { + SolveStatus *SolveStatusMessage `protobuf:"bytes,1,opt,name=SolveStatus,proto3,oneof" json:"SolveStatus,omitempty"` +} +type StatusResponse_NodeInfo struct { + NodeInfo *NodeInfoMessage `protobuf:"bytes,2,opt,name=NodeInfo,proto3,oneof" json:"NodeInfo,omitempty"` +} +type StatusResponse_ResultInfo struct { + ResultInfo *ResultInfoMessage `protobuf:"bytes,3,opt,name=ResultInfo,proto3,oneof" json:"ResultInfo,omitempty"` +} + +func (*StatusResponse_SolveStatus) isStatusResponse_Status() {} +func (*StatusResponse_NodeInfo) isStatusResponse_Status() {} +func (*StatusResponse_ResultInfo) isStatusResponse_Status() {} + +func (m *StatusResponse) GetStatus() isStatusResponse_Status { + if m != nil { + return m.Status + } + return nil +} + +func (m *StatusResponse) GetSolveStatus() *SolveStatusMessage { + if x, ok := m.GetStatus().(*StatusResponse_SolveStatus); ok { + return x.SolveStatus + } + return nil +} + +func (m *StatusResponse) GetNodeInfo() *NodeInfoMessage { + if x, ok := m.GetStatus().(*StatusResponse_NodeInfo); ok { + return x.NodeInfo + } + return nil +} + +func (m *StatusResponse) GetResultInfo() *ResultInfoMessage { + if x, ok := m.GetStatus().(*StatusResponse_ResultInfo); ok { + return x.ResultInfo + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*StatusResponse) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*StatusResponse_SolveStatus)(nil), + (*StatusResponse_NodeInfo)(nil), + (*StatusResponse_ResultInfo)(nil), + } +} + +type SolveStatusMessage struct { + Vertexes []*control.Vertex `protobuf:"bytes,1,rep,name=vertexes,proto3" json:"vertexes,omitempty"` + Statuses []*control.VertexStatus `protobuf:"bytes,2,rep,name=statuses,proto3" json:"statuses,omitempty"` + Logs []*control.VertexLog `protobuf:"bytes,3,rep,name=logs,proto3" json:"logs,omitempty"` + Warnings []*control.VertexWarning `protobuf:"bytes,4,rep,name=warnings,proto3" json:"warnings,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SolveStatusMessage) Reset() { *m = SolveStatusMessage{} } +func (m *SolveStatusMessage) String() string { return proto.CompactTextString(m) } +func (*SolveStatusMessage) ProtoMessage() {} +func (*SolveStatusMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_ed7f10298fa1d90f, []int{31} +} +func (m *SolveStatusMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SolveStatusMessage.Unmarshal(m, b) +} +func (m *SolveStatusMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SolveStatusMessage.Marshal(b, m, deterministic) +} +func (m *SolveStatusMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_SolveStatusMessage.Merge(m, src) +} +func (m *SolveStatusMessage) XXX_Size() int { + return xxx_messageInfo_SolveStatusMessage.Size(m) +} +func (m *SolveStatusMessage) XXX_DiscardUnknown() { + xxx_messageInfo_SolveStatusMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_SolveStatusMessage proto.InternalMessageInfo + +func (m *SolveStatusMessage) GetVertexes() []*control.Vertex { if m != nil { return m.Vertexes } return nil } -func (m *StatusResponse) GetStatuses() []*control.VertexStatus { +func (m *SolveStatusMessage) GetStatuses() []*control.VertexStatus { if m != nil { return m.Statuses } return nil } -func (m *StatusResponse) GetLogs() []*control.VertexLog { +func (m *SolveStatusMessage) GetLogs() []*control.VertexLog { if m != nil { return m.Logs } return nil } -func (m *StatusResponse) GetWarnings() []*control.VertexWarning { +func (m *SolveStatusMessage) GetWarnings() []*control.VertexWarning { if m != nil { return m.Warnings } return nil } +type NodeInfoMessage struct { + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + Driver string `protobuf:"bytes,2,opt,name=Driver,proto3" json:"Driver,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NodeInfoMessage) Reset() { *m = NodeInfoMessage{} } +func (m *NodeInfoMessage) String() string { return proto.CompactTextString(m) } +func (*NodeInfoMessage) ProtoMessage() {} +func (*NodeInfoMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_ed7f10298fa1d90f, []int{32} +} +func (m *NodeInfoMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NodeInfoMessage.Unmarshal(m, b) +} +func (m *NodeInfoMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NodeInfoMessage.Marshal(b, m, deterministic) +} +func (m *NodeInfoMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeInfoMessage.Merge(m, src) +} +func (m *NodeInfoMessage) XXX_Size() int { + return xxx_messageInfo_NodeInfoMessage.Size(m) +} +func (m *NodeInfoMessage) XXX_DiscardUnknown() { + xxx_messageInfo_NodeInfoMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeInfoMessage proto.InternalMessageInfo + +func (m *NodeInfoMessage) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *NodeInfoMessage) GetDriver() string { + if m != nil { + return m.Driver + } + return "" +} + +type ResultInfoMessage struct { + Result map[string]string `protobuf:"bytes,1,rep,name=Result,proto3" json:"Result,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` + Format string `protobuf:"bytes,3,opt,name=Format,proto3" json:"Format,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ResultInfoMessage) Reset() { *m = ResultInfoMessage{} } +func (m *ResultInfoMessage) String() string { return proto.CompactTextString(m) } +func (*ResultInfoMessage) ProtoMessage() {} +func (*ResultInfoMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_ed7f10298fa1d90f, []int{33} +} +func (m *ResultInfoMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ResultInfoMessage.Unmarshal(m, b) +} +func (m *ResultInfoMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ResultInfoMessage.Marshal(b, m, deterministic) +} +func (m *ResultInfoMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResultInfoMessage.Merge(m, src) +} +func (m *ResultInfoMessage) XXX_Size() int { + return xxx_messageInfo_ResultInfoMessage.Size(m) +} +func (m *ResultInfoMessage) XXX_DiscardUnknown() { + xxx_messageInfo_ResultInfoMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_ResultInfoMessage proto.InternalMessageInfo + +func (m *ResultInfoMessage) GetResult() map[string]string { + if m != nil { + return m.Result + } + return nil +} + +func (m *ResultInfoMessage) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ResultInfoMessage) GetFormat() string { + if m != nil { + return m.Format + } + return "" +} + type InfoRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -1792,7 +1944,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{32} + return fileDescriptor_ed7f10298fa1d90f, []int{34} } func (m *InfoRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InfoRequest.Unmarshal(m, b) @@ -1823,7 +1975,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{33} + return fileDescriptor_ed7f10298fa1d90f, []int{35} } func (m *InfoResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InfoResponse.Unmarshal(m, b) @@ -1863,7 +2015,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{34} + return fileDescriptor_ed7f10298fa1d90f, []int{36} } func (m *BuildxVersion) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BuildxVersion.Unmarshal(m, b) @@ -1925,7 +2077,6 @@ func init() { 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") @@ -1944,6 +2095,10 @@ func init() { proto.RegisterType((*SignalMessage)(nil), "buildx.controller.v1.SignalMessage") proto.RegisterType((*StatusRequest)(nil), "buildx.controller.v1.StatusRequest") proto.RegisterType((*StatusResponse)(nil), "buildx.controller.v1.StatusResponse") + proto.RegisterType((*SolveStatusMessage)(nil), "buildx.controller.v1.SolveStatusMessage") + proto.RegisterType((*NodeInfoMessage)(nil), "buildx.controller.v1.NodeInfoMessage") + proto.RegisterType((*ResultInfoMessage)(nil), "buildx.controller.v1.ResultInfoMessage") + proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.ResultInfoMessage.ResultEntry") proto.RegisterType((*InfoRequest)(nil), "buildx.controller.v1.InfoRequest") proto.RegisterType((*InfoResponse)(nil), "buildx.controller.v1.InfoResponse") proto.RegisterType((*BuildxVersion)(nil), "buildx.controller.v1.BuildxVersion") @@ -1952,119 +2107,127 @@ func init() { func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) } var fileDescriptor_ed7f10298fa1d90f = []byte{ - // 1790 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6e, 0x23, 0xc7, - 0x11, 0xce, 0x90, 0x14, 0x7f, 0x8a, 0xa2, 0xac, 0xed, 0x68, 0x8d, 0x31, 0xed, 0x78, 0xb5, 0xb3, - 0x1b, 0x87, 0xc8, 0x06, 0x94, 0x2d, 0xc7, 0x59, 0xaf, 0x77, 0x03, 0x44, 0xa2, 0x44, 0x48, 0xc6, - 0xea, 0x07, 0x4d, 0xed, 0x1a, 0x49, 0x80, 0x18, 0x43, 0xb2, 0x45, 0x0d, 0x38, 0x9c, 0x66, 0xa6, - 0x9b, 0x94, 0x98, 0x53, 0x2e, 0xbe, 0xe6, 0x3d, 0x82, 0x5c, 0x73, 0xcb, 0x29, 0xef, 0x90, 0x07, - 0xc9, 0x23, 0x04, 0x5d, 0xdd, 0x33, 0x9c, 0x11, 0x39, 0x94, 0x14, 0x9f, 0xd8, 0x55, 0xf3, 0x55, - 0x55, 0x57, 0x75, 0xfd, 0x74, 0x13, 0x36, 0x7b, 0x3c, 0x90, 0x21, 0xf7, 0x7d, 0x16, 0x36, 0xc7, - 0x21, 0x97, 0x9c, 0x6c, 0x75, 0x27, 0x9e, 0xdf, 0xbf, 0x69, 0x26, 0x3e, 0x4c, 0xbf, 0xa8, 0xbf, - 0x1e, 0x78, 0xf2, 0x6a, 0xd2, 0x6d, 0xf6, 0xf8, 0x68, 0x67, 0xc4, 0xbb, 0xb3, 0x1d, 0x44, 0x0d, - 0x3d, 0xb9, 0xe3, 0x8e, 0xbd, 0x1d, 0xc1, 0xc2, 0xa9, 0xd7, 0x63, 0x62, 0xc7, 0x08, 0x45, 0xbf, - 0x5a, 0xa5, 0xd3, 0x80, 0xad, 0xb7, 0x9e, 0x90, 0xe7, 0x21, 0xef, 0x31, 0x21, 0x98, 0xa0, 0xec, - 0xcf, 0x13, 0x26, 0x24, 0xd9, 0x84, 0x3c, 0x65, 0x97, 0xb6, 0xb5, 0x6d, 0x35, 0x2a, 0x54, 0x2d, - 0x9d, 0x73, 0x78, 0x7c, 0x0b, 0x29, 0xc6, 0x3c, 0x10, 0x8c, 0xbc, 0x84, 0xb5, 0xe3, 0xe0, 0x92, - 0x0b, 0xdb, 0xda, 0xce, 0x37, 0xaa, 0xbb, 0x4f, 0x9b, 0xcb, 0x76, 0xd9, 0x34, 0x72, 0x0a, 0x49, - 0x35, 0xde, 0x11, 0x50, 0x4d, 0x70, 0xc9, 0x27, 0x50, 0x89, 0xc8, 0x03, 0x63, 0x78, 0xce, 0x20, - 0x6d, 0x58, 0x3f, 0x0e, 0xa6, 0x7c, 0xc8, 0x5a, 0x3c, 0xb8, 0xf4, 0x06, 0x76, 0x6e, 0xdb, 0x6a, - 0x54, 0x77, 0x9d, 0xe5, 0xc6, 0x92, 0x48, 0x9a, 0x92, 0x73, 0xbe, 0x05, 0xfb, 0xc0, 0x13, 0x3d, - 0x1e, 0x04, 0xac, 0x17, 0x39, 0x93, 0xe9, 0x74, 0x7a, 0x4f, 0xb9, 0x5b, 0x7b, 0x72, 0x3e, 0x86, - 0x8f, 0x96, 0xe8, 0xd2, 0x61, 0x71, 0xfe, 0x04, 0xeb, 0xfb, 0x6a, 0x6f, 0xd9, 0xca, 0xdf, 0x40, - 0xe9, 0x6c, 0x2c, 0x3d, 0x1e, 0x88, 0xd5, 0xde, 0xa0, 0x1a, 0x83, 0xa4, 0x91, 0x88, 0xf3, 0x03, - 0x18, 0x03, 0x86, 0x41, 0xb6, 0xa1, 0xda, 0xe2, 0x81, 0x64, 0x37, 0xf2, 0xdc, 0x95, 0x57, 0xc6, - 0x50, 0x92, 0x45, 0x3e, 0x83, 0x8d, 0x03, 0xde, 0x1b, 0xb2, 0xf0, 0xd2, 0xf3, 0xd9, 0xa9, 0x3b, - 0x62, 0xc6, 0xa5, 0x5b, 0x5c, 0xed, 0xb5, 0x17, 0xc8, 0xf6, 0x24, 0xe8, 0xd9, 0xf9, 0xc8, 0x6b, - 0xc3, 0x20, 0x7f, 0x84, 0x9a, 0x42, 0xf5, 0x8d, 0x66, 0x61, 0x17, 0xf0, 0xdc, 0xbf, 0xba, 0x7b, - 0xf3, 0xcd, 0x94, 0xdc, 0x61, 0x20, 0xc3, 0x19, 0x4d, 0xeb, 0x22, 0x5b, 0xb0, 0xb6, 0xe7, 0xfb, - 0xfc, 0xda, 0x5e, 0xdb, 0xce, 0x37, 0x2a, 0x54, 0x13, 0xe4, 0x37, 0x50, 0xda, 0x93, 0x92, 0x09, - 0x29, 0xec, 0x22, 0x1a, 0xfb, 0x64, 0xb9, 0x31, 0x0d, 0xa2, 0x11, 0x98, 0x9c, 0x41, 0x05, 0xed, - 0xef, 0x85, 0x03, 0x61, 0x97, 0x50, 0xf2, 0x8b, 0x7b, 0x6c, 0x33, 0x96, 0xd1, 0x5b, 0x9c, 0xeb, - 0x20, 0x87, 0x50, 0x69, 0xb9, 0xbd, 0x2b, 0xd6, 0x0e, 0xf9, 0xc8, 0x2e, 0xa3, 0xc2, 0x5f, 0x2c, - 0x57, 0x88, 0x30, 0xa3, 0xd0, 0xa8, 0x89, 0x25, 0xc9, 0x1e, 0x94, 0x90, 0xb8, 0xe0, 0x76, 0xe5, - 0x61, 0x4a, 0x22, 0x39, 0xe2, 0xc0, 0x7a, 0x6b, 0x10, 0xf2, 0xc9, 0xf8, 0xdc, 0x0d, 0x59, 0x20, - 0x6d, 0xc0, 0x63, 0x4a, 0xf1, 0xc8, 0x6b, 0x28, 0x1d, 0xde, 0x8c, 0x79, 0x28, 0x85, 0x5d, 0x5d, - 0x55, 0x9b, 0x1a, 0x64, 0x0c, 0x18, 0x09, 0xf2, 0x29, 0xc0, 0xe1, 0x8d, 0x0c, 0xdd, 0x23, 0xae, - 0xc2, 0xbe, 0x8e, 0xc7, 0x91, 0xe0, 0x90, 0x36, 0x14, 0xdf, 0xba, 0x5d, 0xe6, 0x0b, 0xbb, 0x86, - 0xba, 0x9b, 0xf7, 0x08, 0xac, 0x16, 0xd0, 0x86, 0x8c, 0xb4, 0x4a, 0xdb, 0x53, 0x26, 0xaf, 0x79, - 0x38, 0x3c, 0xe1, 0x7d, 0x66, 0x6f, 0xe8, 0xb4, 0x4d, 0xb0, 0xc8, 0x73, 0xa8, 0x9d, 0x72, 0x1d, - 0x3c, 0xcf, 0x97, 0x2c, 0xb4, 0x3f, 0xc0, 0xcd, 0xa4, 0x99, 0x98, 0xb4, 0xbe, 0x2b, 0x2f, 0x79, - 0x38, 0x12, 0xf6, 0x26, 0x22, 0xe6, 0x0c, 0x95, 0x41, 0x1d, 0xd6, 0x0b, 0x99, 0x14, 0xf6, 0xa3, - 0x55, 0x19, 0xa4, 0x41, 0x34, 0x02, 0x13, 0x1b, 0x4a, 0x9d, 0xab, 0x51, 0xc7, 0xfb, 0x0b, 0xb3, - 0xc9, 0xb6, 0xd5, 0xc8, 0xd3, 0x88, 0x24, 0x2f, 0x20, 0xdf, 0xe9, 0x1c, 0xd9, 0x3f, 0x45, 0x6d, - 0x1f, 0x65, 0x68, 0xeb, 0x1c, 0x51, 0x85, 0x22, 0x04, 0x0a, 0x17, 0xee, 0x40, 0xd8, 0x5b, 0xb8, - 0x2f, 0x5c, 0x93, 0x0f, 0xa1, 0x78, 0xe1, 0x86, 0x03, 0x26, 0xed, 0xc7, 0xe8, 0xb3, 0xa1, 0xc8, - 0x2b, 0x28, 0xbd, 0xf3, 0xbd, 0x91, 0x27, 0x85, 0xfd, 0x21, 0xb6, 0x85, 0x27, 0xcb, 0x95, 0x6b, - 0xd0, 0xd9, 0x58, 0xd2, 0x08, 0x4f, 0x5e, 0x42, 0xe1, 0x6c, 0x2c, 0x85, 0x6d, 0xa3, 0xdc, 0xb3, - 0x8c, 0xa4, 0xe2, 0xa3, 0x11, 0x0f, 0xa2, 0x7e, 0x82, 0x02, 0xf5, 0xdf, 0x01, 0x59, 0xac, 0x4d, - 0xd5, 0xb2, 0x86, 0x6c, 0x16, 0xb5, 0xac, 0x21, 0x9b, 0xa9, 0xf2, 0x9c, 0xba, 0xfe, 0x24, 0x6a, - 0x1c, 0x9a, 0xf8, 0x26, 0xf7, 0xb5, 0x55, 0x7f, 0x03, 0x1b, 0xe9, 0xb2, 0x79, 0x90, 0xf4, 0x2b, - 0xa8, 0x26, 0x72, 0xe3, 0x21, 0xa2, 0xce, 0xbf, 0x2d, 0xa8, 0x26, 0x12, 0x18, 0x43, 0x3d, 0x1b, - 0x33, 0x23, 0x8c, 0x6b, 0xb2, 0x0f, 0x6b, 0x7b, 0x52, 0x86, 0xaa, 0xcf, 0xaa, 0xd3, 0xfa, 0xd5, - 0x9d, 0x65, 0xd0, 0x44, 0xb8, 0x4e, 0x54, 0x2d, 0xaa, 0xf2, 0xf4, 0x80, 0x09, 0xe9, 0x05, 0xae, - 0x0a, 0x9c, 0x69, 0x8b, 0x49, 0x56, 0xfd, 0x6b, 0x80, 0xb9, 0xd8, 0x83, 0x7c, 0xf8, 0x87, 0x05, - 0x8f, 0x16, 0x6a, 0x7d, 0xa9, 0x27, 0x47, 0x69, 0x4f, 0x76, 0xef, 0xd9, 0x37, 0x16, 0xfd, 0xf9, - 0x11, 0xbb, 0x3d, 0x85, 0xa2, 0x6e, 0xb0, 0x4b, 0x77, 0x58, 0x87, 0xf2, 0x81, 0x27, 0xdc, 0xae, - 0xcf, 0xfa, 0x28, 0x5a, 0xa6, 0x31, 0x8d, 0xdd, 0x1d, 0x77, 0xaf, 0xa3, 0xa7, 0x09, 0x47, 0x57, - 0x12, 0xd9, 0x80, 0x5c, 0x3c, 0xf8, 0x73, 0xc7, 0x07, 0x0a, 0xac, 0xa6, 0x96, 0x76, 0xb5, 0x42, - 0x35, 0xe1, 0xb4, 0xa1, 0xa8, 0x6b, 0x73, 0x01, 0x5f, 0x87, 0x72, 0xdb, 0xf3, 0x19, 0x0e, 0x3f, - 0xbd, 0xe7, 0x98, 0x56, 0xee, 0x1d, 0x06, 0x53, 0x63, 0x56, 0x2d, 0x9d, 0xbf, 0x5b, 0x50, 0x89, - 0x2b, 0x88, 0xb4, 0xa0, 0x88, 0xfe, 0x45, 0x97, 0x98, 0x17, 0x77, 0x94, 0x5c, 0xf3, 0x3d, 0xa2, - 0x4d, 0x27, 0xd3, 0xa2, 0xf5, 0xef, 0xa0, 0x9a, 0x60, 0x2f, 0x09, 0xe9, 0x6e, 0x32, 0xa4, 0x99, - 0x2d, 0x48, 0x1b, 0x49, 0x06, 0xfc, 0x00, 0x8a, 0x9a, 0xa9, 0x02, 0x8e, 0x73, 0xdb, 0x04, 0x1c, - 0xa7, 0x35, 0x81, 0xc2, 0x91, 0x1b, 0xea, 0x60, 0xe7, 0x29, 0xae, 0x15, 0xaf, 0xc3, 0x2f, 0x25, - 0x3a, 0x9c, 0xa7, 0xb8, 0x76, 0xfe, 0x65, 0x41, 0x2d, 0x55, 0xfb, 0xaa, 0xb9, 0x61, 0xcd, 0xb2, - 0xd0, 0x28, 0x8c, 0x48, 0x35, 0x5d, 0x4e, 0x98, 0x74, 0xfb, 0xae, 0x74, 0x55, 0x0c, 0x4d, 0x3c, - 0x53, 0x3c, 0x25, 0x6d, 0x3a, 0x30, 0x9a, 0x29, 0xd3, 0x88, 0x54, 0xd6, 0xcf, 0x27, 0xbe, 0x6f, - 0x17, 0x90, 0x8d, 0x6b, 0x3d, 0x4e, 0x54, 0x7d, 0x9d, 0x4f, 0xc4, 0x95, 0xbd, 0x86, 0x5f, 0x12, - 0x9c, 0xf9, 0xf7, 0xb7, 0xdc, 0xed, 0xdb, 0xc5, 0xe4, 0x77, 0xc5, 0xc1, 0xdd, 0x9b, 0xfb, 0x94, - 0xb9, 0x77, 0x32, 0xd8, 0xd4, 0xdf, 0x59, 0x18, 0xf1, 0xcc, 0xe9, 0xbd, 0x5a, 0x31, 0x8a, 0x22, - 0x68, 0xf3, 0xb6, 0xac, 0x3e, 0xcb, 0x05, 0x95, 0xf5, 0x16, 0x3c, 0x5e, 0x0a, 0x7d, 0x50, 0xc9, - 0xfc, 0x1c, 0x1e, 0xcd, 0x6f, 0x8a, 0xd9, 0x77, 0xec, 0x2d, 0x20, 0x49, 0x98, 0xb9, 0x49, 0x3e, - 0x81, 0xaa, 0xba, 0x79, 0x67, 0x8b, 0x39, 0xb0, 0xae, 0x01, 0x26, 0x32, 0x04, 0x0a, 0x43, 0x36, - 0xd3, 0xb9, 0x5c, 0xa1, 0xb8, 0x76, 0xfe, 0x66, 0xa9, 0x0b, 0xf4, 0x78, 0x22, 0x4f, 0x98, 0x10, - 0xee, 0x80, 0x91, 0x37, 0x50, 0x38, 0x0e, 0x3c, 0x89, 0x7a, 0xaa, 0xbb, 0x9f, 0x65, 0x5d, 0xa4, - 0xc7, 0x13, 0xa9, 0x60, 0x46, 0xea, 0xe8, 0x27, 0x14, 0xa5, 0xd4, 0xa4, 0x39, 0x70, 0xa5, 0x6b, - 0x32, 0x39, 0xe3, 0x5e, 0xa1, 0x10, 0x09, 0x41, 0x45, 0xee, 0x97, 0xd4, 0x6b, 0x61, 0x3c, 0x91, - 0xce, 0x73, 0xd8, 0xbc, 0xad, 0x7d, 0x89, 0x6b, 0x5f, 0x42, 0x35, 0xa1, 0x05, 0xeb, 0xf8, 0xac, - 0x8d, 0x80, 0x32, 0x55, 0x4b, 0xe5, 0x6b, 0xbc, 0x91, 0x75, 0x6d, 0xc3, 0xf9, 0x00, 0x6a, 0xa8, - 0x3a, 0x8e, 0xe0, 0x5f, 0x73, 0x50, 0x8a, 0x54, 0xbc, 0x4c, 0xf9, 0xfd, 0x34, 0xcb, 0xef, 0x45, - 0x97, 0xbf, 0x82, 0x42, 0x5c, 0x0b, 0x99, 0x43, 0xb9, 0xdd, 0x4f, 0x88, 0x61, 0x99, 0xfc, 0x16, - 0x8a, 0x94, 0x09, 0x75, 0x81, 0xc8, 0xaf, 0x9a, 0xca, 0x1a, 0x33, 0x17, 0x36, 0x42, 0x4a, 0xbc, - 0xe3, 0x0d, 0x02, 0x57, 0x57, 0x53, 0xa6, 0xb8, 0xc6, 0x24, 0xc4, 0x35, 0x63, 0x1e, 0xee, 0x1f, - 0x2c, 0xa8, 0xae, 0x0c, 0xf5, 0xea, 0xb7, 0xce, 0xc2, 0xfb, 0x2b, 0xff, 0x7f, 0xbe, 0xbf, 0xfe, - 0x63, 0xa5, 0x15, 0x61, 0xe1, 0xab, 0x7a, 0x1a, 0x73, 0x2f, 0x90, 0x26, 0x65, 0x13, 0x1c, 0xb5, - 0xd1, 0xd6, 0xa8, 0x6f, 0x86, 0x80, 0x5a, 0xce, 0x9b, 0x79, 0xde, 0x34, 0x73, 0x95, 0x04, 0xef, - 0x04, 0x0b, 0x31, 0x44, 0x15, 0x8a, 0x6b, 0x75, 0xbd, 0x3a, 0xe5, 0xc8, 0xd5, 0xcd, 0xc6, 0x50, - 0xa8, 0xef, 0x5a, 0x77, 0x18, 0xa5, 0xef, 0x1a, 0xa7, 0xd2, 0x29, 0x57, 0xbc, 0x12, 0x02, 0x35, - 0xa1, 0x70, 0x17, 0x72, 0x66, 0x97, 0x75, 0xaa, 0x5d, 0xc8, 0x99, 0x1a, 0x30, 0x94, 0xfb, 0x7e, - 0xd7, 0xed, 0x0d, 0xed, 0x8a, 0x9e, 0x6c, 0x11, 0xed, 0xec, 0x41, 0x25, 0x3e, 0x7a, 0x35, 0x99, - 0xda, 0x7d, 0x0c, 0x6d, 0x8d, 0xe6, 0xda, 0xfd, 0x28, 0x6b, 0x73, 0x8b, 0x59, 0x9b, 0x4f, 0x64, - 0xed, 0x4b, 0xa8, 0xa5, 0x92, 0x40, 0x81, 0x28, 0xbf, 0x16, 0x46, 0x11, 0xae, 0x15, 0xaf, 0xc5, - 0x7d, 0xfd, 0x60, 0xac, 0x51, 0x5c, 0x3b, 0xcf, 0xa0, 0x96, 0x3a, 0xfe, 0x65, 0x53, 0xc2, 0x79, - 0x0a, 0xb5, 0x8e, 0x74, 0xe5, 0x64, 0xc5, 0x0b, 0xff, 0xbf, 0x16, 0x6c, 0x44, 0x18, 0xd3, 0x49, - 0x7e, 0x0d, 0xe5, 0x29, 0x0b, 0x25, 0xbb, 0x89, 0x27, 0xa3, 0xdd, 0x1c, 0xf1, 0xee, 0xac, 0x19, - 0xfd, 0xc7, 0xa0, 0x4e, 0xfb, 0x3d, 0x22, 0x68, 0x8c, 0x24, 0xdf, 0x40, 0x59, 0xa0, 0x1e, 0x16, - 0xdd, 0x53, 0x3e, 0xcd, 0x92, 0x32, 0xf6, 0x62, 0x3c, 0xd9, 0x81, 0x82, 0xcf, 0x07, 0x02, 0x4f, - 0xb7, 0xba, 0xfb, 0x71, 0x96, 0xdc, 0x5b, 0x3e, 0xa0, 0x08, 0x24, 0xaf, 0xa1, 0x7c, 0xed, 0x86, - 0x81, 0x17, 0x0c, 0xa2, 0x97, 0xe8, 0x93, 0x2c, 0xa1, 0xef, 0x34, 0x8e, 0xc6, 0x02, 0x4e, 0x4d, - 0x15, 0xc5, 0x25, 0x37, 0x31, 0x71, 0x7e, 0xaf, 0x72, 0x53, 0x91, 0xc6, 0xfd, 0x63, 0xa8, 0xe9, - 0xfc, 0x7e, 0xcf, 0x42, 0xa1, 0x6e, 0x7d, 0xd6, 0xaa, 0x1a, 0xdc, 0x4f, 0x42, 0x69, 0x5a, 0xd2, - 0xf9, 0xde, 0x8c, 0xaf, 0x88, 0xa1, 0xc6, 0xe7, 0xd8, 0xed, 0x0d, 0xdd, 0x41, 0x74, 0x4e, 0x11, - 0xa9, 0xbe, 0x4c, 0x8d, 0x3d, 0x5d, 0x86, 0x11, 0xa9, 0x32, 0x30, 0x64, 0x53, 0x4f, 0xcc, 0x2f, - 0xa0, 0x31, 0xbd, 0xfb, 0xcf, 0x22, 0x40, 0x2b, 0xde, 0x0f, 0x39, 0x87, 0x35, 0xb4, 0x47, 0x9c, - 0x95, 0xc3, 0x10, 0xfd, 0xae, 0x3f, 0xbb, 0xc7, 0xc0, 0x24, 0xef, 0xa0, 0xa8, 0x4f, 0x8b, 0x64, - 0xf5, 0xa0, 0x64, 0x7e, 0xd5, 0x9f, 0xaf, 0x06, 0x69, 0xa5, 0x9f, 0x5b, 0x84, 0x9a, 0x0e, 0x45, - 0x9c, 0x15, 0x23, 0xc8, 0x64, 0x76, 0xd6, 0x46, 0x53, 0xdd, 0xbe, 0x61, 0x91, 0x6f, 0xa1, 0xa8, - 0x7b, 0x0c, 0xf9, 0xd9, 0x72, 0x81, 0x48, 0xdf, 0xea, 0xcf, 0x0d, 0xeb, 0x73, 0x8b, 0x9c, 0x40, - 0x41, 0x0d, 0x57, 0x92, 0x31, 0x29, 0x12, 0x93, 0xb9, 0xee, 0xac, 0x82, 0x98, 0x28, 0x7e, 0x0f, - 0x30, 0x1f, 0xf1, 0x24, 0xe3, 0xdd, 0xbf, 0x70, 0x57, 0xa8, 0x37, 0xee, 0x06, 0x1a, 0x03, 0x27, - 0x6a, 0xbe, 0x5d, 0x72, 0x92, 0x39, 0xd9, 0xe2, 0x74, 0xaf, 0x3b, 0xab, 0x20, 0x46, 0xdd, 0x15, - 0xd4, 0x52, 0x7f, 0xfb, 0x91, 0x5f, 0x66, 0x3b, 0x79, 0xfb, 0x5f, 0xc4, 0xfa, 0x8b, 0x7b, 0x61, - 0x8d, 0x25, 0x99, 0xbc, 0x23, 0x99, 0xcf, 0xa4, 0x79, 0x97, 0xdf, 0xe9, 0xbf, 0xf0, 0xea, 0x3b, - 0xf7, 0xc6, 0x6b, 0xab, 0xfb, 0x85, 0x3f, 0xe4, 0xc6, 0xdd, 0x6e, 0x11, 0xff, 0x0d, 0xfd, 0xf2, - 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x41, 0x5d, 0x93, 0xf2, 0x74, 0x15, 0x00, 0x00, + // 1915 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x72, 0x1b, 0xc7, + 0x11, 0xce, 0x02, 0x20, 0x7e, 0x1a, 0x04, 0x4d, 0x4d, 0x28, 0x65, 0x04, 0x29, 0x16, 0xb5, 0x92, + 0x6d, 0x54, 0x94, 0x02, 0x6d, 0x2a, 0x8e, 0x2c, 0x4b, 0xae, 0x0a, 0x09, 0x12, 0x45, 0x3a, 0x24, + 0xc5, 0x5a, 0x50, 0x72, 0x25, 0xa9, 0x8a, 0x6b, 0x01, 0x0c, 0xc1, 0x2d, 0x2c, 0x76, 0x90, 0x9d, + 0x01, 0x48, 0xe4, 0x94, 0x4b, 0xae, 0x79, 0x8f, 0x54, 0xae, 0xb9, 0xe5, 0x94, 0x53, 0x5e, 0x20, + 0x8f, 0x92, 0x83, 0x8f, 0xa9, 0xe9, 0x99, 0x5d, 0x2c, 0x08, 0x2c, 0x48, 0x26, 0x27, 0x4c, 0xf7, + 0x7e, 0x5f, 0x4f, 0x77, 0x6f, 0x4f, 0x4f, 0x2f, 0x60, 0xbd, 0xc3, 0x03, 0x19, 0x72, 0xdf, 0x67, + 0x61, 0x7d, 0x18, 0x72, 0xc9, 0xc9, 0x46, 0x7b, 0xe4, 0xf9, 0xdd, 0xab, 0x7a, 0xe2, 0xc1, 0xf8, + 0x8b, 0xea, 0x9b, 0x9e, 0x27, 0x2f, 0x46, 0xed, 0x7a, 0x87, 0x0f, 0xb6, 0x06, 0xbc, 0x3d, 0xd9, + 0x42, 0x54, 0xdf, 0x93, 0x5b, 0xee, 0xd0, 0xdb, 0x12, 0x2c, 0x1c, 0x7b, 0x1d, 0x26, 0xb6, 0x0c, + 0x29, 0xfa, 0xd5, 0x26, 0xed, 0x1a, 0x6c, 0x1c, 0x79, 0x42, 0x9e, 0x86, 0xbc, 0xc3, 0x84, 0x60, + 0xc2, 0x61, 0x7f, 0x18, 0x31, 0x21, 0xc9, 0x3a, 0x64, 0x1d, 0x76, 0x4e, 0xad, 0x4d, 0xab, 0x56, + 0x72, 0xd4, 0xd2, 0x3e, 0x85, 0xfb, 0xd7, 0x90, 0x62, 0xc8, 0x03, 0xc1, 0xc8, 0x2b, 0x58, 0x39, + 0x0c, 0xce, 0xb9, 0xa0, 0xd6, 0x66, 0xb6, 0x56, 0xde, 0x7e, 0x5a, 0x5f, 0xe4, 0x65, 0xdd, 0xf0, + 0x14, 0xd2, 0xd1, 0x78, 0x5b, 0x40, 0x39, 0xa1, 0x25, 0x8f, 0xa1, 0x14, 0x89, 0x7b, 0x66, 0xe3, + 0xa9, 0x82, 0x34, 0x61, 0xf5, 0x30, 0x18, 0xf3, 0x3e, 0x6b, 0xf0, 0xe0, 0xdc, 0xeb, 0xd1, 0xcc, + 0xa6, 0x55, 0x2b, 0x6f, 0xdb, 0x8b, 0x37, 0x4b, 0x22, 0x9d, 0x19, 0x9e, 0xfd, 0x2d, 0xd0, 0x3d, + 0x4f, 0x74, 0x78, 0x10, 0xb0, 0x4e, 0x14, 0x4c, 0x6a, 0xd0, 0xb3, 0x3e, 0x65, 0xae, 0xf9, 0x64, + 0x3f, 0x82, 0x87, 0x0b, 0x6c, 0xe9, 0xb4, 0xd8, 0xbf, 0x87, 0xd5, 0x5d, 0xe5, 0x5b, 0xba, 0xf1, + 0xb7, 0x50, 0x78, 0x37, 0x94, 0x1e, 0x0f, 0xc4, 0xf2, 0x68, 0xd0, 0x8c, 0x41, 0x3a, 0x11, 0xc5, + 0xfe, 0x01, 0xcc, 0x06, 0x46, 0x41, 0x36, 0xa1, 0xdc, 0xe0, 0x81, 0x64, 0x57, 0xf2, 0xd4, 0x95, + 0x17, 0x66, 0xa3, 0xa4, 0x8a, 0x7c, 0x0a, 0x6b, 0x7b, 0xbc, 0xd3, 0x67, 0xe1, 0xb9, 0xe7, 0xb3, + 0x13, 0x77, 0xc0, 0x4c, 0x48, 0xd7, 0xb4, 0x3a, 0x6a, 0x2f, 0x90, 0xcd, 0x51, 0xd0, 0xa1, 0xd9, + 0x28, 0x6a, 0xa3, 0x20, 0xbf, 0x83, 0x8a, 0x42, 0x75, 0x8d, 0x65, 0x41, 0x73, 0xf8, 0xde, 0xbf, + 0xbc, 0xd9, 0xf9, 0xfa, 0x0c, 0x6f, 0x3f, 0x90, 0xe1, 0xc4, 0x99, 0xb5, 0x45, 0x36, 0x60, 0x65, + 0xc7, 0xf7, 0xf9, 0x25, 0x5d, 0xd9, 0xcc, 0xd6, 0x4a, 0x8e, 0x16, 0xc8, 0x2f, 0xa1, 0xb0, 0x23, + 0x25, 0x13, 0x52, 0xd0, 0x3c, 0x6e, 0xf6, 0x78, 0xf1, 0x66, 0x1a, 0xe4, 0x44, 0x60, 0xf2, 0x0e, + 0x4a, 0xb8, 0xff, 0x4e, 0xd8, 0x13, 0xb4, 0x80, 0xcc, 0x2f, 0x6e, 0xe1, 0x66, 0xcc, 0xd1, 0x2e, + 0x4e, 0x6d, 0x90, 0x7d, 0x28, 0x35, 0xdc, 0xce, 0x05, 0x6b, 0x86, 0x7c, 0x40, 0x8b, 0x68, 0xf0, + 0xb3, 0xc5, 0x06, 0x11, 0x66, 0x0c, 0x1a, 0x33, 0x31, 0x93, 0xec, 0x40, 0x01, 0x85, 0x33, 0x4e, + 0x4b, 0x77, 0x33, 0x12, 0xf1, 0x88, 0x0d, 0xab, 0x8d, 0x5e, 0xc8, 0x47, 0xc3, 0x53, 0x37, 0x64, + 0x81, 0xa4, 0x80, 0xaf, 0x69, 0x46, 0x47, 0xde, 0x40, 0x61, 0xff, 0x6a, 0xc8, 0x43, 0x29, 0x68, + 0x79, 0xd9, 0xd9, 0xd4, 0x20, 0xb3, 0x81, 0x61, 0x90, 0x8f, 0x01, 0xf6, 0xaf, 0x64, 0xe8, 0x1e, + 0x70, 0x95, 0xf6, 0x55, 0x7c, 0x1d, 0x09, 0x0d, 0x69, 0x42, 0xfe, 0xc8, 0x6d, 0x33, 0x5f, 0xd0, + 0x0a, 0xda, 0xae, 0xdf, 0x22, 0xb1, 0x9a, 0xa0, 0x37, 0x32, 0x6c, 0x55, 0xb6, 0x27, 0x4c, 0x5e, + 0xf2, 0xb0, 0x7f, 0xcc, 0xbb, 0x8c, 0xae, 0xe9, 0xb2, 0x4d, 0xa8, 0xc8, 0x73, 0xa8, 0x9c, 0x70, + 0x9d, 0x3c, 0xcf, 0x97, 0x2c, 0xa4, 0x1f, 0xa1, 0x33, 0xb3, 0x4a, 0x2c, 0x5a, 0xdf, 0x95, 0xe7, + 0x3c, 0x1c, 0x08, 0xba, 0x8e, 0x88, 0xa9, 0x42, 0x55, 0x50, 0x8b, 0x75, 0x42, 0x26, 0x05, 0xbd, + 0xb7, 0xac, 0x82, 0x34, 0xc8, 0x89, 0xc0, 0x84, 0x42, 0xa1, 0x75, 0x31, 0x68, 0x79, 0x7f, 0x64, + 0x94, 0x6c, 0x5a, 0xb5, 0xac, 0x13, 0x89, 0xe4, 0x05, 0x64, 0x5b, 0xad, 0x03, 0xfa, 0x63, 0xb4, + 0xf6, 0x30, 0xc5, 0x5a, 0xeb, 0xc0, 0x51, 0x28, 0x42, 0x20, 0x77, 0xe6, 0xf6, 0x04, 0xdd, 0x40, + 0xbf, 0x70, 0x4d, 0x1e, 0x40, 0xfe, 0xcc, 0x0d, 0x7b, 0x4c, 0xd2, 0xfb, 0x18, 0xb3, 0x91, 0xc8, + 0x6b, 0x28, 0xbc, 0xf7, 0xbd, 0x81, 0x27, 0x05, 0x7d, 0x80, 0x6d, 0xe1, 0xc9, 0x62, 0xe3, 0x1a, + 0xf4, 0x6e, 0x28, 0x9d, 0x08, 0xaf, 0xbc, 0xc5, 0x7c, 0xb3, 0x90, 0xfe, 0x04, 0x6d, 0x46, 0xa2, + 0x2a, 0x97, 0x63, 0x26, 0xdd, 0xae, 0x2b, 0xdd, 0xa6, 0xe7, 0x33, 0x4a, 0x75, 0xb9, 0x24, 0x75, + 0x8a, 0x6d, 0x52, 0x4a, 0x1f, 0x6e, 0x5a, 0xb5, 0xa2, 0x13, 0x89, 0xca, 0xfd, 0xd3, 0x91, 0xef, + 0xd3, 0x2a, 0xaa, 0x71, 0xad, 0xeb, 0x43, 0x95, 0xca, 0xe9, 0x48, 0x5c, 0xd0, 0x47, 0xf8, 0x24, + 0xa1, 0x99, 0x3e, 0x3f, 0xe2, 0x6e, 0x97, 0x3e, 0x4e, 0x3e, 0x57, 0x9a, 0xea, 0xaf, 0x80, 0xcc, + 0xb7, 0x03, 0xd5, 0x25, 0xfb, 0x6c, 0x12, 0x75, 0xc9, 0x3e, 0x9b, 0xa8, 0x8e, 0x30, 0x76, 0xfd, + 0x51, 0xd4, 0xab, 0xb4, 0xf0, 0x75, 0xe6, 0x2b, 0xab, 0xfa, 0x16, 0xd6, 0x66, 0x4f, 0xea, 0x9d, + 0xd8, 0xaf, 0xa1, 0x9c, 0x28, 0xc7, 0xbb, 0x50, 0xed, 0x7f, 0x5a, 0x50, 0x4e, 0x9c, 0x19, 0x7c, + 0xbb, 0x93, 0x21, 0x33, 0x64, 0x5c, 0x93, 0x5d, 0x58, 0xd9, 0x91, 0x32, 0x54, 0xad, 0x5d, 0x15, + 0xc8, 0xcf, 0x6f, 0x3c, 0x79, 0x75, 0x84, 0xeb, 0xb3, 0xa1, 0xa9, 0xea, 0x68, 0xec, 0x31, 0x21, + 0xbd, 0xc0, 0x55, 0xc7, 0xc7, 0x74, 0xe2, 0xa4, 0xaa, 0xfa, 0x15, 0xc0, 0x94, 0x76, 0xa7, 0x18, + 0xfe, 0x66, 0xc1, 0xbd, 0xb9, 0xf6, 0xb2, 0x30, 0x92, 0x83, 0xd9, 0x48, 0xb6, 0x6f, 0xd9, 0xaa, + 0xe6, 0xe3, 0xf9, 0x3f, 0xbc, 0x3d, 0x81, 0xbc, 0xee, 0xe9, 0x0b, 0x3d, 0xac, 0x42, 0x71, 0xcf, + 0x13, 0x6e, 0xdb, 0x67, 0x5d, 0xa4, 0x16, 0x9d, 0x58, 0xc6, 0x0b, 0x05, 0xbd, 0xd7, 0xd9, 0xd3, + 0x82, 0xad, 0x0f, 0x2f, 0x59, 0x83, 0x4c, 0x3c, 0x6b, 0x64, 0x0e, 0xf7, 0x14, 0x58, 0x5d, 0x94, + 0x3a, 0xd4, 0x92, 0xa3, 0x05, 0xbb, 0x09, 0x79, 0xdd, 0x0e, 0xe6, 0xf0, 0x55, 0x28, 0xaa, 0x93, + 0x83, 0xf7, 0xad, 0xf6, 0x39, 0x96, 0x55, 0x78, 0xfb, 0xc1, 0xd8, 0x6c, 0xab, 0x96, 0xf6, 0x5f, + 0x2d, 0x28, 0xc5, 0x87, 0x96, 0x34, 0x20, 0x8f, 0xf1, 0x45, 0x73, 0xd3, 0x8b, 0x1b, 0x4e, 0x79, + 0xfd, 0x03, 0xa2, 0x4d, 0xf3, 0xd4, 0xd4, 0xea, 0x77, 0x50, 0x4e, 0xa8, 0x17, 0xa4, 0x74, 0x3b, + 0x99, 0xd2, 0xd4, 0xae, 0xa7, 0x37, 0x49, 0x26, 0x7c, 0x0f, 0xf2, 0x5a, 0xa9, 0x12, 0x8e, 0xa3, + 0x82, 0x49, 0x38, 0x0e, 0x08, 0x04, 0x72, 0x07, 0x6e, 0xa8, 0x93, 0x9d, 0x75, 0x70, 0xad, 0x74, + 0x2d, 0x7e, 0x2e, 0x31, 0xe0, 0xac, 0x83, 0x6b, 0xfb, 0x1f, 0x16, 0x54, 0xcc, 0x10, 0x64, 0x86, + 0x45, 0x06, 0xeb, 0xba, 0xe6, 0x59, 0x18, 0xe9, 0x4c, 0xfc, 0xaf, 0x97, 0xdc, 0x1f, 0x11, 0xb4, + 0x7e, 0x9d, 0xab, 0xb3, 0x31, 0x67, 0xb2, 0xda, 0x80, 0xfb, 0x0b, 0xa1, 0x77, 0x2a, 0xba, 0x4f, + 0xe0, 0xde, 0x74, 0xbc, 0x4b, 0x1f, 0x8c, 0x37, 0x80, 0x24, 0x61, 0x66, 0xfc, 0x7b, 0x02, 0x65, + 0x35, 0x2e, 0xa7, 0xd3, 0x6c, 0x58, 0xd5, 0x00, 0x93, 0x19, 0x02, 0xb9, 0x3e, 0x9b, 0xe8, 0x6a, + 0x28, 0x39, 0xb8, 0xb6, 0xff, 0x62, 0xa9, 0xa9, 0x77, 0x38, 0x92, 0xc7, 0x4c, 0x08, 0xb7, 0xc7, + 0xc8, 0x5b, 0xc8, 0x1d, 0x06, 0x9e, 0x44, 0x3b, 0xe5, 0xed, 0x4f, 0xd3, 0xa6, 0xdf, 0xe1, 0x48, + 0x2a, 0x98, 0x61, 0x1d, 0xfc, 0xc8, 0x41, 0x16, 0x79, 0x05, 0xb9, 0x3d, 0x57, 0xba, 0xa6, 0x16, + 0x52, 0x86, 0x01, 0x85, 0x48, 0x10, 0x95, 0xb8, 0x5b, 0x50, 0x23, 0xfe, 0x70, 0x24, 0xed, 0xe7, + 0xb0, 0x7e, 0xdd, 0xfa, 0x82, 0xd0, 0x5e, 0x42, 0x39, 0x61, 0x05, 0x4f, 0xc2, 0xbb, 0x26, 0x02, + 0x8a, 0x8e, 0x5a, 0xaa, 0x58, 0x63, 0x47, 0x56, 0xf5, 0x1e, 0xf6, 0x47, 0x50, 0x41, 0xd3, 0x71, + 0x06, 0xff, 0x94, 0x81, 0x42, 0x64, 0xe2, 0xd5, 0x4c, 0xdc, 0x4f, 0xd3, 0xe2, 0x9e, 0x0f, 0xf9, + 0x4b, 0xc8, 0xe1, 0x7d, 0x97, 0x59, 0x76, 0x93, 0x36, 0xbb, 0x09, 0x1a, 0x5e, 0x85, 0xdf, 0x40, + 0xde, 0x61, 0x42, 0xdd, 0xfa, 0x59, 0x24, 0x3e, 0x5b, 0x4c, 0xd4, 0x98, 0x29, 0xd9, 0x90, 0x14, + 0xbd, 0xe5, 0xf5, 0x02, 0xd7, 0xa7, 0xb9, 0x65, 0x74, 0x8d, 0x49, 0xd0, 0xb5, 0x62, 0x9a, 0xee, + 0x3f, 0x5b, 0x50, 0x5e, 0x9a, 0xea, 0xe5, 0x1f, 0x28, 0x73, 0x1f, 0x4d, 0xd9, 0xff, 0xf1, 0xa3, + 0xe9, 0xdf, 0xd6, 0xac, 0x21, 0xbc, 0xdc, 0xd5, 0x79, 0x1a, 0x72, 0x2f, 0x90, 0xa6, 0x64, 0x13, + 0x1a, 0xe5, 0x68, 0x63, 0xd0, 0x35, 0x6d, 0x54, 0x2d, 0xa7, 0xed, 0x30, 0x6b, 0xda, 0xa1, 0x2a, + 0x82, 0xf7, 0x82, 0x85, 0x98, 0xa2, 0x92, 0x83, 0x6b, 0x35, 0x13, 0x9d, 0x70, 0xd4, 0xae, 0x60, + 0xb5, 0x18, 0x09, 0xed, 0x5d, 0x76, 0x69, 0x5e, 0x07, 0xde, 0xb8, 0xc4, 0xbe, 0x7e, 0xc2, 0x95, + 0xae, 0x80, 0x40, 0x2d, 0x28, 0xdc, 0x99, 0x9c, 0xd0, 0xa2, 0x2e, 0xb5, 0x33, 0x39, 0x51, 0x2d, + 0xda, 0xe1, 0xbe, 0xdf, 0x76, 0x3b, 0x7d, 0x5a, 0xd2, 0x77, 0x43, 0x24, 0xdb, 0x3b, 0x50, 0x8a, + 0x5f, 0xbd, 0xea, 0xed, 0xcd, 0x2e, 0xa6, 0xb6, 0xe2, 0x64, 0x9a, 0xdd, 0xa8, 0x6a, 0x33, 0xf3, + 0x55, 0x9b, 0x4d, 0x54, 0xed, 0x2b, 0xa8, 0xcc, 0x14, 0x81, 0x02, 0x39, 0xfc, 0x52, 0x18, 0x43, + 0xb8, 0x56, 0xba, 0x06, 0xf7, 0xf5, 0x57, 0x5e, 0xc5, 0xc1, 0xb5, 0xfd, 0x0c, 0x2a, 0x33, 0xaf, + 0x7f, 0x51, 0x9f, 0xb5, 0x9f, 0x42, 0xa5, 0x25, 0x5d, 0x39, 0x5a, 0xf2, 0x59, 0xfe, 0x83, 0x05, + 0x6b, 0x11, 0xc6, 0x74, 0x92, 0x23, 0x28, 0xb7, 0xb8, 0x3f, 0x66, 0x5a, 0x6d, 0xce, 0x4c, 0x2d, + 0xa5, 0x04, 0xa7, 0xc0, 0x69, 0x1d, 0x26, 0xe9, 0xa4, 0x01, 0xc5, 0x13, 0xde, 0x65, 0xea, 0x13, + 0xdd, 0x9c, 0xa2, 0x4f, 0x16, 0x9b, 0x8a, 0x50, 0x53, 0x3b, 0x31, 0x91, 0x1c, 0x02, 0x38, 0x4c, + 0x8c, 0x7c, 0x89, 0x66, 0x74, 0x19, 0x7e, 0x96, 0x7a, 0xa6, 0x0c, 0x6e, 0x6a, 0x28, 0x41, 0xde, + 0x2d, 0x42, 0x5e, 0x7b, 0x66, 0xff, 0xc7, 0x02, 0x32, 0xef, 0x3f, 0xf9, 0x05, 0x14, 0xc7, 0x2c, + 0x94, 0xec, 0x2a, 0xbe, 0x5a, 0x69, 0x7d, 0xc0, 0xdb, 0x93, 0x7a, 0xf4, 0xbf, 0x88, 0xda, 0xe5, + 0x03, 0x22, 0x9c, 0x18, 0x49, 0xbe, 0x86, 0xa2, 0x40, 0x33, 0x2c, 0x1a, 0x74, 0x3e, 0x4e, 0x63, + 0x99, 0x74, 0xc7, 0x78, 0xb2, 0x05, 0x39, 0x9f, 0xf7, 0x04, 0x16, 0x77, 0x79, 0xfb, 0x51, 0x1a, + 0xef, 0x88, 0xf7, 0x1c, 0x04, 0x92, 0x37, 0x50, 0xbc, 0x74, 0xc3, 0xc0, 0x0b, 0x7a, 0xd1, 0xd7, + 0xf3, 0x93, 0x34, 0xd2, 0x77, 0x1a, 0xe7, 0xc4, 0x04, 0xfb, 0x1b, 0xf8, 0xe8, 0x5a, 0xaa, 0x17, + 0xde, 0xd1, 0x0f, 0x20, 0xbf, 0x17, 0x7a, 0x63, 0x16, 0x9a, 0xb6, 0x60, 0x24, 0xfb, 0x5f, 0x16, + 0xdc, 0x9b, 0xcb, 0x31, 0xf9, 0x35, 0x36, 0xbc, 0x91, 0x2f, 0x4d, 0xca, 0x5e, 0xde, 0xf2, 0xe5, + 0x18, 0x8d, 0x99, 0x4a, 0xb4, 0x10, 0xbb, 0x93, 0x99, 0x75, 0xa7, 0xc9, 0xc3, 0x81, 0x2b, 0xcd, + 0x44, 0x64, 0x24, 0x35, 0x86, 0x27, 0x4c, 0xdc, 0xe9, 0x7e, 0xae, 0xa8, 0xe6, 0x78, 0xce, 0xcd, + 0xd9, 0xb0, 0x7f, 0xa3, 0x7a, 0x94, 0x12, 0xcd, 0x31, 0x38, 0x84, 0x8a, 0x8e, 0xe1, 0x03, 0x0b, + 0x85, 0x9a, 0x9f, 0xad, 0x65, 0xbd, 0x78, 0x37, 0x09, 0x75, 0x66, 0x99, 0xf6, 0xf7, 0x66, 0x8c, + 0x89, 0x14, 0xea, 0x53, 0x69, 0xe8, 0x76, 0xfa, 0x6e, 0x2f, 0xca, 0x79, 0x24, 0xaa, 0x27, 0x63, + 0xb3, 0x9f, 0x76, 0x38, 0x12, 0x55, 0x27, 0x0a, 0xd9, 0xd8, 0x13, 0xd3, 0x51, 0x3e, 0x96, 0xb7, + 0xff, 0x9e, 0x07, 0x68, 0xc4, 0xfe, 0x90, 0x53, 0x58, 0xc1, 0xfd, 0x88, 0xbd, 0x74, 0x28, 0xc2, + 0xb8, 0xab, 0xcf, 0x6e, 0x31, 0x38, 0x91, 0xf7, 0xd1, 0xa9, 0x21, 0x69, 0x77, 0x51, 0xb2, 0xcf, + 0x54, 0x9f, 0x2f, 0x07, 0x69, 0xa3, 0x9f, 0x5b, 0xc4, 0x31, 0x37, 0x15, 0xb1, 0x97, 0x8c, 0x22, + 0xa6, 0x54, 0xd2, 0x1c, 0x9d, 0xb9, 0xf5, 0x6b, 0x16, 0xf9, 0x16, 0xf2, 0xfa, 0xae, 0x21, 0x3f, + 0x5d, 0x4c, 0x88, 0xec, 0x2d, 0x7f, 0x5c, 0xb3, 0x3e, 0xb7, 0xc8, 0x31, 0xe4, 0xd4, 0x90, 0x45, + 0x52, 0x26, 0x86, 0xc4, 0x84, 0x56, 0xb5, 0x97, 0x41, 0x4c, 0x16, 0xbf, 0x07, 0x98, 0x8e, 0x7a, + 0x24, 0xa5, 0x81, 0xcd, 0xcd, 0x8c, 0xd5, 0xda, 0xcd, 0x40, 0xb3, 0xc1, 0xb1, 0x9a, 0x73, 0xce, + 0x39, 0x49, 0x9d, 0x70, 0xe2, 0x72, 0xaf, 0xda, 0xcb, 0x20, 0xc6, 0xdc, 0x05, 0x54, 0x66, 0xfe, + 0xb3, 0x25, 0x3f, 0x4b, 0x0f, 0xf2, 0xfa, 0x5f, 0xc0, 0xd5, 0x17, 0xb7, 0xc2, 0x9a, 0x9d, 0x64, + 0x72, 0x56, 0x36, 0x8f, 0x49, 0xfd, 0xa6, 0xb8, 0x67, 0xff, 0x7f, 0xad, 0x6e, 0xdd, 0x1a, 0xaf, + 0x77, 0xdd, 0xcd, 0xfd, 0x36, 0x33, 0x6c, 0xb7, 0xf3, 0xf8, 0x57, 0xf6, 0xcb, 0xff, 0x06, 0x00, + 0x00, 0xff, 0xff, 0x62, 0xe5, 0x06, 0x57, 0x31, 0x17, 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 944bbc26..35a1be98 100644 --- a/controller/pb/controller.proto +++ b/controller/pb/controller.proto @@ -69,7 +69,12 @@ message BuildOptions { string Target = 21; UlimitOpt Ulimits = 22; - CommonOptions Opts = 24; + string Builder = 23; + string MetadataFile = 24; + bool NoCache = 25; + bool Pull = 26; + bool ExportPush = 27; + bool ExportLoad = 28; } message ExportEntry { @@ -110,16 +115,6 @@ message Ulimit { int64 Soft = 3; } -message CommonOptions { - string Builder = 1; - string MetadataFile = 2; - bool NoCache = 3; - // string Progress: no progress view on server side - bool Pull = 4; - bool ExportPush = 5; - bool ExportLoad = 6; -} - message BuildResponse { map ExporterResponse = 1; } @@ -214,12 +209,31 @@ message StatusRequest { } message StatusResponse { + oneof Status { + SolveStatusMessage SolveStatus = 1; + NodeInfoMessage NodeInfo = 2; + ResultInfoMessage ResultInfo = 3; + } +} + +message SolveStatusMessage { repeated moby.buildkit.v1.Vertex vertexes = 1; repeated moby.buildkit.v1.VertexStatus statuses = 2; repeated moby.buildkit.v1.VertexLog logs = 3; repeated moby.buildkit.v1.VertexWarning warnings = 4; } +message NodeInfoMessage { + string Name = 1; + string Driver = 2; +} + +message ResultInfoMessage { + map Result = 1; + string Name = 2; + string Format = 3; +} + message InfoRequest {} message InfoResponse { diff --git a/controller/remote/client.go b/controller/remote/client.go index 9eeab3f1..c2bd413b 100644 --- a/controller/remote/client.go +++ b/controller/remote/client.go @@ -6,11 +6,9 @@ import ( "sync" "time" - "github.com/containerd/console" "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/pkg/dialer" "github.com/docker/buildx/controller/pb" - "github.com/docker/buildx/util/progress" "github.com/moby/buildkit/client" "github.com/moby/buildkit/identity" "github.com/pkg/errors" @@ -104,38 +102,13 @@ func (c *Client) Invoke(ctx context.Context, ref string, pid string, invokeConfi }) } -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) { +func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, statusChan chan *pb.StatusResponse) (string, *client.SolveResponse, error) { ref := identity.NewID() - pw, err := progress.NewPrinter(context.TODO(), w, out, progressMode) - if err != nil { - 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) - var err error - resp, err = c.build(egCtx, ref, options, in, statusChan) - return err - }) - eg.Go(func() error { - defer close(statusDone) - for s := range statusChan { - st := s - pw.Write(st) - } - return nil - }) - eg.Go(func() error { - <-statusDone - return pw.Wait() - }) - return ref, resp, eg.Wait() + resp, err := c.build(ctx, ref, options, in, statusChan) + return ref, resp, err } -func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, statusChan chan *client.SolveStatus) (*client.SolveResponse, error) { +func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, statusChan chan *pb.StatusResponse) (*client.SolveResponse, error) { eg, egCtx := errgroup.WithContext(ctx) done := make(chan struct{}) @@ -170,51 +143,7 @@ func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, } return errors.Wrap(err, "failed to receive status") } - s := client.SolveStatus{} - for _, v := range resp.Vertexes { - s.Vertexes = append(s.Vertexes, &client.Vertex{ - Digest: v.Digest, - Inputs: v.Inputs, - Name: v.Name, - Started: v.Started, - Completed: v.Completed, - Error: v.Error, - Cached: v.Cached, - ProgressGroup: v.ProgressGroup, - }) - } - for _, v := range resp.Statuses { - s.Statuses = append(s.Statuses, &client.VertexStatus{ - ID: v.ID, - Vertex: v.Vertex, - Name: v.Name, - Total: v.Total, - Current: v.Current, - Timestamp: v.Timestamp, - Started: v.Started, - Completed: v.Completed, - }) - } - for _, v := range resp.Logs { - s.Logs = append(s.Logs, &client.VertexLog{ - Vertex: v.Vertex, - Stream: int(v.Stream), - Data: v.Msg, - Timestamp: v.Timestamp, - }) - } - for _, v := range resp.Warnings { - s.Warnings = append(s.Warnings, &client.VertexWarning{ - Vertex: v.Vertex, - Level: int(v.Level), - Short: v.Short, - Detail: v.Detail, - URL: v.Url, - SourceInfo: v.Info, - Range: v.Ranges, - }) - } - statusChan <- &s + statusChan <- resp } }) if in != nil { diff --git a/controller/remote/controller.go b/controller/remote/controller.go index 81e69820..ed154599 100644 --- a/controller/remote/controller.go +++ b/controller/remote/controller.go @@ -141,8 +141,8 @@ 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) (*client.SolveResponse, *build.ResultContext, error) { - return cbuild.RunBuild(ctx, dockerCli, *options, stdin, "quiet", statusChan) + b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, statusChan chan *controllerapi.StatusResponse) (*client.SolveResponse, *build.ResultContext, error) { + return cbuild.RunBuild(ctx, dockerCli, *options, stdin, control.ForwardProgress(statusChan)) }) defer b.Close() diff --git a/controller/remote/server.go b/controller/remote/server.go index ae387755..835e7ec8 100644 --- a/controller/remote/server.go +++ b/controller/remote/server.go @@ -12,13 +12,12 @@ import ( "github.com/docker/buildx/controller/processes" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/version" - controlapi "github.com/moby/buildkit/api/services/control" "github.com/moby/buildkit/client" "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) -type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, statusChan chan *client.SolveStatus) (resp *client.SolveResponse, res *build.ResultContext, err error) +type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, statusChan chan *pb.StatusResponse) (resp *client.SolveResponse, res *build.ResultContext, err error) func NewServer(buildFunc BuildFunc) *Server { return &Server{ @@ -34,7 +33,7 @@ type Server struct { type session struct { buildOnGoing atomic.Bool - statusChan chan *client.SolveStatus + statusChan chan *pb.StatusResponse cancelBuild func() inputPipe *io.PipeWriter @@ -156,7 +155,7 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp s.buildOnGoing.Store(true) } s.processes = processes.NewManager() - statusChan := make(chan *client.SolveStatus) + statusChan := make(chan *pb.StatusResponse) s.statusChan = statusChan inR, inW := io.Pipe() defer inR.Close() @@ -204,7 +203,7 @@ func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer } // Wait and get status channel prepared by Build() - var statusChan <-chan *client.SolveStatus + var statusChan <-chan *pb.StatusResponse for { // TODO: timeout? m.sessionMu.Lock() @@ -223,7 +222,7 @@ func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer if ss == nil { break } - cs := toControlStatus(ss) + cs := ss if err := stream.Send(cs); err != nil { return err } @@ -404,51 +403,3 @@ func (m *Server) Invoke(srv pb.Controller_InvokeServer) error { return eg.Wait() } - -func toControlStatus(s *client.SolveStatus) *pb.StatusResponse { - resp := pb.StatusResponse{} - for _, v := range s.Vertexes { - resp.Vertexes = append(resp.Vertexes, &controlapi.Vertex{ - Digest: v.Digest, - Inputs: v.Inputs, - Name: v.Name, - Started: v.Started, - Completed: v.Completed, - Error: v.Error, - Cached: v.Cached, - ProgressGroup: v.ProgressGroup, - }) - } - for _, v := range s.Statuses { - resp.Statuses = append(resp.Statuses, &controlapi.VertexStatus{ - ID: v.ID, - Vertex: v.Vertex, - Name: v.Name, - Total: v.Total, - Current: v.Current, - Timestamp: v.Timestamp, - Started: v.Started, - Completed: v.Completed, - }) - } - for _, v := range s.Logs { - resp.Logs = append(resp.Logs, &controlapi.VertexLog{ - Vertex: v.Vertex, - Stream: int64(v.Stream), - Msg: v.Data, - Timestamp: v.Timestamp, - }) - } - for _, v := range s.Warnings { - resp.Warnings = append(resp.Warnings, &controlapi.VertexWarning{ - Vertex: v.Vertex, - Level: int64(v.Level), - Short: v.Short, - Detail: v.Detail, - Url: v.URL, - Info: v.SourceInfo, - Ranges: v.Range, - }) - } - return &resp -} diff --git a/monitor/monitor.go b/monitor/monitor.go index ca7dfc9b..ef851446 100644 --- a/monitor/monitor.go +++ b/monitor/monitor.go @@ -125,7 +125,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 := control.Build(ctx, c, options, nil, stdout, stderr, progressMode) // TODO: support stdin if needed if err != nil { fmt.Printf("failed to reload: %v\n", err) } else { diff --git a/util/progress/writer.go b/util/progress/writer.go index 7cc63f6a..b5da6de5 100644 --- a/util/progress/writer.go +++ b/util/progress/writer.go @@ -69,23 +69,18 @@ func NewChannel(w Writer) (chan *client.SolveStatus, chan struct{}) { return ch, done } -type tee struct { - Writer - ch chan *client.SolveStatus -} - -func (t *tee) Write(v *client.SolveStatus) { - v2 := *v - t.ch <- &v2 - t.Writer.Write(v) -} - -func Tee(w Writer, ch chan *client.SolveStatus) Writer { - if ch == nil { - return w - } - return &tee{ - Writer: w, - ch: ch, - } +func Tee(w *Printer, ch chan *client.SolveStatus) *Printer { + wStatus := make(chan *client.SolveStatus) + orgStatus := w.status + w.status = wStatus + go func() { + defer close(orgStatus) + for st := range wStatus { + st := st + st2 := *st + ch <- &st2 + orgStatus <- st + } + }() + return w }