From 0c5a6a35986eee2ac5195792d41d83c57419c136 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 08:17:01 +0000 Subject: [PATCH] Bump tags.cncf.io/container-device-interface Bumps [tags.cncf.io/container-device-interface](https://github.com/cncf-tags/container-device-interface) from 1.0.2-0.20251114135136-1b24d969689f to 1.1.0. - [Release notes](https://github.com/cncf-tags/container-device-interface/releases) - [Changelog](https://github.com/cncf-tags/container-device-interface/blob/main/RELEASE.md) - [Commits](https://github.com/cncf-tags/container-device-interface/commits/v1.1.0) --- updated-dependencies: - dependency-name: tags.cncf.io/container-device-interface dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 +- go.sum | 8 +- vendor/modules.txt | 4 +- .../pkg/cdi/container-edits.go | 76 ++++++++++++++++++ .../pkg/cdi/container-edits_unix.go | 80 +++++++++++++++---- .../container-device-interface/pkg/cdi/oci.go | 15 +++- .../specs-go/config.go | 29 ++++--- .../specs-go/version.go | 31 ++++++- 8 files changed, 207 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index faa246d6e..47f87b6c6 100644 --- a/go.mod +++ b/go.mod @@ -19,8 +19,8 @@ require ( github.com/urfave/cli/v3 v3.6.1 golang.org/x/mod v0.31.0 golang.org/x/sys v0.39.0 - tags.cncf.io/container-device-interface v1.0.2-0.20251114135136-1b24d969689f - tags.cncf.io/container-device-interface/specs-go v1.0.0 + tags.cncf.io/container-device-interface v1.1.0 + tags.cncf.io/container-device-interface/specs-go v1.1.0 ) require ( diff --git a/go.sum b/go.sum index 524a90a8b..0f0143361 100644 --- a/go.sum +++ b/go.sum @@ -87,7 +87,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -tags.cncf.io/container-device-interface v1.0.2-0.20251114135136-1b24d969689f h1:5kGvyig0u//IrA7XOluYjeElgVHtKkZLoYWjKfBXfls= -tags.cncf.io/container-device-interface v1.0.2-0.20251114135136-1b24d969689f/go.mod h1:kIlIMADdgOVbyLj4ZvEtCvHXqFXqxfbVKKKgBZt8NgQ= -tags.cncf.io/container-device-interface/specs-go v1.0.0 h1:8gLw29hH1ZQP9K1YtAzpvkHCjjyIxHZYzBAvlQ+0vD8= -tags.cncf.io/container-device-interface/specs-go v1.0.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ= +tags.cncf.io/container-device-interface v1.1.0 h1:RnxNhxF1JOu6CJUVpetTYvrXHdxw9j9jFYgZpI+anSY= +tags.cncf.io/container-device-interface v1.1.0/go.mod h1:76Oj0Yqp9FwTx/pySDc8Bxjpg+VqXfDb50cKAXVJ34Q= +tags.cncf.io/container-device-interface/specs-go v1.1.0 h1:QRZVeAceQM+zTZe12eyfuJuuzp524EKYwhmvLd+h+yQ= +tags.cncf.io/container-device-interface/specs-go v1.1.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ= diff --git a/vendor/modules.txt b/vendor/modules.txt index 252af8b18..bae2ade7b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -121,12 +121,12 @@ gopkg.in/yaml.v3 ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 -# tags.cncf.io/container-device-interface v1.0.2-0.20251114135136-1b24d969689f +# tags.cncf.io/container-device-interface v1.1.0 ## explicit; go 1.21 tags.cncf.io/container-device-interface/internal/validation tags.cncf.io/container-device-interface/internal/validation/k8s tags.cncf.io/container-device-interface/pkg/cdi tags.cncf.io/container-device-interface/pkg/parser -# tags.cncf.io/container-device-interface/specs-go v1.0.0 +# tags.cncf.io/container-device-interface/specs-go v1.1.0 ## explicit; go 1.19 tags.cncf.io/container-device-interface/specs-go diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go index 450a84f69..f498049c6 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go @@ -113,6 +113,14 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error { } } + if len(e.NetDevices) > 0 { + // specgen is currently missing functionality to set Linux NetDevices, + // so we use a locally rolled function for now. + for _, dev := range e.NetDevices { + specgenAddLinuxNetDevice(&specgen, dev.HostInterfaceName, (&LinuxNetDevice{dev}).toOCI()) + } + } + if len(e.Mounts) > 0 { for _, m := range e.Mounts { specgen.RemoveMount(m.ContainerPath) @@ -162,6 +170,24 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error { return nil } +func specgenAddLinuxNetDevice(specgen *ocigen.Generator, hostIf string, netDev *oci.LinuxNetDevice) { + if specgen == nil || netDev == nil { + return + } + ensureLinuxNetDevices(specgen.Config) + specgen.Config.Linux.NetDevices[hostIf] = *netDev +} + +// Ensure OCI Spec Linux NetDevices map is not nil. +func ensureLinuxNetDevices(spec *oci.Spec) { + if spec.Linux == nil { + spec.Linux = &oci.Linux{} + } + if spec.Linux.NetDevices == nil { + spec.Linux.NetDevices = map[string]oci.LinuxNetDevice{} + } +} + // Validate container edits. func (e *ContainerEdits) Validate() error { if e == nil || e.ContainerEdits == nil { @@ -191,6 +217,9 @@ func (e *ContainerEdits) Validate() error { return err } } + if err := ValidateNetDevices(e.NetDevices); err != nil { + return err + } return nil } @@ -210,6 +239,7 @@ func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits { e.Env = append(e.Env, o.Env...) e.DeviceNodes = append(e.DeviceNodes, o.DeviceNodes...) + e.NetDevices = append(e.NetDevices, o.NetDevices...) e.Hooks = append(e.Hooks, o.Hooks...) e.Mounts = append(e.Mounts, o.Mounts...) if o.IntelRdt != nil { @@ -244,6 +274,9 @@ func (e *ContainerEdits) isEmpty() bool { if e.IntelRdt != nil { return false } + if len(e.NetDevices) > 0 { + return false + } return true } @@ -257,6 +290,49 @@ func ValidateEnv(env []string) error { return nil } +// ValidateNetDevices validates the given net devices. +func ValidateNetDevices(devices []*cdi.LinuxNetDevice) error { + var ( + hostSeen = map[string]string{} + nameSeen = map[string]string{} + ) + + for _, dev := range devices { + if err := (&LinuxNetDevice{dev}).Validate(); err != nil { + return err + } + if other, ok := hostSeen[dev.HostInterfaceName]; ok { + return fmt.Errorf("invalid linux net device, duplicate HostInterfaceName %q with names %q and %q", + dev.HostInterfaceName, dev.Name, other) + } + hostSeen[dev.HostInterfaceName] = dev.Name + + if other, ok := nameSeen[dev.Name]; ok { + return fmt.Errorf("invalid linux net device, duplicate Name %q with HostInterfaceName %q and %q", + dev.Name, dev.HostInterfaceName, other) + } + nameSeen[dev.Name] = dev.HostInterfaceName + } + + return nil +} + +// LinuxNetDevice is a CDI Spec LinuxNetDevice wrapper, used for OCI conversion and validating. +type LinuxNetDevice struct { + *cdi.LinuxNetDevice +} + +// Validate LinuxNetDevice. +func (d *LinuxNetDevice) Validate() error { + if d.HostInterfaceName == "" { + return errors.New("invalid linux net device, empty HostInterfaceName") + } + if d.Name == "" { + return errors.New("invalid linux net device, empty Name") + } + return nil +} + // DeviceNode is a CDI Spec DeviceNode wrapper, used for validating DeviceNodes. type DeviceNode struct { *cdi.DeviceNode diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits_unix.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits_unix.go index e0d41a681..a84097809 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits_unix.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits_unix.go @@ -21,6 +21,7 @@ package cdi import ( "errors" "fmt" + "os" "golang.org/x/sys/unix" ) @@ -31,16 +32,28 @@ const ( fifoDevice = "p" ) +type deviceInfo struct { + // cgroup properties + deviceType string + major int64 + minor int64 + + // device node properties + fileMode os.FileMode +} + // deviceInfoFromPath takes the path to a device and returns its type, // major and minor device numbers. // // It was adapted from https://github.com/opencontainers/runc/blob/v1.1.9/libcontainer/devices/device_unix.go#L30-L69 -func deviceInfoFromPath(path string) (devType string, major, minor int64, _ error) { +func deviceInfoFromPath(path string) (*deviceInfo, error) { var stat unix.Stat_t err := unix.Lstat(path, &stat) if err != nil { - return "", 0, 0, err + return nil, err } + + var devType string switch stat.Mode & unix.S_IFMT { case unix.S_IFBLK: devType = blockDevice @@ -49,38 +62,71 @@ func deviceInfoFromPath(path string) (devType string, major, minor int64, _ erro case unix.S_IFIFO: devType = fifoDevice default: - return "", 0, 0, errors.New("not a device node") + return nil, errors.New("not a device node") } devNumber := uint64(stat.Rdev) //nolint:unconvert // Rdev is uint32 on e.g. MIPS. - return devType, int64(unix.Major(devNumber)), int64(unix.Minor(devNumber)), nil + + di := deviceInfo{ + deviceType: devType, + major: int64(unix.Major(devNumber)), + minor: int64(unix.Minor(devNumber)), + fileMode: os.FileMode(stat.Mode &^ unix.S_IFMT), + } + + return &di, nil } // fillMissingInfo fills in missing mandatory attributes from the host device. func (d *DeviceNode) fillMissingInfo() error { + hasMinimalSpecification := d.Type != "" && (d.Major != 0 || d.Type == fifoDevice) + + // Ensure that the host path and the container path match. if d.HostPath == "" { d.HostPath = d.Path } - if d.Type != "" && (d.Major != 0 || d.Type == "p") { + // Try to extract the device info from the host path. + di, err := deviceInfoFromPath(d.HostPath) + if err != nil { + // The error is only considered fatal if the device is not already + // minimally specified since it is allowed for a device vendor to fully + // specify a device node specification. + if !hasMinimalSpecification { + return fmt.Errorf("failed to stat CDI host device %q: %w", d.HostPath, err) + } return nil } - deviceType, major, minor, err := deviceInfoFromPath(d.HostPath) - if err != nil { - return fmt.Errorf("failed to stat CDI host device %q: %w", d.HostPath, err) + // Even for minimally-specified device nodes, we update the file mode if + // required. This is useful for rootless containers where device node + // requests may be treated as bind mounts. + if d.FileMode == nil { + d.FileMode = &di.fileMode + } + + // If the device is minimally specified, we make no further updates and + // don't perform additional checks. + if hasMinimalSpecification { + return nil } if d.Type == "" { - d.Type = deviceType - } else { - if d.Type != deviceType { - return fmt.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)", - d.Path, d.HostPath, d.Type, deviceType) - } + d.Type = di.deviceType } - if d.Major == 0 && d.Type != "p" { - d.Major = major - d.Minor = minor + if d.Type != di.deviceType { + return fmt.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)", + d.Path, d.HostPath, d.Type, di.deviceType) + } + + // For a fifoDevice, we do not update the major and minor number. + if d.Type == fifoDevice { + return nil + } + + // Update the major and minor number for the device node if required. + if d.Major == 0 { + d.Major = di.major + d.Minor = di.minor } return nil diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go index e7d18cdc1..f37499fcf 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go @@ -56,8 +56,17 @@ func (d *DeviceNode) toOCI() spec.LinuxDevice { // toOCI returns the opencontainers runtime Spec LinuxIntelRdt for this IntelRdt config. func (i *IntelRdt) toOCI() *spec.LinuxIntelRdt { return &spec.LinuxIntelRdt{ - ClosID: i.ClosID, - L3CacheSchema: i.L3CacheSchema, - MemBwSchema: i.MemBwSchema, + ClosID: i.ClosID, + L3CacheSchema: i.L3CacheSchema, + MemBwSchema: i.MemBwSchema, + Schemata: i.Schemata, + EnableMonitoring: i.EnableMonitoring, + } +} + +// toOCI returns the opencontainers runtime Spec LinuxNetDevice for this LinuxNetDevice. +func (d *LinuxNetDevice) toOCI() *spec.LinuxNetDevice { + return &spec.LinuxNetDevice{ + Name: d.Name, } } diff --git a/vendor/tags.cncf.io/container-device-interface/specs-go/config.go b/vendor/tags.cncf.io/container-device-interface/specs-go/config.go index f28657b86..ccda9d860 100644 --- a/vendor/tags.cncf.io/container-device-interface/specs-go/config.go +++ b/vendor/tags.cncf.io/container-device-interface/specs-go/config.go @@ -24,12 +24,13 @@ type Device struct { // ContainerEdits are edits a container runtime must make to the OCI spec to expose the device. type ContainerEdits struct { - Env []string `json:"env,omitempty" yaml:"env,omitempty"` - DeviceNodes []*DeviceNode `json:"deviceNodes,omitempty" yaml:"deviceNodes,omitempty"` - Hooks []*Hook `json:"hooks,omitempty" yaml:"hooks,omitempty"` - Mounts []*Mount `json:"mounts,omitempty" yaml:"mounts,omitempty"` - IntelRdt *IntelRdt `json:"intelRdt,omitempty" yaml:"intelRdt,omitempty"` // Added in v0.7.0 - AdditionalGIDs []uint32 `json:"additionalGids,omitempty" yaml:"additionalGids,omitempty"` // Added in v0.7.0 + Env []string `json:"env,omitempty" yaml:"env,omitempty"` + DeviceNodes []*DeviceNode `json:"deviceNodes,omitempty" yaml:"deviceNodes,omitempty"` + NetDevices []*LinuxNetDevice `json:"netDevices,omitempty" yaml:"netDevices,omitempty"` // Added in v1.1.0 + Hooks []*Hook `json:"hooks,omitempty" yaml:"hooks,omitempty"` + Mounts []*Mount `json:"mounts,omitempty" yaml:"mounts,omitempty"` + IntelRdt *IntelRdt `json:"intelRdt,omitempty" yaml:"intelRdt,omitempty"` // Added in v0.7.0 + AdditionalGIDs []uint32 `json:"additionalGids,omitempty" yaml:"additionalGids,omitempty"` // Added in v0.7.0 } // DeviceNode represents a device node that needs to be added to the OCI spec. @@ -64,9 +65,15 @@ type Hook struct { // IntelRdt describes the Linux IntelRdt parameters to set in the OCI spec. type IntelRdt struct { - ClosID string `json:"closID,omitempty" yaml:"closID,omitempty"` - L3CacheSchema string `json:"l3CacheSchema,omitempty" yaml:"l3CacheSchema,omitempty"` - MemBwSchema string `json:"memBwSchema,omitempty" yaml:"memBwSchema,omitempty"` - EnableCMT bool `json:"enableCMT,omitempty" yaml:"enableCMT,omitempty"` - EnableMBM bool `json:"enableMBM,omitempty" yaml:"enableMBM,omitempty"` + ClosID string `json:"closID,omitempty" yaml:"closID,omitempty"` + L3CacheSchema string `json:"l3CacheSchema,omitempty" yaml:"l3CacheSchema,omitempty"` + MemBwSchema string `json:"memBwSchema,omitempty" yaml:"memBwSchema,omitempty"` + Schemata []string `json:"schemata,omitempty" yaml:"schemata,omitempty"` // Added in v1.1.0. + EnableMonitoring bool `json:"enableMonitoring,omitempty" yaml:"enableMonitoring,omitempty"` // Added in v1.1.0. +} + +// LinuxNetDevice represents an OCI LinuxNetDevice to be added to the OCI Spec. +type LinuxNetDevice struct { + HostInterfaceName string `json:"hostInterfaceName" yaml:"hostInterfaceName"` + Name string `json:"name" yaml:"name"` } diff --git a/vendor/tags.cncf.io/container-device-interface/specs-go/version.go b/vendor/tags.cncf.io/container-device-interface/specs-go/version.go index 002e03505..c3f5a8d10 100644 --- a/vendor/tags.cncf.io/container-device-interface/specs-go/version.go +++ b/vendor/tags.cncf.io/container-device-interface/specs-go/version.go @@ -25,7 +25,7 @@ import ( const ( // CurrentVersion is the current version of the Spec. - CurrentVersion = "1.0.0" + CurrentVersion = "1.1.0" // vCurrent is the current version as a semver-comparable type vCurrent version = "v" + CurrentVersion @@ -40,6 +40,7 @@ const ( v070 version = "v0.7.0" v080 version = "v0.8.0" v100 version = "v1.0.0" + v110 version = "v1.1.0" // vEarliest is the earliest supported version of the CDI specification vEarliest version = v030 @@ -58,6 +59,7 @@ var validSpecVersions = requiredVersionMap{ v070: requiresV070, v080: requiresV080, v100: requiresV100, + v110: requiresV110, } // ValidateVersion checks whether the specified spec version is valid. @@ -140,6 +142,33 @@ func (r requiredVersionMap) requiredVersion(spec *Spec) version { return minVersion } +// requiresV110 returns true if the spec uses v1.1.0 features. +func requiresV110(spec *Spec) bool { + if i := spec.ContainerEdits.IntelRdt; i != nil { + if i.Schemata != nil || i.EnableMonitoring { + return true + } + } + + if len(spec.ContainerEdits.NetDevices) > 0 { + return true + } + + for _, dev := range spec.Devices { + if i := dev.ContainerEdits.IntelRdt; i != nil { + if i.Schemata != nil || i.EnableMonitoring { + return true + } + } + + if len(dev.ContainerEdits.NetDevices) > 0 { + return true + } + } + + return false +} + // requiresV100 returns true if the spec uses v1.0.0 features. // Since the v1.0.0 spec bump was due to moving the minimum version checks to // the spec package, there are no explicit spec changes.