Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions internal/factory/container/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,53 @@ func (c *container) specAddContainerConfigDevices(enableDeviceOwnershipFromSecur
}

func (c *container) specInjectCDIDevices() error {
// TODO: Once CRI is extended with native CDI support this will need to be updated...
_, names, err := cdi.ParseAnnotations(c.Config().GetAnnotations())
var (
cdiDevices = c.Config().CDIDevices
fromCRI = map[string]struct{}{}
requested = make([]string, 0, len(cdiDevices))
annotated []string
err error
)

// Take CDI devices from the dedicated CDIDevices CRI field.
for _, dev := range cdiDevices {
requested = append(requested, dev.Name)
fromCRI[dev.Name] = struct{}{}
}

// Extract CDI devices from annotations which is still supported as a means
// of injecting CDI devices to give people time to update their DRA drivers.
// TODO(klihub): Change the log message to a warning once annotations are
// deprecated, and to an error once support is removed altogether.
_, annotated, err = cdi.ParseAnnotations(c.Config().GetAnnotations())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we mark them as deprecated for 1.28 and then remove them in 1.29?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we should mark it deprecated. About removing support for it altogether, I think we should go in sync with what @bart0sh is doing on that front in containerd.

if err != nil {
return fmt.Errorf("failed to parse CDI device annotations: %w", err)
}
if names == nil {

// Allow injecting the same device using both a dedicated field and an
// annotation. This helps the transition from annotations to dedicated
// CDI fields. DRA drivers can be updated to first inject devices using
// both. This allows updated drivers to be used in clusters that still
// talk old, pre-CDIDevices CRI. Then once annotations are deprecated
// drivers can be updated to stop using annotations. This also mirrors
// the behavior implemented in containerd.
if len(annotated) > 0 {
for _, name := range annotated {
if _, ok := fromCRI[name]; ok {
// TODO(klihub): change to a warning once annotations are deprecated
log.Infof(context.TODO(),
"Skipping duplicate annotated CDI device %s", name)
continue
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above is a valid warning. Can you add a test case covering this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klihub would you like to handle this as a follow-up?

Copy link
Member

@sohankunkerkar sohankunkerkar Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's handle this in the follow-up PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if it is OK for folks to just get this in and then handle that and anything else that might come up with with a follow-up PR, then I'd be for that, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But let me rebase on latest main and check at the same time if I could add such a test with minimal effort.

requested = append(requested, name)
}
// TODO(klihub): change to a warning once annotations are deprecated
log.Infof(context.TODO(),
"Passing CDI devices as annotations will be deprecated soon "+
"please use the CDIDevices CRI field instead")
}

if len(requested) == 0 {
return nil
}

Expand All @@ -196,7 +237,7 @@ func (c *container) specInjectCDIDevices() error {
log.Warnf(context.TODO(), "CDI registry has errors: %v", err)
}

if _, err := registry.InjectDevices(c.Spec().Config, names...); err != nil {
if _, err := registry.InjectDevices(c.Spec().Config, requested...); err != nil {
return fmt.Errorf("CDI device injection failed: %w", err)
}

Expand Down
98 changes: 97 additions & 1 deletion internal/factory/container/device_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,108 @@ var _ = t.Describe("Container", func() {
type testdata struct {
testDescription string
cdiSpecFiles []string
cdiDevices []*types.CDIDevice
annotations map[string]string
expectError bool
expectDevices []rspec.LinuxDevice
expectEnv []string
}

tests := []testdata{
// test CDI device injection by dedicated CRI CDIDevices field
{
testDescription: "Expect no CDI error for nil CDIDevices",
},
{
testDescription: "Expect no CDI error for empty CDIDevices",
cdiDevices: []*types.CDIDevice{},
},
{
testDescription: "Expect CDI error for invalid CDI device reference in CDIDevices",
cdiDevices: []*types.CDIDevice{
{
Name: "foobar",
},
},
expectError: true,
},
{
testDescription: "Expect CDI error for unresolvable CDIDevices",
cdiDevices: []*types.CDIDevice{
{
Name: "vendor1.com/device=no-such-dev",
},
},
expectError: true,
},
{
testDescription: "Expect properly injected resolvable CDIDevices",
cdiSpecFiles: []string{
`
cdiVersion: "0.3.0"
kind: "vendor1.com/device"
devices:
- name: foo
containerEdits:
deviceNodes:
- path: /dev/loop8
type: b
major: 7
minor: 8
env:
- FOO=injected
containerEdits:
env:
- "VENDOR1=present"
`,
`
cdiVersion: "0.3.0"
kind: "vendor2.com/device"
devices:
- name: bar
containerEdits:
deviceNodes:
- path: /dev/loop9
type: b
major: 7
minor: 9
env:
- BAR=injected
containerEdits:
env:
- "VENDOR2=present"
`,
},
cdiDevices: []*types.CDIDevice{
{
Name: "vendor1.com/device=foo",
},
{
Name: "vendor2.com/device=bar",
},
},
expectDevices: []rspec.LinuxDevice{
{
Path: "/dev/loop8",
Type: "b",
Major: 7,
Minor: 8,
},
{
Path: "/dev/loop9",
Type: "b",
Major: 7,
Minor: 9,
},
},
expectEnv: []string{
"FOO=injected",
"VENDOR1=present",
"BAR=injected",
"VENDOR2=present",
},
},
// test CDI device injection by annotations
{
testDescription: "Expect no CDI error for nil annotations",
},
Expand Down Expand Up @@ -313,7 +408,8 @@ containerEdits:
Linux: &types.LinuxContainerConfig{
SecurityContext: &types.LinuxContainerSecurityContext{},
},
Devices: []*types.Device{},
Devices: []*types.Device{},
CDIDevices: test.cdiDevices,
}
sboxConfig := &types.PodSandboxConfig{
Linux: &types.LinuxPodSandboxConfig{
Expand Down
Loading