monitor: Enable to exec into the container

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
This commit is contained in:
Kohei Tokunaga
2023-02-14 21:16:29 +09:00
parent eefe27ff42
commit e8f55a3cf7
14 changed files with 1249 additions and 481 deletions

View File

@ -11,11 +11,17 @@ import (
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)
Invoke(ctx context.Context, ref string, options controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) (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.
// 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)
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
}
type ControlOptions struct {

View File

@ -3,12 +3,15 @@ package local
import (
"context"
"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"
controllerapi "github.com/docker/buildx/controller/pb"
"github.com/docker/buildx/controller/processes"
"github.com/docker/buildx/util/ioset"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/client"
"github.com/pkg/errors"
@ -18,6 +21,7 @@ func NewLocalBuildxController(ctx context.Context, dockerCli command.Cli) contro
return &localController{
dockerCli: dockerCli,
ref: "local",
processes: processes.NewManager(),
}
}
@ -25,9 +29,17 @@ type localController struct {
dockerCli command.Cli
ref string
resultCtx *build.ResultContext
processes *processes.Manager
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) {
if !b.buildOnGoing.CompareAndSwap(false, true) {
return "", nil, errors.New("build ongoing")
}
defer b.buildOnGoing.Store(false)
resp, res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, progressMode, nil)
if err != nil {
return "", nil, err
@ -36,38 +48,64 @@ func (b *localController) Build(ctx context.Context, options controllerapi.Build
return b.ref, resp, nil
}
func (b *localController) Invoke(ctx context.Context, ref string, cfg controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error {
func (b *localController) ListProcesses(ctx context.Context, ref string) (infos []*controllerapi.ProcessInfo, retErr error) {
if ref != b.ref {
return nil, errors.Errorf("unknown ref %q", ref)
}
return b.processes.ListProcesses(), nil
}
func (b *localController) DisconnectProcess(ctx context.Context, ref, pid string) error {
if ref != b.ref {
return errors.Errorf("unknown ref %q", ref)
}
if b.resultCtx == nil {
return errors.New("no build result is registered")
return b.processes.DeleteProcess(pid)
}
func (b *localController) cancelRunningProcesses() {
b.processes.CancelRunningProcesses()
}
func (b *localController) Invoke(ctx context.Context, ref string, pid string, cfg controllerapi.InvokeConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error {
if ref != b.ref {
return errors.Errorf("unknown ref %q", ref)
}
ccfg := build.ContainerConfig{
ResultCtx: b.resultCtx,
Entrypoint: cfg.Entrypoint,
Cmd: cfg.Cmd,
Env: cfg.Env,
Tty: cfg.Tty,
Stdin: ioIn,
Stdout: ioOut,
Stderr: ioErr,
proc, ok := b.processes.Get(pid)
if !ok {
// Start a new process.
if b.resultCtx == nil {
return errors.New("no build result is registered")
}
var err error
proc, err = b.processes.StartProcess(pid, b.resultCtx, &cfg)
if err != nil {
return err
}
}
if !cfg.NoUser {
ccfg.User = &cfg.User
// Attach containerIn to this process
ioCancelledCh := make(chan struct{})
proc.ForwardIO(&ioset.In{Stdin: ioIn, Stdout: ioOut, Stderr: ioErr}, func() { close(ioCancelledCh) })
select {
case <-ioCancelledCh:
return errors.Errorf("io cancelled")
case err := <-proc.Done():
return err
case <-ctx.Done():
return ctx.Err()
}
if !cfg.NoCwd {
ccfg.Cwd = &cfg.Cwd
}
return build.Invoke(ctx, ccfg)
}
func (b *localController) Kill(context.Context) error {
return nil // nop
b.cancelRunningProcesses()
return nil
}
func (b *localController) Close() error {
// TODO: cancel current build and invoke
b.cancelRunningProcesses()
// TODO: cancel ongoing builds?
return nil
}
@ -76,5 +114,6 @@ func (b *localController) List(ctx context.Context) (res []string, _ error) {
}
func (b *localController) Disconnect(ctx context.Context, key string) error {
return nil // nop
b.cancelRunningProcesses()
return nil
}

View File

@ -25,6 +25,204 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type ListProcessesRequest 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 *ListProcessesRequest) Reset() { *m = ListProcessesRequest{} }
func (m *ListProcessesRequest) String() string { return proto.CompactTextString(m) }
func (*ListProcessesRequest) ProtoMessage() {}
func (*ListProcessesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{0}
}
func (m *ListProcessesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListProcessesRequest.Unmarshal(m, b)
}
func (m *ListProcessesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListProcessesRequest.Marshal(b, m, deterministic)
}
func (m *ListProcessesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListProcessesRequest.Merge(m, src)
}
func (m *ListProcessesRequest) XXX_Size() int {
return xxx_messageInfo_ListProcessesRequest.Size(m)
}
func (m *ListProcessesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ListProcessesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ListProcessesRequest proto.InternalMessageInfo
func (m *ListProcessesRequest) GetRef() string {
if m != nil {
return m.Ref
}
return ""
}
type ListProcessesResponse struct {
Infos []*ProcessInfo `protobuf:"bytes,1,rep,name=Infos,proto3" json:"Infos,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListProcessesResponse) Reset() { *m = ListProcessesResponse{} }
func (m *ListProcessesResponse) String() string { return proto.CompactTextString(m) }
func (*ListProcessesResponse) ProtoMessage() {}
func (*ListProcessesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{1}
}
func (m *ListProcessesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListProcessesResponse.Unmarshal(m, b)
}
func (m *ListProcessesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListProcessesResponse.Marshal(b, m, deterministic)
}
func (m *ListProcessesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListProcessesResponse.Merge(m, src)
}
func (m *ListProcessesResponse) XXX_Size() int {
return xxx_messageInfo_ListProcessesResponse.Size(m)
}
func (m *ListProcessesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ListProcessesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ListProcessesResponse proto.InternalMessageInfo
func (m *ListProcessesResponse) GetInfos() []*ProcessInfo {
if m != nil {
return m.Infos
}
return nil
}
type ProcessInfo struct {
ProcessID string `protobuf:"bytes,1,opt,name=ProcessID,proto3" json:"ProcessID,omitempty"`
InvokeConfig *InvokeConfig `protobuf:"bytes,2,opt,name=InvokeConfig,proto3" json:"InvokeConfig,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ProcessInfo) Reset() { *m = ProcessInfo{} }
func (m *ProcessInfo) String() string { return proto.CompactTextString(m) }
func (*ProcessInfo) ProtoMessage() {}
func (*ProcessInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{2}
}
func (m *ProcessInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ProcessInfo.Unmarshal(m, b)
}
func (m *ProcessInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ProcessInfo.Marshal(b, m, deterministic)
}
func (m *ProcessInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_ProcessInfo.Merge(m, src)
}
func (m *ProcessInfo) XXX_Size() int {
return xxx_messageInfo_ProcessInfo.Size(m)
}
func (m *ProcessInfo) XXX_DiscardUnknown() {
xxx_messageInfo_ProcessInfo.DiscardUnknown(m)
}
var xxx_messageInfo_ProcessInfo proto.InternalMessageInfo
func (m *ProcessInfo) GetProcessID() string {
if m != nil {
return m.ProcessID
}
return ""
}
func (m *ProcessInfo) GetInvokeConfig() *InvokeConfig {
if m != nil {
return m.InvokeConfig
}
return nil
}
type DisconnectProcessRequest struct {
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
ProcessID string `protobuf:"bytes,2,opt,name=ProcessID,proto3" json:"ProcessID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DisconnectProcessRequest) Reset() { *m = DisconnectProcessRequest{} }
func (m *DisconnectProcessRequest) String() string { return proto.CompactTextString(m) }
func (*DisconnectProcessRequest) ProtoMessage() {}
func (*DisconnectProcessRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{3}
}
func (m *DisconnectProcessRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DisconnectProcessRequest.Unmarshal(m, b)
}
func (m *DisconnectProcessRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DisconnectProcessRequest.Marshal(b, m, deterministic)
}
func (m *DisconnectProcessRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_DisconnectProcessRequest.Merge(m, src)
}
func (m *DisconnectProcessRequest) XXX_Size() int {
return xxx_messageInfo_DisconnectProcessRequest.Size(m)
}
func (m *DisconnectProcessRequest) XXX_DiscardUnknown() {
xxx_messageInfo_DisconnectProcessRequest.DiscardUnknown(m)
}
var xxx_messageInfo_DisconnectProcessRequest proto.InternalMessageInfo
func (m *DisconnectProcessRequest) GetRef() string {
if m != nil {
return m.Ref
}
return ""
}
func (m *DisconnectProcessRequest) GetProcessID() string {
if m != nil {
return m.ProcessID
}
return ""
}
type DisconnectProcessResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DisconnectProcessResponse) Reset() { *m = DisconnectProcessResponse{} }
func (m *DisconnectProcessResponse) String() string { return proto.CompactTextString(m) }
func (*DisconnectProcessResponse) ProtoMessage() {}
func (*DisconnectProcessResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{4}
}
func (m *DisconnectProcessResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DisconnectProcessResponse.Unmarshal(m, b)
}
func (m *DisconnectProcessResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DisconnectProcessResponse.Marshal(b, m, deterministic)
}
func (m *DisconnectProcessResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DisconnectProcessResponse.Merge(m, src)
}
func (m *DisconnectProcessResponse) XXX_Size() int {
return xxx_messageInfo_DisconnectProcessResponse.Size(m)
}
func (m *DisconnectProcessResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DisconnectProcessResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DisconnectProcessResponse proto.InternalMessageInfo
type BuildRequest struct {
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
Options *BuildOptions `protobuf:"bytes,2,opt,name=Options,proto3" json:"Options,omitempty"`
@ -37,7 +235,7 @@ func (m *BuildRequest) Reset() { *m = BuildRequest{} }
func (m *BuildRequest) String() string { return proto.CompactTextString(m) }
func (*BuildRequest) ProtoMessage() {}
func (*BuildRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{0}
return fileDescriptor_ed7f10298fa1d90f, []int{5}
}
func (m *BuildRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BuildRequest.Unmarshal(m, b)
@ -104,7 +302,7 @@ func (m *BuildOptions) Reset() { *m = BuildOptions{} }
func (m *BuildOptions) String() string { return proto.CompactTextString(m) }
func (*BuildOptions) ProtoMessage() {}
func (*BuildOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{1}
return fileDescriptor_ed7f10298fa1d90f, []int{6}
}
func (m *BuildOptions) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BuildOptions.Unmarshal(m, b)
@ -298,7 +496,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{2}
return fileDescriptor_ed7f10298fa1d90f, []int{7}
}
func (m *ExportEntry) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ExportEntry.Unmarshal(m, b)
@ -351,7 +549,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{3}
return fileDescriptor_ed7f10298fa1d90f, []int{8}
}
func (m *CacheOptionsEntry) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CacheOptionsEntry.Unmarshal(m, b)
@ -398,7 +596,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{4}
return fileDescriptor_ed7f10298fa1d90f, []int{9}
}
func (m *Attest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Attest.Unmarshal(m, b)
@ -451,7 +649,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{5}
return fileDescriptor_ed7f10298fa1d90f, []int{10}
}
func (m *SSH) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SSH.Unmarshal(m, b)
@ -498,7 +696,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{6}
return fileDescriptor_ed7f10298fa1d90f, []int{11}
}
func (m *Secret) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Secret.Unmarshal(m, b)
@ -550,7 +748,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{7}
return fileDescriptor_ed7f10298fa1d90f, []int{12}
}
func (m *UlimitOpt) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UlimitOpt.Unmarshal(m, b)
@ -590,7 +788,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{8}
return fileDescriptor_ed7f10298fa1d90f, []int{13}
}
func (m *Ulimit) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Ulimit.Unmarshal(m, b)
@ -648,7 +846,7 @@ func (m *CommonOptions) Reset() { *m = CommonOptions{} }
func (m *CommonOptions) String() string { return proto.CompactTextString(m) }
func (*CommonOptions) ProtoMessage() {}
func (*CommonOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{9}
return fileDescriptor_ed7f10298fa1d90f, []int{14}
}
func (m *CommonOptions) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CommonOptions.Unmarshal(m, b)
@ -721,7 +919,7 @@ func (m *BuildResponse) Reset() { *m = BuildResponse{} }
func (m *BuildResponse) String() string { return proto.CompactTextString(m) }
func (*BuildResponse) ProtoMessage() {}
func (*BuildResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{10}
return fileDescriptor_ed7f10298fa1d90f, []int{15}
}
func (m *BuildResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BuildResponse.Unmarshal(m, b)
@ -759,7 +957,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{11}
return fileDescriptor_ed7f10298fa1d90f, []int{16}
}
func (m *DisconnectRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DisconnectRequest.Unmarshal(m, b)
@ -796,7 +994,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{12}
return fileDescriptor_ed7f10298fa1d90f, []int{17}
}
func (m *DisconnectResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DisconnectResponse.Unmarshal(m, b)
@ -827,7 +1025,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{13}
return fileDescriptor_ed7f10298fa1d90f, []int{18}
}
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRequest.Unmarshal(m, b)
@ -865,7 +1063,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{14}
return fileDescriptor_ed7f10298fa1d90f, []int{19}
}
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListResponse.Unmarshal(m, b)
@ -906,7 +1104,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{15}
return fileDescriptor_ed7f10298fa1d90f, []int{20}
}
func (m *InputMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InputMessage.Unmarshal(m, b)
@ -980,7 +1178,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{16}
return fileDescriptor_ed7f10298fa1d90f, []int{21}
}
func (m *InputInitMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InputInitMessage.Unmarshal(m, b)
@ -1019,7 +1217,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{17}
return fileDescriptor_ed7f10298fa1d90f, []int{22}
}
func (m *DataMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DataMessage.Unmarshal(m, b)
@ -1063,7 +1261,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{18}
return fileDescriptor_ed7f10298fa1d90f, []int{23}
}
func (m *InputResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InputResponse.Unmarshal(m, b)
@ -1099,7 +1297,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{19}
return fileDescriptor_ed7f10298fa1d90f, []int{24}
}
func (m *Message) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Message.Unmarshal(m, b)
@ -1187,18 +1385,21 @@ func (*Message) XXX_OneofWrappers() []interface{} {
}
type InitMessage struct {
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
ContainerConfig *ContainerConfig `protobuf:"bytes,2,opt,name=ContainerConfig,proto3" json:"ContainerConfig,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
// If ProcessID already exists in the server, it tries to connect to it
// instead of invoking the new one. In this case, InvokeConfig will be ignored.
ProcessID string `protobuf:"bytes,2,opt,name=ProcessID,proto3" json:"ProcessID,omitempty"`
InvokeConfig *InvokeConfig `protobuf:"bytes,3,opt,name=InvokeConfig,proto3" json:"InvokeConfig,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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{20}
return fileDescriptor_ed7f10298fa1d90f, []int{25}
}
func (m *InitMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InitMessage.Unmarshal(m, b)
@ -1225,14 +1426,21 @@ func (m *InitMessage) GetRef() string {
return ""
}
func (m *InitMessage) GetContainerConfig() *ContainerConfig {
func (m *InitMessage) GetProcessID() string {
if m != nil {
return m.ContainerConfig
return m.ProcessID
}
return ""
}
func (m *InitMessage) GetInvokeConfig() *InvokeConfig {
if m != nil {
return m.InvokeConfig
}
return nil
}
type ContainerConfig struct {
type InvokeConfig struct {
Entrypoint []string `protobuf:"bytes,1,rep,name=Entrypoint,proto3" json:"Entrypoint,omitempty"`
Cmd []string `protobuf:"bytes,2,rep,name=Cmd,proto3" json:"Cmd,omitempty"`
Env []string `protobuf:"bytes,3,rep,name=Env,proto3" json:"Env,omitempty"`
@ -1241,91 +1449,99 @@ type ContainerConfig struct {
Cwd string `protobuf:"bytes,6,opt,name=Cwd,proto3" json:"Cwd,omitempty"`
NoCwd bool `protobuf:"varint,7,opt,name=NoCwd,proto3" json:"NoCwd,omitempty"`
Tty bool `protobuf:"varint,8,opt,name=Tty,proto3" json:"Tty,omitempty"`
Rollback bool `protobuf:"varint,9,opt,name=Rollback,proto3" json:"Rollback,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContainerConfig) Reset() { *m = ContainerConfig{} }
func (m *ContainerConfig) String() string { return proto.CompactTextString(m) }
func (*ContainerConfig) ProtoMessage() {}
func (*ContainerConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{21}
func (m *InvokeConfig) Reset() { *m = InvokeConfig{} }
func (m *InvokeConfig) String() string { return proto.CompactTextString(m) }
func (*InvokeConfig) ProtoMessage() {}
func (*InvokeConfig) Descriptor() ([]byte, []int) {
return fileDescriptor_ed7f10298fa1d90f, []int{26}
}
func (m *ContainerConfig) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContainerConfig.Unmarshal(m, b)
func (m *InvokeConfig) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InvokeConfig.Unmarshal(m, b)
}
func (m *ContainerConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContainerConfig.Marshal(b, m, deterministic)
func (m *InvokeConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InvokeConfig.Marshal(b, m, deterministic)
}
func (m *ContainerConfig) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContainerConfig.Merge(m, src)
func (m *InvokeConfig) XXX_Merge(src proto.Message) {
xxx_messageInfo_InvokeConfig.Merge(m, src)
}
func (m *ContainerConfig) XXX_Size() int {
return xxx_messageInfo_ContainerConfig.Size(m)
func (m *InvokeConfig) XXX_Size() int {
return xxx_messageInfo_InvokeConfig.Size(m)
}
func (m *ContainerConfig) XXX_DiscardUnknown() {
xxx_messageInfo_ContainerConfig.DiscardUnknown(m)
func (m *InvokeConfig) XXX_DiscardUnknown() {
xxx_messageInfo_InvokeConfig.DiscardUnknown(m)
}
var xxx_messageInfo_ContainerConfig proto.InternalMessageInfo
var xxx_messageInfo_InvokeConfig proto.InternalMessageInfo
func (m *ContainerConfig) GetEntrypoint() []string {
func (m *InvokeConfig) GetEntrypoint() []string {
if m != nil {
return m.Entrypoint
}
return nil
}
func (m *ContainerConfig) GetCmd() []string {
func (m *InvokeConfig) GetCmd() []string {
if m != nil {
return m.Cmd
}
return nil
}
func (m *ContainerConfig) GetEnv() []string {
func (m *InvokeConfig) GetEnv() []string {
if m != nil {
return m.Env
}
return nil
}
func (m *ContainerConfig) GetUser() string {
func (m *InvokeConfig) GetUser() string {
if m != nil {
return m.User
}
return ""
}
func (m *ContainerConfig) GetNoUser() bool {
func (m *InvokeConfig) GetNoUser() bool {
if m != nil {
return m.NoUser
}
return false
}
func (m *ContainerConfig) GetCwd() string {
func (m *InvokeConfig) GetCwd() string {
if m != nil {
return m.Cwd
}
return ""
}
func (m *ContainerConfig) GetNoCwd() bool {
func (m *InvokeConfig) GetNoCwd() bool {
if m != nil {
return m.NoCwd
}
return false
}
func (m *ContainerConfig) GetTty() bool {
func (m *InvokeConfig) GetTty() bool {
if m != nil {
return m.Tty
}
return false
}
func (m *InvokeConfig) GetRollback() bool {
if m != nil {
return m.Rollback
}
return false
}
type FdMessage struct {
Fd uint32 `protobuf:"varint,1,opt,name=Fd,proto3" json:"Fd,omitempty"`
EOF bool `protobuf:"varint,2,opt,name=EOF,proto3" json:"EOF,omitempty"`
@ -1339,7 +1555,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{22}
return fileDescriptor_ed7f10298fa1d90f, []int{27}
}
func (m *FdMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FdMessage.Unmarshal(m, b)
@ -1392,7 +1608,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{23}
return fileDescriptor_ed7f10298fa1d90f, []int{28}
}
func (m *ResizeMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ResizeMessage.Unmarshal(m, b)
@ -1439,7 +1655,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{24}
return fileDescriptor_ed7f10298fa1d90f, []int{29}
}
func (m *SignalMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SignalMessage.Unmarshal(m, b)
@ -1477,7 +1693,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{25}
return fileDescriptor_ed7f10298fa1d90f, []int{30}
}
func (m *StatusRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StatusRequest.Unmarshal(m, b)
@ -1518,7 +1734,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{26}
return fileDescriptor_ed7f10298fa1d90f, []int{31}
}
func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StatusResponse.Unmarshal(m, b)
@ -1576,7 +1792,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{27}
return fileDescriptor_ed7f10298fa1d90f, []int{32}
}
func (m *InfoRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InfoRequest.Unmarshal(m, b)
@ -1607,7 +1823,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{28}
return fileDescriptor_ed7f10298fa1d90f, []int{33}
}
func (m *InfoResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InfoResponse.Unmarshal(m, b)
@ -1647,7 +1863,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{29}
return fileDescriptor_ed7f10298fa1d90f, []int{34}
}
func (m *BuildxVersion) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BuildxVersion.Unmarshal(m, b)
@ -1689,6 +1905,11 @@ func (m *BuildxVersion) GetRevision() string {
}
func init() {
proto.RegisterType((*ListProcessesRequest)(nil), "buildx.controller.v1.ListProcessesRequest")
proto.RegisterType((*ListProcessesResponse)(nil), "buildx.controller.v1.ListProcessesResponse")
proto.RegisterType((*ProcessInfo)(nil), "buildx.controller.v1.ProcessInfo")
proto.RegisterType((*DisconnectProcessRequest)(nil), "buildx.controller.v1.DisconnectProcessRequest")
proto.RegisterType((*DisconnectProcessResponse)(nil), "buildx.controller.v1.DisconnectProcessResponse")
proto.RegisterType((*BuildRequest)(nil), "buildx.controller.v1.BuildRequest")
proto.RegisterType((*BuildOptions)(nil), "buildx.controller.v1.BuildOptions")
proto.RegisterMapType((map[string]string)(nil), "buildx.controller.v1.BuildOptions.BuildArgsEntry")
@ -1717,7 +1938,7 @@ func init() {
proto.RegisterType((*InputResponse)(nil), "buildx.controller.v1.InputResponse")
proto.RegisterType((*Message)(nil), "buildx.controller.v1.Message")
proto.RegisterType((*InitMessage)(nil), "buildx.controller.v1.InitMessage")
proto.RegisterType((*ContainerConfig)(nil), "buildx.controller.v1.ContainerConfig")
proto.RegisterType((*InvokeConfig)(nil), "buildx.controller.v1.InvokeConfig")
proto.RegisterType((*FdMessage)(nil), "buildx.controller.v1.FdMessage")
proto.RegisterType((*ResizeMessage)(nil), "buildx.controller.v1.ResizeMessage")
proto.RegisterType((*SignalMessage)(nil), "buildx.controller.v1.SignalMessage")
@ -1731,111 +1952,119 @@ func init() {
func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) }
var fileDescriptor_ed7f10298fa1d90f = []byte{
// 1657 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xdd, 0x6e, 0xdb, 0xc6,
0x12, 0x3e, 0x94, 0x64, 0xfd, 0x8c, 0x2c, 0xc7, 0xd9, 0xe3, 0x04, 0x3c, 0x3a, 0x39, 0x89, 0xc3,
0xfc, 0x1c, 0x01, 0x29, 0xe4, 0xc4, 0x69, 0x9a, 0xdf, 0x02, 0xb5, 0x25, 0x0b, 0x76, 0xe1, 0x3f,
0x50, 0x4e, 0x82, 0xb6, 0x40, 0x03, 0x5a, 0x5a, 0xcb, 0x84, 0x28, 0xae, 0xca, 0x5d, 0xc9, 0x56,
0xaf, 0x7a, 0xd3, 0xdb, 0xbe, 0x47, 0xd1, 0x47, 0xe8, 0x55, 0xdf, 0xa1, 0x0f, 0xd2, 0x47, 0x28,
0x76, 0x76, 0x49, 0x51, 0x96, 0x28, 0xdb, 0xe8, 0x95, 0x77, 0x86, 0xdf, 0x37, 0xb3, 0x3b, 0x3b,
0x3f, 0x2b, 0xc3, 0x72, 0x8b, 0xf9, 0x22, 0x60, 0x9e, 0x47, 0x83, 0x6a, 0x3f, 0x60, 0x82, 0x91,
0x95, 0xe3, 0x81, 0xeb, 0xb5, 0xcf, 0xab, 0xb1, 0x0f, 0xc3, 0x67, 0xe5, 0xb7, 0x1d, 0x57, 0x9c,
0x0e, 0x8e, 0xab, 0x2d, 0xd6, 0x5b, 0xeb, 0xb1, 0xe3, 0xd1, 0x1a, 0xa2, 0xba, 0xae, 0x58, 0x73,
0xfa, 0xee, 0x1a, 0xa7, 0xc1, 0xd0, 0x6d, 0x51, 0xbe, 0xa6, 0x49, 0xe1, 0x5f, 0x65, 0xd2, 0xfa,
0x1e, 0x16, 0x37, 0x25, 0xdc, 0xa6, 0x3f, 0x0c, 0x28, 0x17, 0x64, 0x19, 0xd2, 0x36, 0x3d, 0x31,
0x8d, 0x55, 0xa3, 0x52, 0xb0, 0xe5, 0x92, 0xbc, 0x83, 0xdc, 0x41, 0x5f, 0xb8, 0xcc, 0xe7, 0x66,
0x6a, 0xd5, 0xa8, 0x14, 0xd7, 0xad, 0xea, 0xac, 0x6d, 0x54, 0xd1, 0x8c, 0x46, 0xda, 0x21, 0xc5,
0xfa, 0x19, 0xb4, 0x03, 0xad, 0x20, 0xab, 0x50, 0xac, 0x31, 0x5f, 0xd0, 0x73, 0x71, 0xe8, 0x88,
0x53, 0xed, 0x28, 0xae, 0x22, 0x8f, 0x61, 0xa9, 0xce, 0x5a, 0x5d, 0x1a, 0x9c, 0xb8, 0x1e, 0xdd,
0x77, 0x7a, 0x14, 0xfd, 0x16, 0xec, 0x0b, 0x5a, 0x72, 0x07, 0x0a, 0x87, 0x81, 0xeb, 0x8b, 0xc6,
0xc0, 0x6f, 0x99, 0x69, 0x84, 0x8c, 0x15, 0xe4, 0x3b, 0x28, 0x49, 0x54, 0x5b, 0x5b, 0xe6, 0x66,
0x66, 0x35, 0x5d, 0x29, 0xae, 0xbf, 0xb8, 0x7c, 0xf3, 0xd5, 0x09, 0xde, 0x96, 0x2f, 0x82, 0x91,
0x3d, 0x69, 0x8b, 0xac, 0xc0, 0xc2, 0x86, 0xe7, 0xb1, 0x33, 0x73, 0x61, 0x35, 0x5d, 0x29, 0xd8,
0x4a, 0x20, 0x5f, 0x40, 0x6e, 0x43, 0x08, 0xca, 0x05, 0x37, 0xb3, 0xe8, 0xec, 0xce, 0x6c, 0x67,
0x0a, 0x64, 0x87, 0x60, 0x72, 0x00, 0x05, 0xf4, 0xbf, 0x11, 0x74, 0xb8, 0x99, 0x43, 0xe6, 0xb3,
0x2b, 0x6c, 0x33, 0xe2, 0xa8, 0x2d, 0x8e, 0x6d, 0x90, 0x2d, 0x28, 0xd4, 0x9c, 0xd6, 0x29, 0x6d,
0x04, 0xac, 0x67, 0xe6, 0xd1, 0xe0, 0xff, 0x67, 0x1b, 0x44, 0x98, 0x36, 0xa8, 0xcd, 0x44, 0x4c,
0xb2, 0x01, 0x39, 0x14, 0x8e, 0x98, 0x59, 0xb8, 0x9e, 0x91, 0x90, 0x47, 0x2c, 0x58, 0xac, 0x75,
0x02, 0x36, 0xe8, 0x1f, 0x3a, 0x01, 0xf5, 0x85, 0x09, 0x78, 0x4d, 0x13, 0x3a, 0xf2, 0x16, 0x72,
0x5b, 0xe7, 0x7d, 0x16, 0x08, 0x6e, 0x16, 0xd1, 0xcd, 0xfd, 0xd9, 0x6e, 0x14, 0x48, 0x3b, 0xd0,
0x0c, 0x72, 0x17, 0x60, 0xeb, 0x5c, 0x04, 0xce, 0x36, 0x93, 0x61, 0x5f, 0xc4, 0xeb, 0x88, 0x69,
0x48, 0x03, 0xb2, 0xbb, 0xce, 0x31, 0xf5, 0xb8, 0x59, 0x42, 0xdb, 0xd5, 0x2b, 0x04, 0x56, 0x11,
0x94, 0x23, 0xcd, 0x96, 0x69, 0xbb, 0x4f, 0xc5, 0x19, 0x0b, 0xba, 0x7b, 0xac, 0x4d, 0xcd, 0x25,
0x95, 0xb6, 0x31, 0x15, 0x79, 0x08, 0xa5, 0x7d, 0xa6, 0x82, 0xe7, 0x7a, 0x82, 0x06, 0xe6, 0x0d,
0xdc, 0xcc, 0xa4, 0x12, 0x93, 0xd6, 0x73, 0xc4, 0x09, 0x0b, 0x7a, 0xdc, 0x5c, 0x46, 0xc4, 0x58,
0x21, 0x33, 0xa8, 0x49, 0x5b, 0x01, 0x15, 0xdc, 0xbc, 0x39, 0x2f, 0x83, 0x14, 0xc8, 0x0e, 0xc1,
0xc4, 0x84, 0x5c, 0xf3, 0xb4, 0xd7, 0x74, 0x7f, 0xa4, 0x26, 0x59, 0x35, 0x2a, 0x69, 0x3b, 0x14,
0xc9, 0x13, 0x48, 0x37, 0x9b, 0xdb, 0xe6, 0xbf, 0xd1, 0xda, 0x7f, 0x12, 0xac, 0x35, 0xb7, 0x6d,
0x89, 0x22, 0x04, 0x32, 0x47, 0x4e, 0x87, 0x9b, 0x2b, 0xb8, 0x2f, 0x5c, 0x93, 0xdb, 0x90, 0x3d,
0x72, 0x82, 0x0e, 0x15, 0xe6, 0x2d, 0x3c, 0xb3, 0x96, 0xc8, 0x6b, 0xc8, 0xbd, 0xf7, 0xdc, 0x9e,
0x2b, 0xb8, 0x79, 0x1b, 0xdb, 0xc2, 0xbd, 0xd9, 0xc6, 0x15, 0xe8, 0xa0, 0x2f, 0xec, 0x10, 0x4f,
0x5e, 0x42, 0xe6, 0xa0, 0x2f, 0xb8, 0x69, 0x22, 0xef, 0x41, 0x42, 0x52, 0xb1, 0x5e, 0x8f, 0xf9,
0x61, 0x3f, 0x41, 0x42, 0xf9, 0x2b, 0x20, 0xd3, 0xb5, 0x29, 0x5b, 0x56, 0x97, 0x8e, 0xc2, 0x96,
0xd5, 0xa5, 0x23, 0x59, 0x9e, 0x43, 0xc7, 0x1b, 0x84, 0x8d, 0x43, 0x09, 0x6f, 0x52, 0xaf, 0x8c,
0xf2, 0x3b, 0x58, 0x9a, 0x2c, 0x9b, 0x6b, 0xb1, 0x5f, 0x43, 0x31, 0x96, 0x1b, 0xd7, 0xa1, 0x5a,
0x7f, 0x18, 0x50, 0x8c, 0x25, 0x30, 0x86, 0x7a, 0xd4, 0xa7, 0x9a, 0x8c, 0x6b, 0xb2, 0x09, 0x0b,
0x1b, 0x42, 0x04, 0xb2, 0xcf, 0xca, 0xdb, 0xfa, 0xec, 0xd2, 0x32, 0xa8, 0x22, 0x5c, 0x25, 0xaa,
0xa2, 0xca, 0x3c, 0xad, 0x53, 0x2e, 0x5c, 0xdf, 0x91, 0x81, 0xd3, 0x6d, 0x31, 0xae, 0x2a, 0xbf,
0x02, 0x18, 0xd3, 0xae, 0x75, 0x86, 0xdf, 0x0c, 0xb8, 0x39, 0x55, 0xeb, 0x33, 0x4f, 0xb2, 0x3d,
0x79, 0x92, 0xf5, 0x2b, 0xf6, 0x8d, 0xe9, 0xf3, 0xfc, 0x83, 0xdd, 0xee, 0x43, 0x56, 0x35, 0xd8,
0x99, 0x3b, 0x2c, 0x43, 0xbe, 0xee, 0x72, 0xe7, 0xd8, 0xa3, 0x6d, 0xa4, 0xe6, 0xed, 0x48, 0xc6,
0xee, 0x8e, 0xbb, 0x57, 0xd1, 0x53, 0x82, 0xa5, 0x2a, 0x89, 0x2c, 0x41, 0x6a, 0xa7, 0xae, 0x4d,
0xa5, 0x76, 0xea, 0x12, 0x2c, 0xa7, 0x96, 0x3a, 0x6a, 0xc1, 0x56, 0x82, 0xd5, 0x80, 0xac, 0xaa,
0xcd, 0x29, 0x7c, 0x19, 0xf2, 0x0d, 0xd7, 0xa3, 0x38, 0xfc, 0xd4, 0x9e, 0x23, 0x59, 0x1e, 0x6f,
0xcb, 0x1f, 0x6a, 0xb7, 0x72, 0x69, 0xfd, 0x6a, 0x40, 0x21, 0xaa, 0x20, 0x52, 0x83, 0x2c, 0x9e,
0x8f, 0x9b, 0x06, 0xc6, 0xf5, 0xc9, 0x25, 0x25, 0x57, 0xfd, 0x80, 0x68, 0xdd, 0xc9, 0x14, 0xb5,
0xfc, 0x11, 0x8a, 0x31, 0xf5, 0x8c, 0x90, 0xae, 0xc7, 0x43, 0x9a, 0xd8, 0x82, 0x94, 0x93, 0x78,
0xc0, 0xeb, 0x90, 0x55, 0x4a, 0x19, 0x70, 0x9c, 0xdb, 0x3a, 0xe0, 0x38, 0xad, 0x09, 0x64, 0xb6,
0x9d, 0x40, 0x05, 0x3b, 0x6d, 0xe3, 0x5a, 0xea, 0x9a, 0xec, 0x44, 0xe0, 0x81, 0xd3, 0x36, 0xae,
0xad, 0xdf, 0x0d, 0x28, 0x4d, 0xd4, 0xbe, 0x6c, 0x6e, 0x58, 0xb3, 0x34, 0xd0, 0x06, 0x43, 0x51,
0x4e, 0x97, 0x3d, 0x2a, 0x9c, 0xb6, 0x23, 0x1c, 0x19, 0x43, 0x1d, 0xcf, 0x09, 0x9d, 0x64, 0xeb,
0x0e, 0x8c, 0x6e, 0xf2, 0x76, 0x28, 0x4a, 0xef, 0x87, 0x03, 0xcf, 0x33, 0x33, 0xa8, 0xc6, 0xb5,
0x1a, 0x27, 0xb2, 0xbe, 0x0e, 0x07, 0xfc, 0xd4, 0x5c, 0xc0, 0x2f, 0x31, 0xcd, 0xf8, 0xfb, 0x2e,
0x73, 0xda, 0x66, 0x36, 0xfe, 0x5d, 0x6a, 0x70, 0xf7, 0xfa, 0x3d, 0xc5, 0xfb, 0xcc, 0xe7, 0x94,
0x50, 0x58, 0x56, 0xdf, 0x69, 0x10, 0xea, 0xf4, 0xed, 0xbd, 0x9e, 0x33, 0x8a, 0x42, 0x68, 0xf5,
0x22, 0x57, 0xdd, 0xe5, 0x94, 0xc9, 0x72, 0x0d, 0x6e, 0xcd, 0x84, 0x5e, 0xab, 0x64, 0x1e, 0xc1,
0xcd, 0xba, 0xcb, 0x5b, 0xcc, 0xf7, 0x69, 0x4b, 0x24, 0xbe, 0x08, 0xad, 0x15, 0x20, 0x71, 0x98,
0xf2, 0x66, 0xdd, 0x83, 0xe2, 0xae, 0xcb, 0xe7, 0xd0, 0x2c, 0x58, 0x54, 0x00, 0x1d, 0x19, 0x02,
0x99, 0x2e, 0x1d, 0xa9, 0x5c, 0x2e, 0xd8, 0xb8, 0xb6, 0x7e, 0x31, 0x60, 0x71, 0xc7, 0xef, 0x0f,
0xc4, 0x1e, 0xe5, 0xdc, 0xe9, 0x50, 0xf2, 0x0e, 0x32, 0x3b, 0xbe, 0x2b, 0xd0, 0x4e, 0x71, 0xfd,
0xf1, 0xec, 0x90, 0x21, 0x43, 0xc2, 0x34, 0x6b, 0xfb, 0x5f, 0x36, 0xb2, 0xe4, 0xa4, 0xa9, 0x3b,
0xc2, 0xd1, 0x99, 0x9c, 0xf0, 0xae, 0x90, 0x88, 0x18, 0x51, 0x8a, 0x9b, 0x39, 0x58, 0x40, 0xa3,
0xd6, 0x43, 0x58, 0xbe, 0x68, 0x7d, 0xc6, 0xd1, 0x9e, 0x43, 0x31, 0x66, 0x05, 0xeb, 0xf8, 0xa0,
0x81, 0x80, 0xbc, 0x2d, 0x97, 0xf2, 0xac, 0xd1, 0x46, 0x16, 0x95, 0x0f, 0xeb, 0x06, 0x94, 0xd0,
0x74, 0x14, 0xc1, 0x9f, 0x52, 0x90, 0x0b, 0x4d, 0xbc, 0x9c, 0x38, 0xf7, 0xfd, 0xa4, 0x73, 0x4f,
0x1f, 0xf9, 0x05, 0x64, 0xa2, 0x5a, 0x48, 0x1c, 0xca, 0x8d, 0x76, 0x8c, 0x86, 0x65, 0xf2, 0x25,
0x64, 0x6d, 0xca, 0xe5, 0x03, 0x22, 0x3d, 0x6f, 0x2a, 0x2b, 0xcc, 0x98, 0xac, 0x49, 0x92, 0xde,
0x74, 0x3b, 0xbe, 0xa3, 0xaa, 0x29, 0x91, 0xae, 0x30, 0x31, 0xba, 0x52, 0x8c, 0xc3, 0xdd, 0x87,
0xe2, 0xdc, 0x48, 0x93, 0x03, 0xb8, 0x21, 0xa7, 0xbf, 0xe3, 0xfa, 0x34, 0xa8, 0x31, 0xff, 0xc4,
0xed, 0xe8, 0x93, 0x3e, 0x4a, 0x7a, 0x46, 0x4c, 0x80, 0xed, 0x8b, 0x6c, 0x59, 0xb1, 0x17, 0x75,
0x58, 0xe5, 0xb2, 0x78, 0xfa, 0xcc, 0xf5, 0x85, 0xce, 0xcf, 0x98, 0x46, 0x6e, 0xab, 0xd6, 0x6b,
0xeb, 0x8e, 0x2f, 0x97, 0xe3, 0xce, 0x9d, 0xd6, 0x9d, 0x5b, 0xde, 0xf8, 0x7b, 0x4e, 0x03, 0x8c,
0x47, 0xc1, 0xc6, 0xb5, 0x7c, 0x4b, 0xed, 0x33, 0xd4, 0xaa, 0xce, 0xa2, 0x25, 0xb4, 0x77, 0xa6,
0xda, 0x89, 0xb4, 0x77, 0x86, 0x23, 0x68, 0x9f, 0x49, 0x5d, 0x0e, 0x81, 0x4a, 0x90, 0xb8, 0x23,
0x31, 0x32, 0xf3, 0x2a, 0xaf, 0x8e, 0xc4, 0xc8, 0xda, 0x80, 0x42, 0x74, 0x97, 0x72, 0xd4, 0x34,
0xda, 0x18, 0xac, 0x92, 0x9d, 0x6a, 0xb4, 0xc3, 0x34, 0x4c, 0x4d, 0xa7, 0x61, 0x3a, 0x96, 0x86,
0x2f, 0xa1, 0x34, 0x71, 0xab, 0x12, 0x64, 0xb3, 0x33, 0xae, 0x0d, 0xe1, 0x5a, 0xea, 0x6a, 0xcc,
0x53, 0xbf, 0x00, 0x4b, 0x36, 0xae, 0xad, 0x07, 0x50, 0x9a, 0xb8, 0xcf, 0x59, 0x6d, 0xdf, 0xba,
0x0f, 0xa5, 0xa6, 0x70, 0xc4, 0x80, 0x27, 0xf7, 0x85, 0xbf, 0x0c, 0x58, 0x0a, 0x31, 0xba, 0x35,
0x7c, 0x0e, 0xf9, 0x21, 0x0d, 0x04, 0x3d, 0x8f, 0x46, 0x9d, 0x59, 0x95, 0x3f, 0x6d, 0xab, 0xe1,
0x4f, 0x5b, 0x79, 0xb5, 0x1f, 0x10, 0x61, 0x47, 0x48, 0xf2, 0x06, 0xf2, 0x1c, 0xed, 0xd0, 0xf0,
0xe1, 0x71, 0x37, 0x89, 0xa5, 0xfd, 0x45, 0x78, 0xb2, 0x06, 0x19, 0x8f, 0x75, 0x38, 0xde, 0x60,
0x71, 0xfd, 0xbf, 0x49, 0xbc, 0x5d, 0xd6, 0xb1, 0x11, 0x48, 0xde, 0x42, 0xfe, 0xcc, 0x09, 0x7c,
0xd7, 0xef, 0x84, 0x3f, 0x2d, 0xef, 0x25, 0x91, 0x3e, 0x2a, 0x9c, 0x1d, 0x11, 0xac, 0x92, 0x4c,
0xf3, 0x13, 0xa6, 0x63, 0x62, 0x7d, 0x23, 0x9b, 0x9e, 0x14, 0xf5, 0xf1, 0x77, 0xa0, 0xa4, 0x92,
0xf9, 0x03, 0x0d, 0xb8, 0x7c, 0xc6, 0x19, 0xf3, 0x8a, 0x6a, 0x33, 0x0e, 0xb5, 0x27, 0x99, 0xd6,
0x27, 0x3d, 0x8f, 0x42, 0x85, 0x9c, 0x87, 0x7d, 0xa7, 0xd5, 0x75, 0x3a, 0xe1, 0x3d, 0x85, 0xa2,
0xfc, 0x32, 0xd4, 0xfe, 0xd4, 0x64, 0x08, 0x45, 0xf9, 0x66, 0x09, 0xe8, 0xd0, 0xe5, 0xe3, 0x17,
0x65, 0x24, 0xaf, 0xff, 0x99, 0x01, 0xa8, 0x45, 0xfb, 0x21, 0x87, 0xb0, 0x80, 0xfe, 0x88, 0x35,
0x77, 0xba, 0xe1, 0xb9, 0xcb, 0x0f, 0xae, 0x30, 0x01, 0xc9, 0x7b, 0xc8, 0xaa, 0xdb, 0x22, 0x49,
0x4d, 0x25, 0x9e, 0x5f, 0xe5, 0x87, 0xf3, 0x41, 0xca, 0xe8, 0x53, 0x83, 0xd8, 0xba, 0xe5, 0x24,
0x6d, 0x34, 0x3e, 0x85, 0x92, 0x36, 0x3a, 0xd1, 0xbe, 0x2b, 0x06, 0xf9, 0x1a, 0xb2, 0x3b, 0xfe,
0x90, 0x75, 0x29, 0xf9, 0xdf, 0x6c, 0x42, 0x68, 0x6f, 0xfe, 0xe7, 0x8a, 0xf1, 0xd4, 0x20, 0x7b,
0x90, 0x91, 0xd3, 0x92, 0x24, 0xb4, 0xfe, 0xd8, 0xa8, 0x2d, 0x5b, 0xf3, 0x20, 0x3a, 0x8a, 0x9f,
0x00, 0xc6, 0x33, 0x9b, 0x24, 0xfc, 0x90, 0x9f, 0x1a, 0xfe, 0xe5, 0xca, 0xe5, 0x40, 0xed, 0x60,
0x4f, 0x0e, 0xac, 0x13, 0x46, 0x12, 0x47, 0x55, 0x94, 0xee, 0x65, 0x6b, 0x1e, 0x44, 0x99, 0xdb,
0xcc, 0x7c, 0x9b, 0xea, 0x1f, 0x1f, 0x67, 0xf1, 0x9f, 0x54, 0xcf, 0xff, 0x0e, 0x00, 0x00, 0xff,
0xff, 0xf4, 0x2e, 0xaa, 0xc4, 0x0b, 0x13, 0x00, 0x00,
// 1790 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6e, 0x23, 0xc7,
0x11, 0xce, 0x90, 0x14, 0x7f, 0x8a, 0xa2, 0xac, 0xed, 0x68, 0x8d, 0x31, 0xed, 0x78, 0xb5, 0xb3,
0x1b, 0x87, 0xc8, 0x06, 0x94, 0x2d, 0xc7, 0x59, 0xaf, 0x77, 0x03, 0x44, 0xa2, 0x44, 0x48, 0xc6,
0xea, 0x07, 0x4d, 0xed, 0x1a, 0x49, 0x80, 0x18, 0x43, 0xb2, 0x45, 0x0d, 0x38, 0x9c, 0x66, 0xa6,
0x9b, 0x94, 0x98, 0x53, 0x2e, 0xbe, 0xe6, 0x3d, 0x82, 0x5c, 0x73, 0xcb, 0x29, 0xef, 0x90, 0x07,
0xc9, 0x23, 0x04, 0x5d, 0xdd, 0x33, 0x9c, 0x11, 0x39, 0x94, 0x14, 0x9f, 0xd8, 0x55, 0xf3, 0x55,
0x55, 0x57, 0x75, 0xfd, 0x74, 0x13, 0x36, 0x7b, 0x3c, 0x90, 0x21, 0xf7, 0x7d, 0x16, 0x36, 0xc7,
0x21, 0x97, 0x9c, 0x6c, 0x75, 0x27, 0x9e, 0xdf, 0xbf, 0x69, 0x26, 0x3e, 0x4c, 0xbf, 0xa8, 0xbf,
0x1e, 0x78, 0xf2, 0x6a, 0xd2, 0x6d, 0xf6, 0xf8, 0x68, 0x67, 0xc4, 0xbb, 0xb3, 0x1d, 0x44, 0x0d,
0x3d, 0xb9, 0xe3, 0x8e, 0xbd, 0x1d, 0xc1, 0xc2, 0xa9, 0xd7, 0x63, 0x62, 0xc7, 0x08, 0x45, 0xbf,
0x5a, 0xa5, 0xd3, 0x80, 0xad, 0xb7, 0x9e, 0x90, 0xe7, 0x21, 0xef, 0x31, 0x21, 0x98, 0xa0, 0xec,
0xcf, 0x13, 0x26, 0x24, 0xd9, 0x84, 0x3c, 0x65, 0x97, 0xb6, 0xb5, 0x6d, 0x35, 0x2a, 0x54, 0x2d,
0x9d, 0x73, 0x78, 0x7c, 0x0b, 0x29, 0xc6, 0x3c, 0x10, 0x8c, 0xbc, 0x84, 0xb5, 0xe3, 0xe0, 0x92,
0x0b, 0xdb, 0xda, 0xce, 0x37, 0xaa, 0xbb, 0x4f, 0x9b, 0xcb, 0x76, 0xd9, 0x34, 0x72, 0x0a, 0x49,
0x35, 0xde, 0x11, 0x50, 0x4d, 0x70, 0xc9, 0x27, 0x50, 0x89, 0xc8, 0x03, 0x63, 0x78, 0xce, 0x20,
0x6d, 0x58, 0x3f, 0x0e, 0xa6, 0x7c, 0xc8, 0x5a, 0x3c, 0xb8, 0xf4, 0x06, 0x76, 0x6e, 0xdb, 0x6a,
0x54, 0x77, 0x9d, 0xe5, 0xc6, 0x92, 0x48, 0x9a, 0x92, 0x73, 0xbe, 0x05, 0xfb, 0xc0, 0x13, 0x3d,
0x1e, 0x04, 0xac, 0x17, 0x39, 0x93, 0xe9, 0x74, 0x7a, 0x4f, 0xb9, 0x5b, 0x7b, 0x72, 0x3e, 0x86,
0x8f, 0x96, 0xe8, 0xd2, 0x61, 0x71, 0xfe, 0x04, 0xeb, 0xfb, 0x6a, 0x6f, 0xd9, 0xca, 0xdf, 0x40,
0xe9, 0x6c, 0x2c, 0x3d, 0x1e, 0x88, 0xd5, 0xde, 0xa0, 0x1a, 0x83, 0xa4, 0x91, 0x88, 0xf3, 0x03,
0x18, 0x03, 0x86, 0x41, 0xb6, 0xa1, 0xda, 0xe2, 0x81, 0x64, 0x37, 0xf2, 0xdc, 0x95, 0x57, 0xc6,
0x50, 0x92, 0x45, 0x3e, 0x83, 0x8d, 0x03, 0xde, 0x1b, 0xb2, 0xf0, 0xd2, 0xf3, 0xd9, 0xa9, 0x3b,
0x62, 0xc6, 0xa5, 0x5b, 0x5c, 0xed, 0xb5, 0x17, 0xc8, 0xf6, 0x24, 0xe8, 0xd9, 0xf9, 0xc8, 0x6b,
0xc3, 0x20, 0x7f, 0x84, 0x9a, 0x42, 0xf5, 0x8d, 0x66, 0x61, 0x17, 0xf0, 0xdc, 0xbf, 0xba, 0x7b,
0xf3, 0xcd, 0x94, 0xdc, 0x61, 0x20, 0xc3, 0x19, 0x4d, 0xeb, 0x22, 0x5b, 0xb0, 0xb6, 0xe7, 0xfb,
0xfc, 0xda, 0x5e, 0xdb, 0xce, 0x37, 0x2a, 0x54, 0x13, 0xe4, 0x37, 0x50, 0xda, 0x93, 0x92, 0x09,
0x29, 0xec, 0x22, 0x1a, 0xfb, 0x64, 0xb9, 0x31, 0x0d, 0xa2, 0x11, 0x98, 0x9c, 0x41, 0x05, 0xed,
0xef, 0x85, 0x03, 0x61, 0x97, 0x50, 0xf2, 0x8b, 0x7b, 0x6c, 0x33, 0x96, 0xd1, 0x5b, 0x9c, 0xeb,
0x20, 0x87, 0x50, 0x69, 0xb9, 0xbd, 0x2b, 0xd6, 0x0e, 0xf9, 0xc8, 0x2e, 0xa3, 0xc2, 0x5f, 0x2c,
0x57, 0x88, 0x30, 0xa3, 0xd0, 0xa8, 0x89, 0x25, 0xc9, 0x1e, 0x94, 0x90, 0xb8, 0xe0, 0x76, 0xe5,
0x61, 0x4a, 0x22, 0x39, 0xe2, 0xc0, 0x7a, 0x6b, 0x10, 0xf2, 0xc9, 0xf8, 0xdc, 0x0d, 0x59, 0x20,
0x6d, 0xc0, 0x63, 0x4a, 0xf1, 0xc8, 0x6b, 0x28, 0x1d, 0xde, 0x8c, 0x79, 0x28, 0x85, 0x5d, 0x5d,
0x55, 0x9b, 0x1a, 0x64, 0x0c, 0x18, 0x09, 0xf2, 0x29, 0xc0, 0xe1, 0x8d, 0x0c, 0xdd, 0x23, 0xae,
0xc2, 0xbe, 0x8e, 0xc7, 0x91, 0xe0, 0x90, 0x36, 0x14, 0xdf, 0xba, 0x5d, 0xe6, 0x0b, 0xbb, 0x86,
0xba, 0x9b, 0xf7, 0x08, 0xac, 0x16, 0xd0, 0x86, 0x8c, 0xb4, 0x4a, 0xdb, 0x53, 0x26, 0xaf, 0x79,
0x38, 0x3c, 0xe1, 0x7d, 0x66, 0x6f, 0xe8, 0xb4, 0x4d, 0xb0, 0xc8, 0x73, 0xa8, 0x9d, 0x72, 0x1d,
0x3c, 0xcf, 0x97, 0x2c, 0xb4, 0x3f, 0xc0, 0xcd, 0xa4, 0x99, 0x98, 0xb4, 0xbe, 0x2b, 0x2f, 0x79,
0x38, 0x12, 0xf6, 0x26, 0x22, 0xe6, 0x0c, 0x95, 0x41, 0x1d, 0xd6, 0x0b, 0x99, 0x14, 0xf6, 0xa3,
0x55, 0x19, 0xa4, 0x41, 0x34, 0x02, 0x13, 0x1b, 0x4a, 0x9d, 0xab, 0x51, 0xc7, 0xfb, 0x0b, 0xb3,
0xc9, 0xb6, 0xd5, 0xc8, 0xd3, 0x88, 0x24, 0x2f, 0x20, 0xdf, 0xe9, 0x1c, 0xd9, 0x3f, 0x45, 0x6d,
0x1f, 0x65, 0x68, 0xeb, 0x1c, 0x51, 0x85, 0x22, 0x04, 0x0a, 0x17, 0xee, 0x40, 0xd8, 0x5b, 0xb8,
0x2f, 0x5c, 0x93, 0x0f, 0xa1, 0x78, 0xe1, 0x86, 0x03, 0x26, 0xed, 0xc7, 0xe8, 0xb3, 0xa1, 0xc8,
0x2b, 0x28, 0xbd, 0xf3, 0xbd, 0x91, 0x27, 0x85, 0xfd, 0x21, 0xb6, 0x85, 0x27, 0xcb, 0x95, 0x6b,
0xd0, 0xd9, 0x58, 0xd2, 0x08, 0x4f, 0x5e, 0x42, 0xe1, 0x6c, 0x2c, 0x85, 0x6d, 0xa3, 0xdc, 0xb3,
0x8c, 0xa4, 0xe2, 0xa3, 0x11, 0x0f, 0xa2, 0x7e, 0x82, 0x02, 0xf5, 0xdf, 0x01, 0x59, 0xac, 0x4d,
0xd5, 0xb2, 0x86, 0x6c, 0x16, 0xb5, 0xac, 0x21, 0x9b, 0xa9, 0xf2, 0x9c, 0xba, 0xfe, 0x24, 0x6a,
0x1c, 0x9a, 0xf8, 0x26, 0xf7, 0xb5, 0x55, 0x7f, 0x03, 0x1b, 0xe9, 0xb2, 0x79, 0x90, 0xf4, 0x2b,
0xa8, 0x26, 0x72, 0xe3, 0x21, 0xa2, 0xce, 0xbf, 0x2d, 0xa8, 0x26, 0x12, 0x18, 0x43, 0x3d, 0x1b,
0x33, 0x23, 0x8c, 0x6b, 0xb2, 0x0f, 0x6b, 0x7b, 0x52, 0x86, 0xaa, 0xcf, 0xaa, 0xd3, 0xfa, 0xd5,
0x9d, 0x65, 0xd0, 0x44, 0xb8, 0x4e, 0x54, 0x2d, 0xaa, 0xf2, 0xf4, 0x80, 0x09, 0xe9, 0x05, 0xae,
0x0a, 0x9c, 0x69, 0x8b, 0x49, 0x56, 0xfd, 0x6b, 0x80, 0xb9, 0xd8, 0x83, 0x7c, 0xf8, 0x87, 0x05,
0x8f, 0x16, 0x6a, 0x7d, 0xa9, 0x27, 0x47, 0x69, 0x4f, 0x76, 0xef, 0xd9, 0x37, 0x16, 0xfd, 0xf9,
0x11, 0xbb, 0x3d, 0x85, 0xa2, 0x6e, 0xb0, 0x4b, 0x77, 0x58, 0x87, 0xf2, 0x81, 0x27, 0xdc, 0xae,
0xcf, 0xfa, 0x28, 0x5a, 0xa6, 0x31, 0x8d, 0xdd, 0x1d, 0x77, 0xaf, 0xa3, 0xa7, 0x09, 0x47, 0x57,
0x12, 0xd9, 0x80, 0x5c, 0x3c, 0xf8, 0x73, 0xc7, 0x07, 0x0a, 0xac, 0xa6, 0x96, 0x76, 0xb5, 0x42,
0x35, 0xe1, 0xb4, 0xa1, 0xa8, 0x6b, 0x73, 0x01, 0x5f, 0x87, 0x72, 0xdb, 0xf3, 0x19, 0x0e, 0x3f,
0xbd, 0xe7, 0x98, 0x56, 0xee, 0x1d, 0x06, 0x53, 0x63, 0x56, 0x2d, 0x9d, 0xbf, 0x5b, 0x50, 0x89,
0x2b, 0x88, 0xb4, 0xa0, 0x88, 0xfe, 0x45, 0x97, 0x98, 0x17, 0x77, 0x94, 0x5c, 0xf3, 0x3d, 0xa2,
0x4d, 0x27, 0xd3, 0xa2, 0xf5, 0xef, 0xa0, 0x9a, 0x60, 0x2f, 0x09, 0xe9, 0x6e, 0x32, 0xa4, 0x99,
0x2d, 0x48, 0x1b, 0x49, 0x06, 0xfc, 0x00, 0x8a, 0x9a, 0xa9, 0x02, 0x8e, 0x73, 0xdb, 0x04, 0x1c,
0xa7, 0x35, 0x81, 0xc2, 0x91, 0x1b, 0xea, 0x60, 0xe7, 0x29, 0xae, 0x15, 0xaf, 0xc3, 0x2f, 0x25,
0x3a, 0x9c, 0xa7, 0xb8, 0x76, 0xfe, 0x65, 0x41, 0x2d, 0x55, 0xfb, 0xaa, 0xb9, 0x61, 0xcd, 0xb2,
0xd0, 0x28, 0x8c, 0x48, 0x35, 0x5d, 0x4e, 0x98, 0x74, 0xfb, 0xae, 0x74, 0x55, 0x0c, 0x4d, 0x3c,
0x53, 0x3c, 0x25, 0x6d, 0x3a, 0x30, 0x9a, 0x29, 0xd3, 0x88, 0x54, 0xd6, 0xcf, 0x27, 0xbe, 0x6f,
0x17, 0x90, 0x8d, 0x6b, 0x3d, 0x4e, 0x54, 0x7d, 0x9d, 0x4f, 0xc4, 0x95, 0xbd, 0x86, 0x5f, 0x12,
0x9c, 0xf9, 0xf7, 0xb7, 0xdc, 0xed, 0xdb, 0xc5, 0xe4, 0x77, 0xc5, 0xc1, 0xdd, 0x9b, 0xfb, 0x94,
0xb9, 0x77, 0x32, 0xd8, 0xd4, 0xdf, 0x59, 0x18, 0xf1, 0xcc, 0xe9, 0xbd, 0x5a, 0x31, 0x8a, 0x22,
0x68, 0xf3, 0xb6, 0xac, 0x3e, 0xcb, 0x05, 0x95, 0xf5, 0x16, 0x3c, 0x5e, 0x0a, 0x7d, 0x50, 0xc9,
0xfc, 0x1c, 0x1e, 0xcd, 0x6f, 0x8a, 0xd9, 0x77, 0xec, 0x2d, 0x20, 0x49, 0x98, 0xb9, 0x49, 0x3e,
0x81, 0xaa, 0xba, 0x79, 0x67, 0x8b, 0x39, 0xb0, 0xae, 0x01, 0x26, 0x32, 0x04, 0x0a, 0x43, 0x36,
0xd3, 0xb9, 0x5c, 0xa1, 0xb8, 0x76, 0xfe, 0x66, 0xa9, 0x0b, 0xf4, 0x78, 0x22, 0x4f, 0x98, 0x10,
0xee, 0x80, 0x91, 0x37, 0x50, 0x38, 0x0e, 0x3c, 0x89, 0x7a, 0xaa, 0xbb, 0x9f, 0x65, 0x5d, 0xa4,
0xc7, 0x13, 0xa9, 0x60, 0x46, 0xea, 0xe8, 0x27, 0x14, 0xa5, 0xd4, 0xa4, 0x39, 0x70, 0xa5, 0x6b,
0x32, 0x39, 0xe3, 0x5e, 0xa1, 0x10, 0x09, 0x41, 0x45, 0xee, 0x97, 0xd4, 0x6b, 0x61, 0x3c, 0x91,
0xce, 0x73, 0xd8, 0xbc, 0xad, 0x7d, 0x89, 0x6b, 0x5f, 0x42, 0x35, 0xa1, 0x05, 0xeb, 0xf8, 0xac,
0x8d, 0x80, 0x32, 0x55, 0x4b, 0xe5, 0x6b, 0xbc, 0x91, 0x75, 0x6d, 0xc3, 0xf9, 0x00, 0x6a, 0xa8,
0x3a, 0x8e, 0xe0, 0x5f, 0x73, 0x50, 0x8a, 0x54, 0xbc, 0x4c, 0xf9, 0xfd, 0x34, 0xcb, 0xef, 0x45,
0x97, 0xbf, 0x82, 0x42, 0x5c, 0x0b, 0x99, 0x43, 0xb9, 0xdd, 0x4f, 0x88, 0x61, 0x99, 0xfc, 0x16,
0x8a, 0x94, 0x09, 0x75, 0x81, 0xc8, 0xaf, 0x9a, 0xca, 0x1a, 0x33, 0x17, 0x36, 0x42, 0x4a, 0xbc,
0xe3, 0x0d, 0x02, 0x57, 0x57, 0x53, 0xa6, 0xb8, 0xc6, 0x24, 0xc4, 0x35, 0x63, 0x1e, 0xee, 0x1f,
0x2c, 0xa8, 0xae, 0x0c, 0xf5, 0xea, 0xb7, 0xce, 0xc2, 0xfb, 0x2b, 0xff, 0x7f, 0xbe, 0xbf, 0xfe,
0x63, 0xa5, 0x15, 0x61, 0xe1, 0xab, 0x7a, 0x1a, 0x73, 0x2f, 0x90, 0x26, 0x65, 0x13, 0x1c, 0xb5,
0xd1, 0xd6, 0xa8, 0x6f, 0x86, 0x80, 0x5a, 0xce, 0x9b, 0x79, 0xde, 0x34, 0x73, 0x95, 0x04, 0xef,
0x04, 0x0b, 0x31, 0x44, 0x15, 0x8a, 0x6b, 0x75, 0xbd, 0x3a, 0xe5, 0xc8, 0xd5, 0xcd, 0xc6, 0x50,
0xa8, 0xef, 0x5a, 0x77, 0x18, 0xa5, 0xef, 0x1a, 0xa7, 0xd2, 0x29, 0x57, 0xbc, 0x12, 0x02, 0x35,
0xa1, 0x70, 0x17, 0x72, 0x66, 0x97, 0x75, 0xaa, 0x5d, 0xc8, 0x99, 0x1a, 0x30, 0x94, 0xfb, 0x7e,
0xd7, 0xed, 0x0d, 0xed, 0x8a, 0x9e, 0x6c, 0x11, 0xed, 0xec, 0x41, 0x25, 0x3e, 0x7a, 0x35, 0x99,
0xda, 0x7d, 0x0c, 0x6d, 0x8d, 0xe6, 0xda, 0xfd, 0x28, 0x6b, 0x73, 0x8b, 0x59, 0x9b, 0x4f, 0x64,
0xed, 0x4b, 0xa8, 0xa5, 0x92, 0x40, 0x81, 0x28, 0xbf, 0x16, 0x46, 0x11, 0xae, 0x15, 0xaf, 0xc5,
0x7d, 0xfd, 0x60, 0xac, 0x51, 0x5c, 0x3b, 0xcf, 0xa0, 0x96, 0x3a, 0xfe, 0x65, 0x53, 0xc2, 0x79,
0x0a, 0xb5, 0x8e, 0x74, 0xe5, 0x64, 0xc5, 0x0b, 0xff, 0xbf, 0x16, 0x6c, 0x44, 0x18, 0xd3, 0x49,
0x7e, 0x0d, 0xe5, 0x29, 0x0b, 0x25, 0xbb, 0x89, 0x27, 0xa3, 0xdd, 0x1c, 0xf1, 0xee, 0xac, 0x19,
0xfd, 0xc7, 0xa0, 0x4e, 0xfb, 0x3d, 0x22, 0x68, 0x8c, 0x24, 0xdf, 0x40, 0x59, 0xa0, 0x1e, 0x16,
0xdd, 0x53, 0x3e, 0xcd, 0x92, 0x32, 0xf6, 0x62, 0x3c, 0xd9, 0x81, 0x82, 0xcf, 0x07, 0x02, 0x4f,
0xb7, 0xba, 0xfb, 0x71, 0x96, 0xdc, 0x5b, 0x3e, 0xa0, 0x08, 0x24, 0xaf, 0xa1, 0x7c, 0xed, 0x86,
0x81, 0x17, 0x0c, 0xa2, 0x97, 0xe8, 0x93, 0x2c, 0xa1, 0xef, 0x34, 0x8e, 0xc6, 0x02, 0x4e, 0x4d,
0x15, 0xc5, 0x25, 0x37, 0x31, 0x71, 0x7e, 0xaf, 0x72, 0x53, 0x91, 0xc6, 0xfd, 0x63, 0xa8, 0xe9,
0xfc, 0x7e, 0xcf, 0x42, 0xa1, 0x6e, 0x7d, 0xd6, 0xaa, 0x1a, 0xdc, 0x4f, 0x42, 0x69, 0x5a, 0xd2,
0xf9, 0xde, 0x8c, 0xaf, 0x88, 0xa1, 0xc6, 0xe7, 0xd8, 0xed, 0x0d, 0xdd, 0x41, 0x74, 0x4e, 0x11,
0xa9, 0xbe, 0x4c, 0x8d, 0x3d, 0x5d, 0x86, 0x11, 0xa9, 0x32, 0x30, 0x64, 0x53, 0x4f, 0xcc, 0x2f,
0xa0, 0x31, 0xbd, 0xfb, 0xcf, 0x22, 0x40, 0x2b, 0xde, 0x0f, 0x39, 0x87, 0x35, 0xb4, 0x47, 0x9c,
0x95, 0xc3, 0x10, 0xfd, 0xae, 0x3f, 0xbb, 0xc7, 0xc0, 0x24, 0xef, 0xa0, 0xa8, 0x4f, 0x8b, 0x64,
0xf5, 0xa0, 0x64, 0x7e, 0xd5, 0x9f, 0xaf, 0x06, 0x69, 0xa5, 0x9f, 0x5b, 0x84, 0x9a, 0x0e, 0x45,
0x9c, 0x15, 0x23, 0xc8, 0x64, 0x76, 0xd6, 0x46, 0x53, 0xdd, 0xbe, 0x61, 0x91, 0x6f, 0xa1, 0xa8,
0x7b, 0x0c, 0xf9, 0xd9, 0x72, 0x81, 0x48, 0xdf, 0xea, 0xcf, 0x0d, 0xeb, 0x73, 0x8b, 0x9c, 0x40,
0x41, 0x0d, 0x57, 0x92, 0x31, 0x29, 0x12, 0x93, 0xb9, 0xee, 0xac, 0x82, 0x98, 0x28, 0x7e, 0x0f,
0x30, 0x1f, 0xf1, 0x24, 0xe3, 0xdd, 0xbf, 0x70, 0x57, 0xa8, 0x37, 0xee, 0x06, 0x1a, 0x03, 0x27,
0x6a, 0xbe, 0x5d, 0x72, 0x92, 0x39, 0xd9, 0xe2, 0x74, 0xaf, 0x3b, 0xab, 0x20, 0x46, 0xdd, 0x15,
0xd4, 0x52, 0x7f, 0xfb, 0x91, 0x5f, 0x66, 0x3b, 0x79, 0xfb, 0x5f, 0xc4, 0xfa, 0x8b, 0x7b, 0x61,
0x8d, 0x25, 0x99, 0xbc, 0x23, 0x99, 0xcf, 0xa4, 0x79, 0x97, 0xdf, 0xe9, 0xbf, 0xf0, 0xea, 0x3b,
0xf7, 0xc6, 0x6b, 0xab, 0xfb, 0x85, 0x3f, 0xe4, 0xc6, 0xdd, 0x6e, 0x11, 0xff, 0x0d, 0xfd, 0xf2,
0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x41, 0x5d, 0x93, 0xf2, 0x74, 0x15, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -1857,6 +2086,8 @@ type ControllerClient interface {
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)
ListProcesses(ctx context.Context, in *ListProcessesRequest, opts ...grpc.CallOption) (*ListProcessesResponse, error)
DisconnectProcess(ctx context.Context, in *DisconnectProcessRequest, opts ...grpc.CallOption) (*DisconnectProcessResponse, error)
}
type controllerClient struct {
@ -2000,6 +2231,24 @@ func (c *controllerClient) Info(ctx context.Context, in *InfoRequest, opts ...gr
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...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *controllerClient) DisconnectProcess(ctx context.Context, in *DisconnectProcessRequest, opts ...grpc.CallOption) (*DisconnectProcessResponse, error) {
out := new(DisconnectProcessResponse)
err := c.cc.Invoke(ctx, "/buildx.controller.v1.Controller/DisconnectProcess", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ControllerServer is the server API for Controller service.
type ControllerServer interface {
Build(context.Context, *BuildRequest) (*BuildResponse, error)
@ -2009,6 +2258,8 @@ type ControllerServer interface {
List(context.Context, *ListRequest) (*ListResponse, error)
Disconnect(context.Context, *DisconnectRequest) (*DisconnectResponse, error)
Info(context.Context, *InfoRequest) (*InfoResponse, error)
ListProcesses(context.Context, *ListProcessesRequest) (*ListProcessesResponse, error)
DisconnectProcess(context.Context, *DisconnectProcessRequest) (*DisconnectProcessResponse, error)
}
// UnimplementedControllerServer can be embedded to have forward compatible implementations.
@ -2036,6 +2287,12 @@ func (*UnimplementedControllerServer) Disconnect(ctx context.Context, req *Disco
func (*UnimplementedControllerServer) Info(ctx context.Context, req *InfoRequest) (*InfoResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Info not implemented")
}
func (*UnimplementedControllerServer) ListProcesses(ctx context.Context, req *ListProcessesRequest) (*ListProcessesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListProcesses not implemented")
}
func (*UnimplementedControllerServer) DisconnectProcess(ctx context.Context, req *DisconnectProcessRequest) (*DisconnectProcessResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DisconnectProcess not implemented")
}
func RegisterControllerServer(s *grpc.Server, srv ControllerServer) {
s.RegisterService(&_Controller_serviceDesc, srv)
@ -2186,6 +2443,42 @@ func _Controller_Info_Handler(srv interface{}, ctx context.Context, dec func(int
return interceptor(ctx, in, info, handler)
}
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 {
return nil, err
}
if interceptor == nil {
return srv.(ControllerServer).ListProcesses(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/buildx.controller.v1.Controller/ListProcesses",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ControllerServer).ListProcesses(ctx, req.(*ListProcessesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Controller_DisconnectProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DisconnectProcessRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ControllerServer).DisconnectProcess(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/buildx.controller.v1.Controller/DisconnectProcess",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ControllerServer).DisconnectProcess(ctx, req.(*DisconnectProcessRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Controller_serviceDesc = grpc.ServiceDesc{
ServiceName: "buildx.controller.v1.Controller",
HandlerType: (*ControllerServer)(nil),
@ -2206,6 +2499,14 @@ var _Controller_serviceDesc = grpc.ServiceDesc{
MethodName: "Info",
Handler: _Controller_Info_Handler,
},
{
MethodName: "ListProcesses",
Handler: _Controller_ListProcesses_Handler,
},
{
MethodName: "DisconnectProcess",
Handler: _Controller_DisconnectProcess_Handler,
},
},
Streams: []grpc.StreamDesc{
{

View File

@ -14,6 +14,29 @@ service Controller {
rpc List(ListRequest) returns (ListResponse);
rpc Disconnect(DisconnectRequest) returns (DisconnectResponse);
rpc Info(InfoRequest) returns (InfoResponse);
rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse);
rpc DisconnectProcess(DisconnectProcessRequest) returns (DisconnectProcessResponse);
}
message ListProcessesRequest {
string Ref = 1;
}
message ListProcessesResponse {
repeated ProcessInfo Infos = 1;
}
message ProcessInfo {
string ProcessID = 1;
InvokeConfig InvokeConfig = 2;
}
message DisconnectProcessRequest {
string Ref = 1;
string ProcessID = 2;
}
message DisconnectProcessResponse {
}
message BuildRequest {
@ -149,10 +172,14 @@ message Message {
message InitMessage {
string Ref = 1;
ContainerConfig ContainerConfig = 2;
// If ProcessID already exists in the server, it tries to connect to it
// instead of invoking the new one. In this case, InvokeConfig will be ignored.
string ProcessID = 2;
InvokeConfig InvokeConfig = 3;
}
message ContainerConfig {
message InvokeConfig {
repeated string Entrypoint = 1;
repeated string Cmd = 2;
repeated string Env = 3;
@ -161,6 +188,7 @@ message ContainerConfig {
string Cwd = 6;
bool NoCwd = 7; // Do not set cwd but use the image's default
bool Tty = 8;
bool Rollback = 9; // Kill all process in the container and recreate it.
}
message FdMessage {

View File

@ -0,0 +1,149 @@
package processes
import (
"context"
"sync"
"sync/atomic"
"github.com/docker/buildx/build"
"github.com/docker/buildx/controller/pb"
"github.com/docker/buildx/util/ioset"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// Process provides methods to control a process.
type Process struct {
inEnd *ioset.Forwarder
invokeConfig *pb.InvokeConfig
errCh chan error
processCancel func()
serveIOCancel func()
}
// ForwardIO forwards process's io to the specified reader/writer.
// Optionally specify ioCancelCallback which will be called when
// the process closes the specified IO. This will be useful for additional cleanup.
func (p *Process) ForwardIO(in *ioset.In, ioCancelCallback func()) {
p.inEnd.SetIn(in)
if f := p.serveIOCancel; f != nil {
f()
}
p.serveIOCancel = ioCancelCallback
}
// Done returns a channel where error or nil will be sent
// when the process exits.
// TODO: change this to Wait()
func (p *Process) Done() <-chan error {
return p.errCh
}
// Manager manages a set of proceses.
type Manager struct {
container atomic.Value
processes sync.Map
}
// NewManager creates and returns a Manager.
func NewManager() *Manager {
return &Manager{}
}
// Get returns the specified process.
func (m *Manager) Get(id string) (*Process, bool) {
v, ok := m.processes.Load(id)
if !ok {
return nil, false
}
return v.(*Process), true
}
// CancelRunningProcesses cancels execution of all running processes.
func (m *Manager) CancelRunningProcesses() {
var funcs []func()
m.processes.Range(func(key, value any) bool {
funcs = append(funcs, value.(*Process).processCancel)
m.processes.Delete(key)
return true
})
for _, f := range funcs {
f()
}
}
// ListProcesses lists all running processes.
func (m *Manager) ListProcesses() (res []*pb.ProcessInfo) {
m.processes.Range(func(key, value any) bool {
res = append(res, &pb.ProcessInfo{
ProcessID: key.(string),
InvokeConfig: value.(*Process).invokeConfig,
})
return true
})
return res
}
// DeleteProcess deletes the specified process.
func (m *Manager) DeleteProcess(id string) error {
p, ok := m.processes.LoadAndDelete(id)
if !ok {
return errors.Errorf("unknown process %q", id)
}
p.(*Process).processCancel()
return nil
}
// StartProcess starts a process in the container.
// When a container isn't available (i.e. first time invoking or the container has exited) or cfg.Rollback is set,
// this method will start a new container and run the process in it. Otherwise, this method starts a new process in the
// existing container.
func (m *Manager) StartProcess(pid string, resultCtx *build.ResultContext, cfg *pb.InvokeConfig) (*Process, error) {
// Get the target result to invoke a container from
var ctr *build.Container
if a := m.container.Load(); a != nil {
ctr = a.(*build.Container)
}
if cfg.Rollback || ctr == nil || ctr.IsUnavailable() {
go m.CancelRunningProcesses()
// (Re)create a new container if this is rollback or first time to invoke a process.
if ctr != nil {
go ctr.Cancel() // Finish the existing container
}
var err error
ctr, err = build.NewContainer(context.TODO(), resultCtx)
if err != nil {
return nil, errors.Errorf("failed to create container %v", err)
}
m.container.Store(ctr)
}
// [client(ForwardIO)] <-forwarder(switchable)-> [out] <-pipe-> [in] <- [process]
in, out := ioset.Pipe()
f := ioset.NewForwarder()
f.PropagateStdinClose = false
f.SetOut(&out)
// Register process
ctx, cancel := context.WithCancel(context.TODO())
var cancelOnce sync.Once
processCancelFunc := func() { cancelOnce.Do(func() { cancel(); f.Close(); in.Close(); out.Close() }) }
p := &Process{
inEnd: f,
invokeConfig: cfg,
processCancel: processCancelFunc,
errCh: make(chan error),
}
m.processes.Store(pid, p)
go func() {
var err error
if err = ctr.Exec(ctx, cfg, in.Stdin, in.Stdout, in.Stderr); err != nil {
logrus.Errorf("failed to exec process: %v", err)
}
logrus.Debugf("finished process %s %v", pid, cfg.Entrypoint)
m.processes.Delete(pid)
processCancelFunc()
p.errCh <- err
}()
return p, nil
}

View File

@ -75,15 +75,28 @@ func (c *Client) Disconnect(ctx context.Context, key string) error {
return err
}
func (c *Client) Invoke(ctx context.Context, ref string, containerConfig pb.ContainerConfig, in io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
if ref == "" {
func (c *Client) ListProcesses(ctx context.Context, ref string) (infos []*pb.ProcessInfo, retErr error) {
res, err := c.client().ListProcesses(ctx, &pb.ListProcessesRequest{Ref: ref})
if err != nil {
return nil, err
}
return res.Infos, nil
}
func (c *Client) DisconnectProcess(ctx context.Context, ref, pid string) error {
_, err := c.client().DisconnectProcess(ctx, &pb.DisconnectProcessRequest{Ref: ref, ProcessID: pid})
return err
}
func (c *Client) Invoke(ctx context.Context, ref string, pid string, invokeConfig pb.InvokeConfig, in io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
if ref == "" || pid == "" {
return errors.New("build reference must be specified")
}
stream, err := c.client().Invoke(ctx)
if err != nil {
return err
}
return attachIO(ctx, stream, &pb.InitMessage{Ref: ref, ContainerConfig: &containerConfig}, ioAttachConfig{
return attachIO(ctx, stream, &pb.InitMessage{Ref: ref, ProcessID: pid, InvokeConfig: &invokeConfig}, ioAttachConfig{
stdin: in,
stdout: stdout,
stderr: stderr,

View File

@ -4,16 +4,17 @@ import (
"context"
"io"
"sync"
"sync/atomic"
"time"
"github.com/docker/buildx/build"
"github.com/docker/buildx/controller/pb"
"github.com/docker/buildx/controller/processes"
"github.com/docker/buildx/util/ioset"
"github.com/docker/buildx/version"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/client"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
)
@ -27,16 +28,47 @@ func NewServer(buildFunc BuildFunc) *Server {
type Server struct {
buildFunc BuildFunc
session map[string]session
session map[string]*session
sessionMu sync.Mutex
}
type session struct {
statusChan chan *client.SolveStatus
result *build.ResultContext
inputPipe *io.PipeWriter
curInvokeCancel func()
curBuildCancel func()
buildOnGoing atomic.Bool
statusChan chan *client.SolveStatus
cancelBuild func()
inputPipe *io.PipeWriter
result *build.ResultContext
processes *processes.Manager
}
func (s *session) cancelRunningProcesses() {
s.processes.CancelRunningProcesses()
}
func (m *Server) ListProcesses(ctx context.Context, req *pb.ListProcessesRequest) (res *pb.ListProcessesResponse, err error) {
m.sessionMu.Lock()
defer m.sessionMu.Unlock()
s, ok := m.session[req.Ref]
if !ok {
return nil, errors.Errorf("unknown ref %q", req.Ref)
}
res = new(pb.ListProcessesResponse)
for _, p := range s.processes.ListProcesses() {
res.Infos = append(res.Infos, p)
}
return res, nil
}
func (m *Server) DisconnectProcess(ctx context.Context, req *pb.DisconnectProcessRequest) (res *pb.DisconnectProcessResponse, err error) {
m.sessionMu.Lock()
defer m.sessionMu.Unlock()
s, ok := m.session[req.Ref]
if !ok {
return nil, errors.Errorf("unknown ref %q", req.Ref)
}
return res, s.processes.DeleteProcess(req.ProcessID)
}
func (m *Server) Info(ctx context.Context, req *pb.InfoRequest) (res *pb.InfoResponse, err error) {
@ -75,12 +107,10 @@ func (m *Server) Disconnect(ctx context.Context, req *pb.DisconnectRequest) (res
m.sessionMu.Lock()
if s, ok := m.session[key]; ok {
if s.curBuildCancel != nil {
s.curBuildCancel()
}
if s.curInvokeCancel != nil {
s.curInvokeCancel()
if s.cancelBuild != nil {
s.cancelBuild()
}
s.cancelRunningProcesses()
}
delete(m.session, key)
m.sessionMu.Unlock()
@ -92,12 +122,10 @@ func (m *Server) Close() error {
m.sessionMu.Lock()
for k := range m.session {
if s, ok := m.session[k]; ok {
if s.curBuildCancel != nil {
s.curBuildCancel()
}
if s.curInvokeCancel != nil {
s.curInvokeCancel()
if s.cancelBuild != nil {
s.cancelBuild()
}
s.cancelRunningProcesses()
}
}
m.sessionMu.Unlock()
@ -110,19 +138,30 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
return nil, errors.New("build: empty key")
}
// Prepare status channel and session if not exists
// Prepare status channel and session
m.sessionMu.Lock()
if m.session == nil {
m.session = make(map[string]session)
m.session = make(map[string]*session)
}
s, ok := m.session[ref]
if ok && m.session[ref].statusChan != nil {
m.sessionMu.Unlock()
return &pb.BuildResponse{}, errors.New("build or status ongoing or status didn't call")
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()
statusChan := make(chan *client.SolveStatus)
s.statusChan = statusChan
m.session[ref] = session{statusChan: statusChan}
inR, inW := io.Pipe()
defer inR.Close()
s.inputPipe = inW
m.session[ref] = s
m.sessionMu.Unlock()
defer func() {
close(statusChan)
@ -130,23 +169,11 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
s, ok := m.session[ref]
if ok {
s.statusChan = nil
s.buildOnGoing.Store(false)
}
m.sessionMu.Unlock()
}()
// Prepare input stream pipe
inR, inW := io.Pipe()
m.sessionMu.Lock()
if s, ok := m.session[ref]; ok {
s.inputPipe = inW
m.session[ref] = s
} else {
m.sessionMu.Unlock()
return nil, errors.Errorf("build: unknown key %v", ref)
}
m.sessionMu.Unlock()
defer inR.Close()
// Build the specified request
ctx, cancel := context.WithCancel(ctx)
defer cancel()
@ -154,7 +181,7 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
m.sessionMu.Lock()
if s, ok := m.session[ref]; ok {
s.result = res
s.curBuildCancel = cancel
s.cancelBuild = cancel
m.session[ref] = s
} else {
m.sessionMu.Unlock()
@ -298,56 +325,51 @@ func (m *Server) Input(stream pb.Controller_InputServer) (err error) {
}
func (m *Server) Invoke(srv pb.Controller_InvokeServer) error {
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
containerIn, containerOut := ioset.Pipe()
waitInvokeDoneCh := make(chan struct{})
var cancelOnce sync.Once
curInvokeCancel := func() {
cancelOnce.Do(func() { containerOut.Close(); containerIn.Close(); cancel() })
<-waitInvokeDoneCh
}
defer curInvokeCancel()
defer func() { containerOut.Close(); containerIn.Close() }()
var cfg *pb.ContainerConfig
var resultCtx *build.ResultContext
initDoneCh := make(chan struct{})
initDoneCh := make(chan *processes.Process)
initErrCh := make(chan error)
eg, egCtx := errgroup.WithContext(ctx)
eg, egCtx := errgroup.WithContext(context.TODO())
srvIOCtx, srvIOCancel := context.WithCancel(egCtx)
eg.Go(func() error {
return serveIO(egCtx, srv, func(initMessage *pb.InitMessage) (retErr error) {
defer srvIOCancel()
return serveIO(srvIOCtx, srv, func(initMessage *pb.InitMessage) (retErr error) {
defer func() {
if retErr != nil {
initErrCh <- retErr
}
close(initDoneCh)
}()
ref := initMessage.Ref
cfg = initMessage.ContainerConfig
cfg := initMessage.InvokeConfig
// Register cancel callback
m.sessionMu.Lock()
if s, ok := m.session[ref]; ok {
if cancel := s.curInvokeCancel; cancel != nil {
logrus.Warnf("invoke: cancelling ongoing invoke of %q", ref)
cancel()
}
s.curInvokeCancel = curInvokeCancel
m.session[ref] = s
} else {
s, ok := m.session[ref]
if !ok {
m.sessionMu.Unlock()
return errors.Errorf("invoke: unknown key %v", ref)
}
m.sessionMu.Unlock()
// Get the target result to invoke a container from
m.sessionMu.Lock()
if _, ok := m.session[ref]; !ok || m.session[ref].result == nil {
m.sessionMu.Unlock()
return errors.Errorf("unknown reference: %q", ref)
pid := initMessage.ProcessID
if pid == "" {
return errors.Errorf("invoke: specify process ID")
}
resultCtx = m.session[ref].result
m.sessionMu.Unlock()
proc, ok := s.processes.Get(pid)
if !ok {
// Start a new process.
if cfg == nil {
return errors.New("no container config is provided")
}
var err error
proc, err = s.processes.StartProcess(pid, s.result, cfg)
if err != nil {
return err
}
}
// Attach containerIn to this process
proc.ForwardIO(&containerIn, srvIOCancel)
initDoneCh <- proc
return nil
}, &ioServerConfig{
stdin: containerOut.Stdin,
@ -356,43 +378,31 @@ func (m *Server) Invoke(srv pb.Controller_InvokeServer) error {
// TODO: signal, resize
})
})
eg.Go(func() error {
defer containerIn.Close()
defer cancel()
eg.Go(func() (rErr error) {
defer srvIOCancel()
// Wait for init done
var proc *processes.Process
select {
case <-initDoneCh:
case p := <-initDoneCh:
proc = p
case err := <-initErrCh:
return err
case <-egCtx.Done():
return egCtx.Err()
}
if cfg == nil {
return errors.New("no container config is provided")
}
if resultCtx == nil {
return errors.New("no result is provided")
}
ccfg := build.ContainerConfig{
ResultCtx: resultCtx,
Entrypoint: cfg.Entrypoint,
Cmd: cfg.Cmd,
Env: cfg.Env,
Tty: cfg.Tty,
Stdin: containerIn.Stdin,
Stdout: containerIn.Stdout,
Stderr: containerIn.Stderr,
}
if !cfg.NoUser {
ccfg.User = &cfg.User
}
if !cfg.NoCwd {
ccfg.Cwd = &cfg.Cwd
}
return build.Invoke(egCtx, ccfg)
})
err := eg.Wait()
close(waitInvokeDoneCh)
curInvokeCancel()
return err
// Wait for IO done
select {
case <-srvIOCtx.Done():
return srvIOCtx.Err()
case err := <-proc.Done():
return err
case <-egCtx.Done():
return egCtx.Err()
}
})
return eg.Wait()
}
func toControlStatus(s *client.SolveStatus) *pb.StatusResponse {