Cleanup introspection interface

Split service proxy from service plugin.
Make introspection service easier for clients to use.
Update service proxy to support grpc and ttrpc.

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan 2024-03-01 23:06:22 -08:00
parent 9a2b85561a
commit 1bf781d8eb
No known key found for this signature in database
GPG Key ID: F58C5D0A4405ACDB
14 changed files with 195 additions and 159 deletions

View File

@ -31,7 +31,6 @@ import (
diffapi "github.com/containerd/containerd/v2/api/services/diff/v1"
eventsapi "github.com/containerd/containerd/v2/api/services/events/v1"
imagesapi "github.com/containerd/containerd/v2/api/services/images/v1"
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
leasesapi "github.com/containerd/containerd/v2/api/services/leases/v1"
namespacesapi "github.com/containerd/containerd/v2/api/services/namespaces/v1"
sandboxsapi "github.com/containerd/containerd/v2/api/services/sandbox/v1"
@ -44,6 +43,8 @@ import (
contentproxy "github.com/containerd/containerd/v2/core/content/proxy"
"github.com/containerd/containerd/v2/core/events"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/core/introspection"
introspectionproxy "github.com/containerd/containerd/v2/core/introspection/proxy"
"github.com/containerd/containerd/v2/core/leases"
leasesproxy "github.com/containerd/containerd/v2/core/leases/proxy"
"github.com/containerd/containerd/v2/core/remotes"
@ -56,7 +57,6 @@ import (
"github.com/containerd/containerd/v2/pkg/dialer"
"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/errdefs"
@ -681,7 +681,7 @@ func (c *Client) IntrospectionService() introspection.Service {
}
c.connMu.Lock()
defer c.connMu.Unlock()
return introspection.NewIntrospectionServiceFromClient(introspectionapi.NewIntrospectionClient(c.conn))
return introspectionproxy.NewIntrospectionProxy(c.conn)
}
// LeasesService returns the underlying Leases Client
@ -785,7 +785,7 @@ func (c *Client) Server(ctx context.Context) (ServerInfo, error) {
}
c.connMu.Unlock()
response, err := c.IntrospectionService().Server(ctx, &ptypes.Empty{})
response, err := c.IntrospectionService().Server(ctx)
if err != nil {
return ServerInfo{}, err
}
@ -831,7 +831,7 @@ func (c *Client) GetSnapshotterSupportedPlatforms(ctx context.Context, snapshott
filters := []string{fmt.Sprintf("type==%s, id==%s", plugins.SnapshotPlugin, snapshotterName)}
in := c.IntrospectionService()
resp, err := in.Plugins(ctx, filters)
resp, err := in.Plugins(ctx, filters...)
if err != nil {
return nil, err
}
@ -862,7 +862,7 @@ func (c *Client) GetSnapshotterCapabilities(ctx context.Context, snapshotterName
filters := []string{fmt.Sprintf("type==%s, id==%s", plugins.SnapshotPlugin, snapshotterName)}
in := c.IntrospectionService()
resp, err := in.Plugins(ctx, filters)
resp, err := in.Plugins(ctx, filters...)
if err != nil {
return nil, err
}
@ -903,20 +903,10 @@ func (c *Client) RuntimeInfo(ctx context.Context, runtimePath string, runtimeOpt
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)
resp, err := s.PluginInfo(ctx, string(plugins.RuntimePluginV2), "task", rr)
if err != nil {
return nil, err
}

View File

@ -112,8 +112,7 @@ func (c *Client) getInstallPath(ctx context.Context, config InstallConfig) (stri
if config.Path != "" {
return config.Path, nil
}
filters := []string{"id==opt"}
resp, err := c.IntrospectionService().Plugins(ctx, filters)
resp, err := c.IntrospectionService().Plugins(ctx, "id==opt")
if err != nil {
return "", err
}

View File

@ -22,19 +22,18 @@ import (
containersapi "github.com/containerd/containerd/v2/api/services/containers/v1"
"github.com/containerd/containerd/v2/api/services/diff/v1"
imagesapi "github.com/containerd/containerd/v2/api/services/images/v1"
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
namespacesapi "github.com/containerd/containerd/v2/api/services/namespaces/v1"
"github.com/containerd/containerd/v2/api/services/tasks/v1"
"github.com/containerd/containerd/v2/core/containers"
"github.com/containerd/containerd/v2/core/content"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/core/introspection"
"github.com/containerd/containerd/v2/core/leases"
"github.com/containerd/containerd/v2/core/sandbox"
"github.com/containerd/containerd/v2/core/snapshots"
"github.com/containerd/containerd/v2/pkg/namespaces"
"github.com/containerd/containerd/v2/plugins"
srv "github.com/containerd/containerd/v2/plugins/services"
"github.com/containerd/containerd/v2/plugins/services/introspection"
"github.com/containerd/plugin"
)
@ -150,13 +149,6 @@ func WithLeasesService(leasesService leases.Manager) ServicesOpt {
}
}
// WithIntrospectionClient sets the introspection service using an introspection client.
func WithIntrospectionClient(in introspectionapi.IntrospectionClient) ServicesOpt {
return func(s *services) {
s.introspectionService = introspection.NewIntrospectionServiceFromClient(in)
}
}
// WithIntrospectionService sets the introspection service.
func WithIntrospectionService(in introspection.Service) ServicesOpt {
return func(s *services) {
@ -221,7 +213,7 @@ func WithInMemoryServices(ic *plugin.InitContext) Opt {
return WithNamespaceClient(s.(namespacesapi.NamespacesClient))
},
srv.IntrospectionService: func(s interface{}) ServicesOpt {
return WithIntrospectionClient(s.(introspectionapi.IntrospectionClient))
return WithIntrospectionService(s.(introspection.Service))
},
} {
i := plugins[s]

View File

@ -24,7 +24,6 @@ import (
containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/pkg/epoch"
"github.com/containerd/containerd/v2/pkg/namespaces"
ptypes "github.com/containerd/containerd/v2/protobuf/types"
"github.com/containerd/log"
"github.com/urfave/cli/v2"
)
@ -73,7 +72,7 @@ func NewClient(context *cli.Context, opts ...containerd.Opt) (*containerd.Client
}
}
if !suppressDeprecationWarnings {
resp, err := client.IntrospectionService().Server(ctx, &ptypes.Empty{})
resp, err := client.IntrospectionService().Server(ctx)
if err != nil {
log.L.WithError(err).Warn("Failed to check deprecations")
} else {

View File

@ -27,7 +27,6 @@ import (
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
"github.com/containerd/containerd/v2/cmd/ctr/commands"
"github.com/containerd/containerd/v2/protobuf"
ptypes "github.com/containerd/containerd/v2/protobuf/types"
)
// Command is the parent for all commands under "deprecations"
@ -56,7 +55,7 @@ var listCommand = &cli.Command{
}
defer cancel()
resp, err := client.IntrospectionService().Server(ctx, &ptypes.Empty{})
resp, err := client.IntrospectionService().Server(ctx)
if err != nil {
return err
}

View File

@ -19,7 +19,6 @@ package info
import (
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
"github.com/containerd/containerd/v2/cmd/ctr/commands"
ptypes "github.com/containerd/containerd/v2/protobuf/types"
"github.com/urfave/cli/v2"
)
@ -38,7 +37,7 @@ var Command = &cli.Command{
}
defer cancel()
var info Info
info.Server, err = client.IntrospectionService().Server(ctx, &ptypes.Empty{})
info.Server, err = client.IntrospectionService().Server(ctx)
if err != nil {
return err
}

View File

@ -71,7 +71,7 @@ var listCommand = &cli.Command{
}
defer cancel()
ps := client.IntrospectionService()
response, err := ps.Plugins(ctx, context.Args().Slice())
response, err := ps.Plugins(ctx, context.Args().Slice()...)
if err != nil {
return err
}

View File

@ -0,0 +1,30 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package introspection
import (
context "context"
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
)
// Service defines the introspection service interface
type Service interface {
Plugins(context.Context, ...string) (*api.PluginsResponse, error)
Server(context.Context) (*api.ServerResponse, error)
PluginInfo(context.Context, string, string, any) (*api.PluginInfoResponse, error)
}

View File

@ -0,0 +1,108 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package introspectionproxy
import (
"context"
"fmt"
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
"github.com/containerd/containerd/v2/core/introspection"
"github.com/containerd/containerd/v2/protobuf"
"github.com/containerd/errdefs"
"github.com/containerd/log"
"github.com/containerd/ttrpc"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/emptypb"
)
var _ = (introspection.Service)(&introspectionRemote{})
// NewIntrospectionServiceFromClient creates a new introspection service from an API client
func NewIntrospectionProxy(client any) introspection.Service {
switch c := client.(type) {
case api.IntrospectionClient:
return &introspectionRemote{client: convertIntrospection{c}}
case api.TTRPCIntrospectionService:
return &introspectionRemote{client: c}
case grpc.ClientConnInterface:
return &introspectionRemote{client: convertIntrospection{api.NewIntrospectionClient(c)}}
case *ttrpc.Client:
return &introspectionRemote{client: api.NewTTRPCIntrospectionClient(c)}
default:
panic(fmt.Errorf("unsupported introspection client %T: %w", client, errdefs.ErrNotImplemented))
}
}
type introspectionRemote struct {
client api.TTRPCIntrospectionService
}
func (i *introspectionRemote) Plugins(ctx context.Context, filters ...string) (*api.PluginsResponse, error) {
log.G(ctx).WithField("filters", filters).Debug("remote introspection plugin filters")
resp, err := i.client.Plugins(ctx, &api.PluginsRequest{
Filters: filters,
})
if err != nil {
return nil, errdefs.FromGRPC(err)
}
return resp, nil
}
func (i *introspectionRemote) Server(ctx context.Context) (*api.ServerResponse, error) {
resp, err := i.client.Server(ctx, &emptypb.Empty{})
if err != nil {
return nil, errdefs.FromGRPC(err)
}
return resp, nil
}
func (i *introspectionRemote) PluginInfo(ctx context.Context, pluginType, id string, options any) (resp *api.PluginInfoResponse, err error) {
var optionsPB *anypb.Any
if options != nil {
optionsPB, err = protobuf.MarshalAnyToProto(options)
if err != nil {
return nil, fmt.Errorf("failed to marshal runtime requst: %w", err)
}
}
resp, err = i.client.PluginInfo(ctx, &api.PluginInfoRequest{
Type: pluginType,
ID: id,
Options: optionsPB,
})
return resp, errdefs.FromGRPC(err)
}
type convertIntrospection struct {
client api.IntrospectionClient
}
func (c convertIntrospection) Plugins(ctx context.Context, req *api.PluginsRequest) (*api.PluginsResponse, error) {
return c.client.Plugins(ctx, req)
}
func (c convertIntrospection) Server(ctx context.Context, in *emptypb.Empty) (*api.ServerResponse, error) {
return c.client.Server(ctx, in)
}
func (c convertIntrospection) PluginInfo(ctx context.Context, req *api.PluginInfoRequest) (*api.PluginInfoResponse, error) {
return c.client.PluginInfo(ctx, req)
}

View File

@ -34,9 +34,9 @@ import (
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
"k8s.io/kubelet/pkg/cri/streaming"
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
apitypes "github.com/containerd/containerd/v2/api/types"
containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/introspection"
_ "github.com/containerd/containerd/v2/core/runtime" // for typeurl init
"github.com/containerd/containerd/v2/core/sandbox"
"github.com/containerd/containerd/v2/internal/cri/config"
@ -54,7 +54,6 @@ import (
"github.com/containerd/containerd/v2/pkg/oci"
osinterface "github.com/containerd/containerd/v2/pkg/os"
"github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/services/introspection"
"github.com/containerd/containerd/v2/protobuf"
)
@ -407,10 +406,7 @@ func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service,
plugins.RuntimeRuncV2, r.Type)
// For other runtimes, protobuf.MarshalAnyToProto will cause nil panic during typeurl dereference
}
infoReq := &introspectionapi.PluginInfoRequest{
Type: string(plugins.RuntimePluginV2), // "io.containerd.runtime.v2"
ID: "task",
}
rr := &apitypes.RuntimeRequest{
RuntimePath: r.Type, // "io.containerd.runc.v2"
}
@ -425,11 +421,8 @@ func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service,
if err != nil {
return nil, fmt.Errorf("failed to marshal %T: %w", options, err)
}
infoReq.Options, err = protobuf.MarshalAnyToProto(rr)
if err != nil {
return nil, fmt.Errorf("failed to marshal %T: %w", rr, err)
}
infoResp, err := intro.PluginInfo(ctx, infoReq)
infoResp, err := intro.PluginInfo(ctx, string(plugins.RuntimePluginV2), "task", rr)
if err != nil {
return nil, fmt.Errorf("failed to call PluginInfo: %w", err)
}

View File

@ -23,7 +23,6 @@ import (
goruntime "runtime"
"github.com/containerd/containerd/v2/api/services/introspection/v1"
ptypes "github.com/containerd/containerd/v2/protobuf/types"
"github.com/containerd/log"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
)
@ -97,7 +96,7 @@ func (c *criService) Status(ctx context.Context, r *runtime.StatusRequest) (*run
}
resp.Info["lastCNILoadStatus"] = defaultStatus
}
intro, err := c.client.IntrospectionService().Server(ctx, &ptypes.Empty{})
intro, err := c.client.IntrospectionService().Server(ctx)
if err != nil {
return nil, err
}

View File

@ -1,77 +0,0 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package introspection
import (
context "context"
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
ptypes "github.com/containerd/containerd/v2/protobuf/types"
"github.com/containerd/errdefs"
"github.com/containerd/log"
)
// Service defines the introspection service interface
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 {
client api.IntrospectionClient
}
var _ = (Service)(&introspectionRemote{})
// NewIntrospectionServiceFromClient creates a new introspection service from an API client
func NewIntrospectionServiceFromClient(c api.IntrospectionClient) Service {
return &introspectionRemote{client: c}
}
func (i *introspectionRemote) Plugins(ctx context.Context, filters []string) (*api.PluginsResponse, error) {
log.G(ctx).WithField("filters", filters).Debug("remote introspection plugin filters")
resp, err := i.client.Plugins(ctx, &api.PluginsRequest{
Filters: filters,
})
if err != nil {
return nil, errdefs.FromGRPC(err)
}
return resp, nil
}
func (i *introspectionRemote) Server(ctx context.Context, in *ptypes.Empty) (*api.ServerResponse, error) {
resp, err := i.client.Server(ctx, in)
if err != nil {
return nil, errdefs.FromGRPC(err)
}
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
}

View File

@ -28,11 +28,11 @@ import (
"github.com/google/uuid"
"google.golang.org/genproto/googleapis/rpc/code"
rpc "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc"
"google.golang.org/grpc/status"
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
"github.com/containerd/containerd/v2/api/types"
"github.com/containerd/containerd/v2/core/introspection"
"github.com/containerd/containerd/v2/pkg/filters"
"github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/services"
@ -80,7 +80,7 @@ type Local struct {
warningClient warning.Service
}
var _ = (api.IntrospectionClient)(&Local{})
var _ = (introspection.Service)(&Local{})
// UpdateLocal updates the local introspection service
func (l *Local) UpdateLocal(root string) {
@ -90,10 +90,10 @@ func (l *Local) UpdateLocal(root string) {
}
// Plugins returns the locally defined plugins
func (l *Local) Plugins(ctx context.Context, req *api.PluginsRequest, _ ...grpc.CallOption) (*api.PluginsResponse, error) {
filter, err := filters.ParseAll(req.Filters...)
func (l *Local) Plugins(ctx context.Context, fs ...string) (*api.PluginsResponse, error) {
filter, err := filters.ParseAll(fs...)
if err != nil {
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, err.Error())
return nil, fmt.Errorf("%w: %w", errdefs.ErrInvalidArgument, err)
}
var plugins []*api.Plugin
@ -121,17 +121,17 @@ func (l *Local) getPlugins() []*api.Plugin {
}
// Server returns the local server information
func (l *Local) Server(ctx context.Context, _ *ptypes.Empty, _ ...grpc.CallOption) (*api.ServerResponse, error) {
func (l *Local) Server(ctx context.Context) (*api.ServerResponse, error) {
u, err := l.getUUID()
if err != nil {
return nil, errdefs.ToGRPC(err)
return nil, err
}
pid := os.Getpid()
var pidns uint64
if runtime.GOOS == "linux" {
pidns, err = statPIDNS(pid)
if err != nil {
return nil, errdefs.ToGRPC(err)
return nil, err
}
}
return &api.ServerResponse{
@ -278,11 +278,10 @@ 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)
func (l *Local) PluginInfo(ctx context.Context, pluginType, id string, options any) (*api.PluginInfoResponse, error) {
p := l.plugins.Get(plugin.Type(pluginType), id)
if p == nil {
err := fmt.Errorf("plugin %s.%s not found: %w", req.Type, req.ID, errdefs.ErrNotFound)
return nil, errdefs.ToGRPC(err)
return nil, fmt.Errorf("plugin %s.%s not found: %w", pluginType, id, errdefs.ErrNotFound)
}
resp := &api.PluginInfoResponse{
@ -290,35 +289,26 @@ func (l *Local) PluginInfo(ctx context.Context, req *api.PluginInfoRequest, _ ..
}
// Request additional info from plugin instance
if req.Options != nil {
if 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)
return resp, fmt.Errorf("cannot get extra info, plugin not successfully loaded: %w", errdefs.ErrFailedPrecondition)
}
inst, err := p.Instance()
if err != nil {
err := fmt.Errorf("failed to get plugin instance: %w", errdefs.ErrFailedPrecondition)
return resp, errdefs.ToGRPC(err)
return resp, fmt.Errorf("failed to get plugin instance: %w", errdefs.ErrFailedPrecondition)
}
pi, ok := inst.(pluginInfoProvider)
if !ok {
err := fmt.Errorf("plugin does not provided extra information: %w", errdefs.ErrNotImplemented)
return resp, errdefs.ToGRPC(err)
return resp, fmt.Errorf("plugin does not provided extra information: %w", errdefs.ErrNotImplemented)
}
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)
return resp, fmt.Errorf("failed to marshal plugin info: %w", err)
}
resp.Extra = &ptypes.Any{
TypeUrl: ai.GetTypeUrl(),

View File

@ -19,13 +19,17 @@ package introspection
import (
context "context"
"errors"
"fmt"
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
"github.com/containerd/containerd/v2/core/introspection"
"github.com/containerd/containerd/v2/plugins"
"github.com/containerd/containerd/v2/plugins/services"
ptypes "github.com/containerd/containerd/v2/protobuf/types"
"github.com/containerd/errdefs"
"github.com/containerd/plugin"
"github.com/containerd/plugin/registry"
"github.com/containerd/typeurl/v2"
"google.golang.org/grpc"
)
@ -54,7 +58,7 @@ func init() {
}
type server struct {
local api.IntrospectionClient
local introspection.Service
api.UnimplementedIntrospectionServer
}
@ -65,14 +69,25 @@ func (s *server) Register(server *grpc.Server) error {
return nil
}
func (s *server) Plugins(ctx context.Context, req *api.PluginsRequest) (*api.PluginsResponse, error) {
return s.local.Plugins(ctx, req)
func (s *server) Plugins(ctx context.Context, req *api.PluginsRequest) (resp *api.PluginsResponse, err error) {
resp, err = s.local.Plugins(ctx, req.Filters...)
return resp, errdefs.ToGRPC(err)
}
func (s *server) Server(ctx context.Context, empty *ptypes.Empty) (*api.ServerResponse, error) {
return s.local.Server(ctx, empty)
func (s *server) Server(ctx context.Context, _ *ptypes.Empty) (resp *api.ServerResponse, err error) {
resp, err = s.local.Server(ctx)
return resp, errdefs.ToGRPC(err)
}
func (s *server) PluginInfo(ctx context.Context, req *api.PluginInfoRequest) (*api.PluginInfoResponse, error) {
return s.local.PluginInfo(ctx, req)
func (s *server) PluginInfo(ctx context.Context, req *api.PluginInfoRequest) (resp *api.PluginInfoResponse, err error) {
var options any
if req.Options != nil {
options, err = typeurl.UnmarshalAny(req.Options)
if err != nil {
return resp, errdefs.ToGRPC(fmt.Errorf("failed to unmarshal plugin info Options: %w", err))
}
}
resp, err = s.local.PluginInfo(ctx, req.Type, req.ID, options)
return resp, errdefs.ToGRPC(err)
}