diff --git a/src/runtime/containerd-shim-v2/errors.go b/src/runtime/containerd-shim-v2/errors.go index 8b94bc82af..d4e33e8c1d 100644 --- a/src/runtime/containerd-shim-v2/errors.go +++ b/src/runtime/containerd-shim-v2/errors.go @@ -60,3 +60,11 @@ func isNotFound(err error) bool { return err == vc.ErrNoSuchContainer || err == syscall.ENOENT || strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "not exist") } + +func isGRPCErrorCode(code codes.Code, err error) bool { + s, ok := status.FromError(err) + if !ok { + return false + } + return s != nil && s.Code() == code +} diff --git a/src/runtime/containerd-shim-v2/errors_test.go b/src/runtime/containerd-shim-v2/errors_test.go index eb5f09d744..e1e90a3e9e 100644 --- a/src/runtime/containerd-shim-v2/errors_test.go +++ b/src/runtime/containerd-shim-v2/errors_test.go @@ -6,11 +6,14 @@ package containerdshim import ( + "errors" "syscall" "testing" vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types" "github.com/stretchr/testify/assert" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) func TestToGRPC(t *testing.T) { @@ -27,3 +30,10 @@ func TestToGRPC(t *testing.T) { assert.True(isGRPCError(err)) } } + +func TestIsGRPCErrorCode(t *testing.T) { + assert := assert.New(t) + + assert.True(isGRPCErrorCode(codes.Unimplemented, status.New(codes.Unimplemented, "foobar").Err())) + assert.False(isGRPCErrorCode(codes.Unimplemented, errors.New("foobar"))) +} diff --git a/src/runtime/containerd-shim-v2/start.go b/src/runtime/containerd-shim-v2/start.go index c257c2504c..afcb327fc8 100644 --- a/src/runtime/containerd-shim-v2/start.go +++ b/src/runtime/containerd-shim-v2/start.go @@ -37,8 +37,9 @@ func startContainer(ctx context.Context, s *service, c *container) error { } go watchSandbox(s) - // Start watching for oom events - go watchOOMEvents(ctx, s) + // We don't rely on the context passed to startContainer as it can be cancelled after + // this rpc call. + go watchOOMEvents(s.ctx, s) } else { _, err := s.sandbox.StartContainer(c.id) if err != nil { diff --git a/src/runtime/containerd-shim-v2/wait.go b/src/runtime/containerd-shim-v2/wait.go index 06da508135..815178bade 100644 --- a/src/runtime/containerd-shim-v2/wait.go +++ b/src/runtime/containerd-shim-v2/wait.go @@ -14,6 +14,7 @@ import ( "github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/mount" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" ) func wait(s *service, c *container, execID string) (int32, error) { @@ -141,7 +142,12 @@ func watchOOMEvents(ctx context.Context, s *service) { default: containerID, err := s.sandbox.GetOOMEvent() if err != nil { - logrus.WithError(err).Warn("failed to get oom event from sandbox") + logrus.WithField("sandbox", s.sandbox.ID()).WithError(err).Warn("failed to get OOM event from sandbox") + // If the GetOOMEvent call is not implemented, then the agent is most likely an older version, + // stop attempting to get OOM events. + if isGRPCErrorCode(codes.Unimplemented, err) { + return + } continue }