Merge pull request #9442 from AkihiroSuda/runtime-info2
api/services/instrospection: add PluginInfo
This commit is contained in:
		
							
								
								
									
										157
									
								
								api/next.pb.txt
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								api/next.pb.txt
									
									
									
									
									
								
							@@ -4307,6 +4307,112 @@ file {
 | 
			
		||||
  }
 | 
			
		||||
  syntax: "proto3"
 | 
			
		||||
}
 | 
			
		||||
file {
 | 
			
		||||
  name: "github.com/containerd/containerd/api/types/introspection.proto"
 | 
			
		||||
  package: "containerd.types"
 | 
			
		||||
  dependency: "google/protobuf/any.proto"
 | 
			
		||||
  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"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  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"
 | 
			
		||||
@@ -4348,6 +4454,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"
 | 
			
		||||
@@ -4505,6 +4613,50 @@ file {
 | 
			
		||||
      json_name: "lastOccurrence"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  message_type {
 | 
			
		||||
    name: "PluginInfoRequest"
 | 
			
		||||
    field {
 | 
			
		||||
      name: "type"
 | 
			
		||||
      number: 1
 | 
			
		||||
      label: LABEL_OPTIONAL
 | 
			
		||||
      type: TYPE_STRING
 | 
			
		||||
      json_name: "type"
 | 
			
		||||
    }
 | 
			
		||||
    field {
 | 
			
		||||
      name: "id"
 | 
			
		||||
      number: 2
 | 
			
		||||
      label: LABEL_OPTIONAL
 | 
			
		||||
      type: TYPE_STRING
 | 
			
		||||
      json_name: "id"
 | 
			
		||||
    }
 | 
			
		||||
    field {
 | 
			
		||||
      name: "options"
 | 
			
		||||
      number: 3
 | 
			
		||||
      label: LABEL_OPTIONAL
 | 
			
		||||
      type: TYPE_MESSAGE
 | 
			
		||||
      type_name: ".google.protobuf.Any"
 | 
			
		||||
      json_name: "options"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  message_type {
 | 
			
		||||
    name: "PluginInfoResponse"
 | 
			
		||||
    field {
 | 
			
		||||
      name: "plugin"
 | 
			
		||||
      number: 1
 | 
			
		||||
      label: LABEL_OPTIONAL
 | 
			
		||||
      type: TYPE_MESSAGE
 | 
			
		||||
      type_name: ".containerd.services.introspection.v1.Plugin"
 | 
			
		||||
      json_name: "plugin"
 | 
			
		||||
    }
 | 
			
		||||
    field {
 | 
			
		||||
      name: "extra"
 | 
			
		||||
      number: 2
 | 
			
		||||
      label: LABEL_OPTIONAL
 | 
			
		||||
      type: TYPE_MESSAGE
 | 
			
		||||
      type_name: ".google.protobuf.Any"
 | 
			
		||||
      json_name: "extra"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  service {
 | 
			
		||||
    name: "Introspection"
 | 
			
		||||
    method {
 | 
			
		||||
@@ -4517,6 +4669,11 @@ file {
 | 
			
		||||
      input_type: ".google.protobuf.Empty"
 | 
			
		||||
      output_type: ".containerd.services.introspection.v1.ServerResponse"
 | 
			
		||||
    }
 | 
			
		||||
    method {
 | 
			
		||||
      name: "PluginInfo"
 | 
			
		||||
      input_type: ".containerd.services.introspection.v1.PluginInfoRequest"
 | 
			
		||||
      output_type: ".containerd.services.introspection.v1.PluginInfoResponse"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  options {
 | 
			
		||||
    go_package: "github.com/containerd/containerd/v2/api/services/introspection/v1;introspection"
 | 
			
		||||
 
 | 
			
		||||
@@ -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,128 @@ func (x *DeprecationWarning) GetLastOccurrence() *timestamppb.Timestamp {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PluginInfoRequest struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
 | 
			
		||||
	ID   string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
 | 
			
		||||
	// Options may be used to request extra dynamic information from
 | 
			
		||||
	// a plugin.
 | 
			
		||||
	// This object is determined by the plugin and the plugin may return
 | 
			
		||||
	// NotImplemented or InvalidArgument if it is not supported
 | 
			
		||||
	Options *anypb.Any `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoRequest) Reset() {
 | 
			
		||||
	*x = PluginInfoRequest{}
 | 
			
		||||
	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 *PluginInfoRequest) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*PluginInfoRequest) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoRequest) 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 PluginInfoRequest.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*PluginInfoRequest) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_rawDescGZIP(), []int{5}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoRequest) GetType() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Type
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoRequest) GetID() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.ID
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoRequest) GetOptions() *anypb.Any {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Options
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PluginInfoResponse struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	Plugin *Plugin    `protobuf:"bytes,1,opt,name=plugin,proto3" json:"plugin,omitempty"`
 | 
			
		||||
	Extra  *anypb.Any `protobuf:"bytes,2,opt,name=extra,proto3" json:"extra,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoResponse) Reset() {
 | 
			
		||||
	*x = PluginInfoResponse{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes[6]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		ms.StoreMessageInfo(mi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoResponse) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*PluginInfoResponse) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoResponse) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_msgTypes[6]
 | 
			
		||||
	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 PluginInfoResponse.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*PluginInfoResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_github_com_containerd_containerd_api_services_introspection_v1_introspection_proto_rawDescGZIP(), []int{6}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoResponse) GetPlugin() *Plugin {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Plugin
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *PluginInfoResponse) GetExtra() *anypb.Any {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Extra
 | 
			
		||||
	}
 | 
			
		||||
	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,86 +535,115 @@ 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,
 | 
			
		||||
	0x6e, 0x12, 0x76, 0x0a, 0x07, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x34, 0x2e, 0x63,
 | 
			
		||||
	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, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
 | 
			
		||||
	0x73, 0x74, 0x1a, 0x35, 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,
 | 
			
		||||
	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x06, 0x53, 0x65, 0x72,
 | 
			
		||||
	0x76, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
 | 
			
		||||
	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 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, 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,
 | 
			
		||||
	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,
 | 
			
		||||
	0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63,
 | 
			
		||||
	0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
	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, 0x67, 0x0a, 0x11, 0x50, 0x6c,
 | 
			
		||||
	0x75, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, 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, 0x22, 0x86, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x49, 0x6e,
 | 
			
		||||
	0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x06, 0x70, 0x6c,
 | 
			
		||||
	0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 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, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
 | 
			
		||||
	0x12, 0x2a, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 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, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x32, 0xe0, 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, 0x2e, 0x76, 0x31,
 | 
			
		||||
	0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
 | 
			
		||||
	0x35, 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, 0x73, 0x52, 0x65,
 | 
			
		||||
	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
 | 
			
		||||
	0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
 | 
			
		||||
	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 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,
 | 
			
		||||
	0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f,
 | 
			
		||||
	0x0a, 0x0a, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x37, 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, 0x49, 0x6e, 0x66, 0x6f, 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, 0x69, 0x6e, 0x74, 0x72,
 | 
			
		||||
	0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x75,
 | 
			
		||||
	0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x69, 0x6f,
 | 
			
		||||
	0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69,
 | 
			
		||||
	0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@@ -506,35 +658,43 @@ 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, 8)
 | 
			
		||||
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
 | 
			
		||||
	(*PluginInfoRequest)(nil),     // 5: containerd.services.introspection.v1.PluginInfoRequest
 | 
			
		||||
	(*PluginInfoResponse)(nil),    // 6: containerd.services.introspection.v1.PluginInfoResponse
 | 
			
		||||
	nil,                           // 7: containerd.services.introspection.v1.Plugin.ExportsEntry
 | 
			
		||||
	(*types.Platform)(nil),        // 8: containerd.types.Platform
 | 
			
		||||
	(*status.Status)(nil),         // 9: google.rpc.Status
 | 
			
		||||
	(*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp
 | 
			
		||||
	(*anypb.Any)(nil),             // 11: google.protobuf.Any
 | 
			
		||||
	(*emptypb.Empty)(nil),         // 12: google.protobuf.Empty
 | 
			
		||||
}
 | 
			
		||||
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
 | 
			
		||||
	8,  // 0: containerd.services.introspection.v1.Plugin.platforms:type_name -> containerd.types.Platform
 | 
			
		||||
	7,  // 1: containerd.services.introspection.v1.Plugin.exports:type_name -> containerd.services.introspection.v1.Plugin.ExportsEntry
 | 
			
		||||
	9,  // 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
 | 
			
		||||
	10, // 5: containerd.services.introspection.v1.DeprecationWarning.last_occurrence:type_name -> google.protobuf.Timestamp
 | 
			
		||||
	11, // 6: containerd.services.introspection.v1.PluginInfoRequest.options:type_name -> google.protobuf.Any
 | 
			
		||||
	0,  // 7: containerd.services.introspection.v1.PluginInfoResponse.plugin:type_name -> containerd.services.introspection.v1.Plugin
 | 
			
		||||
	11, // 8: containerd.services.introspection.v1.PluginInfoResponse.extra:type_name -> google.protobuf.Any
 | 
			
		||||
	1,  // 9: containerd.services.introspection.v1.Introspection.Plugins:input_type -> containerd.services.introspection.v1.PluginsRequest
 | 
			
		||||
	12, // 10: containerd.services.introspection.v1.Introspection.Server:input_type -> google.protobuf.Empty
 | 
			
		||||
	5,  // 11: containerd.services.introspection.v1.Introspection.PluginInfo:input_type -> containerd.services.introspection.v1.PluginInfoRequest
 | 
			
		||||
	2,  // 12: containerd.services.introspection.v1.Introspection.Plugins:output_type -> containerd.services.introspection.v1.PluginsResponse
 | 
			
		||||
	3,  // 13: containerd.services.introspection.v1.Introspection.Server:output_type -> containerd.services.introspection.v1.ServerResponse
 | 
			
		||||
	6,  // 14: containerd.services.introspection.v1.Introspection.PluginInfo:output_type -> containerd.services.introspection.v1.PluginInfoResponse
 | 
			
		||||
	12, // [12:15] is the sub-list for method output_type
 | 
			
		||||
	9,  // [9:12] is the sub-list for method input_type
 | 
			
		||||
	9,  // [9:9] is the sub-list for extension type_name
 | 
			
		||||
	9,  // [9:9] is the sub-list for extension extendee
 | 
			
		||||
	0,  // [0:9] is the sub-list for field type_name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
@@ -605,6 +765,30 @@ 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.(*PluginInfoRequest); 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_services_introspection_v1_introspection_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*PluginInfoResponse); 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 +796,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:   8,
 | 
			
		||||
			NumExtensions: 0,
 | 
			
		||||
			NumServices:   1,
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
	// PluginInfo returns information directly from a plugin if the plugin supports it
 | 
			
		||||
	rpc PluginInfo(PluginInfoRequest) returns (PluginInfoResponse);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message Plugin {
 | 
			
		||||
@@ -111,3 +115,19 @@ message DeprecationWarning {
 | 
			
		||||
	string message = 2;
 | 
			
		||||
	google.protobuf.Timestamp last_occurrence = 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message PluginInfoRequest {
 | 
			
		||||
	string type = 1;
 | 
			
		||||
	string id = 2;
 | 
			
		||||
 | 
			
		||||
	// Options may be used to request extra dynamic information from
 | 
			
		||||
	// a plugin.
 | 
			
		||||
	// This object is determined by the plugin and the plugin may return
 | 
			
		||||
	// NotImplemented or InvalidArgument if it is not supported
 | 
			
		||||
	google.protobuf.Any options = 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message PluginInfoResponse {
 | 
			
		||||
	Plugin plugin = 1;
 | 
			
		||||
	google.protobuf.Any extra = 2;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,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)
 | 
			
		||||
	// PluginInfo returns information directly from a plugin if the plugin supports it
 | 
			
		||||
	PluginInfo(ctx context.Context, in *PluginInfoRequest, opts ...grpc.CallOption) (*PluginInfoResponse, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type introspectionClient struct {
 | 
			
		||||
@@ -58,6 +60,15 @@ func (c *introspectionClient) Server(ctx context.Context, in *emptypb.Empty, opt
 | 
			
		||||
	return out, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *introspectionClient) PluginInfo(ctx context.Context, in *PluginInfoRequest, opts ...grpc.CallOption) (*PluginInfoResponse, error) {
 | 
			
		||||
	out := new(PluginInfoResponse)
 | 
			
		||||
	err := c.cc.Invoke(ctx, "/containerd.services.introspection.v1.Introspection/PluginInfo", 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 +80,8 @@ type IntrospectionServer interface {
 | 
			
		||||
	Plugins(context.Context, *PluginsRequest) (*PluginsResponse, error)
 | 
			
		||||
	// Server returns information about the containerd server
 | 
			
		||||
	Server(context.Context, *emptypb.Empty) (*ServerResponse, error)
 | 
			
		||||
	// PluginInfo returns information directly from a plugin if the plugin supports it
 | 
			
		||||
	PluginInfo(context.Context, *PluginInfoRequest) (*PluginInfoResponse, error)
 | 
			
		||||
	mustEmbedUnimplementedIntrospectionServer()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -82,6 +95,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) PluginInfo(context.Context, *PluginInfoRequest) (*PluginInfoResponse, error) {
 | 
			
		||||
	return nil, status.Errorf(codes.Unimplemented, "method PluginInfo not implemented")
 | 
			
		||||
}
 | 
			
		||||
func (UnimplementedIntrospectionServer) mustEmbedUnimplementedIntrospectionServer() {}
 | 
			
		||||
 | 
			
		||||
// UnsafeIntrospectionServer may be embedded to opt out of forward compatibility for this service.
 | 
			
		||||
@@ -131,6 +147,24 @@ func _Introspection_Server_Handler(srv interface{}, ctx context.Context, dec fun
 | 
			
		||||
	return interceptor(ctx, in, info, handler)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _Introspection_PluginInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 | 
			
		||||
	in := new(PluginInfoRequest)
 | 
			
		||||
	if err := dec(in); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if interceptor == nil {
 | 
			
		||||
		return srv.(IntrospectionServer).PluginInfo(ctx, in)
 | 
			
		||||
	}
 | 
			
		||||
	info := &grpc.UnaryServerInfo{
 | 
			
		||||
		Server:     srv,
 | 
			
		||||
		FullMethod: "/containerd.services.introspection.v1.Introspection/PluginInfo",
 | 
			
		||||
	}
 | 
			
		||||
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 | 
			
		||||
		return srv.(IntrospectionServer).PluginInfo(ctx, req.(*PluginInfoRequest))
 | 
			
		||||
	}
 | 
			
		||||
	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 +180,10 @@ var Introspection_ServiceDesc = grpc.ServiceDesc{
 | 
			
		||||
			MethodName: "Server",
 | 
			
		||||
			Handler:    _Introspection_Server_Handler,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			MethodName: "PluginInfo",
 | 
			
		||||
			Handler:    _Introspection_PluginInfo_Handler,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	Streams:  []grpc.StreamDesc{},
 | 
			
		||||
	Metadata: "github.com/containerd/containerd/api/services/introspection/v1/introspection.proto",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										375
									
								
								api/types/introspection.pb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								api/types/introspection.pb.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,375 @@
 | 
			
		||||
//
 | 
			
		||||
//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 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_types_introspection_proto_msgTypes[0]
 | 
			
		||||
		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_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 RuntimeRequest.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*RuntimeRequest) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{0}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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[1]
 | 
			
		||||
		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[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 RuntimeVersion.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*RuntimeVersion) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{1}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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[2]
 | 
			
		||||
		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[2]
 | 
			
		||||
	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{2}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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, 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, 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, 4)
 | 
			
		||||
var file_github_com_containerd_containerd_api_types_introspection_proto_goTypes = []interface{}{
 | 
			
		||||
	(*RuntimeRequest)(nil), // 0: containerd.types.RuntimeRequest
 | 
			
		||||
	(*RuntimeVersion)(nil), // 1: containerd.types.RuntimeVersion
 | 
			
		||||
	(*RuntimeInfo)(nil),    // 2: containerd.types.RuntimeInfo
 | 
			
		||||
	nil,                    // 3: containerd.types.RuntimeInfo.AnnotationsEntry
 | 
			
		||||
	(*anypb.Any)(nil),      // 4: google.protobuf.Any
 | 
			
		||||
}
 | 
			
		||||
var file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs = []int32{
 | 
			
		||||
	4, // 0: containerd.types.RuntimeRequest.options:type_name -> google.protobuf.Any
 | 
			
		||||
	1, // 1: containerd.types.RuntimeInfo.version:type_name -> containerd.types.RuntimeVersion
 | 
			
		||||
	4, // 2: containerd.types.RuntimeInfo.options:type_name -> google.protobuf.Any
 | 
			
		||||
	4, // 3: containerd.types.RuntimeInfo.features:type_name -> google.protobuf.Any
 | 
			
		||||
	3, // 4: containerd.types.RuntimeInfo.annotations:type_name -> containerd.types.RuntimeInfo.AnnotationsEntry
 | 
			
		||||
	5, // [5:5] is the sub-list for method output_type
 | 
			
		||||
	5, // [5:5] is the sub-list for method input_type
 | 
			
		||||
	5, // [5:5] is the sub-list for extension type_name
 | 
			
		||||
	5, // [5:5] is the sub-list for extension extendee
 | 
			
		||||
	0, // [0:5] 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.(*RuntimeRequest); 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.(*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[2].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:   4,
 | 
			
		||||
			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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								api/types/introspection.proto
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								api/types/introspection.proto
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
	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 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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<string, string> annotations = 5;
 | 
			
		||||
}
 | 
			
		||||
@@ -58,11 +58,13 @@ import (
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/namespaces"
 | 
			
		||||
	"github.com/containerd/containerd/v2/plugins"
 | 
			
		||||
	"github.com/containerd/containerd/v2/plugins/services/introspection"
 | 
			
		||||
	"github.com/containerd/containerd/v2/protobuf"
 | 
			
		||||
	ptypes "github.com/containerd/containerd/v2/protobuf/types"
 | 
			
		||||
	"github.com/containerd/platforms"
 | 
			
		||||
	"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,76 @@ 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
 | 
			
		||||
	}
 | 
			
		||||
	rr := &apitypes.RuntimeRequest{
 | 
			
		||||
		RuntimePath: rt,
 | 
			
		||||
	}
 | 
			
		||||
	var err error
 | 
			
		||||
	if runtimeOptions != nil {
 | 
			
		||||
		rr.Options, err = protobuf.MarshalAnyToProto(runtimeOptions)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("failed to marshal %T: %w", runtimeOptions, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	options, err := protobuf.MarshalAnyToProto(rr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("failed to marshal runtime requst: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := c.IntrospectionService()
 | 
			
		||||
 | 
			
		||||
	req := &introspectionapi.PluginInfoRequest{
 | 
			
		||||
		Type:    string(plugins.RuntimePluginV2),
 | 
			
		||||
		ID:      "task",
 | 
			
		||||
		Options: options,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := s.PluginInfo(ctx, req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var info apitypes.RuntimeInfo
 | 
			
		||||
	if err := typeurl.UnmarshalTo(resp.Extra, &info); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("failed to get runtime info from plugin info: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var result RuntimeInfo
 | 
			
		||||
	result.Name = info.Name
 | 
			
		||||
	if info.Version != nil {
 | 
			
		||||
		result.Version.Version = info.Version.Version
 | 
			
		||||
		result.Version.Revision = info.Version.Revision
 | 
			
		||||
	}
 | 
			
		||||
	if info.Options != nil {
 | 
			
		||||
		result.Options, err = typeurl.UnmarshalAny(info.Options)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("failed to unmarshal RuntimeInfo.Options (%T): %w", info.Options, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if info.Features != nil {
 | 
			
		||||
		result.Features, err = typeurl.UnmarshalAny(info.Features)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("failed to unmarshal RuntimeInfo.Features (%T): %w", info.Features, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	result.Annotations = info.Annotations
 | 
			
		||||
	return &result, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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/core/mount"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/runtime/v2/shim"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/errdefs"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/namespaces"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/oci"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/schedcore"
 | 
			
		||||
	"github.com/containerd/containerd/v2/protobuf"
 | 
			
		||||
	"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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
 
 | 
			
		||||
@@ -19,10 +19,24 @@
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
 | 
			
		||||
	runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
 | 
			
		||||
	"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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
package plugins
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sort"
 | 
			
		||||
@@ -39,6 +40,7 @@ var Command = cli.Command{
 | 
			
		||||
	Usage:   "Provides information about containerd plugins",
 | 
			
		||||
	Subcommands: []cli.Command{
 | 
			
		||||
		listCommand,
 | 
			
		||||
		inspectRuntimeCommand,
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -162,3 +164,32 @@ func prettyPlatforms(pspb []*types.Platform) string {
 | 
			
		||||
	sort.Stable(sort.StringSlice(ps))
 | 
			
		||||
	return strings.Join(ps, ",")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var inspectRuntimeCommand = cli.Command{
 | 
			
		||||
	Name:      "inspect-runtime",
 | 
			
		||||
	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
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -128,8 +128,9 @@ var Command = cli.Command{
 | 
			
		||||
			Usage: "Enable cni networking for the container",
 | 
			
		||||
		},
 | 
			
		||||
	}, append(platformRunFlags,
 | 
			
		||||
		append(commands.RuntimeFlags,
 | 
			
		||||
			append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...),
 | 
			
		||||
			commands.ContainerFlags...)...)...),
 | 
			
		||||
				commands.ContainerFlags...)...)...)...),
 | 
			
		||||
	Action: func(context *cli.Context) error {
 | 
			
		||||
		var (
 | 
			
		||||
			err error
 | 
			
		||||
 
 | 
			
		||||
@@ -34,10 +34,8 @@ import (
 | 
			
		||||
	"github.com/containerd/containerd/v2/contrib/nvidia"
 | 
			
		||||
	"github.com/containerd/containerd/v2/contrib/seccomp"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/containers"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/snapshots"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/oci"
 | 
			
		||||
	runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
 | 
			
		||||
	"github.com/containerd/log"
 | 
			
		||||
	"github.com/containerd/platforms"
 | 
			
		||||
	"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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<string, string> annotations = 5;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Host Level Shim Configuration
 | 
			
		||||
 | 
			
		||||
containerd does not provide any host level configuration for shims via the API.
 | 
			
		||||
 
 | 
			
		||||
@@ -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/core/runtime/v2/shim"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/errdefs"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/shutdown"
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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/core/containers"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/metadata"
 | 
			
		||||
	"github.com/containerd/containerd/v2/core/runtime"
 | 
			
		||||
@@ -38,6 +40,7 @@ import (
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/timeout"
 | 
			
		||||
	"github.com/containerd/containerd/v2/plugins"
 | 
			
		||||
	"github.com/containerd/containerd/v2/protobuf"
 | 
			
		||||
	"github.com/containerd/containerd/v2/protobuf/proto"
 | 
			
		||||
	"github.com/containerd/log"
 | 
			
		||||
	"github.com/containerd/platforms"
 | 
			
		||||
	"github.com/containerd/plugin"
 | 
			
		||||
@@ -533,3 +536,35 @@ func (m *TaskManager) Delete(ctx context.Context, taskID string) (*runtime.Exit,
 | 
			
		||||
 | 
			
		||||
	return exit, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *TaskManager) PluginInfo(ctx context.Context, request interface{}) (interface{}, error) {
 | 
			
		||||
	req, ok := request.(*apitypes.RuntimeRequest)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, fmt.Errorf("unknown request type %T: %w", request, errdefs.ErrNotImplemented)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	runtimePath, err := m.manager.resolveRuntimePath(req.RuntimePath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("failed to resolve runtime path: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	var optsB []byte
 | 
			
		||||
	if req.Options != nil {
 | 
			
		||||
		optsB, err = proto.Marshal(req.Options)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("failed to marshal %s: %w", req.Options.TypeUrl, 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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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/pkg/events"
 | 
			
		||||
	"github.com/containerd/containerd/v2/pkg/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")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ import (
 | 
			
		||||
type Service interface {
 | 
			
		||||
	Plugins(context.Context, []string) (*api.PluginsResponse, error)
 | 
			
		||||
	Server(context.Context, *ptypes.Empty) (*api.ServerResponse, error)
 | 
			
		||||
	PluginInfo(ctx context.Context, in *api.PluginInfoRequest) (*api.PluginInfoResponse, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type introspectionRemote struct {
 | 
			
		||||
@@ -64,3 +65,13 @@ func (i *introspectionRemote) Server(ctx context.Context, in *ptypes.Empty) (*ap
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (i *introspectionRemote) PluginInfo(ctx context.Context, in *api.PluginInfoRequest) (*api.PluginInfoResponse, error) {
 | 
			
		||||
	resp, err := i.client.PluginInfo(ctx, in)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errdefs.FromGRPC(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ package introspection
 | 
			
		||||
import (
 | 
			
		||||
	context "context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
@@ -41,6 +42,7 @@ import (
 | 
			
		||||
	ptypes "github.com/containerd/containerd/v2/protobuf/types"
 | 
			
		||||
	"github.com/containerd/plugin"
 | 
			
		||||
	"github.com/containerd/plugin/registry"
 | 
			
		||||
	"github.com/containerd/typeurl/v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
@@ -209,9 +211,7 @@ func adaptPlugin(o interface{}) filters.Adaptor {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin {
 | 
			
		||||
	var pluginsPB []*api.Plugin
 | 
			
		||||
	for _, p := range plugins {
 | 
			
		||||
func pluginToPB(p *plugin.Plugin) *api.Plugin {
 | 
			
		||||
	var requires []string
 | 
			
		||||
	for _, r := range p.Registration.Requires {
 | 
			
		||||
		requires = append(requires, r.String())
 | 
			
		||||
@@ -241,7 +241,7 @@ func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		pluginsPB = append(pluginsPB, &api.Plugin{
 | 
			
		||||
	return &api.Plugin{
 | 
			
		||||
		Type:         p.Registration.Type.String(),
 | 
			
		||||
		ID:           p.Registration.ID,
 | 
			
		||||
		Requires:     requires,
 | 
			
		||||
@@ -249,7 +249,13 @@ func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin {
 | 
			
		||||
		Capabilities: p.Meta.Capabilities,
 | 
			
		||||
		Exports:      p.Meta.Exports,
 | 
			
		||||
		InitErr:      initErr,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin {
 | 
			
		||||
	pluginsPB := make([]*api.Plugin, 0, len(plugins))
 | 
			
		||||
	for _, p := range plugins {
 | 
			
		||||
		pluginsPB = append(pluginsPB, pluginToPB(p))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pluginsPB
 | 
			
		||||
@@ -267,3 +273,57 @@ func warningsPB(ctx context.Context, warnings []warning.Warning) []*api.Deprecat
 | 
			
		||||
	}
 | 
			
		||||
	return pb
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type pluginInfoProvider interface {
 | 
			
		||||
	PluginInfo(context.Context, interface{}) (interface{}, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Local) PluginInfo(ctx context.Context, req *api.PluginInfoRequest, _ ...grpc.CallOption) (*api.PluginInfoResponse, error) {
 | 
			
		||||
	p := l.plugins.Get(plugin.Type(req.Type), req.ID)
 | 
			
		||||
	if p == nil {
 | 
			
		||||
		err := fmt.Errorf("plugin %s.%s not found: %w", req.Type, req.ID, errdefs.ErrNotFound)
 | 
			
		||||
		return nil, errdefs.ToGRPC(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp := &api.PluginInfoResponse{
 | 
			
		||||
		Plugin: pluginToPB(p),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Request additional info from plugin instance
 | 
			
		||||
	if req.Options != nil {
 | 
			
		||||
		if p.Err() != nil {
 | 
			
		||||
			err := fmt.Errorf("cannot get extra info, plugin not successfully loaded: %w", errdefs.ErrFailedPrecondition)
 | 
			
		||||
			return resp, errdefs.ToGRPC(err)
 | 
			
		||||
		}
 | 
			
		||||
		inst, err := p.Instance()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			err := fmt.Errorf("failed to get plugin instance: %w", errdefs.ErrFailedPrecondition)
 | 
			
		||||
			return resp, errdefs.ToGRPC(err)
 | 
			
		||||
		}
 | 
			
		||||
		pi, ok := inst.(pluginInfoProvider)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			err := fmt.Errorf("plugin does not provided extra information: %w", errdefs.ErrNotImplemented)
 | 
			
		||||
			return resp, errdefs.ToGRPC(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		options, err := typeurl.UnmarshalAny(req.Options)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			err = fmt.Errorf("failed to unmarshal plugin info Options: %w", err)
 | 
			
		||||
			return resp, errdefs.ToGRPC(err)
 | 
			
		||||
		}
 | 
			
		||||
		info, err := pi.PluginInfo(ctx, options)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return resp, errdefs.ToGRPC(err)
 | 
			
		||||
		}
 | 
			
		||||
		ai, err := typeurl.MarshalAny(info)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			err = fmt.Errorf("failed to marshal plugin info: %w", err)
 | 
			
		||||
			return resp, errdefs.ToGRPC(err)
 | 
			
		||||
		}
 | 
			
		||||
		resp.Extra = &ptypes.Any{
 | 
			
		||||
			TypeUrl: ai.GetTypeUrl(),
 | 
			
		||||
			Value:   ai.GetValue(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -72,3 +72,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) PluginInfo(ctx context.Context, req *api.PluginInfoRequest) (*api.PluginInfoResponse, error) {
 | 
			
		||||
	return s.local.PluginInfo(ctx, req)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user