api/services/instrospection: add PluginInfo
The new `PlunginInfo()` call can be used for instrospecting the details
of the runtime plugin.
```console
$ ctr plugins inspect-runtime --runtime=io.containerd.runc.v2 --runc-binary=runc
{
    "Name": "io.containerd.runc.v2",
    "Version": {
        "Version": "v2.0.0-beta.0-XX-gXXXXXXXXX.m",
        "Revision": "v2.0.0-beta.0-XX-gXXXXXXXXX.m"
    },
    "Options": {
        "binary_name": "runc"
    },
    "Features": {
        "ociVersionMin": "1.0.0",
        "ociVersionMax": "1.1.0-rc.2",
        ...,
    },
    "Annotations": null
}
```
The shim binary has to support `-info` flag, see `runtime/v2/README.md`
Replaces PR 8509 (`api/services/task: add RuntimeInfo()`)
Co-authored-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
			
			
This commit is contained in:
		| @@ -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 | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Akihiro Suda
					Akihiro Suda