Merge pull request #7419 from bart0sh/PR005-configure-CDI-registry-on-start
This commit is contained in:
@@ -28,6 +28,7 @@ import (
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
@@ -729,3 +730,39 @@ func GetUTSNamespace(pid uint32) string {
|
||||
func GetPIDNamespace(pid uint32) string {
|
||||
return fmt.Sprintf(pidNSFormat, pid)
|
||||
}
|
||||
|
||||
// WithCDI updates OCI spec with CDI content
|
||||
func WithCDI(annotations map[string]string) oci.SpecOpts {
|
||||
return func(ctx context.Context, _ oci.Client, c *containers.Container, s *oci.Spec) error {
|
||||
// TODO: Once CRI is extended with native CDI support this will need to be updated...
|
||||
_, cdiDevices, err := cdi.ParseAnnotations(annotations)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse CDI device annotations: %w", err)
|
||||
}
|
||||
if cdiDevices == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.G(ctx).Infof("container %v: CDI devices: %v", c.ID, cdiDevices)
|
||||
|
||||
registry := cdi.GetRegistry()
|
||||
if err = registry.Refresh(); err != nil {
|
||||
// We don't consider registry refresh failure a fatal error.
|
||||
// For instance, a dynamically generated invalid CDI Spec file for
|
||||
// any particular vendor shouldn't prevent injection of devices of
|
||||
// different vendors. CDI itself knows better and it will fail the
|
||||
// injection if necessary.
|
||||
log.G(ctx).Warnf("CDI registry refresh failed: %v", err)
|
||||
}
|
||||
|
||||
if _, err := registry.InjectDevices(s, cdiDevices...); err != nil {
|
||||
return fmt.Errorf("CDI device injection failed: %w", err)
|
||||
}
|
||||
|
||||
// One crucial thing to keep in mind is that CDI device injection
|
||||
// might add OCI Spec environment variables, hooks, and mounts as
|
||||
// well. Therefore it is important that none of the corresponding
|
||||
// OCI Spec fields are reset up in the call stack once we return.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageCon
|
||||
specOpts = append(specOpts, seccompSpecOpts)
|
||||
}
|
||||
if c.config.EnableCDI {
|
||||
specOpts = append(specOpts, oci.WithCDI(config.Annotations, c.config.CDISpecDirs))
|
||||
specOpts = append(specOpts, customopts.WithCDI(config.Annotations))
|
||||
}
|
||||
return specOpts, nil
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"github.com/containerd/containerd/pkg/cri/annotations"
|
||||
"github.com/containerd/containerd/pkg/cri/config"
|
||||
"github.com/containerd/containerd/pkg/cri/opts"
|
||||
customopts "github.com/containerd/containerd/pkg/cri/opts"
|
||||
"github.com/containerd/containerd/pkg/cri/util"
|
||||
ctrdutil "github.com/containerd/containerd/pkg/cri/util"
|
||||
ostesting "github.com/containerd/containerd/pkg/os/testing"
|
||||
@@ -1547,6 +1548,8 @@ func TestCDIInjections(t *testing.T) {
|
||||
containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
|
||||
ociRuntime := config.Runtime{}
|
||||
c := newTestCRIService()
|
||||
testContainer := &containers.Container{ID: "64ddfe361f0099f8d59075398feeb3dcb3863b6851df7b946744755066c03e9d"}
|
||||
ctx := context.Background()
|
||||
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
@@ -1647,8 +1650,12 @@ containerEdits:
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
injectFun := oci.WithCDI(test.annotations, []string{cdiDir})
|
||||
err = injectFun(nil, nil, nil, spec)
|
||||
reg := cdi.GetRegistry()
|
||||
err = reg.Configure(cdi.WithSpecDirs(cdiDir))
|
||||
require.NoError(t, err)
|
||||
|
||||
injectFun := customopts.WithCDI(test.annotations)
|
||||
err = injectFun(ctx, nil, testContainer, spec)
|
||||
assert.Equal(t, test.expectError, err != nil)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -19,6 +19,7 @@ package sbserver
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||
"github.com/containerd/containerd/pkg/cap"
|
||||
"github.com/containerd/containerd/pkg/userns"
|
||||
"github.com/containerd/go-cni"
|
||||
@@ -87,6 +88,14 @@ func (c *criService) initPlatform() (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if c.config.EnableCDI {
|
||||
reg := cdi.GetRegistry()
|
||||
err = reg.Configure(cdi.WithSpecDirs(c.config.CDISpecDirs...))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to configure CDI registry")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageCon
|
||||
specOpts = append(specOpts, seccompSpecOpts)
|
||||
}
|
||||
if c.config.EnableCDI {
|
||||
specOpts = append(specOpts, oci.WithCDI(config.Annotations, c.config.CDISpecDirs))
|
||||
specOpts = append(specOpts, customopts.WithCDI(config.Annotations))
|
||||
}
|
||||
return specOpts, nil
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"github.com/containerd/containerd/pkg/cri/annotations"
|
||||
"github.com/containerd/containerd/pkg/cri/config"
|
||||
"github.com/containerd/containerd/pkg/cri/opts"
|
||||
customopts "github.com/containerd/containerd/pkg/cri/opts"
|
||||
"github.com/containerd/containerd/pkg/cri/util"
|
||||
ctrdutil "github.com/containerd/containerd/pkg/cri/util"
|
||||
ostesting "github.com/containerd/containerd/pkg/os/testing"
|
||||
@@ -1547,6 +1548,8 @@ func TestCDIInjections(t *testing.T) {
|
||||
containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
|
||||
ociRuntime := config.Runtime{}
|
||||
c := newTestCRIService()
|
||||
testContainer := &containers.Container{ID: "64ddfe361f0099f8d59075398feeb3dcb3863b6851df7b946744755066c03e9d"}
|
||||
ctx := context.Background()
|
||||
|
||||
for _, test := range []struct {
|
||||
description string
|
||||
@@ -1647,8 +1650,12 @@ containerEdits:
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
injectFun := oci.WithCDI(test.annotations, []string{cdiDir})
|
||||
err = injectFun(nil, nil, nil, spec)
|
||||
reg := cdi.GetRegistry()
|
||||
err = reg.Configure(cdi.WithSpecDirs(cdiDir))
|
||||
require.NoError(t, err)
|
||||
|
||||
injectFun := customopts.WithCDI(test.annotations)
|
||||
err = injectFun(ctx, nil, testContainer, spec)
|
||||
assert.Equal(t, test.expectError, err != nil)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -19,6 +19,7 @@ package server
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||
"github.com/containerd/containerd/pkg/cap"
|
||||
"github.com/containerd/containerd/pkg/userns"
|
||||
cni "github.com/containerd/go-cni"
|
||||
@@ -87,6 +88,14 @@ func (c *criService) initPlatform() (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if c.config.EnableCDI {
|
||||
reg := cdi.GetRegistry()
|
||||
err = reg.Configure(cdi.WithSpecDirs(c.config.CDISpecDirs...))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to configure CDI registry")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user