mirror of
https://github.com/containerd/containerd.git
synced 2026-08-09 09:33:06 +00:00
server: tolerate failed gRPC plugins when starting listeners
The grpc, grpc-tcp, and ttrpc server plugins enumerated their services
through ic.GetByType, which short-circuits on the first plugin whose
Instance() returned an error. A single failed gRPC plugin (e.g. CRI
under rootless, which cannot watch /etc/cni/net.d) therefore prevented
the server plugins from initialising, leaving /run/containerd/containerd.sock
uncreated.
Iterate the plugin set directly and skip plugins that failed to
initialise, restoring the pre-c15ec2485 behaviour where the listener
is still created and only the failed services are missing.
Fixes: c15ec2485 ("Add server plugins for grpc and ttrpc")
Fixes: https://github.com/containerd/containerd/issues/13362
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
@@ -20,7 +20,6 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -112,12 +111,19 @@ func init() {
|
||||
}
|
||||
|
||||
s := grpc.NewServer(serverOpts...)
|
||||
ps, err := ic.GetByType(plugins.GRPCPlugin) // ensure grpc plugin is initialized
|
||||
if err != nil && !errors.Is(err, plugin.ErrPluginNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range ps {
|
||||
if gs, ok := p.(grpcService); ok {
|
||||
// Iterate plugins directly rather than using GetByType, which
|
||||
// short-circuits on the first plugin that failed to initialize.
|
||||
// Plugins that failed (e.g. CRI under rootless) have already been
|
||||
// logged and should not prevent the GRPC server from starting.
|
||||
for _, p := range ic.Plugins().GetAll() {
|
||||
if p.Registration.Type != plugins.GRPCPlugin {
|
||||
continue
|
||||
}
|
||||
instance, err := p.Instance()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if gs, ok := instance.(grpcService); ok {
|
||||
if err := gs.Register(s); err != nil {
|
||||
return nil, fmt.Errorf("failed to register grpc service: %w", err)
|
||||
}
|
||||
@@ -218,13 +224,18 @@ func init() {
|
||||
}
|
||||
|
||||
s := grpc.NewServer(serverOpts...)
|
||||
ps, err := ic.GetByType(plugins.GRPCPlugin) // ensure grpc plugin is initialized
|
||||
if err != nil && !errors.Is(err, plugin.ErrPluginNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
// Iterate plugins directly rather than using GetByType, which
|
||||
// short-circuits on the first plugin that failed to initialize.
|
||||
var hasService bool
|
||||
for _, p := range ps {
|
||||
if gs, ok := p.(tcpService); ok {
|
||||
for _, p := range ic.Plugins().GetAll() {
|
||||
if p.Registration.Type != plugins.GRPCPlugin {
|
||||
continue
|
||||
}
|
||||
instance, err := p.Instance()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if gs, ok := instance.(tcpService); ok {
|
||||
if err := gs.RegisterTCP(s); err != nil {
|
||||
return nil, fmt.Errorf("failed to register grpc service: %w", err)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package ttrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -75,25 +74,20 @@ func init() {
|
||||
type ttrpcService interface {
|
||||
RegisterTTRPC(*ttrpc.Server) error
|
||||
}
|
||||
// Iterate plugins directly rather than using GetByType, which
|
||||
// short-circuits on the first plugin that failed to initialize.
|
||||
// Plugins that failed (e.g. CRI under rootless) have already been
|
||||
// logged and should not prevent the TTRPC server from starting.
|
||||
var hasService bool
|
||||
ps, err := ic.GetByType(plugins.TTRPCPlugin) // ensure grpc plugin is initialized
|
||||
if err != nil && !errors.Is(err, plugin.ErrPluginNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range ps {
|
||||
if gs, ok := p.(ttrpcService); ok {
|
||||
if err := gs.RegisterTTRPC(s); err != nil {
|
||||
return nil, fmt.Errorf("failed to register ttrpc service: %w", err)
|
||||
}
|
||||
hasService = true
|
||||
for _, p := range ic.Plugins().GetAll() {
|
||||
if p.Registration.Type != plugins.TTRPCPlugin && p.Registration.Type != plugins.GRPCPlugin {
|
||||
continue
|
||||
}
|
||||
}
|
||||
ps, err = ic.GetByType(plugins.GRPCPlugin) // ensure grpc plugin is initialized
|
||||
if err != nil && !errors.Is(err, plugin.ErrPluginNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range ps {
|
||||
if gs, ok := p.(ttrpcService); ok {
|
||||
instance, err := p.Instance()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if gs, ok := instance.(ttrpcService); ok {
|
||||
if err := gs.RegisterTTRPC(s); err != nil {
|
||||
return nil, fmt.Errorf("failed to register ttrpc service: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user