From 2717685dad023d261bd4caafecec89343b8261c8 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Wed, 18 Jan 2023 21:53:34 -0800 Subject: [PATCH 1/4] Refactor sandbox controller interface Update the sandbox controller interface to use local types rather than using the API types. Signed-off-by: Derek McGowan --- api/next.pb.txt | 8 +- api/runtime/sandbox/v1/sandbox.pb.go | 196 ++++++------- api/runtime/sandbox/v1/sandbox.proto | 2 +- api/services/sandbox/v1/sandbox.pb.go | 257 +++++++++--------- api/services/sandbox/v1/sandbox.proto | 2 +- pkg/cri/sbserver/container_create.go | 6 +- pkg/cri/sbserver/podsandbox/controller.go | 9 +- .../sbserver/podsandbox/controller_test.go | 3 +- pkg/cri/sbserver/podsandbox/sandbox_delete.go | 15 +- pkg/cri/sbserver/podsandbox/sandbox_run.go | 54 ++-- pkg/cri/sbserver/podsandbox/sandbox_status.go | 27 +- pkg/cri/sbserver/podsandbox/sandbox_stop.go | 11 +- pkg/cri/sbserver/sandbox_remove.go | 2 +- pkg/cri/sbserver/sandbox_run.go | 15 +- pkg/cri/sbserver/sandbox_status.go | 6 +- pkg/cri/sbserver/sandbox_stop.go | 2 +- sandbox.go | 14 +- sandbox/controller.go | 35 ++- sandbox/proxy/controller.go | 51 ++-- services.go | 8 +- services/sandbox/controller_local.go | 10 +- 21 files changed, 378 insertions(+), 355 deletions(-) diff --git a/api/next.pb.txt b/api/next.pb.txt index 534a6cbed..294e1d483 100644 --- a/api/next.pb.txt +++ b/api/next.pb.txt @@ -1039,11 +1039,11 @@ file { message_type { name: "SandboxStatusResponse" field { - name: "id" + name: "sandbox_id" number: 1 label: LABEL_OPTIONAL type: TYPE_STRING - json_name: "id" + json_name: "sandboxId" } field { name: "pid" @@ -5176,11 +5176,11 @@ file { message_type { name: "ControllerStatusResponse" field { - name: "id" + name: "sandbox_id" number: 1 label: LABEL_OPTIONAL type: TYPE_STRING - json_name: "id" + json_name: "sandboxId" } field { name: "pid" diff --git a/api/runtime/sandbox/v1/sandbox.pb.go b/api/runtime/sandbox/v1/sandbox.pb.go index 9487b568d..373ecd24b 100644 --- a/api/runtime/sandbox/v1/sandbox.pb.go +++ b/api/runtime/sandbox/v1/sandbox.pb.go @@ -699,7 +699,7 @@ type SandboxStatusResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SandboxID string `protobuf:"bytes,1,opt,name=sandbox_id,json=sandboxId,proto3" json:"sandbox_id,omitempty"` Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` Info map[string]string `protobuf:"bytes,4,rep,name=info,proto3" json:"info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -740,9 +740,9 @@ func (*SandboxStatusResponse) Descriptor() ([]byte, []int) { return file_github_com_containerd_containerd_api_runtime_sandbox_v1_sandbox_proto_rawDescGZIP(), []int{13} } -func (x *SandboxStatusResponse) GetID() string { +func (x *SandboxStatusResponse) GetSandboxID() string { if x != nil { - return x.ID + return x.SandboxID } return "" } @@ -1051,105 +1051,105 @@ var file_github_com_containerd_containerd_api_runtime_sandbox_v1_sandbox_proto_r 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x62, 0x6f, 0x73, 0x65, 0x22, 0xfc, 0x02, 0x0a, 0x15, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, - 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x52, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x62, 0x6f, 0x73, 0x65, 0x22, 0x8b, 0x03, 0x0a, 0x15, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x52, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 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, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x06, 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, 0x08, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2a, 0x0a, + 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, + 0x6f, 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, 0x22, 0x2c, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, + 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x37, 0x0a, 0x16, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x68, 0x75, + 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xbe, 0x07, 0x0a, 0x07, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x12, 0x7a, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x12, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x32, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x57, 0x61, 0x69, 0x74, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, + 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 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, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x06, 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, 0x08, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2a, - 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x41, 0x6e, 0x79, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, - 0x66, 0x6f, 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, 0x22, 0x2c, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, - 0x64, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x37, 0x0a, 0x16, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x68, - 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xbe, 0x07, 0x0a, 0x07, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x12, 0x7a, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x12, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, - 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x32, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x0b, 0x50, 0x69, + 0x6e, 0x67, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x57, 0x61, 0x69, - 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x69, 0x74, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x7a, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x0b, 0x50, - 0x69, 0x6e, 0x67, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2f, 0x76, - 0x31, 0x3b, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, + 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2f, 0x76, 0x31, + 0x3b, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/runtime/sandbox/v1/sandbox.proto b/api/runtime/sandbox/v1/sandbox.proto index 6abc93d0a..a33c9fc8f 100644 --- a/api/runtime/sandbox/v1/sandbox.proto +++ b/api/runtime/sandbox/v1/sandbox.proto @@ -113,7 +113,7 @@ message SandboxStatusRequest { } message SandboxStatusResponse { - string id = 1; + string sandbox_id = 1; uint32 pid = 2; string state = 3; map info = 4; diff --git a/api/services/sandbox/v1/sandbox.pb.go b/api/services/sandbox/v1/sandbox.pb.go index b8e1277e7..cf1179794 100644 --- a/api/services/sandbox/v1/sandbox.pb.go +++ b/api/services/sandbox/v1/sandbox.pb.go @@ -1092,7 +1092,7 @@ type ControllerStatusResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SandboxID string `protobuf:"bytes,1,opt,name=sandbox_id,json=sandboxId,proto3" json:"sandbox_id,omitempty"` Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` Info map[string]string `protobuf:"bytes,4,rep,name=info,proto3" json:"info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -1133,9 +1133,9 @@ func (*ControllerStatusResponse) Descriptor() ([]byte, []int) { return file_github_com_containerd_containerd_api_services_sandbox_v1_sandbox_proto_rawDescGZIP(), []int{21} } -func (x *ControllerStatusResponse) GetID() string { +func (x *ControllerStatusResponse) GetSandboxID() string { if x != nil { - return x.ID + return x.SandboxID } return "" } @@ -1398,133 +1398,134 @@ var file_github_com_containerd_containerd_api_services_sandbox_v1_sandbox_proto_ 0x0a, 0x0a, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, 0x83, 0x03, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x74, + 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x22, 0x92, 0x03, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x04, - 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, - 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x05, 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, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x37, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 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, 0x08, - 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, - 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x65, - 0x78, 0x74, 0x72, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, 0x6f, 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, 0x22, 0x3a, 0x0a, - 0x19, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x68, 0x75, 0x74, 0x64, - 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb7, 0x04, 0x0a, 0x05, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x12, 0x71, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x32, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, - 0x72, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x04, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x2f, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xf6, 0x06, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x12, 0x7b, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, - 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x3a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x04, 0x53, - 0x74, 0x6f, 0x70, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, - 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x75, 0x0a, 0x04, 0x57, 0x61, 0x69, 0x74, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x57, 0x61, 0x69, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x06, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, - 0x6f, 0x77, 0x6e, 0x12, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, - 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x04, 0x69, + 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, + 0x6e, 0x66, 0x6f, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x05, 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, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x37, + 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 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, 0x08, 0x65, + 0x78, 0x69, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x65, 0x78, + 0x74, 0x72, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x49, 0x6e, 0x66, 0x6f, 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, 0x22, 0x3a, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, - 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb7, 0x04, 0x0a, 0x05, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x12, 0x71, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x32, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x04, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x2f, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x32, 0xf6, 0x06, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, + 0x7b, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x12, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x04, 0x53, 0x74, + 0x6f, 0x70, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, + 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x75, 0x0a, 0x04, 0x57, 0x61, 0x69, 0x74, 0x12, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x57, 0x61, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, + 0x77, 0x6e, 0x12, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x68, + 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/services/sandbox/v1/sandbox.proto b/api/services/sandbox/v1/sandbox.proto index 3e8ca4a12..d234c72e4 100644 --- a/api/services/sandbox/v1/sandbox.proto +++ b/api/services/sandbox/v1/sandbox.proto @@ -146,7 +146,7 @@ message ControllerStatusRequest { } message ControllerStatusResponse { - string id = 1; + string sandbox_id = 1; uint32 pid = 2; string state = 3; map info = 4; diff --git a/pkg/cri/sbserver/container_create.go b/pkg/cri/sbserver/container_create.go index 1c7077f54..b1ca20f44 100644 --- a/pkg/cri/sbserver/container_create.go +++ b/pkg/cri/sbserver/container_create.go @@ -67,14 +67,14 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta return nil, fmt.Errorf("failed to get sandbox controller: %w", err) } - statusResponse, err := controller.Status(ctx, sandbox.ID, false) + cstatus, err := controller.Status(ctx, sandbox.ID, false) if err != nil { return nil, fmt.Errorf("failed to get controller status: %w", err) } var ( - sandboxID = statusResponse.GetID() - sandboxPid = statusResponse.GetPid() + sandboxID = cstatus.SandboxID + sandboxPid = cstatus.Pid ) // Generate unique id and name for the container and reserve the name. diff --git a/pkg/cri/sbserver/podsandbox/controller.go b/pkg/cri/sbserver/podsandbox/controller.go index 175780b97..ba7c39150 100644 --- a/pkg/cri/sbserver/podsandbox/controller.go +++ b/pkg/cri/sbserver/podsandbox/controller.go @@ -26,7 +26,6 @@ import ( "github.com/containerd/containerd" eventtypes "github.com/containerd/containerd/api/events" - api "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/oci" criconfig "github.com/containerd/containerd/pkg/cri/config" @@ -94,17 +93,17 @@ func (c *Controller) Platform(_ctx context.Context, _sandboxID string) (platform return platforms.DefaultSpec(), nil } -func (c *Controller) Wait(ctx context.Context, sandboxID string) (*api.ControllerWaitResponse, error) { +func (c *Controller) Wait(ctx context.Context, sandboxID string) (sandbox.ExitStatus, error) { status := c.store.Get(sandboxID) if status == nil { - return nil, fmt.Errorf("failed to get exit channel. %q", sandboxID) + return sandbox.ExitStatus{}, fmt.Errorf("failed to get exit channel. %q", sandboxID) } exitStatus, exitedAt, err := c.waitSandboxExit(ctx, sandboxID, status.Waiter) - return &api.ControllerWaitResponse{ + return sandbox.ExitStatus{ ExitStatus: exitStatus, - ExitedAt: protobuf.ToTimestamp(exitedAt), + ExitedAt: exitedAt, }, err } diff --git a/pkg/cri/sbserver/podsandbox/controller_test.go b/pkg/cri/sbserver/podsandbox/controller_test.go index 12a0aae7d..4a3decc2c 100644 --- a/pkg/cri/sbserver/podsandbox/controller_test.go +++ b/pkg/cri/sbserver/podsandbox/controller_test.go @@ -25,7 +25,6 @@ import ( "github.com/containerd/containerd/pkg/cri/store/label" sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" ostesting "github.com/containerd/containerd/pkg/os/testing" - "github.com/containerd/containerd/protobuf" "github.com/stretchr/testify/assert" ) @@ -83,6 +82,6 @@ func Test_Status(t *testing.T) { t.Fatal(err) } assert.Equal(t, s.Pid, pid) - assert.Equal(t, s.ExitedAt, protobuf.ToTimestamp(exitedAt)) + assert.Equal(t, s.ExitedAt, exitedAt) assert.Equal(t, s.State, sandboxstore.StateReady.String()) } diff --git a/pkg/cri/sbserver/podsandbox/sandbox_delete.go b/pkg/cri/sbserver/podsandbox/sandbox_delete.go index fc1a4102e..eda4ec178 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_delete.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_delete.go @@ -23,30 +23,29 @@ import ( runtime "k8s.io/cri-api/pkg/apis/runtime/v1" "github.com/containerd/containerd" - api "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" ) -func (c *Controller) Shutdown(ctx context.Context, sandboxID string) (*api.ControllerShutdownResponse, error) { +func (c *Controller) Shutdown(ctx context.Context, sandboxID string) error { sandbox, err := c.sandboxStore.Get(sandboxID) if err != nil { if !errdefs.IsNotFound(err) { - return nil, fmt.Errorf("an error occurred when try to find sandbox %q: %w", sandboxID, err) + return fmt.Errorf("an error occurred when try to find sandbox %q: %w", sandboxID, err) } // Do not return error if the id doesn't exist. log.G(ctx).Tracef("Sandbox controller Delete called for sandbox %q that does not exist", sandboxID) - return &api.ControllerShutdownResponse{}, nil + return nil } // Cleanup the sandbox root directories. sandboxRootDir := c.getSandboxRootDir(sandboxID) if err := ensureRemoveAll(ctx, sandboxRootDir); err != nil { - return nil, fmt.Errorf("failed to remove sandbox root directory %q: %w", sandboxRootDir, err) + return fmt.Errorf("failed to remove sandbox root directory %q: %w", sandboxRootDir, err) } volatileSandboxRootDir := c.getVolatileSandboxRootDir(sandboxID) if err := ensureRemoveAll(ctx, volatileSandboxRootDir); err != nil { - return nil, fmt.Errorf("failed to remove volatile sandbox root directory %q: %w", + return fmt.Errorf("failed to remove volatile sandbox root directory %q: %w", volatileSandboxRootDir, err) } @@ -54,7 +53,7 @@ func (c *Controller) Shutdown(ctx context.Context, sandboxID string) (*api.Contr if sandbox.Container != nil { if err := sandbox.Container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil { if !errdefs.IsNotFound(err) { - return nil, fmt.Errorf("failed to delete sandbox container %q: %w", sandboxID, err) + return fmt.Errorf("failed to delete sandbox container %q: %w", sandboxID, err) } log.G(ctx).Tracef("Sandbox controller Delete called for sandbox container %q that does not exist", sandboxID) } @@ -65,5 +64,5 @@ func (c *Controller) Shutdown(ctx context.Context, sandboxID string) (*api.Contr // Send CONTAINER_DELETED event with ContainerId equal to SandboxId. c.cri.GenerateAndSendContainerEvent(ctx, sandboxID, sandboxID, runtime.ContainerEventType_CONTAINER_DELETED_EVENT) - return &api.ControllerShutdownResponse{}, nil + return nil } diff --git a/pkg/cri/sbserver/podsandbox/sandbox_run.go b/pkg/cri/sbserver/podsandbox/sandbox_run.go index 055efd598..da6d2343a 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_run.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_run.go @@ -29,7 +29,6 @@ import ( runtime "k8s.io/cri-api/pkg/apis/runtime/v1" "github.com/containerd/containerd" - api "github.com/containerd/containerd/api/services/sandbox/v1" containerdio "github.com/containerd/containerd/cio" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" @@ -38,7 +37,7 @@ import ( customopts "github.com/containerd/containerd/pkg/cri/opts" sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" ctrdutil "github.com/containerd/containerd/pkg/cri/util" - "github.com/containerd/containerd/protobuf" + "github.com/containerd/containerd/sandbox" "github.com/containerd/containerd/snapshots" ) @@ -51,23 +50,22 @@ func init() { // down the created resources. If an error occurs while tearing down resources, a zero-valued response is returned // alongside the error. If the teardown was successful, a nil response is returned with the error. // TODO(samuelkarp) Determine whether this error indication is reasonable to retain once controller.Delete is implemented. -func (c *Controller) Start(ctx context.Context, id string) (resp *api.ControllerStartResponse, retErr error) { +func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.ControllerInstance, retErr error) { var cleanupErr error defer func() { if retErr != nil && cleanupErr != nil { log.G(ctx).WithField("id", id).WithError(cleanupErr).Errorf("failed to fully teardown sandbox resources after earlier error: %s", retErr) - resp = &api.ControllerStartResponse{} } }() sandboxInfo, err := c.client.SandboxStore().Get(ctx, id) if err != nil { - return nil, fmt.Errorf("unable to find sandbox with id %q: %w", id, err) + return cin, fmt.Errorf("unable to find sandbox with id %q: %w", id, err) } var metadata sandboxstore.Metadata if err := sandboxInfo.GetExtension(MetadataKey, &metadata); err != nil { - return nil, fmt.Errorf("failed to get sandbox %q metadata: %w", id, err) + return cin, fmt.Errorf("failed to get sandbox %q metadata: %w", id, err) } var ( @@ -78,17 +76,17 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // Ensure sandbox container image snapshot. image, err := c.cri.EnsureImageExists(ctx, c.config.SandboxImage, config) if err != nil { - return nil, fmt.Errorf("failed to get sandbox image %q: %w", c.config.SandboxImage, err) + return cin, fmt.Errorf("failed to get sandbox image %q: %w", c.config.SandboxImage, err) } containerdImage, err := c.toContainerdImage(ctx, *image) if err != nil { - return nil, fmt.Errorf("failed to get image from containerd %q: %w", image.ID, err) + return cin, fmt.Errorf("failed to get image from containerd %q: %w", image.ID, err) } ociRuntime, err := c.getSandboxRuntime(config, metadata.RuntimeHandler) if err != nil { - return nil, fmt.Errorf("failed to get sandbox runtime: %w", err) + return cin, fmt.Errorf("failed to get sandbox runtime: %w", err) } log.G(ctx).WithField("podsandboxid", id).Debugf("use OCI runtime %+v", ociRuntime) @@ -100,7 +98,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // it safely. spec, err := c.sandboxContainerSpec(id, config, &image.ImageSpec.Config, metadata.NetNSPath, ociRuntime.PodAnnotations) if err != nil { - return nil, fmt.Errorf("failed to generate sandbox container spec: %w", err) + return cin, fmt.Errorf("failed to generate sandbox container spec: %w", err) } log.G(ctx).WithField("podsandboxid", id).Debugf("sandbox container spec: %#+v", spew.NewFormatter(spec)) @@ -114,7 +112,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // handle any KVM based runtime if err := modifyProcessLabel(ociRuntime.Type, spec); err != nil { - return nil, err + return cin, err } if config.GetLinux().GetSecurityContext().GetPrivileged() { @@ -126,7 +124,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // Generate spec options that will be applied to the spec later. specOpts, err := c.sandboxContainerSpecOpts(config, &image.ImageSpec.Config) if err != nil { - return nil, fmt.Errorf("failed to generate sandbox container spec options: %w", err) + return cin, fmt.Errorf("failed to generate sandbox container spec options: %w", err) } sandboxLabels := buildLabels(config.Labels, image.ImageSpec.Config.Labels, containerKindSandbox) @@ -143,7 +141,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller container, err := c.client.NewContainer(ctx, id, opts...) if err != nil { - return nil, fmt.Errorf("failed to create containerd container: %w", err) + return cin, fmt.Errorf("failed to create containerd container: %w", err) } defer func() { if retErr != nil && cleanupErr == nil { @@ -163,7 +161,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // Create sandbox container root directories. sandboxRootDir := c.getSandboxRootDir(id) if err := c.os.MkdirAll(sandboxRootDir, 0755); err != nil { - return nil, fmt.Errorf("failed to create sandbox root directory %q: %w", + return cin, fmt.Errorf("failed to create sandbox root directory %q: %w", sandboxRootDir, err) } defer func() { @@ -178,7 +176,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller volatileSandboxRootDir := c.getVolatileSandboxRootDir(id) if err := c.os.MkdirAll(volatileSandboxRootDir, 0755); err != nil { - return nil, fmt.Errorf("failed to create volatile sandbox root directory %q: %w", + return cin, fmt.Errorf("failed to create volatile sandbox root directory %q: %w", volatileSandboxRootDir, err) } defer func() { @@ -193,7 +191,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // Setup files required for the sandbox. if err = c.setupSandboxFiles(id, config); err != nil { - return nil, fmt.Errorf("failed to setup sandbox files: %w", err) + return cin, fmt.Errorf("failed to setup sandbox files: %w", err) } defer func() { if retErr != nil && cleanupErr == nil { @@ -207,7 +205,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // Update sandbox created timestamp. info, err := container.Info(ctx) if err != nil { - return nil, fmt.Errorf("failed to get sandbox container info: %w", err) + return cin, fmt.Errorf("failed to get sandbox container info: %w", err) } // Create sandbox task in containerd. @@ -221,7 +219,7 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // We don't need stdio for sandbox container. task, err := container.NewTask(ctx, containerdio.NullIO, taskOpts...) if err != nil { - return nil, fmt.Errorf("failed to create containerd task: %w", err) + return cin, fmt.Errorf("failed to create containerd task: %w", err) } defer func() { if retErr != nil && cleanupErr == nil { @@ -238,13 +236,13 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller // wait is a long running background request, no timeout needed. exitCh, err := task.Wait(ctrdutil.NamespacedContext()) if err != nil { - return nil, fmt.Errorf("failed to wait for sandbox container task: %w", err) + return cin, fmt.Errorf("failed to wait for sandbox container task: %w", err) } c.store.Save(id, exitCh) nric, err := nri.New() if err != nil { - return nil, fmt.Errorf("unable to create nri client: %w", err) + return cin, fmt.Errorf("unable to create nri client: %w", err) } if nric != nil { nriSB := &nri.Sandbox{ @@ -252,25 +250,23 @@ func (c *Controller) Start(ctx context.Context, id string) (resp *api.Controller Labels: config.Labels, } if _, err := nric.InvokeWithSandbox(ctx, task, v1.Create, nriSB); err != nil { - return nil, fmt.Errorf("nri invoke: %w", err) + return cin, fmt.Errorf("nri invoke: %w", err) } } if err := task.Start(ctx); err != nil { - return nil, fmt.Errorf("failed to start sandbox container task %q: %w", id, err) + return cin, fmt.Errorf("failed to start sandbox container task %q: %w", id, err) } // Send CONTAINER_STARTED event with ContainerId equal to SandboxId. c.cri.GenerateAndSendContainerEvent(ctx, id, id, runtime.ContainerEventType_CONTAINER_STARTED_EVENT) - resp = &api.ControllerStartResponse{ - SandboxID: id, - Pid: task.Pid(), - CreatedAt: protobuf.ToTimestamp(info.CreatedAt), - Labels: labels, - } + cin.SandboxID = id + cin.Pid = task.Pid() + cin.CreatedAt = info.CreatedAt + cin.Labels = labels - return resp, nil + return } func (c *Controller) Create(ctx context.Context, _id string) error { diff --git a/pkg/cri/sbserver/podsandbox/sandbox_status.go b/pkg/cri/sbserver/podsandbox/sandbox_status.go index 1711d73e2..599f57e91 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_status.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_status.go @@ -22,11 +22,10 @@ import ( "fmt" "github.com/containerd/containerd" - api "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/errdefs" sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" - "github.com/containerd/containerd/protobuf" + "github.com/containerd/containerd/sandbox" "github.com/containerd/go-cni" "github.com/containerd/typeurl" runtimespec "github.com/opencontainers/runtime-spec/specs-go" @@ -55,36 +54,36 @@ type SandboxInfo struct { Metadata *sandboxstore.Metadata `json:"sandboxMetadata"` } -func (c *Controller) Status(ctx context.Context, sandboxID string, verbose bool) (*api.ControllerStatusResponse, error) { - sandbox, err := c.sandboxStore.Get(sandboxID) +func (c *Controller) Status(ctx context.Context, sandboxID string, verbose bool) (sandbox.ControllerStatus, error) { + sb, err := c.sandboxStore.Get(sandboxID) if err != nil { - return nil, fmt.Errorf("an error occurred while trying to find sandbox %q: %w", + return sandbox.ControllerStatus{}, fmt.Errorf("an error occurred while trying to find sandbox %q: %w", sandboxID, err) } - status := sandbox.Status.Get() - resp := &api.ControllerStatusResponse{ - ID: sandboxID, + status := sb.Status.Get() + cstatus := sandbox.ControllerStatus{ + SandboxID: sandboxID, Pid: status.Pid, State: status.State.String(), - CreatedAt: protobuf.ToTimestamp(status.CreatedAt), + CreatedAt: status.CreatedAt, Extra: nil, } if !status.ExitedAt.IsZero() { - resp.ExitedAt = protobuf.ToTimestamp(status.ExitedAt) + cstatus.ExitedAt = status.ExitedAt } if verbose { - info, err := toCRISandboxInfo(ctx, sandbox) + info, err := toCRISandboxInfo(ctx, sb) if err != nil { - return nil, err + return sandbox.ControllerStatus{}, err } - resp.Info = info + cstatus.Info = info } - return resp, nil + return cstatus, nil } // toCRISandboxInfo converts internal container object information to CRI sandbox status response info map. diff --git a/pkg/cri/sbserver/podsandbox/sandbox_stop.go b/pkg/cri/sbserver/podsandbox/sandbox_stop.go index c6ed33c40..0bc0cf6ba 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_stop.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_stop.go @@ -25,22 +25,21 @@ import ( "github.com/sirupsen/logrus" eventtypes "github.com/containerd/containerd/api/events" - api "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/errdefs" sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" ctrdutil "github.com/containerd/containerd/pkg/cri/util" "github.com/containerd/containerd/protobuf" ) -func (c *Controller) Stop(ctx context.Context, sandboxID string) (*api.ControllerStopResponse, error) { +func (c *Controller) Stop(ctx context.Context, sandboxID string) error { sandbox, err := c.sandboxStore.Get(sandboxID) if err != nil { - return nil, fmt.Errorf("an error occurred when try to find sandbox %q: %w", + return fmt.Errorf("an error occurred when try to find sandbox %q: %w", sandboxID, err) } if err := c.cleanupSandboxFiles(sandboxID, sandbox.Config); err != nil { - return nil, fmt.Errorf("failed to cleanup sandbox files: %w", err) + return fmt.Errorf("failed to cleanup sandbox files: %w", err) } // TODO: The Controller maintains its own Status instead of CRI's sandboxStore. @@ -48,10 +47,10 @@ func (c *Controller) Stop(ctx context.Context, sandboxID string) (*api.Controlle state := sandbox.Status.Get().State if (state == sandboxstore.StateReady || state == sandboxstore.StateUnknown) && sandbox.Container != nil { if err := c.stopSandboxContainer(ctx, sandbox); err != nil { - return nil, fmt.Errorf("failed to stop sandbox container %q in %q state: %w", sandboxID, state, err) + return fmt.Errorf("failed to stop sandbox container %q in %q state: %w", sandboxID, state, err) } } - return &api.ControllerStopResponse{}, nil + return nil } // stopSandboxContainer kills the sandbox container. diff --git a/pkg/cri/sbserver/sandbox_remove.go b/pkg/cri/sbserver/sandbox_remove.go index a64efb235..989e3f3ac 100644 --- a/pkg/cri/sbserver/sandbox_remove.go +++ b/pkg/cri/sbserver/sandbox_remove.go @@ -86,7 +86,7 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS return nil, fmt.Errorf("failed to get sandbox controller: %w", err) } - if _, err := controller.Shutdown(ctx, id); err != nil && !errdefs.IsNotFound(err) { + if err := controller.Shutdown(ctx, id); err != nil && !errdefs.IsNotFound(err) { return nil, fmt.Errorf("failed to delete sandbox %q: %w", id, err) } diff --git a/pkg/cri/sbserver/sandbox_run.go b/pkg/cri/sbserver/sandbox_run.go index 214a689ed..76a28ac9f 100644 --- a/pkg/cri/sbserver/sandbox_run.go +++ b/pkg/cri/sbserver/sandbox_run.go @@ -41,7 +41,6 @@ import ( "github.com/containerd/containerd/pkg/cri/util" ctrdutil "github.com/containerd/containerd/pkg/cri/util" "github.com/containerd/containerd/pkg/netns" - "github.com/containerd/containerd/protobuf" sb "github.com/containerd/containerd/sandbox" ) @@ -230,10 +229,10 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox return nil, fmt.Errorf("failed to create sandbox %q: %w", id, err) } - resp, err := controller.Start(ctx, id) + ctrl, err := controller.Start(ctx, id) if err != nil { sandbox.Container, _ = c.client.LoadContainer(ctx, id) - if resp != nil && resp.SandboxID == "" && resp.Pid == 0 && resp.CreatedAt == nil && len(resp.Labels) == 0 { + if ctrl.SandboxID == "" && ctrl.Pid == 0 && ctrl.CreatedAt.IsZero() && len(ctrl.Labels) == 0 { // if resp is a non-nil zero-value, an error occurred during cleanup cleanupErr = fmt.Errorf("failed to cleanup sandbox") } @@ -249,7 +248,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox sandbox.Container = container } - labels := resp.GetLabels() + labels := ctrl.Labels if labels == nil { labels = map[string]string{} } @@ -258,9 +257,9 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox if err := sandbox.Status.Update(func(status sandboxstore.Status) (sandboxstore.Status, error) { // Set the pod sandbox as ready after successfully start sandbox container. - status.Pid = resp.Pid + status.Pid = ctrl.Pid status.State = sandboxstore.StateReady - status.CreatedAt = protobuf.FromTimestamp(resp.CreatedAt) + status.CreatedAt = ctrl.CreatedAt return status, nil }); err != nil { return nil, fmt.Errorf("failed to update sandbox status: %w", err) @@ -284,7 +283,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox return } - exitCh <- *containerd.NewExitStatus(resp.ExitStatus, protobuf.FromTimestamp(resp.ExitedAt), nil) + exitCh <- *containerd.NewExitStatus(resp.ExitStatus, resp.ExitedAt, nil) }() // start the monitor after adding sandbox into the store, this ensures @@ -292,7 +291,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox // // TaskOOM from containerd may come before sandbox is added to store, // but we don't care about sandbox TaskOOM right now, so it is fine. - c.eventMonitor.startSandboxExitMonitor(context.Background(), id, resp.GetPid(), exitCh) + c.eventMonitor.startSandboxExitMonitor(context.Background(), id, ctrl.Pid, exitCh) sandboxRuntimeCreateTimer.WithValues(labels["oci_runtime_type"]).UpdateSince(runtimeStart) diff --git a/pkg/cri/sbserver/sandbox_status.go b/pkg/cri/sbserver/sandbox_status.go index ef85916d0..f4a02f2ab 100644 --- a/pkg/cri/sbserver/sandbox_status.go +++ b/pkg/cri/sbserver/sandbox_status.go @@ -42,12 +42,12 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox return nil, fmt.Errorf("failed to get sandbox controller: %w", err) } - statusResponse, err := controller.Status(ctx, sandbox.ID, r.GetVerbose()) + cstatus, err := controller.Status(ctx, sandbox.ID, r.GetVerbose()) if err != nil { return nil, fmt.Errorf("failed to query controller status: %w", err) } - status := toCRISandboxStatus(sandbox.Metadata, statusResponse.State, statusResponse.GetCreatedAt().AsTime(), ip, additionalIPs) + status := toCRISandboxStatus(sandbox.Metadata, cstatus.State, cstatus.CreatedAt, ip, additionalIPs) if status.GetCreatedAt() == 0 { // CRI doesn't allow CreatedAt == 0. sandboxInfo, err := c.client.SandboxStore().Get(ctx, sandbox.ID) @@ -59,7 +59,7 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox return &runtime.PodSandboxStatusResponse{ Status: status, - Info: statusResponse.GetInfo(), + Info: cstatus.Info, }, nil } diff --git a/pkg/cri/sbserver/sandbox_stop.go b/pkg/cri/sbserver/sandbox_stop.go index 267316f3c..1ca8470e5 100644 --- a/pkg/cri/sbserver/sandbox_stop.go +++ b/pkg/cri/sbserver/sandbox_stop.go @@ -73,7 +73,7 @@ func (c *criService) stopPodSandbox(ctx context.Context, sandbox sandboxstore.Sa return fmt.Errorf("failed to get sandbox controller: %w", err) } - if _, err := controller.Stop(ctx, id); err != nil { + if err := controller.Stop(ctx, id); err != nil { return fmt.Errorf("failed to stop sandbox %q: %w", id, err) } } diff --git a/sandbox.go b/sandbox.go index 9644dd783..5234c9ff6 100644 --- a/sandbox.go +++ b/sandbox.go @@ -24,7 +24,6 @@ import ( "github.com/containerd/containerd/containers" "github.com/containerd/containerd/oci" - "github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/protobuf/types" api "github.com/containerd/containerd/sandbox" "github.com/containerd/typeurl" @@ -96,7 +95,7 @@ func (s *sandboxClient) Wait(ctx context.Context) (<-chan ExitStatus, error) { go func() { defer close(c) - resp, err := s.client.SandboxController().Wait(ctx, s.ID()) + exitStatus, err := s.client.SandboxController().Wait(ctx, s.ID()) if err != nil { c <- ExitStatus{ code: UnknownExitStatus, @@ -106,8 +105,8 @@ func (s *sandboxClient) Wait(ctx context.Context) (<-chan ExitStatus, error) { } c <- ExitStatus{ - code: resp.ExitStatus, - exitedAt: protobuf.FromTimestamp(resp.ExitedAt), + code: exitStatus.ExitStatus, + exitedAt: exitStatus.ExitedAt, } }() @@ -115,14 +114,11 @@ func (s *sandboxClient) Wait(ctx context.Context) (<-chan ExitStatus, error) { } func (s *sandboxClient) Stop(ctx context.Context) error { - if _, err := s.client.SandboxController().Stop(ctx, s.ID()); err != nil { - return err - } - return nil + return s.client.SandboxController().Stop(ctx, s.ID()) } func (s *sandboxClient) Shutdown(ctx context.Context) error { - if _, err := s.client.SandboxController().Shutdown(ctx, s.ID()); err != nil { + if err := s.client.SandboxController().Shutdown(ctx, s.ID()); err != nil { return fmt.Errorf("failed to shutdown sandbox: %w", err) } diff --git a/sandbox/controller.go b/sandbox/controller.go index 559868dcd..11a4b7125 100644 --- a/sandbox/controller.go +++ b/sandbox/controller.go @@ -18,9 +18,10 @@ package sandbox import ( "context" + "time" - "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/platforms" + "github.com/containerd/typeurl" ) // Controller is an interface to manage sandboxes at runtime. @@ -30,17 +31,39 @@ type Controller interface { // Create is used to initialize sandbox environment. Create(ctx context.Context, sandboxID string) error // Start will start previously created sandbox. - Start(ctx context.Context, sandboxID string) (*sandbox.ControllerStartResponse, error) + Start(ctx context.Context, sandboxID string) (ControllerInstance, error) // Platform returns target sandbox OS that will be used by Controller. // containerd will rely on this to generate proper OCI spec. Platform(_ctx context.Context, _sandboxID string) (platforms.Platform, error) // Stop will stop sandbox instance - Stop(ctx context.Context, sandboxID string) (*sandbox.ControllerStopResponse, error) + Stop(ctx context.Context, sandboxID string) error // Wait blocks until sandbox process exits. - Wait(ctx context.Context, sandboxID string) (*sandbox.ControllerWaitResponse, error) + Wait(ctx context.Context, sandboxID string) (ExitStatus, error) // Status will query sandbox process status. It is heavier than Ping call and must be used whenever you need to // gather metadata about current sandbox state (status, uptime, resource use, etc). - Status(ctx context.Context, sandboxID string, verbose bool) (*sandbox.ControllerStatusResponse, error) + Status(ctx context.Context, sandboxID string, verbose bool) (ControllerStatus, error) // Shutdown deletes and cleans all tasks and sandbox instance. - Shutdown(ctx context.Context, sandboxID string) (*sandbox.ControllerShutdownResponse, error) + Shutdown(ctx context.Context, sandboxID string) error +} + +type ControllerInstance struct { + SandboxID string + Pid uint32 + CreatedAt time.Time + Labels map[string]string +} + +type ExitStatus struct { + ExitStatus uint32 + ExitedAt time.Time +} + +type ControllerStatus struct { + SandboxID string + Pid uint32 + State string + Info map[string]string + CreatedAt time.Time + ExitedAt time.Time + Extra typeurl.Any } diff --git a/sandbox/proxy/controller.go b/sandbox/proxy/controller.go index 2bd8c03fc..4a6c81dd5 100644 --- a/sandbox/proxy/controller.go +++ b/sandbox/proxy/controller.go @@ -46,13 +46,18 @@ func (s *remoteSandboxController) Create(ctx context.Context, sandboxID string) return nil } -func (s *remoteSandboxController) Start(ctx context.Context, sandboxID string) (*api.ControllerStartResponse, error) { +func (s *remoteSandboxController) Start(ctx context.Context, sandboxID string) (sb.ControllerInstance, error) { resp, err := s.client.Start(ctx, &api.ControllerStartRequest{SandboxID: sandboxID}) if err != nil { - return nil, errdefs.FromGRPC(err) + return sb.ControllerInstance{}, errdefs.FromGRPC(err) } - return resp, nil + return sb.ControllerInstance{ + SandboxID: sandboxID, + Pid: resp.GetPid(), + CreatedAt: resp.GetCreatedAt().AsTime(), + Labels: resp.GetLabels(), + }, nil } func (s *remoteSandboxController) Platform(ctx context.Context, sandboxID string) (platforms.Platform, error) { @@ -69,38 +74,48 @@ func (s *remoteSandboxController) Platform(ctx context.Context, sandboxID string }, nil } -func (s *remoteSandboxController) Stop(ctx context.Context, sandboxID string) (*api.ControllerStopResponse, error) { - resp, err := s.client.Stop(ctx, &api.ControllerStopRequest{SandboxID: sandboxID}) +func (s *remoteSandboxController) Stop(ctx context.Context, sandboxID string) error { + _, err := s.client.Stop(ctx, &api.ControllerStopRequest{SandboxID: sandboxID}) if err != nil { - return nil, errdefs.FromGRPC(err) + return errdefs.FromGRPC(err) } - return resp, nil + return nil } -func (s *remoteSandboxController) Shutdown(ctx context.Context, sandboxID string) (*api.ControllerShutdownResponse, error) { - resp, err := s.client.Shutdown(ctx, &api.ControllerShutdownRequest{SandboxID: sandboxID}) +func (s *remoteSandboxController) Shutdown(ctx context.Context, sandboxID string) error { + _, err := s.client.Shutdown(ctx, &api.ControllerShutdownRequest{SandboxID: sandboxID}) if err != nil { - return nil, errdefs.FromGRPC(err) + return errdefs.FromGRPC(err) } - return resp, nil + return nil } -func (s *remoteSandboxController) Wait(ctx context.Context, sandboxID string) (*api.ControllerWaitResponse, error) { +func (s *remoteSandboxController) Wait(ctx context.Context, sandboxID string) (sb.ExitStatus, error) { resp, err := s.client.Wait(ctx, &api.ControllerWaitRequest{SandboxID: sandboxID}) if err != nil { - return nil, errdefs.FromGRPC(err) + return sb.ExitStatus{}, errdefs.FromGRPC(err) } - return resp, nil + return sb.ExitStatus{ + ExitStatus: resp.GetExitStatus(), + ExitedAt: resp.GetExitedAt().AsTime(), + }, nil } -func (s *remoteSandboxController) Status(ctx context.Context, sandboxID string, verbose bool) (*api.ControllerStatusResponse, error) { +func (s *remoteSandboxController) Status(ctx context.Context, sandboxID string, verbose bool) (sb.ControllerStatus, error) { resp, err := s.client.Status(ctx, &api.ControllerStatusRequest{SandboxID: sandboxID, Verbose: verbose}) if err != nil { - return nil, errdefs.FromGRPC(err) + return sb.ControllerStatus{}, errdefs.FromGRPC(err) } - - return resp, nil + return sb.ControllerStatus{ + SandboxID: sandboxID, + Pid: resp.GetPid(), + State: resp.GetState(), + Info: resp.GetInfo(), + CreatedAt: resp.GetCreatedAt().AsTime(), + ExitedAt: resp.GetExitedAt().AsTime(), + Extra: resp.GetExtra(), + }, nil } diff --git a/services.go b/services.go index 1c8efec15..47e2ffcc2 100644 --- a/services.go +++ b/services.go @@ -24,7 +24,6 @@ import ( imagesapi "github.com/containerd/containerd/api/services/images/v1" introspectionapi "github.com/containerd/containerd/api/services/introspection/v1" namespacesapi "github.com/containerd/containerd/api/services/namespaces/v1" - sandboxapi "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" @@ -33,7 +32,6 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/sandbox" - "github.com/containerd/containerd/sandbox/proxy" srv "github.com/containerd/containerd/services" "github.com/containerd/containerd/services/introspection" "github.com/containerd/containerd/snapshots" @@ -173,9 +171,9 @@ func WithSandboxStore(client sandbox.Store) ServicesOpt { } // WithSandboxController sets the sandbox controller. -func WithSandboxController(client sandboxapi.ControllerClient) ServicesOpt { +func WithSandboxController(client sandbox.Controller) ServicesOpt { return func(s *services) { - s.sandboxController = proxy.NewSandboxController(client) + s.sandboxController = client } } @@ -232,7 +230,7 @@ func WithInMemoryServices(ic *plugin.InitContext) ClientOpt { return WithIntrospectionClient(s.(introspectionapi.IntrospectionClient)) }, srv.SandboxControllerService: func(s interface{}) ServicesOpt { - return WithSandboxController(s.(sandboxapi.ControllerClient)) + return WithSandboxController(s.(sandbox.Controller)) }, } { p := plugins[s] diff --git a/services/sandbox/controller_local.go b/services/sandbox/controller_local.go index 74dc6ddb1..688720a54 100644 --- a/services/sandbox/controller_local.go +++ b/services/sandbox/controller_local.go @@ -217,11 +217,11 @@ func (c *controllerLocal) Status(ctx context.Context, in *api.ControllerStatusRe } return &api.ControllerStatusResponse{ - ID: resp.ID, - Pid: resp.Pid, - State: resp.State, - ExitedAt: resp.ExitedAt, - Extra: resp.Extra, + SandboxID: resp.SandboxID, + Pid: resp.Pid, + State: resp.State, + ExitedAt: resp.ExitedAt, + Extra: resp.Extra, }, nil } From a788f6c799bfd7073b482a3d7d2ac78fd559ca34 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Thu, 19 Jan 2023 00:05:47 -0800 Subject: [PATCH 2/4] Move local sandbox controller under plugins package Add options to sandbox controller interface. Update sandbox controller interface to fully utilize sandbox controller interface. Move grpc error conversion to service. Signed-off-by: Derek McGowan --- pkg/cri/sbserver/podsandbox/sandbox_run.go | 2 +- pkg/cri/sbserver/podsandbox/sandbox_stop.go | 3 +- plugin/plugin.go | 2 + plugins/sandbox/controller.go | 263 ++++++++++++++++++++ sandbox/controller.go | 40 ++- sandbox/proxy/controller.go | 29 ++- services/sandbox/controller_local.go | 236 ------------------ services/sandbox/controller_service.go | 74 ++++-- services/services.go | 4 +- 9 files changed, 384 insertions(+), 269 deletions(-) create mode 100644 plugins/sandbox/controller.go delete mode 100644 services/sandbox/controller_local.go diff --git a/pkg/cri/sbserver/podsandbox/sandbox_run.go b/pkg/cri/sbserver/podsandbox/sandbox_run.go index da6d2343a..7d4228d67 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_run.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_run.go @@ -269,7 +269,7 @@ func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.Controll return } -func (c *Controller) Create(ctx context.Context, _id string) error { +func (c *Controller) Create(ctx context.Context, _id string, _ ...sandbox.CreateOpt) error { // Not used by pod-sandbox implementation as there is no need to split pause containers logic. return nil } diff --git a/pkg/cri/sbserver/podsandbox/sandbox_stop.go b/pkg/cri/sbserver/podsandbox/sandbox_stop.go index 0bc0cf6ba..7aab32b32 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_stop.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_stop.go @@ -29,9 +29,10 @@ import ( sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" ctrdutil "github.com/containerd/containerd/pkg/cri/util" "github.com/containerd/containerd/protobuf" + "github.com/containerd/containerd/sandbox" ) -func (c *Controller) Stop(ctx context.Context, sandboxID string) error { +func (c *Controller) Stop(ctx context.Context, sandboxID string, _ ...sandbox.StopOpt) error { sandbox, err := c.sandboxStore.Get(sandboxID) if err != nil { return fmt.Errorf("an error occurred when try to find sandbox %q: %w", diff --git a/plugin/plugin.go b/plugin/plugin.go index 0bc59d76f..082f3178b 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -88,6 +88,8 @@ const ( TransferPlugin Type = "io.containerd.transfer.v1" // SandboxStorePlugin implements a sandbox store SandboxStorePlugin Type = "io.containerd.sandbox.store.v1" + // SandboxControllerPlugin implements a sandbox controller + SandboxControllerPlugin Type = "io.containerd.sandbox.controller.v1" ) const ( diff --git a/plugins/sandbox/controller.go b/plugins/sandbox/controller.go new file mode 100644 index 000000000..d2483fcaa --- /dev/null +++ b/plugins/sandbox/controller.go @@ -0,0 +1,263 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package sandbox + +import ( + "context" + "fmt" + + runtimeAPI "github.com/containerd/containerd/api/runtime/sandbox/v1" + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/events" + "github.com/containerd/containerd/events/exchange" + "github.com/containerd/containerd/platforms" + "github.com/containerd/containerd/plugin" + "github.com/containerd/containerd/runtime" + v2 "github.com/containerd/containerd/runtime/v2" + "github.com/containerd/containerd/sandbox" + + "google.golang.org/protobuf/types/known/anypb" +) + +func init() { + plugin.Register(&plugin.Registration{ + Type: plugin.SandboxControllerPlugin, + ID: "local", + Requires: []plugin.Type{ + plugin.RuntimePluginV2, + plugin.EventPlugin, + plugin.SandboxStorePlugin, + }, + InitFn: func(ic *plugin.InitContext) (interface{}, error) { + shimPlugin, err := ic.GetByID(plugin.RuntimePluginV2, "shim") + if err != nil { + return nil, err + } + + exchangePlugin, err := ic.GetByID(plugin.EventPlugin, "exchange") + if err != nil { + return nil, err + } + + sbPlugin, err := ic.GetByID(plugin.SandboxStorePlugin, "local") + if err != nil { + return nil, err + } + + var ( + shims = shimPlugin.(*v2.ShimManager) + publisher = exchangePlugin.(*exchange.Exchange) + store = sbPlugin.(sandbox.Store) + ) + + return &controllerLocal{ + shims: shims, + store: store, + publisher: publisher, + }, nil + }, + }) +} + +type controllerLocal struct { + shims *v2.ShimManager + store sandbox.Store + publisher events.Publisher +} + +var _ sandbox.Controller = (*controllerLocal)(nil) + +func (c *controllerLocal) Create(ctx context.Context, sandboxID string, opts ...sandbox.CreateOpt) error { + var coptions sandbox.CreateOptions + for _, opt := range opts { + opt(&coptions) + } + + if _, err := c.shims.Get(ctx, sandboxID); err == nil { + return fmt.Errorf("sandbox %s already running: %w", sandboxID, errdefs.ErrAlreadyExists) + } + + info, err := c.store.Get(ctx, sandboxID) + if err != nil { + return fmt.Errorf("failed to query sandbox metadata from store: %w", err) + } + + shim, err := c.shims.Start(ctx, sandboxID, runtime.CreateOpts{ + Spec: info.Spec, + RuntimeOptions: info.Runtime.Options, + Runtime: info.Runtime.Name, + TaskOptions: nil, + }) + + if err != nil { + return fmt.Errorf("failed to start new sandbox: %w", err) + } + + svc := runtimeAPI.NewTTRPCSandboxClient(shim.Client()) + + var options *anypb.Any + if coptions.Options != nil { + options = &anypb.Any{ + TypeUrl: coptions.Options.GetTypeUrl(), + Value: coptions.Options.GetValue(), + } + } + + if _, err := svc.CreateSandbox(ctx, &runtimeAPI.CreateSandboxRequest{ + SandboxID: sandboxID, + BundlePath: shim.Bundle(), + Rootfs: coptions.Rootfs, + Options: options, + }); err != nil { + // TODO: Delete sandbox shim here. + return fmt.Errorf("failed to start sandbox %s: %w", sandboxID, errdefs.FromGRPC(err)) + } + + return nil +} + +func (c *controllerLocal) Start(ctx context.Context, sandboxID string) (sandbox.ControllerInstance, error) { + shim, err := c.shims.Get(ctx, sandboxID) + if err != nil { + return sandbox.ControllerInstance{}, fmt.Errorf("unable to find sandbox %q", sandboxID) + } + + svc := runtimeAPI.NewTTRPCSandboxClient(shim.Client()) + resp, err := svc.StartSandbox(ctx, &runtimeAPI.StartSandboxRequest{SandboxID: sandboxID}) + if err != nil { + return sandbox.ControllerInstance{}, fmt.Errorf("failed to start sandbox %s: %w", sandboxID, errdefs.FromGRPC(err)) + } + + return sandbox.ControllerInstance{ + SandboxID: sandboxID, + Pid: resp.GetPid(), + CreatedAt: resp.GetCreatedAt().AsTime(), + }, nil +} + +func (c *controllerLocal) Platform(ctx context.Context, sandboxID string) (platforms.Platform, error) { + svc, err := c.getSandbox(ctx, sandboxID) + if err != nil { + return platforms.Platform{}, err + } + + response, err := svc.Platform(ctx, &runtimeAPI.PlatformRequest{SandboxID: sandboxID}) + if err != nil { + return platforms.Platform{}, fmt.Errorf("failed to get sandbox platform: %w", errdefs.FromGRPC(err)) + } + + var platform platforms.Platform + if p := response.GetPlatform(); p != nil { + platform.OS = p.OS + platform.Architecture = p.Architecture + platform.Variant = p.Variant + } + return platform, nil +} + +func (c *controllerLocal) Stop(ctx context.Context, sandboxID string, opts ...sandbox.StopOpt) error { + var soptions sandbox.StopOptions + for _, opt := range opts { + opt(&soptions) + } + req := &runtimeAPI.StopSandboxRequest{SandboxID: sandboxID} + if soptions.Timeout != nil { + req.TimeoutSecs = uint32(soptions.Timeout.Seconds()) + } + + svc, err := c.getSandbox(ctx, sandboxID) + if err != nil { + return err + } + + if _, err := svc.StopSandbox(ctx, req); err != nil { + return fmt.Errorf("failed to stop sandbox: %w", errdefs.FromGRPC(err)) + } + + return nil +} + +func (c *controllerLocal) Shutdown(ctx context.Context, sandboxID string) error { + svc, err := c.getSandbox(ctx, sandboxID) + if err != nil { + return err + } + + _, err = svc.ShutdownSandbox(ctx, &runtimeAPI.ShutdownSandboxRequest{SandboxID: sandboxID}) + if err != nil { + return fmt.Errorf("failed to shutdown sandbox: %w", errdefs.FromGRPC(err)) + } + + if err := c.shims.Delete(ctx, sandboxID); err != nil { + return fmt.Errorf("failed to delete sandbox shim: %w", err) + } + + return nil +} + +func (c *controllerLocal) Wait(ctx context.Context, sandboxID string) (sandbox.ExitStatus, error) { + svc, err := c.getSandbox(ctx, sandboxID) + if err != nil { + return sandbox.ExitStatus{}, err + } + + resp, err := svc.WaitSandbox(ctx, &runtimeAPI.WaitSandboxRequest{ + SandboxID: sandboxID, + }) + + if err != nil { + return sandbox.ExitStatus{}, fmt.Errorf("failed to wait sandbox %s: %w", sandboxID, errdefs.FromGRPC(err)) + } + + return sandbox.ExitStatus{ + ExitStatus: resp.GetExitStatus(), + ExitedAt: resp.GetExitedAt().AsTime(), + }, nil +} + +func (c *controllerLocal) Status(ctx context.Context, sandboxID string, verbose bool) (sandbox.ControllerStatus, error) { + svc, err := c.getSandbox(ctx, sandboxID) + if err != nil { + return sandbox.ControllerStatus{}, err + } + + resp, err := svc.SandboxStatus(ctx, &runtimeAPI.SandboxStatusRequest{ + SandboxID: sandboxID, + Verbose: verbose, + }) + if err != nil { + return sandbox.ControllerStatus{}, fmt.Errorf("failed to query sandbox %s status: %w", sandboxID, err) + } + + return sandbox.ControllerStatus{ + SandboxID: resp.GetSandboxID(), + Pid: resp.GetPid(), + State: resp.GetState(), + ExitedAt: resp.GetCreatedAt().AsTime(), + Extra: resp.GetExtra(), + }, nil +} + +func (c *controllerLocal) getSandbox(ctx context.Context, id string) (runtimeAPI.TTRPCSandboxService, error) { + shim, err := c.shims.Get(ctx, id) + if err != nil { + return nil, errdefs.ErrNotFound + } + + svc := runtimeAPI.NewTTRPCSandboxClient(shim.Client()) + return svc, nil +} diff --git a/sandbox/controller.go b/sandbox/controller.go index 11a4b7125..8d49937b8 100644 --- a/sandbox/controller.go +++ b/sandbox/controller.go @@ -20,23 +20,57 @@ import ( "context" "time" + "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/platforms" "github.com/containerd/typeurl" ) +type CreateOptions struct { + Rootfs []*types.Mount + Options typeurl.Any +} + +type CreateOpt func(*CreateOptions) + +// WithRootFS is used to create a sandbox with the provided rootfs mount +// TODO: Switch to mount.Mount once target added +func WithRootFS(m []*types.Mount) CreateOpt { + return func(co *CreateOptions) { + co.Rootfs = m + } +} + +func WithOptions(a typeurl.Any) CreateOpt { + return func(co *CreateOptions) { + co.Options = a + } +} + +type StopOptions struct { + Timeout *time.Duration +} + +type StopOpt func(*StopOptions) + +func WithTimeout(timeout time.Duration) StopOpt { + return func(so *StopOptions) { + so.Timeout = &timeout + } +} + // Controller is an interface to manage sandboxes at runtime. // When running in sandbox mode, shim expected to implement `SandboxService`. // Shim lifetimes are now managed manually via sandbox API by the containerd's client. type Controller interface { - // Create is used to initialize sandbox environment. - Create(ctx context.Context, sandboxID string) error + // Create is used to initialize sandbox environment. (mounts, any) + Create(ctx context.Context, sandboxID string, opts ...CreateOpt) error // Start will start previously created sandbox. Start(ctx context.Context, sandboxID string) (ControllerInstance, error) // Platform returns target sandbox OS that will be used by Controller. // containerd will rely on this to generate proper OCI spec. Platform(_ctx context.Context, _sandboxID string) (platforms.Platform, error) // Stop will stop sandbox instance - Stop(ctx context.Context, sandboxID string) error + Stop(ctx context.Context, sandboxID string, opts ...StopOpt) error // Wait blocks until sandbox process exits. Wait(ctx context.Context, sandboxID string) (ExitStatus, error) // Status will query sandbox process status. It is heavier than Ping call and must be used whenever you need to diff --git a/sandbox/proxy/controller.go b/sandbox/proxy/controller.go index 4a6c81dd5..cdae4c5d4 100644 --- a/sandbox/proxy/controller.go +++ b/sandbox/proxy/controller.go @@ -22,7 +22,9 @@ import ( api "github.com/containerd/containerd/api/services/sandbox/v1" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/platforms" + "github.com/containerd/containerd/sandbox" sb "github.com/containerd/containerd/sandbox" + "google.golang.org/protobuf/types/known/anypb" ) // remoteSandboxController is a low level GRPC client for containerd's sandbox controller service @@ -37,8 +39,19 @@ func NewSandboxController(client api.ControllerClient) sb.Controller { return &remoteSandboxController{client: client} } -func (s *remoteSandboxController) Create(ctx context.Context, sandboxID string) error { - _, err := s.client.Create(ctx, &api.ControllerCreateRequest{SandboxID: sandboxID}) +func (s *remoteSandboxController) Create(ctx context.Context, sandboxID string, opts ...sandbox.CreateOpt) error { + var options sandbox.CreateOptions + for _, opt := range opts { + opt(&options) + } + _, err := s.client.Create(ctx, &api.ControllerCreateRequest{ + SandboxID: sandboxID, + Rootfs: options.Rootfs, + Options: &anypb.Any{ + TypeUrl: options.Options.GetTypeUrl(), + Value: options.Options.GetValue(), + }, + }) if err != nil { return errdefs.FromGRPC(err) } @@ -74,8 +87,16 @@ func (s *remoteSandboxController) Platform(ctx context.Context, sandboxID string }, nil } -func (s *remoteSandboxController) Stop(ctx context.Context, sandboxID string) error { - _, err := s.client.Stop(ctx, &api.ControllerStopRequest{SandboxID: sandboxID}) +func (s *remoteSandboxController) Stop(ctx context.Context, sandboxID string, opts ...sandbox.StopOpt) error { + var soptions sandbox.StopOptions + for _, opt := range opts { + opt(&soptions) + } + req := &api.ControllerStopRequest{SandboxID: sandboxID} + if soptions.Timeout != nil { + req.TimeoutSecs = uint32(soptions.Timeout.Seconds()) + } + _, err := s.client.Stop(ctx, req) if err != nil { return errdefs.FromGRPC(err) } diff --git a/services/sandbox/controller_local.go b/services/sandbox/controller_local.go deleted file mode 100644 index 688720a54..000000000 --- a/services/sandbox/controller_local.go +++ /dev/null @@ -1,236 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package sandbox - -import ( - "context" - "fmt" - - runtimeAPI "github.com/containerd/containerd/api/runtime/sandbox/v1" - api "github.com/containerd/containerd/api/services/sandbox/v1" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/events/exchange" - "github.com/containerd/containerd/plugin" - "github.com/containerd/containerd/runtime" - v2 "github.com/containerd/containerd/runtime/v2" - "github.com/containerd/containerd/sandbox" - "github.com/containerd/containerd/services" - "google.golang.org/grpc" -) - -func init() { - plugin.Register(&plugin.Registration{ - Type: plugin.ServicePlugin, - ID: services.SandboxControllerService, - Requires: []plugin.Type{ - plugin.RuntimePluginV2, - plugin.EventPlugin, - plugin.SandboxStorePlugin, - }, - InitFn: func(ic *plugin.InitContext) (interface{}, error) { - shimPlugin, err := ic.GetByID(plugin.RuntimePluginV2, "shim") - if err != nil { - return nil, err - } - - exchangePlugin, err := ic.GetByID(plugin.EventPlugin, "exchange") - if err != nil { - return nil, err - } - - storePlugin, err := ic.GetByID(plugin.SandboxStorePlugin, "local") - if err != nil { - return nil, err - } - var ( - shims = shimPlugin.(*v2.ShimManager) - publisher = exchangePlugin.(*exchange.Exchange) - store = storePlugin.(sandbox.Store) - ) - - return &controllerLocal{ - shims: shims, - store: store, - publisher: publisher, - }, nil - }, - }) -} - -type controllerLocal struct { - shims *v2.ShimManager - store sandbox.Store - publisher events.Publisher -} - -var _ api.ControllerClient = (*controllerLocal)(nil) - -func (c *controllerLocal) Create(ctx context.Context, in *api.ControllerCreateRequest, opts ...grpc.CallOption) (*api.ControllerCreateResponse, error) { - if _, err := c.shims.Get(ctx, in.SandboxID); err == nil { - return nil, fmt.Errorf("sandbox %s already running: %w", in.SandboxID, errdefs.ErrAlreadyExists) - } - - info, err := c.store.Get(ctx, in.SandboxID) - if err != nil { - return nil, fmt.Errorf("failed to query sandbox metadata from store: %w", err) - } - - shim, err := c.shims.Start(ctx, in.SandboxID, runtime.CreateOpts{ - Spec: info.Spec, - RuntimeOptions: info.Runtime.Options, - Runtime: info.Runtime.Name, - TaskOptions: nil, - }) - - if err != nil { - return nil, fmt.Errorf("failed to start new sandbox: %w", err) - } - - svc := runtimeAPI.NewTTRPCSandboxClient(shim.Client()) - - if _, err := svc.CreateSandbox(ctx, &runtimeAPI.CreateSandboxRequest{ - SandboxID: in.SandboxID, - BundlePath: shim.Bundle(), - Rootfs: in.Rootfs, - Options: in.Options, - }); err != nil { - // TODO: Delete sandbox shim here. - return nil, fmt.Errorf("failed to start sandbox %s: %w", in.SandboxID, err) - } - - return &api.ControllerCreateResponse{SandboxID: in.SandboxID}, nil -} - -func (c *controllerLocal) Start(ctx context.Context, in *api.ControllerStartRequest, opts ...grpc.CallOption) (*api.ControllerStartResponse, error) { - shim, err := c.shims.Get(ctx, in.GetSandboxID()) - if err != nil { - return nil, fmt.Errorf("unable to find sandbox %q", in.GetSandboxID()) - } - - svc := runtimeAPI.NewTTRPCSandboxClient(shim.Client()) - resp, err := svc.StartSandbox(ctx, &runtimeAPI.StartSandboxRequest{SandboxID: in.SandboxID}) - if err != nil { - return nil, fmt.Errorf("failed to start sandbox %s: %w", in.SandboxID, err) - } - - return &api.ControllerStartResponse{ - SandboxID: in.SandboxID, - Pid: resp.Pid, - CreatedAt: resp.CreatedAt, - }, nil -} - -func (c *controllerLocal) Platform(ctx context.Context, in *api.ControllerPlatformRequest, opts ...grpc.CallOption) (*api.ControllerPlatformResponse, error) { - svc, err := c.getSandbox(ctx, in.SandboxID) - if err != nil { - return nil, err - } - - response, err := svc.Platform(ctx, &runtimeAPI.PlatformRequest{SandboxID: in.GetSandboxID()}) - if err != nil { - return nil, fmt.Errorf("failed to get sandbox platform: %w", err) - } - - return &api.ControllerPlatformResponse{ - Platform: response.GetPlatform(), - }, nil -} - -func (c *controllerLocal) Stop(ctx context.Context, in *api.ControllerStopRequest, opts ...grpc.CallOption) (*api.ControllerStopResponse, error) { - svc, err := c.getSandbox(ctx, in.SandboxID) - if err != nil { - return nil, err - } - - if _, err := svc.StopSandbox(ctx, &runtimeAPI.StopSandboxRequest{ - SandboxID: in.SandboxID, - TimeoutSecs: in.TimeoutSecs, - }); err != nil { - return nil, fmt.Errorf("failed to stop sandbox: %w", err) - } - - return &api.ControllerStopResponse{}, nil -} - -func (c *controllerLocal) Shutdown(ctx context.Context, in *api.ControllerShutdownRequest, opts ...grpc.CallOption) (*api.ControllerShutdownResponse, error) { - svc, err := c.getSandbox(ctx, in.SandboxID) - if err != nil { - return nil, err - } - - _, err = svc.ShutdownSandbox(ctx, &runtimeAPI.ShutdownSandboxRequest{SandboxID: in.SandboxID}) - if err != nil { - return nil, errdefs.ToGRPC(fmt.Errorf("failed to shutdown sandbox: %w", err)) - } - - if err := c.shims.Delete(ctx, in.SandboxID); err != nil { - return nil, errdefs.ToGRPC(fmt.Errorf("failed to delete sandbox shim: %w", err)) - } - - return &api.ControllerShutdownResponse{}, nil -} - -func (c *controllerLocal) Wait(ctx context.Context, in *api.ControllerWaitRequest, opts ...grpc.CallOption) (*api.ControllerWaitResponse, error) { - svc, err := c.getSandbox(ctx, in.SandboxID) - if err != nil { - return nil, err - } - - resp, err := svc.WaitSandbox(ctx, &runtimeAPI.WaitSandboxRequest{ - SandboxID: in.SandboxID, - }) - - if err != nil { - return nil, fmt.Errorf("failed to wait sandbox %s: %w", in.SandboxID, err) - } - - return &api.ControllerWaitResponse{ - ExitStatus: resp.ExitStatus, - ExitedAt: resp.ExitedAt, - }, nil -} - -func (c *controllerLocal) Status(ctx context.Context, in *api.ControllerStatusRequest, opts ...grpc.CallOption) (*api.ControllerStatusResponse, error) { - svc, err := c.getSandbox(ctx, in.SandboxID) - if err != nil { - return nil, errdefs.ToGRPC(err) - } - - resp, err := svc.SandboxStatus(ctx, &runtimeAPI.SandboxStatusRequest{SandboxID: in.SandboxID}) - if err != nil { - return nil, fmt.Errorf("failed to query sandbox %s status: %w", in.SandboxID, err) - } - - return &api.ControllerStatusResponse{ - SandboxID: resp.SandboxID, - Pid: resp.Pid, - State: resp.State, - ExitedAt: resp.ExitedAt, - Extra: resp.Extra, - }, nil -} - -func (c *controllerLocal) getSandbox(ctx context.Context, id string) (runtimeAPI.TTRPCSandboxService, error) { - shim, err := c.shims.Get(ctx, id) - if err != nil { - return nil, errdefs.ErrNotFound - } - - svc := runtimeAPI.NewTTRPCSandboxClient(shim.Client()) - return svc, nil -} diff --git a/services/sandbox/controller_service.go b/services/sandbox/controller_service.go index 339082eaf..10a39fd2a 100644 --- a/services/sandbox/controller_service.go +++ b/services/sandbox/controller_service.go @@ -18,13 +18,15 @@ package sandbox import ( "context" - "errors" api "github.com/containerd/containerd/api/services/sandbox/v1" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/plugin" - "github.com/containerd/containerd/services" + "github.com/containerd/containerd/protobuf" + "github.com/containerd/containerd/sandbox" "google.golang.org/grpc" + "google.golang.org/protobuf/types/known/anypb" ) func init() { @@ -32,33 +34,23 @@ func init() { Type: plugin.GRPCPlugin, ID: "sandbox-controllers", Requires: []plugin.Type{ - plugin.ServicePlugin, + plugin.SandboxControllerPlugin, }, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - plugins, err := ic.GetByType(plugin.ServicePlugin) - if err != nil { - return nil, err - } - - p, ok := plugins[services.SandboxControllerService] - if !ok { - return nil, errors.New("sandbox service not found") - } - - i, err := p.Instance() + sc, err := ic.GetByID(plugin.SandboxControllerPlugin, "local") if err != nil { return nil, err } return &controllerService{ - local: i.(api.ControllerClient), + local: sc.(sandbox.Controller), }, nil }, }) } type controllerService struct { - local api.ControllerClient + local sandbox.Controller api.UnimplementedControllerServer } @@ -71,30 +63,68 @@ func (s *controllerService) Register(server *grpc.Server) error { func (s *controllerService) Create(ctx context.Context, req *api.ControllerCreateRequest) (*api.ControllerCreateResponse, error) { log.G(ctx).WithField("req", req).Debug("create sandbox") - return s.local.Create(ctx, req) + // TODO: Rootfs, any + err := s.local.Create(ctx, req.GetSandboxID()) + if err != nil { + return &api.ControllerCreateResponse{}, errdefs.ToGRPC(err) + } + return &api.ControllerCreateResponse{ + SandboxID: req.GetSandboxID(), + }, nil } func (s *controllerService) Start(ctx context.Context, req *api.ControllerStartRequest) (*api.ControllerStartResponse, error) { log.G(ctx).WithField("req", req).Debug("start sandbox") - return s.local.Start(ctx, req) + inst, err := s.local.Start(ctx, req.GetSandboxID()) + if err != nil { + return &api.ControllerStartResponse{}, errdefs.ToGRPC(err) + } + return &api.ControllerStartResponse{ + SandboxID: inst.SandboxID, + Pid: inst.Pid, + CreatedAt: protobuf.ToTimestamp(inst.CreatedAt), + Labels: inst.Labels, + }, nil } func (s *controllerService) Stop(ctx context.Context, req *api.ControllerStopRequest) (*api.ControllerStopResponse, error) { log.G(ctx).WithField("req", req).Debug("delete sandbox") - return s.local.Stop(ctx, req) + return &api.ControllerStopResponse{}, errdefs.ToGRPC(s.local.Stop(ctx, req.GetSandboxID())) } func (s *controllerService) Wait(ctx context.Context, req *api.ControllerWaitRequest) (*api.ControllerWaitResponse, error) { log.G(ctx).WithField("req", req).Debug("wait sandbox") - return s.local.Wait(ctx, req) + exitStatus, err := s.local.Wait(ctx, req.GetSandboxID()) + if err != nil { + return &api.ControllerWaitResponse{}, errdefs.ToGRPC(err) + } + return &api.ControllerWaitResponse{ + ExitStatus: exitStatus.ExitStatus, + ExitedAt: protobuf.ToTimestamp(exitStatus.ExitedAt), + }, nil } func (s *controllerService) Status(ctx context.Context, req *api.ControllerStatusRequest) (*api.ControllerStatusResponse, error) { log.G(ctx).WithField("req", req).Debug("sandbox status") - return s.local.Status(ctx, req) + cstatus, err := s.local.Status(ctx, req.GetSandboxID(), req.GetVerbose()) + if err != nil { + return &api.ControllerStatusResponse{}, errdefs.ToGRPC(err) + } + return &api.ControllerStatusResponse{ + SandboxID: cstatus.SandboxID, + Pid: cstatus.Pid, + State: cstatus.State, + Info: cstatus.Info, + CreatedAt: protobuf.ToTimestamp(cstatus.CreatedAt), + ExitedAt: protobuf.ToTimestamp(cstatus.ExitedAt), + Extra: &anypb.Any{ + TypeUrl: cstatus.Extra.GetTypeUrl(), + Value: cstatus.Extra.GetValue(), + }, + }, nil } func (s *controllerService) Shutdown(ctx context.Context, req *api.ControllerShutdownRequest) (*api.ControllerShutdownResponse, error) { log.G(ctx).WithField("req", req).Debug("shutdown sandbox") - return s.local.Shutdown(ctx, req) + return &api.ControllerShutdownResponse{}, errdefs.ToGRPC(s.local.Shutdown(ctx, req.GetSandboxID())) } diff --git a/services/services.go b/services/services.go index 26c800fc8..b3ebf68e2 100644 --- a/services/services.go +++ b/services/services.go @@ -33,10 +33,10 @@ const ( DiffService = "diff-service" // IntrospectionService is the id of introspection service IntrospectionService = "introspection-service" - // SandboxStoreService is the id of Sandbox's store service - SandboxStoreService = "sandbox-store-service" // SandboxControllerService is the id of Sandbox's controller service SandboxControllerService = "sandbox-controller-service" + // SandboxStoreService is the id of Sandbox's store service + SandboxStoreService = "sandbox-store-service" // Streaming service is the id of the streaming service StreamingService = "streaming-service" ) From 34314717b07fa7223b6af7f2e76646e80f9d83ae Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Wed, 25 Jan 2023 21:46:40 -0800 Subject: [PATCH 3/4] Remove sandox store and controller service type Signed-off-by: Derek McGowan --- services.go | 6 +++--- services/services.go | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/services.go b/services.go index 47e2ffcc2..edb8872e5 100644 --- a/services.go +++ b/services.go @@ -192,6 +192,9 @@ func WithInMemoryServices(ic *plugin.InitContext) ClientOpt { plugin.SandboxStorePlugin: func(i interface{}) ServicesOpt { return WithSandboxStore(i.(sandbox.Store)) }, + plugin.SandboxControllerPlugin: func(i interface{}) ServicesOpt { + return WithSandboxController(i.(sandbox.Controller)) + }, } { i, err := ic.Get(t) if err != nil { @@ -229,9 +232,6 @@ func WithInMemoryServices(ic *plugin.InitContext) ClientOpt { srv.IntrospectionService: func(s interface{}) ServicesOpt { return WithIntrospectionClient(s.(introspectionapi.IntrospectionClient)) }, - srv.SandboxControllerService: func(s interface{}) ServicesOpt { - return WithSandboxController(s.(sandbox.Controller)) - }, } { p := plugins[s] if p == nil { diff --git a/services/services.go b/services/services.go index b3ebf68e2..d7255169f 100644 --- a/services/services.go +++ b/services/services.go @@ -33,10 +33,6 @@ const ( DiffService = "diff-service" // IntrospectionService is the id of introspection service IntrospectionService = "introspection-service" - // SandboxControllerService is the id of Sandbox's controller service - SandboxControllerService = "sandbox-controller-service" - // SandboxStoreService is the id of Sandbox's store service - SandboxStoreService = "sandbox-store-service" // Streaming service is the id of the streaming service StreamingService = "streaming-service" ) From b0e97c0f9b042a73bda7859089ee5fa6bc503134 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Tue, 7 Feb 2023 09:57:22 -0800 Subject: [PATCH 4/4] Use multierror for cleanup error Signed-off-by: Derek McGowan --- pkg/cri/sbserver/podsandbox/sandbox_run.go | 6 ++++++ pkg/cri/sbserver/sandbox_run.go | 14 +++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pkg/cri/sbserver/podsandbox/sandbox_run.go b/pkg/cri/sbserver/podsandbox/sandbox_run.go index 7d4228d67..ed8f1aef7 100644 --- a/pkg/cri/sbserver/podsandbox/sandbox_run.go +++ b/pkg/cri/sbserver/podsandbox/sandbox_run.go @@ -25,6 +25,7 @@ import ( v1 "github.com/containerd/nri/types/v1" "github.com/containerd/typeurl" "github.com/davecgh/go-spew/spew" + "github.com/hashicorp/go-multierror" "github.com/opencontainers/selinux/go-selinux" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" @@ -46,6 +47,10 @@ func init() { "github.com/containerd/cri/pkg/store/sandbox", "Metadata") } +type CleanupErr struct { + error +} + // Start creates resources required for the sandbox and starts the sandbox. If an error occurs, Start attempts to tear // down the created resources. If an error occurs while tearing down resources, a zero-valued response is returned // alongside the error. If the teardown was successful, a nil response is returned with the error. @@ -55,6 +60,7 @@ func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.Controll defer func() { if retErr != nil && cleanupErr != nil { log.G(ctx).WithField("id", id).WithError(cleanupErr).Errorf("failed to fully teardown sandbox resources after earlier error: %s", retErr) + retErr = multierror.Append(retErr, CleanupErr{cleanupErr}) } }() diff --git a/pkg/cri/sbserver/sandbox_run.go b/pkg/cri/sbserver/sandbox_run.go index 76a28ac9f..58701b8f7 100644 --- a/pkg/cri/sbserver/sandbox_run.go +++ b/pkg/cri/sbserver/sandbox_run.go @@ -28,6 +28,7 @@ import ( "github.com/containerd/go-cni" "github.com/containerd/typeurl" + "github.com/hashicorp/go-multierror" "github.com/sirupsen/logrus" runtime "k8s.io/cri-api/pkg/apis/runtime/v1" @@ -232,9 +233,16 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox ctrl, err := controller.Start(ctx, id) if err != nil { sandbox.Container, _ = c.client.LoadContainer(ctx, id) - if ctrl.SandboxID == "" && ctrl.Pid == 0 && ctrl.CreatedAt.IsZero() && len(ctrl.Labels) == 0 { - // if resp is a non-nil zero-value, an error occurred during cleanup - cleanupErr = fmt.Errorf("failed to cleanup sandbox") + var cerr podsandbox.CleanupErr + if errors.As(err, &cerr) { + cleanupErr = fmt.Errorf("failed to cleanup sandbox: %w", cerr) + + // Strip last error as cleanup error to handle separately + if merr, ok := err.(*multierror.Error); ok { + if errs := merr.WrappedErrors(); len(errs) > 0 { + err = errs[0] + } + } } return nil, fmt.Errorf("failed to start sandbox %q: %w", id, err) }