From 1fd23933c2024b1e2abc4e74fbb8372f4cd60a30 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 3 Apr 2023 13:04:28 +0100 Subject: [PATCH 1/4] controller: refactor progress api Refactor the progress printer creation to the caller-side of the controller api. Then, instead of passing around status channels, we can simply pass around the higher level interface progress.Writer, which allows us to correctly pull warnings out of the remote controller. Signed-off-by: Justin Chadwell --- commands/build.go | 93 +++++++++++++++++++++-- commands/debug-shell.go | 13 +++- controller/build/build.go | 75 ++----------------- controller/control/controller.go | 4 +- controller/local/controller.go | 6 +- controller/pb/progress.go | 122 +++++++++++++++++++++++++++++++ controller/remote/client.go | 61 +--------------- controller/remote/controller.go | 5 +- controller/remote/server.go | 66 +++-------------- monitor/monitor.go | 5 +- 10 files changed, 251 insertions(+), 199 deletions(-) create mode 100644 controller/pb/progress.go diff --git a/commands/build.go b/commands/build.go index 0822128878b9..12f34a072521 100644 --- a/commands/build.go +++ b/commands/build.go @@ -1,6 +1,7 @@ package commands import ( + "bytes" "context" "encoding/base64" "encoding/csv" @@ -15,6 +16,7 @@ import ( "github.com/containerd/console" "github.com/docker/buildx/build" + "github.com/docker/buildx/builder" "github.com/docker/buildx/controller" cbuild "github.com/docker/buildx/controller/build" "github.com/docker/buildx/controller/control" @@ -35,8 +37,11 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/moby/buildkit/client" "github.com/moby/buildkit/exporter/containerimage/exptypes" + "github.com/moby/buildkit/solver/errdefs" "github.com/moby/buildkit/util/appcontext" "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" "github.com/spf13/cobra" @@ -200,7 +205,22 @@ 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 + } + b, err := builder.New(dockerCli, + builder.WithName(opts.Builder), + builder.WithContextPathHash(opts.ContextPath), + ) + if err != nil { + return err + } + printer, err := progress.NewPrinter(context.TODO(), os.Stderr, os.Stderr, progressMode, progressui.WithDesc( + fmt.Sprintf("building with %q instance using %s driver", b.Name, b.Driver), + fmt.Sprintf("%s:%s", b.Driver, b.Name), + )) if err != nil { return err } @@ -211,10 +231,14 @@ 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, false) + resp, _, err := cbuild.RunBuild(ctx, dockerCli, opts, os.Stdin, printer, false) + if err1 := printer.Wait(); err == nil { + err = err1 + } if err != nil { return err } + printWarnings(os.Stderr, printer.Warnings(), progressMode) if in.quiet { fmt.Println(resp.ExporterResponse[exptypes.ExporterImageDigestKey]) } @@ -517,7 +541,22 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er if err != nil { return err } - progress, err := options.toProgress() + + progressMode, err := options.toProgress() + if err != nil { + return err + } + b, err := builder.New(dockerCli, + builder.WithName(opts.Builder), + builder.WithContextPathHash(opts.ContextPath), + ) + if err != nil { + return err + } + printer, err := progress.NewPrinter(context.TODO(), os.Stderr, os.Stderr, progressMode, progressui.WithDesc( + fmt.Sprintf("building with %q instance using %s driver", b.Name, b.Driver), + fmt.Sprintf("%s:%s", b.Driver, b.Name), + )) if err != nil { return err } @@ -550,7 +589,10 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er } var resp *client.SolveResponse - ref, resp, err = c.Build(ctx, opts, pr, os.Stdout, os.Stderr, progress) + ref, resp, err = c.Build(ctx, opts, pr, printer) + if err1 := printer.Wait(); err == nil { + err = err1 + } if err != nil { var be *controllererrors.BuildError if errors.As(err, &be) { @@ -561,6 +603,7 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er return errors.Wrapf(err, "failed to build") } } + printWarnings(os.Stderr, printer.Warnings(), progressMode) if err := pw.Close(); err != nil { logrus.Debug("failed to close stdin pipe writer") } @@ -595,7 +638,7 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er } return errors.Errorf("failed to configure terminal: %v", err) } - err = monitor.RunMonitor(ctx, ref, &opts, options.invoke.InvokeConfig, c, progress, pr2, os.Stdout, os.Stderr) + err = monitor.RunMonitor(ctx, ref, &opts, options.invoke.InvokeConfig, c, pr2, os.Stdout, os.Stderr, printer) con.Reset() if err := pw2.Close(); err != nil { logrus.Debug("failed to close monitor stdin pipe reader") @@ -881,3 +924,43 @@ func resolvePaths(options *controllerapi.BuildOptions) (_ *controllerapi.BuildOp return options, nil } + +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/commands/debug-shell.go b/commands/debug-shell.go index 29f9d38f187a..1a9cc6acbfe8 100644 --- a/commands/debug-shell.go +++ b/commands/debug-shell.go @@ -10,6 +10,7 @@ import ( "github.com/docker/buildx/controller/control" controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/monitor" + "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -18,7 +19,7 @@ import ( func debugShellCmd(dockerCli command.Cli) *cobra.Command { var options control.ControlOptions - var progress string + var progressMode string cmd := &cobra.Command{ Use: "debug-shell", @@ -38,9 +39,15 @@ func debugShellCmd(dockerCli command.Cli) *cobra.Command { if err := con.SetRaw(); err != nil { return errors.Errorf("failed to configure terminal: %v", err) } + + printer, err := progress.NewPrinter(context.TODO(), os.Stderr, os.Stderr, progressMode) + if err != nil { + return err + } + err = monitor.RunMonitor(ctx, "", nil, controllerapi.InvokeConfig{ Tty: true, - }, c, progress, os.Stdin, os.Stdout, os.Stderr) + }, c, os.Stdin, os.Stdout, os.Stderr, printer) con.Reset() return err }, @@ -51,7 +58,7 @@ func debugShellCmd(dockerCli command.Cli) *cobra.Command { flags.StringVar(&options.Root, "root", "", "Specify root directory of server to connect [experimental]") flags.BoolVar(&options.Detach, "detach", runtime.GOOS == "linux", "Detach buildx server (supported only on linux) [experimental]") flags.StringVar(&options.ServerConfig, "server-config", "", "Specify buildx server config file (used only when launching new server) [experimental]") - flags.StringVar(&progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`) + flags.StringVar(&progressMode, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`) return cmd } diff --git a/controller/build/build.go b/controller/build/build.go index 86a3c0167c9b..c519fa990c06 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,12 +28,8 @@ 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" ) @@ -46,7 +40,7 @@ const defaultTargetName = "default" // NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultContext, // this function returns it in addition to the error (i.e. it does "return nil, res, err"). The caller can // inspect the result and debug the cause of that error. -func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progressMode string, statusChan chan *client.SolveStatus, generateResult bool) (*client.SolveResponse, *build.ResultContext, error) { +func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progress progress.Writer, generateResult bool) (*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") } @@ -164,6 +158,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build contextPathHash = in.ContextPath } + // TODO: this should not be loaded this side of the controller api b, err := builder.New(dockerCli, builder.WithName(in.Builder), builder.WithContextPathHash(contextPathHash), @@ -179,7 +174,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.MetadataFile, statusChan, generateResult) + resp, res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progress, in.MetadataFile, generateResult) err = wrapBuildError(err, false) if err != nil { // NOTE: buildTargets can return *build.ResultContext even on error. @@ -193,24 +188,14 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build // NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultContext, // this function returns it in addition to the error (i.e. it does "return nil, res, err"). The caller can // inspect the result and debug the cause of that 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, generateResult bool) (*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), - )) - if err != nil { - return nil, nil, err - } - +func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer, metadataFile string, generateResult bool) (*client.SolveResponse, *build.ResultContext, error) { var res *build.ResultContext var resp map[string]*client.SolveResponse + var err error if generateResult { 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), progress, func(driverIndex int, gotRes *build.ResultContext) { mu.Lock() defer mu.Unlock() if res == nil || driverIndex < idx { @@ -218,11 +203,7 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou } }) } else { - resp, err = build.Build(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress.Tee(printer, statusChan)) - } - err1 := printer.Wait() - if err == nil { - err = err1 + resp, err = build.Build(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress) } if err != nil { return nil, res, err @@ -234,8 +215,6 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGrou } } - printWarnings(os.Stderr, printer.Warnings(), progressMode) - for k := range resp { if opts[k].PrintFunc != nil { if err := printResult(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil { @@ -247,46 +226,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/control/controller.go b/controller/control/controller.go index 5fa0c5953470..bdc5b7f891ef 100644 --- a/controller/control/controller.go +++ b/controller/control/controller.go @@ -4,13 +4,13 @@ import ( "context" "io" - "github.com/containerd/console" controllerapi "github.com/docker/buildx/controller/pb" + "github.com/docker/buildx/util/progress" "github.com/moby/buildkit/client" ) 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, progress progress.Writer) (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. diff --git a/controller/local/controller.go b/controller/local/controller.go index 991c98d0999a..2bce2b28c622 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" @@ -13,6 +12,7 @@ import ( controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/controller/processes" "github.com/docker/buildx/util/ioset" + "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" "github.com/moby/buildkit/client" "github.com/pkg/errors" @@ -42,13 +42,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, progress progress.Writer) (string, *client.SolveResponse, error) { if !b.buildOnGoing.CompareAndSwap(false, true) { return "", nil, errors.New("build ongoing") } defer b.buildOnGoing.Store(false) - resp, res, buildErr := cbuild.RunBuild(ctx, b.dockerCli, options, in, progressMode, nil, true) + resp, res, buildErr := cbuild.RunBuild(ctx, b.dockerCli, options, in, progress, true) // NOTE: RunBuild can return *build.ResultContext even on error. if res != nil { b.buildConfig = buildConfig{ diff --git a/controller/pb/progress.go b/controller/pb/progress.go new file mode 100644 index 000000000000..0b81aaa6ea26 --- /dev/null +++ b/controller/pb/progress.go @@ -0,0 +1,122 @@ +package pb + +import ( + "github.com/docker/buildx/util/progress" + control "github.com/moby/buildkit/api/services/control" + "github.com/moby/buildkit/client" + "github.com/opencontainers/go-digest" +) + +type writer struct { + ch chan<- *StatusResponse +} + +func NewProgressWriter(ch chan<- *StatusResponse) progress.Writer { + return &writer{ch: ch} +} + +func (w *writer) Write(status *client.SolveStatus) { + w.ch <- ToControlStatus(status) +} + +func (w *writer) ValidateLogSource(digest.Digest, interface{}) bool { + return true +} + +func (w *writer) ClearLogSource(interface{}) {} + +func ToControlStatus(s *client.SolveStatus) *StatusResponse { + resp := StatusResponse{} + for _, v := range s.Vertexes { + resp.Vertexes = append(resp.Vertexes, &control.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, &control.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, &control.VertexLog{ + Vertex: v.Vertex, + Stream: int64(v.Stream), + Msg: v.Data, + Timestamp: v.Timestamp, + }) + } + for _, v := range s.Warnings { + resp.Warnings = append(resp.Warnings, &control.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 FromControlStatus(resp *StatusResponse) *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/remote/client.go b/controller/remote/client.go index 545961f9b347..b3b6c12be2d0 100644 --- a/controller/remote/client.go +++ b/controller/remote/client.go @@ -6,7 +6,6 @@ import ( "sync" "time" - "github.com/containerd/console" "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/pkg/dialer" "github.com/docker/buildx/controller/pb" @@ -114,14 +113,9 @@ func (c *Client) Inspect(ctx context.Context, ref string) (*pb.InspectResponse, return c.client().Inspect(ctx, &pb.InspectRequest{Ref: ref}) } -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, progress progress.Writer) (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 { @@ -131,17 +125,12 @@ func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadC return err }) eg.Go(func() error { - defer close(statusDone) for s := range statusChan { st := s - pw.Write(st) + progress.Write(st) } return nil }) - eg.Go(func() error { - <-statusDone - return pw.Wait() - }) return ref, resp, eg.Wait() } @@ -180,51 +169,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 <- pb.FromControlStatus(resp) } }) if in != nil { diff --git a/controller/remote/controller.go b/controller/remote/controller.go index 7c91c9717c5d..60aaa852195e 100644 --- a/controller/remote/controller.go +++ b/controller/remote/controller.go @@ -21,6 +21,7 @@ import ( "github.com/docker/buildx/controller/control" controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/util/confutil" + "github.com/docker/buildx/util/progress" "github.com/docker/buildx/version" "github.com/docker/cli/cli/command" "github.com/moby/buildkit/client" @@ -142,8 +143,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, true) + b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, progress progress.Writer) (*client.SolveResponse, *build.ResultContext, error) { + return cbuild.RunBuild(ctx, dockerCli, *options, stdin, progress, true) }) defer b.Close() diff --git a/controller/remote/server.go b/controller/remote/server.go index d78146b1e962..d89fc2180667 100644 --- a/controller/remote/server.go +++ b/controller/remote/server.go @@ -12,14 +12,14 @@ import ( "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/controller/processes" "github.com/docker/buildx/util/ioset" + "github.com/docker/buildx/util/progress" "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, progress progress.Writer) (resp *client.SolveResponse, res *build.ResultContext, err error) func NewServer(buildFunc BuildFunc) *Server { return &Server{ @@ -35,7 +35,7 @@ type Server struct { type session struct { buildOnGoing atomic.Bool - statusChan chan *client.SolveStatus + statusChan chan *pb.StatusResponse cancelBuild func() buildOptions *pb.BuildOptions inputPipe *io.PipeWriter @@ -177,8 +177,9 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp s = &session{} 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() @@ -196,10 +197,12 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp m.sessionMu.Unlock() }() + pw := pb.NewProgressWriter(statusChan) + // Build the specified request ctx, cancel := context.WithCancel(ctx) defer cancel() - resp, res, buildErr := m.buildFunc(ctx, req.Options, inR, statusChan) + resp, res, buildErr := m.buildFunc(ctx, req.Options, inR, pw) m.sessionMu.Lock() if s, ok := m.session[ref]; ok { // NOTE: buildFunc can return *build.ResultContext even on error (e.g. when it's implemented using (github.com/docker/buildx/controller/build).RunBuild). @@ -237,7 +240,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() @@ -256,8 +259,7 @@ func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer if ss == nil { break } - cs := toControlStatus(ss) - if err := stream.Send(cs); err != nil { + if err := stream.Send(ss); err != nil { return err } } @@ -437,51 +439,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 4ca9954aee2a..d727d241c84a 100644 --- a/monitor/monitor.go +++ b/monitor/monitor.go @@ -15,6 +15,7 @@ import ( controllererrors "github.com/docker/buildx/controller/errdefs" controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/util/ioset" + "github.com/docker/buildx/util/progress" "github.com/moby/buildkit/identity" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -36,7 +37,7 @@ Available commands are: ` // RunMonitor provides an interactive session for running and managing containers via specified IO. -func RunMonitor(ctx context.Context, curRef string, options *controllerapi.BuildOptions, invokeConfig controllerapi.InvokeConfig, c control.BuildxController, progressMode string, stdin io.ReadCloser, stdout io.WriteCloser, stderr console.File) error { +func RunMonitor(ctx context.Context, curRef string, options *controllerapi.BuildOptions, invokeConfig controllerapi.InvokeConfig, c control.BuildxController, stdin io.ReadCloser, stdout io.WriteCloser, stderr console.File, progress progress.Writer) error { defer func() { if err := c.Disconnect(ctx, curRef); err != nil { logrus.Warnf("disconnect error: %v", err) @@ -145,7 +146,7 @@ func RunMonitor(ctx context.Context, curRef string, options *controllerapi.Build } } var resultUpdated bool - ref, _, err := c.Build(ctx, *bo, nil, stdout, stderr, progressMode) // TODO: support stdin, hold build ref + ref, _, err := c.Build(ctx, *bo, nil, progress) // TODO: support stdin, hold build ref if err != nil { var be *controllererrors.BuildError if errors.As(err, &be) { From c6a78d216cc408860ffb19050732b98a8180ad72 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 19 Apr 2023 11:42:16 +0100 Subject: [PATCH 2/4] build: refactor to avoid unneccessary nesting Signed-off-by: Justin Chadwell --- build/build.go | 515 ++++++++++++++++++++++++------------------------- 1 file changed, 254 insertions(+), 261 deletions(-) diff --git a/build/build.go b/build/build.go index f479aa65c9bf..9d5160010023 100644 --- a/build/build.go +++ b/build/build.go @@ -792,320 +792,313 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s multiTarget := len(opt) > 1 for k, opt := range opt { - err := func(k string) error { - opt := opt - dps := m[k] - multiDriver := len(m[k]) > 1 - - var span trace.Span - ctx := ctx - if multiTarget { - span, ctx = tracing.StartSpan(ctx, k) - } - baseCtx := ctx - - res := make([]*client.SolveResponse, len(dps)) - eg2, ctx := errgroup.WithContext(ctx) - - var pushNames string - var insecurePush bool - - for i, dp := range dps { - i, dp, so := i, dp, *dp.so - if multiDriver { - for i, e := range so.Exports { - switch e.Type { - case "oci", "tar": - return errors.Errorf("%s for multi-node builds currently not supported", e.Type) - case "image": - if pushNames == "" && e.Attrs["push"] != "" { - if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { - pushNames = e.Attrs["name"] - if pushNames == "" { - return errors.Errorf("tag is needed when pushing to registry") - } - names, err := toRepoOnly(e.Attrs["name"]) - if err != nil { - return err - } - if ok, _ := strconv.ParseBool(e.Attrs["registry.insecure"]); ok { - insecurePush = true - } - e.Attrs["name"] = names - e.Attrs["push-by-digest"] = "true" - so.Exports[i].Attrs = e.Attrs + k, opt := k, opt + dps := m[k] + multiDriver := len(m[k]) > 1 + + var span trace.Span + ctx := ctx + if multiTarget { + span, ctx = tracing.StartSpan(ctx, k) + } + baseCtx := ctx + + res := make([]*client.SolveResponse, len(dps)) + eg2, ctx := errgroup.WithContext(ctx) + + var pushNames string + var insecurePush bool + + for i, dp := range dps { + i, dp, so := i, dp, *dp.so + if multiDriver { + for i, e := range so.Exports { + switch e.Type { + case "oci", "tar": + return nil, errors.Errorf("%s for multi-node builds currently not supported", e.Type) + case "image": + if pushNames == "" && e.Attrs["push"] != "" { + if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { + pushNames = e.Attrs["name"] + if pushNames == "" { + return nil, errors.Errorf("tag is needed when pushing to registry") } + names, err := toRepoOnly(e.Attrs["name"]) + if err != nil { + return nil, err + } + if ok, _ := strconv.ParseBool(e.Attrs["registry.insecure"]); ok { + insecurePush = true + } + e.Attrs["name"] = names + e.Attrs["push-by-digest"] = "true" + so.Exports[i].Attrs = e.Attrs } } } } + } + + pw := progress.WithPrefix(w, k, multiTarget) - pw := progress.WithPrefix(w, k, multiTarget) + c := clients[dp.driverIndex] + eg2.Go(func() error { + pw = progress.ResetTime(pw) - c := clients[dp.driverIndex] - eg2.Go(func() error { - pw = progress.ResetTime(pw) + if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil { + return err + } - if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil { + frontendInputs := make(map[string]*pb.Definition) + for key, st := range so.FrontendInputs { + def, err := st.Marshal(ctx) + if err != nil { return err } + frontendInputs[key] = def.ToPB() + } - frontendInputs := make(map[string]*pb.Definition) - for key, st := range so.FrontendInputs { - def, err := st.Marshal(ctx) - if err != nil { - return err + req := gateway.SolveRequest{ + Frontend: so.Frontend, + FrontendInputs: frontendInputs, + FrontendOpt: make(map[string]string), + } + for k, v := range so.FrontendAttrs { + req.FrontendOpt[k] = v + } + so.Frontend = "" + so.FrontendInputs = nil + + ch, done := progress.NewChannel(pw) + defer func() { <-done }() + + cc := c + var printRes map[string][]byte + rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { + var isFallback bool + var origErr error + for { + if opt.PrintFunc != nil { + if _, ok := req.FrontendOpt["frontend.caps"]; !ok { + req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward" + } else { + req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward" + } + req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name + if isFallback { + req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage + } } - frontendInputs[key] = def.ToPB() - } - - req := gateway.SolveRequest{ - Frontend: so.Frontend, - FrontendInputs: frontendInputs, - FrontendOpt: make(map[string]string), - } - for k, v := range so.FrontendAttrs { - req.FrontendOpt[k] = v - } - so.Frontend = "" - so.FrontendInputs = nil - - ch, done := progress.NewChannel(pw) - defer func() { <-done }() - - cc := c - var printRes map[string][]byte - rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { - var isFallback bool - var origErr error - for { - if opt.PrintFunc != nil { - if _, ok := req.FrontendOpt["frontend.caps"]; !ok { - req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward" - } else { - req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward" - } - req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name - if isFallback { - req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage - } + res, err := c.Solve(ctx, req) + if err != nil { + if origErr != nil { + return nil, err } - res, err := c.Solve(ctx, req) - if err != nil { - if origErr != nil { - return nil, err - } - var reqErr *errdefs.UnsupportedSubrequestError - if !isFallback { - if errors.As(err, &reqErr) { - switch reqErr.Name { - case "frontend.outline", "frontend.targets": - isFallback = true - origErr = err - continue - } - return nil, err - } - // buildkit v0.8 vendored in Docker 20.10 does not support typed errors - if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") { + var reqErr *errdefs.UnsupportedSubrequestError + if !isFallback { + if errors.As(err, &reqErr) { + switch reqErr.Name { + case "frontend.outline", "frontend.targets": isFallback = true origErr = err continue } + return nil, err } - return nil, err - } - if opt.PrintFunc != nil { - printRes = res.Metadata - } - results.Set(resultKey(dp.driverIndex, k), res) - if resultHandleFunc != nil { - resultCtx, err := NewResultContext(cc, so, res) - if err == nil { - resultHandleFunc(dp.driverIndex, resultCtx) - } else { - logrus.Warnf("failed to record result: %s", err) + // buildkit v0.8 vendored in Docker 20.10 does not support typed errors + if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") { + isFallback = true + origErr = err + continue } } - return res, nil + return nil, err } - }, ch) - if err != nil { - return err + if opt.PrintFunc != nil { + printRes = res.Metadata + } + results.Set(resultKey(dp.driverIndex, k), res) + if resultHandleFunc != nil { + resultCtx, err := NewResultContext(cc, so, res) + if err == nil { + resultHandleFunc(dp.driverIndex, resultCtx) + } else { + logrus.Warnf("failed to record result: %s", err) + } + } + return res, nil } - res[i] = rr + }, ch) + if err != nil { + return err + } + res[i] = rr - if rr.ExporterResponse == nil { - rr.ExporterResponse = map[string]string{} - } - for k, v := range printRes { - rr.ExporterResponse[k] = string(v) - } + if rr.ExporterResponse == nil { + rr.ExporterResponse = map[string]string{} + } + for k, v := range printRes { + rr.ExporterResponse[k] = string(v) + } - node := nodes[dp.driverIndex].Driver - if node.IsMobyDriver() { - for _, e := range so.Exports { - if e.Type == "moby" && e.Attrs["push"] != "" { - if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { - pushNames = e.Attrs["name"] - if pushNames == "" { - return errors.Errorf("tag is needed when pushing to registry") - } - pw := progress.ResetTime(pw) - pushList := strings.Split(pushNames, ",") - for _, name := range pushList { - if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error { - return pushWithMoby(ctx, node, name, l) - }); err != nil { - return err - } + node := nodes[dp.driverIndex].Driver + if node.IsMobyDriver() { + for _, e := range so.Exports { + if e.Type == "moby" && e.Attrs["push"] != "" { + if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { + pushNames = e.Attrs["name"] + if pushNames == "" { + return errors.Errorf("tag is needed when pushing to registry") + } + pw := progress.ResetTime(pw) + pushList := strings.Split(pushNames, ",") + for _, name := range pushList { + if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error { + return pushWithMoby(ctx, node, name, l) + }); err != nil { + return err } - remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0]) - if err == nil && remoteDigest != "" { - // old daemons might not have containerimage.config.digest set - // in response so use containerimage.digest value for it if available - if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok { - if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok { - rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v - } + } + remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0]) + if err == nil && remoteDigest != "" { + // old daemons might not have containerimage.config.digest set + // in response so use containerimage.digest value for it if available + if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok { + if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok { + rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v } - rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest - } else if err != nil { - return err } + rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest + } else if err != nil { + return err } } } } - return nil - }) - } - - eg.Go(func() (err error) { - ctx := baseCtx - defer func() { - if span != nil { - tracing.FinishWithError(span, err) - } - }() - pw := progress.WithPrefix(w, "default", false) - if err := eg2.Wait(); err != nil { - return err } + return nil + }) + } - respMu.Lock() - resp[k] = res[0] - respMu.Unlock() - if len(res) == 1 { - return nil + eg.Go(func() (err error) { + ctx := baseCtx + defer func() { + if span != nil { + tracing.FinishWithError(span, err) } + }() + pw := progress.WithPrefix(w, "default", false) + if err := eg2.Wait(); err != nil { + return err + } - if pushNames != "" { - progress.Write(pw, fmt.Sprintf("merging manifest list %s", pushNames), func() error { - descs := make([]specs.Descriptor, 0, len(res)) - - for _, r := range res { - s, ok := r.ExporterResponse[exptypes.ExporterImageDescriptorKey] - if ok { - dt, err := base64.StdEncoding.DecodeString(s) - if err != nil { - return err - } - var desc specs.Descriptor - if err := json.Unmarshal(dt, &desc); err != nil { - return errors.Wrapf(err, "failed to unmarshal descriptor %s", s) - } - descs = append(descs, desc) - continue - } - // This is fallback for some very old buildkit versions. - // Note that the mediatype isn't really correct as most of the time it is image manifest and - // not manifest list but actually both are handled because for Docker mediatypes the - // mediatype value in the Accpet header does not seem to matter. - s, ok = r.ExporterResponse[exptypes.ExporterImageDigestKey] - if ok { - descs = append(descs, specs.Descriptor{ - Digest: digest.Digest(s), - MediaType: images.MediaTypeDockerSchema2ManifestList, - Size: -1, - }) - } - } - if len(descs) > 0 { - var imageopt imagetools.Opt - for _, dp := range dps { - imageopt = nodes[dp.driverIndex].ImageOpt - break - } - names := strings.Split(pushNames, ",") - - if insecurePush { - insecureTrue := true - httpTrue := true - nn, err := reference.ParseNormalizedNamed(names[0]) - if err != nil { - return err - } - imageopt.RegistryConfig = map[string]resolver.RegistryConfig{ - reference.Domain(nn): { - Insecure: &insecureTrue, - PlainHTTP: &httpTrue, - }, - } - } + respMu.Lock() + resp[k] = res[0] + respMu.Unlock() + if len(res) == 1 { + return nil + } - itpull := imagetools.New(imageopt) + if pushNames != "" { + progress.Write(pw, fmt.Sprintf("merging manifest list %s", pushNames), func() error { + descs := make([]specs.Descriptor, 0, len(res)) - ref, err := reference.ParseNormalizedNamed(names[0]) + for _, r := range res { + s, ok := r.ExporterResponse[exptypes.ExporterImageDescriptorKey] + if ok { + dt, err := base64.StdEncoding.DecodeString(s) if err != nil { return err } - ref = reference.TagNameOnly(ref) - - srcs := make([]*imagetools.Source, len(descs)) - for i, desc := range descs { - srcs[i] = &imagetools.Source{ - Desc: desc, - Ref: ref, - } + var desc specs.Descriptor + if err := json.Unmarshal(dt, &desc); err != nil { + return errors.Wrapf(err, "failed to unmarshal descriptor %s", s) } + descs = append(descs, desc) + continue + } + // This is fallback for some very old buildkit versions. + // Note that the mediatype isn't really correct as most of the time it is image manifest and + // not manifest list but actually both are handled because for Docker mediatypes the + // mediatype value in the Accpet header does not seem to matter. + s, ok = r.ExporterResponse[exptypes.ExporterImageDigestKey] + if ok { + descs = append(descs, specs.Descriptor{ + Digest: digest.Digest(s), + MediaType: images.MediaTypeDockerSchema2ManifestList, + Size: -1, + }) + } + } + if len(descs) > 0 { + var imageopt imagetools.Opt + for _, dp := range dps { + imageopt = nodes[dp.driverIndex].ImageOpt + break + } + names := strings.Split(pushNames, ",") - dt, desc, err := itpull.Combine(ctx, srcs) + if insecurePush { + insecureTrue := true + httpTrue := true + nn, err := reference.ParseNormalizedNamed(names[0]) if err != nil { return err } + imageopt.RegistryConfig = map[string]resolver.RegistryConfig{ + reference.Domain(nn): { + Insecure: &insecureTrue, + PlainHTTP: &httpTrue, + }, + } + } - itpush := imagetools.New(imageopt) + itpull := imagetools.New(imageopt) - for _, n := range names { - nn, err := reference.ParseNormalizedNamed(n) - if err != nil { - return err - } - if err := itpush.Push(ctx, nn, desc, dt); err != nil { - return err - } + ref, err := reference.ParseNormalizedNamed(names[0]) + if err != nil { + return err + } + ref = reference.TagNameOnly(ref) + + srcs := make([]*imagetools.Source, len(descs)) + for i, desc := range descs { + srcs[i] = &imagetools.Source{ + Desc: desc, + Ref: ref, } + } - respMu.Lock() - resp[k] = &client.SolveResponse{ - ExporterResponse: map[string]string{ - exptypes.ExporterImageDigestKey: desc.Digest.String(), - }, + dt, desc, err := itpull.Combine(ctx, srcs) + if err != nil { + return err + } + + itpush := imagetools.New(imageopt) + + for _, n := range names { + nn, err := reference.ParseNormalizedNamed(n) + if err != nil { + return err + } + if err := itpush.Push(ctx, nn, desc, dt); err != nil { + return err } - respMu.Unlock() } - return nil - }) - } - return nil - }) + respMu.Lock() + resp[k] = &client.SolveResponse{ + ExporterResponse: map[string]string{ + exptypes.ExporterImageDigestKey: desc.Digest.String(), + }, + } + respMu.Unlock() + } + return nil + }) + } return nil - }(k) - if err != nil { - return nil, err - } + }) } if err := eg.Wait(); err != nil { From 1571c137bc02dfc57e5e95c74831ae6e76ae6271 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 19 Apr 2023 11:54:02 +0100 Subject: [PATCH 3/4] build: rework build package to use only a single Build call Signed-off-by: Justin Chadwell --- build/build.go | 551 +++++++----- build/result.go | 157 ++-- commands/build.go | 160 +++- controller/build/build.go | 148 +--- controller/build/print.go | 48 -- controller/control/controller.go | 16 +- controller/local/controller.go | 32 +- controller/pb/controller.pb.go | 808 +++++++++++------- controller/pb/controller.proto | 31 +- controller/remote/client.go | 71 +- controller/remote/controller.go | 5 +- controller/remote/server.go | 110 +-- monitor/monitor.go | 7 +- util/progress/printer.go | 9 +- .../util/progress/progressui/display.go | 15 +- .../util/progress/progresswriter/printer.go | 2 +- 16 files changed, 1181 insertions(+), 989 deletions(-) delete mode 100644 controller/build/print.go diff --git a/build/build.go b/build/build.go index 9d5160010023..60afda70928d 100644 --- a/build/build.go +++ b/build/build.go @@ -653,11 +653,166 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op return &so, releaseF, nil } +func build(ctx context.Context, c *client.Client, opt Options, so client.SolveOpt, pw progress.Writer) (*ResultContext, error) { + frontendInputs := make(map[string]*pb.Definition) + for key, st := range so.FrontendInputs { + def, err := st.Marshal(ctx) + if err != nil { + return nil, err + } + frontendInputs[key] = def.ToPB() + } + + req := gateway.SolveRequest{ + Frontend: so.Frontend, + FrontendInputs: frontendInputs, + FrontendOpt: make(map[string]string), + } + for k, v := range so.FrontendAttrs { + req.FrontendOpt[k] = v + } + so.Frontend = "" + so.FrontendInputs = nil + + ch, chdone := progress.NewChannel(pw) + + rcs := make(chan *ResultContext) + + suspend := make(chan struct{}) + suspendDone := make(chan struct{}) + + go func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var rc *ResultContext + + var printRes map[string][]byte + rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { + var isFallback bool + var origErr error + for { + if opt.PrintFunc != nil { + if _, ok := req.FrontendOpt["frontend.caps"]; !ok { + req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward" + } else { + req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward" + } + req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name + if isFallback { + req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage + } + } + res, err := c.Solve(ctx, req) + if err != nil { + if origErr != nil { + return nil, err + } + var reqErr *errdefs.UnsupportedSubrequestError + if !isFallback { + if errors.As(err, &reqErr) { + switch reqErr.Name { + case "frontend.outline", "frontend.targets": + isFallback = true + origErr = err + continue + } + return nil, err + } + // buildkit v0.8 vendored in Docker 20.10 does not support typed errors + if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") { + isFallback = true + origErr = err + continue + } + } + } + + // TODO: would we want to compute this on demand instead of blocking? + eg, ctx2 := errgroup.WithContext(ctx) + res.EachRef(func(r gateway.Reference) error { + eg.Go(func() error { + return r.Evaluate(ctx2) + }) + return nil + }) + err = eg.Wait() + + if opt.PrintFunc != nil { + printRes = res.Metadata + } + + rc = &ResultContext{ + gwClient: c, + gwCtx: ctx, + gwDone: cancel, + gwRef: res, + suspend: suspend, + suspendDone: suspendDone, + } + var se *errdefs.SolveError + if errors.As(err, &se) { + rc.gwErr = se + } else if err != nil { + return nil, err + } + rcs <- rc + + <-suspend + return res, err + } + }, ch) + + <-chdone + + if rr != nil { + if rr.ExporterResponse == nil { + rr.ExporterResponse = map[string]string{} + } + for k, v := range printRes { + rr.ExporterResponse[k] = string(v) + } + } + + rc.resp = rr + rc.err = err + close(suspendDone) + }() + + select { + case <-ctx.Done(): + return nil, ctx.Err() + case rc := <-rcs: + return rc, nil + } +} + func Build(ctx context.Context, nodes []builder.Node, opt map[string]Options, docker *dockerutil.Client, configDir string, w progress.Writer) (resp map[string]*client.SolveResponse, err error) { - return BuildWithResultHandler(ctx, nodes, opt, docker, configDir, w, nil) + resp = map[string]*client.SolveResponse{} + + rcs, err := BuildResults(ctx, nodes, opt, docker, configDir, w) + if err != nil { + return nil, err + } + eg, ctx := errgroup.WithContext(ctx) + for k, v := range rcs { + k, v := k, v + eg.Go(func() error { + v2, err := v.Wait(ctx) + if err != nil { + return err + } + resp[k] = v2 + return nil + }) + } + if err := eg.Wait(); err != nil { + return nil, err + } + return resp, nil } -func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[string]Options, docker *dockerutil.Client, configDir string, w progress.Writer, resultHandleFunc func(driverIndex int, rCtx *ResultContext)) (resp map[string]*client.SolveResponse, err error) { +func BuildResults(ctx context.Context, nodes []builder.Node, opt map[string]Options, docker *dockerutil.Client, configDir string, w progress.Writer) (resp map[string]*ResultContext, err error) { if len(nodes) == 0 { return nil, errors.Errorf("driver required for build") } @@ -708,8 +863,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s } }() - eg, ctx := errgroup.WithContext(ctx) - for k, opt := range opt { multiDriver := len(m[k]) > 1 hasMobyDriver := false @@ -785,8 +938,9 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s } } - resp = map[string]*client.SolveResponse{} + eg, ctx := errgroup.WithContext(ctx) var respMu sync.Mutex + resp = map[string]*ResultContext{} results := waitmap.New() multiTarget := len(opt) > 1 @@ -801,15 +955,17 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s if multiTarget { span, ctx = tracing.StartSpan(ctx, k) } - baseCtx := ctx - res := make([]*client.SolveResponse, len(dps)) - eg2, ctx := errgroup.WithContext(ctx) + res := make([]*ResultContext, len(dps)) var pushNames string var insecurePush bool + wg := sync.WaitGroup{} + for i, dp := range dps { + wg.Add(1) + i, dp, so := i, dp, *dp.so if multiDriver { for i, e := range so.Exports { @@ -842,263 +998,188 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s pw := progress.WithPrefix(w, k, multiTarget) c := clients[dp.driverIndex] - eg2.Go(func() error { + eg.Go(func() error { pw = progress.ResetTime(pw) if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil { return err } - frontendInputs := make(map[string]*pb.Definition) - for key, st := range so.FrontendInputs { - def, err := st.Marshal(ctx) - if err != nil { - return err - } - frontendInputs[key] = def.ToPB() - } - - req := gateway.SolveRequest{ - Frontend: so.Frontend, - FrontendInputs: frontendInputs, - FrontendOpt: make(map[string]string), - } - for k, v := range so.FrontendAttrs { - req.FrontendOpt[k] = v - } - so.Frontend = "" - so.FrontendInputs = nil - - ch, done := progress.NewChannel(pw) - defer func() { <-done }() - - cc := c - var printRes map[string][]byte - rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { - var isFallback bool - var origErr error - for { - if opt.PrintFunc != nil { - if _, ok := req.FrontendOpt["frontend.caps"]; !ok { - req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward" - } else { - req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward" - } - req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name - if isFallback { - req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage - } - } - res, err := c.Solve(ctx, req) - if err != nil { - if origErr != nil { - return nil, err - } - var reqErr *errdefs.UnsupportedSubrequestError - if !isFallback { - if errors.As(err, &reqErr) { - switch reqErr.Name { - case "frontend.outline", "frontend.targets": - isFallback = true - origErr = err - continue - } - return nil, err - } - // buildkit v0.8 vendored in Docker 20.10 does not support typed errors - if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") { - isFallback = true - origErr = err - continue - } - } - return nil, err - } - if opt.PrintFunc != nil { - printRes = res.Metadata - } - results.Set(resultKey(dp.driverIndex, k), res) - if resultHandleFunc != nil { - resultCtx, err := NewResultContext(cc, so, res) - if err == nil { - resultHandleFunc(dp.driverIndex, resultCtx) - } else { - logrus.Warnf("failed to record result: %s", err) - } - } - return res, nil - } - }, ch) + result, err := build(ctx, c, opt, so, pw) if err != nil { return err } - res[i] = rr - - if rr.ExporterResponse == nil { - rr.ExporterResponse = map[string]string{} - } - for k, v := range printRes { - rr.ExporterResponse[k] = string(v) - } - - node := nodes[dp.driverIndex].Driver - if node.IsMobyDriver() { - for _, e := range so.Exports { - if e.Type == "moby" && e.Attrs["push"] != "" { - if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { - pushNames = e.Attrs["name"] - if pushNames == "" { - return errors.Errorf("tag is needed when pushing to registry") - } - pw := progress.ResetTime(pw) - pushList := strings.Split(pushNames, ",") - for _, name := range pushList { - if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error { - return pushWithMoby(ctx, node, name, l) - }); err != nil { - return err + results.Set(resultKey(dp.driverIndex, k), result.gwRef) + + res[i] = result + resp[k] = result + + result.hook(func(ctx context.Context) error { + defer wg.Done() + + node := nodes[dp.driverIndex].Driver + if node.IsMobyDriver() { + for _, e := range so.Exports { + if e.Type == "moby" && e.Attrs["push"] != "" { + if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok { + pushNames = e.Attrs["name"] + if pushNames == "" { + return errors.Errorf("tag is needed when pushing to registry") } - } - remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0]) - if err == nil && remoteDigest != "" { - // old daemons might not have containerimage.config.digest set - // in response so use containerimage.digest value for it if available - if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok { - if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok { - rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v + pw := progress.ResetTime(pw) + pushList := strings.Split(pushNames, ",") + for _, name := range pushList { + if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error { + return pushWithMoby(ctx, node, name, l) + }); err != nil { + return err } } - rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest - } else if err != nil { - return err + remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0]) + if err == nil && remoteDigest != "" { + // old daemons might not have containerimage.config.digest set + // in response so use containerimage.digest value for it if available + if _, ok := result.resp.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok { + if v, ok := result.resp.ExporterResponse[exptypes.ExporterImageDigestKey]; ok { + result.resp.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v + } + } + result.resp.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest + } else if err != nil { + return err + } } } } } - } - return nil - }) - } - eg.Go(func() (err error) { - ctx := baseCtx - defer func() { - if span != nil { - tracing.FinishWithError(span, err) - } - }() - pw := progress.WithPrefix(w, "default", false) - if err := eg2.Wait(); err != nil { - return err - } - - respMu.Lock() - resp[k] = res[0] - respMu.Unlock() - if len(res) == 1 { - return nil - } + return nil + }) - if pushNames != "" { - progress.Write(pw, fmt.Sprintf("merging manifest list %s", pushNames), func() error { - descs := make([]specs.Descriptor, 0, len(res)) + if i == 0 { + result.hook(func(ctx context.Context) error { + wg.Wait() - for _, r := range res { - s, ok := r.ExporterResponse[exptypes.ExporterImageDescriptorKey] - if ok { - dt, err := base64.StdEncoding.DecodeString(s) - if err != nil { - return err - } - var desc specs.Descriptor - if err := json.Unmarshal(dt, &desc); err != nil { - return errors.Wrapf(err, "failed to unmarshal descriptor %s", s) + defer func() { + if span != nil { + tracing.FinishWithError(span, err) } - descs = append(descs, desc) - continue - } - // This is fallback for some very old buildkit versions. - // Note that the mediatype isn't really correct as most of the time it is image manifest and - // not manifest list but actually both are handled because for Docker mediatypes the - // mediatype value in the Accpet header does not seem to matter. - s, ok = r.ExporterResponse[exptypes.ExporterImageDigestKey] - if ok { - descs = append(descs, specs.Descriptor{ - Digest: digest.Digest(s), - MediaType: images.MediaTypeDockerSchema2ManifestList, - Size: -1, - }) + }() + + pw := progress.WithPrefix(w, "default", false) + + respMu.Lock() + resp[k] = res[0] + respMu.Unlock() + if len(res) == 1 { + return nil } - } - if len(descs) > 0 { - var imageopt imagetools.Opt - for _, dp := range dps { - imageopt = nodes[dp.driverIndex].ImageOpt - break + if pushNames == "" { + return nil } - names := strings.Split(pushNames, ",") - - if insecurePush { - insecureTrue := true - httpTrue := true - nn, err := reference.ParseNormalizedNamed(names[0]) - if err != nil { - return err - } - imageopt.RegistryConfig = map[string]resolver.RegistryConfig{ - reference.Domain(nn): { - Insecure: &insecureTrue, - PlainHTTP: &httpTrue, - }, + + progress.Write(pw, fmt.Sprintf("merging manifest list %s", pushNames), func() error { + descs := make([]specs.Descriptor, 0, len(res)) + + for _, r := range res { + s, ok := r.resp.ExporterResponse[exptypes.ExporterImageDescriptorKey] + if ok { + dt, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return err + } + var desc specs.Descriptor + if err := json.Unmarshal(dt, &desc); err != nil { + return errors.Wrapf(err, "failed to unmarshal descriptor %s", s) + } + descs = append(descs, desc) + continue + } + // This is fallback for some very old buildkit versions. + // Note that the mediatype isn't really correct as most of the time it is image manifest and + // not manifest list but actually both are handled because for Docker mediatypes the + // mediatype value in the Accpet header does not seem to matter. + s, ok = r.resp.ExporterResponse[exptypes.ExporterImageDigestKey] + if ok { + descs = append(descs, specs.Descriptor{ + Digest: digest.Digest(s), + MediaType: images.MediaTypeDockerSchema2ManifestList, + Size: -1, + }) + } } - } + if len(descs) > 0 { + var imageopt imagetools.Opt + for _, dp := range dps { + imageopt = nodes[dp.driverIndex].ImageOpt + break + } + names := strings.Split(pushNames, ",") - itpull := imagetools.New(imageopt) + if insecurePush { + insecureTrue := true + httpTrue := true + nn, err := reference.ParseNormalizedNamed(names[0]) + if err != nil { + return err + } + imageopt.RegistryConfig = map[string]resolver.RegistryConfig{ + reference.Domain(nn): { + Insecure: &insecureTrue, + PlainHTTP: &httpTrue, + }, + } + } - ref, err := reference.ParseNormalizedNamed(names[0]) - if err != nil { - return err - } - ref = reference.TagNameOnly(ref) + itpull := imagetools.New(imageopt) - srcs := make([]*imagetools.Source, len(descs)) - for i, desc := range descs { - srcs[i] = &imagetools.Source{ - Desc: desc, - Ref: ref, - } - } + ref, err := reference.ParseNormalizedNamed(names[0]) + if err != nil { + return err + } + ref = reference.TagNameOnly(ref) - dt, desc, err := itpull.Combine(ctx, srcs) - if err != nil { - return err - } + srcs := make([]*imagetools.Source, len(descs)) + for i, desc := range descs { + srcs[i] = &imagetools.Source{ + Desc: desc, + Ref: ref, + } + } - itpush := imagetools.New(imageopt) + dt, desc, err := itpull.Combine(ctx, srcs) + if err != nil { + return err + } - for _, n := range names { - nn, err := reference.ParseNormalizedNamed(n) - if err != nil { - return err - } - if err := itpush.Push(ctx, nn, desc, dt); err != nil { - return err - } - } + itpush := imagetools.New(imageopt) - respMu.Lock() - resp[k] = &client.SolveResponse{ - ExporterResponse: map[string]string{ - exptypes.ExporterImageDigestKey: desc.Digest.String(), - }, - } - respMu.Unlock() - } - return nil - }) - } - return nil - }) + for _, n := range names { + nn, err := reference.ParseNormalizedNamed(n) + if err != nil { + return err + } + if err := itpush.Push(ctx, nn, desc, dt); err != nil { + return err + } + } + + respMu.Lock() + resp[k].resp = &client.SolveResponse{ + ExporterResponse: map[string]string{ + exptypes.ExporterImageDigestKey: desc.Digest.String(), + }, + } + respMu.Unlock() + } + return nil + }) + return nil + }) + } + return nil + }) + } } if err := eg.Wait(); err != nil { diff --git a/build/result.go b/build/result.go index 3d394be788d6..90326a53947b 100644 --- a/build/result.go +++ b/build/result.go @@ -6,7 +6,6 @@ import ( "encoding/json" "io" "sync" - "sync/atomic" controllerapi "github.com/docker/buildx/controller/pb" "github.com/moby/buildkit/client" @@ -17,110 +16,20 @@ import ( specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" ) -func NewResultContext(c *client.Client, solveOpt client.SolveOpt, res *gateway.Result) (*ResultContext, error) { - ctx := context.Background() - def, err := getDefinition(ctx, res) - if err != nil { - return nil, err - } - return getResultAt(ctx, c, solveOpt, def, nil) -} - -func getDefinition(ctx context.Context, res *gateway.Result) (*pb.Definition, error) { - ref, err := res.SingleRef() - if err != nil { - return nil, err - } - st, err := ref.ToState() - if err != nil { - return nil, err - } - def, err := st.Marshal(ctx) - if err != nil { - return nil, err - } - return def.ToPB(), nil -} - -func getResultAt(ctx context.Context, c *client.Client, solveOpt client.SolveOpt, target *pb.Definition, statusChan chan *client.SolveStatus) (*ResultContext, error) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - // forward SolveStatus - done := new(atomic.Bool) - defer done.Store(true) - ch := make(chan *client.SolveStatus) - go func() { - for { - s := <-ch - if s == nil { - return - } - if done.Load() { - // Do not forward if the function returned because statusChan is possibly closed - continue - } - select { - case statusChan <- s: - case <-ctx.Done(): - } - } - }() - - // get result - resultCtxCh := make(chan *ResultContext) - errCh := make(chan error) - go func() { - _, err := c.Build(context.Background(), solveOpt, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - resultCtx := ResultContext{} - res2, err := c.Solve(ctx, gateway.SolveRequest{ - Evaluate: true, - Definition: target, - }) - if err != nil { - var se *errdefs.SolveError - if errors.As(err, &se) { - resultCtx.solveErr = se - } else { - return nil, err - } - } - // Record the client and ctx as well so that containers can be created from the SolveError. - resultCtx.res = res2 - resultCtx.gwClient = c - resultCtx.gwCtx = ctx - resultCtx.gwDone = cancel - select { - case resultCtxCh <- &resultCtx: - case <-ctx.Done(): - return nil, ctx.Err() - } - <-ctx.Done() - return nil, nil - }, ch) - if err != nil { - errCh <- err - } - }() - - select { - case resultCtx := <-resultCtxCh: - return resultCtx, nil - case err := <-errCh: - return nil, err - case <-ctx.Done(): - return nil, ctx.Err() - } -} - // ResultContext is a build result with the client that built it. type ResultContext struct { - res *gateway.Result - solveErr *errdefs.SolveError + resp *client.SolveResponse + err error + suspend chan<- struct{} + suspendDone <-chan struct{} + + hooks []func(ctx context.Context) error + + gwRef *gateway.Result + gwErr *errdefs.SolveError gwClient gateway.Client gwCtx context.Context @@ -131,7 +40,39 @@ type ResultContext struct { cleanupsMu sync.Mutex } -func (r *ResultContext) Done() { +func (r *ResultContext) hook(hook func(ctx context.Context) error) { + r.hooks = append(r.hooks, hook) +} + +func (r *ResultContext) Result(ctx context.Context) (*gateway.Result, *errdefs.SolveError) { + return r.gwRef, r.gwErr +} + +func (r *ResultContext) Wait(ctx context.Context) (*client.SolveResponse, error) { + defer r.Close() + + close(r.suspend) + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-r.suspendDone: + eg, ctx := errgroup.WithContext(ctx) + eg.Go(func() error { + for _, f := range r.hooks { + if err := f(ctx); err != nil { + return err + } + } + return nil + }) + if err := eg.Wait(); err != nil { + return nil, err + } + return r.resp, r.err + } +} + +func (r *ResultContext) Close() { r.gwDoneOnce.Do(func() { r.cleanupsMu.Lock() cleanups := r.cleanups @@ -156,16 +97,16 @@ func (r *ResultContext) build(buildFunc gateway.BuildFunc) (err error) { } func (r *ResultContext) getContainerConfig(ctx context.Context, c gateway.Client, cfg *controllerapi.InvokeConfig) (containerCfg gateway.NewContainerRequest, _ error) { - if r.res != nil && r.solveErr == nil { + if r.gwRef != nil && r.gwErr == nil { logrus.Debugf("creating container from successful build") - ccfg, err := containerConfigFromResult(ctx, r.res, c, *cfg) + ccfg, err := containerConfigFromResult(ctx, r.gwRef, c, *cfg) if err != nil { return containerCfg, err } containerCfg = *ccfg } else { logrus.Debugf("creating container from failed build %+v", cfg) - ccfg, err := containerConfigFromError(r.solveErr, *cfg) + ccfg, err := containerConfigFromError(r.gwErr, *cfg) if err != nil { return containerCfg, errors.Wrapf(err, "no result nor error is available") } @@ -176,14 +117,14 @@ func (r *ResultContext) getContainerConfig(ctx context.Context, c gateway.Client func (r *ResultContext) getProcessConfig(cfg *controllerapi.InvokeConfig, stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) (_ gateway.StartRequest, err error) { processCfg := newStartRequest(stdin, stdout, stderr) - if r.res != nil && r.solveErr == nil { + if r.gwRef != nil && r.gwErr == nil { logrus.Debugf("creating container from successful build") - if err := populateProcessConfigFromResult(&processCfg, r.res, *cfg); err != nil { + if err := populateProcessConfigFromResult(&processCfg, r.gwRef, *cfg); err != nil { return processCfg, err } } else { logrus.Debugf("creating container from failed build %+v", cfg) - if err := populateProcessConfigFromError(&processCfg, r.solveErr, *cfg); err != nil { + if err := populateProcessConfigFromError(&processCfg, r.gwErr, *cfg); err != nil { return processCfg, err } } diff --git a/commands/build.go b/commands/build.go index 12f34a072521..f0421c236892 100644 --- a/commands/build.go +++ b/commands/build.go @@ -8,11 +8,13 @@ import ( "encoding/json" "fmt" "io" + "log" "os" "path/filepath" "runtime" "strconv" "strings" + "sync" "github.com/containerd/console" "github.com/docker/buildx/build" @@ -33,10 +35,14 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" dockeropts "github.com/docker/cli/opts" + "github.com/docker/docker/api/types/versions" "github.com/docker/docker/builder/remotecontext/urlutil" "github.com/docker/docker/pkg/ioutils" "github.com/moby/buildkit/client" "github.com/moby/buildkit/exporter/containerimage/exptypes" + "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/moby/buildkit/util/appcontext" "github.com/moby/buildkit/util/grpcerrors" @@ -106,7 +112,6 @@ func (o *buildOptions) toControllerOptions() (controllerapi.BuildOptions, error) NetworkMode: o.networkMode, NoCacheFilter: o.noCacheFilter, Platforms: o.platforms, - PrintFunc: o.printFunc, ShmSize: int64(o.shmSize), Tags: o.tags, Target: o.target, @@ -153,6 +158,11 @@ func (o *buildOptions) toControllerOptions() (controllerapi.BuildOptions, error) } } + opts.PrintFunc, err = parsePrintFunc(o.printFunc) + if err != nil { + return controllerapi.BuildOptions{}, err + } + opts.CacheFrom, err = buildflags.ParseCacheEntry(o.cacheFrom) if err != nil { return controllerapi.BuildOptions{}, err @@ -231,9 +241,13 @@ 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, printer, false) - if err1 := printer.Wait(); err == nil { - err = err1 + res, err := cbuild.RunBuild(ctx, dockerCli, opts, os.Stdin, printer) + resp, err2 := res.Wait(ctx) + if err == nil { + err = err2 + } + if err2 := printer.Wait(); err == nil { + err = err2 } if err != nil { return err @@ -249,6 +263,16 @@ func runBuild(dockerCli command.Cli, in buildOptions) error { } return os.WriteFile(in.imageIDFile, []byte(dgst), 0644) } + if in.metadataFile != "" { + if err := writeMetadataFile(in.metadataFile, decodeExporterResponse(resp.ExporterResponse)); err != nil { + return err + } + } + if opts.PrintFunc != nil { + if err := printResult(opts.PrintFunc, resp.ExporterResponse); err != nil { + return err + } + } return nil } @@ -518,7 +542,7 @@ func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error { return txn.UpdateLastActivity(ng) } -func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) error { +func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) (err error) { ctx := context.TODO() if options.invoke != nil && (options.dockerfileName == "-" || options.contextPath == "-") { @@ -560,6 +584,14 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er if err != nil { return err } + printerCloseOnce := sync.Once{} + defer func() { + printerCloseOnce.Do(func() { + if err1 := printer.Wait(); err == nil { + err = err1 + } + }) + }() // NOTE: buildx server has the current working directory different from the client // so we need to resolve paths to abosolute ones in the client. @@ -588,11 +620,7 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er } } - var resp *client.SolveResponse - ref, resp, err = c.Build(ctx, opts, pr, printer) - if err1 := printer.Wait(); err == nil { - err = err1 - } + ref, err = c.Build(ctx, opts, pr, printer) if err != nil { var be *controllererrors.BuildError if errors.As(err, &be) { @@ -610,22 +638,13 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er if err := pr.Close(); err != nil { 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 != nil && options.invoke.needsMonitor(retErr) { + // HACK: pause the printer to prevent interference with monitor + printer.Pause(true) + pr2, pw2 := io.Pipe() f.SetWriter(pw2, func() io.WriteCloser { pw2.Close() // propagate EOF @@ -646,11 +665,40 @@ func launchControllerAndRunBuild(dockerCli command.Cli, options buildOptions) er if err != nil { logrus.Warnf("failed to run monitor: %v", err) } - } else { - if err := c.Disconnect(ctx, ref); err != nil { - logrus.Warnf("disconnect error: %v", err) + + printer.Pause(false) + } + + resp, err := c.Finalize(ctx, ref) + printerCloseOnce.Do(func() { + if err1 := printer.Wait(); err == nil { + err = err1 } + }) + if err != nil { + return err } + 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) + } + if options.metadataFile != "" { + if err := writeMetadataFile(options.metadataFile, decodeExporterResponse(resp.ExporterResponse)); err != nil { + return err + } + } + if opts.PrintFunc != nil { + if err := printResult(opts.PrintFunc, resp.ExporterResponse); err != nil { + return err + } + } + return nil } @@ -964,3 +1012,65 @@ func printWarnings(w io.Writer, warnings []client.VertexWarning, mode string) { } } + +func printResult(f *controllerapi.PrintFunc, res map[string]string) error { + switch f.Name { + case "outline": + return printValue(outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version, f.Format, res) + case "targets": + return printValue(targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version, f.Format, res) + case "subrequests.describe": + return printValue(subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version, f.Format, res) + default: + if dt, ok := res["result.txt"]; ok { + fmt.Print(dt) + } else { + log.Printf("%s %+v", f, res) + } + } + return nil +} + +type printFunc func([]byte, io.Writer) error + +func printValue(printer printFunc, version string, format string, res map[string]string) error { + if format == "json" { + fmt.Fprintln(os.Stdout, 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"]) + return nil + } + return printer([]byte(res["result.json"]), os.Stdout) +} + +func parsePrintFunc(str string) (*controllerapi.PrintFunc, error) { + if str == "" { + return nil, nil + } + csvReader := csv.NewReader(strings.NewReader(str)) + fields, err := csvReader.Read() + if err != nil { + return nil, err + } + f := &controllerapi.PrintFunc{} + for _, field := range fields { + parts := strings.SplitN(field, "=", 2) + if len(parts) == 2 { + if parts[0] == "format" { + f.Format = parts[1] + } else { + return nil, errors.Errorf("invalid print field: %s", field) + } + } else { + if f.Name != "" { + return nil, errors.Errorf("invalid print value: %s", str) + } + f.Name = field + } + } + return f, nil +} diff --git a/controller/build/build.go b/controller/build/build.go index c519fa990c06..b4e999f746fc 100644 --- a/controller/build/build.go +++ b/controller/build/build.go @@ -2,14 +2,10 @@ package build import ( "context" - "encoding/base64" - "encoding/csv" - "encoding/json" "io" "os" "path/filepath" "strings" - "sync" "github.com/docker/buildx/build" "github.com/docker/buildx/builder" @@ -24,7 +20,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config" 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/session/auth/authprovider" @@ -36,13 +31,9 @@ import ( const defaultTargetName = "default" // RunBuild runs the specified build and returns the result. -// -// NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultContext, -// this function returns it in addition to the error (i.e. it does "return nil, res, err"). The caller can -// inspect the result and debug the cause of that error. -func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progress progress.Writer, generateResult bool) (*client.SolveResponse, *build.ResultContext, error) { +func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progress progress.Writer) (*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") + return nil, errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together") } contexts := map[string]build.NamedContext{} @@ -50,11 +41,6 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build contexts[name] = build.NamedContext{Path: path} } - printFunc, err := parsePrintFunc(in.PrintFunc) - if err != nil { - return nil, nil, err - } - opts := build.Options{ Inputs: build.Inputs{ ContextPath: in.ContextPath, @@ -73,12 +59,11 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build Tags: in.Tags, Target: in.Target, Ulimits: controllerUlimitOpt2DockerUlimit(in.Ulimits), - PrintFunc: printFunc, } platforms, err := platformutil.Parse(in.Platforms) if err != nil { - return nil, nil, err + return nil, err } opts.Platforms = platforms @@ -87,7 +72,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build secrets, err := controllerapi.CreateSecrets(in.Secrets) if err != nil { - return nil, nil, err + return nil, err } opts.Session = append(opts.Session, secrets) @@ -97,17 +82,17 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build } ssh, err := controllerapi.CreateSSH(sshSpecs) if err != nil { - return nil, nil, err + return nil, err } opts.Session = append(opts.Session, ssh) outputs, err := controllerapi.CreateExports(in.Exports) if err != nil { - return nil, nil, err + return nil, err } if in.ExportPush { if in.ExportLoad { - return nil, nil, errors.Errorf("push and load may not be set together at the moment") + return nil, errors.Errorf("push and load may not be set together at the moment") } if len(outputs) == 0 { outputs = []client.ExportEntry{{ @@ -121,7 +106,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build case "image": outputs[0].Attrs["push"] = "true" default: - return nil, nil, errors.Errorf("push and %q output can't be used together", outputs[0].Type) + return nil, errors.Errorf("push and %q output can't be used together", outputs[0].Type) } } } @@ -135,12 +120,19 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build switch outputs[0].Type { case "docker": default: - return nil, nil, errors.Errorf("load and %q output can't be used together", outputs[0].Type) + return nil, errors.Errorf("load and %q output can't be used together", outputs[0].Type) } } } opts.Exports = outputs + if in.PrintFunc != nil { + opts.PrintFunc = &build.PrintFunc{ + Name: in.PrintFunc.Name, + Format: in.PrintFunc.Format, + } + } + opts.CacheFrom = controllerapi.CreateCaches(in.CacheFrom) opts.CacheTo = controllerapi.CreateCaches(in.CacheTo) @@ -148,7 +140,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build allow, err := buildflags.ParseEntitlements(in.Allow) if err != nil { - return nil, nil, err + return nil, err } opts.Allow = allow @@ -164,120 +156,32 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build builder.WithContextPathHash(contextPathHash), ) if err != nil { - return nil, nil, err + return nil, err } if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil { - return nil, nil, errors.Wrapf(err, "failed to update builder last activity time") + return nil, errors.Wrapf(err, "failed to update builder last activity time") } nodes, err := b.LoadNodes(ctx, false) if err != nil { - return nil, nil, err + return nil, err } - resp, res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progress, in.MetadataFile, generateResult) + res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progress, in.MetadataFile) err = wrapBuildError(err, false) if err != nil { - // NOTE: buildTargets can return *build.ResultContext even on error. - return nil, res, err + return nil, err } - return resp, res, nil + return res[defaultTargetName], nil } // buildTargets runs the specified build and returns the result. -// -// NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultContext, -// this function returns it in addition to the error (i.e. it does "return nil, res, err"). The caller can -// inspect the result and debug the cause of that error. -func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer, metadataFile string, generateResult bool) (*client.SolveResponse, *build.ResultContext, error) { - var res *build.ResultContext - var resp map[string]*client.SolveResponse - var err error - if generateResult { - var mu sync.Mutex - var idx int - resp, err = build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress, func(driverIndex int, gotRes *build.ResultContext) { - mu.Lock() - defer mu.Unlock() - if res == nil || driverIndex < idx { - idx, res = driverIndex, gotRes - } - }) - } else { - resp, err = build.Build(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress) - } - if err != nil { - return nil, res, err - } - - if len(metadataFile) > 0 && resp != nil { - if err := writeMetadataFile(metadataFile, decodeExporterResponse(resp[defaultTargetName].ExporterResponse)); err != nil { - return nil, nil, err - } - } - - for k := range resp { - if opts[k].PrintFunc != nil { - if err := printResult(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil { - return nil, nil, err - } - } - } - - return resp[defaultTargetName], res, err -} - -func parsePrintFunc(str string) (*build.PrintFunc, error) { - if str == "" { - return nil, nil - } - csvReader := csv.NewReader(strings.NewReader(str)) - fields, err := csvReader.Read() +func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer, metadataFile string) (map[string]*build.ResultContext, error) { + res, err := build.BuildResults(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress) if err != nil { return nil, err } - f := &build.PrintFunc{} - for _, field := range fields { - parts := strings.SplitN(field, "=", 2) - if len(parts) == 2 { - if parts[0] == "format" { - f.Format = parts[1] - } else { - return nil, errors.Errorf("invalid print field: %s", field) - } - } else { - if f.Name != "" { - return nil, errors.Errorf("invalid print value: %s", str) - } - f.Name = field - } - } - return f, nil -} - -func writeMetadataFile(filename string, dt interface{}) error { - b, err := json.MarshalIndent(dt, "", " ") - if err != nil { - return err - } - return ioutils.AtomicWriteFile(filename, b, 0644) -} -func decodeExporterResponse(exporterResponse map[string]string) map[string]interface{} { - out := make(map[string]interface{}) - for k, v := range exporterResponse { - dt, err := base64.StdEncoding.DecodeString(v) - if err != nil { - out[k] = v - continue - } - var raw map[string]interface{} - if err = json.Unmarshal(dt, &raw); err != nil || len(raw) == 0 { - out[k] = v - continue - } - out[k] = json.RawMessage(dt) - } - return out + return res, err } func wrapBuildError(err error, bake bool) error { diff --git a/controller/build/print.go b/controller/build/print.go deleted file mode 100644 index 6817e5e91384..000000000000 --- a/controller/build/print.go +++ /dev/null @@ -1,48 +0,0 @@ -package build - -import ( - "fmt" - "io" - "log" - "os" - - "github.com/docker/buildx/build" - "github.com/docker/docker/api/types/versions" - "github.com/moby/buildkit/frontend/subrequests" - "github.com/moby/buildkit/frontend/subrequests/outline" - "github.com/moby/buildkit/frontend/subrequests/targets" -) - -func printResult(f *build.PrintFunc, res map[string]string) error { - switch f.Name { - case "outline": - return printValue(outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version, f.Format, res) - case "targets": - return printValue(targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version, f.Format, res) - case "subrequests.describe": - return printValue(subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version, f.Format, res) - default: - if dt, ok := res["result.txt"]; ok { - fmt.Print(dt) - } else { - log.Printf("%s %+v", f, res) - } - } - return nil -} - -type printFunc func([]byte, io.Writer) error - -func printValue(printer printFunc, version string, format string, res map[string]string) error { - if format == "json" { - fmt.Fprintln(os.Stdout, 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"]) - return nil - } - return printer([]byte(res["result.json"]), os.Stdout) -} diff --git a/controller/control/controller.go b/controller/control/controller.go index bdc5b7f891ef..748d9236826f 100644 --- a/controller/control/controller.go +++ b/controller/control/controller.go @@ -10,19 +10,23 @@ import ( ) type BuildxController interface { - Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, progress progress.Writer) (ref string, resp *client.SolveResponse, err error) + Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, progress progress.Writer) (string, 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. // NOTE: If needed, in the future, we can split this API into three APIs (NewContainer, NewProcess and Attach). Invoke(ctx context.Context, ref, pid string, options controllerapi.InvokeConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error - Kill(ctx context.Context) error - Close() error - List(ctx context.Context) (refs []string, _ error) + Finalize(ctx context.Context, ref string) (*client.SolveResponse, error) Disconnect(ctx context.Context, ref string) error - ListProcesses(ctx context.Context, ref string) (infos []*controllerapi.ProcessInfo, retErr error) - DisconnectProcess(ctx context.Context, ref, pid string) error + Inspect(ctx context.Context, ref string) (*controllerapi.InspectResponse, error) + List(ctx context.Context) ([]string, error) + + ListProcesses(ctx context.Context, ref string) ([]*controllerapi.ProcessInfo, error) + DisconnectProcess(ctx context.Context, ref, pid string) error + + Kill(ctx context.Context) error + Close() error } type ControlOptions struct { diff --git a/controller/local/controller.go b/controller/local/controller.go index 2bce2b28c622..166b565818cb 100644 --- a/controller/local/controller.go +++ b/controller/local/controller.go @@ -42,27 +42,27 @@ type localController struct { buildOnGoing atomic.Bool } -func (b *localController) Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, progress progress.Writer) (string, *client.SolveResponse, error) { +func (b *localController) Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, progress progress.Writer) (string, error) { if !b.buildOnGoing.CompareAndSwap(false, true) { - return "", nil, errors.New("build ongoing") + return "", errors.New("build ongoing") } defer b.buildOnGoing.Store(false) - resp, res, buildErr := cbuild.RunBuild(ctx, b.dockerCli, options, in, progress, true) - // NOTE: RunBuild can return *build.ResultContext even on error. + res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, progress) + if err != nil { + return "", err + } if res != nil { b.buildConfig = buildConfig{ resultCtx: res, buildOptions: &options, } + _, buildErr := b.buildConfig.resultCtx.Result(ctx) if buildErr != nil { - buildErr = controllererrors.WrapBuild(buildErr, b.ref) + return "", controllererrors.WrapBuild(buildErr, b.ref) } } - if buildErr != nil { - return "", nil, buildErr - } - return b.ref, resp, nil + return b.ref, nil } func (b *localController) ListProcesses(ctx context.Context, ref string) (infos []*controllerapi.ProcessInfo, retErr error) { @@ -123,7 +123,7 @@ func (b *localController) Kill(context.Context) error { func (b *localController) Close() error { b.cancelRunningProcesses() if b.buildConfig.resultCtx != nil { - b.buildConfig.resultCtx.Done() + b.buildConfig.resultCtx.Close() } // TODO: cancel ongoing builds? return nil @@ -133,9 +133,17 @@ func (b *localController) List(ctx context.Context) (res []string, _ error) { return []string{b.ref}, nil } +func (b *localController) Finalize(ctx context.Context, key string) (*client.SolveResponse, error) { + b.cancelRunningProcesses() + + if b.buildConfig.resultCtx != nil { + return b.buildConfig.resultCtx.Wait(ctx) + } + return nil, nil +} + func (b *localController) Disconnect(ctx context.Context, key string) error { - b.Close() - return nil + return b.Close() } func (b *localController) Inspect(ctx context.Context, ref string) (*controllerapi.InspectResponse, error) { diff --git a/controller/pb/controller.pb.go b/controller/pb/controller.pb.go index e9b0969ff72f..f3759e5e40a1 100644 --- a/controller/pb/controller.pb.go +++ b/controller/pb/controller.pb.go @@ -272,7 +272,7 @@ 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"` + PrintFunc *PrintFunc `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"` @@ -341,11 +341,11 @@ func (m *BuildOptions) GetDockerfileName() string { return "" } -func (m *BuildOptions) GetPrintFunc() string { +func (m *BuildOptions) GetPrintFunc() *PrintFunc { if m != nil { return m.PrintFunc } - return "" + return nil } func (m *BuildOptions) GetNamedContexts() map[string]string { @@ -523,6 +523,128 @@ func (m *BuildOptions) GetExportLoad() bool { return false } +type FinalizeRequest struct { + Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FinalizeRequest) Reset() { *m = FinalizeRequest{} } +func (m *FinalizeRequest) String() string { return proto.CompactTextString(m) } +func (*FinalizeRequest) ProtoMessage() {} +func (*FinalizeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ed7f10298fa1d90f, []int{7} +} +func (m *FinalizeRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FinalizeRequest.Unmarshal(m, b) +} +func (m *FinalizeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FinalizeRequest.Marshal(b, m, deterministic) +} +func (m *FinalizeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinalizeRequest.Merge(m, src) +} +func (m *FinalizeRequest) XXX_Size() int { + return xxx_messageInfo_FinalizeRequest.Size(m) +} +func (m *FinalizeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_FinalizeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_FinalizeRequest proto.InternalMessageInfo + +func (m *FinalizeRequest) GetRef() string { + if m != nil { + return m.Ref + } + return "" +} + +type FinalizeResponse 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:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FinalizeResponse) Reset() { *m = FinalizeResponse{} } +func (m *FinalizeResponse) String() string { return proto.CompactTextString(m) } +func (*FinalizeResponse) ProtoMessage() {} +func (*FinalizeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ed7f10298fa1d90f, []int{8} +} +func (m *FinalizeResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FinalizeResponse.Unmarshal(m, b) +} +func (m *FinalizeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FinalizeResponse.Marshal(b, m, deterministic) +} +func (m *FinalizeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinalizeResponse.Merge(m, src) +} +func (m *FinalizeResponse) XXX_Size() int { + return xxx_messageInfo_FinalizeResponse.Size(m) +} +func (m *FinalizeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_FinalizeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_FinalizeResponse proto.InternalMessageInfo + +func (m *FinalizeResponse) GetExporterResponse() map[string]string { + if m != nil { + return m.ExporterResponse + } + return nil +} + +type PrintFunc struct { + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + Format string `protobuf:"bytes,2,opt,name=Format,proto3" json:"Format,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PrintFunc) Reset() { *m = PrintFunc{} } +func (m *PrintFunc) String() string { return proto.CompactTextString(m) } +func (*PrintFunc) ProtoMessage() {} +func (*PrintFunc) Descriptor() ([]byte, []int) { + return fileDescriptor_ed7f10298fa1d90f, []int{9} +} +func (m *PrintFunc) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PrintFunc.Unmarshal(m, b) +} +func (m *PrintFunc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PrintFunc.Marshal(b, m, deterministic) +} +func (m *PrintFunc) XXX_Merge(src proto.Message) { + xxx_messageInfo_PrintFunc.Merge(m, src) +} +func (m *PrintFunc) XXX_Size() int { + return xxx_messageInfo_PrintFunc.Size(m) +} +func (m *PrintFunc) XXX_DiscardUnknown() { + xxx_messageInfo_PrintFunc.DiscardUnknown(m) +} + +var xxx_messageInfo_PrintFunc proto.InternalMessageInfo + +func (m *PrintFunc) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *PrintFunc) GetFormat() string { + if m != nil { + return m.Format + } + return "" +} + 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"` @@ -536,7 +658,7 @@ 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{7} + return fileDescriptor_ed7f10298fa1d90f, []int{10} } func (m *ExportEntry) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExportEntry.Unmarshal(m, b) @@ -589,7 +711,7 @@ 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{8} + return fileDescriptor_ed7f10298fa1d90f, []int{11} } func (m *CacheOptionsEntry) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CacheOptionsEntry.Unmarshal(m, b) @@ -636,7 +758,7 @@ 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{9} + return fileDescriptor_ed7f10298fa1d90f, []int{12} } func (m *Attest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Attest.Unmarshal(m, b) @@ -689,7 +811,7 @@ 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{10} + return fileDescriptor_ed7f10298fa1d90f, []int{13} } func (m *SSH) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SSH.Unmarshal(m, b) @@ -736,7 +858,7 @@ 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{11} + return fileDescriptor_ed7f10298fa1d90f, []int{14} } func (m *Secret) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Secret.Unmarshal(m, b) @@ -788,7 +910,7 @@ func (m *InspectRequest) Reset() { *m = InspectRequest{} } func (m *InspectRequest) String() string { return proto.CompactTextString(m) } func (*InspectRequest) ProtoMessage() {} func (*InspectRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{12} + return fileDescriptor_ed7f10298fa1d90f, []int{15} } func (m *InspectRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InspectRequest.Unmarshal(m, b) @@ -826,7 +948,7 @@ func (m *InspectResponse) Reset() { *m = InspectResponse{} } func (m *InspectResponse) String() string { return proto.CompactTextString(m) } func (*InspectResponse) ProtoMessage() {} func (*InspectResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ed7f10298fa1d90f, []int{13} + return fileDescriptor_ed7f10298fa1d90f, []int{16} } func (m *InspectResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InspectResponse.Unmarshal(m, b) @@ -864,7 +986,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{14} + return fileDescriptor_ed7f10298fa1d90f, []int{17} } func (m *UlimitOpt) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UlimitOpt.Unmarshal(m, b) @@ -904,7 +1026,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{15} + return fileDescriptor_ed7f10298fa1d90f, []int{18} } func (m *Ulimit) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Ulimit.Unmarshal(m, b) @@ -946,17 +1068,16 @@ func (m *Ulimit) GetSoft() int64 { } 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:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + 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{16} + return fileDescriptor_ed7f10298fa1d90f, []int{19} } func (m *BuildResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BuildResponse.Unmarshal(m, b) @@ -976,13 +1097,6 @@ 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:"-"` @@ -994,7 +1108,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{17} + return fileDescriptor_ed7f10298fa1d90f, []int{20} } func (m *DisconnectRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DisconnectRequest.Unmarshal(m, b) @@ -1031,7 +1145,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{18} + return fileDescriptor_ed7f10298fa1d90f, []int{21} } func (m *DisconnectResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DisconnectResponse.Unmarshal(m, b) @@ -1062,7 +1176,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{19} + return fileDescriptor_ed7f10298fa1d90f, []int{22} } func (m *ListRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListRequest.Unmarshal(m, b) @@ -1100,7 +1214,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{20} + return fileDescriptor_ed7f10298fa1d90f, []int{23} } func (m *ListResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListResponse.Unmarshal(m, b) @@ -1141,7 +1255,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{21} + return fileDescriptor_ed7f10298fa1d90f, []int{24} } func (m *InputMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InputMessage.Unmarshal(m, b) @@ -1215,7 +1329,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{22} + return fileDescriptor_ed7f10298fa1d90f, []int{25} } func (m *InputInitMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InputInitMessage.Unmarshal(m, b) @@ -1254,7 +1368,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{23} + return fileDescriptor_ed7f10298fa1d90f, []int{26} } func (m *DataMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DataMessage.Unmarshal(m, b) @@ -1298,7 +1412,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{24} + return fileDescriptor_ed7f10298fa1d90f, []int{27} } func (m *InputResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InputResponse.Unmarshal(m, b) @@ -1334,7 +1448,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{25} + return fileDescriptor_ed7f10298fa1d90f, []int{28} } func (m *Message) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Message.Unmarshal(m, b) @@ -1436,7 +1550,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{26} + return fileDescriptor_ed7f10298fa1d90f, []int{29} } func (m *InitMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMessage.Unmarshal(m, b) @@ -1497,7 +1611,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{27} + return fileDescriptor_ed7f10298fa1d90f, []int{30} } func (m *InvokeConfig) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InvokeConfig.Unmarshal(m, b) @@ -1600,7 +1714,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{28} + return fileDescriptor_ed7f10298fa1d90f, []int{31} } func (m *FdMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FdMessage.Unmarshal(m, b) @@ -1653,7 +1767,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{29} + return fileDescriptor_ed7f10298fa1d90f, []int{32} } func (m *ResizeMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResizeMessage.Unmarshal(m, b) @@ -1700,7 +1814,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{30} + return fileDescriptor_ed7f10298fa1d90f, []int{33} } func (m *SignalMessage) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SignalMessage.Unmarshal(m, b) @@ -1738,7 +1852,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{31} + return fileDescriptor_ed7f10298fa1d90f, []int{34} } func (m *StatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatusRequest.Unmarshal(m, b) @@ -1779,7 +1893,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{32} + return fileDescriptor_ed7f10298fa1d90f, []int{35} } func (m *StatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatusResponse.Unmarshal(m, b) @@ -1837,7 +1951,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{33} + return fileDescriptor_ed7f10298fa1d90f, []int{36} } func (m *InfoRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InfoRequest.Unmarshal(m, b) @@ -1868,7 +1982,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{34} + return fileDescriptor_ed7f10298fa1d90f, []int{37} } func (m *InfoResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InfoResponse.Unmarshal(m, b) @@ -1908,7 +2022,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{35} + return fileDescriptor_ed7f10298fa1d90f, []int{38} } func (m *BuildxVersion) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BuildxVersion.Unmarshal(m, b) @@ -1960,6 +2074,10 @@ func init() { 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((*FinalizeRequest)(nil), "buildx.controller.v1.FinalizeRequest") + proto.RegisterType((*FinalizeResponse)(nil), "buildx.controller.v1.FinalizeResponse") + proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.FinalizeResponse.ExporterResponseEntry") + proto.RegisterType((*PrintFunc)(nil), "buildx.controller.v1.PrintFunc") 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") @@ -1973,7 +2091,6 @@ func init() { proto.RegisterMapType((map[string]*Ulimit)(nil), "buildx.controller.v1.UlimitOpt.ValuesEntry") proto.RegisterType((*Ulimit)(nil), "buildx.controller.v1.Ulimit") 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") @@ -1998,122 +2115,125 @@ func init() { func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) } var fileDescriptor_ed7f10298fa1d90f = []byte{ - // 1832 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x6f, 0xdb, 0xc8, - 0x11, 0x2f, 0x25, 0x59, 0x7f, 0x46, 0x96, 0xe3, 0x6c, 0x9d, 0xeb, 0x86, 0x49, 0x2f, 0x0e, 0x93, - 0xbb, 0x0a, 0x4d, 0x21, 0xdf, 0xf9, 0x7a, 0xcd, 0xe5, 0x72, 0x05, 0x6a, 0xcb, 0x16, 0xec, 0x43, - 0xfc, 0x07, 0x94, 0x93, 0x43, 0x5b, 0xa0, 0x07, 0x4a, 0x5a, 0xcb, 0x84, 0x28, 0xae, 0xca, 0x5d, - 0xd9, 0x56, 0x9f, 0xfa, 0xd2, 0xb7, 0xa2, 0xdf, 0xa3, 0xe8, 0x47, 0xe8, 0x53, 0xbf, 0x50, 0xd1, - 0xc7, 0x3e, 0x16, 0x3b, 0xbb, 0xa4, 0x28, 0x4b, 0x94, 0xed, 0xde, 0x93, 0x76, 0x86, 0xbf, 0xdf, - 0xec, 0xce, 0x70, 0x76, 0x66, 0x44, 0x58, 0xef, 0xf2, 0x50, 0x46, 0x3c, 0x08, 0x58, 0xd4, 0x18, - 0x45, 0x5c, 0x72, 0xb2, 0xd1, 0x19, 0xfb, 0x41, 0xef, 0xba, 0x91, 0x7a, 0x70, 0xf9, 0xb9, 0xfd, - 0xb6, 0xef, 0xcb, 0x8b, 0x71, 0xa7, 0xd1, 0xe5, 0xc3, 0xad, 0x21, 0xef, 0x4c, 0xb6, 0x10, 0x35, - 0xf0, 0xe5, 0x96, 0x37, 0xf2, 0xb7, 0x04, 0x8b, 0x2e, 0xfd, 0x2e, 0x13, 0x5b, 0x86, 0x14, 0xff, - 0x6a, 0x93, 0x4e, 0x1d, 0x36, 0xde, 0xf9, 0x42, 0x9e, 0x46, 0xbc, 0xcb, 0x84, 0x60, 0xc2, 0x65, - 0x7f, 0x1c, 0x33, 0x21, 0xc9, 0x3a, 0xe4, 0x5d, 0x76, 0x4e, 0xad, 0x4d, 0xab, 0x5e, 0x71, 0xd5, - 0xd2, 0x39, 0x85, 0x47, 0x37, 0x90, 0x62, 0xc4, 0x43, 0xc1, 0xc8, 0x6b, 0x58, 0x39, 0x0c, 0xcf, - 0xb9, 0xa0, 0xd6, 0x66, 0xbe, 0x5e, 0xdd, 0x7e, 0xde, 0x58, 0x74, 0xca, 0x86, 0xe1, 0x29, 0xa4, - 0xab, 0xf1, 0x8e, 0x80, 0x6a, 0x4a, 0x4b, 0x9e, 0x42, 0x25, 0x16, 0xf7, 0xcc, 0xc6, 0x53, 0x05, - 0x69, 0xc1, 0xea, 0x61, 0x78, 0xc9, 0x07, 0xac, 0xc9, 0xc3, 0x73, 0xbf, 0x4f, 0x73, 0x9b, 0x56, - 0xbd, 0xba, 0xed, 0x2c, 0xde, 0x2c, 0x8d, 0x74, 0x67, 0x78, 0xce, 0xb7, 0x40, 0xf7, 0x7c, 0xd1, - 0xe5, 0x61, 0xc8, 0xba, 0xb1, 0x33, 0x99, 0x4e, 0xcf, 0x9e, 0x29, 0x77, 0xe3, 0x4c, 0xce, 0x13, - 0x78, 0xbc, 0xc0, 0x96, 0x0e, 0x8b, 0xf3, 0x07, 0x58, 0xdd, 0x55, 0x67, 0xcb, 0x36, 0xfe, 0x0d, - 0x94, 0x4e, 0x46, 0xd2, 0xe7, 0xa1, 0x58, 0xee, 0x0d, 0x9a, 0x31, 0x48, 0x37, 0xa6, 0x38, 0xff, - 0x05, 0xb3, 0x81, 0x51, 0x90, 0x4d, 0xa8, 0x36, 0x79, 0x28, 0xd9, 0xb5, 0x3c, 0xf5, 0xe4, 0x85, - 0xd9, 0x28, 0xad, 0x22, 0x9f, 0xc2, 0xda, 0x1e, 0xef, 0x0e, 0x58, 0x74, 0xee, 0x07, 0xec, 0xd8, - 0x1b, 0x32, 0xe3, 0xd2, 0x0d, 0xad, 0xf6, 0xda, 0x0f, 0x65, 0x6b, 0x1c, 0x76, 0x69, 0x3e, 0xf6, - 0xda, 0x28, 0xc8, 0xef, 0xa1, 0xa6, 0x50, 0x3d, 0x63, 0x59, 0xd0, 0x02, 0xbe, 0xf7, 0x2f, 0x6f, - 0x3f, 0x7c, 0x63, 0x86, 0xb7, 0x1f, 0xca, 0x68, 0xe2, 0xce, 0xda, 0x22, 0x1b, 0xb0, 0xb2, 0x13, - 0x04, 0xfc, 0x8a, 0xae, 0x6c, 0xe6, 0xeb, 0x15, 0x57, 0x0b, 0xe4, 0x57, 0x50, 0xda, 0x91, 0x92, - 0x09, 0x29, 0x68, 0x11, 0x37, 0x7b, 0xba, 0x78, 0x33, 0x0d, 0x72, 0x63, 0x30, 0x39, 0x81, 0x0a, - 0xee, 0xbf, 0x13, 0xf5, 0x05, 0x2d, 0x21, 0xf3, 0xf3, 0x3b, 0x1c, 0x33, 0xe1, 0xe8, 0x23, 0x4e, - 0x6d, 0x90, 0x7d, 0xa8, 0x34, 0xbd, 0xee, 0x05, 0x6b, 0x45, 0x7c, 0x48, 0xcb, 0x68, 0xf0, 0x67, - 0x8b, 0x0d, 0x22, 0xcc, 0x18, 0x34, 0x66, 0x12, 0x26, 0xd9, 0x81, 0x12, 0x0a, 0x67, 0x9c, 0x56, - 0xee, 0x67, 0x24, 0xe6, 0x11, 0x07, 0x56, 0x9b, 0xfd, 0x88, 0x8f, 0x47, 0xa7, 0x5e, 0xc4, 0x42, - 0x49, 0x01, 0x5f, 0xd3, 0x8c, 0x8e, 0xbc, 0x85, 0xd2, 0xfe, 0xf5, 0x88, 0x47, 0x52, 0xd0, 0xea, - 0xb2, 0xbb, 0xa9, 0x41, 0x66, 0x03, 0xc3, 0x20, 0x1f, 0x03, 0xec, 0x5f, 0xcb, 0xc8, 0x3b, 0xe0, - 0x2a, 0xec, 0xab, 0xf8, 0x3a, 0x52, 0x1a, 0xd2, 0x82, 0xe2, 0x3b, 0xaf, 0xc3, 0x02, 0x41, 0x6b, - 0x68, 0xbb, 0x71, 0x87, 0xc0, 0x6a, 0x82, 0xde, 0xc8, 0xb0, 0x55, 0xda, 0x1e, 0x33, 0x79, 0xc5, - 0xa3, 0xc1, 0x11, 0xef, 0x31, 0xba, 0xa6, 0xd3, 0x36, 0xa5, 0x22, 0x2f, 0xa1, 0x76, 0xcc, 0x75, - 0xf0, 0xfc, 0x40, 0xb2, 0x88, 0x3e, 0xc0, 0xc3, 0xcc, 0x2a, 0x31, 0x69, 0x03, 0x4f, 0x9e, 0xf3, - 0x68, 0x28, 0xe8, 0x3a, 0x22, 0xa6, 0x0a, 0x95, 0x41, 0x6d, 0xd6, 0x8d, 0x98, 0x14, 0xf4, 0xe1, - 0xb2, 0x0c, 0xd2, 0x20, 0x37, 0x06, 0x13, 0x0a, 0xa5, 0xf6, 0xc5, 0xb0, 0xed, 0xff, 0x89, 0x51, - 0xb2, 0x69, 0xd5, 0xf3, 0x6e, 0x2c, 0x92, 0x57, 0x90, 0x6f, 0xb7, 0x0f, 0xe8, 0x8f, 0xd1, 0xda, - 0xe3, 0x0c, 0x6b, 0xed, 0x03, 0x57, 0xa1, 0x08, 0x81, 0xc2, 0x99, 0xd7, 0x17, 0x74, 0x03, 0xcf, - 0x85, 0x6b, 0xf2, 0x11, 0x14, 0xcf, 0xbc, 0xa8, 0xcf, 0x24, 0x7d, 0x84, 0x3e, 0x1b, 0x89, 0xbc, - 0x81, 0xd2, 0xfb, 0xc0, 0x1f, 0xfa, 0x52, 0xd0, 0x8f, 0xb0, 0x2c, 0x3c, 0x5b, 0x6c, 0x5c, 0x83, - 0x4e, 0x46, 0xd2, 0x8d, 0xf1, 0xea, 0xb4, 0x18, 0x6f, 0x16, 0xd1, 0x9f, 0xa0, 0xcd, 0x58, 0x54, - 0xe9, 0x72, 0xc4, 0xa4, 0xd7, 0xf3, 0xa4, 0xd7, 0xf2, 0x03, 0x46, 0xa9, 0x4e, 0x97, 0xb4, 0x4e, - 0xb1, 0x4d, 0x48, 0xe9, 0xe3, 0x4d, 0xab, 0x5e, 0x76, 0x63, 0x51, 0x1d, 0xff, 0x74, 0x1c, 0x04, - 0xd4, 0x46, 0x35, 0xae, 0x75, 0x7e, 0xa8, 0x54, 0x39, 0x1d, 0x8b, 0x0b, 0xfa, 0x04, 0x9f, 0xa4, - 0x34, 0xd3, 0xe7, 0xef, 0xb8, 0xd7, 0xa3, 0x4f, 0xd3, 0xcf, 0x95, 0xc6, 0xfe, 0x0d, 0x90, 0xf9, - 0x72, 0xa0, 0xaa, 0xe4, 0x80, 0x4d, 0xe2, 0x2a, 0x39, 0x60, 0x13, 0x55, 0x11, 0x2e, 0xbd, 0x60, - 0x1c, 0xd7, 0x2a, 0x2d, 0x7c, 0x9d, 0xfb, 0xca, 0xb2, 0xbf, 0x81, 0xb5, 0xd9, 0x9b, 0x7a, 0x2f, - 0xf6, 0x1b, 0xa8, 0xa6, 0xd2, 0xf1, 0x3e, 0x54, 0xe7, 0x5f, 0x16, 0x54, 0x53, 0x77, 0x06, 0xdf, - 0xee, 0x64, 0xc4, 0x0c, 0x19, 0xd7, 0x64, 0x17, 0x56, 0x76, 0xa4, 0x8c, 0x54, 0x69, 0x57, 0x09, - 0xf2, 0x8b, 0x5b, 0x6f, 0x5e, 0x03, 0xe1, 0xfa, 0x6e, 0x68, 0xaa, 0xba, 0x1a, 0x7b, 0x4c, 0x48, - 0x3f, 0xf4, 0xd4, 0xf5, 0x31, 0x95, 0x38, 0xad, 0xb2, 0xbf, 0x02, 0x98, 0xd2, 0xee, 0xe5, 0xc3, - 0x3f, 0x2c, 0x78, 0x38, 0x57, 0x5e, 0x16, 0x7a, 0x72, 0x30, 0xeb, 0xc9, 0xf6, 0x1d, 0x4b, 0xd5, - 0xbc, 0x3f, 0x3f, 0xe0, 0xb4, 0xc7, 0x50, 0xd4, 0x35, 0x7d, 0xe1, 0x09, 0x6d, 0x28, 0xef, 0xf9, - 0xc2, 0xeb, 0x04, 0xac, 0x87, 0xd4, 0xb2, 0x9b, 0xc8, 0xd8, 0x50, 0xf0, 0xf4, 0x3a, 0x7a, 0x5a, - 0x70, 0xf4, 0xe5, 0x25, 0x6b, 0x90, 0x4b, 0x66, 0x8d, 0xdc, 0xe1, 0x9e, 0x02, 0xab, 0x46, 0xa9, - 0x5d, 0xad, 0xb8, 0x5a, 0x70, 0x5a, 0x50, 0xd4, 0xe5, 0x60, 0x0e, 0x6f, 0x43, 0x59, 0xdd, 0x1c, - 0xec, 0xb7, 0xfa, 0xcc, 0x89, 0xac, 0xdc, 0xdb, 0x0f, 0x2f, 0xcd, 0xb6, 0x6a, 0xe9, 0x38, 0xb0, - 0x76, 0x18, 0x8a, 0x11, 0xeb, 0xca, 0xec, 0x29, 0xeb, 0x04, 0x1e, 0x24, 0x18, 0x33, 0x5f, 0xa5, - 0xc6, 0x04, 0xeb, 0xfe, 0x63, 0xc2, 0xdf, 0x2d, 0xa8, 0x24, 0x95, 0x82, 0x34, 0xa1, 0x88, 0x41, - 0x8d, 0x87, 0xb5, 0x57, 0xb7, 0x94, 0x96, 0xc6, 0x07, 0x44, 0x9b, 0x8a, 0xad, 0xa9, 0xf6, 0x77, - 0x50, 0x4d, 0xa9, 0x17, 0xbc, 0xc7, 0xed, 0xf4, 0x7b, 0xcc, 0x2c, 0xb5, 0x7a, 0x93, 0xf4, 0x5b, - 0xde, 0x83, 0xa2, 0x56, 0xaa, 0xb7, 0x8c, 0xf3, 0x89, 0x79, 0xcb, 0x38, 0x95, 0x10, 0x28, 0x1c, - 0x78, 0x91, 0x7e, 0xc3, 0x79, 0x17, 0xd7, 0x4a, 0xd7, 0xe6, 0xe7, 0x12, 0xa3, 0x9c, 0x77, 0x71, - 0xed, 0xfc, 0xd3, 0x82, 0x9a, 0x99, 0xbc, 0x4c, 0x04, 0x19, 0xac, 0xeb, 0x8b, 0xc6, 0xa2, 0x58, - 0x67, 0xfc, 0x7f, 0xb3, 0x24, 0x94, 0x31, 0xb4, 0x71, 0x93, 0xab, 0xa3, 0x31, 0x67, 0xd2, 0x6e, - 0xc2, 0xa3, 0x85, 0xd0, 0x7b, 0x65, 0xfa, 0x27, 0xf0, 0x70, 0x3a, 0x53, 0x66, 0xe7, 0xc9, 0x06, - 0x90, 0x34, 0xcc, 0xcc, 0x9c, 0xcf, 0xa0, 0xaa, 0x66, 0xf4, 0x6c, 0x9a, 0x03, 0xab, 0x1a, 0x60, - 0x22, 0x43, 0xa0, 0x30, 0x60, 0x13, 0x9d, 0x0d, 0x15, 0x17, 0xd7, 0xce, 0xdf, 0x2c, 0x35, 0x6a, - 0x8f, 0xc6, 0xf2, 0x88, 0x09, 0xe1, 0xf5, 0x55, 0x02, 0x16, 0x0e, 0x43, 0x5f, 0x9a, 0xec, 0xfb, - 0x34, 0x6b, 0xe4, 0x1e, 0x8d, 0xa5, 0x82, 0x19, 0xd6, 0xc1, 0x8f, 0x5c, 0x64, 0x91, 0xd7, 0x50, - 0xd8, 0xf3, 0xa4, 0x67, 0x72, 0x21, 0x63, 0x02, 0x51, 0x88, 0x14, 0x51, 0x89, 0xbb, 0x25, 0xf5, - 0xbf, 0x62, 0x34, 0x96, 0xce, 0x4b, 0x58, 0xbf, 0x69, 0x7d, 0x81, 0x6b, 0x5f, 0x40, 0x35, 0x65, - 0x05, 0xaf, 0xdf, 0x49, 0x0b, 0x01, 0x65, 0x57, 0x2d, 0x95, 0xaf, 0xc9, 0x41, 0x56, 0xf5, 0x1e, - 0xce, 0x03, 0xa8, 0xa1, 0xe9, 0x24, 0x82, 0x7f, 0xce, 0x41, 0x29, 0x36, 0xf1, 0x7a, 0xc6, 0xef, - 0xe7, 0x59, 0x7e, 0xcf, 0xbb, 0xfc, 0x25, 0x14, 0xb0, 0xc9, 0xe6, 0x96, 0xb5, 0xef, 0x56, 0x2f, - 0x45, 0xc3, 0xfe, 0xfb, 0x6b, 0x28, 0xba, 0x4c, 0xa8, 0x51, 0x23, 0x8f, 0xc4, 0x17, 0x8b, 0x89, - 0x1a, 0x33, 0x25, 0x1b, 0x92, 0xa2, 0xb7, 0xfd, 0x7e, 0xe8, 0x05, 0xb4, 0xb0, 0x8c, 0xae, 0x31, - 0x29, 0xba, 0x56, 0x4c, 0xc3, 0xfd, 0x17, 0x0b, 0xaa, 0x4b, 0x43, 0xbd, 0xfc, 0x5f, 0xd1, 0xdc, - 0x3f, 0xb5, 0xfc, 0xff, 0xf9, 0x4f, 0xed, 0xdf, 0xd6, 0xac, 0x21, 0x9c, 0x28, 0xd4, 0x7d, 0x1a, - 0x71, 0x3f, 0x94, 0x26, 0x65, 0x53, 0x1a, 0x75, 0xd0, 0xe6, 0xb0, 0x67, 0x6a, 0xb7, 0x5a, 0x4e, - 0x6b, 0x70, 0xde, 0xd4, 0x60, 0x95, 0x04, 0xef, 0x05, 0x8b, 0x30, 0x44, 0x15, 0x17, 0xd7, 0x6a, - 0x10, 0x3b, 0xe6, 0xa8, 0x5d, 0xc1, 0x6c, 0x31, 0x12, 0xda, 0xbb, 0xea, 0xd1, 0xa2, 0x76, 0xbc, - 0x79, 0x85, 0xcd, 0xe4, 0x98, 0x2b, 0x5d, 0x09, 0x81, 0x5a, 0x50, 0xb8, 0x33, 0x39, 0xa1, 0x65, - 0x9d, 0x6a, 0x67, 0x72, 0xa2, 0xfa, 0x82, 0xcb, 0x83, 0xa0, 0xe3, 0x75, 0x07, 0xb4, 0xa2, 0x1b, - 0x52, 0x2c, 0xab, 0x29, 0x4b, 0x45, 0xd7, 0xf7, 0x02, 0x9c, 0xd9, 0xcb, 0x6e, 0x2c, 0x3a, 0x3b, - 0x50, 0x49, 0x92, 0x42, 0xb5, 0x9a, 0x56, 0x0f, 0x83, 0x5e, 0x73, 0x73, 0xad, 0x5e, 0x9c, 0xcf, - 0xb9, 0xf9, 0x7c, 0xce, 0xa7, 0xf2, 0xf9, 0x35, 0xd4, 0x66, 0xd2, 0x43, 0x81, 0x5c, 0x7e, 0x25, - 0x8c, 0x21, 0x5c, 0x2b, 0x5d, 0x93, 0x07, 0xfa, 0x4f, 0x67, 0xcd, 0xc5, 0xb5, 0xf3, 0x02, 0x6a, - 0x33, 0x89, 0xb1, 0xa8, 0x02, 0x3b, 0xcf, 0xa1, 0xd6, 0x96, 0x9e, 0x1c, 0x2f, 0xf9, 0x4a, 0xf0, - 0x1f, 0x0b, 0xd6, 0x62, 0x8c, 0xa9, 0x31, 0xbf, 0x84, 0xf2, 0x25, 0x8b, 0x24, 0xbb, 0x4e, 0xba, - 0x0e, 0x6d, 0x0c, 0x79, 0x67, 0xd2, 0x88, 0xbf, 0x53, 0xa8, 0x3c, 0xf8, 0x80, 0x08, 0x37, 0x41, - 0x92, 0xaf, 0xa1, 0x2c, 0xd0, 0x0e, 0x8b, 0x07, 0x8f, 0x8f, 0xb3, 0x58, 0x66, 0xbf, 0x04, 0x4f, - 0xb6, 0xa0, 0x10, 0xf0, 0xbe, 0xc0, 0xf7, 0x5e, 0xdd, 0x7e, 0x92, 0xc5, 0x7b, 0xc7, 0xfb, 0x2e, - 0x02, 0xc9, 0x5b, 0x28, 0x5f, 0x79, 0x51, 0xe8, 0x87, 0xfd, 0xf8, 0xdf, 0xec, 0xb3, 0x2c, 0xd2, - 0x77, 0x1a, 0xe7, 0x26, 0x04, 0xa7, 0xa6, 0xae, 0xcb, 0x39, 0x37, 0x31, 0x71, 0x7e, 0xab, 0xb2, - 0x56, 0x89, 0xc6, 0xfd, 0x43, 0xa8, 0xe9, 0xcc, 0xff, 0xc0, 0x22, 0xa1, 0xc6, 0x38, 0x6b, 0xd9, - 0xed, 0xdc, 0x4d, 0x43, 0xdd, 0x59, 0xa6, 0xf3, 0xbd, 0x69, 0x6c, 0xb1, 0x42, 0xe5, 0xd2, 0xc8, - 0xeb, 0x0e, 0xbc, 0x7e, 0xfc, 0x9e, 0x62, 0x51, 0x3d, 0xb9, 0x34, 0xfb, 0xe9, 0x0b, 0x1a, 0x8b, - 0x2a, 0x37, 0x23, 0x76, 0xe9, 0x8b, 0xe9, 0x44, 0x99, 0xc8, 0xdb, 0x7f, 0x2d, 0x01, 0x34, 0x93, - 0xf3, 0x90, 0x53, 0x58, 0xc1, 0xfd, 0x88, 0xb3, 0xb4, 0x4d, 0xa2, 0xdf, 0xf6, 0x8b, 0x3b, 0xb4, - 0x52, 0xf2, 0x41, 0x25, 0x3f, 0x8e, 0x37, 0xe4, 0x65, 0x56, 0x41, 0x48, 0x4f, 0x48, 0xf6, 0x27, - 0xb7, 0xa0, 0x8c, 0xdd, 0xf7, 0x50, 0xd4, 0x59, 0x40, 0xb2, 0xaa, 0x5e, 0x3a, 0x6f, 0xed, 0x97, - 0xcb, 0x41, 0xda, 0xe8, 0x67, 0x16, 0x71, 0x4d, 0x4d, 0x24, 0xce, 0x92, 0xa6, 0x67, 0x6e, 0x4c, - 0x56, 0x00, 0x66, 0xfa, 0x4b, 0xdd, 0x22, 0xdf, 0x42, 0x51, 0x57, 0x35, 0xf2, 0xd3, 0xc5, 0x84, - 0xd8, 0xde, 0xf2, 0xc7, 0x75, 0xeb, 0x33, 0x8b, 0x1c, 0x41, 0x41, 0xb5, 0x73, 0x92, 0xd1, 0x9b, - 0x52, 0xb3, 0x80, 0xed, 0x2c, 0x83, 0x98, 0x28, 0x7e, 0x0f, 0x30, 0x1d, 0x2a, 0x48, 0xc6, 0x37, - 0x89, 0xb9, 0xe9, 0xc4, 0xae, 0xdf, 0x0e, 0x34, 0x1b, 0x1c, 0xa9, 0x8e, 0x7a, 0xce, 0x49, 0x66, - 0x2f, 0x4d, 0xae, 0x91, 0xed, 0x2c, 0x83, 0x18, 0x73, 0x17, 0x50, 0x9b, 0xf9, 0x24, 0x49, 0x7e, - 0x9e, 0xed, 0xe4, 0xcd, 0x2f, 0x9c, 0xf6, 0xab, 0x3b, 0x61, 0xcd, 0x4e, 0x32, 0x3d, 0x95, 0x99, - 0xc7, 0xa4, 0x71, 0x9b, 0xdf, 0xb3, 0x9f, 0x17, 0xed, 0xad, 0x3b, 0xe3, 0xf5, 0xae, 0xbb, 0x85, - 0xdf, 0xe5, 0x46, 0x9d, 0x4e, 0x11, 0xbf, 0xd4, 0x7e, 0xf1, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xc2, 0xd5, 0x2b, 0x23, 0x10, 0x16, 0x00, 0x00, + // 1887 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x73, 0x1b, 0xb7, + 0x11, 0xef, 0x91, 0x14, 0xff, 0x2c, 0x45, 0x59, 0x46, 0xe5, 0x14, 0xa6, 0xdd, 0x58, 0x3e, 0xd9, + 0x2e, 0xa7, 0xee, 0x50, 0x89, 0xd2, 0x54, 0x49, 0xec, 0xcc, 0x54, 0xa2, 0xc4, 0x91, 0x32, 0xd6, + 0x9f, 0x39, 0xca, 0xce, 0xa4, 0x9d, 0x69, 0xe6, 0x48, 0x42, 0xd4, 0x0d, 0x8f, 0x07, 0xf6, 0x00, + 0x4a, 0xa2, 0x9f, 0xfa, 0xd2, 0xd7, 0xbe, 0xf7, 0x23, 0x74, 0xfa, 0x29, 0xfa, 0x69, 0xfa, 0xd6, + 0xe9, 0x47, 0xe8, 0x2c, 0x80, 0x3b, 0x1e, 0x45, 0x1e, 0x25, 0x35, 0x4f, 0x04, 0x96, 0xbf, 0xdf, + 0x62, 0x77, 0xb1, 0x58, 0x2c, 0x0e, 0x56, 0x3b, 0x3c, 0x90, 0x21, 0xf7, 0x7d, 0x16, 0xd6, 0x87, + 0x21, 0x97, 0x9c, 0xac, 0xb5, 0x47, 0x9e, 0xdf, 0xbd, 0xae, 0x27, 0xfe, 0xb8, 0xfc, 0xbc, 0xfa, + 0xa6, 0xe7, 0xc9, 0x8b, 0x51, 0xbb, 0xde, 0xe1, 0x83, 0xcd, 0x01, 0x6f, 0x8f, 0x37, 0x15, 0xaa, + 0xef, 0xc9, 0x4d, 0x77, 0xe8, 0x6d, 0x0a, 0x16, 0x5e, 0x7a, 0x1d, 0x26, 0x36, 0x0d, 0x29, 0xfa, + 0xd5, 0x2a, 0xed, 0x1a, 0xac, 0xbd, 0xf3, 0x84, 0x3c, 0x0d, 0x79, 0x87, 0x09, 0xc1, 0x84, 0xc3, + 0xfe, 0x3c, 0x62, 0x42, 0x92, 0x55, 0xc8, 0x3a, 0xec, 0x9c, 0x5a, 0xeb, 0x56, 0xad, 0xe4, 0xe0, + 0xd0, 0x3e, 0x85, 0x47, 0x37, 0x90, 0x62, 0xc8, 0x03, 0xc1, 0xc8, 0x36, 0x2c, 0x1d, 0x06, 0xe7, + 0x5c, 0x50, 0x6b, 0x3d, 0x5b, 0x2b, 0x6f, 0x3d, 0xaf, 0xcf, 0xb3, 0xb2, 0x6e, 0x78, 0x88, 0x74, + 0x34, 0xde, 0x16, 0x50, 0x4e, 0x48, 0xc9, 0x53, 0x28, 0x45, 0xd3, 0x3d, 0xb3, 0xf0, 0x44, 0x40, + 0x9a, 0xb0, 0x7c, 0x18, 0x5c, 0xf2, 0x3e, 0x6b, 0xf0, 0xe0, 0xdc, 0xeb, 0xd1, 0xcc, 0xba, 0x55, + 0x2b, 0x6f, 0xd9, 0xf3, 0x17, 0x4b, 0x22, 0x9d, 0x29, 0x9e, 0xfd, 0x1d, 0xd0, 0x3d, 0x4f, 0x74, + 0x78, 0x10, 0xb0, 0x4e, 0xe4, 0x4c, 0xaa, 0xd3, 0xd3, 0x36, 0x65, 0x6e, 0xd8, 0x64, 0x3f, 0x81, + 0xc7, 0x73, 0x74, 0xe9, 0xb0, 0xd8, 0x7f, 0x82, 0xe5, 0x5d, 0xb4, 0x2d, 0x5d, 0xf9, 0x5b, 0x28, + 0x9c, 0x0c, 0xa5, 0xc7, 0x03, 0xb1, 0xd8, 0x1b, 0xa5, 0xc6, 0x20, 0x9d, 0x88, 0x62, 0xff, 0xbd, + 0x6c, 0x16, 0x30, 0x02, 0xb2, 0x0e, 0xe5, 0x06, 0x0f, 0x24, 0xbb, 0x96, 0xa7, 0xae, 0xbc, 0x30, + 0x0b, 0x25, 0x45, 0xe4, 0x15, 0xac, 0xec, 0xf1, 0x4e, 0x9f, 0x85, 0xe7, 0x9e, 0xcf, 0x8e, 0xdd, + 0x01, 0x33, 0x2e, 0xdd, 0x90, 0x92, 0x6f, 0xd1, 0x6b, 0x2f, 0x90, 0xcd, 0x51, 0xd0, 0xa1, 0x59, + 0x65, 0xda, 0xb3, 0xb4, 0x5d, 0x35, 0x30, 0x67, 0xc2, 0x20, 0x7f, 0x84, 0x0a, 0xaa, 0xe9, 0x9a, + 0xa5, 0x05, 0xcd, 0xa9, 0xc4, 0xf8, 0xf2, 0x76, 0xef, 0xea, 0x53, 0xbc, 0xfd, 0x40, 0x86, 0x63, + 0x67, 0x5a, 0x17, 0x59, 0x83, 0xa5, 0x1d, 0xdf, 0xe7, 0x57, 0x74, 0x69, 0x3d, 0x5b, 0x2b, 0x39, + 0x7a, 0x42, 0x7e, 0x07, 0x85, 0x1d, 0x29, 0x99, 0x90, 0x82, 0xe6, 0xd5, 0x62, 0x4f, 0xe7, 0x2f, + 0xa6, 0x41, 0x4e, 0x04, 0x26, 0x27, 0x50, 0x52, 0xeb, 0xef, 0x84, 0x3d, 0x41, 0x0b, 0x8a, 0xf9, + 0xf9, 0x1d, 0xcc, 0x8c, 0x39, 0xda, 0xc4, 0x89, 0x0e, 0xb2, 0x0f, 0xa5, 0x86, 0xdb, 0xb9, 0x60, + 0xcd, 0x90, 0x0f, 0x68, 0x51, 0x29, 0xfc, 0xd5, 0x7c, 0x85, 0x0a, 0x66, 0x14, 0x1a, 0x35, 0x31, + 0x93, 0xec, 0x40, 0x41, 0x4d, 0xce, 0x38, 0x2d, 0xdd, 0x4f, 0x49, 0xc4, 0x23, 0x36, 0x2c, 0x37, + 0x7a, 0x21, 0x1f, 0x0d, 0x4f, 0xdd, 0x90, 0x05, 0x92, 0x82, 0xda, 0xea, 0x29, 0x19, 0x79, 0x03, + 0x85, 0xfd, 0xeb, 0x21, 0x0f, 0xa5, 0xa0, 0xe5, 0x45, 0x87, 0x57, 0x83, 0xcc, 0x02, 0x86, 0x41, + 0x3e, 0x05, 0xd8, 0xbf, 0x96, 0xa1, 0x7b, 0xc0, 0x31, 0xec, 0xcb, 0x6a, 0x3b, 0x12, 0x12, 0xd2, + 0x84, 0xfc, 0x3b, 0xb7, 0xcd, 0x7c, 0x41, 0x2b, 0x4a, 0x77, 0xfd, 0x0e, 0x81, 0xd5, 0x04, 0xbd, + 0x90, 0x61, 0x63, 0x5e, 0x1f, 0x33, 0x79, 0xc5, 0xc3, 0xfe, 0x11, 0xef, 0x32, 0xba, 0xa2, 0xf3, + 0x3a, 0x21, 0x22, 0x2f, 0xa0, 0x72, 0xcc, 0x75, 0xf0, 0x3c, 0x5f, 0xb2, 0x90, 0x3e, 0x50, 0xc6, + 0x4c, 0x0b, 0xd5, 0x59, 0xf6, 0x5d, 0x79, 0xce, 0xc3, 0x81, 0xa0, 0xab, 0x0a, 0x31, 0x11, 0x60, + 0x06, 0xb5, 0x58, 0x27, 0x64, 0x52, 0xd0, 0x87, 0x8b, 0x32, 0x48, 0x83, 0x9c, 0x08, 0x4c, 0x28, + 0x14, 0x5a, 0x17, 0x83, 0x96, 0xf7, 0x91, 0x51, 0xb2, 0x6e, 0xd5, 0xb2, 0x4e, 0x34, 0x25, 0xaf, + 0x21, 0xdb, 0x6a, 0x1d, 0xd0, 0x9f, 0x2b, 0x6d, 0x8f, 0x53, 0xb4, 0xb5, 0x0e, 0x1c, 0x44, 0x11, + 0x02, 0xb9, 0x33, 0xb7, 0x27, 0xe8, 0x9a, 0xb2, 0x4b, 0x8d, 0xc9, 0x27, 0x90, 0x3f, 0x73, 0xc3, + 0x1e, 0x93, 0xf4, 0x91, 0xf2, 0xd9, 0xcc, 0xc8, 0xd7, 0x50, 0x78, 0xef, 0x7b, 0x03, 0x4f, 0x0a, + 0xfa, 0xc9, 0xa2, 0xc3, 0xa9, 0x41, 0x27, 0x43, 0xe9, 0x44, 0x78, 0xb4, 0x56, 0xc5, 0x9b, 0x85, + 0xf4, 0x17, 0x4a, 0x67, 0x34, 0xc5, 0x74, 0x39, 0x62, 0xd2, 0xed, 0xba, 0xd2, 0x6d, 0x7a, 0x3e, + 0xa3, 0x54, 0xa7, 0x4b, 0x52, 0x86, 0x6c, 0x13, 0x52, 0xfa, 0x78, 0xdd, 0xaa, 0x15, 0x9d, 0x68, + 0x8a, 0xe6, 0x9f, 0x8e, 0x7c, 0x9f, 0x56, 0x95, 0x58, 0x8d, 0x75, 0x7e, 0x60, 0xaa, 0x9c, 0x8e, + 0xc4, 0x05, 0x7d, 0xa2, 0xfe, 0x49, 0x48, 0x26, 0xff, 0xbf, 0xe3, 0x6e, 0x97, 0x3e, 0x4d, 0xfe, + 0x8f, 0x92, 0xea, 0xef, 0x81, 0xcc, 0x96, 0x03, 0x2c, 0xa3, 0x7d, 0x36, 0x8e, 0xca, 0x68, 0x9f, + 0x8d, 0xb1, 0x22, 0x5c, 0xba, 0xfe, 0x28, 0x2a, 0x66, 0x7a, 0xf2, 0x4d, 0xe6, 0x2b, 0xab, 0xfa, + 0x16, 0x56, 0xa6, 0x4f, 0xea, 0xbd, 0xd8, 0x5f, 0x43, 0x39, 0x91, 0x8e, 0xf7, 0xa1, 0xda, 0x1b, + 0xf0, 0xa0, 0xe9, 0x05, 0xae, 0xef, 0x7d, 0x64, 0xe9, 0x17, 0xea, 0xbf, 0x2c, 0x58, 0x9d, 0xa0, + 0xcc, 0x65, 0x7a, 0x01, 0xab, 0x3a, 0x04, 0x2c, 0x8c, 0x64, 0xe6, 0x5e, 0x7d, 0x3b, 0x7f, 0x93, + 0x6f, 0x6a, 0xa8, 0xdf, 0xa4, 0xeb, 0xc3, 0x34, 0xa3, 0xb5, 0xda, 0x80, 0x47, 0x73, 0xa1, 0xf7, + 0x72, 0x74, 0x3b, 0x71, 0x53, 0x60, 0x12, 0xa8, 0x4b, 0x45, 0x33, 0xd5, 0x18, 0x73, 0xb8, 0xc9, + 0xc3, 0x81, 0x2b, 0x0d, 0xd7, 0xcc, 0xd0, 0xf9, 0x72, 0xa2, 0xaa, 0xa8, 0xfc, 0x1f, 0x0f, 0x63, + 0x2e, 0x8e, 0xc9, 0x2e, 0x2c, 0xed, 0x48, 0x19, 0xe2, 0xed, 0x88, 0x01, 0xf8, 0xcd, 0xad, 0xb5, + 0xa9, 0xae, 0xe0, 0xda, 0x61, 0x4d, 0xc5, 0xe2, 0xb1, 0xc7, 0x84, 0xf4, 0x02, 0x17, 0x0b, 0x8c, + 0xba, 0xcc, 0x4a, 0x4e, 0x52, 0x54, 0xfd, 0x0a, 0x60, 0x42, 0xbb, 0x97, 0xf3, 0xff, 0xb4, 0xe0, + 0xe1, 0x4c, 0x01, 0x9e, 0xeb, 0xc9, 0xc1, 0xb4, 0x27, 0x5b, 0x77, 0x2c, 0xe6, 0xb3, 0xfe, 0xfc, + 0x04, 0x6b, 0x8f, 0x21, 0xaf, 0x6f, 0xbd, 0xb9, 0x16, 0x56, 0xa1, 0xb8, 0xe7, 0x09, 0xb7, 0xed, + 0xb3, 0xae, 0xa2, 0x16, 0x9d, 0x78, 0xae, 0xae, 0x5c, 0x65, 0xbd, 0x8e, 0x9e, 0x9e, 0xd8, 0xba, + 0xbc, 0x91, 0x15, 0xc8, 0xc4, 0xed, 0x5a, 0xe6, 0x70, 0x0f, 0xc1, 0xd8, 0x6b, 0x68, 0x57, 0x4b, + 0x8e, 0x9e, 0xd8, 0x4d, 0xc8, 0xeb, 0x82, 0x39, 0x83, 0xaf, 0x42, 0x11, 0x6b, 0x8b, 0x6a, 0x59, + 0xb4, 0xcd, 0xf1, 0x1c, 0xdd, 0xdb, 0x0f, 0x2e, 0xcd, 0xb2, 0x38, 0xb4, 0x6d, 0x58, 0x39, 0x0c, + 0xc4, 0x90, 0x75, 0x64, 0xfa, 0xb9, 0x3a, 0x81, 0x07, 0x31, 0xc6, 0x9c, 0xaa, 0x44, 0xa7, 0x65, + 0xdd, 0xbf, 0xd3, 0xfa, 0x87, 0x05, 0xa5, 0xb8, 0x96, 0x92, 0x06, 0xe4, 0x55, 0x50, 0xa3, 0x7e, + 0xf7, 0xf5, 0x2d, 0xc5, 0xb7, 0xfe, 0x41, 0xa1, 0xcd, 0x9d, 0xa6, 0xa9, 0xd5, 0xef, 0xa1, 0x9c, + 0x10, 0xcf, 0xd9, 0xc7, 0xad, 0xe4, 0x3e, 0xa6, 0x5e, 0x46, 0x7a, 0x91, 0xe4, 0x2e, 0xef, 0x41, + 0x5e, 0x0b, 0xe7, 0x9e, 0x46, 0x02, 0xb9, 0x03, 0x37, 0xd4, 0x3b, 0x9c, 0x75, 0xd4, 0x18, 0x65, + 0x2d, 0x7e, 0x2e, 0x55, 0x94, 0xb3, 0x8e, 0x1a, 0xdb, 0x0f, 0xa0, 0x62, 0x7a, 0x57, 0xd3, 0xcc, + 0xbe, 0x84, 0x87, 0x93, 0x4e, 0x37, 0x3d, 0xf4, 0x6b, 0x40, 0x92, 0x30, 0x43, 0x7e, 0x06, 0x65, + 0x7c, 0x39, 0xa4, 0xd3, 0x6c, 0x58, 0xd6, 0x00, 0xb3, 0x5d, 0x04, 0x72, 0x7d, 0x36, 0xd6, 0x01, + 0x2e, 0x39, 0x6a, 0x6c, 0xff, 0xcd, 0xc2, 0x07, 0xc0, 0x70, 0x24, 0x8f, 0x98, 0x10, 0x6e, 0x0f, + 0xf7, 0x34, 0x77, 0x18, 0x78, 0xd2, 0x6c, 0xe8, 0xab, 0xb4, 0x87, 0xc0, 0x70, 0x24, 0x11, 0x66, + 0x58, 0x07, 0x3f, 0x73, 0x14, 0x8b, 0x6c, 0x43, 0x6e, 0xcf, 0x95, 0xae, 0x09, 0x6f, 0x4a, 0xdb, + 0x83, 0x88, 0x04, 0x11, 0xa7, 0xbb, 0x05, 0x7c, 0xed, 0x0c, 0x47, 0xd2, 0x7e, 0x01, 0xab, 0x37, + 0xb5, 0xcf, 0x71, 0xed, 0x0b, 0x28, 0x27, 0xb4, 0xa8, 0x8c, 0x3e, 0x69, 0x2a, 0x40, 0xd1, 0xc1, + 0x21, 0xfa, 0x1a, 0x1b, 0xb2, 0xac, 0xd7, 0xc0, 0xf0, 0x2b, 0xd5, 0x71, 0x04, 0xff, 0x92, 0x81, + 0x42, 0xa4, 0x62, 0x7b, 0xca, 0xef, 0xe7, 0x69, 0x7e, 0xcf, 0xba, 0xfc, 0x25, 0xe4, 0xd4, 0xcd, + 0x9e, 0x59, 0xd4, 0x33, 0x34, 0xbb, 0x09, 0x9a, 0xba, 0xf4, 0xbf, 0x85, 0xbc, 0xc3, 0x04, 0xf6, + 0x37, 0xfa, 0x25, 0xb0, 0x31, 0x9f, 0xa8, 0x31, 0x13, 0xb2, 0x21, 0x21, 0xbd, 0xe5, 0xf5, 0x02, + 0xd7, 0xa7, 0xb9, 0x45, 0x74, 0x8d, 0x49, 0xd0, 0xb5, 0x60, 0x12, 0xee, 0xbf, 0x5a, 0x50, 0x5e, + 0x18, 0xea, 0xc5, 0x6f, 0xb5, 0x99, 0xf7, 0x63, 0xf6, 0xff, 0x7c, 0x3f, 0xfe, 0xc7, 0x9a, 0x56, + 0xa4, 0xda, 0x18, 0x3c, 0xc4, 0x43, 0xee, 0x05, 0xd2, 0xa4, 0x6c, 0x42, 0x82, 0x86, 0x36, 0x06, + 0x5d, 0x53, 0x0e, 0x71, 0x38, 0x29, 0x6b, 0x59, 0x53, 0xd6, 0x30, 0x09, 0xde, 0x0b, 0x16, 0xaa, + 0x10, 0x95, 0x1c, 0x35, 0xc6, 0x9b, 0xf3, 0x98, 0x2b, 0xe9, 0x92, 0xca, 0x16, 0x33, 0x53, 0xfa, + 0xae, 0xba, 0x34, 0xaf, 0x1d, 0x6f, 0x5c, 0xa9, 0xfa, 0x7c, 0xcc, 0x51, 0x56, 0x50, 0x40, 0x3d, + 0x41, 0xdc, 0x99, 0x1c, 0xd3, 0xa2, 0x4e, 0xb5, 0x33, 0x39, 0xc6, 0x52, 0xeb, 0x70, 0xdf, 0x6f, + 0xbb, 0x9d, 0x3e, 0x2d, 0xe9, 0x1a, 0x1f, 0xcd, 0xb1, 0xb5, 0xc3, 0xe8, 0x7a, 0xae, 0xaf, 0x1e, + 0x0a, 0x45, 0x27, 0x9a, 0xda, 0x3b, 0x50, 0x8a, 0x93, 0x02, 0xab, 0x77, 0xb3, 0xab, 0x82, 0x5e, + 0x71, 0x32, 0xcd, 0x6e, 0x94, 0xcf, 0x99, 0xd9, 0x7c, 0xce, 0x26, 0xf2, 0x79, 0x1b, 0x2a, 0x53, + 0xe9, 0x81, 0x20, 0x87, 0x5f, 0x09, 0xa3, 0x48, 0x8d, 0x51, 0xd6, 0xe0, 0xbe, 0x7e, 0x0a, 0x57, + 0x1c, 0x35, 0xb6, 0x37, 0xa0, 0x32, 0x95, 0x18, 0xf3, 0x8a, 0x9a, 0xfd, 0x1c, 0x2a, 0x2d, 0xe9, + 0xca, 0xd1, 0x82, 0x6f, 0x17, 0xff, 0xb5, 0x60, 0x25, 0xc2, 0x98, 0x1a, 0xf3, 0x5b, 0x28, 0x5e, + 0xb2, 0x50, 0xb2, 0xeb, 0xb8, 0x90, 0xd3, 0xfa, 0x80, 0xb7, 0xc7, 0xf5, 0xe8, 0xeb, 0x09, 0xe6, + 0xc1, 0x07, 0x85, 0x70, 0x62, 0x24, 0xf9, 0x06, 0x8a, 0x42, 0xe9, 0x61, 0xd1, 0x5d, 0xfe, 0x69, + 0x1a, 0xcb, 0xac, 0x17, 0xe3, 0xc9, 0x26, 0xe4, 0x7c, 0xde, 0x13, 0x6a, 0xdf, 0xcb, 0x5b, 0x4f, + 0xd2, 0x78, 0xef, 0x78, 0xcf, 0x51, 0x40, 0xf2, 0x06, 0x8a, 0x57, 0x6e, 0x18, 0x78, 0x41, 0x2f, + 0x7a, 0x42, 0x3f, 0x4b, 0x23, 0x7d, 0xaf, 0x71, 0x4e, 0x4c, 0xb0, 0x2b, 0x78, 0x5c, 0xce, 0xb9, + 0x89, 0x89, 0xfd, 0x03, 0x66, 0x2d, 0x4e, 0x8d, 0xfb, 0x87, 0x50, 0xd1, 0x99, 0xff, 0x81, 0x85, + 0x02, 0x3b, 0x23, 0x6b, 0xd1, 0xe9, 0xdc, 0x4d, 0x42, 0x9d, 0x69, 0xa6, 0xfd, 0xa3, 0xb9, 0x2c, + 0x22, 0x01, 0xe6, 0xd2, 0xd0, 0xed, 0xf4, 0xdd, 0x5e, 0xb4, 0x4f, 0xd1, 0x14, 0xff, 0xb9, 0x34, + 0xeb, 0xe9, 0x03, 0x1a, 0x4d, 0x31, 0x37, 0x43, 0x76, 0xe9, 0x89, 0x49, 0x93, 0x16, 0xcf, 0xb7, + 0xfe, 0x5d, 0x00, 0x68, 0xc4, 0xf6, 0x90, 0x23, 0x2c, 0x80, 0xe7, 0x9c, 0xa4, 0x96, 0xbe, 0xd8, + 0xeb, 0xaa, 0xbd, 0x08, 0x62, 0x22, 0x71, 0x0a, 0x4b, 0xca, 0x7c, 0xb2, 0xa8, 0x27, 0x88, 0x14, + 0x6e, 0x2c, 0xc4, 0x18, 0x8d, 0x3f, 0x60, 0x4b, 0xa3, 0xbb, 0x72, 0xf2, 0xf2, 0xb6, 0xae, 0x5d, + 0xeb, 0x7d, 0x75, 0xb7, 0xe6, 0x9e, 0x7c, 0x07, 0x79, 0x5d, 0x7c, 0xc8, 0x2f, 0xe7, 0x33, 0xcc, + 0x41, 0xa9, 0x2e, 0xfe, 0xbb, 0x66, 0x7d, 0x66, 0x91, 0x1f, 0x01, 0x26, 0x97, 0x35, 0x49, 0xf9, + 0xc0, 0x30, 0x73, 0xeb, 0x57, 0x6b, 0xb7, 0x03, 0x8d, 0xb1, 0xef, 0x21, 0xaf, 0x0f, 0x01, 0x49, + 0x2b, 0xfa, 0xc9, 0x63, 0x5b, 0x7d, 0xb1, 0x18, 0xa4, 0x95, 0x7e, 0x66, 0x91, 0x0f, 0x58, 0xaa, + 0x54, 0x7f, 0x47, 0x5e, 0xa4, 0xed, 0x6f, 0xb2, 0x45, 0xac, 0xbe, 0xbc, 0x05, 0x65, 0xcc, 0x3d, + 0x82, 0x1c, 0x76, 0x21, 0x69, 0x79, 0x95, 0x68, 0x61, 0xd2, 0xf2, 0x6a, 0xaa, 0x89, 0x71, 0xcc, + 0xcd, 0x45, 0xec, 0x05, 0xad, 0x49, 0xb4, 0x5d, 0x1b, 0x0b, 0x30, 0x91, 0xc6, 0x9a, 0x45, 0x2e, + 0xa0, 0x32, 0xf5, 0x0d, 0x96, 0xfc, 0x3a, 0xdd, 0x90, 0x9b, 0x9f, 0x74, 0xab, 0xaf, 0xef, 0x84, + 0x35, 0xd6, 0xcb, 0x64, 0xc3, 0x67, 0xfe, 0x26, 0xf5, 0xdb, 0xb6, 0x7e, 0xfa, 0x7b, 0x6a, 0x75, + 0xf3, 0xce, 0x78, 0xbd, 0xea, 0x6e, 0xee, 0x0f, 0x99, 0x61, 0xbb, 0x9d, 0x57, 0x9f, 0xa6, 0xbf, + 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x66, 0x27, 0x0f, 0x01, 0x17, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2128,14 +2248,15 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type ControllerClient interface { + Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResponse, error) Build(ctx context.Context, in *BuildRequest, opts ...grpc.CallOption) (*BuildResponse, error) - Inspect(ctx context.Context, in *InspectRequest, opts ...grpc.CallOption) (*InspectResponse, error) - Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (Controller_StatusClient, error) - Input(ctx context.Context, opts ...grpc.CallOption) (Controller_InputClient, error) + Finalize(ctx context.Context, in *FinalizeRequest, opts ...grpc.CallOption) (*FinalizeResponse, error) Invoke(ctx context.Context, opts ...grpc.CallOption) (Controller_InvokeClient, error) - List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) Disconnect(ctx context.Context, in *DisconnectRequest, opts ...grpc.CallOption) (*DisconnectResponse, error) - Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResponse, error) + Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (Controller_StatusClient, error) + Inspect(ctx context.Context, in *InspectRequest, opts ...grpc.CallOption) (*InspectResponse, error) + List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) + Input(ctx context.Context, opts ...grpc.CallOption) (Controller_InputClient, error) ListProcesses(ctx context.Context, in *ListProcessesRequest, opts ...grpc.CallOption) (*ListProcessesResponse, error) DisconnectProcess(ctx context.Context, in *DisconnectProcessRequest, opts ...grpc.CallOption) (*DisconnectProcessResponse, error) } @@ -2148,6 +2269,15 @@ func NewControllerClient(cc *grpc.ClientConn) ControllerClient { return &controllerClient{cc} } +func (c *controllerClient) Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResponse, error) { + out := new(InfoResponse) + err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Info", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *controllerClient) Build(ctx context.Context, in *BuildRequest, opts ...grpc.CallOption) (*BuildResponse, error) { out := new(BuildResponse) err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Build", in, out, opts...) @@ -2157,9 +2287,49 @@ func (c *controllerClient) Build(ctx context.Context, in *BuildRequest, opts ... return out, nil } -func (c *controllerClient) Inspect(ctx context.Context, in *InspectRequest, opts ...grpc.CallOption) (*InspectResponse, error) { - out := new(InspectResponse) - err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Inspect", in, out, opts...) +func (c *controllerClient) Finalize(ctx context.Context, in *FinalizeRequest, opts ...grpc.CallOption) (*FinalizeResponse, error) { + out := new(FinalizeResponse) + err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Finalize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controllerClient) Invoke(ctx context.Context, opts ...grpc.CallOption) (Controller_InvokeClient, error) { + stream, err := c.cc.NewStream(ctx, &_Controller_serviceDesc.Streams[0], "/buildx.controller.v1.Controller/Invoke", opts...) + if err != nil { + return nil, err + } + x := &controllerInvokeClient{stream} + return x, nil +} + +type Controller_InvokeClient interface { + Send(*Message) error + Recv() (*Message, error) + grpc.ClientStream +} + +type controllerInvokeClient struct { + grpc.ClientStream +} + +func (x *controllerInvokeClient) Send(m *Message) error { + return x.ClientStream.SendMsg(m) +} + +func (x *controllerInvokeClient) Recv() (*Message, error) { + m := new(Message) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *controllerClient) Disconnect(ctx context.Context, in *DisconnectRequest, opts ...grpc.CallOption) (*DisconnectResponse, error) { + out := new(DisconnectResponse) + err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Disconnect", in, out, opts...) if err != nil { return nil, err } @@ -2167,7 +2337,7 @@ func (c *controllerClient) Inspect(ctx context.Context, in *InspectRequest, opts } func (c *controllerClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (Controller_StatusClient, error) { - stream, err := c.cc.NewStream(ctx, &_Controller_serviceDesc.Streams[0], "/buildx.controller.v1.Controller/Status", opts...) + stream, err := c.cc.NewStream(ctx, &_Controller_serviceDesc.Streams[1], "/buildx.controller.v1.Controller/Status", opts...) if err != nil { return nil, err } @@ -2198,8 +2368,26 @@ func (x *controllerStatusClient) Recv() (*StatusResponse, error) { return m, nil } +func (c *controllerClient) Inspect(ctx context.Context, in *InspectRequest, opts ...grpc.CallOption) (*InspectResponse, error) { + out := new(InspectResponse) + err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Inspect", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controllerClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { + out := new(ListResponse) + err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/List", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *controllerClient) Input(ctx context.Context, opts ...grpc.CallOption) (Controller_InputClient, error) { - stream, err := c.cc.NewStream(ctx, &_Controller_serviceDesc.Streams[1], "/buildx.controller.v1.Controller/Input", opts...) + stream, err := c.cc.NewStream(ctx, &_Controller_serviceDesc.Streams[2], "/buildx.controller.v1.Controller/Input", opts...) if err != nil { return nil, err } @@ -2232,64 +2420,6 @@ func (x *controllerInputClient) CloseAndRecv() (*InputResponse, error) { return m, nil } -func (c *controllerClient) Invoke(ctx context.Context, opts ...grpc.CallOption) (Controller_InvokeClient, error) { - stream, err := c.cc.NewStream(ctx, &_Controller_serviceDesc.Streams[2], "/buildx.controller.v1.Controller/Invoke", opts...) - if err != nil { - return nil, err - } - x := &controllerInvokeClient{stream} - return x, nil -} - -type Controller_InvokeClient interface { - Send(*Message) error - Recv() (*Message, error) - grpc.ClientStream -} - -type controllerInvokeClient struct { - grpc.ClientStream -} - -func (x *controllerInvokeClient) Send(m *Message) error { - return x.ClientStream.SendMsg(m) -} - -func (x *controllerInvokeClient) Recv() (*Message, error) { - m := new(Message) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *controllerClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { - out := new(ListResponse) - err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/List", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *controllerClient) Disconnect(ctx context.Context, in *DisconnectRequest, opts ...grpc.CallOption) (*DisconnectResponse, error) { - out := new(DisconnectResponse) - err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Disconnect", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *controllerClient) Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResponse, error) { - out := new(InfoResponse) - err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/Info", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *controllerClient) ListProcesses(ctx context.Context, in *ListProcessesRequest, opts ...grpc.CallOption) (*ListProcessesResponse, error) { out := new(ListProcessesResponse) err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/ListProcesses", in, out, opts...) @@ -2310,14 +2440,15 @@ func (c *controllerClient) DisconnectProcess(ctx context.Context, in *Disconnect // ControllerServer is the server API for Controller service. type ControllerServer interface { + Info(context.Context, *InfoRequest) (*InfoResponse, error) Build(context.Context, *BuildRequest) (*BuildResponse, error) - Inspect(context.Context, *InspectRequest) (*InspectResponse, error) - Status(*StatusRequest, Controller_StatusServer) error - Input(Controller_InputServer) error + Finalize(context.Context, *FinalizeRequest) (*FinalizeResponse, error) Invoke(Controller_InvokeServer) error - List(context.Context, *ListRequest) (*ListResponse, error) Disconnect(context.Context, *DisconnectRequest) (*DisconnectResponse, error) - Info(context.Context, *InfoRequest) (*InfoResponse, error) + Status(*StatusRequest, Controller_StatusServer) error + Inspect(context.Context, *InspectRequest) (*InspectResponse, error) + List(context.Context, *ListRequest) (*ListResponse, error) + Input(Controller_InputServer) error ListProcesses(context.Context, *ListProcessesRequest) (*ListProcessesResponse, error) DisconnectProcess(context.Context, *DisconnectProcessRequest) (*DisconnectProcessResponse, error) } @@ -2326,29 +2457,32 @@ type ControllerServer interface { type UnimplementedControllerServer struct { } +func (*UnimplementedControllerServer) Info(ctx context.Context, req *InfoRequest) (*InfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Info not implemented") +} func (*UnimplementedControllerServer) Build(ctx context.Context, req *BuildRequest) (*BuildResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Build not implemented") } -func (*UnimplementedControllerServer) Inspect(ctx context.Context, req *InspectRequest) (*InspectResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Inspect not implemented") +func (*UnimplementedControllerServer) Finalize(ctx context.Context, req *FinalizeRequest) (*FinalizeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Finalize not implemented") +} +func (*UnimplementedControllerServer) Invoke(srv Controller_InvokeServer) error { + return status.Errorf(codes.Unimplemented, "method Invoke not implemented") +} +func (*UnimplementedControllerServer) Disconnect(ctx context.Context, req *DisconnectRequest) (*DisconnectResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Disconnect not implemented") } func (*UnimplementedControllerServer) Status(req *StatusRequest, srv Controller_StatusServer) error { return status.Errorf(codes.Unimplemented, "method Status not implemented") } -func (*UnimplementedControllerServer) Input(srv Controller_InputServer) error { - return status.Errorf(codes.Unimplemented, "method Input not implemented") -} -func (*UnimplementedControllerServer) Invoke(srv Controller_InvokeServer) error { - return status.Errorf(codes.Unimplemented, "method Invoke not implemented") +func (*UnimplementedControllerServer) Inspect(ctx context.Context, req *InspectRequest) (*InspectResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Inspect not implemented") } func (*UnimplementedControllerServer) List(ctx context.Context, req *ListRequest) (*ListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method List not implemented") } -func (*UnimplementedControllerServer) Disconnect(ctx context.Context, req *DisconnectRequest) (*DisconnectResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Disconnect not implemented") -} -func (*UnimplementedControllerServer) Info(ctx context.Context, req *InfoRequest) (*InfoResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Info not implemented") +func (*UnimplementedControllerServer) Input(srv Controller_InputServer) error { + return status.Errorf(codes.Unimplemented, "method Input not implemented") } func (*UnimplementedControllerServer) ListProcesses(ctx context.Context, req *ListProcessesRequest) (*ListProcessesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListProcesses not implemented") @@ -2361,6 +2495,24 @@ func RegisterControllerServer(s *grpc.Server, srv ControllerServer) { s.RegisterService(&_Controller_serviceDesc, srv) } +func _Controller_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControllerServer).Info(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/buildx.controller.v1.Controller/Info", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControllerServer).Info(ctx, req.(*InfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Controller_Build_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BuildRequest) if err := dec(in); err != nil { @@ -2379,71 +2531,24 @@ func _Controller_Build_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } -func _Controller_Inspect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(InspectRequest) +func _Controller_Finalize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FinalizeRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ControllerServer).Inspect(ctx, in) + return srv.(ControllerServer).Finalize(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/buildx.controller.v1.Controller/Inspect", + FullMethod: "/buildx.controller.v1.Controller/Finalize", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ControllerServer).Inspect(ctx, req.(*InspectRequest)) + return srv.(ControllerServer).Finalize(ctx, req.(*FinalizeRequest)) } return interceptor(ctx, in, info, handler) } -func _Controller_Status_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(StatusRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(ControllerServer).Status(m, &controllerStatusServer{stream}) -} - -type Controller_StatusServer interface { - Send(*StatusResponse) error - grpc.ServerStream -} - -type controllerStatusServer struct { - grpc.ServerStream -} - -func (x *controllerStatusServer) Send(m *StatusResponse) error { - return x.ServerStream.SendMsg(m) -} - -func _Controller_Input_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ControllerServer).Input(&controllerInputServer{stream}) -} - -type Controller_InputServer interface { - SendAndClose(*InputResponse) error - Recv() (*InputMessage, error) - grpc.ServerStream -} - -type controllerInputServer struct { - grpc.ServerStream -} - -func (x *controllerInputServer) SendAndClose(m *InputResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *controllerInputServer) Recv() (*InputMessage, error) { - m := new(InputMessage) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - func _Controller_Invoke_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(ControllerServer).Invoke(&controllerInvokeServer{stream}) } @@ -2470,60 +2575,107 @@ func (x *controllerInvokeServer) Recv() (*Message, error) { return m, nil } -func _Controller_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListRequest) +func _Controller_Disconnect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DisconnectRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ControllerServer).List(ctx, in) + return srv.(ControllerServer).Disconnect(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/buildx.controller.v1.Controller/List", + FullMethod: "/buildx.controller.v1.Controller/Disconnect", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ControllerServer).List(ctx, req.(*ListRequest)) + return srv.(ControllerServer).Disconnect(ctx, req.(*DisconnectRequest)) } return interceptor(ctx, in, info, handler) } -func _Controller_Disconnect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DisconnectRequest) +func _Controller_Status_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StatusRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ControllerServer).Status(m, &controllerStatusServer{stream}) +} + +type Controller_StatusServer interface { + Send(*StatusResponse) error + grpc.ServerStream +} + +type controllerStatusServer struct { + grpc.ServerStream +} + +func (x *controllerStatusServer) Send(m *StatusResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Controller_Inspect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InspectRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ControllerServer).Disconnect(ctx, in) + return srv.(ControllerServer).Inspect(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/buildx.controller.v1.Controller/Disconnect", + FullMethod: "/buildx.controller.v1.Controller/Inspect", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ControllerServer).Disconnect(ctx, req.(*DisconnectRequest)) + return srv.(ControllerServer).Inspect(ctx, req.(*InspectRequest)) } return interceptor(ctx, in, info, handler) } -func _Controller_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(InfoRequest) +func _Controller_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ControllerServer).Info(ctx, in) + return srv.(ControllerServer).List(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/buildx.controller.v1.Controller/Info", + FullMethod: "/buildx.controller.v1.Controller/List", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ControllerServer).Info(ctx, req.(*InfoRequest)) + return srv.(ControllerServer).List(ctx, req.(*ListRequest)) } return interceptor(ctx, in, info, handler) } +func _Controller_Input_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ControllerServer).Input(&controllerInputServer{stream}) +} + +type Controller_InputServer interface { + SendAndClose(*InputResponse) error + Recv() (*InputMessage, error) + grpc.ServerStream +} + +type controllerInputServer struct { + grpc.ServerStream +} + +func (x *controllerInputServer) SendAndClose(m *InputResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *controllerInputServer) Recv() (*InputMessage, error) { + m := new(InputMessage) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func _Controller_ListProcesses_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListProcessesRequest) if err := dec(in); err != nil { @@ -2564,25 +2716,29 @@ var _Controller_serviceDesc = grpc.ServiceDesc{ ServiceName: "buildx.controller.v1.Controller", HandlerType: (*ControllerServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "Info", + Handler: _Controller_Info_Handler, + }, { MethodName: "Build", Handler: _Controller_Build_Handler, }, { - MethodName: "Inspect", - Handler: _Controller_Inspect_Handler, - }, - { - MethodName: "List", - Handler: _Controller_List_Handler, + MethodName: "Finalize", + Handler: _Controller_Finalize_Handler, }, { MethodName: "Disconnect", Handler: _Controller_Disconnect_Handler, }, { - MethodName: "Info", - Handler: _Controller_Info_Handler, + MethodName: "Inspect", + Handler: _Controller_Inspect_Handler, + }, + { + MethodName: "List", + Handler: _Controller_List_Handler, }, { MethodName: "ListProcesses", @@ -2594,6 +2750,12 @@ var _Controller_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{ + { + StreamName: "Invoke", + Handler: _Controller_Invoke_Handler, + ServerStreams: true, + ClientStreams: true, + }, { StreamName: "Status", Handler: _Controller_Status_Handler, @@ -2604,12 +2766,6 @@ var _Controller_serviceDesc = grpc.ServiceDesc{ Handler: _Controller_Input_Handler, ClientStreams: true, }, - { - StreamName: "Invoke", - Handler: _Controller_Invoke_Handler, - ServerStreams: true, - ClientStreams: true, - }, }, Metadata: "controller.proto", } diff --git a/controller/pb/controller.proto b/controller/pb/controller.proto index 1d02c3852bd2..b141dc6e8271 100644 --- a/controller/pb/controller.proto +++ b/controller/pb/controller.proto @@ -7,14 +7,19 @@ import "github.com/moby/buildkit/api/services/control/control.proto"; option go_package = "pb"; service Controller { + rpc Info(InfoRequest) returns (InfoResponse); + rpc Build(BuildRequest) returns (BuildResponse); - rpc Inspect(InspectRequest) returns (InspectResponse); - rpc Status(StatusRequest) returns (stream StatusResponse); - rpc Input(stream InputMessage) returns (InputResponse); + rpc Finalize(FinalizeRequest) returns (FinalizeResponse); rpc Invoke(stream Message) returns (stream Message); - rpc List(ListRequest) returns (ListResponse); rpc Disconnect(DisconnectRequest) returns (DisconnectResponse); - rpc Info(InfoRequest) returns (InfoResponse); + rpc Status(StatusRequest) returns (stream StatusResponse); + + rpc Inspect(InspectRequest) returns (InspectResponse); + rpc List(ListRequest) returns (ListResponse); + + rpc Input(stream InputMessage) returns (InputResponse); + rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse); rpc DisconnectProcess(DisconnectProcessRequest) returns (DisconnectProcessResponse); } @@ -48,7 +53,7 @@ message BuildRequest { message BuildOptions { string ContextPath = 1; string DockerfileName = 2; - string PrintFunc = 3; + PrintFunc PrintFunc = 3; map NamedContexts = 4; repeated string Allow = 5; @@ -78,6 +83,19 @@ message BuildOptions { bool ExportLoad = 28; } +message FinalizeRequest { + string Ref = 1; +} + +message FinalizeResponse { + map ExporterResponse = 1; +} + +message PrintFunc { + string Name = 1; + string Format = 2; +} + message ExportEntry { string Type = 1; map Attrs = 2; @@ -125,7 +143,6 @@ message Ulimit { } message BuildResponse { - map ExporterResponse = 1; } message DisconnectRequest { diff --git a/controller/remote/client.go b/controller/remote/client.go index b3b6c12be2d0..6a173c970514 100644 --- a/controller/remote/client.go +++ b/controller/remote/client.go @@ -113,49 +113,30 @@ func (c *Client) Inspect(ctx context.Context, ref string) (*pb.InspectResponse, return c.client().Inspect(ctx, &pb.InspectRequest{Ref: ref}) } -func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, progress progress.Writer) (string, *client.SolveResponse, error) { +func (c *Client) Build(ctx context.Context, options pb.BuildOptions, in io.ReadCloser, progress progress.Writer) (string, error) { ref := identity.NewID() - statusChan := make(chan *client.SolveStatus) - 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 { - for s := range statusChan { - st := s - progress.Write(st) - } - return nil - }) - return ref, resp, eg.Wait() + if err := c.build(ctx, ref, options, in, progress); err != nil { + return "", err + } + return ref, nil } -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) Finalize(ctx context.Context, ref string) (*client.SolveResponse, error) { + resp, err := c.client().Finalize(ctx, &pb.FinalizeRequest{Ref: ref}) + if err != nil { + return nil, err + } + return &client.SolveResponse{ + ExporterResponse: resp.ExporterResponse, + }, nil +} + +func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, in io.ReadCloser, writer progress.Writer) error { eg, egCtx := errgroup.WithContext(ctx) done := make(chan struct{}) - var resp *client.SolveResponse - - eg.Go(func() error { - defer close(done) - pbResp, err := c.client().Build(egCtx, &pb.BuildRequest{ - Ref: ref, - Options: &options, - }) - if err != nil { - return err - } - resp = &client.SolveResponse{ - ExporterResponse: pbResp.ExporterResponse, - } - return nil - }) - eg.Go(func() error { - stream, err := c.client().Status(egCtx, &pb.StatusRequest{ + go func() error { + stream, err := c.client().Status(ctx, &pb.StatusRequest{ Ref: ref, }) if err != nil { @@ -169,8 +150,20 @@ func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, } return errors.Wrap(err, "failed to receive status") } - statusChan <- pb.FromControlStatus(resp) + writer.Write(pb.FromControlStatus(resp)) + } + }() + + eg.Go(func() error { + defer close(done) + _, err := c.client().Build(egCtx, &pb.BuildRequest{ + Ref: ref, + Options: &options, + }) + if err != nil { + return err } + return nil }) if in != nil { eg.Go(func() error { @@ -232,7 +225,7 @@ func (c *Client) build(ctx context.Context, ref string, options pb.BuildOptions, return eg2.Wait() }) } - return resp, eg.Wait() + return eg.Wait() } func (c *Client) client() pb.ControllerClient { diff --git a/controller/remote/controller.go b/controller/remote/controller.go index 60aaa852195e..0ebdc36ef21d 100644 --- a/controller/remote/controller.go +++ b/controller/remote/controller.go @@ -24,7 +24,6 @@ import ( "github.com/docker/buildx/util/progress" "github.com/docker/buildx/version" "github.com/docker/cli/cli/command" - "github.com/moby/buildkit/client" "github.com/moby/buildkit/util/grpcerrors" "github.com/pelletier/go-toml" "github.com/pkg/errors" @@ -143,8 +142,8 @@ func serveCmd(dockerCli command.Cli) *cobra.Command { }() // prepare server - b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, progress progress.Writer) (*client.SolveResponse, *build.ResultContext, error) { - return cbuild.RunBuild(ctx, dockerCli, *options, stdin, progress, true) + b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, progress progress.Writer) (*build.ResultContext, error) { + return cbuild.RunBuild(ctx, dockerCli, *options, stdin, progress) }) defer b.Close() diff --git a/controller/remote/server.go b/controller/remote/server.go index d89fc2180667..9fcfb4a3e478 100644 --- a/controller/remote/server.go +++ b/controller/remote/server.go @@ -4,7 +4,6 @@ import ( "context" "io" "sync" - "sync/atomic" "time" "github.com/docker/buildx/build" @@ -14,12 +13,11 @@ import ( "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/buildx/version" - "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, progress progress.Writer) (resp *client.SolveResponse, res *build.ResultContext, err error) +type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, progress progress.Writer) (res *build.ResultContext, err error) func NewServer(buildFunc BuildFunc) *Server { return &Server{ @@ -34,7 +32,6 @@ type Server struct { } type session struct { - buildOnGoing atomic.Bool statusChan chan *pb.StatusResponse cancelBuild func() buildOptions *pb.BuildOptions @@ -101,28 +98,6 @@ func (m *Server) List(ctx context.Context, req *pb.ListRequest) (res *pb.ListRes }, nil } -func (m *Server) Disconnect(ctx context.Context, req *pb.DisconnectRequest) (res *pb.DisconnectResponse, err error) { - key := req.Ref - if key == "" { - return nil, errors.New("disconnect: empty key") - } - - m.sessionMu.Lock() - if s, ok := m.session[key]; ok { - if s.cancelBuild != nil { - s.cancelBuild() - } - s.cancelRunningProcesses() - if s.result != nil { - s.result.Done() - } - } - delete(m.session, key) - m.sessionMu.Unlock() - - return &pb.DisconnectResponse{}, nil -} - func (m *Server) Close() error { m.sessionMu.Lock() for k := range m.session { @@ -167,15 +142,10 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp } s, ok := m.session[ref] if ok { - if !s.buildOnGoing.CompareAndSwap(false, true) { - m.sessionMu.Unlock() - return &pb.BuildResponse{}, errors.New("build ongoing") - } s.cancelRunningProcesses() s.result = nil } else { s = &session{} - s.buildOnGoing.Store(true) } s.processes = processes.NewManager() @@ -186,33 +156,24 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp s.inputPipe = inW m.session[ref] = s m.sessionMu.Unlock() - defer func() { - close(statusChan) - m.sessionMu.Lock() - s, ok := m.session[ref] - if ok { - s.statusChan = nil - s.buildOnGoing.Store(false) - } - m.sessionMu.Unlock() - }() pw := pb.NewProgressWriter(statusChan) // Build the specified request ctx, cancel := context.WithCancel(ctx) defer cancel() - resp, res, buildErr := m.buildFunc(ctx, req.Options, inR, pw) + res, err := m.buildFunc(ctx, req.Options, inR, pw) m.sessionMu.Lock() if s, ok := m.session[ref]; ok { - // NOTE: buildFunc can return *build.ResultContext even on error (e.g. when it's implemented using (github.com/docker/buildx/controller/build).RunBuild). if res != nil { s.result = res s.cancelBuild = cancel s.buildOptions = req.Options m.session[ref] = s + + _, buildErr := s.result.Result(ctx) if buildErr != nil { - buildErr = controllererrors.WrapBuild(buildErr, ref) + err = controllererrors.WrapBuild(buildErr, ref) } } } else { @@ -221,18 +182,69 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp } m.sessionMu.Unlock() - if buildErr != nil { - return nil, buildErr + if err != nil { + return nil, err + } + + return &pb.BuildResponse{}, nil +} + +func (m *Server) Finalize(ctx context.Context, req *pb.FinalizeRequest) (*pb.FinalizeResponse, error) { + key := req.Ref + if key == "" { + return nil, errors.New("finalize: empty key") } - if resp == nil { - resp = &client.SolveResponse{} + m.sessionMu.Lock() + defer m.sessionMu.Unlock() + + s, ok := m.session[key] + if !ok { + return nil, errors.Errorf("unknown ref %q", key) + } + if s.result == nil { + return nil, errors.Errorf("no build ongoing for %q", key) + } + resp, err := s.result.Wait(ctx) + if err != nil { + return nil, err + } + if s.cancelBuild != nil { + s.cancelBuild() } - return &pb.BuildResponse{ + s.cancelRunningProcesses() + close(s.statusChan) + delete(m.session, key) + + return &pb.FinalizeResponse{ ExporterResponse: resp.ExporterResponse, }, nil } +func (m *Server) Disconnect(ctx context.Context, req *pb.DisconnectRequest) (res *pb.DisconnectResponse, err error) { + key := req.Ref + if key == "" { + return nil, errors.New("disconnect: empty key") + } + + m.sessionMu.Lock() + defer m.sessionMu.Unlock() + + if s, ok := m.session[key]; ok { + if s.cancelBuild != nil { + s.cancelBuild() + } + close(s.statusChan) + s.cancelRunningProcesses() + if s.result != nil { + s.result.Close() + } + } + delete(m.session, key) + + return &pb.DisconnectResponse{}, nil +} + func (m *Server) Status(req *pb.StatusRequest, stream pb.Controller_StatusServer) error { ref := req.Ref if ref == "" { diff --git a/monitor/monitor.go b/monitor/monitor.go index d727d241c84a..995f16ea9c35 100644 --- a/monitor/monitor.go +++ b/monitor/monitor.go @@ -38,11 +38,6 @@ Available commands are: // RunMonitor provides an interactive session for running and managing containers via specified IO. func RunMonitor(ctx context.Context, curRef string, options *controllerapi.BuildOptions, invokeConfig controllerapi.InvokeConfig, c control.BuildxController, stdin io.ReadCloser, stdout io.WriteCloser, stderr console.File, progress progress.Writer) error { - defer func() { - if err := c.Disconnect(ctx, curRef); err != nil { - logrus.Warnf("disconnect error: %v", err) - } - }() monitorIn, monitorOut := ioset.Pipe() defer func() { monitorIn.Close() @@ -146,7 +141,7 @@ func RunMonitor(ctx context.Context, curRef string, options *controllerapi.Build } } var resultUpdated bool - ref, _, err := c.Build(ctx, *bo, nil, progress) // TODO: support stdin, hold build ref + ref, err := c.Build(ctx, *bo, nil, progress) // TODO: support stdin, hold build ref if err != nil { var be *controllererrors.BuildError if errors.As(err, &be) { diff --git a/util/progress/printer.go b/util/progress/printer.go index 14adfca8f222..8dbbaabae1da 100644 --- a/util/progress/printer.go +++ b/util/progress/printer.go @@ -29,6 +29,7 @@ type Printer struct { warnings []client.VertexWarning logMu sync.Mutex logSourceMap map[digest.Digest]interface{} + paused *bool } func (p *Printer) Wait() error { @@ -45,6 +46,10 @@ func (p *Printer) Warnings() []client.VertexWarning { return p.warnings } +func (p *Printer) Pause(v bool) { + *p.paused = v +} + func (p *Printer) ValidateLogSource(dgst digest.Digest, v interface{}) bool { p.logMu.Lock() defer p.logMu.Unlock() @@ -74,10 +79,12 @@ func NewPrinter(ctx context.Context, w io.Writer, out console.File, mode string, statusCh := make(chan *client.SolveStatus) doneCh := make(chan struct{}) + paused := false pw := &Printer{ status: statusCh, done: doneCh, logSourceMap: map[digest.Digest]interface{}{}, + paused: &paused, } if v := os.Getenv("BUILDKIT_PROGRESS"); v != "" && mode == PrinterModeAuto { @@ -101,7 +108,7 @@ func NewPrinter(ctx context.Context, w io.Writer, out console.File, mode string, go func() { resumeLogs := logutil.Pause(logrus.StandardLogger()) // not using shared context to not disrupt display but let is finish reporting errors - pw.warnings, pw.err = progressui.DisplaySolveStatus(ctx, c, w, statusCh, solveStatusOpt...) + pw.warnings, pw.err = progressui.DisplaySolveStatus(ctx, c, w, statusCh, pw.paused, solveStatusOpt...) resumeLogs() close(doneCh) }() diff --git a/vendor/github.com/moby/buildkit/util/progress/progressui/display.go b/vendor/github.com/moby/buildkit/util/progress/progressui/display.go index 5ba588c1c675..b5adfde437f9 100644 --- a/vendor/github.com/moby/buildkit/util/progress/progressui/display.go +++ b/vendor/github.com/moby/buildkit/util/progress/progressui/display.go @@ -42,7 +42,7 @@ func WithDesc(text string, console string) DisplaySolveStatusOpt { } } -func DisplaySolveStatus(ctx context.Context, c console.Console, w io.Writer, ch chan *client.SolveStatus, opts ...DisplaySolveStatusOpt) ([]client.VertexWarning, error) { +func DisplaySolveStatus(ctx context.Context, c console.Console, w io.Writer, ch chan *client.SolveStatus, paused *bool, opts ...DisplaySolveStatusOpt) ([]client.VertexWarning, error) { modeConsole := c != nil dsso := &displaySolveStatusOpts{} @@ -78,6 +78,11 @@ func DisplaySolveStatus(ctx context.Context, c console.Console, w io.Writer, ch displayLimiter := rate.NewLimiter(rate.Every(displayTimeout), 1) + ispaused := false + if paused != nil { + ispaused = *paused + } + var height int width, _ := disp.getSize() for { @@ -93,6 +98,10 @@ func DisplaySolveStatus(ctx context.Context, c console.Console, w io.Writer, ch } } + if paused != nil && *paused && ispaused { + continue + } + if modeConsole { width, height = disp.getSize() if done { @@ -115,6 +124,10 @@ func DisplaySolveStatus(ctx context.Context, c console.Console, w io.Writer, ch ticker = time.NewTicker(tickerTimeout) } } + + if paused != nil { + ispaused = *paused + } } } diff --git a/vendor/github.com/moby/buildkit/util/progress/progresswriter/printer.go b/vendor/github.com/moby/buildkit/util/progress/progresswriter/printer.go index c400e4121531..2b43c4500620 100644 --- a/vendor/github.com/moby/buildkit/util/progress/progresswriter/printer.go +++ b/vendor/github.com/moby/buildkit/util/progress/progresswriter/printer.go @@ -87,7 +87,7 @@ func NewPrinter(ctx context.Context, out console.File, mode string) (Writer, err go func() { // not using shared context to not disrupt display but let is finish reporting errors - _, pw.err = progressui.DisplaySolveStatus(ctx, c, out, statusCh) + _, pw.err = progressui.DisplaySolveStatus(ctx, c, out, statusCh, nil) close(doneCh) }() return pw, nil From fbc129d6134bca30772559f030c030c9624fcedd Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 19 Apr 2023 18:00:56 +0100 Subject: [PATCH 4/4] build: remove metadata-file from progress api Signed-off-by: Justin Chadwell --- commands/build.go | 8 -- commands/build_test.go | 9 -- controller/build/build.go | 5 +- controller/pb/controller.pb.go | 253 ++++++++++++++++----------------- controller/pb/controller.proto | 9 +- 5 files changed, 128 insertions(+), 156 deletions(-) diff --git a/commands/build.go b/commands/build.go index f0421c236892..9886b1fa0090 100644 --- a/commands/build.go +++ b/commands/build.go @@ -117,7 +117,6 @@ func (o *buildOptions) toControllerOptions() (controllerapi.BuildOptions, error) Target: o.target, Ulimits: dockerUlimitToControllerUlimit(o.ulimits), Builder: o.builder, - MetadataFile: o.metadataFile, NoCache: o.noCache, Pull: o.pull, ExportPush: o.exportPush, @@ -963,13 +962,6 @@ func resolvePaths(options *controllerapi.BuildOptions) (_ *controllerapi.BuildOp } options.SSH = ssh - if options.MetadataFile != "" { - options.MetadataFile, err = filepath.Abs(options.MetadataFile) - if err != nil { - return nil, err - } - } - return options, nil } diff --git a/commands/build_test.go b/commands/build_test.go index 7fa515dcfd05..7fa84772cd90 100644 --- a/commands/build_test.go +++ b/commands/build_test.go @@ -235,15 +235,6 @@ func TestResolvePaths(t *testing.T) { }, }, }, - { - name: "metadatafile", - options: controllerapi.BuildOptions{ - MetadataFile: "test1", - }, - want: controllerapi.BuildOptions{ - MetadataFile: filepath.Join(tmpwd, "test1"), - }, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/controller/build/build.go b/controller/build/build.go index b4e999f746fc..d38b8675ce0f 100644 --- a/controller/build/build.go +++ b/controller/build/build.go @@ -166,7 +166,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build return nil, err } - res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progress, in.MetadataFile) + res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progress) err = wrapBuildError(err, false) if err != nil { return nil, err @@ -175,12 +175,11 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build } // buildTargets runs the specified build and returns the result. -func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer, metadataFile string) (map[string]*build.ResultContext, error) { +func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer) (map[string]*build.ResultContext, error) { res, err := build.BuildResults(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress) if err != nil { return nil, err } - return res, err } diff --git a/controller/pb/controller.pb.go b/controller/pb/controller.pb.go index f3759e5e40a1..ea77237193e9 100644 --- a/controller/pb/controller.pb.go +++ b/controller/pb/controller.pb.go @@ -293,11 +293,10 @@ type BuildOptions struct { Target string `protobuf:"bytes,21,opt,name=Target,proto3" json:"Target,omitempty"` Ulimits *UlimitOpt `protobuf:"bytes,22,opt,name=Ulimits,proto3" json:"Ulimits,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"` + NoCache bool `protobuf:"varint,24,opt,name=NoCache,proto3" json:"NoCache,omitempty"` + Pull bool `protobuf:"varint,25,opt,name=Pull,proto3" json:"Pull,omitempty"` + ExportPush bool `protobuf:"varint,26,opt,name=ExportPush,proto3" json:"ExportPush,omitempty"` + ExportLoad bool `protobuf:"varint,27,opt,name=ExportLoad,proto3" json:"ExportLoad,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -488,13 +487,6 @@ func (m *BuildOptions) GetBuilder() string { return "" } -func (m *BuildOptions) GetMetadataFile() string { - if m != nil { - return m.MetadataFile - } - return "" -} - func (m *BuildOptions) GetNoCache() bool { if m != nil { return m.NoCache @@ -2115,125 +2107,124 @@ func init() { func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) } var fileDescriptor_ed7f10298fa1d90f = []byte{ - // 1887 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x73, 0x1b, 0xb7, - 0x11, 0xef, 0x91, 0x14, 0xff, 0x2c, 0x45, 0x59, 0x46, 0xe5, 0x14, 0xa6, 0xdd, 0x58, 0x3e, 0xd9, - 0x2e, 0xa7, 0xee, 0x50, 0x89, 0xd2, 0x54, 0x49, 0xec, 0xcc, 0x54, 0xa2, 0xc4, 0x91, 0x32, 0xd6, - 0x9f, 0x39, 0xca, 0xce, 0xa4, 0x9d, 0x69, 0xe6, 0x48, 0x42, 0xd4, 0x0d, 0x8f, 0x07, 0xf6, 0x00, - 0x4a, 0xa2, 0x9f, 0xfa, 0xd2, 0xd7, 0xbe, 0xf7, 0x23, 0x74, 0xfa, 0x29, 0xfa, 0x69, 0xfa, 0xd6, - 0xe9, 0x47, 0xe8, 0x2c, 0x80, 0x3b, 0x1e, 0x45, 0x1e, 0x25, 0x35, 0x4f, 0x04, 0x96, 0xbf, 0xdf, - 0x62, 0x77, 0xb1, 0x58, 0x2c, 0x0e, 0x56, 0x3b, 0x3c, 0x90, 0x21, 0xf7, 0x7d, 0x16, 0xd6, 0x87, - 0x21, 0x97, 0x9c, 0xac, 0xb5, 0x47, 0x9e, 0xdf, 0xbd, 0xae, 0x27, 0xfe, 0xb8, 0xfc, 0xbc, 0xfa, - 0xa6, 0xe7, 0xc9, 0x8b, 0x51, 0xbb, 0xde, 0xe1, 0x83, 0xcd, 0x01, 0x6f, 0x8f, 0x37, 0x15, 0xaa, - 0xef, 0xc9, 0x4d, 0x77, 0xe8, 0x6d, 0x0a, 0x16, 0x5e, 0x7a, 0x1d, 0x26, 0x36, 0x0d, 0x29, 0xfa, - 0xd5, 0x2a, 0xed, 0x1a, 0xac, 0xbd, 0xf3, 0x84, 0x3c, 0x0d, 0x79, 0x87, 0x09, 0xc1, 0x84, 0xc3, - 0xfe, 0x3c, 0x62, 0x42, 0x92, 0x55, 0xc8, 0x3a, 0xec, 0x9c, 0x5a, 0xeb, 0x56, 0xad, 0xe4, 0xe0, - 0xd0, 0x3e, 0x85, 0x47, 0x37, 0x90, 0x62, 0xc8, 0x03, 0xc1, 0xc8, 0x36, 0x2c, 0x1d, 0x06, 0xe7, - 0x5c, 0x50, 0x6b, 0x3d, 0x5b, 0x2b, 0x6f, 0x3d, 0xaf, 0xcf, 0xb3, 0xb2, 0x6e, 0x78, 0x88, 0x74, - 0x34, 0xde, 0x16, 0x50, 0x4e, 0x48, 0xc9, 0x53, 0x28, 0x45, 0xd3, 0x3d, 0xb3, 0xf0, 0x44, 0x40, - 0x9a, 0xb0, 0x7c, 0x18, 0x5c, 0xf2, 0x3e, 0x6b, 0xf0, 0xe0, 0xdc, 0xeb, 0xd1, 0xcc, 0xba, 0x55, - 0x2b, 0x6f, 0xd9, 0xf3, 0x17, 0x4b, 0x22, 0x9d, 0x29, 0x9e, 0xfd, 0x1d, 0xd0, 0x3d, 0x4f, 0x74, - 0x78, 0x10, 0xb0, 0x4e, 0xe4, 0x4c, 0xaa, 0xd3, 0xd3, 0x36, 0x65, 0x6e, 0xd8, 0x64, 0x3f, 0x81, - 0xc7, 0x73, 0x74, 0xe9, 0xb0, 0xd8, 0x7f, 0x82, 0xe5, 0x5d, 0xb4, 0x2d, 0x5d, 0xf9, 0x5b, 0x28, - 0x9c, 0x0c, 0xa5, 0xc7, 0x03, 0xb1, 0xd8, 0x1b, 0xa5, 0xc6, 0x20, 0x9d, 0x88, 0x62, 0xff, 0xbd, - 0x6c, 0x16, 0x30, 0x02, 0xb2, 0x0e, 0xe5, 0x06, 0x0f, 0x24, 0xbb, 0x96, 0xa7, 0xae, 0xbc, 0x30, - 0x0b, 0x25, 0x45, 0xe4, 0x15, 0xac, 0xec, 0xf1, 0x4e, 0x9f, 0x85, 0xe7, 0x9e, 0xcf, 0x8e, 0xdd, - 0x01, 0x33, 0x2e, 0xdd, 0x90, 0x92, 0x6f, 0xd1, 0x6b, 0x2f, 0x90, 0xcd, 0x51, 0xd0, 0xa1, 0x59, - 0x65, 0xda, 0xb3, 0xb4, 0x5d, 0x35, 0x30, 0x67, 0xc2, 0x20, 0x7f, 0x84, 0x0a, 0xaa, 0xe9, 0x9a, - 0xa5, 0x05, 0xcd, 0xa9, 0xc4, 0xf8, 0xf2, 0x76, 0xef, 0xea, 0x53, 0xbc, 0xfd, 0x40, 0x86, 0x63, - 0x67, 0x5a, 0x17, 0x59, 0x83, 0xa5, 0x1d, 0xdf, 0xe7, 0x57, 0x74, 0x69, 0x3d, 0x5b, 0x2b, 0x39, - 0x7a, 0x42, 0x7e, 0x07, 0x85, 0x1d, 0x29, 0x99, 0x90, 0x82, 0xe6, 0xd5, 0x62, 0x4f, 0xe7, 0x2f, - 0xa6, 0x41, 0x4e, 0x04, 0x26, 0x27, 0x50, 0x52, 0xeb, 0xef, 0x84, 0x3d, 0x41, 0x0b, 0x8a, 0xf9, - 0xf9, 0x1d, 0xcc, 0x8c, 0x39, 0xda, 0xc4, 0x89, 0x0e, 0xb2, 0x0f, 0xa5, 0x86, 0xdb, 0xb9, 0x60, - 0xcd, 0x90, 0x0f, 0x68, 0x51, 0x29, 0xfc, 0xd5, 0x7c, 0x85, 0x0a, 0x66, 0x14, 0x1a, 0x35, 0x31, - 0x93, 0xec, 0x40, 0x41, 0x4d, 0xce, 0x38, 0x2d, 0xdd, 0x4f, 0x49, 0xc4, 0x23, 0x36, 0x2c, 0x37, - 0x7a, 0x21, 0x1f, 0x0d, 0x4f, 0xdd, 0x90, 0x05, 0x92, 0x82, 0xda, 0xea, 0x29, 0x19, 0x79, 0x03, - 0x85, 0xfd, 0xeb, 0x21, 0x0f, 0xa5, 0xa0, 0xe5, 0x45, 0x87, 0x57, 0x83, 0xcc, 0x02, 0x86, 0x41, - 0x3e, 0x05, 0xd8, 0xbf, 0x96, 0xa1, 0x7b, 0xc0, 0x31, 0xec, 0xcb, 0x6a, 0x3b, 0x12, 0x12, 0xd2, - 0x84, 0xfc, 0x3b, 0xb7, 0xcd, 0x7c, 0x41, 0x2b, 0x4a, 0x77, 0xfd, 0x0e, 0x81, 0xd5, 0x04, 0xbd, - 0x90, 0x61, 0x63, 0x5e, 0x1f, 0x33, 0x79, 0xc5, 0xc3, 0xfe, 0x11, 0xef, 0x32, 0xba, 0xa2, 0xf3, - 0x3a, 0x21, 0x22, 0x2f, 0xa0, 0x72, 0xcc, 0x75, 0xf0, 0x3c, 0x5f, 0xb2, 0x90, 0x3e, 0x50, 0xc6, - 0x4c, 0x0b, 0xd5, 0x59, 0xf6, 0x5d, 0x79, 0xce, 0xc3, 0x81, 0xa0, 0xab, 0x0a, 0x31, 0x11, 0x60, - 0x06, 0xb5, 0x58, 0x27, 0x64, 0x52, 0xd0, 0x87, 0x8b, 0x32, 0x48, 0x83, 0x9c, 0x08, 0x4c, 0x28, - 0x14, 0x5a, 0x17, 0x83, 0x96, 0xf7, 0x91, 0x51, 0xb2, 0x6e, 0xd5, 0xb2, 0x4e, 0x34, 0x25, 0xaf, - 0x21, 0xdb, 0x6a, 0x1d, 0xd0, 0x9f, 0x2b, 0x6d, 0x8f, 0x53, 0xb4, 0xb5, 0x0e, 0x1c, 0x44, 0x11, - 0x02, 0xb9, 0x33, 0xb7, 0x27, 0xe8, 0x9a, 0xb2, 0x4b, 0x8d, 0xc9, 0x27, 0x90, 0x3f, 0x73, 0xc3, - 0x1e, 0x93, 0xf4, 0x91, 0xf2, 0xd9, 0xcc, 0xc8, 0xd7, 0x50, 0x78, 0xef, 0x7b, 0x03, 0x4f, 0x0a, - 0xfa, 0xc9, 0xa2, 0xc3, 0xa9, 0x41, 0x27, 0x43, 0xe9, 0x44, 0x78, 0xb4, 0x56, 0xc5, 0x9b, 0x85, - 0xf4, 0x17, 0x4a, 0x67, 0x34, 0xc5, 0x74, 0x39, 0x62, 0xd2, 0xed, 0xba, 0xd2, 0x6d, 0x7a, 0x3e, - 0xa3, 0x54, 0xa7, 0x4b, 0x52, 0x86, 0x6c, 0x13, 0x52, 0xfa, 0x78, 0xdd, 0xaa, 0x15, 0x9d, 0x68, - 0x8a, 0xe6, 0x9f, 0x8e, 0x7c, 0x9f, 0x56, 0x95, 0x58, 0x8d, 0x75, 0x7e, 0x60, 0xaa, 0x9c, 0x8e, - 0xc4, 0x05, 0x7d, 0xa2, 0xfe, 0x49, 0x48, 0x26, 0xff, 0xbf, 0xe3, 0x6e, 0x97, 0x3e, 0x4d, 0xfe, - 0x8f, 0x92, 0xea, 0xef, 0x81, 0xcc, 0x96, 0x03, 0x2c, 0xa3, 0x7d, 0x36, 0x8e, 0xca, 0x68, 0x9f, - 0x8d, 0xb1, 0x22, 0x5c, 0xba, 0xfe, 0x28, 0x2a, 0x66, 0x7a, 0xf2, 0x4d, 0xe6, 0x2b, 0xab, 0xfa, - 0x16, 0x56, 0xa6, 0x4f, 0xea, 0xbd, 0xd8, 0x5f, 0x43, 0x39, 0x91, 0x8e, 0xf7, 0xa1, 0xda, 0x1b, - 0xf0, 0xa0, 0xe9, 0x05, 0xae, 0xef, 0x7d, 0x64, 0xe9, 0x17, 0xea, 0xbf, 0x2c, 0x58, 0x9d, 0xa0, - 0xcc, 0x65, 0x7a, 0x01, 0xab, 0x3a, 0x04, 0x2c, 0x8c, 0x64, 0xe6, 0x5e, 0x7d, 0x3b, 0x7f, 0x93, - 0x6f, 0x6a, 0xa8, 0xdf, 0xa4, 0xeb, 0xc3, 0x34, 0xa3, 0xb5, 0xda, 0x80, 0x47, 0x73, 0xa1, 0xf7, - 0x72, 0x74, 0x3b, 0x71, 0x53, 0x60, 0x12, 0xa8, 0x4b, 0x45, 0x33, 0xd5, 0x18, 0x73, 0xb8, 0xc9, - 0xc3, 0x81, 0x2b, 0x0d, 0xd7, 0xcc, 0xd0, 0xf9, 0x72, 0xa2, 0xaa, 0xa8, 0xfc, 0x1f, 0x0f, 0x63, - 0x2e, 0x8e, 0xc9, 0x2e, 0x2c, 0xed, 0x48, 0x19, 0xe2, 0xed, 0x88, 0x01, 0xf8, 0xcd, 0xad, 0xb5, - 0xa9, 0xae, 0xe0, 0xda, 0x61, 0x4d, 0xc5, 0xe2, 0xb1, 0xc7, 0x84, 0xf4, 0x02, 0x17, 0x0b, 0x8c, - 0xba, 0xcc, 0x4a, 0x4e, 0x52, 0x54, 0xfd, 0x0a, 0x60, 0x42, 0xbb, 0x97, 0xf3, 0xff, 0xb4, 0xe0, - 0xe1, 0x4c, 0x01, 0x9e, 0xeb, 0xc9, 0xc1, 0xb4, 0x27, 0x5b, 0x77, 0x2c, 0xe6, 0xb3, 0xfe, 0xfc, - 0x04, 0x6b, 0x8f, 0x21, 0xaf, 0x6f, 0xbd, 0xb9, 0x16, 0x56, 0xa1, 0xb8, 0xe7, 0x09, 0xb7, 0xed, - 0xb3, 0xae, 0xa2, 0x16, 0x9d, 0x78, 0xae, 0xae, 0x5c, 0x65, 0xbd, 0x8e, 0x9e, 0x9e, 0xd8, 0xba, - 0xbc, 0x91, 0x15, 0xc8, 0xc4, 0xed, 0x5a, 0xe6, 0x70, 0x0f, 0xc1, 0xd8, 0x6b, 0x68, 0x57, 0x4b, - 0x8e, 0x9e, 0xd8, 0x4d, 0xc8, 0xeb, 0x82, 0x39, 0x83, 0xaf, 0x42, 0x11, 0x6b, 0x8b, 0x6a, 0x59, - 0xb4, 0xcd, 0xf1, 0x1c, 0xdd, 0xdb, 0x0f, 0x2e, 0xcd, 0xb2, 0x38, 0xb4, 0x6d, 0x58, 0x39, 0x0c, - 0xc4, 0x90, 0x75, 0x64, 0xfa, 0xb9, 0x3a, 0x81, 0x07, 0x31, 0xc6, 0x9c, 0xaa, 0x44, 0xa7, 0x65, - 0xdd, 0xbf, 0xd3, 0xfa, 0x87, 0x05, 0xa5, 0xb8, 0x96, 0x92, 0x06, 0xe4, 0x55, 0x50, 0xa3, 0x7e, - 0xf7, 0xf5, 0x2d, 0xc5, 0xb7, 0xfe, 0x41, 0xa1, 0xcd, 0x9d, 0xa6, 0xa9, 0xd5, 0xef, 0xa1, 0x9c, - 0x10, 0xcf, 0xd9, 0xc7, 0xad, 0xe4, 0x3e, 0xa6, 0x5e, 0x46, 0x7a, 0x91, 0xe4, 0x2e, 0xef, 0x41, - 0x5e, 0x0b, 0xe7, 0x9e, 0x46, 0x02, 0xb9, 0x03, 0x37, 0xd4, 0x3b, 0x9c, 0x75, 0xd4, 0x18, 0x65, - 0x2d, 0x7e, 0x2e, 0x55, 0x94, 0xb3, 0x8e, 0x1a, 0xdb, 0x0f, 0xa0, 0x62, 0x7a, 0x57, 0xd3, 0xcc, - 0xbe, 0x84, 0x87, 0x93, 0x4e, 0x37, 0x3d, 0xf4, 0x6b, 0x40, 0x92, 0x30, 0x43, 0x7e, 0x06, 0x65, - 0x7c, 0x39, 0xa4, 0xd3, 0x6c, 0x58, 0xd6, 0x00, 0xb3, 0x5d, 0x04, 0x72, 0x7d, 0x36, 0xd6, 0x01, - 0x2e, 0x39, 0x6a, 0x6c, 0xff, 0xcd, 0xc2, 0x07, 0xc0, 0x70, 0x24, 0x8f, 0x98, 0x10, 0x6e, 0x0f, - 0xf7, 0x34, 0x77, 0x18, 0x78, 0xd2, 0x6c, 0xe8, 0xab, 0xb4, 0x87, 0xc0, 0x70, 0x24, 0x11, 0x66, - 0x58, 0x07, 0x3f, 0x73, 0x14, 0x8b, 0x6c, 0x43, 0x6e, 0xcf, 0x95, 0xae, 0x09, 0x6f, 0x4a, 0xdb, - 0x83, 0x88, 0x04, 0x11, 0xa7, 0xbb, 0x05, 0x7c, 0xed, 0x0c, 0x47, 0xd2, 0x7e, 0x01, 0xab, 0x37, - 0xb5, 0xcf, 0x71, 0xed, 0x0b, 0x28, 0x27, 0xb4, 0xa8, 0x8c, 0x3e, 0x69, 0x2a, 0x40, 0xd1, 0xc1, - 0x21, 0xfa, 0x1a, 0x1b, 0xb2, 0xac, 0xd7, 0xc0, 0xf0, 0x2b, 0xd5, 0x71, 0x04, 0xff, 0x92, 0x81, - 0x42, 0xa4, 0x62, 0x7b, 0xca, 0xef, 0xe7, 0x69, 0x7e, 0xcf, 0xba, 0xfc, 0x25, 0xe4, 0xd4, 0xcd, - 0x9e, 0x59, 0xd4, 0x33, 0x34, 0xbb, 0x09, 0x9a, 0xba, 0xf4, 0xbf, 0x85, 0xbc, 0xc3, 0x04, 0xf6, - 0x37, 0xfa, 0x25, 0xb0, 0x31, 0x9f, 0xa8, 0x31, 0x13, 0xb2, 0x21, 0x21, 0xbd, 0xe5, 0xf5, 0x02, - 0xd7, 0xa7, 0xb9, 0x45, 0x74, 0x8d, 0x49, 0xd0, 0xb5, 0x60, 0x12, 0xee, 0xbf, 0x5a, 0x50, 0x5e, - 0x18, 0xea, 0xc5, 0x6f, 0xb5, 0x99, 0xf7, 0x63, 0xf6, 0xff, 0x7c, 0x3f, 0xfe, 0xc7, 0x9a, 0x56, - 0xa4, 0xda, 0x18, 0x3c, 0xc4, 0x43, 0xee, 0x05, 0xd2, 0xa4, 0x6c, 0x42, 0x82, 0x86, 0x36, 0x06, - 0x5d, 0x53, 0x0e, 0x71, 0x38, 0x29, 0x6b, 0x59, 0x53, 0xd6, 0x30, 0x09, 0xde, 0x0b, 0x16, 0xaa, - 0x10, 0x95, 0x1c, 0x35, 0xc6, 0x9b, 0xf3, 0x98, 0x2b, 0xe9, 0x92, 0xca, 0x16, 0x33, 0x53, 0xfa, - 0xae, 0xba, 0x34, 0xaf, 0x1d, 0x6f, 0x5c, 0xa9, 0xfa, 0x7c, 0xcc, 0x51, 0x56, 0x50, 0x40, 0x3d, - 0x41, 0xdc, 0x99, 0x1c, 0xd3, 0xa2, 0x4e, 0xb5, 0x33, 0x39, 0xc6, 0x52, 0xeb, 0x70, 0xdf, 0x6f, - 0xbb, 0x9d, 0x3e, 0x2d, 0xe9, 0x1a, 0x1f, 0xcd, 0xb1, 0xb5, 0xc3, 0xe8, 0x7a, 0xae, 0xaf, 0x1e, - 0x0a, 0x45, 0x27, 0x9a, 0xda, 0x3b, 0x50, 0x8a, 0x93, 0x02, 0xab, 0x77, 0xb3, 0xab, 0x82, 0x5e, - 0x71, 0x32, 0xcd, 0x6e, 0x94, 0xcf, 0x99, 0xd9, 0x7c, 0xce, 0x26, 0xf2, 0x79, 0x1b, 0x2a, 0x53, - 0xe9, 0x81, 0x20, 0x87, 0x5f, 0x09, 0xa3, 0x48, 0x8d, 0x51, 0xd6, 0xe0, 0xbe, 0x7e, 0x0a, 0x57, - 0x1c, 0x35, 0xb6, 0x37, 0xa0, 0x32, 0x95, 0x18, 0xf3, 0x8a, 0x9a, 0xfd, 0x1c, 0x2a, 0x2d, 0xe9, - 0xca, 0xd1, 0x82, 0x6f, 0x17, 0xff, 0xb5, 0x60, 0x25, 0xc2, 0x98, 0x1a, 0xf3, 0x5b, 0x28, 0x5e, - 0xb2, 0x50, 0xb2, 0xeb, 0xb8, 0x90, 0xd3, 0xfa, 0x80, 0xb7, 0xc7, 0xf5, 0xe8, 0xeb, 0x09, 0xe6, - 0xc1, 0x07, 0x85, 0x70, 0x62, 0x24, 0xf9, 0x06, 0x8a, 0x42, 0xe9, 0x61, 0xd1, 0x5d, 0xfe, 0x69, - 0x1a, 0xcb, 0xac, 0x17, 0xe3, 0xc9, 0x26, 0xe4, 0x7c, 0xde, 0x13, 0x6a, 0xdf, 0xcb, 0x5b, 0x4f, - 0xd2, 0x78, 0xef, 0x78, 0xcf, 0x51, 0x40, 0xf2, 0x06, 0x8a, 0x57, 0x6e, 0x18, 0x78, 0x41, 0x2f, - 0x7a, 0x42, 0x3f, 0x4b, 0x23, 0x7d, 0xaf, 0x71, 0x4e, 0x4c, 0xb0, 0x2b, 0x78, 0x5c, 0xce, 0xb9, - 0x89, 0x89, 0xfd, 0x03, 0x66, 0x2d, 0x4e, 0x8d, 0xfb, 0x87, 0x50, 0xd1, 0x99, 0xff, 0x81, 0x85, - 0x02, 0x3b, 0x23, 0x6b, 0xd1, 0xe9, 0xdc, 0x4d, 0x42, 0x9d, 0x69, 0xa6, 0xfd, 0xa3, 0xb9, 0x2c, - 0x22, 0x01, 0xe6, 0xd2, 0xd0, 0xed, 0xf4, 0xdd, 0x5e, 0xb4, 0x4f, 0xd1, 0x14, 0xff, 0xb9, 0x34, - 0xeb, 0xe9, 0x03, 0x1a, 0x4d, 0x31, 0x37, 0x43, 0x76, 0xe9, 0x89, 0x49, 0x93, 0x16, 0xcf, 0xb7, - 0xfe, 0x5d, 0x00, 0x68, 0xc4, 0xf6, 0x90, 0x23, 0x2c, 0x80, 0xe7, 0x9c, 0xa4, 0x96, 0xbe, 0xd8, - 0xeb, 0xaa, 0xbd, 0x08, 0x62, 0x22, 0x71, 0x0a, 0x4b, 0xca, 0x7c, 0xb2, 0xa8, 0x27, 0x88, 0x14, - 0x6e, 0x2c, 0xc4, 0x18, 0x8d, 0x3f, 0x60, 0x4b, 0xa3, 0xbb, 0x72, 0xf2, 0xf2, 0xb6, 0xae, 0x5d, - 0xeb, 0x7d, 0x75, 0xb7, 0xe6, 0x9e, 0x7c, 0x07, 0x79, 0x5d, 0x7c, 0xc8, 0x2f, 0xe7, 0x33, 0xcc, - 0x41, 0xa9, 0x2e, 0xfe, 0xbb, 0x66, 0x7d, 0x66, 0x91, 0x1f, 0x01, 0x26, 0x97, 0x35, 0x49, 0xf9, - 0xc0, 0x30, 0x73, 0xeb, 0x57, 0x6b, 0xb7, 0x03, 0x8d, 0xb1, 0xef, 0x21, 0xaf, 0x0f, 0x01, 0x49, - 0x2b, 0xfa, 0xc9, 0x63, 0x5b, 0x7d, 0xb1, 0x18, 0xa4, 0x95, 0x7e, 0x66, 0x91, 0x0f, 0x58, 0xaa, - 0x54, 0x7f, 0x47, 0x5e, 0xa4, 0xed, 0x6f, 0xb2, 0x45, 0xac, 0xbe, 0xbc, 0x05, 0x65, 0xcc, 0x3d, - 0x82, 0x1c, 0x76, 0x21, 0x69, 0x79, 0x95, 0x68, 0x61, 0xd2, 0xf2, 0x6a, 0xaa, 0x89, 0x71, 0xcc, - 0xcd, 0x45, 0xec, 0x05, 0xad, 0x49, 0xb4, 0x5d, 0x1b, 0x0b, 0x30, 0x91, 0xc6, 0x9a, 0x45, 0x2e, - 0xa0, 0x32, 0xf5, 0x0d, 0x96, 0xfc, 0x3a, 0xdd, 0x90, 0x9b, 0x9f, 0x74, 0xab, 0xaf, 0xef, 0x84, - 0x35, 0xd6, 0xcb, 0x64, 0xc3, 0x67, 0xfe, 0x26, 0xf5, 0xdb, 0xb6, 0x7e, 0xfa, 0x7b, 0x6a, 0x75, - 0xf3, 0xce, 0x78, 0xbd, 0xea, 0x6e, 0xee, 0x0f, 0x99, 0x61, 0xbb, 0x9d, 0x57, 0x9f, 0xa6, 0xbf, - 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x66, 0x27, 0x0f, 0x01, 0x17, 0x00, 0x00, + // 1870 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x53, 0x23, 0xc7, + 0x11, 0xcf, 0x22, 0xa1, 0x3f, 0x2d, 0xc4, 0x71, 0x13, 0xce, 0x99, 0xd3, 0x39, 0x3e, 0x6e, 0xb9, + 0xbb, 0xa8, 0x72, 0x29, 0x61, 0xe3, 0x38, 0xd8, 0xbe, 0x73, 0x55, 0x40, 0xa0, 0x02, 0xd7, 0x1d, + 0x50, 0x03, 0x77, 0x2e, 0x27, 0x55, 0x71, 0x2d, 0xd2, 0x20, 0xb6, 0xb4, 0xda, 0x51, 0x76, 0x46, + 0x80, 0xfc, 0x94, 0x97, 0xbc, 0xe6, 0x7b, 0xa4, 0xf2, 0x29, 0xf2, 0x69, 0xf2, 0x96, 0xca, 0x4b, + 0xde, 0x53, 0x3d, 0x33, 0xbb, 0x5a, 0x21, 0xad, 0x80, 0xf8, 0x49, 0xdb, 0xbd, 0xbf, 0x5f, 0x4f, + 0x77, 0x4f, 0x4f, 0x4f, 0xaf, 0x60, 0xa5, 0x2d, 0x42, 0x15, 0x89, 0x20, 0xe0, 0x51, 0x63, 0x10, + 0x09, 0x25, 0xc8, 0xea, 0xd9, 0xd0, 0x0f, 0x3a, 0xd7, 0x8d, 0xd4, 0x8b, 0xcb, 0xcf, 0x6a, 0xaf, + 0xbb, 0xbe, 0xba, 0x18, 0x9e, 0x35, 0xda, 0xa2, 0xbf, 0xd1, 0x17, 0x67, 0xa3, 0x0d, 0x8d, 0xea, + 0xf9, 0x6a, 0xc3, 0x1b, 0xf8, 0x1b, 0x92, 0x47, 0x97, 0x7e, 0x9b, 0xcb, 0x0d, 0x4b, 0x8a, 0x7f, + 0x8d, 0x49, 0xb7, 0x0e, 0xab, 0x6f, 0x7d, 0xa9, 0x8e, 0x23, 0xd1, 0xe6, 0x52, 0x72, 0xc9, 0xf8, + 0x9f, 0x87, 0x5c, 0x2a, 0xb2, 0x02, 0x39, 0xc6, 0xcf, 0xa9, 0xb3, 0xe6, 0xd4, 0xcb, 0x0c, 0x1f, + 0xdd, 0x63, 0x78, 0x74, 0x03, 0x29, 0x07, 0x22, 0x94, 0x9c, 0x6c, 0xc1, 0xe2, 0x41, 0x78, 0x2e, + 0x24, 0x75, 0xd6, 0x72, 0xf5, 0xca, 0xe6, 0xb3, 0xc6, 0x2c, 0x2f, 0x1b, 0x96, 0x87, 0x48, 0x66, + 0xf0, 0xae, 0x84, 0x4a, 0x4a, 0x4b, 0x3e, 0x86, 0x72, 0x2c, 0xee, 0xda, 0x85, 0xc7, 0x0a, 0xd2, + 0x82, 0xa5, 0x83, 0xf0, 0x52, 0xf4, 0x78, 0x53, 0x84, 0xe7, 0x7e, 0x97, 0x2e, 0xac, 0x39, 0xf5, + 0xca, 0xa6, 0x3b, 0x7b, 0xb1, 0x34, 0x92, 0x4d, 0xf0, 0xdc, 0x6f, 0x81, 0xee, 0xfa, 0xb2, 0x2d, + 0xc2, 0x90, 0xb7, 0xe3, 0x60, 0x32, 0x83, 0x9e, 0xf4, 0x69, 0xe1, 0x86, 0x4f, 0xee, 0x13, 0x78, + 0x3c, 0xc3, 0x96, 0x49, 0x8b, 0xfb, 0x27, 0x58, 0xda, 0x41, 0xdf, 0xb2, 0x8d, 0xbf, 0x81, 0xe2, + 0xd1, 0x40, 0xf9, 0x22, 0x94, 0xf3, 0xa3, 0xd1, 0x66, 0x2c, 0x92, 0xc5, 0x14, 0xf7, 0xbf, 0x60, + 0x17, 0xb0, 0x0a, 0xb2, 0x06, 0x95, 0xa6, 0x08, 0x15, 0xbf, 0x56, 0xc7, 0x9e, 0xba, 0xb0, 0x0b, + 0xa5, 0x55, 0xe4, 0x25, 0x2c, 0xef, 0x8a, 0x76, 0x8f, 0x47, 0xe7, 0x7e, 0xc0, 0x0f, 0xbd, 0x3e, + 0xb7, 0x21, 0xdd, 0xd0, 0x92, 0x6f, 0x30, 0x6a, 0x3f, 0x54, 0xad, 0x61, 0xd8, 0xa6, 0x39, 0xed, + 0xda, 0xd3, 0xac, 0x5d, 0xb5, 0x30, 0x36, 0x66, 0x90, 0x3f, 0x42, 0x15, 0xcd, 0x74, 0xec, 0xd2, + 0x92, 0xe6, 0x75, 0x61, 0x7c, 0x71, 0x7b, 0x74, 0x8d, 0x09, 0xde, 0x5e, 0xa8, 0xa2, 0x11, 0x9b, + 0xb4, 0x45, 0x56, 0x61, 0x71, 0x3b, 0x08, 0xc4, 0x15, 0x5d, 0x5c, 0xcb, 0xd5, 0xcb, 0xcc, 0x08, + 0xe4, 0x77, 0x50, 0xdc, 0x56, 0x8a, 0x4b, 0x25, 0x69, 0x41, 0x2f, 0xf6, 0xf1, 0xec, 0xc5, 0x0c, + 0x88, 0xc5, 0x60, 0x72, 0x04, 0x65, 0xbd, 0xfe, 0x76, 0xd4, 0x95, 0xb4, 0xa8, 0x99, 0x9f, 0xdd, + 0xc1, 0xcd, 0x84, 0x63, 0x5c, 0x1c, 0xdb, 0x20, 0x7b, 0x50, 0x6e, 0x7a, 0xed, 0x0b, 0xde, 0x8a, + 0x44, 0x9f, 0x96, 0xb4, 0xc1, 0x5f, 0xcd, 0x36, 0xa8, 0x61, 0xd6, 0xa0, 0x35, 0x93, 0x30, 0xc9, + 0x36, 0x14, 0xb5, 0x70, 0x2a, 0x68, 0xf9, 0x7e, 0x46, 0x62, 0x1e, 0x71, 0x61, 0xa9, 0xd9, 0x8d, + 0xc4, 0x70, 0x70, 0xec, 0x45, 0x3c, 0x54, 0x14, 0xf4, 0x56, 0x4f, 0xe8, 0xc8, 0x6b, 0x28, 0xee, + 0x5d, 0x0f, 0x44, 0xa4, 0x24, 0xad, 0xcc, 0x3b, 0xbc, 0x06, 0x64, 0x17, 0xb0, 0x0c, 0xf2, 0x09, + 0xc0, 0xde, 0xb5, 0x8a, 0xbc, 0x7d, 0x81, 0x69, 0x5f, 0xd2, 0xdb, 0x91, 0xd2, 0x90, 0x16, 0x14, + 0xde, 0x7a, 0x67, 0x3c, 0x90, 0xb4, 0xaa, 0x6d, 0x37, 0xee, 0x90, 0x58, 0x43, 0x30, 0x0b, 0x59, + 0x36, 0xd6, 0xf5, 0x21, 0x57, 0x57, 0x22, 0xea, 0xbd, 0x13, 0x1d, 0x4e, 0x97, 0x4d, 0x5d, 0xa7, + 0x54, 0xe4, 0x39, 0x54, 0x0f, 0x85, 0x49, 0x9e, 0x1f, 0x28, 0x1e, 0xd1, 0x07, 0xda, 0x99, 0x49, + 0xa5, 0x3e, 0xcb, 0x81, 0xa7, 0xce, 0x45, 0xd4, 0x97, 0x74, 0x45, 0x23, 0xc6, 0x0a, 0xac, 0xa0, + 0x13, 0xde, 0x8e, 0xb8, 0x92, 0xf4, 0xe1, 0xbc, 0x0a, 0x32, 0x20, 0x16, 0x83, 0x09, 0x85, 0xe2, + 0xc9, 0x45, 0xff, 0xc4, 0xff, 0x91, 0x53, 0xb2, 0xe6, 0xd4, 0x73, 0x2c, 0x16, 0xc9, 0x2b, 0xc8, + 0x9d, 0x9c, 0xec, 0xd3, 0x9f, 0x6b, 0x6b, 0x8f, 0x33, 0xac, 0x9d, 0xec, 0x33, 0x44, 0x11, 0x02, + 0xf9, 0x53, 0xaf, 0x2b, 0xe9, 0xaa, 0xf6, 0x4b, 0x3f, 0x93, 0x8f, 0xa0, 0x70, 0xea, 0x45, 0x5d, + 0xae, 0xe8, 0x23, 0x1d, 0xb3, 0x95, 0xc8, 0x57, 0x50, 0x7c, 0x1f, 0xf8, 0x7d, 0x5f, 0x49, 0xfa, + 0xd1, 0xbc, 0xc3, 0x69, 0x40, 0x47, 0x03, 0xc5, 0x62, 0x3c, 0x7a, 0xab, 0xf3, 0xcd, 0x23, 0xfa, + 0x0b, 0x6d, 0x33, 0x16, 0xf1, 0x8d, 0x4d, 0x17, 0xa5, 0x6b, 0x4e, 0xbd, 0xc4, 0x62, 0x11, 0x5d, + 0x3b, 0x1e, 0x06, 0x01, 0x7d, 0xac, 0xd5, 0xfa, 0xd9, 0xec, 0x3d, 0x96, 0xc1, 0xf1, 0x50, 0x5e, + 0xd0, 0x9a, 0x7e, 0x93, 0xd2, 0x8c, 0xdf, 0xbf, 0x15, 0x5e, 0x87, 0x3e, 0x49, 0xbf, 0x47, 0x4d, + 0xed, 0xf7, 0x40, 0xa6, 0x8f, 0x3a, 0xb6, 0xc8, 0x1e, 0x1f, 0xc5, 0x2d, 0xb2, 0xc7, 0x47, 0x78, + 0xda, 0x2f, 0xbd, 0x60, 0x18, 0x37, 0x2a, 0x23, 0x7c, 0xbd, 0xf0, 0xa5, 0x53, 0x7b, 0x03, 0xcb, + 0x93, 0xa7, 0xf0, 0x5e, 0xec, 0xaf, 0xa0, 0x92, 0x2a, 0xb5, 0xfb, 0x50, 0xdd, 0x75, 0x78, 0xd0, + 0xf2, 0x43, 0x2f, 0xf0, 0x7f, 0xe4, 0xd9, 0x97, 0xe5, 0x3f, 0x1d, 0x58, 0x19, 0xa3, 0xec, 0x45, + 0x79, 0x01, 0x2b, 0x26, 0x05, 0x3c, 0x8a, 0x75, 0xf6, 0xce, 0x7c, 0x33, 0x7b, 0x03, 0x6f, 0x5a, + 0x68, 0xdc, 0xa4, 0x9b, 0x83, 0x32, 0x65, 0xb5, 0xd6, 0x84, 0x47, 0x33, 0xa1, 0xf7, 0x0a, 0x74, + 0x2b, 0x75, 0x0b, 0x60, 0x11, 0xe8, 0x0b, 0xc3, 0x30, 0xf5, 0x33, 0xd6, 0x67, 0x4b, 0x44, 0x7d, + 0x4f, 0x59, 0xae, 0x95, 0x30, 0xf8, 0x4a, 0xaa, 0x63, 0xe8, 0xda, 0x1e, 0x0d, 0x12, 0x2e, 0x3e, + 0x93, 0x1d, 0x58, 0xdc, 0x56, 0x2a, 0xc2, 0x9b, 0x0f, 0x13, 0xf0, 0x9b, 0x5b, 0xfb, 0x4e, 0x43, + 0xc3, 0x4d, 0xc0, 0x86, 0x8a, 0x8d, 0x61, 0x97, 0x4b, 0xe5, 0x87, 0x1e, 0x36, 0x0f, 0x7d, 0x51, + 0x95, 0x59, 0x5a, 0x55, 0xfb, 0x12, 0x60, 0x4c, 0xbb, 0x57, 0xf0, 0xff, 0x70, 0xe0, 0xe1, 0x54, + 0x73, 0x9d, 0x19, 0xc9, 0xfe, 0x64, 0x24, 0x9b, 0x77, 0x6c, 0xd4, 0xd3, 0xf1, 0xfc, 0x04, 0x6f, + 0x0f, 0xa1, 0x60, 0x6e, 0xb4, 0x99, 0x1e, 0xd6, 0xa0, 0xb4, 0xeb, 0x4b, 0xef, 0x2c, 0xe0, 0x1d, + 0x4d, 0x2d, 0xb1, 0x44, 0xd6, 0xd7, 0xa9, 0xf6, 0xde, 0x64, 0xcf, 0x08, 0xae, 0x69, 0x5d, 0x64, + 0x19, 0x16, 0x92, 0x51, 0x6c, 0xe1, 0x60, 0x17, 0xc1, 0x38, 0x47, 0x98, 0x50, 0xcb, 0xcc, 0x08, + 0x6e, 0x0b, 0x0a, 0xa6, 0x19, 0x4e, 0xe1, 0x6b, 0x50, 0x6a, 0xf9, 0x01, 0xd7, 0xe3, 0x88, 0xf1, + 0x39, 0x91, 0x31, 0xbc, 0xbd, 0xf0, 0xd2, 0x2e, 0x8b, 0x8f, 0xae, 0x0b, 0xcb, 0x07, 0xa1, 0x1c, + 0xf0, 0xb6, 0xca, 0x3e, 0x57, 0x47, 0xf0, 0x20, 0xc1, 0xd8, 0x53, 0x95, 0x9a, 0xa2, 0x9c, 0xfb, + 0x4f, 0x51, 0x7f, 0x77, 0xa0, 0x9c, 0xf4, 0x49, 0xd2, 0x84, 0x82, 0x4e, 0x6a, 0x3c, 0xcb, 0xbe, + 0xba, 0xa5, 0xb1, 0x36, 0x3e, 0x68, 0xb4, 0xbd, 0xaf, 0x0c, 0xb5, 0xf6, 0x1d, 0x54, 0x52, 0xea, + 0x19, 0xfb, 0xb8, 0x99, 0xde, 0xc7, 0xcc, 0x8b, 0xc6, 0x2c, 0x92, 0xde, 0xe5, 0x5d, 0x28, 0x18, + 0xe5, 0xcc, 0xd3, 0x48, 0x20, 0xbf, 0xef, 0x45, 0x66, 0x87, 0x73, 0x4c, 0x3f, 0xa3, 0xee, 0x44, + 0x9c, 0x2b, 0x9d, 0xe5, 0x1c, 0xd3, 0xcf, 0xee, 0x03, 0xa8, 0xda, 0xb9, 0xd4, 0x0e, 0xaa, 0x2f, + 0xe0, 0xe1, 0x78, 0x8a, 0xcd, 0x4e, 0xfd, 0x2a, 0x90, 0x34, 0xcc, 0x92, 0x9f, 0x42, 0x05, 0xbf, + 0x0a, 0xb2, 0x69, 0x2e, 0x2c, 0x19, 0x80, 0xdd, 0x2e, 0x02, 0xf9, 0x1e, 0x1f, 0x99, 0x04, 0x97, + 0x99, 0x7e, 0x76, 0xff, 0xe6, 0xe0, 0x70, 0x3f, 0x18, 0xaa, 0x77, 0x5c, 0x4a, 0xaf, 0x8b, 0x7b, + 0x9a, 0x3f, 0x08, 0x7d, 0x65, 0x37, 0xf4, 0x65, 0xd6, 0x90, 0x3f, 0x18, 0x2a, 0x84, 0x59, 0xd6, + 0xfe, 0xcf, 0x98, 0x66, 0x91, 0x2d, 0xc8, 0xef, 0x7a, 0xca, 0xb3, 0xe9, 0xcd, 0x18, 0x69, 0x10, + 0x91, 0x22, 0xa2, 0xb8, 0x53, 0xc4, 0x2f, 0x99, 0xc1, 0x50, 0xb9, 0xcf, 0x61, 0xe5, 0xa6, 0xf5, + 0x19, 0xa1, 0x7d, 0x0e, 0x95, 0x94, 0x15, 0x5d, 0xd1, 0x47, 0x2d, 0x0d, 0x28, 0x31, 0x7c, 0xc4, + 0x58, 0x13, 0x47, 0x96, 0xcc, 0x1a, 0x98, 0x7e, 0x6d, 0x3a, 0xc9, 0xe0, 0x5f, 0x16, 0xa0, 0x18, + 0x9b, 0xd8, 0x9a, 0x88, 0xfb, 0x59, 0x56, 0xdc, 0xd3, 0x21, 0x7f, 0x01, 0x79, 0x3c, 0x59, 0x36, + 0xe4, 0x8c, 0x79, 0xa0, 0xd5, 0x49, 0xd1, 0x10, 0x4e, 0xbe, 0x81, 0x02, 0xe3, 0x12, 0x67, 0x17, + 0x33, 0xe5, 0xaf, 0xcf, 0x26, 0x1a, 0xcc, 0x98, 0x6c, 0x49, 0x48, 0x3f, 0xf1, 0xbb, 0xa1, 0x17, + 0xd0, 0xfc, 0x3c, 0xba, 0xc1, 0xa4, 0xe8, 0x46, 0x31, 0x4e, 0xf7, 0x5f, 0x1d, 0xa8, 0xcc, 0x4d, + 0xf5, 0xfc, 0xef, 0xb0, 0xa9, 0x6f, 0xc3, 0xdc, 0xff, 0xf9, 0x6d, 0xf8, 0x6f, 0x67, 0xd2, 0x90, + 0x1e, 0x63, 0xf0, 0x10, 0x0f, 0x84, 0x1f, 0x2a, 0x5b, 0xb2, 0x29, 0x0d, 0x3a, 0xda, 0xec, 0x77, + 0x6c, 0x3b, 0xc4, 0xc7, 0x71, 0x5b, 0xcb, 0xd9, 0xb6, 0x86, 0x45, 0xf0, 0x5e, 0xf2, 0x48, 0xa7, + 0xa8, 0xcc, 0xf4, 0x33, 0xde, 0x9c, 0x87, 0x42, 0x6b, 0x17, 0x75, 0xb5, 0x58, 0x49, 0xdb, 0xbb, + 0xea, 0xd0, 0x82, 0x09, 0xbc, 0x79, 0xa5, 0xfb, 0xf3, 0xa1, 0x40, 0x5d, 0x51, 0x03, 0x8d, 0x80, + 0xb8, 0x53, 0x35, 0xa2, 0x25, 0x53, 0x6a, 0xa7, 0x6a, 0x84, 0xad, 0x96, 0x89, 0x20, 0x38, 0xf3, + 0xda, 0x3d, 0x5a, 0x36, 0x3d, 0x3e, 0x96, 0x71, 0xb4, 0xc3, 0xec, 0xfa, 0x5e, 0xa0, 0x3f, 0x02, + 0x4a, 0x2c, 0x16, 0xdd, 0x6d, 0x28, 0x27, 0x45, 0x81, 0xdd, 0xbb, 0xd5, 0xd1, 0x49, 0xaf, 0xb2, + 0x85, 0x56, 0x27, 0xae, 0xe7, 0x85, 0xe9, 0x7a, 0xce, 0xa5, 0xea, 0x79, 0x0b, 0xaa, 0x13, 0xe5, + 0x81, 0x20, 0x26, 0xae, 0xa4, 0x35, 0xa4, 0x9f, 0x51, 0xd7, 0x14, 0x81, 0xf9, 0xcc, 0xad, 0x32, + 0xfd, 0xec, 0xae, 0x43, 0x75, 0xa2, 0x30, 0x66, 0x35, 0x35, 0xf7, 0x19, 0x54, 0x4f, 0x94, 0xa7, + 0x86, 0x73, 0xfe, 0x97, 0xf8, 0x8f, 0x03, 0xcb, 0x31, 0xc6, 0xf6, 0x98, 0xdf, 0x42, 0xe9, 0x92, + 0x47, 0x8a, 0x5f, 0x27, 0x8d, 0x9c, 0x36, 0xfa, 0xe2, 0x6c, 0xd4, 0x88, 0xff, 0x19, 0xc1, 0x3a, + 0xf8, 0xa0, 0x11, 0x2c, 0x41, 0x92, 0xaf, 0xa1, 0x24, 0xb5, 0x1d, 0x1e, 0xdf, 0xe5, 0x9f, 0x64, + 0xb1, 0xec, 0x7a, 0x09, 0x9e, 0x6c, 0x40, 0x3e, 0x10, 0x5d, 0xa9, 0xf7, 0xbd, 0xb2, 0xf9, 0x24, + 0x8b, 0xf7, 0x56, 0x74, 0x99, 0x06, 0x92, 0xd7, 0x50, 0xba, 0xf2, 0xa2, 0xd0, 0x0f, 0xbb, 0xf1, + 0xe7, 0xf1, 0xd3, 0x2c, 0xd2, 0x77, 0x06, 0xc7, 0x12, 0x82, 0x5b, 0xc5, 0xe3, 0x72, 0x2e, 0x6c, + 0x4e, 0xdc, 0xef, 0xb1, 0x6a, 0x51, 0xb4, 0xe1, 0x1f, 0x40, 0xd5, 0x54, 0xfe, 0x07, 0x1e, 0x49, + 0x9c, 0x8c, 0x9c, 0x79, 0xa7, 0x73, 0x27, 0x0d, 0x65, 0x93, 0x4c, 0xf7, 0x07, 0x7b, 0x59, 0xc4, + 0x0a, 0xac, 0xa5, 0x81, 0xd7, 0xee, 0x79, 0xdd, 0x78, 0x9f, 0x62, 0x11, 0xdf, 0x5c, 0xda, 0xf5, + 0xcc, 0x01, 0x8d, 0x45, 0xac, 0xcd, 0x88, 0x5f, 0xfa, 0x72, 0x3c, 0xa4, 0x25, 0xf2, 0xe6, 0xbf, + 0x8a, 0x00, 0xcd, 0xc4, 0x1f, 0xf2, 0x0e, 0x1b, 0xe0, 0xb9, 0x20, 0x99, 0xad, 0x2f, 0x89, 0xba, + 0xe6, 0xce, 0x83, 0xd8, 0x4c, 0x1c, 0xc3, 0xa2, 0x76, 0x9f, 0xcc, 0x9b, 0x09, 0x62, 0x83, 0xeb, + 0x73, 0x31, 0xd6, 0xe2, 0xf7, 0x38, 0xd2, 0x98, 0xa9, 0x9c, 0xbc, 0xb8, 0x6d, 0x6a, 0x37, 0x76, + 0x5f, 0xde, 0x6d, 0xb8, 0x27, 0xdf, 0x42, 0xc1, 0x34, 0x1f, 0xf2, 0xcb, 0xd9, 0x0c, 0x7b, 0x50, + 0x6a, 0xf3, 0x5f, 0xd7, 0x9d, 0x4f, 0x1d, 0xf2, 0x03, 0xc0, 0xf8, 0xb2, 0x26, 0x19, 0x7f, 0x1e, + 0x4c, 0xdd, 0xfa, 0xb5, 0xfa, 0xed, 0x40, 0xeb, 0xec, 0x7b, 0x28, 0x98, 0x43, 0x40, 0xb2, 0x9a, + 0x7e, 0xfa, 0xd8, 0xd6, 0x9e, 0xcf, 0x07, 0x19, 0xa3, 0x9f, 0x3a, 0xe4, 0x03, 0xb6, 0x2a, 0x3d, + 0xdf, 0x91, 0xe7, 0x59, 0xfb, 0x9b, 0x1e, 0x11, 0x6b, 0x2f, 0x6e, 0x41, 0x59, 0x77, 0xdf, 0x41, + 0x1e, 0xa7, 0x90, 0xac, 0xba, 0x4a, 0x8d, 0x30, 0x59, 0x75, 0x35, 0x31, 0xc4, 0x30, 0x7b, 0x73, + 0x11, 0x77, 0xce, 0x68, 0x12, 0x6f, 0xd7, 0xfa, 0x1c, 0x4c, 0x6c, 0xb1, 0xee, 0x90, 0x0b, 0xa8, + 0x4e, 0xfc, 0xbf, 0x4a, 0x7e, 0x9d, 0xed, 0xc8, 0xcd, 0xbf, 0x6b, 0x6b, 0xaf, 0xee, 0x84, 0xb5, + 0xde, 0xab, 0xf4, 0xc0, 0x67, 0x5f, 0x93, 0xc6, 0x6d, 0x5b, 0x3f, 0xf9, 0x5f, 0x69, 0x6d, 0xe3, + 0xce, 0x78, 0xb3, 0xea, 0x4e, 0xfe, 0x0f, 0x0b, 0x83, 0xb3, 0xb3, 0x82, 0xfe, 0xdb, 0xf9, 0xf3, + 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x43, 0xa6, 0xfc, 0x5a, 0xdd, 0x16, 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 b141dc6e8271..ddab5956e29d 100644 --- a/controller/pb/controller.proto +++ b/controller/pb/controller.proto @@ -76,11 +76,10 @@ message BuildOptions { UlimitOpt Ulimits = 22; string Builder = 23; - string MetadataFile = 24; - bool NoCache = 25; - bool Pull = 26; - bool ExportPush = 27; - bool ExportLoad = 28; + bool NoCache = 24; + bool Pull = 25; + bool ExportPush = 26; + bool ExportLoad = 27; } message FinalizeRequest {