diff --git a/api/next.pb.txt b/api/next.pb.txt index 26715ff08fa1e..0ad845ae55464 100644 --- a/api/next.pb.txt +++ b/api/next.pb.txt @@ -4300,6 +4300,94 @@ file { } syntax: "proto3" } +file { + name: "github.com/containerd/containerd/api/types/introspection.proto" + package: "containerd.types" + dependency: "google/protobuf/any.proto" + message_type { + name: "RuntimeVersion" + field { + name: "version" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "version" + } + field { + name: "revision" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "revision" + } + } + message_type { + name: "RuntimeInfo" + field { + name: "name" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "name" + } + field { + name: "version" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".containerd.types.RuntimeVersion" + json_name: "version" + } + field { + name: "options" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Any" + json_name: "options" + } + field { + name: "features" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Any" + json_name: "features" + } + field { + name: "annotations" + number: 5 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".containerd.types.RuntimeInfo.AnnotationsEntry" + json_name: "annotations" + } + nested_type { + name: "AnnotationsEntry" + field { + name: "key" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "key" + } + field { + name: "value" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "value" + } + options { + map_entry: true + } + } + } + options { + go_package: "github.com/containerd/containerd/v2/api/types;types" + } + syntax: "proto3" +} file { name: "google/rpc/status.proto" package: "google.rpc" @@ -4341,6 +4429,8 @@ file { file { name: "github.com/containerd/containerd/api/services/introspection/v1/introspection.proto" package: "containerd.services.introspection.v1" + dependency: "google/protobuf/any.proto" + dependency: "github.com/containerd/containerd/api/types/introspection.proto" dependency: "github.com/containerd/containerd/api/types/platform.proto" dependency: "google/rpc/status.proto" dependency: "google/protobuf/empty.proto" @@ -4498,6 +4588,24 @@ file { json_name: "lastOccurrence" } } + message_type { + name: "RuntimeRequest" + field { + name: "runtime_path" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "runtimePath" + } + field { + name: "options" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".google.protobuf.Any" + json_name: "options" + } + } service { name: "Introspection" method { @@ -4510,6 +4618,11 @@ file { input_type: ".google.protobuf.Empty" output_type: ".containerd.services.introspection.v1.ServerResponse" } + method { + name: "Runtime" + input_type: ".containerd.services.introspection.v1.RuntimeRequest" + output_type: ".containerd.types.RuntimeInfo" + } } options { go_package: "github.com/containerd/containerd/v2/api/services/introspection/v1;introspection" diff --git a/api/services/introspection/v1/introspection.pb.go b/api/services/introspection/v1/introspection.pb.go index 869459c93588b..c68243abddb56 100644 --- a/api/services/introspection/v1/introspection.pb.go +++ b/api/services/introspection/v1/introspection.pb.go @@ -26,6 +26,7 @@ import ( status "google.golang.org/genproto/googleapis/rpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" emptypb "google.golang.org/protobuf/types/known/emptypb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" @@ -402,6 +403,63 @@ func (x *DeprecationWarning) GetLastOccurrence() *timestamppb.Timestamp { return nil } +type RuntimeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuntimePath string `protobuf:"bytes,1,opt,name=runtime_path,json=runtimePath,proto3" json:"runtime_path,omitempty"` + // Options correspond to CreateTaskRequest.options. + // This is needed to pass the runc binary path, etc. + Options *anypb.Any `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *RuntimeRequest) Reset() { + *x = RuntimeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuntimeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuntimeRequest) ProtoMessage() {} + +func (x *RuntimeRequest) ProtoReflect() protoreflect.Message { + mi := &file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuntimeRequest.ProtoReflect.Descriptor instead. +func (*RuntimeRequest) Descriptor() ([]byte, []int) { + return file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_rawDescGZIP(), []int{5} +} + +func (x *RuntimeRequest) GetRuntimePath() string { + if x != nil { + return x.RuntimePath + } + return "" +} + +func (x *RuntimeRequest) GetOptions() *anypb.Any { + if x != nil { + return x.Options + } + return nil +} + var File_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto protoreflect.FileDescriptor var file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_rawDesc = []byte{ @@ -412,67 +470,79 @@ var file_github_com_containerd_containerd_api_services_introspection_v1_introspe 0x2f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x24, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, - 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x39, 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, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, - 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x02, 0x0a, - 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x73, 0x12, 0x53, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, - 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, - 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x69, 0x6e, - 0x69, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x07, 0x69, 0x6e, 0x69, 0x74, 0x45, 0x72, 0x72, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x78, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x0e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x22, 0x59, 0x0a, 0x0f, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, - 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x52, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xaa, 0x01, 0x0a, - 0x0e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, - 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x69, 0x64, 0x6e, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x70, 0x69, 0x64, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x0c, 0x64, - 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x64, 0x65, 0x70, - 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x12, 0x44, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x4f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x32, - 0xdf, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3e, 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, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x39, 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, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x02, 0x0a, 0x06, 0x50, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x12, 0x53, 0x0a, 0x07, + 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x65, 0x72, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x69, 0x6e, 0x69, + 0x74, 0x45, 0x72, 0x72, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x2a, 0x0a, 0x0e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x59, 0x0a, 0x0f, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x46, 0x0a, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x07, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x10, + 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x70, 0x69, 0x64, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x05, 0x70, 0x69, 0x64, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x63, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, + 0x4f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x63, 0x0a, 0x0e, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x2e, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 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, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x32, + 0xbf, 0x02, 0x0a, 0x0d, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x76, 0x0a, 0x07, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, @@ -486,7 +556,13 @@ var file_github_com_containerd_containerd_api_services_introspection_v1_introspe 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x65, 0x12, 0x5e, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x34, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x42, 0x51, 0x5a, 0x4f, 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, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, @@ -506,35 +582,41 @@ func file_github_com_containerd_containerd_api_services_introspection_v1_introsp return file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_rawDescData } -var file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_goTypes = []interface{}{ (*Plugin)(nil), // 0: containerd.services.introspection.v1.Plugin (*PluginsRequest)(nil), // 1: containerd.services.introspection.v1.PluginsRequest (*PluginsResponse)(nil), // 2: containerd.services.introspection.v1.PluginsResponse (*ServerResponse)(nil), // 3: containerd.services.introspection.v1.ServerResponse (*DeprecationWarning)(nil), // 4: containerd.services.introspection.v1.DeprecationWarning - nil, // 5: containerd.services.introspection.v1.Plugin.ExportsEntry - (*types.Platform)(nil), // 6: containerd.types.Platform - (*status.Status)(nil), // 7: google.rpc.Status - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp - (*emptypb.Empty)(nil), // 9: google.protobuf.Empty + (*RuntimeRequest)(nil), // 5: containerd.services.introspection.v1.RuntimeRequest + nil, // 6: containerd.services.introspection.v1.Plugin.ExportsEntry + (*types.Platform)(nil), // 7: containerd.types.Platform + (*status.Status)(nil), // 8: google.rpc.Status + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp + (*anypb.Any)(nil), // 10: google.protobuf.Any + (*emptypb.Empty)(nil), // 11: google.protobuf.Empty + (*types.RuntimeInfo)(nil), // 12: containerd.types.RuntimeInfo } var file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_depIdxs = []int32{ - 6, // 0: containerd.services.introspection.v1.Plugin.platforms:type_name -> containerd.types.Platform - 5, // 1: containerd.services.introspection.v1.Plugin.exports:type_name -> containerd.services.introspection.v1.Plugin.ExportsEntry - 7, // 2: containerd.services.introspection.v1.Plugin.init_err:type_name -> google.rpc.Status - 0, // 3: containerd.services.introspection.v1.PluginsResponse.plugins:type_name -> containerd.services.introspection.v1.Plugin - 4, // 4: containerd.services.introspection.v1.ServerResponse.deprecations:type_name -> containerd.services.introspection.v1.DeprecationWarning - 8, // 5: containerd.services.introspection.v1.DeprecationWarning.last_occurrence:type_name -> google.protobuf.Timestamp - 1, // 6: containerd.services.introspection.v1.Introspection.Plugins:input_type -> containerd.services.introspection.v1.PluginsRequest - 9, // 7: containerd.services.introspection.v1.Introspection.Server:input_type -> google.protobuf.Empty - 2, // 8: containerd.services.introspection.v1.Introspection.Plugins:output_type -> containerd.services.introspection.v1.PluginsResponse - 3, // 9: containerd.services.introspection.v1.Introspection.Server:output_type -> containerd.services.introspection.v1.ServerResponse - 8, // [8:10] is the sub-list for method output_type - 6, // [6:8] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 7, // 0: containerd.services.introspection.v1.Plugin.platforms:type_name -> containerd.types.Platform + 6, // 1: containerd.services.introspection.v1.Plugin.exports:type_name -> containerd.services.introspection.v1.Plugin.ExportsEntry + 8, // 2: containerd.services.introspection.v1.Plugin.init_err:type_name -> google.rpc.Status + 0, // 3: containerd.services.introspection.v1.PluginsResponse.plugins:type_name -> containerd.services.introspection.v1.Plugin + 4, // 4: containerd.services.introspection.v1.ServerResponse.deprecations:type_name -> containerd.services.introspection.v1.DeprecationWarning + 9, // 5: containerd.services.introspection.v1.DeprecationWarning.last_occurrence:type_name -> google.protobuf.Timestamp + 10, // 6: containerd.services.introspection.v1.RuntimeRequest.options:type_name -> google.protobuf.Any + 1, // 7: containerd.services.introspection.v1.Introspection.Plugins:input_type -> containerd.services.introspection.v1.PluginsRequest + 11, // 8: containerd.services.introspection.v1.Introspection.Server:input_type -> google.protobuf.Empty + 5, // 9: containerd.services.introspection.v1.Introspection.Runtime:input_type -> containerd.services.introspection.v1.RuntimeRequest + 2, // 10: containerd.services.introspection.v1.Introspection.Plugins:output_type -> containerd.services.introspection.v1.PluginsResponse + 3, // 11: containerd.services.introspection.v1.Introspection.Server:output_type -> containerd.services.introspection.v1.ServerResponse + 12, // 12: containerd.services.introspection.v1.Introspection.Runtime:output_type -> containerd.types.RuntimeInfo + 10, // [10:13] is the sub-list for method output_type + 7, // [7:10] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { @@ -605,6 +687,18 @@ func file_github_com_containerd_containerd_api_services_introspection_v1_introsp return nil } } + file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuntimeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -612,7 +706,7 @@ func file_github_com_containerd_containerd_api_services_introspection_v1_introsp GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/api/services/introspection/v1/introspection.proto b/api/services/introspection/v1/introspection.proto index 7ec1961eb321b..6dd2a83d3dd94 100644 --- a/api/services/introspection/v1/introspection.proto +++ b/api/services/introspection/v1/introspection.proto @@ -18,6 +18,8 @@ syntax = "proto3"; package containerd.services.introspection.v1; +import "google/protobuf/any.proto"; +import "github.com/containerd/containerd/api/types/introspection.proto"; import "github.com/containerd/containerd/api/types/platform.proto"; import "google/rpc/status.proto"; import "google/protobuf/empty.proto"; @@ -33,6 +35,8 @@ service Introspection { rpc Plugins(PluginsRequest) returns (PluginsResponse); // Server returns information about the containerd server rpc Server(google.protobuf.Empty) returns (ServerResponse); + // Runtime returns the runtime info + rpc Runtime(RuntimeRequest) returns (types.RuntimeInfo); } message Plugin { @@ -110,4 +114,11 @@ message DeprecationWarning { string id = 1; string message = 2; google.protobuf.Timestamp last_occurrence = 3; -} \ No newline at end of file +} + +message RuntimeRequest { + string runtime_path = 1; + // Options correspond to CreateTaskRequest.options. + // This is needed to pass the runc binary path, etc. + google.protobuf.Any options = 2; +} diff --git a/api/services/introspection/v1/introspection_grpc.pb.go b/api/services/introspection/v1/introspection_grpc.pb.go index c2cf80765ccb8..7fdc5928f5682 100644 --- a/api/services/introspection/v1/introspection_grpc.pb.go +++ b/api/services/introspection/v1/introspection_grpc.pb.go @@ -8,6 +8,7 @@ package introspection import ( context "context" + types "github.com/containerd/containerd/v2/api/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -30,6 +31,8 @@ type IntrospectionClient interface { Plugins(ctx context.Context, in *PluginsRequest, opts ...grpc.CallOption) (*PluginsResponse, error) // Server returns information about the containerd server Server(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ServerResponse, error) + // Runtime returns the runtime info + Runtime(ctx context.Context, in *RuntimeRequest, opts ...grpc.CallOption) (*types.RuntimeInfo, error) } type introspectionClient struct { @@ -58,6 +61,15 @@ func (c *introspectionClient) Server(ctx context.Context, in *emptypb.Empty, opt return out, nil } +func (c *introspectionClient) Runtime(ctx context.Context, in *RuntimeRequest, opts ...grpc.CallOption) (*types.RuntimeInfo, error) { + out := new(types.RuntimeInfo) + err := c.cc.Invoke(ctx, "/containerd.services.introspection.v1.Introspection/Runtime", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // IntrospectionServer is the server API for Introspection service. // All implementations must embed UnimplementedIntrospectionServer // for forward compatibility @@ -69,6 +81,8 @@ type IntrospectionServer interface { Plugins(context.Context, *PluginsRequest) (*PluginsResponse, error) // Server returns information about the containerd server Server(context.Context, *emptypb.Empty) (*ServerResponse, error) + // Runtime returns the runtime info + Runtime(context.Context, *RuntimeRequest) (*types.RuntimeInfo, error) mustEmbedUnimplementedIntrospectionServer() } @@ -82,6 +96,9 @@ func (UnimplementedIntrospectionServer) Plugins(context.Context, *PluginsRequest func (UnimplementedIntrospectionServer) Server(context.Context, *emptypb.Empty) (*ServerResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Server not implemented") } +func (UnimplementedIntrospectionServer) Runtime(context.Context, *RuntimeRequest) (*types.RuntimeInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method Runtime not implemented") +} func (UnimplementedIntrospectionServer) mustEmbedUnimplementedIntrospectionServer() {} // UnsafeIntrospectionServer may be embedded to opt out of forward compatibility for this service. @@ -131,6 +148,24 @@ func _Introspection_Server_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Introspection_Runtime_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RuntimeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IntrospectionServer).Runtime(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/containerd.services.introspection.v1.Introspection/Runtime", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IntrospectionServer).Runtime(ctx, req.(*RuntimeRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Introspection_ServiceDesc is the grpc.ServiceDesc for Introspection service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -146,6 +181,10 @@ var Introspection_ServiceDesc = grpc.ServiceDesc{ MethodName: "Server", Handler: _Introspection_Server_Handler, }, + { + MethodName: "Runtime", + Handler: _Introspection_Runtime_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "github.com/containerd/containerd/api/services/introspection/v1/introspection.proto", diff --git a/api/types/introspection.pb.go b/api/types/introspection.pb.go new file mode 100644 index 0000000000000..da35c843b8150 --- /dev/null +++ b/api/types/introspection.pb.go @@ -0,0 +1,298 @@ +// +//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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.20.1 +// source: github.com/containerd/containerd/api/types/introspection.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RuntimeVersion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` +} + +func (x *RuntimeVersion) Reset() { + *x = RuntimeVersion{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuntimeVersion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuntimeVersion) ProtoMessage() {} + +func (x *RuntimeVersion) ProtoReflect() protoreflect.Message { + mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuntimeVersion.ProtoReflect.Descriptor instead. +func (*RuntimeVersion) Descriptor() ([]byte, []int) { + return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{0} +} + +func (x *RuntimeVersion) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RuntimeVersion) GetRevision() string { + if x != nil { + return x.Revision + } + return "" +} + +type RuntimeInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Version *RuntimeVersion `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // Options correspond to RuntimeInfoRequest.Options (contains runc binary path, etc.) + Options *anypb.Any `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` + // OCI-compatible runtimes should use https://github.com/opencontainers/runtime-spec/blob/main/features.md + Features *anypb.Any `protobuf:"bytes,4,opt,name=features,proto3" json:"features,omitempty"` + // Annotations of the shim. Irrelevant to features.Annotations. + Annotations map[string]string `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *RuntimeInfo) Reset() { + *x = RuntimeInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuntimeInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuntimeInfo) ProtoMessage() {} + +func (x *RuntimeInfo) ProtoReflect() protoreflect.Message { + mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuntimeInfo.ProtoReflect.Descriptor instead. +func (*RuntimeInfo) Descriptor() ([]byte, []int) { + return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{1} +} + +func (x *RuntimeInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RuntimeInfo) GetVersion() *RuntimeVersion { + if x != nil { + return x.Version + } + return nil +} + +func (x *RuntimeInfo) GetOptions() *anypb.Any { + if x != nil { + return x.Options + } + return nil +} + +func (x *RuntimeInfo) GetFeatures() *anypb.Any { + if x != nil { + return x.Features + } + return nil +} + +func (x *RuntimeInfo) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +var File_github_com_containerd_containerd_api_types_introspection_proto protoreflect.FileDescriptor + +var file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc = []byte{ + 0x0a, 0x3e, 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, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, + 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a, + 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd1, 0x02, 0x0a, 0x0b, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x03, 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, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x18, 0x04, 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, 0x08, 0x66, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x35, 0x5a, 0x33, 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, 0x76, 0x32, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_github_com_containerd_containerd_api_types_introspection_proto_rawDescOnce sync.Once + file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData = file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc +) + +func file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP() []byte { + file_github_com_containerd_containerd_api_types_introspection_proto_rawDescOnce.Do(func() { + file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData) + }) + return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData +} + +var file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_github_com_containerd_containerd_api_types_introspection_proto_goTypes = []interface{}{ + (*RuntimeVersion)(nil), // 0: containerd.types.RuntimeVersion + (*RuntimeInfo)(nil), // 1: containerd.types.RuntimeInfo + nil, // 2: containerd.types.RuntimeInfo.AnnotationsEntry + (*anypb.Any)(nil), // 3: google.protobuf.Any +} +var file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs = []int32{ + 0, // 0: containerd.types.RuntimeInfo.version:type_name -> containerd.types.RuntimeVersion + 3, // 1: containerd.types.RuntimeInfo.options:type_name -> google.protobuf.Any + 3, // 2: containerd.types.RuntimeInfo.features:type_name -> google.protobuf.Any + 2, // 3: containerd.types.RuntimeInfo.annotations:type_name -> containerd.types.RuntimeInfo.AnnotationsEntry + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_github_com_containerd_containerd_api_types_introspection_proto_init() } +func file_github_com_containerd_containerd_api_types_introspection_proto_init() { + if File_github_com_containerd_containerd_api_types_introspection_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuntimeVersion); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuntimeInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_containerd_containerd_api_types_introspection_proto_goTypes, + DependencyIndexes: file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs, + MessageInfos: file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes, + }.Build() + File_github_com_containerd_containerd_api_types_introspection_proto = out.File + file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc = nil + file_github_com_containerd_containerd_api_types_introspection_proto_goTypes = nil + file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs = nil +} diff --git a/api/types/introspection.proto b/api/types/introspection.proto new file mode 100644 index 0000000000000..d412d1cfdf5dd --- /dev/null +++ b/api/types/introspection.proto @@ -0,0 +1,39 @@ +/* + 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. +*/ + +syntax = "proto3"; + +package containerd.types; + +import "google/protobuf/any.proto"; + +option go_package = "github.com/containerd/containerd/v2/api/types;types"; + +message RuntimeVersion { + string version = 1; + string revision = 2; +} + +message RuntimeInfo { + string name = 1; + RuntimeVersion version = 2; + // Options correspond to RuntimeInfoRequest.Options (contains runc binary path, etc.) + google.protobuf.Any options = 3; + // OCI-compatible runtimes should use https://github.com/opencontainers/runtime-spec/blob/main/features.md + google.protobuf.Any features = 4; + // Annotations of the shim. Irrelevant to features.Annotations. + map annotations = 5; +} diff --git a/client/client.go b/client/client.go index 036e6e5ac4075..c47582d2bb0c4 100644 --- a/client/client.go +++ b/client/client.go @@ -52,6 +52,7 @@ import ( "github.com/containerd/containerd/v2/pkg/dialer" "github.com/containerd/containerd/v2/platforms" "github.com/containerd/containerd/v2/plugins" + "github.com/containerd/containerd/v2/protobuf" ptypes "github.com/containerd/containerd/v2/protobuf/types" "github.com/containerd/containerd/v2/remotes" "github.com/containerd/containerd/v2/remotes/docker" @@ -63,6 +64,7 @@ import ( "github.com/containerd/typeurl/v2" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runtime-spec/specs-go/features" "golang.org/x/sync/semaphore" "google.golang.org/grpc" "google.golang.org/grpc/backoff" @@ -78,6 +80,7 @@ func init() { typeurl.Register(&specs.Process{}, prefix, "opencontainers/runtime-spec", major, "Process") typeurl.Register(&specs.LinuxResources{}, prefix, "opencontainers/runtime-spec", major, "LinuxResources") typeurl.Register(&specs.WindowsResources{}, prefix, "opencontainers/runtime-spec", major, "WindowsResources") + typeurl.Register(&features.Features{}, prefix, "opencontainers/runtime-spec", major, "features", "Features") } // New returns a new containerd client that is connected to the containerd @@ -871,3 +874,58 @@ func (c *Client) GetSnapshotterCapabilities(ctx context.Context, snapshotterName sn := resp.Plugins[0] return sn.Capabilities, nil } + +type RuntimeVersion struct { + Version string + Revision string +} + +type RuntimeInfo struct { + Name string + Version RuntimeVersion + Options interface{} + Features interface{} + Annotations map[string]string +} + +func (c *Client) RuntimeInfo(ctx context.Context, runtimePath string, runtimeOptions interface{}) (*RuntimeInfo, error) { + rt := c.runtime + if runtimePath != "" { + rt = runtimePath + } + req := &introspectionapi.RuntimeRequest{ + RuntimePath: rt, + } + var err error + if runtimeOptions != nil { + req.Options, err = protobuf.MarshalAnyToProto(runtimeOptions) + if err != nil { + return nil, fmt.Errorf("failed to marshal %T: %w", runtimeOptions, err) + } + } + s := c.IntrospectionService() + resp, err := s.Runtime(ctx, req) + if err != nil { + return nil, err + } + var result RuntimeInfo + result.Name = resp.Name + if resp.Version != nil { + result.Version.Version = resp.Version.Version + result.Version.Revision = resp.Version.Revision + } + if resp.Options != nil { + result.Options, err = typeurl.UnmarshalAny(resp.Options) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal RuntimeInfo.Options (%T): %w", resp.Options, err) + } + } + if resp.Features != nil { + result.Features, err = typeurl.UnmarshalAny(resp.Features) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal RuntimeInfo.Features (%T): %w", resp.Features, err) + } + } + result.Annotations = resp.Annotations + return &result, nil +} diff --git a/cmd/containerd-shim-runc-v2/manager/manager_linux.go b/cmd/containerd-shim-runc-v2/manager/manager_linux.go index 9f5f81489c93e..cefbb5097ab19 100644 --- a/cmd/containerd-shim-runc-v2/manager/manager_linux.go +++ b/cmd/containerd-shim-runc-v2/manager/manager_linux.go @@ -17,9 +17,12 @@ package manager import ( + "bytes" "context" "encoding/json" + "errors" "fmt" + "io" "os" "os/exec" "path/filepath" @@ -30,16 +33,21 @@ import ( "github.com/containerd/cgroups/v3" "github.com/containerd/cgroups/v3/cgroup1" cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2" + "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/cmd/containerd-shim-runc-v2/process" "github.com/containerd/containerd/v2/cmd/containerd-shim-runc-v2/runc" + "github.com/containerd/containerd/v2/errdefs" "github.com/containerd/containerd/v2/mount" "github.com/containerd/containerd/v2/namespaces" "github.com/containerd/containerd/v2/oci" "github.com/containerd/containerd/v2/pkg/schedcore" + "github.com/containerd/containerd/v2/protobuf" "github.com/containerd/containerd/v2/runtime/v2/runc/options" "github.com/containerd/containerd/v2/runtime/v2/shim" + "github.com/containerd/containerd/v2/version" runcC "github.com/containerd/go-runc" "github.com/containerd/log" + "github.com/opencontainers/runtime-spec/specs-go/features" "golang.org/x/sys/unix" ) @@ -272,3 +280,63 @@ func (manager) Stop(ctx context.Context, id string) (shim.StopStatus, error) { Pid: pid, }, nil } + +func (m manager) Info(ctx context.Context, optionsR io.Reader) (*types.RuntimeInfo, error) { + info := &types.RuntimeInfo{ + Name: m.name, + Version: &types.RuntimeVersion{ + Version: version.Version, + Revision: version.Version, + }, + Annotations: nil, + } + binaryName := runcC.DefaultCommand + opts, err := shim.ReadRuntimeOptions[*options.Options](optionsR) + if err != nil { + if !errors.Is(err, errdefs.ErrNotFound) { + return nil, fmt.Errorf("failed to read runtime options (*options.Options): %w", err) + } + } + if opts != nil { + info.Options, err = protobuf.MarshalAnyToProto(opts) + if err != nil { + return nil, fmt.Errorf("failed to marshal %T: %w", opts, err) + } + if opts.BinaryName != "" { + binaryName = opts.BinaryName + } + + } + absBinary, err := exec.LookPath(binaryName) + if err != nil { + return nil, fmt.Errorf("failed to look up the path of %q: %w", binaryName, err) + } + features, err := m.features(ctx, absBinary, opts) + if err != nil { + // youki does not implement `runc features` yet, at the time of writing this (Sep 2023) + // https://github.com/containers/youki/issues/815 + log.G(ctx).WithError(err).Debug("Failed to get the runtime features. The runc binary does not implement `runc features` command?") + } + if features != nil { + info.Features, err = protobuf.MarshalAnyToProto(features) + if err != nil { + return nil, fmt.Errorf("failed to marshal %T: %w", features, err) + } + } + return info, nil +} + +func (m manager) features(ctx context.Context, absBinary string, opts *options.Options) (*features.Features, error) { + var stderr bytes.Buffer + cmd := exec.CommandContext(ctx, absBinary, "features") + cmd.Stderr = &stderr + stdout, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("failed to execute %v: %w (stderr: %q)", cmd.Args, err, stderr.String()) + } + var feat features.Features + if err := json.Unmarshal(stdout, &feat); err != nil { + return nil, err + } + return &feat, nil +} diff --git a/cmd/ctr/app/main.go b/cmd/ctr/app/main.go index 9e4af514e2b99..246780034f959 100644 --- a/cmd/ctr/app/main.go +++ b/cmd/ctr/app/main.go @@ -37,6 +37,7 @@ import ( "github.com/containerd/containerd/v2/cmd/ctr/commands/plugins" "github.com/containerd/containerd/v2/cmd/ctr/commands/pprof" "github.com/containerd/containerd/v2/cmd/ctr/commands/run" + "github.com/containerd/containerd/v2/cmd/ctr/commands/runtimes" "github.com/containerd/containerd/v2/cmd/ctr/commands/sandboxes" "github.com/containerd/containerd/v2/cmd/ctr/commands/snapshots" "github.com/containerd/containerd/v2/cmd/ctr/commands/tasks" @@ -129,6 +130,7 @@ containerd CLI sandboxes.Command, info.Command, deprecations.Command, + runtimes.Command, }, extraCmds...) app.Before = func(context *cli.Context) error { if context.GlobalBool("debug") { diff --git a/cmd/ctr/commands/commands.go b/cmd/ctr/commands/commands.go index 8157acaccb105..9a870fbb94a54 100644 --- a/cmd/ctr/commands/commands.go +++ b/cmd/ctr/commands/commands.go @@ -96,6 +96,19 @@ var ( }, } + // RuntimeFlags are cli flags specifying runtime + RuntimeFlags = []cli.Flag{ + cli.StringFlag{ + Name: "runtime", + Usage: "Runtime name or absolute path to runtime binary", + Value: defaults.DefaultRuntime, + }, + cli.StringFlag{ + Name: "runtime-config-path", + Usage: "Optional runtime config path", + }, + } + // ContainerFlags are cli flags specifying container options ContainerFlags = []cli.Flag{ cli.StringFlag{ @@ -138,19 +151,10 @@ var ( Name: "read-only", Usage: "Set the containers filesystem as readonly", }, - cli.StringFlag{ - Name: "runtime", - Usage: "Runtime name or absolute path to runtime binary", - Value: defaults.DefaultRuntime, - }, cli.StringFlag{ Name: "sandbox", Usage: "Create the container in the given sandbox", }, - cli.StringFlag{ - Name: "runtime-config-path", - Usage: "Optional runtime config path", - }, cli.BoolFlag{ Name: "tty,t", Usage: "Allocate a TTY for the container", diff --git a/cmd/ctr/commands/commands_unix.go b/cmd/ctr/commands/commands_unix.go index 569113e961014..6338fa1b05a66 100644 --- a/cmd/ctr/commands/commands_unix.go +++ b/cmd/ctr/commands/commands_unix.go @@ -19,10 +19,24 @@ package commands import ( + "errors" + + runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1" + "github.com/containerd/containerd/v2/runtime/v2/runc/options" "github.com/urfave/cli" ) func init() { + RuntimeFlags = append(RuntimeFlags, cli.StringFlag{ + Name: "runc-binary", + Usage: "Specify runc-compatible binary", + }, cli.StringFlag{ + Name: "runc-root", + Usage: "Specify runc-compatible root", + }, cli.BoolFlag{ + Name: "runc-systemd-cgroup", + Usage: "Start runc with systemd cgroup manager", + }) ContainerFlags = append(ContainerFlags, cli.BoolFlag{ Name: "rootfs", Usage: "Use custom rootfs that is not managed by containerd snapshotter", @@ -44,3 +58,42 @@ func init() { Usage: "File path to a device to add to the container; or a path to a directory tree of devices to add to the container", }) } + +func getRuncOptions(context *cli.Context) (*options.Options, error) { + runtimeOpts := &options.Options{} + if runcBinary := context.String("runc-binary"); runcBinary != "" { + runtimeOpts.BinaryName = runcBinary + } + if context.Bool("runc-systemd-cgroup") { + if context.String("cgroup") == "" { + // runc maps "machine.slice:foo:deadbeef" to "/machine.slice/foo-deadbeef.scope" + return nil, errors.New("option --runc-systemd-cgroup requires --cgroup to be set, e.g. \"machine.slice:foo:deadbeef\"") + } + runtimeOpts.SystemdCgroup = true + } + if root := context.String("runc-root"); root != "" { + runtimeOpts.Root = root + } + + return runtimeOpts, nil +} + +func RuntimeOptions(context *cli.Context) (interface{}, error) { + // validate first + if (context.String("runc-binary") != "" || context.Bool("runc-systemd-cgroup")) && + context.String("runtime") != "io.containerd.runc.v2" { + return nil, errors.New("specifying runc-binary and runc-systemd-cgroup is only supported for \"io.containerd.runc.v2\" runtime") + } + + if context.String("runtime") == "io.containerd.runc.v2" { + return getRuncOptions(context) + } + + if configPath := context.String("runtime-config-path"); configPath != "" { + return &runtimeoptions.Options{ + ConfigPath: configPath, + }, nil + } + + return nil, nil +} diff --git a/cmd/ctr/commands/commands_windows.go b/cmd/ctr/commands/commands_windows.go index d7b6be2860cc2..5e8ed328c4ca6 100644 --- a/cmd/ctr/commands/commands_windows.go +++ b/cmd/ctr/commands/commands_windows.go @@ -38,3 +38,7 @@ func init() { Usage: "Identifier of a device to add to the container (e.g. class://5B45201D-F2F2-4F3B-85BB-30FF1F953599)", }) } + +func RuntimeOptions(context *cli.Context) (interface{}, error) { + return nil, nil +} diff --git a/cmd/ctr/commands/containers/containers.go b/cmd/ctr/commands/containers/containers.go index 68fed0b280cb9..6851949b4acd9 100644 --- a/cmd/ctr/commands/containers/containers.go +++ b/cmd/ctr/commands/containers/containers.go @@ -55,7 +55,7 @@ var createCommand = cli.Command{ Usage: "Create container", ArgsUsage: "[flags] Image|RootFS CONTAINER [COMMAND] [ARG...]", SkipArgReorder: true, - Flags: append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), commands.ContainerFlags...), + Flags: append(commands.RuntimeFlags, append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), commands.ContainerFlags...)...), Action: func(context *cli.Context) error { var ( id string diff --git a/cmd/ctr/commands/run/run.go b/cmd/ctr/commands/run/run.go index d8644a11d4ff4..70ad9a3537362 100644 --- a/cmd/ctr/commands/run/run.go +++ b/cmd/ctr/commands/run/run.go @@ -128,8 +128,9 @@ var Command = cli.Command{ Usage: "Enable cni networking for the container", }, }, append(platformRunFlags, - append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), - commands.ContainerFlags...)...)...), + append(commands.RuntimeFlags, + append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), + commands.ContainerFlags...)...)...)...), Action: func(context *cli.Context) error { var ( err error diff --git a/cmd/ctr/commands/run/run_unix.go b/cmd/ctr/commands/run/run_unix.go index 0d08004a18ab7..d02ed8ef0f0f1 100644 --- a/cmd/ctr/commands/run/run_unix.go +++ b/cmd/ctr/commands/run/run_unix.go @@ -37,9 +37,7 @@ import ( "github.com/containerd/containerd/v2/contrib/nvidia" "github.com/containerd/containerd/v2/contrib/seccomp" "github.com/containerd/containerd/v2/oci" - runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1" "github.com/containerd/containerd/v2/platforms" - "github.com/containerd/containerd/v2/runtime/v2/runc/options" "github.com/containerd/containerd/v2/snapshots" "github.com/containerd/log" "github.com/intel/goresctrl/pkg/blockio" @@ -48,18 +46,6 @@ import ( ) var platformRunFlags = []cli.Flag{ - cli.StringFlag{ - Name: "runc-binary", - Usage: "Specify runc-compatible binary", - }, - cli.StringFlag{ - Name: "runc-root", - Usage: "Specify runc-compatible root", - }, - cli.BoolFlag{ - Name: "runc-systemd-cgroup", - Usage: "Start runc with systemd cgroup manager", - }, cli.StringFlag{ Name: "uidmap", Usage: "Run inside a user namespace with the specified UID mapping range; specified with the format `container-uid:host-uid:length`", @@ -413,7 +399,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli cOpts = append(cOpts, containerd.WithContainerExtension(commands.CtrCniMetadataExtension, cniMeta)) } - runtimeOpts, err := getRuntimeOptions(context) + runtimeOpts, err := commands.RuntimeOptions(context) if err != nil { return nil, err } @@ -430,45 +416,6 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli return client.NewContainer(ctx, id, cOpts...) } -func getRuncOptions(context *cli.Context) (*options.Options, error) { - runtimeOpts := &options.Options{} - if runcBinary := context.String("runc-binary"); runcBinary != "" { - runtimeOpts.BinaryName = runcBinary - } - if context.Bool("runc-systemd-cgroup") { - if context.String("cgroup") == "" { - // runc maps "machine.slice:foo:deadbeef" to "/machine.slice/foo-deadbeef.scope" - return nil, errors.New("option --runc-systemd-cgroup requires --cgroup to be set, e.g. \"machine.slice:foo:deadbeef\"") - } - runtimeOpts.SystemdCgroup = true - } - if root := context.String("runc-root"); root != "" { - runtimeOpts.Root = root - } - - return runtimeOpts, nil -} - -func getRuntimeOptions(context *cli.Context) (interface{}, error) { - // validate first - if (context.String("runc-binary") != "" || context.Bool("runc-systemd-cgroup")) && - context.String("runtime") != "io.containerd.runc.v2" { - return nil, errors.New("specifying runc-binary and runc-systemd-cgroup is only supported for \"io.containerd.runc.v2\" runtime") - } - - if context.String("runtime") == "io.containerd.runc.v2" { - return getRuncOptions(context) - } - - if configPath := context.String("runtime-config-path"); configPath != "" { - return &runtimeoptions.Options{ - ConfigPath: configPath, - }, nil - } - - return nil, nil -} - func parseIDMapping(mapping string) (specs.LinuxIDMapping, error) { // We expect 3 parts, but limit to 4 to allow detection of invalid values. parts := strings.SplitN(mapping, ":", 4) diff --git a/cmd/ctr/commands/runtimes/inspect.go b/cmd/ctr/commands/runtimes/inspect.go new file mode 100644 index 0000000000000..46aace31e3c9e --- /dev/null +++ b/cmd/ctr/commands/runtimes/inspect.go @@ -0,0 +1,55 @@ +/* + 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 runtimes + +import ( + "encoding/json" + "fmt" + + "github.com/containerd/containerd/v2/cmd/ctr/commands" + "github.com/urfave/cli" +) + +var inspectCommand = cli.Command{ + Name: "inspect", + Aliases: []string{"i"}, + Usage: "Display runtime info", + ArgsUsage: "[flags]", + Flags: commands.RuntimeFlags, + Action: func(context *cli.Context) error { + rt := context.String("runtime") + rtOptions, err := commands.RuntimeOptions(context) + if err != nil { + return err + } + client, ctx, cancel, err := commands.NewClient(context) + if err != nil { + return err + } + defer cancel() + rtInfo, err := client.RuntimeInfo(ctx, rt, rtOptions) + if err != nil { + return err + } + j, err := json.MarshalIndent(rtInfo, "", " ") + if err != nil { + return err + } + _, err = fmt.Fprintln(context.App.Writer, string(j)) + return err + }, +} diff --git a/cmd/ctr/commands/runtimes/runtimes.go b/cmd/ctr/commands/runtimes/runtimes.go new file mode 100644 index 0000000000000..1999b6ad7ad86 --- /dev/null +++ b/cmd/ctr/commands/runtimes/runtimes.go @@ -0,0 +1,31 @@ +/* + 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 runtimes + +import ( + "github.com/urfave/cli" +) + +// Command is the cli command for managing runtimes +var Command = cli.Command{ + Name: "runtimes", + Usage: "Manage runtime", + Aliases: []string{"r", "runtime"}, + Subcommands: []cli.Command{ + inspectCommand, + }, +} diff --git a/integration/client/client_test.go b/integration/client/client_test.go index 06eed9654f6b6..163c086a8fc89 100644 --- a/integration/client/client_test.go +++ b/integration/client/client_test.go @@ -24,11 +24,13 @@ import ( "io" "os" "os/exec" + "runtime" "testing" "time" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" + "github.com/opencontainers/runtime-spec/specs-go/features" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" @@ -546,3 +548,46 @@ func TestDefaultRuntimeWithNamespaceLabels(t *testing.T) { t.Error("failed to set default runtime from namespace labels") } } + +func TestRuntimeInfo(t *testing.T) { + t.Parallel() + + if runtime.GOOS == "windows" { + t.Skip("io.containerd.runhcs.v1 does not implement `containerd-shim-runhcs-v1.exe -info` yet") + } + + client, err := newClient(t, address) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + ctx, cancel := testContext(t) + defer cancel() + + rti, err := client.RuntimeInfo(ctx, "", nil) + if err != nil { + t.Fatal(err) + } + + if rti.Name == "" { + t.Fatal("got empty RuntimeInfo.Name") + } + + feat, ok := rti.Features.(*features.Features) + if !ok { + t.Fatalf("expected RuntimeInfo.Features to be *features.Features, got %T", rti.Features) + } + + var rroRecognized bool + for _, f := range feat.MountOptions { + // "rro" is recognized since runc v1.1. + // The functionality needs kernel >= 5.12, but `runc features` consistently include "rro" in feat.MountOptions. + if f == "rro" { + rroRecognized = true + } + } + if !rroRecognized { + t.Fatalf("expected feat.MountOptions to contain \"rro\", only got %v", feat.MountOptions) + } +} diff --git a/runtime/runtime.go b/runtime/runtime.go index 52760e37e444b..429cc7b2ecbc3 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -20,6 +20,7 @@ import ( "context" "time" + "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/mount" "github.com/containerd/typeurl/v2" ) @@ -74,4 +75,6 @@ type PlatformRuntime interface { Tasks(ctx context.Context, all bool) ([]Task, error) // Delete remove a task. Delete(ctx context.Context, taskID string) (*Exit, error) + // RuntimeInfo returns the runtime info. + RuntimeInfo(ctx context.Context, runtimeName string, runtimeOptions interface{}) (*types.RuntimeInfo, error) } diff --git a/runtime/typeurl.go b/runtime/typeurl.go index d4ad8ccc84f4b..818a508917963 100644 --- a/runtime/typeurl.go +++ b/runtime/typeurl.go @@ -21,6 +21,7 @@ import ( "github.com/containerd/typeurl/v2" specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runtime-spec/specs-go/features" ) func init() { @@ -31,4 +32,5 @@ func init() { typeurl.Register(&specs.Process{}, prefix, "opencontainers/runtime-spec", major, "Process") typeurl.Register(&specs.LinuxResources{}, prefix, "opencontainers/runtime-spec", major, "LinuxResources") typeurl.Register(&specs.WindowsResources{}, prefix, "opencontainers/runtime-spec", major, "WindowsResources") + typeurl.Register(&features.Features{}, prefix, "opencontainers/runtime-spec", major, "features", "Features") } diff --git a/runtime/v2/README.md b/runtime/v2/README.md index a81e3b37dc7ae..1171686113bfa 100644 --- a/runtime/v2/README.md +++ b/runtime/v2/README.md @@ -243,6 +243,29 @@ The delete command MUST accept the following flags: The delete command will be executed in the container's bundle as its `cwd` except for on Windows and FreeBSD platforms. +### Command-like flags +#### `-v` +Each shim SHOULD implement a `-v` flag. +This command-like flag prints the shim implementation version and exits. +The output is not machine-parsable. + +#### `-info` +Each shim SHOULD implement a `-info` flag. +This command-like flag gets the option protobuf from stdin, prints the shim info protobuf (see below) to stdout, and exits. + +```proto +message RuntimeInfo { + string name = 1; + RuntimeVersion version = 2; + // Options from stdin + google.protobuf.Any options = 3; + // OCI-compatible runtimes should use https://github.com/opencontainers/runtime-spec/blob/main/features.md + google.protobuf.Any features = 4; + // Annotations of the shim. Irrelevant to features.Annotations. + map annotations = 5; +} +``` + ### Host Level Shim Configuration containerd does not provide any host level configuration for shims via the API. diff --git a/runtime/v2/example/example.go b/runtime/v2/example/example.go index cef6df162230b..c176618d4003a 100644 --- a/runtime/v2/example/example.go +++ b/runtime/v2/example/example.go @@ -18,9 +18,11 @@ package example import ( "context" + "io" "os" taskAPI "github.com/containerd/containerd/v2/api/runtime/task/v2" + apitypes "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/errdefs" "github.com/containerd/containerd/v2/pkg/shutdown" "github.com/containerd/containerd/v2/plugins" @@ -73,6 +75,16 @@ func (m manager) Stop(ctx context.Context, id string) (shim.StopStatus, error) { return shim.StopStatus{}, errdefs.ErrNotImplemented } +func (m manager) Info(ctx context.Context, optionsR io.Reader) (*apitypes.RuntimeInfo, error) { + info := &apitypes.RuntimeInfo{ + Name: "io.containerd.example.v1", + Version: &apitypes.RuntimeVersion{ + Version: "v1.0.0", + }, + } + return info, nil +} + func newTaskService(ctx context.Context, publisher shim.Publisher, sd shutdown.Service) (taskAPI.TaskService, error) { // The shim.Publisher and shutdown.Service are usually useful for your task service, // but we don't need them in the exampleTaskService. diff --git a/runtime/v2/manager.go b/runtime/v2/manager.go index 072b167678f55..c7c22053c4c25 100644 --- a/runtime/v2/manager.go +++ b/runtime/v2/manager.go @@ -17,6 +17,7 @@ package v2 import ( + "bytes" "context" "errors" "fmt" @@ -26,6 +27,7 @@ import ( "strings" "sync" + apitypes "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/containers" "github.com/containerd/containerd/v2/errdefs" "github.com/containerd/containerd/v2/events/exchange" @@ -36,6 +38,7 @@ import ( "github.com/containerd/containerd/v2/platforms" "github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/protobuf" + "github.com/containerd/containerd/v2/protobuf/proto" "github.com/containerd/containerd/v2/runtime" shimbinary "github.com/containerd/containerd/v2/runtime/v2/shim" "github.com/containerd/containerd/v2/sandbox" @@ -533,3 +536,34 @@ func (m *TaskManager) Delete(ctx context.Context, taskID string) (*runtime.Exit, return exit, nil } + +func (m *TaskManager) RuntimeInfo(ctx context.Context, runtimeName string, runtimeOptions interface{}) (*apitypes.RuntimeInfo, error) { + runtimePath, err := m.manager.resolveRuntimePath(runtimeName) + if err != nil { + return nil, fmt.Errorf("failed to resolve runtime path: %w", err) + } + var optsB []byte + if runtimeOptions != nil { + optsPBAny, err := protobuf.MarshalAnyToProto(runtimeOptions) + if err != nil { + return nil, fmt.Errorf("failed to marshal %T: %w", runtimeOptions, err) + } + optsB, err = proto.Marshal(optsPBAny) + if err != nil { + return nil, fmt.Errorf("failed to marshal %T: %w", optsPBAny, err) + } + } + var stderr bytes.Buffer + cmd := exec.CommandContext(ctx, runtimePath, "-info") + cmd.Stdin = bytes.NewReader(optsB) + cmd.Stderr = &stderr + stdout, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("failed to run %v: %w (stderr: %q)", cmd.Args, err, stderr.String()) + } + var info apitypes.RuntimeInfo + if err = proto.Unmarshal(stdout, &info); err != nil { + return nil, fmt.Errorf("failed to unmarshal stdout from %v into %T: %w", cmd.Args, &info, err) + } + return &info, nil +} diff --git a/runtime/v2/shim/shim.go b/runtime/v2/shim/shim.go index 87c053307fc39..a60b6f9046bad 100644 --- a/runtime/v2/shim/shim.go +++ b/runtime/v2/shim/shim.go @@ -31,6 +31,7 @@ import ( "time" shimapi "github.com/containerd/containerd/v2/api/runtime/task/v3" + "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/events" "github.com/containerd/containerd/v2/namespaces" "github.com/containerd/containerd/v2/pkg/shutdown" @@ -79,6 +80,7 @@ type Manager interface { Name() string Start(ctx context.Context, id string, opts StartOpts) (BootstrapParams, error) Stop(ctx context.Context, id string) (StopStatus, error) + Info(ctx context.Context, optionsR io.Reader) (*types.RuntimeInfo, error) } // OptsKey is the context key for the Opts value. @@ -116,6 +118,7 @@ type TTRPCServerOptioner interface { var ( debugFlag bool versionFlag bool + infoFlag bool id string namespaceFlag string socketFlag string @@ -135,6 +138,9 @@ const ( func parseFlags() { flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") flag.BoolVar(&versionFlag, "v", false, "show the shim version and exit") + // "info" is not a subcommand, because old shims produce very confusing errors for unknown subcommands + // https://github.com/containerd/containerd/pull/8509#discussion_r1210021403 + flag.BoolVar(&infoFlag, "info", false, "get the option protobuf from stdin, print the shim info protobuf to stdout, and exit") flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") flag.StringVar(&id, "id", "", "id of the task") flag.StringVar(&socketFlag, "socket", "", "socket path to serve") @@ -195,6 +201,19 @@ func Run(ctx context.Context, manager Manager, opts ...BinaryOpts) { } } +func runInfo(ctx context.Context, manager Manager) error { + info, err := manager.Info(ctx, os.Stdin) + if err != nil { + return err + } + infoB, err := proto.Marshal(info) + if err != nil { + return err + } + _, err = os.Stdout.Write(infoB) + return err +} + func run(ctx context.Context, manager Manager, config Config) error { parseFlags() if versionFlag { @@ -206,6 +225,10 @@ func run(ctx context.Context, manager Manager, config Config) error { return nil } + if infoFlag { + return runInfo(ctx, manager) + } + if namespaceFlag == "" { return fmt.Errorf("shim namespace cannot be empty") } diff --git a/services/introspection/introspection.go b/services/introspection/introspection.go index 9fcff9ec79ae4..f9ab982503b27 100644 --- a/services/introspection/introspection.go +++ b/services/introspection/introspection.go @@ -20,6 +20,7 @@ import ( context "context" api "github.com/containerd/containerd/v2/api/services/introspection/v1" + apitypes "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/errdefs" ptypes "github.com/containerd/containerd/v2/protobuf/types" "github.com/containerd/log" @@ -29,6 +30,7 @@ import ( type Service interface { Plugins(context.Context, []string) (*api.PluginsResponse, error) Server(context.Context, *ptypes.Empty) (*api.ServerResponse, error) + Runtime(ctx context.Context, in *api.RuntimeRequest) (*apitypes.RuntimeInfo, error) } type introspectionRemote struct { @@ -64,3 +66,13 @@ func (i *introspectionRemote) Server(ctx context.Context, in *ptypes.Empty) (*ap return resp, nil } + +func (i *introspectionRemote) Runtime(ctx context.Context, in *api.RuntimeRequest) (*apitypes.RuntimeInfo, error) { + resp, err := i.client.Runtime(ctx, in) + + if err != nil { + return nil, errdefs.FromGRPC(err) + } + + return resp, nil +} diff --git a/services/introspection/local.go b/services/introspection/local.go index e1405ad8de60e..d1a30ef224f53 100644 --- a/services/introspection/local.go +++ b/services/introspection/local.go @@ -19,6 +19,7 @@ package introspection import ( context "context" "errors" + "fmt" "os" "path/filepath" "runtime" @@ -37,17 +38,19 @@ import ( "github.com/containerd/containerd/v2/plugins" "github.com/containerd/containerd/v2/protobuf" ptypes "github.com/containerd/containerd/v2/protobuf/types" + containerdruntime "github.com/containerd/containerd/v2/runtime" "github.com/containerd/containerd/v2/services" "github.com/containerd/containerd/v2/services/warning" "github.com/containerd/plugin" "github.com/containerd/plugin/registry" + "github.com/containerd/typeurl/v2" ) func init() { registry.Register(&plugin.Registration{ Type: plugins.ServicePlugin, ID: services.IntrospectionService, - Requires: []plugin.Type{plugins.WarningPlugin}, + Requires: []plugin.Type{plugins.WarningPlugin, plugins.RuntimePluginV2}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { i, err := ic.GetByID(plugins.WarningPlugin, plugins.DeprecationsPlugin) if err != nil { @@ -59,11 +62,17 @@ func init() { return nil, errors.New("could not create a local client for warning service") } + v2r, err := ic.GetByID(plugins.RuntimePluginV2, "task") + if err != nil { + return nil, err + } + // this service fetches all plugins through the plugin set of the plugin context return &Local{ plugins: ic.Plugins(), root: ic.Properties[plugins.PropertyRootDir], warningClient: warningClient, + v2Runtime: v2r.(containerdruntime.PlatformRuntime), }, nil }, }) @@ -76,6 +85,7 @@ type Local struct { plugins *plugin.Set pluginCache []*api.Plugin warningClient warning.Service + v2Runtime containerdruntime.PlatformRuntime } var _ = (api.IntrospectionClient)(&Local{}) @@ -267,3 +277,23 @@ func warningsPB(ctx context.Context, warnings []warning.Warning) []*api.Deprecat } return pb } + +func (l *Local) Runtime(ctx context.Context, req *api.RuntimeRequest, _ ...grpc.CallOption) (*types.RuntimeInfo, error) { + var ( + rtOptions interface{} + err error + ) + if req.Options != nil { + rtOptions, err = typeurl.UnmarshalAny(req.Options) + if err != nil { + err = fmt.Errorf("failed to unmarshal RuntimeRequest.Options: %w", err) + return nil, errdefs.ToGRPC(err) + } + } + info, err := l.v2Runtime.RuntimeInfo(ctx, req.RuntimePath, rtOptions) + if err != nil { + err = fmt.Errorf("failed to get runtime info for %q: %w", req.RuntimePath, err) + return nil, errdefs.ToGRPC(err) + } + return info, nil +} diff --git a/services/introspection/service.go b/services/introspection/service.go index 6c791913ac37c..96371348b6375 100644 --- a/services/introspection/service.go +++ b/services/introspection/service.go @@ -21,6 +21,7 @@ import ( "errors" api "github.com/containerd/containerd/v2/api/services/introspection/v1" + apitypes "github.com/containerd/containerd/v2/api/types" "github.com/containerd/containerd/v2/plugins" ptypes "github.com/containerd/containerd/v2/protobuf/types" "github.com/containerd/containerd/v2/services" @@ -72,3 +73,7 @@ func (s *server) Plugins(ctx context.Context, req *api.PluginsRequest) (*api.Plu func (s *server) Server(ctx context.Context, empty *ptypes.Empty) (*api.ServerResponse, error) { return s.local.Server(ctx, empty) } + +func (s *server) Runtime(ctx context.Context, req *api.RuntimeRequest) (*apitypes.RuntimeInfo, error) { + return s.local.Runtime(ctx, req) +}