1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-21 21:33:18 +01:00

feat: support shell resize (#4287)

This commit is contained in:
Amir Raminfar
2025-12-12 15:07:54 -08:00
committed by GitHub
parent b74dc9f58a
commit 8000b6c14e
15 changed files with 1180 additions and 310 deletions

View File

@@ -1,16 +1,12 @@
<template> <template>
<aside> <aside class="flex h-[calc(100vh-50px)] flex-col gap-2">
<header class="flex items-center gap-4"> <header class="flex items-center gap-4">
<material-symbols:terminal class="size-8" /> <material-symbols:terminal class="size-8" />
<h1 class="text-2xl max-md:hidden">{{ container.name }}</h1> <h1 class="text-2xl max-md:hidden">{{ container.name }}</h1>
<h2 class="text-sm">Started <RelativeTime :date="container.created" /></h2> <h2 class="text-sm">Started <RelativeTime :date="container.created" /></h2>
</header> </header>
<div class="mt-8 flex flex-col gap-2"> <div ref="host" class="shell flex-1"></div>
<section>
<div ref="host" class="shell"></div>
</section>
</div>
</aside> </aside>
</template> </template>
@@ -21,6 +17,7 @@ const { container, action } = defineProps<{ container: Container; action: "attac
const { Terminal } = await import("@xterm/xterm"); const { Terminal } = await import("@xterm/xterm");
const { WebLinksAddon } = await import("@xterm/addon-web-links"); const { WebLinksAddon } = await import("@xterm/addon-web-links");
const { FitAddon } = await import("@xterm/addon-fit");
const host = useTemplateRef<HTMLDivElement>("host"); const host = useTemplateRef<HTMLDivElement>("host");
const terminal = new Terminal({ const terminal = new Terminal({
@@ -28,27 +25,61 @@ const terminal = new Terminal({
cursorStyle: "block", cursorStyle: "block",
}); });
terminal.loadAddon(new WebLinksAddon()); terminal.loadAddon(new WebLinksAddon());
const fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
let ws: WebSocket | null = null; let ws: WebSocket | null = null;
function sendEvent(type: "userinput" | "resize", data?: string, width?: number, height?: number) {
if (!ws || ws.readyState !== WebSocket.OPEN) return;
const event: { type: string; data?: string; width?: number; height?: number } = { type };
if (data !== undefined) event.data = data;
if (width !== undefined) event.width = width;
if (height !== undefined) event.height = height;
ws.send(JSON.stringify(event));
}
onMounted(() => { onMounted(() => {
terminal.open(host.value!); terminal.open(host.value!);
terminal.resize(100, 40); fitAddon.fit();
ws = new WebSocket(withBase(`/api/hosts/${container.host}/containers/${container.id}/${action}`)); ws = new WebSocket(withBase(`/api/hosts/${container.host}/containers/${container.id}/${action}`));
ws.onopen = () => { ws.onopen = () => {
terminal.writeln(`Attaching to ${container.name} 🚀`); terminal.writeln(`Attaching to ${container.name} 🚀`);
// Send initial resize event
sendEvent("resize", undefined, terminal.cols, terminal.rows);
if (action === "attach") { if (action === "attach") {
ws?.send("\r"); sendEvent("userinput", "\r");
} }
terminal.onData((data) => { terminal.onData((data) => {
ws?.send(data); sendEvent("userinput", data);
}); });
// Handle terminal resize
terminal.onResize(({ cols, rows }) => {
sendEvent("resize", undefined, cols, rows);
});
terminal.focus(); terminal.focus();
}; };
ws.onmessage = (event) => terminal.write(event.data); ws.onmessage = (event) => terminal.write(event.data);
ws.addEventListener("close", () => { ws.addEventListener("close", () => {
terminal.writeln("⚠️ Connection closed"); terminal.writeln("⚠️ Connection closed");
}); });
// Handle window resize
const { width, height } = useWindowSize();
watch([width, height], () => {
requestAnimationFrame(() => {
fitAddon.fit();
});
});
}); });
onUnmounted(() => { onUnmounted(() => {
@@ -62,7 +93,7 @@ onUnmounted(() => {
.shell { .shell {
& :deep(.terminal) { & :deep(.terminal) {
@apply overflow-hidden rounded border-1 p-2; @apply overflow-hidden rounded border p-2;
&:is(.focus) { &:is(.focus) {
@apply border-primary; @apply border-primary;
} }

View File

@@ -334,21 +334,82 @@ func (c *Client) ContainerAction(ctx context.Context, containerId string, action
return err return err
} }
func (c *Client) ContainerAttach(ctx context.Context, containerId string) (io.WriteCloser, io.Reader, error) { func (c *Client) ContainerAttach(ctx context.Context, containerId string) (*container.ExecSession, error) {
panic("not implemented") stream, err := c.client.ContainerAttach(ctx)
if err != nil {
return nil, err
}
if err = stream.Send(&pb.ContainerAttachRequest{
ContainerId: containerId,
}); err != nil {
return nil, err
}
stdoutReader, stdoutWriter := io.Pipe()
stdinReader, stdinWriter := io.Pipe()
go func() {
defer stdoutWriter.Close()
for {
msg, err := stream.Recv()
if err != nil {
return
}
stdoutWriter.Write(msg.Stdout)
}
}()
go func() {
buffer := make([]byte, 1024)
for {
n, err := stdinReader.Read(buffer)
if err != nil {
return
}
if err := stream.Send(&pb.ContainerAttachRequest{
Payload: &pb.ContainerAttachRequest_Stdin{
Stdin: buffer[:n],
},
}); err != nil {
return
}
}
}()
// Create resize closure that sends via gRPC
resizeFn := func(width uint, height uint) error {
return stream.Send(&pb.ContainerAttachRequest{
Payload: &pb.ContainerAttachRequest_Resize{
Resize: &pb.ResizePayload{
Width: uint32(width),
Height: uint32(height),
},
},
})
}
return &container.ExecSession{
Writer: stdinWriter,
Reader: stdoutReader,
Resize: resizeFn,
}, nil
} }
func (c *Client) ContainerExec(ctx context.Context, containerId string, cmd []string) (io.WriteCloser, io.Reader, error) { func (c *Client) ContainerExec(ctx context.Context, containerId string, cmd []string) (*container.ExecSession, error) {
stream, err := c.client.ContainerExec(ctx) stream, err := c.client.ContainerExec(ctx)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
if err = stream.Send(&pb.ContainerExecRequest{ if err = stream.Send(&pb.ContainerExecRequest{
ContainerId: containerId, ContainerId: containerId,
Command: cmd, Command: cmd,
}); err != nil { }); err != nil {
return nil, nil, err return nil, err
} }
stdoutReader, stdoutWriter := io.Pipe() stdoutReader, stdoutWriter := io.Pipe()
stdinReader, stdinWriter := io.Pipe() stdinReader, stdinWriter := io.Pipe()
@@ -376,14 +437,32 @@ func (c *Client) ContainerExec(ctx context.Context, containerId string, cmd []st
} }
if err := stream.Send(&pb.ContainerExecRequest{ if err := stream.Send(&pb.ContainerExecRequest{
Payload: &pb.ContainerExecRequest_Stdin{
Stdin: buffer[:n], Stdin: buffer[:n],
},
}); err != nil { }); err != nil {
return return
} }
} }
}() }()
return stdinWriter, stdoutReader, nil // Create resize closure that sends via gRPC
resizeFn := func(width uint, height uint) error {
return stream.Send(&pb.ContainerExecRequest{
Payload: &pb.ContainerExecRequest_Resize{
Resize: &pb.ResizePayload{
Width: uint32(width),
Height: uint32(height),
},
},
})
}
return &container.ExecSession{
Writer: stdinWriter,
Reader: stdoutReader,
Resize: resizeFn,
}, nil
} }
func (c *Client) Close() error { func (c *Client) Close() error {

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.6 // protoc-gen-go v1.36.5
// protoc v5.29.3 // protoc v6.33.1
// source: rpc.proto // source: rpc.proto
package pb package pb
@@ -946,7 +946,11 @@ type ContainerExecRequest struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
ContainerId string `protobuf:"bytes,1,opt,name=containerId,proto3" json:"containerId,omitempty"` ContainerId string `protobuf:"bytes,1,opt,name=containerId,proto3" json:"containerId,omitempty"`
Command []string `protobuf:"bytes,2,rep,name=command,proto3" json:"command,omitempty"` Command []string `protobuf:"bytes,2,rep,name=command,proto3" json:"command,omitempty"`
Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3" json:"stdin,omitempty"` // Types that are valid to be assigned to Payload:
//
// *ContainerExecRequest_Stdin
// *ContainerExecRequest_Resize
Payload isContainerExecRequest_Payload `protobuf_oneof:"payload"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@@ -995,13 +999,99 @@ func (x *ContainerExecRequest) GetCommand() []string {
return nil return nil
} }
func (x *ContainerExecRequest) GetStdin() []byte { func (x *ContainerExecRequest) GetPayload() isContainerExecRequest_Payload {
if x != nil { if x != nil {
return x.Stdin return x.Payload
} }
return nil return nil
} }
func (x *ContainerExecRequest) GetStdin() []byte {
if x != nil {
if x, ok := x.Payload.(*ContainerExecRequest_Stdin); ok {
return x.Stdin
}
}
return nil
}
func (x *ContainerExecRequest) GetResize() *ResizePayload {
if x != nil {
if x, ok := x.Payload.(*ContainerExecRequest_Resize); ok {
return x.Resize
}
}
return nil
}
type isContainerExecRequest_Payload interface {
isContainerExecRequest_Payload()
}
type ContainerExecRequest_Stdin struct {
Stdin []byte `protobuf:"bytes,3,opt,name=stdin,proto3,oneof"`
}
type ContainerExecRequest_Resize struct {
Resize *ResizePayload `protobuf:"bytes,4,opt,name=resize,proto3,oneof"`
}
func (*ContainerExecRequest_Stdin) isContainerExecRequest_Payload() {}
func (*ContainerExecRequest_Resize) isContainerExecRequest_Payload() {}
type ResizePayload struct {
state protoimpl.MessageState `protogen:"open.v1"`
Width uint32 `protobuf:"varint,1,opt,name=width,proto3" json:"width,omitempty"`
Height uint32 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ResizePayload) Reset() {
*x = ResizePayload{}
mi := &file_rpc_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ResizePayload) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResizePayload) ProtoMessage() {}
func (x *ResizePayload) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[21]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ResizePayload.ProtoReflect.Descriptor instead.
func (*ResizePayload) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{21}
}
func (x *ResizePayload) GetWidth() uint32 {
if x != nil {
return x.Width
}
return 0
}
func (x *ResizePayload) GetHeight() uint32 {
if x != nil {
return x.Height
}
return 0
}
type ContainerExecResponse struct { type ContainerExecResponse struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"`
@@ -1011,7 +1101,7 @@ type ContainerExecResponse struct {
func (x *ContainerExecResponse) Reset() { func (x *ContainerExecResponse) Reset() {
*x = ContainerExecResponse{} *x = ContainerExecResponse{}
mi := &file_rpc_proto_msgTypes[21] mi := &file_rpc_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1023,7 +1113,7 @@ func (x *ContainerExecResponse) String() string {
func (*ContainerExecResponse) ProtoMessage() {} func (*ContainerExecResponse) ProtoMessage() {}
func (x *ContainerExecResponse) ProtoReflect() protoreflect.Message { func (x *ContainerExecResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[21] mi := &file_rpc_proto_msgTypes[22]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1036,7 +1126,7 @@ func (x *ContainerExecResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ContainerExecResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ContainerExecResponse.ProtoReflect.Descriptor instead.
func (*ContainerExecResponse) Descriptor() ([]byte, []int) { func (*ContainerExecResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{21} return file_rpc_proto_rawDescGZIP(), []int{22}
} }
func (x *ContainerExecResponse) GetStdout() []byte { func (x *ContainerExecResponse) GetStdout() []byte {
@@ -1046,83 +1136,356 @@ func (x *ContainerExecResponse) GetStdout() []byte {
return nil return nil
} }
type ContainerAttachRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
ContainerId string `protobuf:"bytes,1,opt,name=containerId,proto3" json:"containerId,omitempty"`
// Types that are valid to be assigned to Payload:
//
// *ContainerAttachRequest_Stdin
// *ContainerAttachRequest_Resize
Payload isContainerAttachRequest_Payload `protobuf_oneof:"payload"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ContainerAttachRequest) Reset() {
*x = ContainerAttachRequest{}
mi := &file_rpc_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ContainerAttachRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ContainerAttachRequest) ProtoMessage() {}
func (x *ContainerAttachRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[23]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ContainerAttachRequest.ProtoReflect.Descriptor instead.
func (*ContainerAttachRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{23}
}
func (x *ContainerAttachRequest) GetContainerId() string {
if x != nil {
return x.ContainerId
}
return ""
}
func (x *ContainerAttachRequest) GetPayload() isContainerAttachRequest_Payload {
if x != nil {
return x.Payload
}
return nil
}
func (x *ContainerAttachRequest) GetStdin() []byte {
if x != nil {
if x, ok := x.Payload.(*ContainerAttachRequest_Stdin); ok {
return x.Stdin
}
}
return nil
}
func (x *ContainerAttachRequest) GetResize() *ResizePayload {
if x != nil {
if x, ok := x.Payload.(*ContainerAttachRequest_Resize); ok {
return x.Resize
}
}
return nil
}
type isContainerAttachRequest_Payload interface {
isContainerAttachRequest_Payload()
}
type ContainerAttachRequest_Stdin struct {
Stdin []byte `protobuf:"bytes,2,opt,name=stdin,proto3,oneof"`
}
type ContainerAttachRequest_Resize struct {
Resize *ResizePayload `protobuf:"bytes,3,opt,name=resize,proto3,oneof"`
}
func (*ContainerAttachRequest_Stdin) isContainerAttachRequest_Payload() {}
func (*ContainerAttachRequest_Resize) isContainerAttachRequest_Payload() {}
type ContainerAttachResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Stdout []byte `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ContainerAttachResponse) Reset() {
*x = ContainerAttachResponse{}
mi := &file_rpc_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ContainerAttachResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ContainerAttachResponse) ProtoMessage() {}
func (x *ContainerAttachResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[24]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ContainerAttachResponse.ProtoReflect.Descriptor instead.
func (*ContainerAttachResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{24}
}
func (x *ContainerAttachResponse) GetStdout() []byte {
if x != nil {
return x.Stdout
}
return nil
}
var File_rpc_proto protoreflect.FileDescriptor var File_rpc_proto protoreflect.FileDescriptor
const file_rpc_proto_rawDesc = "" + var file_rpc_proto_rawDesc = string([]byte{
"\n" + 0x0a, 0x09, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f,
"\trpc.proto\x12\bprotobuf\x1a\vtypes.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb1\x01\n" + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f,
"\x15ListContainersRequest\x12C\n" + 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
"\x06filter\x18\x01 \x03(\v2+.protobuf.ListContainersRequest.FilterEntryR\x06filter\x1aS\n" + 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72,
"\vFilterEntry\x12\x10\n" + 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74,
"\x03key\x18\x01 \x01(\tR\x03key\x12.\n" + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a,
"\x05value\x18\x02 \x01(\v2\x18.protobuf.RepeatedStringR\x05value:\x028\x01\"(\n" + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
"\x0eRepeatedString\x12\x16\n" + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e,
"\x06values\x18\x01 \x03(\tR\x06values\"M\n" + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46,
"\x16ListContainersResponse\x123\n" + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74,
"\n" + 0x65, 0x72, 0x1a, 0x53, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72,
"containers\x18\x01 \x03(\v2\x13.protobuf.ContainerR\n" + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
"containers\"\xd1\x01\n" + 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
"\x14FindContainerRequest\x12 \n" + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65,
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x12B\n" + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61,
"\x06filter\x18\x02 \x03(\v2*.protobuf.FindContainerRequest.FilterEntryR\x06filter\x1aS\n" + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61,
"\vFilterEntry\x12\x10\n" + 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c,
"\x03key\x18\x01 \x01(\tR\x03key\x12.\n" + 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65,
"\x05value\x18\x02 \x01(\v2\x18.protobuf.RepeatedStringR\x05value:\x028\x01\"J\n" + 0x73, 0x22, 0x4d, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
"\x15FindContainerResponse\x121\n" + 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x63,
"\tcontainer\x18\x01 \x01(\v2\x13.protobuf.ContainerR\tcontainer\"\x89\x01\n" + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
"\x11StreamLogsRequest\x12 \n" + 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x120\n" + 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
"\x05since\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\x12 \n" + 0x22, 0xd1, 0x01, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
"\vstreamTypes\x18\x03 \x01(\x05R\vstreamTypes\">\n" + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e,
"\x12StreamLogsResponse\x12(\n" + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
"\x05event\x18\x01 \x01(\v2\x12.protobuf.LogEventR\x05event\"\xc1\x01\n" + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x42, 0x0a, 0x06, 0x66,
"\x17LogsBetweenDatesRequest\x12 \n" + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72,
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x120\n" + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61,
"\x05since\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\x120\n" + 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74,
"\x05until\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x05until\x12 \n" + 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a,
"\vstreamTypes\x18\x04 \x01(\x05R\vstreamTypes\"\xbf\x01\n" + 0x53, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
"\x15StreamRawBytesRequest\x12 \n" + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x120\n" + 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
"\x05since\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\x05since\x120\n" + 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61,
"\x05until\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\x05until\x12 \n" + 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
"\vstreamTypes\x18\x04 \x01(\x05R\vstreamTypes\",\n" + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4a, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74,
"\x16StreamRawBytesResponse\x12\x12\n" + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a,
"\x04data\x18\x01 \x01(\fR\x04data\"\x15\n" + 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
"\x13StreamEventsRequest\"F\n" + 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
"\x14StreamEventsResponse\x12.\n" + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
"\x05event\x18\x01 \x01(\v2\x18.protobuf.ContainerEventR\x05event\"\x14\n" + 0x22, 0x89, 0x01, 0x0a, 0x11, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52,
"\x12StreamStatsRequest\"B\n" + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
"\x13StreamStatsResponse\x12+\n" + 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e,
"\x04stat\x18\x01 \x01(\v2\x17.protobuf.ContainerStatR\x04stat\"\x11\n" + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63,
"\x0fHostInfoRequest\"6\n" + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
"\x10HostInfoResponse\x12\"\n" + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
"\x04host\x18\x01 \x01(\v2\x0e.protobuf.HostR\x04host\"\x1f\n" + 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74,
"\x1dStreamContainerStartedRequest\"S\n" + 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
"\x1eStreamContainerStartedResponse\x121\n" + 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x12,
"\tcontainer\x18\x01 \x01(\v2\x13.protobuf.ContainerR\tcontainer\"m\n" + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
"\x16ContainerActionRequest\x12 \n" + 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x121\n" + 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x6f, 0x67,
"\x06action\x18\x02 \x01(\x0e2\x19.protobuf.ContainerActionR\x06action\"\x19\n" + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xc1, 0x01, 0x0a,
"\x17ContainerActionResponse\"h\n" + 0x17, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65,
"\x14ContainerExecRequest\x12 \n" + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74,
"\vcontainerId\x18\x01 \x01(\tR\vcontainerId\x12\x18\n" + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
"\acommand\x18\x02 \x03(\tR\acommand\x12\x14\n" + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69,
"\x05stdin\x18\x03 \x01(\fR\x05stdin\"/\n" + 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
"\x15ContainerExecResponse\x12\x16\n" + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
"\x06stdout\x18\x01 \x01(\fR\x06stdout2\xc3\a\n" + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x05,
"\fAgentService\x12U\n" + 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
"\x0eListContainers\x12\x1f.protobuf.ListContainersRequest\x1a .protobuf.ListContainersResponse\"\x00\x12R\n" + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
"\rFindContainer\x12\x1e.protobuf.FindContainerRequest\x1a\x1f.protobuf.FindContainerResponse\"\x00\x12K\n" + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x12, 0x20,
"\n" + 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20,
"StreamLogs\x12\x1b.protobuf.StreamLogsRequest\x1a\x1c.protobuf.StreamLogsResponse\"\x000\x01\x12W\n" + 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73,
"\x10LogsBetweenDates\x12!.protobuf.LogsBetweenDatesRequest\x1a\x1c.protobuf.StreamLogsResponse\"\x000\x01\x12W\n" + 0x22, 0xbf, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79,
"\x0eStreamRawBytes\x12\x1f.protobuf.StreamRawBytesRequest\x1a .protobuf.StreamRawBytesResponse\"\x000\x01\x12Q\n" + 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f,
"\fStreamEvents\x12\x1d.protobuf.StreamEventsRequest\x1a\x1e.protobuf.StreamEventsResponse\"\x000\x01\x12N\n" + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
"\vStreamStats\x12\x1c.protobuf.StreamStatsRequest\x1a\x1d.protobuf.StreamStatsResponse\"\x000\x01\x12o\n" + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05,
"\x16StreamContainerStarted\x12'.protobuf.StreamContainerStartedRequest\x1a(.protobuf.StreamContainerStartedResponse\"\x000\x01\x12C\n" + 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
"\bHostInfo\x12\x19.protobuf.HostInfoRequest\x1a\x1a.protobuf.HostInfoResponse\"\x00\x12X\n" + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
"\x0fContainerAction\x12 .protobuf.ContainerActionRequest\x1a!.protobuf.ContainerActionResponse\"\x00\x12V\n" + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x30,
"\rContainerExec\x12\x1e.protobuf.ContainerExecRequest\x1a\x1f.protobuf.ContainerExecResponse\"\x00(\x010\x01B\x13Z\x11internal/agent/pbb\x06proto3" 0x0a, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c,
0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18,
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70,
0x65, 0x73, 0x22, 0x2c, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42,
0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04,
0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x2e, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22,
0x14, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x42, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53,
0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04,
0x73, 0x74, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53,
0x74, 0x61, 0x74, 0x52, 0x04, 0x73, 0x74, 0x61, 0x74, 0x22, 0x11, 0x0a, 0x0f, 0x48, 0x6f, 0x73,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x10,
0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x22, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x04,
0x68, 0x6f, 0x73, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x1e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52,
0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x6d, 0x0a, 0x16, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a,
0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12,
0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x05, 0x73, 0x74, 0x64,
0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69,
0x6e, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, 0x73,
0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65,
0x73, 0x69, 0x7a, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22,
0x3d, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x2f,
0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x22,
0x90, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74,
0x61, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x05,
0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x73,
0x74, 0x64, 0x69, 0x6e, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52,
0x06, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x22, 0x31, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41,
0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a,
0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73,
0x74, 0x64, 0x6f, 0x75, 0x74, 0x32, 0xa1, 0x08, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a,
0x0d, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x12,
0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f,
0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57,
0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74,
0x65, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x6f,
0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79,
0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42,
0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
0x12, 0x51, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x30, 0x01, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61,
0x74, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x27, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f,
0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x45, 0x78, 0x65, 0x63, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5c, 0x0a, 0x0f, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x12, 0x20,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x13, 0x5a, 0x11, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x62, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var ( var (
file_rpc_proto_rawDescOnce sync.Once file_rpc_proto_rawDescOnce sync.Once
@@ -1136,7 +1499,7 @@ func file_rpc_proto_rawDescGZIP() []byte {
return file_rpc_proto_rawDescData return file_rpc_proto_rawDescData
} }
var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 27)
var file_rpc_proto_goTypes = []any{ var file_rpc_proto_goTypes = []any{
(*ListContainersRequest)(nil), // 0: protobuf.ListContainersRequest (*ListContainersRequest)(nil), // 0: protobuf.ListContainersRequest
(*RepeatedString)(nil), // 1: protobuf.RepeatedString (*RepeatedString)(nil), // 1: protobuf.RepeatedString
@@ -1159,62 +1522,69 @@ var file_rpc_proto_goTypes = []any{
(*ContainerActionRequest)(nil), // 18: protobuf.ContainerActionRequest (*ContainerActionRequest)(nil), // 18: protobuf.ContainerActionRequest
(*ContainerActionResponse)(nil), // 19: protobuf.ContainerActionResponse (*ContainerActionResponse)(nil), // 19: protobuf.ContainerActionResponse
(*ContainerExecRequest)(nil), // 20: protobuf.ContainerExecRequest (*ContainerExecRequest)(nil), // 20: protobuf.ContainerExecRequest
(*ContainerExecResponse)(nil), // 21: protobuf.ContainerExecResponse (*ResizePayload)(nil), // 21: protobuf.ResizePayload
nil, // 22: protobuf.ListContainersRequest.FilterEntry (*ContainerExecResponse)(nil), // 22: protobuf.ContainerExecResponse
nil, // 23: protobuf.FindContainerRequest.FilterEntry (*ContainerAttachRequest)(nil), // 23: protobuf.ContainerAttachRequest
(*Container)(nil), // 24: protobuf.Container (*ContainerAttachResponse)(nil), // 24: protobuf.ContainerAttachResponse
(*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp nil, // 25: protobuf.ListContainersRequest.FilterEntry
(*LogEvent)(nil), // 26: protobuf.LogEvent nil, // 26: protobuf.FindContainerRequest.FilterEntry
(*ContainerEvent)(nil), // 27: protobuf.ContainerEvent (*Container)(nil), // 27: protobuf.Container
(*ContainerStat)(nil), // 28: protobuf.ContainerStat (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp
(*Host)(nil), // 29: protobuf.Host (*LogEvent)(nil), // 29: protobuf.LogEvent
(ContainerAction)(0), // 30: protobuf.ContainerAction (*ContainerEvent)(nil), // 30: protobuf.ContainerEvent
(*ContainerStat)(nil), // 31: protobuf.ContainerStat
(*Host)(nil), // 32: protobuf.Host
(ContainerAction)(0), // 33: protobuf.ContainerAction
} }
var file_rpc_proto_depIdxs = []int32{ var file_rpc_proto_depIdxs = []int32{
22, // 0: protobuf.ListContainersRequest.filter:type_name -> protobuf.ListContainersRequest.FilterEntry 25, // 0: protobuf.ListContainersRequest.filter:type_name -> protobuf.ListContainersRequest.FilterEntry
24, // 1: protobuf.ListContainersResponse.containers:type_name -> protobuf.Container 27, // 1: protobuf.ListContainersResponse.containers:type_name -> protobuf.Container
23, // 2: protobuf.FindContainerRequest.filter:type_name -> protobuf.FindContainerRequest.FilterEntry 26, // 2: protobuf.FindContainerRequest.filter:type_name -> protobuf.FindContainerRequest.FilterEntry
24, // 3: protobuf.FindContainerResponse.container:type_name -> protobuf.Container 27, // 3: protobuf.FindContainerResponse.container:type_name -> protobuf.Container
25, // 4: protobuf.StreamLogsRequest.since:type_name -> google.protobuf.Timestamp 28, // 4: protobuf.StreamLogsRequest.since:type_name -> google.protobuf.Timestamp
26, // 5: protobuf.StreamLogsResponse.event:type_name -> protobuf.LogEvent 29, // 5: protobuf.StreamLogsResponse.event:type_name -> protobuf.LogEvent
25, // 6: protobuf.LogsBetweenDatesRequest.since:type_name -> google.protobuf.Timestamp 28, // 6: protobuf.LogsBetweenDatesRequest.since:type_name -> google.protobuf.Timestamp
25, // 7: protobuf.LogsBetweenDatesRequest.until:type_name -> google.protobuf.Timestamp 28, // 7: protobuf.LogsBetweenDatesRequest.until:type_name -> google.protobuf.Timestamp
25, // 8: protobuf.StreamRawBytesRequest.since:type_name -> google.protobuf.Timestamp 28, // 8: protobuf.StreamRawBytesRequest.since:type_name -> google.protobuf.Timestamp
25, // 9: protobuf.StreamRawBytesRequest.until:type_name -> google.protobuf.Timestamp 28, // 9: protobuf.StreamRawBytesRequest.until:type_name -> google.protobuf.Timestamp
27, // 10: protobuf.StreamEventsResponse.event:type_name -> protobuf.ContainerEvent 30, // 10: protobuf.StreamEventsResponse.event:type_name -> protobuf.ContainerEvent
28, // 11: protobuf.StreamStatsResponse.stat:type_name -> protobuf.ContainerStat 31, // 11: protobuf.StreamStatsResponse.stat:type_name -> protobuf.ContainerStat
29, // 12: protobuf.HostInfoResponse.host:type_name -> protobuf.Host 32, // 12: protobuf.HostInfoResponse.host:type_name -> protobuf.Host
24, // 13: protobuf.StreamContainerStartedResponse.container:type_name -> protobuf.Container 27, // 13: protobuf.StreamContainerStartedResponse.container:type_name -> protobuf.Container
30, // 14: protobuf.ContainerActionRequest.action:type_name -> protobuf.ContainerAction 33, // 14: protobuf.ContainerActionRequest.action:type_name -> protobuf.ContainerAction
1, // 15: protobuf.ListContainersRequest.FilterEntry.value:type_name -> protobuf.RepeatedString 21, // 15: protobuf.ContainerExecRequest.resize:type_name -> protobuf.ResizePayload
1, // 16: protobuf.FindContainerRequest.FilterEntry.value:type_name -> protobuf.RepeatedString 21, // 16: protobuf.ContainerAttachRequest.resize:type_name -> protobuf.ResizePayload
0, // 17: protobuf.AgentService.ListContainers:input_type -> protobuf.ListContainersRequest 1, // 17: protobuf.ListContainersRequest.FilterEntry.value:type_name -> protobuf.RepeatedString
3, // 18: protobuf.AgentService.FindContainer:input_type -> protobuf.FindContainerRequest 1, // 18: protobuf.FindContainerRequest.FilterEntry.value:type_name -> protobuf.RepeatedString
5, // 19: protobuf.AgentService.StreamLogs:input_type -> protobuf.StreamLogsRequest 0, // 19: protobuf.AgentService.ListContainers:input_type -> protobuf.ListContainersRequest
7, // 20: protobuf.AgentService.LogsBetweenDates:input_type -> protobuf.LogsBetweenDatesRequest 3, // 20: protobuf.AgentService.FindContainer:input_type -> protobuf.FindContainerRequest
8, // 21: protobuf.AgentService.StreamRawBytes:input_type -> protobuf.StreamRawBytesRequest 5, // 21: protobuf.AgentService.StreamLogs:input_type -> protobuf.StreamLogsRequest
10, // 22: protobuf.AgentService.StreamEvents:input_type -> protobuf.StreamEventsRequest 7, // 22: protobuf.AgentService.LogsBetweenDates:input_type -> protobuf.LogsBetweenDatesRequest
12, // 23: protobuf.AgentService.StreamStats:input_type -> protobuf.StreamStatsRequest 8, // 23: protobuf.AgentService.StreamRawBytes:input_type -> protobuf.StreamRawBytesRequest
16, // 24: protobuf.AgentService.StreamContainerStarted:input_type -> protobuf.StreamContainerStartedRequest 10, // 24: protobuf.AgentService.StreamEvents:input_type -> protobuf.StreamEventsRequest
14, // 25: protobuf.AgentService.HostInfo:input_type -> protobuf.HostInfoRequest 12, // 25: protobuf.AgentService.StreamStats:input_type -> protobuf.StreamStatsRequest
18, // 26: protobuf.AgentService.ContainerAction:input_type -> protobuf.ContainerActionRequest 16, // 26: protobuf.AgentService.StreamContainerStarted:input_type -> protobuf.StreamContainerStartedRequest
20, // 27: protobuf.AgentService.ContainerExec:input_type -> protobuf.ContainerExecRequest 14, // 27: protobuf.AgentService.HostInfo:input_type -> protobuf.HostInfoRequest
2, // 28: protobuf.AgentService.ListContainers:output_type -> protobuf.ListContainersResponse 18, // 28: protobuf.AgentService.ContainerAction:input_type -> protobuf.ContainerActionRequest
4, // 29: protobuf.AgentService.FindContainer:output_type -> protobuf.FindContainerResponse 20, // 29: protobuf.AgentService.ContainerExec:input_type -> protobuf.ContainerExecRequest
6, // 30: protobuf.AgentService.StreamLogs:output_type -> protobuf.StreamLogsResponse 23, // 30: protobuf.AgentService.ContainerAttach:input_type -> protobuf.ContainerAttachRequest
6, // 31: protobuf.AgentService.LogsBetweenDates:output_type -> protobuf.StreamLogsResponse 2, // 31: protobuf.AgentService.ListContainers:output_type -> protobuf.ListContainersResponse
9, // 32: protobuf.AgentService.StreamRawBytes:output_type -> protobuf.StreamRawBytesResponse 4, // 32: protobuf.AgentService.FindContainer:output_type -> protobuf.FindContainerResponse
11, // 33: protobuf.AgentService.StreamEvents:output_type -> protobuf.StreamEventsResponse 6, // 33: protobuf.AgentService.StreamLogs:output_type -> protobuf.StreamLogsResponse
13, // 34: protobuf.AgentService.StreamStats:output_type -> protobuf.StreamStatsResponse 6, // 34: protobuf.AgentService.LogsBetweenDates:output_type -> protobuf.StreamLogsResponse
17, // 35: protobuf.AgentService.StreamContainerStarted:output_type -> protobuf.StreamContainerStartedResponse 9, // 35: protobuf.AgentService.StreamRawBytes:output_type -> protobuf.StreamRawBytesResponse
15, // 36: protobuf.AgentService.HostInfo:output_type -> protobuf.HostInfoResponse 11, // 36: protobuf.AgentService.StreamEvents:output_type -> protobuf.StreamEventsResponse
19, // 37: protobuf.AgentService.ContainerAction:output_type -> protobuf.ContainerActionResponse 13, // 37: protobuf.AgentService.StreamStats:output_type -> protobuf.StreamStatsResponse
21, // 38: protobuf.AgentService.ContainerExec:output_type -> protobuf.ContainerExecResponse 17, // 38: protobuf.AgentService.StreamContainerStarted:output_type -> protobuf.StreamContainerStartedResponse
28, // [28:39] is the sub-list for method output_type 15, // 39: protobuf.AgentService.HostInfo:output_type -> protobuf.HostInfoResponse
17, // [17:28] is the sub-list for method input_type 19, // 40: protobuf.AgentService.ContainerAction:output_type -> protobuf.ContainerActionResponse
17, // [17:17] is the sub-list for extension type_name 22, // 41: protobuf.AgentService.ContainerExec:output_type -> protobuf.ContainerExecResponse
17, // [17:17] is the sub-list for extension extendee 24, // 42: protobuf.AgentService.ContainerAttach:output_type -> protobuf.ContainerAttachResponse
0, // [0:17] is the sub-list for field type_name 31, // [31:43] is the sub-list for method output_type
19, // [19:31] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
} }
func init() { file_rpc_proto_init() } func init() { file_rpc_proto_init() }
@@ -1223,13 +1593,21 @@ func file_rpc_proto_init() {
return return
} }
file_types_proto_init() file_types_proto_init()
file_rpc_proto_msgTypes[20].OneofWrappers = []any{
(*ContainerExecRequest_Stdin)(nil),
(*ContainerExecRequest_Resize)(nil),
}
file_rpc_proto_msgTypes[23].OneofWrappers = []any{
(*ContainerAttachRequest_Stdin)(nil),
(*ContainerAttachRequest_Resize)(nil),
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_rpc_proto_rawDesc), len(file_rpc_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_rpc_proto_rawDesc), len(file_rpc_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 24, NumMessages: 27,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT. // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-grpc v1.5.1 // - protoc-gen-go-grpc v1.5.1
// - protoc v5.29.3 // - protoc v6.33.1
// source: rpc.proto // source: rpc.proto
package pb package pb
@@ -30,6 +30,7 @@ const (
AgentService_HostInfo_FullMethodName = "/protobuf.AgentService/HostInfo" AgentService_HostInfo_FullMethodName = "/protobuf.AgentService/HostInfo"
AgentService_ContainerAction_FullMethodName = "/protobuf.AgentService/ContainerAction" AgentService_ContainerAction_FullMethodName = "/protobuf.AgentService/ContainerAction"
AgentService_ContainerExec_FullMethodName = "/protobuf.AgentService/ContainerExec" AgentService_ContainerExec_FullMethodName = "/protobuf.AgentService/ContainerExec"
AgentService_ContainerAttach_FullMethodName = "/protobuf.AgentService/ContainerAttach"
) )
// AgentServiceClient is the client API for AgentService service. // AgentServiceClient is the client API for AgentService service.
@@ -47,6 +48,7 @@ type AgentServiceClient interface {
HostInfo(ctx context.Context, in *HostInfoRequest, opts ...grpc.CallOption) (*HostInfoResponse, error) HostInfo(ctx context.Context, in *HostInfoRequest, opts ...grpc.CallOption) (*HostInfoResponse, error)
ContainerAction(ctx context.Context, in *ContainerActionRequest, opts ...grpc.CallOption) (*ContainerActionResponse, error) ContainerAction(ctx context.Context, in *ContainerActionRequest, opts ...grpc.CallOption) (*ContainerActionResponse, error)
ContainerExec(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ContainerExecRequest, ContainerExecResponse], error) ContainerExec(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ContainerExecRequest, ContainerExecResponse], error)
ContainerAttach(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ContainerAttachRequest, ContainerAttachResponse], error)
} }
type agentServiceClient struct { type agentServiceClient struct {
@@ -224,6 +226,19 @@ func (c *agentServiceClient) ContainerExec(ctx context.Context, opts ...grpc.Cal
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type AgentService_ContainerExecClient = grpc.BidiStreamingClient[ContainerExecRequest, ContainerExecResponse] type AgentService_ContainerExecClient = grpc.BidiStreamingClient[ContainerExecRequest, ContainerExecResponse]
func (c *agentServiceClient) ContainerAttach(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ContainerAttachRequest, ContainerAttachResponse], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &AgentService_ServiceDesc.Streams[7], AgentService_ContainerAttach_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[ContainerAttachRequest, ContainerAttachResponse]{ClientStream: stream}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type AgentService_ContainerAttachClient = grpc.BidiStreamingClient[ContainerAttachRequest, ContainerAttachResponse]
// AgentServiceServer is the server API for AgentService service. // AgentServiceServer is the server API for AgentService service.
// All implementations must embed UnimplementedAgentServiceServer // All implementations must embed UnimplementedAgentServiceServer
// for forward compatibility. // for forward compatibility.
@@ -239,6 +254,7 @@ type AgentServiceServer interface {
HostInfo(context.Context, *HostInfoRequest) (*HostInfoResponse, error) HostInfo(context.Context, *HostInfoRequest) (*HostInfoResponse, error)
ContainerAction(context.Context, *ContainerActionRequest) (*ContainerActionResponse, error) ContainerAction(context.Context, *ContainerActionRequest) (*ContainerActionResponse, error)
ContainerExec(grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse]) error ContainerExec(grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse]) error
ContainerAttach(grpc.BidiStreamingServer[ContainerAttachRequest, ContainerAttachResponse]) error
mustEmbedUnimplementedAgentServiceServer() mustEmbedUnimplementedAgentServiceServer()
} }
@@ -282,6 +298,9 @@ func (UnimplementedAgentServiceServer) ContainerAction(context.Context, *Contain
func (UnimplementedAgentServiceServer) ContainerExec(grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse]) error { func (UnimplementedAgentServiceServer) ContainerExec(grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse]) error {
return status.Errorf(codes.Unimplemented, "method ContainerExec not implemented") return status.Errorf(codes.Unimplemented, "method ContainerExec not implemented")
} }
func (UnimplementedAgentServiceServer) ContainerAttach(grpc.BidiStreamingServer[ContainerAttachRequest, ContainerAttachResponse]) error {
return status.Errorf(codes.Unimplemented, "method ContainerAttach not implemented")
}
func (UnimplementedAgentServiceServer) mustEmbedUnimplementedAgentServiceServer() {} func (UnimplementedAgentServiceServer) mustEmbedUnimplementedAgentServiceServer() {}
func (UnimplementedAgentServiceServer) testEmbeddedByValue() {} func (UnimplementedAgentServiceServer) testEmbeddedByValue() {}
@@ -448,6 +467,13 @@ func _AgentService_ContainerExec_Handler(srv interface{}, stream grpc.ServerStre
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type AgentService_ContainerExecServer = grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse] type AgentService_ContainerExecServer = grpc.BidiStreamingServer[ContainerExecRequest, ContainerExecResponse]
func _AgentService_ContainerAttach_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(AgentServiceServer).ContainerAttach(&grpc.GenericServerStream[ContainerAttachRequest, ContainerAttachResponse]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type AgentService_ContainerAttachServer = grpc.BidiStreamingServer[ContainerAttachRequest, ContainerAttachResponse]
// AgentService_ServiceDesc is the grpc.ServiceDesc for AgentService service. // AgentService_ServiceDesc is the grpc.ServiceDesc for AgentService service.
// It's only intended for direct use with grpc.RegisterService, // It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy) // and not to be introspected or modified (even as a copy)
@@ -509,6 +535,12 @@ var AgentService_ServiceDesc = grpc.ServiceDesc{
ServerStreams: true, ServerStreams: true,
ClientStreams: true, ClientStreams: true,
}, },
{
StreamName: "ContainerAttach",
Handler: _AgentService_ContainerAttach_Handler,
ServerStreams: true,
ClientStreams: true,
},
}, },
Metadata: "rpc.proto", Metadata: "rpc.proto",
} }

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.6 // protoc-gen-go v1.36.5
// protoc v5.29.3 // protoc v6.33.1
// source: types.proto // source: types.proto
package pb package pb
@@ -718,81 +718,128 @@ func (x *Host) GetDockerVersion() string {
var File_types_proto protoreflect.FileDescriptor var File_types_proto protoreflect.FileDescriptor
const file_types_proto_rawDesc = "" + var file_types_proto_rawDesc = string([]byte{
"\n" + 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70,
"\vtypes.proto\x12\bprotobuf\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19google/protobuf/any.proto\"\xa2\x05\n" + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
"\tContainer\x12\x0e\n" + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
"\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72,
"\x05image\x18\x03 \x01(\tR\x05image\x12\x16\n" + 0x6f, 0x74, 0x6f, 0x22, 0xa2, 0x05, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
"\x06status\x18\x04 \x01(\tR\x06status\x12\x14\n" + 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
"\x05state\x18\x05 \x01(\tR\x05state\x12\x18\n" + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
"\aImageId\x18\x06 \x01(\tR\aImageId\x124\n" + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03,
"\acreated\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\acreated\x124\n" + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
"\astarted\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\astarted\x12\x16\n" + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61,
"\x06health\x18\t \x01(\tR\x06health\x12\x12\n" + 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01,
"\x04host\x18\n" + 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6d, 0x61,
" \x01(\tR\x04host\x12\x10\n" + 0x67, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x49, 0x6d, 0x61, 0x67,
"\x03tty\x18\v \x01(\bR\x03tty\x127\n" + 0x65, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x07,
"\x06labels\x18\f \x03(\v2\x1f.protobuf.Container.LabelsEntryR\x06labels\x12-\n" + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
"\x05stats\x18\r \x03(\v2\x17.protobuf.ContainerStatR\x05stats\x12\x14\n" + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
"\x05group\x18\x0e \x01(\tR\x05group\x12\x18\n" + 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x74, 0x61,
"\acommand\x18\x0f \x01(\tR\acommand\x126\n" + 0x72, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
"\bfinished\x18\x10 \x01(\v2\x1a.google.protobuf.TimestampR\bfinished\x12 \n" + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
"\vmemoryLimit\x18\x11 \x01(\x04R\vmemoryLimit\x12\x1a\n" + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12,
"\bcpuLimit\x18\x12 \x01(\x01R\bcpuLimit\x12 \n" + 0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52,
"\vfullyLoaded\x18\x13 \x01(\bR\vfullyLoaded\x1a9\n" + 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18,
"\vLabelsEntry\x12\x10\n" + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74,
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + 0x74, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x74, 0x74, 0x79, 0x12, 0x37, 0x0a,
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x87\x01\n" + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
"\rContainerStat\x12\x0e\n" + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1e\n" + 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06,
"\n" + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18,
"cpuPercent\x18\x02 \x01(\x01R\n" + 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
"cpuPercent\x12 \n" + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x52, 0x05,
"\vmemoryUsage\x18\x03 \x01(\x01R\vmemoryUsage\x12$\n" + 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0e,
"\rmemoryPercent\x18\x04 \x01(\x01R\rmemoryPercent\"\x90\x02\n" + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63,
"\bLogEvent\x12\x0e\n" + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
"\x02id\x18\x01 \x01(\rR\x02id\x12 \n" + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65,
"\vcontainerId\x18\x02 \x01(\tR\vcontainerId\x12.\n" + 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
"\amessage\x18\x03 \x01(\v2\x14.google.protobuf.AnyR\amessage\x128\n" + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
"\ttimestamp\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12\x14\n" + 0x61, 0x6d, 0x70, 0x52, 0x08, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x20, 0x0a,
"\x05level\x18\x05 \x01(\tR\x05level\x12\x16\n" + 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x11, 0x20, 0x01,
"\x06stream\x18\x06 \x01(\tR\x06stream\x12\x1a\n" + 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12,
"\bposition\x18\a \x01(\tR\bposition\x12\x1e\n" + 0x1a, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28,
"\n" + 0x01, 0x52, 0x08, 0x63, 0x70, 0x75, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x66,
"rawMessage\x18\b \x01(\tR\n" + 0x75, 0x6c, 0x6c, 0x79, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08,
"rawMessage\")\n" + 0x52, 0x0b, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x1a, 0x39, 0x0a,
"\rSimpleMessage\x12\x18\n" + 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
"\amessage\x18\x01 \x01(\tR\amessage\"$\n" + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
"\x0eComplexMessage\x12\x12\n" + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
"\x04data\x18\x01 \x01(\fR\x04data\"\x8c\x01\n" + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x87, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e,
"\x0eContainerEvent\x12\x18\n" + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
"\aactorId\x18\x01 \x01(\tR\aactorId\x12\x12\n" + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x70,
"\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + 0x75, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a,
"\x04host\x18\x03 \x01(\tR\x04host\x128\n" + 0x63, 0x70, 0x75, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65,
"\ttimestamp\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\"\xaf\x03\n" + 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52,
"\x04Host\x12\x0e\n" + 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0d,
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20,
"\x04name\x18\x02 \x01(\tR\x04name\x12 \n" + 0x01, 0x28, 0x01, 0x52, 0x0d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65,
"\vnodeAddress\x18\x03 \x01(\tR\vnodeAddress\x12\x14\n" + 0x6e, 0x74, 0x22, 0x90, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
"\x05swarm\x18\x04 \x01(\bR\x05swarm\x122\n" + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12,
"\x06labels\x18\x05 \x03(\v2\x1a.protobuf.Host.LabelsEntryR\x06labels\x12(\n" + 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02,
"\x0foperatingSystem\x18\x06 \x01(\tR\x0foperatingSystem\x12\x1c\n" + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49,
"\tosVersion\x18\a \x01(\tR\tosVersion\x12\x16\n" + 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01,
"\x06osType\x18\b \x01(\tR\x06osType\x12\x1a\n" + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
"\bcpuCores\x18\t \x01(\rR\bcpuCores\x12\x16\n" + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
"\x06memory\x18\n" + 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04,
" \x01(\x04R\x06memory\x12\"\n" + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
"\fagentVersion\x18\v \x01(\tR\fagentVersion\x12$\n" + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
"\rdockerVersion\x18\f \x01(\tR\rdockerVersion\x1a9\n" + 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6c,
"\vLabelsEntry\x12\x10\n" + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65,
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28,
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01*3\n" + 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73,
"\x0fContainerAction\x12\t\n" + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73,
"\x05Start\x10\x00\x12\b\n" + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x77, 0x4d, 0x65, 0x73, 0x73,
"\x04Stop\x10\x01\x12\v\n" + 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x4d, 0x65,
"\aRestart\x10\x02B\x13Z\x11internal/agent/pbb\x06proto3" 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x29, 0x0a, 0x0d, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x22, 0x24, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8c, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74,
0x6f, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x6f,
0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xaf, 0x03, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x0e,
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x77, 0x61, 0x72, 0x6d, 0x18, 0x04, 0x20,
0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x77, 0x61, 0x72, 0x6d, 0x12, 0x32, 0x0a, 0x06, 0x6c, 0x61,
0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x28,
0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x73, 0x74, 0x65,
0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6e, 0x67, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x73, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x73, 0x54, 0x79, 0x70, 0x65,
0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a,
0x0a, 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x08, 0x63, 0x70, 0x75, 0x43, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65,
0x6d, 0x6f, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
0x72, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64,
0x6f, 0x63, 0x6b, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b,
0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x33, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x74,
0x61, 0x72, 0x74, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x10, 0x01, 0x12,
0x0b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x10, 0x02, 0x42, 0x13, 0x5a, 0x11,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70,
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
})
var ( var (
file_types_proto_rawDescOnce sync.Once file_types_proto_rawDescOnce sync.Once

View File

@@ -289,7 +289,7 @@ func (s *server) ContainerExec(stream pb.AgentService_ContainerExecServer) error
} }
cancelCtx, cancel := context.WithCancel(stream.Context()) cancelCtx, cancel := context.WithCancel(stream.Context())
containerWriter, containerReader, err := s.client.ContainerExec(cancelCtx, request.ContainerId, request.Command) session, err := s.client.ContainerExec(cancelCtx, request.ContainerId, request.Command)
if err != nil { if err != nil {
cancel() cancel()
return status.Error(codes.Internal, err.Error()) return status.Error(codes.Internal, err.Error())
@@ -297,26 +297,12 @@ func (s *server) ContainerExec(stream pb.AgentService_ContainerExecServer) error
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Go(func() { // Read from container and send to client
defer cancel()
defer containerWriter.Close()
for {
stdinReq, err := stream.Recv()
if err != nil {
return
}
if _, err := containerWriter.Write(stdinReq.Stdin); err != nil {
return
}
}
})
wg.Go(func() { wg.Go(func() {
defer cancel() defer cancel()
buffer := make([]byte, 1024) buffer := make([]byte, 1024)
for { for {
n, err := containerReader.Read(buffer) n, err := session.Reader.Read(buffer)
if err != nil { if err != nil {
return return
} }
@@ -327,6 +313,90 @@ func (s *server) ContainerExec(stream pb.AgentService_ContainerExecServer) error
} }
}) })
// Read from client stream and handle stdin/resize
wg.Go(func() {
defer cancel()
defer session.Writer.Close()
for {
req, err := stream.Recv()
if err != nil {
return
}
switch payload := req.Payload.(type) {
case *pb.ContainerExecRequest_Stdin:
if _, err := session.Writer.Write(payload.Stdin); err != nil {
log.Error().Err(err).Msg("error writing stdin to container")
return
}
case *pb.ContainerExecRequest_Resize:
if err := session.Resize(uint(payload.Resize.Width), uint(payload.Resize.Height)); err != nil {
log.Error().Err(err).Msg("error resizing terminal")
}
}
}
})
wg.Wait()
return nil
}
func (s *server) ContainerAttach(stream pb.AgentService_ContainerAttachServer) error {
request, err := stream.Recv()
if err != nil {
return status.Error(codes.Internal, err.Error())
}
cancelCtx, cancel := context.WithCancel(stream.Context())
session, err := s.client.ContainerAttach(cancelCtx, request.ContainerId)
if err != nil {
cancel()
return status.Error(codes.Internal, err.Error())
}
var wg sync.WaitGroup
// Read from container and send to client
wg.Go(func() {
defer cancel()
buffer := make([]byte, 1024)
for {
n, err := session.Reader.Read(buffer)
if err != nil {
return
}
if err := stream.Send(&pb.ContainerAttachResponse{Stdout: buffer[:n]}); err != nil {
return
}
}
})
// Read from client stream and handle stdin/resize
wg.Go(func() {
defer cancel()
defer session.Writer.Close()
for {
req, err := stream.Recv()
if err != nil {
return
}
switch payload := req.Payload.(type) {
case *pb.ContainerAttachRequest_Stdin:
if _, err := session.Writer.Write(payload.Stdin); err != nil {
log.Error().Err(err).Msg("error writing stdin to container")
return
}
case *pb.ContainerAttachRequest_Resize:
if err := session.Resize(uint(payload.Resize.Width), uint(payload.Resize.Height)); err != nil {
log.Error().Err(err).Msg("error resizing terminal")
}
}
}
})
wg.Wait() wg.Wait()
return nil return nil

View File

@@ -28,6 +28,19 @@ func (s StdType) String() string {
} }
} }
type ExecSession struct {
Writer io.WriteCloser
Reader io.Reader
Resize func(width uint, height uint) error
}
type ExecEvent struct {
Type string `json:"type"`
Data string `json:"data,omitempty"`
Width uint `json:"width,omitempty"`
Height uint `json:"height,omitempty"`
}
type Client interface { type Client interface {
ListContainers(context.Context, ContainerLabels) ([]Container, error) ListContainers(context.Context, ContainerLabels) ([]Container, error)
FindContainer(context.Context, string) (Container, error) FindContainer(context.Context, string) (Container, error)
@@ -38,6 +51,6 @@ type Client interface {
Ping(context.Context) error Ping(context.Context) error
Host() Host Host() Host
ContainerActions(ctx context.Context, action ContainerAction, containerID string) error ContainerActions(ctx context.Context, action ContainerAction, containerID string) error
ContainerAttach(ctx context.Context, id string) (io.WriteCloser, io.Reader, error) ContainerAttach(ctx context.Context, id string) (*ExecSession, error)
ContainerExec(ctx context.Context, id string, cmd []string) (io.WriteCloser, io.Reader, error) ContainerExec(ctx context.Context, id string, cmd []string) (*ExecSession, error)
} }

View File

@@ -301,7 +301,7 @@ func (d *DockerClient) Host() container.Host {
return d.host return d.host
} }
func (d *DockerClient) ContainerAttach(ctx context.Context, id string) (io.WriteCloser, io.Reader, error) { func (d *DockerClient) ContainerAttach(ctx context.Context, id string) (*container.ExecSession, error) {
log.Debug().Str("id", id).Str("host", d.host.Name).Msg("Attaching to container") log.Debug().Str("id", id).Str("host", d.host.Name).Msg("Attaching to container")
options := docker.AttachOptions{ options := docker.AttachOptions{
Stream: true, Stream: true,
@@ -313,13 +313,24 @@ func (d *DockerClient) ContainerAttach(ctx context.Context, id string) (io.Write
waiter, err := d.cli.ContainerAttach(ctx, id, options) waiter, err := d.cli.ContainerAttach(ctx, id, options)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
return waiter.Conn, waiter.Reader, nil // Docker attach doesn't support resize - it's not an exec session
// Return a no-op resize function
resizeFn := func(width uint, height uint) error {
log.Debug().Uint("width", width).Uint("height", height).Msg("resize not supported for attach")
return nil
}
return &container.ExecSession{
Writer: waiter.Conn,
Reader: waiter.Reader,
Resize: resizeFn,
}, nil
} }
func (d *DockerClient) ContainerExec(ctx context.Context, id string, cmd []string) (io.WriteCloser, io.Reader, error) { func (d *DockerClient) ContainerExec(ctx context.Context, id string, cmd []string) (*container.ExecSession, error) {
log.Debug().Str("id", id).Str("host", d.host.Name).Msg("Executing command in container") log.Debug().Str("id", id).Str("host", d.host.Name).Msg("Executing command in container")
options := docker.ExecOptions{ options := docker.ExecOptions{
AttachStdout: true, AttachStdout: true,
@@ -331,22 +342,35 @@ func (d *DockerClient) ContainerExec(ctx context.Context, id string, cmd []strin
execID, err := d.cli.ContainerExecCreate(ctx, id, options) execID, err := d.cli.ContainerExecCreate(ctx, id, options)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
waiter, err := d.cli.ContainerExecAttach(ctx, execID.ID, docker.ExecAttachOptions{}) waiter, err := d.cli.ContainerExecAttach(ctx, execID.ID, docker.ExecAttachOptions{})
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
// Initial resize
if err = d.cli.ContainerExecResize(ctx, execID.ID, docker.ResizeOptions{ if err = d.cli.ContainerExecResize(ctx, execID.ID, docker.ResizeOptions{
Width: 100, Width: 100,
Height: 40, Height: 40,
}); err != nil { }); err != nil {
return nil, nil, err return nil, err
} }
return waiter.Conn, waiter.Reader, nil // Create resize closure that captures execID and context
resizeFn := func(width uint, height uint) error {
return d.cli.ContainerExecResize(ctx, execID.ID, docker.ResizeOptions{
Width: width,
Height: height,
})
}
return &container.ExecSession{
Writer: waiter.Conn,
Reader: waiter.Reader,
Resize: resizeFn,
}, nil
} }
func newContainer(c docker.Summary, host string) container.Container { func newContainer(c docker.Summary, host string) container.Container {

View File

@@ -293,9 +293,9 @@ func (k *K8sClient) ContainerActions(ctx context.Context, action container.Conta
panic("not implemented") panic("not implemented")
} }
func (k *K8sClient) ContainerAttach(ctx context.Context, id string) (io.WriteCloser, io.Reader, error) { func (k *K8sClient) ContainerAttach(ctx context.Context, id string) (*container.ExecSession, error) {
namespace, podName, containerName := parsePodContainerID(id) namespace, podName, containerName := parsePodContainerID(id)
log.Debug().Str("container", containerName).Str("pod", podName).Msg("Executing command in pod") log.Debug().Str("container", containerName).Str("pod", podName).Msg("Attaching to pod")
req := k.Clientset.CoreV1().RESTClient().Post(). req := k.Clientset.CoreV1().RESTClient().Post().
Resource("pods"). Resource("pods").
Name(podName). Name(podName).
@@ -317,27 +317,60 @@ func (k *K8sClient) ContainerAttach(ctx context.Context, id string) (io.WriteClo
exec, err := remotecommand.NewSPDYExecutor(k.config, "POST", req.URL()) exec, err := remotecommand.NewSPDYExecutor(k.config, "POST", req.URL())
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
stdinReader, stdinWriter := io.Pipe() stdinReader, stdinWriter := io.Pipe()
stdoutReader, stdoutWriter := io.Pipe() stdoutReader, stdoutWriter := io.Pipe()
// Create TerminalSizeQueue for dynamic resizing
sizeQueue := &terminalSizeQueue{
resizeChan: make(chan remotecommand.TerminalSize, 1),
}
go func() { go func() {
err := exec.StreamWithContext(ctx, remotecommand.StreamOptions{ err := exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdin: stdinReader, Stdin: stdinReader,
Stdout: stdoutWriter, Stdout: stdoutWriter,
Tty: true, Tty: true,
TerminalSizeQueue: sizeQueue,
}) })
if err != nil { if err != nil {
log.Error().Err(err).Msg("Error streaming command") log.Error().Err(err).Msg("Error streaming command")
} }
}() }()
return stdinWriter, stdoutReader, nil // Create resize closure that sends to the queue
resizeFn := func(width uint, height uint) error {
select {
case sizeQueue.resizeChan <- remotecommand.TerminalSize{Width: uint16(width), Height: uint16(height)}:
return nil
default:
return fmt.Errorf("resize queue full")
}
}
return &container.ExecSession{
Writer: stdinWriter,
Reader: stdoutReader,
Resize: resizeFn,
}, nil
} }
func (k *K8sClient) ContainerExec(ctx context.Context, id string, cmd []string) (io.WriteCloser, io.Reader, error) { // terminalSizeQueue implements remotecommand.TerminalSizeQueue
type terminalSizeQueue struct {
resizeChan chan remotecommand.TerminalSize
}
func (t *terminalSizeQueue) Next() *remotecommand.TerminalSize {
size, ok := <-t.resizeChan
if !ok {
return nil
}
return &size
}
func (k *K8sClient) ContainerExec(ctx context.Context, id string, cmd []string) (*container.ExecSession, error) {
namespace, podName, containerName := parsePodContainerID(id) namespace, podName, containerName := parsePodContainerID(id)
log.Debug().Str("container", containerName).Str("pod", podName).Msg("Executing command in pod") log.Debug().Str("container", containerName).Str("pod", podName).Msg("Executing command in pod")
req := k.Clientset.CoreV1().RESTClient().Post(). req := k.Clientset.CoreV1().RESTClient().Post().
@@ -362,24 +395,44 @@ func (k *K8sClient) ContainerExec(ctx context.Context, id string, cmd []string)
exec, err := remotecommand.NewSPDYExecutor(k.config, "POST", req.URL()) exec, err := remotecommand.NewSPDYExecutor(k.config, "POST", req.URL())
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
stdinReader, stdinWriter := io.Pipe() stdinReader, stdinWriter := io.Pipe()
stdoutReader, stdoutWriter := io.Pipe() stdoutReader, stdoutWriter := io.Pipe()
// Create TerminalSizeQueue for dynamic resizing
sizeQueue := &terminalSizeQueue{
resizeChan: make(chan remotecommand.TerminalSize, 1),
}
go func() { go func() {
err := exec.StreamWithContext(ctx, remotecommand.StreamOptions{ err := exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdin: stdinReader, Stdin: stdinReader,
Stdout: stdoutWriter, Stdout: stdoutWriter,
Tty: true, Tty: true,
TerminalSizeQueue: sizeQueue,
}) })
if err != nil { if err != nil {
log.Error().Err(err).Msg("Error streaming command") log.Error().Err(err).Msg("Error streaming command")
} }
}() }()
return stdinWriter, stdoutReader, nil // Create resize closure that sends to the queue
resizeFn := func(width uint, height uint) error {
select {
case sizeQueue.resizeChan <- remotecommand.TerminalSize{Width: uint16(width), Height: uint16(height)}:
return nil
default:
return fmt.Errorf("resize queue full")
}
}
return &container.ExecSession{
Writer: stdinWriter,
Reader: stdoutReader,
Resize: resizeFn,
}, nil
} }
// Helper function to parse pod and container names from container ID // Helper function to parse pod and container names from container ID

View File

@@ -2,6 +2,7 @@ package container_support
import ( import (
"context" "context"
"encoding/json"
"io" "io"
"sync" "sync"
@@ -77,9 +78,9 @@ func (a *agentService) Attach(ctx context.Context, container container.Container
panic("not implemented") panic("not implemented")
} }
func (a *agentService) Exec(ctx context.Context, container container.Container, cmd []string, stdin io.Reader, stdout io.Writer) error { func (a *agentService) Exec(ctx context.Context, c container.Container, cmd []string, stdin io.Reader, stdout io.Writer) error {
cancelCtx, cancel := context.WithCancel(ctx) cancelCtx, cancel := context.WithCancel(ctx)
containerWriter, containerReader, err := a.client.ContainerExec(cancelCtx, container.ID, cmd) session, err := a.client.ContainerExec(cancelCtx, c.ID, cmd)
if err != nil { if err != nil {
cancel() cancel()
@@ -89,15 +90,35 @@ func (a *agentService) Exec(ctx context.Context, container container.Container,
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Go(func() { wg.Go(func() {
if _, err := io.Copy(containerWriter, stdin); err != nil { decoder := json.NewDecoder(stdin)
log.Error().Err(err).Msg("error while reading from ws using agent") loop:
for {
var event container.ExecEvent
if err := decoder.Decode(&event); err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("error decoding event from ws using agent")
}
break
}
switch event.Type {
case "userinput":
if _, err := session.Writer.Write([]byte(event.Data)); err != nil {
log.Error().Err(err).Msg("error writing to container using agent")
break loop
}
case "resize":
if err := session.Resize(event.Width, event.Height); err != nil {
log.Error().Err(err).Msg("error resizing terminal using agent")
}
}
} }
cancel() cancel()
containerWriter.Close() session.Writer.Close()
}) })
wg.Go(func() { wg.Go(func() {
if _, err := stdcopy.StdCopy(stdout, stdout, containerReader); err != nil { if _, err := stdcopy.StdCopy(stdout, stdout, session.Reader); err != nil {
log.Error().Err(err).Msg("error while writing to ws using agent") log.Error().Err(err).Msg("error while writing to ws using agent")
} }
cancel() cancel()

View File

@@ -2,6 +2,7 @@ package docker_support
import ( import (
"context" "context"
"encoding/json"
"io" "io"
"sync" "sync"
"time" "time"
@@ -111,9 +112,9 @@ func (d *DockerClientService) SubscribeContainersStarted(ctx context.Context, co
d.store.SubscribeNewContainers(ctx, containers) d.store.SubscribeNewContainers(ctx, containers)
} }
func (d *DockerClientService) Attach(ctx context.Context, container container.Container, stdin io.Reader, stdout io.Writer) error { func (d *DockerClientService) Attach(ctx context.Context, c container.Container, stdin io.Reader, stdout io.Writer) error {
cancelCtx, cancel := context.WithCancel(ctx) cancelCtx, cancel := context.WithCancel(ctx)
containerWriter, containerReader, err := d.client.ContainerAttach(cancelCtx, container.ID) session, err := d.client.ContainerAttach(cancelCtx, c.ID)
if err != nil { if err != nil {
cancel() cancel()
return err return err
@@ -122,20 +123,42 @@ func (d *DockerClientService) Attach(ctx context.Context, container container.Co
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Go(func() { wg.Go(func() {
if _, err := io.Copy(containerWriter, stdin); err != nil { decoder := json.NewDecoder(stdin)
log.Error().Err(err).Msg("error while reading from ws") loop:
for {
var event container.ExecEvent
if err := decoder.Decode(&event); err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("error while decoding event from ws")
}
break
}
switch event.Type {
case "userinput":
if _, err := session.Writer.Write([]byte(event.Data)); err != nil {
log.Error().Err(err).Msg("error while writing to container")
break loop
}
case "resize":
if err := session.Resize(event.Width, event.Height); err != nil {
log.Error().Err(err).Msg("error while resizing terminal")
}
default:
log.Warn().Str("type", event.Type).Msg("unknown event type")
}
} }
cancel() cancel()
containerWriter.Close() session.Writer.Close()
}) })
wg.Go(func() { wg.Go(func() {
if container.Tty { if c.Tty {
if _, err := io.Copy(stdout, containerReader); err != nil { if _, err := io.Copy(stdout, session.Reader); err != nil {
log.Error().Err(err).Msg("error while writing to ws") log.Error().Err(err).Msg("error while writing to ws")
} }
} else { } else {
if _, err := stdcopy.StdCopy(stdout, stdout, containerReader); err != nil { if _, err := stdcopy.StdCopy(stdout, stdout, session.Reader); err != nil {
log.Error().Err(err).Msg("error while writing to ws") log.Error().Err(err).Msg("error while writing to ws")
} }
} }
@@ -147,25 +170,48 @@ func (d *DockerClientService) Attach(ctx context.Context, container container.Co
return nil return nil
} }
func (d *DockerClientService) Exec(ctx context.Context, container container.Container, cmd []string, stdin io.Reader, stdout io.Writer) error { func (d *DockerClientService) Exec(ctx context.Context, c container.Container, cmd []string, stdin io.Reader, stdout io.Writer) error {
cancelCtx, cancel := context.WithCancel(ctx) cancelCtx, cancel := context.WithCancel(ctx)
containerWriter, containerReader, err := d.client.ContainerExec(cancelCtx, container.ID, cmd) session, err := d.client.ContainerExec(cancelCtx, c.ID, cmd)
if err != nil { if err != nil {
cancel() cancel()
return err return err
} }
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Go(func() { wg.Go(func() {
if _, err := io.Copy(containerWriter, stdin); err != nil { decoder := json.NewDecoder(stdin)
log.Error().Err(err).Msg("error while reading from ws") loop:
for {
var event container.ExecEvent
if err := decoder.Decode(&event); err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("error while decoding event from ws")
}
break
}
switch event.Type {
case "userinput":
if _, err := session.Writer.Write([]byte(event.Data)); err != nil {
log.Error().Err(err).Msg("error while writing to container")
break loop
}
case "resize":
if err := session.Resize(event.Width, event.Height); err != nil {
log.Error().Err(err).Msg("error while resizing terminal")
}
default:
log.Warn().Str("type", event.Type).Msg("unknown event type")
}
} }
cancel() cancel()
containerWriter.Close() session.Writer.Close()
}) })
wg.Go(func() { wg.Go(func() {
if _, err := stdcopy.StdCopy(stdout, stdout, containerReader); err != nil { if _, err := stdcopy.StdCopy(stdout, stdout, session.Reader); err != nil {
log.Error().Err(err).Msg("error while writing to ws") log.Error().Err(err).Msg("error while writing to ws")
} }
cancel() cancel()

View File

@@ -2,6 +2,7 @@ package k8s_support
import ( import (
"context" "context"
"encoding/json"
"io" "io"
"sync" "sync"
@@ -92,9 +93,9 @@ func (k *K8sClientService) SubscribeContainersStarted(ctx context.Context, conta
k.store.SubscribeNewContainers(ctx, containers) k.store.SubscribeNewContainers(ctx, containers)
} }
func (k *K8sClientService) Attach(ctx context.Context, container container.Container, stdin io.Reader, stdout io.Writer) error { func (k *K8sClientService) Attach(ctx context.Context, c container.Container, stdin io.Reader, stdout io.Writer) error {
cancelCtx, cancel := context.WithCancel(ctx) cancelCtx, cancel := context.WithCancel(ctx)
writer, reader, err := k.client.ContainerAttach(cancelCtx, container.ID) session, err := k.client.ContainerAttach(cancelCtx, c.ID)
if err != nil { if err != nil {
cancel() cancel()
return err return err
@@ -103,16 +104,37 @@ func (k *K8sClientService) Attach(ctx context.Context, container container.Conta
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Go(func() { wg.Go(func() {
defer writer.Close() defer session.Writer.Close()
defer cancel() defer cancel()
if _, err := io.Copy(writer, stdin); err != nil {
log.Error().Err(err).Msg("error copying stdin") decoder := json.NewDecoder(stdin)
loop:
for {
var event container.ExecEvent
if err := decoder.Decode(&event); err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("error decoding event")
}
break
}
switch event.Type {
case "userinput":
if _, err := session.Writer.Write([]byte(event.Data)); err != nil {
log.Error().Err(err).Msg("error writing to container")
break loop
}
case "resize":
if err := session.Resize(event.Width, event.Height); err != nil {
log.Error().Err(err).Msg("error resizing terminal")
}
}
} }
}) })
wg.Go(func() { wg.Go(func() {
defer cancel() defer cancel()
if _, err := io.Copy(stdout, reader); err != nil { if _, err := io.Copy(stdout, session.Reader); err != nil {
log.Error().Err(err).Msg("error copying stdout") log.Error().Err(err).Msg("error copying stdout")
} }
}) })
@@ -121,9 +143,9 @@ func (k *K8sClientService) Attach(ctx context.Context, container container.Conta
return nil return nil
} }
func (k *K8sClientService) Exec(ctx context.Context, container container.Container, cmd []string, stdin io.Reader, stdout io.Writer) error { func (k *K8sClientService) Exec(ctx context.Context, c container.Container, cmd []string, stdin io.Reader, stdout io.Writer) error {
cancelCtx, cancel := context.WithCancel(ctx) cancelCtx, cancel := context.WithCancel(ctx)
writer, reader, err := k.client.ContainerExec(cancelCtx, container.ID, cmd) session, err := k.client.ContainerExec(cancelCtx, c.ID, cmd)
if err != nil { if err != nil {
cancel() cancel()
return err return err
@@ -132,16 +154,37 @@ func (k *K8sClientService) Exec(ctx context.Context, container container.Contain
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Go(func() { wg.Go(func() {
defer writer.Close() defer session.Writer.Close()
defer cancel() defer cancel()
if _, err := io.Copy(writer, stdin); err != nil {
log.Error().Err(err).Msg("error copying stdin") decoder := json.NewDecoder(stdin)
loop:
for {
var event container.ExecEvent
if err := decoder.Decode(&event); err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("error decoding event")
}
break
}
switch event.Type {
case "userinput":
if _, err := session.Writer.Write([]byte(event.Data)); err != nil {
log.Error().Err(err).Msg("error writing to container")
break loop
}
case "resize":
if err := session.Resize(event.Width, event.Height); err != nil {
log.Error().Err(err).Msg("error resizing terminal")
}
}
} }
}) })
wg.Go(func() { wg.Go(func() {
defer cancel() defer cancel()
if _, err := io.Copy(stdout, reader); err != nil { if _, err := io.Copy(stdout, session.Reader); err != nil {
log.Error().Err(err).Msg("error copying stdout") log.Error().Err(err).Msg("error copying stdout")
} }
}) })

View File

@@ -45,6 +45,7 @@
"@vueuse/core": "^14.1.0", "@vueuse/core": "^14.1.0",
"@vueuse/integrations": "^14.1.0", "@vueuse/integrations": "^14.1.0",
"@vueuse/router": "14.1.0", "@vueuse/router": "14.1.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0", "@xterm/addon-web-links": "^0.11.0",
"@xterm/xterm": "^5.5.0", "@xterm/xterm": "^5.5.0",
"ansi-to-html": "^0.7.2", "ansi-to-html": "^0.7.2",

12
pnpm-lock.yaml generated
View File

@@ -59,6 +59,9 @@ importers:
'@vueuse/router': '@vueuse/router':
specifier: 14.1.0 specifier: 14.1.0
version: 14.1.0(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) version: 14.1.0(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@xterm/addon-fit':
specifier: ^0.10.0
version: 0.10.0(@xterm/xterm@5.5.0)
'@xterm/addon-web-links': '@xterm/addon-web-links':
specifier: ^0.11.0 specifier: ^0.11.0
version: 0.11.0(@xterm/xterm@5.5.0) version: 0.11.0(@xterm/xterm@5.5.0)
@@ -1965,6 +1968,11 @@ packages:
peerDependencies: peerDependencies:
vue: ^3.5.0 vue: ^3.5.0
'@xterm/addon-fit@0.10.0':
resolution: {integrity: sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==}
peerDependencies:
'@xterm/xterm': ^5.0.0
'@xterm/addon-web-links@0.11.0': '@xterm/addon-web-links@0.11.0':
resolution: {integrity: sha512-nIHQ38pQI+a5kXnRaTgwqSHnX7KE6+4SVoceompgHL26unAxdfP6IPqUTSYPQgSwM56hsElfoNrrW5V7BUED/Q==} resolution: {integrity: sha512-nIHQ38pQI+a5kXnRaTgwqSHnX7KE6+4SVoceompgHL26unAxdfP6IPqUTSYPQgSwM56hsElfoNrrW5V7BUED/Q==}
peerDependencies: peerDependencies:
@@ -5710,6 +5718,10 @@ snapshots:
dependencies: dependencies:
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
'@xterm/addon-fit@0.10.0(@xterm/xterm@5.5.0)':
dependencies:
'@xterm/xterm': 5.5.0
'@xterm/addon-web-links@0.11.0(@xterm/xterm@5.5.0)': '@xterm/addon-web-links@0.11.0(@xterm/xterm@5.5.0)':
dependencies: dependencies:
'@xterm/xterm': 5.5.0 '@xterm/xterm': 5.5.0

View File

@@ -23,6 +23,8 @@ service AgentService {
returns (ContainerActionResponse) {} returns (ContainerActionResponse) {}
rpc ContainerExec(stream ContainerExecRequest) rpc ContainerExec(stream ContainerExecRequest)
returns (stream ContainerExecResponse) {} returns (stream ContainerExecResponse) {}
rpc ContainerAttach(stream ContainerAttachRequest)
returns (stream ContainerAttachResponse) {}
} }
message ListContainersRequest { map<string, RepeatedString> filter = 1; } message ListContainersRequest { map<string, RepeatedString> filter = 1; }
@@ -84,7 +86,25 @@ message ContainerActionResponse {}
message ContainerExecRequest { message ContainerExecRequest {
string containerId = 1; string containerId = 1;
repeated string command = 2; repeated string command = 2;
oneof payload {
bytes stdin = 3; bytes stdin = 3;
ResizePayload resize = 4;
}
}
message ResizePayload {
uint32 width = 1;
uint32 height = 2;
} }
message ContainerExecResponse { bytes stdout = 1; } message ContainerExecResponse { bytes stdout = 1; }
message ContainerAttachRequest {
string containerId = 1;
oneof payload {
bytes stdin = 2;
ResizePayload resize = 3;
}
}
message ContainerAttachResponse { bytes stdout = 1; }