Skip to content

Commit 3e874ab

Browse files
committed
specs-go,cdi: implement NetDevice injection.
Implement OCI Spec (Linux) NetDevice injection. Signed-off-by: Krisztian Litkey <[email protected]>
1 parent 40559a7 commit 3e874ab

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

pkg/cdi/container-edits.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
113113
}
114114
}
115115

116+
if e.NetDevices != nil {
117+
// specgen is currently missing functionality to set Linux NetDevices,
118+
// so we use a locally rolled function for now.
119+
for _, dev := range e.NetDevices {
120+
specgenAddLinuxNetDevice(&specgen, dev.HostIf, &oci.LinuxNetDevice{
121+
Name: dev.Name,
122+
})
123+
}
124+
}
125+
116126
if len(e.Mounts) > 0 {
117127
for _, m := range e.Mounts {
118128
specgen.RemoveMount(m.ContainerPath)
@@ -162,6 +172,14 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
162172
return nil
163173
}
164174

175+
func specgenAddLinuxNetDevice(specgen *ocigen.Generator, hostIf string, netDev *oci.LinuxNetDevice) {
176+
if specgen == nil || netDev == nil {
177+
return
178+
}
179+
ensureLinuxNetDevices(specgen.Config)
180+
specgen.Config.Linux.NetDevices[hostIf] = *netDev
181+
}
182+
165183
// Validate container edits.
166184
func (e *ContainerEdits) Validate() error {
167185
if e == nil || e.ContainerEdits == nil {
@@ -191,6 +209,9 @@ func (e *ContainerEdits) Validate() error {
191209
return err
192210
}
193211
}
212+
if err := ValidateNetDevices(e.NetDevices); err != nil {
213+
return err
214+
}
194215

195216
return nil
196217
}
@@ -210,6 +231,7 @@ func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits {
210231

211232
e.Env = append(e.Env, o.Env...)
212233
e.DeviceNodes = append(e.DeviceNodes, o.DeviceNodes...)
234+
e.NetDevices = append(e.NetDevices, o.NetDevices...)
213235
e.Hooks = append(e.Hooks, o.Hooks...)
214236
e.Mounts = append(e.Mounts, o.Mounts...)
215237
if o.IntelRdt != nil {
@@ -244,6 +266,9 @@ func (e *ContainerEdits) isEmpty() bool {
244266
if e.IntelRdt != nil {
245267
return false
246268
}
269+
if e.NetDevices != nil {
270+
return false
271+
}
247272
return true
248273
}
249274

@@ -257,6 +282,37 @@ func ValidateEnv(env []string) error {
257282
return nil
258283
}
259284

285+
// ValidateNetDevices validates the given net devices.
286+
func ValidateNetDevices(devices []*cdi.NetDevice) error {
287+
var (
288+
hostSeen = map[string]string{}
289+
nameSeen = map[string]string{}
290+
)
291+
292+
for _, dev := range devices {
293+
if dev.HostIf == "" {
294+
return errors.New("invalid net device, empty HostIf")
295+
}
296+
if dev.Name == "" {
297+
return errors.New("invalid net device, empty Name")
298+
}
299+
300+
if other, ok := hostSeen[dev.HostIf]; ok {
301+
return fmt.Errorf("invalid net device, duplicate HostIf %q with names %q and %q",
302+
dev.HostIf, dev.Name, other)
303+
}
304+
hostSeen[dev.HostIf] = dev.Name
305+
306+
if other, ok := nameSeen[dev.Name]; ok {
307+
return fmt.Errorf("invalid net device, duplicate Name %q with HostIf %q and %q",
308+
dev.Name, dev.HostIf, other)
309+
}
310+
nameSeen[dev.Name] = dev.HostIf
311+
}
312+
313+
return nil
314+
}
315+
260316
// DeviceNode is a CDI Spec DeviceNode wrapper, used for validating DeviceNodes.
261317
type DeviceNode struct {
262318
*cdi.DeviceNode
@@ -351,6 +407,16 @@ func ensureOCIHooks(spec *oci.Spec) {
351407
}
352408
}
353409

410+
// Ensure OCI Spec Linux NetDevices map is not nil.
411+
func ensureLinuxNetDevices(spec *oci.Spec) {
412+
if spec.Linux == nil {
413+
spec.Linux = &oci.Linux{}
414+
}
415+
if spec.Linux.NetDevices == nil {
416+
spec.Linux.NetDevices = map[string]oci.LinuxNetDevice{}
417+
}
418+
}
419+
354420
// sortMounts sorts the mounts in the given OCI Spec.
355421
func sortMounts(specgen *ocigen.Generator) {
356422
mounts := specgen.Mounts()

specs-go/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Device struct {
2626
type ContainerEdits struct {
2727
Env []string `json:"env,omitempty" yaml:"env,omitempty"`
2828
DeviceNodes []*DeviceNode `json:"deviceNodes,omitempty" yaml:"deviceNodes,omitempty"`
29+
NetDevices []*NetDevice `json:"netDevices,omitempty" yaml:"netDevices,omitempty"` // Added in v1.1.0
2930
Hooks []*Hook `json:"hooks,omitempty" yaml:"hooks,omitempty"`
3031
Mounts []*Mount `json:"mounts,omitempty" yaml:"mounts,omitempty"`
3132
IntelRdt *IntelRdt `json:"intelRdt,omitempty" yaml:"intelRdt,omitempty"` // Added in v0.7.0
@@ -70,3 +71,9 @@ type IntelRdt struct {
7071
EnableCMT bool `json:"enableCMT,omitempty" yaml:"enableCMT,omitempty"`
7172
EnableMBM bool `json:"enableMBM,omitempty" yaml:"enableMBM,omitempty"`
7273
}
74+
75+
// NetDevice represents an OCI [Linux]NetDevice to be added to the OCI Spec.
76+
type NetDevice struct {
77+
HostIf string `json:"hostIf" yaml:"hostIf"`
78+
Name string `json:"name" yaml:"name"`
79+
}

0 commit comments

Comments
 (0)