Pārlūkot izejas kodu

Update tags.cncf.io/container-device-interface to v0.7.1

This also bumps the maximum supported CDI specification to v0.7.0.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
Evan Lezar 1 gadu atpakaļ
vecāks
revīzija
745e2356ab

+ 2 - 2
vendor.mod

@@ -110,7 +110,7 @@ require (
 	google.golang.org/protobuf v1.33.0
 	gotest.tools/v3 v3.5.1
 	resenje.org/singleflight v0.4.1
-	tags.cncf.io/container-device-interface v0.6.2
+	tags.cncf.io/container-device-interface v0.7.1
 )
 
 require (
@@ -228,5 +228,5 @@ require (
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	k8s.io/klog/v2 v2.90.1 // indirect
 	sigs.k8s.io/yaml v1.3.0 // indirect
-	tags.cncf.io/container-device-interface/specs-go v0.6.0 // indirect
+	tags.cncf.io/container-device-interface/specs-go v0.7.0 // indirect
 )

+ 4 - 4
vendor.sum

@@ -1106,7 +1106,7 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
 sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
 sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
 sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
-tags.cncf.io/container-device-interface v0.6.2 h1:dThE6dtp/93ZDGhqaED2Pu374SOeUkBfuvkLuiTdwzg=
-tags.cncf.io/container-device-interface v0.6.2/go.mod h1:Shusyhjs1A5Na/kqPVLL0KqnHQHuunol9LFeUNkuGVE=
-tags.cncf.io/container-device-interface/specs-go v0.6.0 h1:V+tJJN6dqu8Vym6p+Ru+K5mJ49WL6Aoc5SJFSY0RLsQ=
-tags.cncf.io/container-device-interface/specs-go v0.6.0/go.mod h1:hMAwAbMZyBLdmYqWgYcKH0F/yctNpV3P35f+/088A80=
+tags.cncf.io/container-device-interface v0.7.1 h1:MATNCbAD1su9U6zwQe5BrQ2vGGp1GBayD70bYaxYCNE=
+tags.cncf.io/container-device-interface v0.7.1/go.mod h1:h1JVuOqTQVORp8DziaWKUCDNzAmN+zeCbqbqD30D0ZQ=
+tags.cncf.io/container-device-interface/specs-go v0.7.0 h1:w/maMGVeLP6TIQJVYT5pbqTi8SCw/iHZ+n4ignuGHqg=
+tags.cncf.io/container-device-interface/specs-go v0.7.0/go.mod h1:hMAwAbMZyBLdmYqWgYcKH0F/yctNpV3P35f+/088A80=

+ 3 - 4
vendor/modules.txt

@@ -1600,13 +1600,12 @@ resenje.org/singleflight
 # sigs.k8s.io/yaml v1.3.0
 ## explicit; go 1.12
 sigs.k8s.io/yaml
-# tags.cncf.io/container-device-interface v0.6.2
-## explicit; go 1.19
-tags.cncf.io/container-device-interface/internal/multierror
+# tags.cncf.io/container-device-interface v0.7.1
+## explicit; go 1.20
 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 v0.6.0
+# tags.cncf.io/container-device-interface/specs-go v0.7.0
 ## explicit; go 1.19
 tags.cncf.io/container-device-interface/specs-go

+ 0 - 82
vendor/tags.cncf.io/container-device-interface/internal/multierror/multierror.go

@@ -1,82 +0,0 @@
-/*
-   Copyright © 2022 The CDI Authors
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package multierror
-
-import (
-	"strings"
-)
-
-// New combines several errors into a single error. Parameters that are nil are
-// ignored. If no errors are passed in or all parameters are nil, then the
-// result is also nil.
-func New(errors ...error) error {
-	// Filter out nil entries.
-	numErrors := 0
-	for _, err := range errors {
-		if err != nil {
-			errors[numErrors] = err
-			numErrors++
-		}
-	}
-	if numErrors == 0 {
-		return nil
-	}
-	return multiError(errors[0:numErrors])
-}
-
-// multiError is the underlying implementation used by New.
-//
-// Beware that a null multiError is not the same as a nil error.
-type multiError []error
-
-// multiError returns all individual error strings concatenated with "\n"
-func (e multiError) Error() string {
-	var builder strings.Builder
-	for i, err := range e {
-		if i > 0 {
-			_, _ = builder.WriteString("\n")
-		}
-		_, _ = builder.WriteString(err.Error())
-	}
-	return builder.String()
-}
-
-// Append returns a new multi error all errors concatenated. Errors that are
-// multi errors get flattened, nil is ignored.
-func Append(err error, errors ...error) error {
-	var result multiError
-	if m, ok := err.(multiError); ok {
-		result = m
-	} else if err != nil {
-		result = append(result, err)
-	}
-
-	for _, e := range errors {
-		if e == nil {
-			continue
-		}
-		if m, ok := e.(multiError); ok {
-			result = append(result, m...)
-		} else {
-			result = append(result, e)
-		}
-	}
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}

+ 5 - 6
vendor/tags.cncf.io/container-device-interface/internal/validation/k8s/objectmeta.go

@@ -20,10 +20,9 @@ limitations under the License.
 package k8s
 
 import (
+	"errors"
 	"fmt"
 	"strings"
-
-	"tags.cncf.io/container-device-interface/internal/multierror"
 )
 
 // TotalAnnotationSizeLimitB defines the maximum size of all annotations in characters.
@@ -31,17 +30,17 @@ const TotalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
 
 // ValidateAnnotations validates that a set of annotations are correctly defined.
 func ValidateAnnotations(annotations map[string]string, path string) error {
-	errors := multierror.New()
+	errs := []error{}
 	for k := range annotations {
 		// The rule is QualifiedName except that case doesn't matter, so convert to lowercase before checking.
 		for _, msg := range IsQualifiedName(strings.ToLower(k)) {
-			errors = multierror.Append(errors, fmt.Errorf("%v.%v is invalid: %v", path, k, msg))
+			errs = append(errs, fmt.Errorf("%v.%v is invalid: %v", path, k, msg))
 		}
 	}
 	if err := ValidateAnnotationsSize(annotations); err != nil {
-		errors = multierror.Append(errors, fmt.Errorf("%v is too long: %v", path, err))
+		errs = append(errs, fmt.Errorf("%v is too long: %v", path, err))
 	}
-	return errors
+	return errors.Join(errs...)
 }
 
 // ValidateAnnotationsSize validates that a set of annotations is not too large.

+ 30 - 21
vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go

@@ -28,12 +28,11 @@ import (
 
 	"github.com/fsnotify/fsnotify"
 	oci "github.com/opencontainers/runtime-spec/specs-go"
-	"tags.cncf.io/container-device-interface/internal/multierror"
 	cdi "tags.cncf.io/container-device-interface/specs-go"
 )
 
 // Option is an option to change some aspect of default CDI behavior.
-type Option func(*Cache) error
+type Option func(*Cache)
 
 // Cache stores CDI Specs loaded from Spec directories.
 type Cache struct {
@@ -54,16 +53,27 @@ type Cache struct {
 // is detected. This option can be used to disable this behavior when a
 // manually refreshed mode is preferable.
 func WithAutoRefresh(autoRefresh bool) Option {
-	return func(c *Cache) error {
+	return func(c *Cache) {
 		c.autoRefresh = autoRefresh
-		return nil
 	}
 }
 
 // NewCache creates a new CDI Cache. The cache is populated from a set
 // of CDI Spec directories. These can be specified using a WithSpecDirs
 // option. The default set of directories is exposed in DefaultSpecDirs.
+//
+// Note:
+//
+//	The error returned by this function is always nil and it is only
+//	returned to maintain API compatibility with consumers.
 func NewCache(options ...Option) (*Cache, error) {
+	return newCache(options...), nil
+}
+
+// newCache creates a CDI cache with the supplied options.
+// This function allows testing without handling the nil error returned by the
+// NewCache function.
+func newCache(options ...Option) *Cache {
 	c := &Cache{
 		autoRefresh: true,
 		watch:       &watch{},
@@ -73,7 +83,8 @@ func NewCache(options ...Option) (*Cache, error) {
 	c.Lock()
 	defer c.Unlock()
 
-	return c, c.configure(options...)
+	c.configure(options...)
+	return c
 }
 
 // Configure applies options to the Cache. Updates and refreshes the
@@ -86,18 +97,16 @@ func (c *Cache) Configure(options ...Option) error {
 	c.Lock()
 	defer c.Unlock()
 
-	return c.configure(options...)
+	c.configure(options...)
+
+	return nil
 }
 
 // Configure the Cache. Start/stop CDI Spec directory watch, refresh
 // the Cache if necessary.
-func (c *Cache) configure(options ...Option) error {
-	var err error
-
+func (c *Cache) configure(options ...Option) {
 	for _, o := range options {
-		if err = o(c); err != nil {
-			return fmt.Errorf("failed to apply cache options: %w", err)
-		}
+		o(c)
 	}
 
 	c.dirErrors = make(map[string]error)
@@ -108,8 +117,6 @@ func (c *Cache) configure(options ...Option) error {
 		c.watch.start(&c.Mutex, c.refresh, c.dirErrors)
 	}
 	c.refresh()
-
-	return nil
 }
 
 // Refresh rescans the CDI Spec directories and refreshes the Cache.
@@ -125,11 +132,11 @@ func (c *Cache) Refresh() error {
 	}
 
 	// collect and return cached errors, much like refresh() does it
-	var result error
-	for _, errors := range c.errors {
-		result = multierror.Append(result, errors...)
+	errs := []error{}
+	for _, specErrs := range c.errors {
+		errs = append(errs, errors.Join(specErrs...))
 	}
-	return result
+	return errors.Join(errs...)
 }
 
 // Refresh the Cache by rescanning CDI Spec directories and files.
@@ -139,12 +146,10 @@ func (c *Cache) refresh() error {
 		devices    = map[string]*Device{}
 		conflicts  = map[string]struct{}{}
 		specErrors = map[string][]error{}
-		result     []error
 	)
 
 	// collect errors per spec file path and once globally
 	collectError := func(err error, paths ...string) {
-		result = append(result, err)
 		for _, path := range paths {
 			specErrors[path] = append(specErrors[path], err)
 		}
@@ -197,7 +202,11 @@ func (c *Cache) refresh() error {
 	c.devices = devices
 	c.errors = specErrors
 
-	return multierror.New(result...)
+	errs := []error{}
+	for _, specErrs := range specErrors {
+		errs = append(errs, errors.Join(specErrs...))
+	}
+	return errors.Join(errs...)
 }
 
 // RefreshIfRequired triggers a refresh if necessary.

+ 51 - 1
vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go

@@ -144,6 +144,20 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
 		}
 	}
 
+	if e.IntelRdt != nil {
+		// The specgen is missing functionality to set all parameters so we
+		// just piggy-back on it to initialize all structs and the copy over.
+		specgen.SetLinuxIntelRdtClosID(e.IntelRdt.ClosID)
+		spec.Linux.IntelRdt = e.IntelRdt.ToOCI()
+	}
+
+	for _, additionalGID := range e.AdditionalGIDs {
+		if additionalGID == 0 {
+			continue
+		}
+		specgen.AddProcessAdditionalGid(additionalGID)
+	}
+
 	return nil
 }
 
@@ -171,6 +185,11 @@ func (e *ContainerEdits) Validate() error {
 			return err
 		}
 	}
+	if e.IntelRdt != nil {
+		if err := ValidateIntelRdt(e.IntelRdt); err != nil {
+			return err
+		}
+	}
 
 	return nil
 }
@@ -192,6 +211,10 @@ func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits {
 	e.DeviceNodes = append(e.DeviceNodes, o.DeviceNodes...)
 	e.Hooks = append(e.Hooks, o.Hooks...)
 	e.Mounts = append(e.Mounts, o.Mounts...)
+	if o.IntelRdt != nil {
+		e.IntelRdt = o.IntelRdt
+	}
+	e.AdditionalGIDs = append(e.AdditionalGIDs, o.AdditionalGIDs...)
 
 	return e
 }
@@ -202,7 +225,25 @@ func (e *ContainerEdits) isEmpty() bool {
 	if e == nil {
 		return false
 	}
-	return len(e.Env)+len(e.DeviceNodes)+len(e.Hooks)+len(e.Mounts) == 0
+	if len(e.Env) > 0 {
+		return false
+	}
+	if len(e.DeviceNodes) > 0 {
+		return false
+	}
+	if len(e.Hooks) > 0 {
+		return false
+	}
+	if len(e.Mounts) > 0 {
+		return false
+	}
+	if len(e.AdditionalGIDs) > 0 {
+		return false
+	}
+	if e.IntelRdt != nil {
+		return false
+	}
+	return true
 }
 
 // ValidateEnv validates the given environment variables.
@@ -280,6 +321,15 @@ func (m *Mount) Validate() error {
 	return nil
 }
 
+// ValidateIntelRdt validates the IntelRdt configuration.
+func ValidateIntelRdt(i *specs.IntelRdt) error {
+	// ClosID must be a valid Linux filename
+	if len(i.ClosID) >= 4096 || i.ClosID == "." || i.ClosID == ".." || strings.ContainsAny(i.ClosID, "/\n") {
+		return errors.New("invalid ClosID")
+	}
+	return nil
+}
+
 // Ensure OCI Spec hooks are not nil so we can add hooks.
 func ensureOCIHooks(spec *oci.Spec) {
 	if spec.Hooks == nil {

+ 70 - 0
vendor/tags.cncf.io/container-device-interface/pkg/cdi/default-cache.go

@@ -0,0 +1,70 @@
+/*
+   Copyright © 2024 The CDI Authors
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package cdi
+
+import (
+	"sync"
+
+	oci "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+var (
+	defaultCache   *Cache
+	getDefaultOnce sync.Once
+)
+
+func getOrCreateDefaultCache(options ...Option) (*Cache, bool) {
+	var created bool
+	getDefaultOnce.Do(func() {
+		defaultCache = newCache(options...)
+		created = true
+	})
+	return defaultCache, created
+}
+
+// GetDefaultCache returns the default CDI cache instance.
+func GetDefaultCache() *Cache {
+	cache, _ := getOrCreateDefaultCache()
+	return cache
+}
+
+// Configure applies options to the default CDI cache. Updates and refreshes
+// the default cache if options are not empty.
+func Configure(options ...Option) error {
+	cache, created := getOrCreateDefaultCache(options...)
+	if len(options) == 0 || created {
+		return nil
+	}
+	return cache.Configure(options...)
+}
+
+// Refresh explicitly refreshes the default CDI cache instance.
+func Refresh() error {
+	return GetDefaultCache().Refresh()
+}
+
+// InjectDevices injects the given qualified devices to the given OCI Spec.
+// using the default CDI cache instance to resolve devices.
+func InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, error) {
+	return GetDefaultCache().InjectDevices(ociSpec, devices...)
+}
+
+// GetErrors returns all errors encountered during the last refresh of
+// the default CDI cache instance.
+func GetErrors() map[string][]error {
+	return GetDefaultCache().GetErrors()
+}

+ 14 - 0
vendor/tags.cncf.io/container-device-interface/pkg/cdi/doc.go

@@ -29,8 +29,22 @@
 // the vast majority of CDI consumers need. The API should be usable both
 // by OCI runtime clients and runtime implementations.
 //
+// # Default CDI Cache
+//
+// There is a default CDI cache instance which is always implicitly
+// available and instantiated the first time it is referenced directly
+// or indirectly. The most frequently used cache functions are available
+// as identically named package level functions which operate on the
+// default cache instance. Moreover, the registry also operates on the
+// same default cache. We plan to deprecate the registry and eventually
+// remove it in a future release.
+//
 // # CDI Registry
 //
+// Note: the Registry and its related interfaces are deprecated and will
+// be removed in a future version. Please use the default cache and its
+// related package-level function instead.
+//
 // The primary interface to interact with CDI devices is the Registry. It
 // is essentially a cache of all Specs and devices discovered in standard
 // CDI directories on the host. The registry has two main functionality,

+ 39 - 11
vendor/tags.cncf.io/container-device-interface/pkg/cdi/registry.go

@@ -29,6 +29,11 @@ import (
 //
 // The most commonly used Registry functions are for refreshing the
 // registry and injecting CDI devices into an OCI Spec.
+//
+// Deprecated: Registry is deprecated and will be removed in a future
+// version. Please update your code to use the corresponding package-
+// level functions Configure(), Refresh(), InjectDevices(), GetErrors(),
+// and GetDefaultCache().
 type Registry interface {
 	RegistryResolver
 	RegistryRefresher
@@ -54,6 +59,10 @@ type Registry interface {
 //
 // GetSpecDirErrors returns any errors related to the configured
 // Spec directories.
+//
+// Deprecated: RegistryRefresher is deprecated and will be removed
+// in a future version. Please use the default cache and its related
+// package-level functions instead.
 type RegistryRefresher interface {
 	Configure(...Option) error
 	Refresh() error
@@ -68,6 +77,10 @@ type RegistryRefresher interface {
 // InjectDevices takes an OCI Spec and injects into it a set of
 // CDI devices given by qualified name. It returns the names of
 // any unresolved devices and an error if injection fails.
+//
+// Deprecated: RegistryRefresher is deprecated and will be removed
+// in a future version. Please use the default cache and its related
+// package-level functions instead.
 type RegistryResolver interface {
 	InjectDevices(spec *oci.Spec, device ...string) (unresolved []string, err error)
 }
@@ -79,6 +92,12 @@ type RegistryResolver interface {
 //
 // ListDevices returns a slice with the names of qualified device
 // known. The returned slice is sorted.
+//
+// Deprecated: RegistryDeviceDB is deprecated and will be removed
+// in a future version. Please use the default cache and its related
+// package-level functions instead.
+// and will be removed in a future version. Please use the default
+// cache and its related package-level functions instead.
 type RegistryDeviceDB interface {
 	GetDevice(device string) *Device
 	ListDevices() []string
@@ -99,6 +118,10 @@ type RegistryDeviceDB interface {
 //
 // WriteSpec writes the Spec with the given content and name to the
 // last Spec directory.
+//
+// Deprecated: RegistrySpecDB is deprecated and will be removed
+// in a future version. Please use the default cache and its related
+// package-level functions instead.
 type RegistrySpecDB interface {
 	ListVendors() []string
 	ListClasses() []string
@@ -121,30 +144,35 @@ var (
 
 // GetRegistry returns the CDI registry. If any options are given, those
 // are applied to the registry.
+//
+// Deprecated: GetRegistry is deprecated and will be removed in a future
+// version. Please use the default cache and its related package-level
+// functions instead.
 func GetRegistry(options ...Option) Registry {
-	var new bool
 	initOnce.Do(func() {
-		reg, _ = getRegistry(options...)
-		new = true
+		reg = &registry{GetDefaultCache()}
 	})
-	if !new && len(options) > 0 {
-		reg.Configure(options...)
-		reg.Refresh()
+	if len(options) > 0 {
+		// We don't care about errors here
+		_ = reg.Configure(options...)
 	}
 	return reg
 }
 
 // DeviceDB returns the registry interface for querying devices.
+//
+// Deprecated: DeviceDB is deprecated and will be removed in a future
+// version. Please use the default cache and its related package-level
+// functions instead.
 func (r *registry) DeviceDB() RegistryDeviceDB {
 	return r
 }
 
 // SpecDB returns the registry interface for querying Specs.
+//
+// Deprecated: SpecDB is deprecated and will be removed in a future
+// version. Please use the default cache and its related package-level
+// functions instead.
 func (r *registry) SpecDB() RegistrySpecDB {
 	return r
 }
-
-func getRegistry(options ...Option) (*registry, error) {
-	c, err := NewCache(options...)
-	return &registry{c}, err
-}

+ 1 - 2
vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go

@@ -44,13 +44,12 @@ var (
 
 // WithSpecDirs returns an option to override the CDI Spec directories.
 func WithSpecDirs(dirs ...string) Option {
-	return func(c *Cache) error {
+	return func(c *Cache) {
 		specDirs := make([]string, len(dirs))
 		for i, dir := range dirs {
 			specDirs[i] = filepath.Clean(dir)
 		}
 		c.specDirs = specDirs
-		return nil
 	}
 }
 

+ 1 - 2
vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go

@@ -19,7 +19,6 @@ package cdi
 import (
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -62,7 +61,7 @@ type Spec struct {
 // assigned the given priority. If reading or parsing the Spec
 // data fails ReadSpec returns a nil Spec and an error.
 func ReadSpec(path string, priority int) (*Spec, error) {
-	data, err := ioutil.ReadFile(path)
+	data, err := os.ReadFile(path)
 	switch {
 	case os.IsNotExist(err):
 		return nil, err

+ 25 - 0
vendor/tags.cncf.io/container-device-interface/pkg/cdi/version.go

@@ -39,6 +39,7 @@ const (
 	v040 version = "v0.4.0"
 	v050 version = "v0.5.0"
 	v060 version = "v0.6.0"
+	v070 version = "v0.7.0"
 
 	// vEarliest is the earliest supported version of the CDI specification
 	vEarliest version = v030
@@ -54,6 +55,7 @@ var validSpecVersions = requiredVersionMap{
 	v040: requiresV040,
 	v050: requiresV050,
 	v060: requiresV060,
+	v070: requiresV070,
 }
 
 // MinimumRequiredVersion determines the minimum spec version for the input spec.
@@ -118,6 +120,29 @@ func (r requiredVersionMap) requiredVersion(spec *cdi.Spec) version {
 	return minVersion
 }
 
+// requiresV070 returns true if the spec uses v0.7.0 features
+func requiresV070(spec *cdi.Spec) bool {
+	if spec.ContainerEdits.IntelRdt != nil {
+		return true
+	}
+	// The v0.7.0 spec allows additional GIDs to be specified at a spec level.
+	if len(spec.ContainerEdits.AdditionalGIDs) > 0 {
+		return true
+	}
+
+	for _, d := range spec.Devices {
+		if d.ContainerEdits.IntelRdt != nil {
+			return true
+		}
+		// The v0.7.0 spec allows additional GIDs to be specified at a device level.
+		if len(d.ContainerEdits.AdditionalGIDs) > 0 {
+			return true
+		}
+	}
+
+	return false
+}
+
 // requiresV060 returns true if the spec uses v0.6.0 features
 func requiresV060(spec *cdi.Spec) bool {
 	// The v0.6.0 spec allows annotations to be specified at a spec level

+ 16 - 5
vendor/tags.cncf.io/container-device-interface/specs-go/config.go

@@ -3,7 +3,7 @@ package specs
 import "os"
 
 // CurrentVersion is the current version of the Spec.
-const CurrentVersion = "0.6.0"
+const CurrentVersion = "0.7.0"
 
 // Spec is the base configuration for CDI
 type Spec struct {
@@ -25,10 +25,12 @@ 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"`
-	DeviceNodes []*DeviceNode `json:"deviceNodes,omitempty"`
-	Hooks       []*Hook       `json:"hooks,omitempty"`
-	Mounts      []*Mount      `json:"mounts,omitempty"`
+	Env            []string      `json:"env,omitempty"`
+	DeviceNodes    []*DeviceNode `json:"deviceNodes,omitempty"`
+	Hooks          []*Hook       `json:"hooks,omitempty"`
+	Mounts         []*Mount      `json:"mounts,omitempty"`
+	IntelRdt       *IntelRdt     `json:"intelRdt,omitempty"`
+	AdditionalGIDs []uint32      `json:"additionalGids,omitempty"`
 }
 
 // DeviceNode represents a device node that needs to be added to the OCI spec.
@@ -60,3 +62,12 @@ type Hook struct {
 	Env      []string `json:"env,omitempty"`
 	Timeout  *int     `json:"timeout,omitempty"`
 }
+
+// IntelRdt describes the Linux IntelRdt parameters to set in the OCI spec.
+type IntelRdt struct {
+	ClosID        string `json:"closID,omitempty"`
+	L3CacheSchema string `json:"l3CacheSchema,omitempty"`
+	MemBwSchema   string `json:"memBwSchema,omitempty"`
+	EnableCMT     bool   `json:"enableCMT,omitempty"`
+	EnableMBM     bool   `json:"enableMBM,omitempty"`
+}

+ 11 - 0
vendor/tags.cncf.io/container-device-interface/specs-go/oci.go

@@ -36,3 +36,14 @@ func (d *DeviceNode) ToOCI() spec.LinuxDevice {
 		GID:      d.GID,
 	}
 }
+
+// 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,
+		EnableCMT:     i.EnableCMT,
+		EnableMBM:     i.EnableMBM,
+	}
+}