feat: Add GPU CDI support for workspace containers (#332)

* feat: add CDI GPU support for workspace containers

* feat: expose GPU CDI settings in bot container UI

* feat: move GPU settings into advanced container options

* docs: document advanced CDI device configuration
This commit is contained in:
Ming Lin
2026-04-10 14:52:17 +08:00
committed by GitHub
parent 19619d73a9
commit 4d3f2de7e2
22 changed files with 752 additions and 84 deletions
+19
View File
@@ -13,15 +13,18 @@ import (
tasksv1 "github.com/containerd/containerd/api/services/tasks/v1"
tasktypes "github.com/containerd/containerd/api/types/task"
containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/containers"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/core/remotes/docker"
"github.com/containerd/containerd/v2/core/snapshots"
cdispec "github.com/containerd/containerd/v2/pkg/cdi"
"github.com/containerd/containerd/v2/pkg/cio"
"github.com/containerd/containerd/v2/pkg/namespaces"
"github.com/containerd/containerd/v2/pkg/oci"
"github.com/containerd/errdefs"
"github.com/opencontainers/image-spec/identity"
"github.com/opencontainers/runtime-spec/specs-go"
cdi "tags.cncf.io/container-device-interface/pkg/cdi"
"github.com/memohai/memoh/internal/config"
)
@@ -248,10 +251,26 @@ func specOptsFromSpec(spec ContainerSpec) []oci.SpecOpts {
}
opts = append(opts, oci.WithMounts(mounts))
}
if len(spec.CDIDevices) > 0 {
opts = append(opts, withStaticCDIRegistry())
opts = append(opts, cdispec.WithCDIDevices(spec.CDIDevices...))
}
return opts
}
func withStaticCDIRegistry() oci.SpecOpts {
return func(_ context.Context, _ oci.Client, _ *containers.Container, _ *oci.Spec) error {
_ = cdi.Configure(cdi.WithAutoRefresh(false))
if err := cdi.Refresh(); err != nil {
// Invalid specs for other vendors should not block injection of a
// resolvable device set for the current container.
return nil
}
return nil
}
}
func (s *DefaultService) CreateContainer(ctx context.Context, req CreateContainerRequest) (ContainerInfo, error) {
if req.ID == "" || req.ImageRef == "" {
return ContainerInfo{}, ErrInvalidArgument
+3
View File
@@ -161,6 +161,9 @@ func (s *AppleService) CreateContainer(ctx context.Context, req CreateContainerR
if req.ID == "" || req.ImageRef == "" {
return ContainerInfo{}, ErrInvalidArgument
}
if len(req.Spec.CDIDevices) > 0 {
return ContainerInfo{}, ErrNotSupported
}
if err := s.ensureHealthy(ctx); err != nil {
return ContainerInfo{}, err
}
+4 -1
View File
@@ -91,7 +91,10 @@ type ContainerSpec struct {
User string
Mounts []MountSpec
DNS []string
TTY bool
// CDIDevices contains fully-qualified CDI device names such as
// "nvidia.com/gpu=0" or "amd.com/gpu=0".
CDIDevices []string
TTY bool
}
type LayerStatus struct {