mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-07-09 22:24:51 +00:00
runtime: fall back to CDI annotations when kubelet socket is absent
NVIDIA GPU configs default pod_resource_api_sock to the kubelet Pod Resources API path. On non-Kubernetes hosts that path is usually missing; use CDI sandbox annotations for cold-plug instead of failing kubelet lookup. Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com> Assisted-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
||||
@@ -39,12 +40,15 @@ func coldPlugDevices(ctx context.Context, s *service, ociSpec *specs.Spec) error
|
||||
return nil
|
||||
}
|
||||
|
||||
kubeletSock := s.config.PodResourceAPISock
|
||||
if kubeletSock != "" {
|
||||
if kubeletPodResourceSocketAvailable(s.config.PodResourceAPISock) {
|
||||
return coldPlugWithAPI(ctx, s, ociSpec)
|
||||
}
|
||||
|
||||
shimLog.Debug("config.PodResourceAPISock not set, skip k8s based device cold plug")
|
||||
if s.config.PodResourceAPISock != "" {
|
||||
shimLog.Debugf("config.PodResourceAPISock %q not available, fall back to CDI annotations", s.config.PodResourceAPISock)
|
||||
} else {
|
||||
shimLog.Debug("config.PodResourceAPISock not set, use CDI annotations for cold plug")
|
||||
}
|
||||
|
||||
// Here we deal with CDI devices that are cold-plugged
|
||||
// for the single_container (nerdctl, podman, ...) use-case.
|
||||
@@ -58,6 +62,20 @@ func coldPlugDevices(ctx context.Context, s *service, ociSpec *specs.Spec) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// kubeletPodResourceSocketAvailable reports whether the configured kubelet Pod
|
||||
// Resources API socket exists and can be used for Kubernetes-based cold plug.
|
||||
func kubeletPodResourceSocketAvailable(sock string) bool {
|
||||
if sock == "" {
|
||||
return false
|
||||
}
|
||||
fi, err := os.Stat(sock)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return (fi.Mode() & os.ModeSocket) != 0
|
||||
}
|
||||
|
||||
func coldPlugWithAPI(ctx context.Context, s *service, ociSpec *specs.Spec) error {
|
||||
ann := ociSpec.Annotations
|
||||
devices, err := getDeviceSpec(ctx, s.config.PodResourceAPISock, ann)
|
||||
|
||||
36
src/runtime/pkg/containerd-shim-v2/device_cold_plug_test.go
Normal file
36
src/runtime/pkg/containerd-shim-v2/device_cold_plug_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2025 NVIDIA CORPORATION.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package containerdshim
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestKubeletPodResourceSocketAvailable(t *testing.T) {
|
||||
assert.False(t, kubeletPodResourceSocketAvailable(""))
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
sockPath := filepath.Join(tmpDir, "kubelet.sock")
|
||||
assert.False(t, kubeletPodResourceSocketAvailable(sockPath))
|
||||
|
||||
f, err := os.Create(sockPath)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, f.Close())
|
||||
|
||||
assert.False(t, kubeletPodResourceSocketAvailable(sockPath))
|
||||
|
||||
assert.NoError(t, os.Remove(sockPath))
|
||||
l, err := net.Listen("unix", sockPath)
|
||||
assert.NoError(t, err)
|
||||
defer l.Close()
|
||||
|
||||
assert.True(t, kubeletPodResourceSocketAvailable(sockPath))
|
||||
}
|
||||
Reference in New Issue
Block a user