Skip to content

Commit 7d2bc06

Browse files
authored
Merge pull request containerd#9911 from dmcgowan/introspection-split
Cleanup introspection interface
2 parents c3dc720 + 1bf781d commit 7d2bc06

File tree

14 files changed

+195
-159
lines changed

14 files changed

+195
-159
lines changed

client/client.go

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
containersapi "github.com/containerd/containerd/v2/api/services/containers/v1"
3030
diffapi "github.com/containerd/containerd/v2/api/services/diff/v1"
3131
imagesapi "github.com/containerd/containerd/v2/api/services/images/v1"
32-
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
3332
leasesapi "github.com/containerd/containerd/v2/api/services/leases/v1"
3433
namespacesapi "github.com/containerd/containerd/v2/api/services/namespaces/v1"
3534
sandboxsapi "github.com/containerd/containerd/v2/api/services/sandbox/v1"
@@ -43,6 +42,8 @@ import (
4342
"github.com/containerd/containerd/v2/core/events"
4443
eventsproxy "github.com/containerd/containerd/v2/core/events/proxy"
4544
"github.com/containerd/containerd/v2/core/images"
45+
"github.com/containerd/containerd/v2/core/introspection"
46+
introspectionproxy "github.com/containerd/containerd/v2/core/introspection/proxy"
4647
"github.com/containerd/containerd/v2/core/leases"
4748
leasesproxy "github.com/containerd/containerd/v2/core/leases/proxy"
4849
"github.com/containerd/containerd/v2/core/remotes"
@@ -55,7 +56,6 @@ import (
5556
"github.com/containerd/containerd/v2/pkg/dialer"
5657
"github.com/containerd/containerd/v2/pkg/namespaces"
5758
"github.com/containerd/containerd/v2/plugins"
58-
"github.com/containerd/containerd/v2/plugins/services/introspection"
5959
"github.com/containerd/containerd/v2/protobuf"
6060
ptypes "github.com/containerd/containerd/v2/protobuf/types"
6161
"github.com/containerd/errdefs"
@@ -680,7 +680,7 @@ func (c *Client) IntrospectionService() introspection.Service {
680680
}
681681
c.connMu.Lock()
682682
defer c.connMu.Unlock()
683-
return introspection.NewIntrospectionServiceFromClient(introspectionapi.NewIntrospectionClient(c.conn))
683+
return introspectionproxy.NewIntrospectionProxy(c.conn)
684684
}
685685

686686
// LeasesService returns the underlying Leases Client
@@ -785,7 +785,7 @@ func (c *Client) Server(ctx context.Context) (ServerInfo, error) {
785785
}
786786
c.connMu.Unlock()
787787

788-
response, err := c.IntrospectionService().Server(ctx, &ptypes.Empty{})
788+
response, err := c.IntrospectionService().Server(ctx)
789789
if err != nil {
790790
return ServerInfo{}, err
791791
}
@@ -831,7 +831,7 @@ func (c *Client) GetSnapshotterSupportedPlatforms(ctx context.Context, snapshott
831831
filters := []string{fmt.Sprintf("type==%s, id==%s", plugins.SnapshotPlugin, snapshotterName)}
832832
in := c.IntrospectionService()
833833

834-
resp, err := in.Plugins(ctx, filters)
834+
resp, err := in.Plugins(ctx, filters...)
835835
if err != nil {
836836
return nil, err
837837
}
@@ -862,7 +862,7 @@ func (c *Client) GetSnapshotterCapabilities(ctx context.Context, snapshotterName
862862
filters := []string{fmt.Sprintf("type==%s, id==%s", plugins.SnapshotPlugin, snapshotterName)}
863863
in := c.IntrospectionService()
864864

865-
resp, err := in.Plugins(ctx, filters)
865+
resp, err := in.Plugins(ctx, filters...)
866866
if err != nil {
867867
return nil, err
868868
}
@@ -903,20 +903,10 @@ func (c *Client) RuntimeInfo(ctx context.Context, runtimePath string, runtimeOpt
903903
return nil, fmt.Errorf("failed to marshal %T: %w", runtimeOptions, err)
904904
}
905905
}
906-
options, err := protobuf.MarshalAnyToProto(rr)
907-
if err != nil {
908-
return nil, fmt.Errorf("failed to marshal runtime requst: %w", err)
909-
}
910906

911907
s := c.IntrospectionService()
912908

913-
req := &introspectionapi.PluginInfoRequest{
914-
Type: string(plugins.RuntimePluginV2),
915-
ID: "task",
916-
Options: options,
917-
}
918-
919-
resp, err := s.PluginInfo(ctx, req)
909+
resp, err := s.PluginInfo(ctx, string(plugins.RuntimePluginV2), "task", rr)
920910
if err != nil {
921911
return nil, err
922912
}

client/install.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ func (c *Client) getInstallPath(ctx context.Context, config InstallConfig) (stri
112112
if config.Path != "" {
113113
return config.Path, nil
114114
}
115-
filters := []string{"id==opt"}
116-
resp, err := c.IntrospectionService().Plugins(ctx, filters)
115+
resp, err := c.IntrospectionService().Plugins(ctx, "id==opt")
117116
if err != nil {
118117
return "", err
119118
}

client/services.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,18 @@ import (
2222
containersapi "github.com/containerd/containerd/v2/api/services/containers/v1"
2323
"github.com/containerd/containerd/v2/api/services/diff/v1"
2424
imagesapi "github.com/containerd/containerd/v2/api/services/images/v1"
25-
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
2625
namespacesapi "github.com/containerd/containerd/v2/api/services/namespaces/v1"
2726
"github.com/containerd/containerd/v2/api/services/tasks/v1"
2827
"github.com/containerd/containerd/v2/core/containers"
2928
"github.com/containerd/containerd/v2/core/content"
3029
"github.com/containerd/containerd/v2/core/images"
30+
"github.com/containerd/containerd/v2/core/introspection"
3131
"github.com/containerd/containerd/v2/core/leases"
3232
"github.com/containerd/containerd/v2/core/sandbox"
3333
"github.com/containerd/containerd/v2/core/snapshots"
3434
"github.com/containerd/containerd/v2/pkg/namespaces"
3535
"github.com/containerd/containerd/v2/plugins"
3636
srv "github.com/containerd/containerd/v2/plugins/services"
37-
"github.com/containerd/containerd/v2/plugins/services/introspection"
3837
"github.com/containerd/plugin"
3938
)
4039

@@ -150,13 +149,6 @@ func WithLeasesService(leasesService leases.Manager) ServicesOpt {
150149
}
151150
}
152151

153-
// WithIntrospectionClient sets the introspection service using an introspection client.
154-
func WithIntrospectionClient(in introspectionapi.IntrospectionClient) ServicesOpt {
155-
return func(s *services) {
156-
s.introspectionService = introspection.NewIntrospectionServiceFromClient(in)
157-
}
158-
}
159-
160152
// WithIntrospectionService sets the introspection service.
161153
func WithIntrospectionService(in introspection.Service) ServicesOpt {
162154
return func(s *services) {
@@ -221,7 +213,7 @@ func WithInMemoryServices(ic *plugin.InitContext) Opt {
221213
return WithNamespaceClient(s.(namespacesapi.NamespacesClient))
222214
},
223215
srv.IntrospectionService: func(s interface{}) ServicesOpt {
224-
return WithIntrospectionClient(s.(introspectionapi.IntrospectionClient))
216+
return WithIntrospectionService(s.(introspection.Service))
225217
},
226218
} {
227219
i := plugins[s]

cmd/ctr/commands/client.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
containerd "github.com/containerd/containerd/v2/client"
2525
"github.com/containerd/containerd/v2/pkg/epoch"
2626
"github.com/containerd/containerd/v2/pkg/namespaces"
27-
ptypes "github.com/containerd/containerd/v2/protobuf/types"
2827
"github.com/containerd/log"
2928
"github.com/urfave/cli/v2"
3029
)
@@ -73,7 +72,7 @@ func NewClient(context *cli.Context, opts ...containerd.Opt) (*containerd.Client
7372
}
7473
}
7574
if !suppressDeprecationWarnings {
76-
resp, err := client.IntrospectionService().Server(ctx, &ptypes.Empty{})
75+
resp, err := client.IntrospectionService().Server(ctx)
7776
if err != nil {
7877
log.L.WithError(err).Warn("Failed to check deprecations")
7978
} else {

cmd/ctr/commands/deprecations/deprecations.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
2828
"github.com/containerd/containerd/v2/cmd/ctr/commands"
2929
"github.com/containerd/containerd/v2/protobuf"
30-
ptypes "github.com/containerd/containerd/v2/protobuf/types"
3130
)
3231

3332
// Command is the parent for all commands under "deprecations"
@@ -56,7 +55,7 @@ var listCommand = &cli.Command{
5655
}
5756
defer cancel()
5857

59-
resp, err := client.IntrospectionService().Server(ctx, &ptypes.Empty{})
58+
resp, err := client.IntrospectionService().Server(ctx)
6059
if err != nil {
6160
return err
6261
}

cmd/ctr/commands/info/info.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package info
1919
import (
2020
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
2121
"github.com/containerd/containerd/v2/cmd/ctr/commands"
22-
ptypes "github.com/containerd/containerd/v2/protobuf/types"
2322
"github.com/urfave/cli/v2"
2423
)
2524

@@ -38,7 +37,7 @@ var Command = &cli.Command{
3837
}
3938
defer cancel()
4039
var info Info
41-
info.Server, err = client.IntrospectionService().Server(ctx, &ptypes.Empty{})
40+
info.Server, err = client.IntrospectionService().Server(ctx)
4241
if err != nil {
4342
return err
4443
}

cmd/ctr/commands/plugins/plugins.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ var listCommand = &cli.Command{
7171
}
7272
defer cancel()
7373
ps := client.IntrospectionService()
74-
response, err := ps.Plugins(ctx, context.Args().Slice())
74+
response, err := ps.Plugins(ctx, context.Args().Slice()...)
7575
if err != nil {
7676
return err
7777
}

core/introspection/introspection.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package introspection
18+
19+
import (
20+
context "context"
21+
22+
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
23+
)
24+
25+
// Service defines the introspection service interface
26+
type Service interface {
27+
Plugins(context.Context, ...string) (*api.PluginsResponse, error)
28+
Server(context.Context) (*api.ServerResponse, error)
29+
PluginInfo(context.Context, string, string, any) (*api.PluginInfoResponse, error)
30+
}

core/introspection/proxy/remote.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package introspectionproxy
18+
19+
import (
20+
"context"
21+
"fmt"
22+
23+
api "github.com/containerd/containerd/v2/api/services/introspection/v1"
24+
"github.com/containerd/containerd/v2/core/introspection"
25+
"github.com/containerd/containerd/v2/protobuf"
26+
"github.com/containerd/errdefs"
27+
"github.com/containerd/log"
28+
"github.com/containerd/ttrpc"
29+
"google.golang.org/grpc"
30+
"google.golang.org/protobuf/types/known/anypb"
31+
"google.golang.org/protobuf/types/known/emptypb"
32+
)
33+
34+
var _ = (introspection.Service)(&introspectionRemote{})
35+
36+
// NewIntrospectionServiceFromClient creates a new introspection service from an API client
37+
func NewIntrospectionProxy(client any) introspection.Service {
38+
switch c := client.(type) {
39+
case api.IntrospectionClient:
40+
return &introspectionRemote{client: convertIntrospection{c}}
41+
case api.TTRPCIntrospectionService:
42+
return &introspectionRemote{client: c}
43+
case grpc.ClientConnInterface:
44+
return &introspectionRemote{client: convertIntrospection{api.NewIntrospectionClient(c)}}
45+
case *ttrpc.Client:
46+
return &introspectionRemote{client: api.NewTTRPCIntrospectionClient(c)}
47+
default:
48+
panic(fmt.Errorf("unsupported introspection client %T: %w", client, errdefs.ErrNotImplemented))
49+
}
50+
}
51+
52+
type introspectionRemote struct {
53+
client api.TTRPCIntrospectionService
54+
}
55+
56+
func (i *introspectionRemote) Plugins(ctx context.Context, filters ...string) (*api.PluginsResponse, error) {
57+
log.G(ctx).WithField("filters", filters).Debug("remote introspection plugin filters")
58+
resp, err := i.client.Plugins(ctx, &api.PluginsRequest{
59+
Filters: filters,
60+
})
61+
62+
if err != nil {
63+
return nil, errdefs.FromGRPC(err)
64+
}
65+
66+
return resp, nil
67+
}
68+
69+
func (i *introspectionRemote) Server(ctx context.Context) (*api.ServerResponse, error) {
70+
resp, err := i.client.Server(ctx, &emptypb.Empty{})
71+
72+
if err != nil {
73+
return nil, errdefs.FromGRPC(err)
74+
}
75+
76+
return resp, nil
77+
}
78+
79+
func (i *introspectionRemote) PluginInfo(ctx context.Context, pluginType, id string, options any) (resp *api.PluginInfoResponse, err error) {
80+
var optionsPB *anypb.Any
81+
if options != nil {
82+
optionsPB, err = protobuf.MarshalAnyToProto(options)
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to marshal runtime requst: %w", err)
85+
}
86+
}
87+
resp, err = i.client.PluginInfo(ctx, &api.PluginInfoRequest{
88+
Type: pluginType,
89+
ID: id,
90+
Options: optionsPB,
91+
})
92+
93+
return resp, errdefs.FromGRPC(err)
94+
}
95+
96+
type convertIntrospection struct {
97+
client api.IntrospectionClient
98+
}
99+
100+
func (c convertIntrospection) Plugins(ctx context.Context, req *api.PluginsRequest) (*api.PluginsResponse, error) {
101+
return c.client.Plugins(ctx, req)
102+
}
103+
func (c convertIntrospection) Server(ctx context.Context, in *emptypb.Empty) (*api.ServerResponse, error) {
104+
return c.client.Server(ctx, in)
105+
}
106+
func (c convertIntrospection) PluginInfo(ctx context.Context, req *api.PluginInfoRequest) (*api.PluginInfoResponse, error) {
107+
return c.client.PluginInfo(ctx, req)
108+
}

internal/cri/server/service.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ import (
3434
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
3535
"k8s.io/kubelet/pkg/cri/streaming"
3636

37-
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
3837
apitypes "github.com/containerd/containerd/v2/api/types"
3938
containerd "github.com/containerd/containerd/v2/client"
39+
"github.com/containerd/containerd/v2/core/introspection"
4040
_ "github.com/containerd/containerd/v2/core/runtime" // for typeurl init
4141
"github.com/containerd/containerd/v2/core/sandbox"
4242
"github.com/containerd/containerd/v2/internal/cri/config"
@@ -54,7 +54,6 @@ import (
5454
"github.com/containerd/containerd/v2/pkg/oci"
5555
osinterface "github.com/containerd/containerd/v2/pkg/os"
5656
"github.com/containerd/containerd/v2/plugins"
57-
"github.com/containerd/containerd/v2/plugins/services/introspection"
5857
"github.com/containerd/containerd/v2/protobuf"
5958
)
6059

@@ -407,10 +406,7 @@ func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service,
407406
plugins.RuntimeRuncV2, r.Type)
408407
// For other runtimes, protobuf.MarshalAnyToProto will cause nil panic during typeurl dereference
409408
}
410-
infoReq := &introspectionapi.PluginInfoRequest{
411-
Type: string(plugins.RuntimePluginV2), // "io.containerd.runtime.v2"
412-
ID: "task",
413-
}
409+
414410
rr := &apitypes.RuntimeRequest{
415411
RuntimePath: r.Type, // "io.containerd.runc.v2"
416412
}
@@ -425,11 +421,8 @@ func introspectRuntimeFeatures(ctx context.Context, intro introspection.Service,
425421
if err != nil {
426422
return nil, fmt.Errorf("failed to marshal %T: %w", options, err)
427423
}
428-
infoReq.Options, err = protobuf.MarshalAnyToProto(rr)
429-
if err != nil {
430-
return nil, fmt.Errorf("failed to marshal %T: %w", rr, err)
431-
}
432-
infoResp, err := intro.PluginInfo(ctx, infoReq)
424+
425+
infoResp, err := intro.PluginInfo(ctx, string(plugins.RuntimePluginV2), "task", rr)
433426
if err != nil {
434427
return nil, fmt.Errorf("failed to call PluginInfo: %w", err)
435428
}

0 commit comments

Comments
 (0)