diff --git a/go.mod b/go.mod index e8b034eb..3f98372c 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,8 @@ require ( github.com/urfave/cli/v2 v2.27.6 golang.org/x/mod v0.24.0 golang.org/x/sys v0.31.0 - tags.cncf.io/container-device-interface v0.8.1 - tags.cncf.io/container-device-interface/specs-go v0.8.0 + tags.cncf.io/container-device-interface v1.0.0 + tags.cncf.io/container-device-interface/specs-go v1.0.0 ) require ( diff --git a/go.sum b/go.sum index 7e5c8b3f..ec099d40 100644 --- a/go.sum +++ b/go.sum @@ -92,7 +92,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.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -tags.cncf.io/container-device-interface v0.8.1 h1:c0jN4Mt6781jD67NdPajmZlD1qrqQyov/Xfoab37lj0= -tags.cncf.io/container-device-interface v0.8.1/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y= -tags.cncf.io/container-device-interface/specs-go v0.8.0 h1:QYGFzGxvYK/ZLMrjhvY0RjpUavIn4KcmRmVP/JjdBTA= -tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws= +tags.cncf.io/container-device-interface v1.0.0 h1:fbwPQiWZNpXUb9Os6t6JW52rsOppTFUbeJOpNtN1TmI= +tags.cncf.io/container-device-interface v1.0.0/go.mod h1:mmi2aRGmOjK/6NR3TXjLpEIarOJ9qwgZjQ3nTIRwAaA= +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= diff --git a/vendor/modules.txt b/vendor/modules.txt index f0765bc1..316de900 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -94,12 +94,12 @@ gopkg.in/yaml.v3 # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# tags.cncf.io/container-device-interface v0.8.1 +# tags.cncf.io/container-device-interface v1.0.0 ## 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.8.0 +# tags.cncf.io/container-device-interface/specs-go v1.0.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/annotations.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/annotations.go index a38b0f1b..a596c610 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/annotations.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/annotations.go @@ -71,7 +71,7 @@ func ParseAnnotations(annotations map[string]string) ([]string, []string, error) continue } for _, d := range strings.Split(value, ",") { - if !IsQualifiedName(d) { + if !parser.IsQualifiedName(d) { return nil, nil, fmt.Errorf("invalid CDI device name %q", d) } devices = append(devices, d) @@ -130,7 +130,7 @@ func AnnotationKey(pluginName, deviceID string) (string, error) { func AnnotationValue(devices []string) (string, error) { value, sep := "", "" for _, d := range devices { - if _, _, _, err := ParseQualifiedName(d); err != nil { + if _, _, _, err := parser.ParseQualifiedName(d); err != nil { return "", err } value += sep + d diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go index 9afa4b18..7095f27d 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go @@ -22,6 +22,7 @@ import ( "io/fs" "os" "path/filepath" + "runtime" "sort" "strings" "sync" @@ -116,7 +117,7 @@ func (c *Cache) configure(options ...Option) { c.watch.setup(c.specDirs, c.dirErrors) c.watch.start(&c.Mutex, c.refresh, c.dirErrors) } - c.refresh() + _ = c.refresh() // we record but ignore errors } // Refresh rescans the CDI Spec directories and refreshes the Cache. @@ -222,7 +223,8 @@ func (c *Cache) refreshIfRequired(force bool) (bool, error) { // InjectDevices injects the given qualified devices to an OCI Spec. It // returns any unresolvable devices and an error if injection fails for -// any of the devices. +// any of the devices. Might trigger a cache refresh, in which case any +// errors encountered can be obtained using GetErrors(). func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, error) { var unresolved []string @@ -233,7 +235,7 @@ func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, e c.Lock() defer c.Unlock() - c.refreshIfRequired(false) + _, _ = c.refreshIfRequired(false) // we record but ignore errors edits := &ContainerEdits{} specs := map[*Spec]struct{}{} @@ -335,24 +337,27 @@ func (c *Cache) RemoveSpec(name string) error { return err } -// GetDevice returns the cached device for the given qualified name. +// GetDevice returns the cached device for the given qualified name. Might trigger +// a cache refresh, in which case any errors encountered can be obtained using +// GetErrors(). func (c *Cache) GetDevice(device string) *Device { c.Lock() defer c.Unlock() - c.refreshIfRequired(false) + _, _ = c.refreshIfRequired(false) // we record but ignore errors return c.devices[device] } -// ListDevices lists all cached devices by qualified name. +// ListDevices lists all cached devices by qualified name. Might trigger a cache +// refresh, in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) ListDevices() []string { var devices []string c.Lock() defer c.Unlock() - c.refreshIfRequired(false) + _, _ = c.refreshIfRequired(false) // we record but ignore errors for name := range c.devices { devices = append(devices, name) @@ -362,14 +367,15 @@ func (c *Cache) ListDevices() []string { return devices } -// ListVendors lists all vendors known to the cache. +// ListVendors lists all vendors known to the cache. Might trigger a cache refresh, +// in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) ListVendors() []string { var vendors []string c.Lock() defer c.Unlock() - c.refreshIfRequired(false) + _, _ = c.refreshIfRequired(false) // we record but ignore errors for vendor := range c.specs { vendors = append(vendors, vendor) @@ -379,7 +385,8 @@ func (c *Cache) ListVendors() []string { return vendors } -// ListClasses lists all device classes known to the cache. +// ListClasses lists all device classes known to the cache. Might trigger a cache +// refresh, in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) ListClasses() []string { var ( cmap = map[string]struct{}{} @@ -389,7 +396,7 @@ func (c *Cache) ListClasses() []string { c.Lock() defer c.Unlock() - c.refreshIfRequired(false) + _, _ = c.refreshIfRequired(false) // we record but ignore errors for _, specs := range c.specs { for _, spec := range specs { @@ -404,12 +411,13 @@ func (c *Cache) ListClasses() []string { return classes } -// GetVendorSpecs returns all specs for the given vendor. +// GetVendorSpecs returns all specs for the given vendor. Might trigger a cache +// refresh, in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) GetVendorSpecs(vendor string) []*Spec { c.Lock() defer c.Unlock() - c.refreshIfRequired(false) + _, _ = c.refreshIfRequired(false) // we record but ignore errors return c.specs[vendor] } @@ -522,6 +530,13 @@ func (w *watch) watch(fsw *fsnotify.Watcher, m *sync.Mutex, refresh func() error if watch == nil { return } + + eventMask := fsnotify.Rename | fsnotify.Remove | fsnotify.Write + // On macOS, we also need to watch for Create events. + if runtime.GOOS == "darwin" { + eventMask |= fsnotify.Create + } + for { select { case event, ok := <-watch.Events: @@ -529,10 +544,10 @@ func (w *watch) watch(fsw *fsnotify.Watcher, m *sync.Mutex, refresh func() error return } - if (event.Op & (fsnotify.Rename | fsnotify.Remove | fsnotify.Write)) == 0 { + if (event.Op & eventMask) == 0 { continue } - if event.Op == fsnotify.Write { + if event.Op == fsnotify.Write || event.Op == fsnotify.Create { if ext := filepath.Ext(event.Name); ext != ".json" && ext != ".yaml" { continue } @@ -544,7 +559,7 @@ func (w *watch) watch(fsw *fsnotify.Watcher, m *sync.Mutex, refresh func() error } else { w.update(dirErrors) } - refresh() + _ = refresh() m.Unlock() case _, ok := <-watch.Errors: diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_darwin.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_darwin.go new file mode 100644 index 00000000..b09ea6ff --- /dev/null +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_darwin.go @@ -0,0 +1,26 @@ +//go:build darwin +// +build darwin + +/* + Copyright © 2021 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 "syscall" + +func osSync() { + _ = syscall.Sync() +} diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_unix.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_unix.go index 0ee5fb86..b7c44129 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_unix.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache_test_unix.go @@ -1,5 +1,5 @@ -//go:build !windows -// +build !windows +//go:build !windows && !darwin +// +build !windows,!darwin /* Copyright © 2021 The CDI Authors 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 70791666..4744eff8 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 @@ -26,7 +26,7 @@ import ( oci "github.com/opencontainers/runtime-spec/specs-go" ocigen "github.com/opencontainers/runtime-tools/generate" - "tags.cncf.io/container-device-interface/specs-go" + cdi "tags.cncf.io/container-device-interface/specs-go" ) const ( @@ -64,7 +64,7 @@ var ( // to all OCI Specs where at least one devices from the CDI Spec // is injected. type ContainerEdits struct { - *specs.ContainerEdits + *cdi.ContainerEdits } // Apply edits to the given OCI Spec. Updates the OCI Spec in place. @@ -205,7 +205,7 @@ func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits { e = &ContainerEdits{} } if e.ContainerEdits == nil { - e.ContainerEdits = &specs.ContainerEdits{} + e.ContainerEdits = &cdi.ContainerEdits{} } e.Env = append(e.Env, o.Env...) @@ -259,7 +259,7 @@ func ValidateEnv(env []string) error { // DeviceNode is a CDI Spec DeviceNode wrapper, used for validating DeviceNodes. type DeviceNode struct { - *specs.DeviceNode + *cdi.DeviceNode } // Validate a CDI Spec DeviceNode. @@ -289,7 +289,7 @@ func (d *DeviceNode) Validate() error { // Hook is a CDI Spec Hook wrapper, used for validating hooks. type Hook struct { - *specs.Hook + *cdi.Hook } // Validate a hook. @@ -308,7 +308,7 @@ func (h *Hook) Validate() error { // Mount is a CDI Mount wrapper, used for validating mounts. type Mount struct { - *specs.Mount + *cdi.Mount } // Validate a mount. @@ -325,13 +325,13 @@ func (m *Mount) Validate() error { // IntelRdt is a CDI IntelRdt wrapper. // This is used for validation and conversion to OCI specifications. type IntelRdt struct { - *specs.IntelRdt + *cdi.IntelRdt } // ValidateIntelRdt validates the IntelRdt configuration. // // Deprecated: ValidateIntelRdt is deprecated use IntelRdt.Validate() instead. -func ValidateIntelRdt(i *specs.IntelRdt) error { +func ValidateIntelRdt(i *cdi.IntelRdt) error { return (&IntelRdt{i}).Validate() } @@ -355,7 +355,7 @@ func ensureOCIHooks(spec *oci.Spec) { func sortMounts(specgen *ocigen.Generator) { mounts := specgen.Mounts() specgen.ClearMounts() - sort.Sort(orderedMounts(mounts)) + sort.Stable(orderedMounts(mounts)) specgen.Config.Mounts = mounts } @@ -375,14 +375,7 @@ func (m orderedMounts) Len() int { // mount indexed by parameter 1 is less than that of the mount indexed by // parameter 2. Used in sorting. func (m orderedMounts) Less(i, j int) bool { - ip, jp := m.parts(i), m.parts(j) - if ip < jp { - return true - } - if jp < ip { - return false - } - return m[i].Destination < m[j].Destination + return m.parts(i) < m.parts(j) } // Swap swaps two items in an array of mounts. Used in sorting diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/device.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/device.go index 00be48dd..2e5fa57f 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/device.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/device.go @@ -67,7 +67,7 @@ func (d *Device) edits() *ContainerEdits { // Validate the device. func (d *Device) validate() error { - if err := ValidateDeviceName(d.Name); err != nil { + if err := parser.ValidateDeviceName(d.Name); err != nil { return err } name := d.Name diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/doc.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/doc.go index 0ea07145..d00e0d33 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/doc.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/doc.go @@ -35,25 +35,11 @@ // 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, -// injecting devices into an OCI Spec and refreshing the cache of CDI -// Specs and devices. +// default cache instance. // // # Device Injection // -// Using the Registry one can inject CDI devices into a container with code +// Using the Cache one can inject CDI devices into a container with code // similar to the following snippet: // // import ( @@ -63,13 +49,14 @@ // log "github.com/sirupsen/logrus" // // "tags.cncf.io/container-device-interface/pkg/cdi" -// oci "github.com/opencontainers/runtime-spec/specs-go" +// "github.com/opencontainers/runtime-spec/specs-go" // ) // -// func injectCDIDevices(spec *oci.Spec, devices []string) error { +// func injectCDIDevices(spec *specs.Spec, devices []string) error { // log.Debug("pristine OCI Spec: %s", dumpSpec(spec)) // -// unresolved, err := cdi.GetRegistry().InjectDevices(spec, devices) +// cache := cdi.GetDefaultCache() +// unresolved, err := cache.InjectDevices(spec, devices) // if err != nil { // return fmt.Errorf("CDI device injection failed: %w", err) // } @@ -106,17 +93,17 @@ // log "github.com/sirupsen/logrus" // // "tags.cncf.io/container-device-interface/pkg/cdi" -// oci "github.com/opencontainers/runtime-spec/specs-go" +// "github.com/opencontainers/runtime-spec/specs-go" // ) // -// func injectCDIDevices(spec *oci.Spec, devices []string) error { -// registry := cdi.GetRegistry() +// func injectCDIDevices(spec *specs.Spec, devices []string) error { +// cache := cdi.GetDefaultCache() // -// if err := registry.Refresh(); err != nil { +// if err := cache.Refresh(); err != nil { // // Note: // // It is up to the implementation to decide whether // // to abort injection on errors. A failed Refresh() -// // does not necessarily render the registry unusable. +// // does not necessarily render the cache unusable. // // For instance, a parse error in a Spec file for // // vendor A does not have any effect on devices of // // vendor B... @@ -125,7 +112,7 @@ // // log.Debug("pristine OCI Spec: %s", dumpSpec(spec)) // -// unresolved, err := registry.InjectDevices(spec, devices) +// unresolved, err := cache.InjectDevices(spec, devices) // if err != nil { // return fmt.Errorf("CDI device injection failed: %w", err) // } @@ -192,7 +179,7 @@ // ) // // func generateDeviceSpecs() error { -// registry := cdi.GetRegistry() +// cache := specs.GetDefaultCache() // spec := &specs.Spec{ // Version: specs.CurrentVersion, // Kind: vendor+"/"+class, @@ -210,7 +197,7 @@ // return fmt.Errorf("failed to generate Spec name: %w", err) // } // -// return registry.SpecDB().WriteSpec(spec, specName) +// return cache.WriteSpec(spec, specName) // } // // Similarly, generating and later cleaning up transient Spec files can be @@ -229,7 +216,7 @@ // ) // // func generateTransientSpec(ctr Container) error { -// registry := cdi.GetRegistry() +// cache := specs.GetDefaultCache() // devices := getContainerDevs(ctr, vendor, class) // spec := &specs.Spec{ // Version: specs.CurrentVersion, @@ -257,21 +244,21 @@ // return fmt.Errorf("failed to generate Spec name: %w", err) // } // -// return registry.SpecDB().WriteSpec(spec, specName) +// return cache.WriteSpec(spec, specName) // } // // func removeTransientSpec(ctr Container) error { -// registry := cdi.GetRegistry() +// cache := specs.GetDefaultCache() // transientID := getSomeSufficientlyUniqueIDForContainer(ctr) // specName := cdi.GenerateNameForTransientSpec(vendor, class, transientID) // -// return registry.SpecDB().RemoveSpec(specName) +// return cache.RemoveSpec(specName) // } // // # CDI Spec Validation // // This package performs both syntactic and semantic validation of CDI -// Spec file data when a Spec file is loaded via the registry or using +// Spec file data when a Spec file is loaded via the cache or using // the ReadSpec API function. As part of the semantic verification, the // Spec file is verified against the CDI Spec JSON validation schema. // diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/qualified-device.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/qualified-device.go deleted file mode 100644 index 0bdfdc16..00000000 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/qualified-device.go +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright © 2021 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 ( - "tags.cncf.io/container-device-interface/pkg/parser" -) - -// QualifiedName returns the qualified name for a device. -// The syntax for a qualified device names is -// -// "/=". -// -// A valid vendor and class name may contain the following runes: -// -// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'. -// -// A valid device name may contain the following runes: -// -// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':' -// -// Deprecated: use parser.QualifiedName instead -func QualifiedName(vendor, class, name string) string { - return parser.QualifiedName(vendor, class, name) -} - -// IsQualifiedName tests if a device name is qualified. -// -// Deprecated: use parser.IsQualifiedName instead -func IsQualifiedName(device string) bool { - return parser.IsQualifiedName(device) -} - -// ParseQualifiedName splits a qualified name into device vendor, class, -// and name. If the device fails to parse as a qualified name, or if any -// of the split components fail to pass syntax validation, vendor and -// class are returned as empty, together with the verbatim input as the -// name and an error describing the reason for failure. -// -// Deprecated: use parser.ParseQualifiedName instead -func ParseQualifiedName(device string) (string, string, string, error) { - return parser.ParseQualifiedName(device) -} - -// ParseDevice tries to split a device name into vendor, class, and name. -// If this fails, for instance in the case of unqualified device names, -// ParseDevice returns an empty vendor and class together with name set -// to the verbatim input. -// -// Deprecated: use parser.ParseDevice instead -func ParseDevice(device string) (string, string, string) { - return parser.ParseDevice(device) -} - -// ParseQualifier splits a device qualifier into vendor and class. -// The syntax for a device qualifier is -// -// "/" -// -// If parsing fails, an empty vendor and the class set to the -// verbatim input is returned. -// -// Deprecated: use parser.ParseQualifier instead -func ParseQualifier(kind string) (string, string) { - return parser.ParseQualifier(kind) -} - -// ValidateVendorName checks the validity of a vendor name. -// A vendor name may contain the following ASCII characters: -// - upper- and lowercase letters ('A'-'Z', 'a'-'z') -// - digits ('0'-'9') -// - underscore, dash, and dot ('_', '-', and '.') -// -// Deprecated: use parser.ValidateVendorName instead -func ValidateVendorName(vendor string) error { - return parser.ValidateVendorName(vendor) -} - -// ValidateClassName checks the validity of class name. -// A class name may contain the following ASCII characters: -// - upper- and lowercase letters ('A'-'Z', 'a'-'z') -// - digits ('0'-'9') -// - underscore, dash, and dot ('_', '-', and '.') -// -// Deprecated: use parser.ValidateClassName instead -func ValidateClassName(class string) error { - return parser.ValidateClassName(class) -} - -// ValidateDeviceName checks the validity of a device name. -// A device name may contain the following ASCII characters: -// - upper- and lowercase letters ('A'-'Z', 'a'-'z') -// - digits ('0'-'9') -// - underscore, dash, dot, colon ('_', '-', '.', ':') -// -// Deprecated: use parser.ValidateDeviceName instead -func ValidateDeviceName(name string) error { - return parser.ValidateDeviceName(name) -} diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/registry.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/registry.go deleted file mode 100644 index 3113a05a..00000000 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/registry.go +++ /dev/null @@ -1,178 +0,0 @@ -/* - Copyright © 2021 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" - cdi "tags.cncf.io/container-device-interface/specs-go" -) - -// Registry keeps a cache of all CDI Specs installed or generated on -// the host. Registry is the primary interface clients should use to -// interact with CDI. -// -// 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 - DeviceDB() RegistryDeviceDB - SpecDB() RegistrySpecDB -} - -// RegistryRefresher is the registry interface for refreshing the -// cache of CDI Specs and devices. -// -// Configure reconfigures the registry with the given options. -// -// Refresh rescans all CDI Spec directories and updates the -// state of the cache to reflect any changes. It returns any -// errors encountered during the refresh. -// -// GetErrors returns all errors encountered for any of the scanned -// Spec files during the last cache refresh. -// -// GetSpecDirectories returns the set up CDI Spec directories -// currently in use. The directories are returned in the scan -// order of Refresh(). -// -// 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 - GetErrors() map[string][]error - GetSpecDirectories() []string - GetSpecDirErrors() map[string]error -} - -// RegistryResolver is the registry interface for injecting CDI -// devices into an OCI Spec. -// -// 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) -} - -// RegistryDeviceDB is the registry interface for querying devices. -// -// GetDevice returns the CDI device for the given qualified name. If -// the device is not GetDevice returns nil. -// -// 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 -} - -// RegistrySpecDB is the registry interface for querying CDI Specs. -// -// ListVendors returns a slice with all vendors known. The returned -// slice is sorted. -// -// ListClasses returns a slice with all classes known. The returned -// slice is sorted. -// -// GetVendorSpecs returns a slice of all Specs for the vendor. -// -// GetSpecErrors returns any errors for the Spec encountered during -// the last cache refresh. -// -// 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 - GetVendorSpecs(vendor string) []*Spec - GetSpecErrors(*Spec) []error - WriteSpec(raw *cdi.Spec, name string) error - RemoveSpec(name string) error -} - -type registry struct { - *Cache -} - -var _ Registry = ®istry{} - -var ( - reg *registry - initOnce sync.Once -) - -// 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 { - initOnce.Do(func() { - reg = ®istry{GetDefaultCache()} - }) - 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 -} diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go index 09005d69..b192f962 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go @@ -35,8 +35,7 @@ var ( // While altering this variable changes the package defaults, // the preferred way of overriding the default directories is // to use a WithSpecDirs options. Otherwise the change is only - // effective if it takes place before creating the Registry or - // other Cache instances. + // effective if it takes place before creating the cache instance. DefaultSpecDirs = []string{DefaultStaticDir, DefaultDynamicDir} // ErrStopScan can be returned from a ScanSpecFunc to stop the scan. ErrStopScan = errors.New("stop Spec scan") diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go index 1a0a662b..1ddc244f 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go @@ -25,9 +25,11 @@ import ( "sync" oci "github.com/opencontainers/runtime-spec/specs-go" + orderedyaml "gopkg.in/yaml.v2" "sigs.k8s.io/yaml" "tags.cncf.io/container-device-interface/internal/validation" + "tags.cncf.io/container-device-interface/pkg/parser" cdi "tags.cncf.io/container-device-interface/specs-go" ) @@ -36,9 +38,13 @@ const ( defaultSpecExt = ".yaml" ) +type validator interface { + Validate(*cdi.Spec) error +} + var ( // Externally set CDI Spec validation function. - specValidator func(*cdi.Spec) error + specValidator validator validatorLock sync.RWMutex ) @@ -105,7 +111,7 @@ func newSpec(raw *cdi.Spec, path string, priority int) (*Spec, error) { spec.path += defaultSpecExt } - spec.vendor, spec.class = ParseQualifier(spec.Kind) + spec.vendor, spec.class = parser.ParseQualifier(spec.Kind) if spec.devices, err = spec.validate(); err != nil { return nil, fmt.Errorf("invalid CDI Spec: %w", err) @@ -130,7 +136,7 @@ func (s *Spec) write(overwrite bool) error { } if filepath.Ext(s.path) == ".yaml" { - data, err = yaml.Marshal(s.Spec) + data, err = orderedyaml.Marshal(s.Spec) data = append([]byte("---\n"), data...) } else { data, err = json.Marshal(s.Spec) @@ -200,24 +206,21 @@ func (s *Spec) edits() *ContainerEdits { return &ContainerEdits{&s.ContainerEdits} } +// MinimumRequiredVersion determines the minimum spec version for the input spec. +// Deprecated: use cdi.MinimumRequiredVersion instead +func MinimumRequiredVersion(spec *cdi.Spec) (string, error) { + return cdi.MinimumRequiredVersion(spec) +} + // Validate the Spec. func (s *Spec) validate() (map[string]*Device, error) { - if err := validateVersion(s.Version); err != nil { + if err := cdi.ValidateVersion(s.Spec); err != nil { return nil, err } - - minVersion, err := MinimumRequiredVersion(s.Spec) - if err != nil { - return nil, fmt.Errorf("could not determine minimum required version: %v", err) - } - if newVersion(minVersion).IsGreaterThan(newVersion(s.Version)) { - return nil, fmt.Errorf("the spec version must be at least v%v", minVersion) - } - - if err := ValidateVendorName(s.vendor); err != nil { + if err := parser.ValidateVendorName(s.vendor); err != nil { return nil, err } - if err := ValidateClassName(s.class); err != nil { + if err := parser.ValidateClassName(s.class); err != nil { return nil, err } if err := validation.ValidateSpecAnnotations(s.Kind, s.Annotations); err != nil { @@ -238,17 +241,11 @@ func (s *Spec) validate() (map[string]*Device, error) { } devices[d.Name] = dev } - - return devices, nil -} - -// validateVersion checks whether the specified spec version is supported. -func validateVersion(version string) error { - if !validSpecVersions.isValidVersion(version) { - return fmt.Errorf("invalid version %q", version) + if len(devices) == 0 { + return nil, fmt.Errorf("invalid spec, no devices") } - return nil + return devices, nil } // ParseSpec parses CDI Spec data into a raw CDI Spec. @@ -264,13 +261,13 @@ func ParseSpec(data []byte) (*cdi.Spec, error) { // SetSpecValidator sets a CDI Spec validator function. This function // is used for extra CDI Spec content validation whenever a Spec file // loaded (using ReadSpec() or written (using WriteSpec()). -func SetSpecValidator(fn func(*cdi.Spec) error) { +func SetSpecValidator(v validator) { validatorLock.Lock() defer validatorLock.Unlock() - specValidator = fn + specValidator = v } -// validateSpec validates the Spec using the extneral validator. +// validateSpec validates the Spec using the external validator. func validateSpec(raw *cdi.Spec) error { validatorLock.RLock() defer validatorLock.RUnlock() @@ -278,7 +275,7 @@ func validateSpec(raw *cdi.Spec) error { if specValidator == nil { return nil } - err := specValidator(raw) + err := specValidator.Validate(raw) if err != nil { return fmt.Errorf("Spec validation failed: %w", err) } @@ -328,7 +325,7 @@ func GenerateTransientSpecName(vendor, class, transientID string) string { // the Spec does not contain a valid vendor or class, it returns // an empty name and a non-nil error. func GenerateNameForSpec(raw *cdi.Spec) (string, error) { - vendor, class := ParseQualifier(raw.Kind) + vendor, class := parser.ParseQualifier(raw.Kind) if vendor == "" { return "", fmt.Errorf("invalid vendor/class %q in Spec", raw.Kind) } @@ -342,7 +339,7 @@ func GenerateNameForSpec(raw *cdi.Spec) (string, error) { // If the Spec does not contain a valid vendor or class, it returns an // an empty name and a non-nil error. func GenerateNameForTransientSpec(raw *cdi.Spec, transientID string) (string, error) { - vendor, class := ParseQualifier(raw.Kind) + vendor, class := parser.ParseQualifier(raw.Kind) if vendor == "" { return "", fmt.Errorf("invalid vendor/class %q in Spec", raw.Kind) } 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 d6d6302f..f28657b8 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 @@ -2,72 +2,71 @@ package specs import "os" -// CurrentVersion is the current version of the Spec. -const CurrentVersion = "0.8.0" - // Spec is the base configuration for CDI type Spec struct { - Version string `json:"cdiVersion"` - Kind string `json:"kind"` + Version string `json:"cdiVersion" yaml:"cdiVersion"` + Kind string `json:"kind" yaml:"kind"` // Annotations add meta information per CDI spec. Note these are CDI-specific and do not affect container metadata. - Annotations map[string]string `json:"annotations,omitempty"` - Devices []Device `json:"devices"` - ContainerEdits ContainerEdits `json:"containerEdits,omitempty"` + // Added in v0.6.0. + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Devices []Device `json:"devices" yaml:"devices"` + ContainerEdits ContainerEdits `json:"containerEdits,omitempty" yaml:"containerEdits,omitempty"` } // Device is a "Device" a container runtime can add to a container type Device struct { - Name string `json:"name"` + Name string `json:"name" yaml:"name"` // Annotations add meta information per device. Note these are CDI-specific and do not affect container metadata. - Annotations map[string]string `json:"annotations,omitempty"` - ContainerEdits ContainerEdits `json:"containerEdits"` + // Added in v0.6.0. + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ContainerEdits ContainerEdits `json:"containerEdits" yaml:"containerEdits"` } // 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"` - IntelRdt *IntelRdt `json:"intelRdt,omitempty"` - AdditionalGIDs []uint32 `json:"additionalGids,omitempty"` + 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 } // DeviceNode represents a device node that needs to be added to the OCI spec. type DeviceNode struct { - Path string `json:"path"` - HostPath string `json:"hostPath,omitempty"` - Type string `json:"type,omitempty"` - Major int64 `json:"major,omitempty"` - Minor int64 `json:"minor,omitempty"` - FileMode *os.FileMode `json:"fileMode,omitempty"` - Permissions string `json:"permissions,omitempty"` - UID *uint32 `json:"uid,omitempty"` - GID *uint32 `json:"gid,omitempty"` + Path string `json:"path" yaml:"path"` + HostPath string `json:"hostPath,omitempty" yaml:"hostPath,omitempty"` // Added in v0.5.0 + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Major int64 `json:"major,omitempty" yaml:"major,omitempty"` + Minor int64 `json:"minor,omitempty" yaml:"minor,omitempty"` + FileMode *os.FileMode `json:"fileMode,omitempty" yaml:"fileMode,omitempty"` + Permissions string `json:"permissions,omitempty" yaml:"permissions,omitempty"` + UID *uint32 `json:"uid,omitempty" yaml:"uid,omitempty"` + GID *uint32 `json:"gid,omitempty" yaml:"gid,omitempty"` } // Mount represents a mount that needs to be added to the OCI spec. type Mount struct { - HostPath string `json:"hostPath"` - ContainerPath string `json:"containerPath"` - Options []string `json:"options,omitempty"` - Type string `json:"type,omitempty"` + HostPath string `json:"hostPath" yaml:"hostPath"` + ContainerPath string `json:"containerPath" yaml:"containerPath"` + Options []string `json:"options,omitempty" yaml:"options,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` // Added in v0.4.0 } // Hook represents a hook that needs to be added to the OCI spec. type Hook struct { - HookName string `json:"hookName"` - Path string `json:"path"` - Args []string `json:"args,omitempty"` - Env []string `json:"env,omitempty"` - Timeout *int `json:"timeout,omitempty"` + HookName string `json:"hookName" yaml:"hookName"` + Path string `json:"path" yaml:"path"` + Args []string `json:"args,omitempty" yaml:"args,omitempty"` + Env []string `json:"env,omitempty" yaml:"env,omitempty"` + Timeout *int `json:"timeout,omitempty" yaml:"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"` + 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"` } diff --git a/vendor/tags.cncf.io/container-device-interface/specs-go/oci.go b/vendor/tags.cncf.io/container-device-interface/specs-go/oci.go deleted file mode 100644 index ce485cb2..00000000 --- a/vendor/tags.cncf.io/container-device-interface/specs-go/oci.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright © 2021 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 specs - -import "errors" - -// errDeprecated is returned for the ToOCI functions below. -// This should provide better guidance for user when migrating from the API -// below to the APIs provided in the cdi package. -var errDeprecated = errors.New("deprecated; Use cdi package functions instead") - -// ToOCI returns the opencontainers runtime Spec Hook for this Hook. -// -// Deprecated: This function has been moved to tags.cncf.io/container-device-interface/pkg/cdi.Hook.toOCI -// and made private. -func (h *Hook) ToOCI() error { - return errDeprecated -} - -// ToOCI returns the opencontainers runtime Spec Mount for this Mount. -// -// Deprecated: This function has been moved to tags.cncf.io/container-device-interface/pkg/cdi.Mount.toOCI -// and made private. -func (m *Mount) ToOCI() error { - return errDeprecated -} - -// ToOCI returns the opencontainers runtime Spec LinuxDevice for this DeviceNode. -// -// Deprecated: This function has been moved to tags.cncf.io/container-device-interface/pkg/cdi.DeviceNode.toOCI -// and made private. -func (d *DeviceNode) ToOCI() error { - return errDeprecated -} - -// ToOCI returns the opencontainers runtime Spec LinuxIntelRdt for this IntelRdt config. -// -// Deprecated: This function has been moved to tags.cncf.io/container-device-interface/pkg/cdi.IntelRdt.toOCI -// and made private. -func (i *IntelRdt) ToOCI() error { - return errDeprecated -} diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/version.go b/vendor/tags.cncf.io/container-device-interface/specs-go/version.go similarity index 69% rename from vendor/tags.cncf.io/container-device-interface/pkg/cdi/version.go rename to vendor/tags.cncf.io/container-device-interface/specs-go/version.go index 9ca91267..002e0350 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/version.go +++ b/vendor/tags.cncf.io/container-device-interface/specs-go/version.go @@ -14,20 +14,18 @@ limitations under the License. */ -package cdi +package specs import ( + "fmt" "strings" "golang.org/x/mod/semver" - - "tags.cncf.io/container-device-interface/pkg/parser" - cdi "tags.cncf.io/container-device-interface/specs-go" ) const ( - // CurrentVersion is the current version of the CDI Spec. - CurrentVersion = cdi.CurrentVersion + // CurrentVersion is the current version of the Spec. + CurrentVersion = "1.0.0" // vCurrent is the current version as a semver-comparable type vCurrent version = "v" + CurrentVersion @@ -41,6 +39,7 @@ const ( v060 version = "v0.6.0" v070 version = "v0.7.0" v080 version = "v0.8.0" + v100 version = "v1.0.0" // vEarliest is the earliest supported version of the CDI specification vEarliest version = v030 @@ -58,10 +57,29 @@ var validSpecVersions = requiredVersionMap{ v060: requiresV060, v070: requiresV070, v080: requiresV080, + v100: requiresV100, +} + +// ValidateVersion checks whether the specified spec version is valid. +// In addition to checking whether the spec version is in the set of known versions, +// the spec is inspected to determine whether the features used are available in specified +// version. +func ValidateVersion(spec *Spec) error { + if !validSpecVersions.isValidVersion(spec.Version) { + return fmt.Errorf("invalid version %q", spec.Version) + } + minVersion, err := MinimumRequiredVersion(spec) + if err != nil { + return fmt.Errorf("could not determine minimum required version: %w", err) + } + if newVersion(minVersion).isGreaterThan(newVersion(spec.Version)) { + return fmt.Errorf("the spec version must be at least v%v", minVersion) + } + return nil } // MinimumRequiredVersion determines the minimum spec version for the input spec. -func MinimumRequiredVersion(spec *cdi.Spec) (string, error) { +func MinimumRequiredVersion(spec *Spec) (string, error) { minVersion := validSpecVersions.requiredVersion(spec) return minVersion.String(), nil } @@ -80,17 +98,17 @@ func (v version) String() string { return strings.TrimPrefix(string(v), "v") } -// IsGreaterThan checks with a version is greater than the specified version. -func (v version) IsGreaterThan(o version) bool { +// isGreaterThan checks with a version is greater than the specified version. +func (v version) isGreaterThan(o version) bool { return semver.Compare(string(v), string(o)) > 0 } -// IsLatest checks whether the version is the latest supported version -func (v version) IsLatest() bool { +// isLatest checks whether the version is the latest supported version +func (v version) isLatest() bool { return v == vCurrent } -type requiredFunc func(*cdi.Spec) bool +type requiredFunc func(*Spec) bool type requiredVersionMap map[version]requiredFunc @@ -103,18 +121,18 @@ func (r requiredVersionMap) isValidVersion(specVersion string) bool { } // requiredVersion returns the minimum version required for the given spec -func (r requiredVersionMap) requiredVersion(spec *cdi.Spec) version { +func (r requiredVersionMap) requiredVersion(spec *Spec) version { minVersion := vEarliest for v, isRequired := range validSpecVersions { if isRequired == nil { continue } - if isRequired(spec) && v.IsGreaterThan(minVersion) { + if isRequired(spec) && v.isGreaterThan(minVersion) { minVersion = v } // If we have already detected the latest version then no later version could be detected - if minVersion.IsLatest() { + if minVersion.isLatest() { break } } @@ -122,15 +140,22 @@ func (r requiredVersionMap) requiredVersion(spec *cdi.Spec) version { return minVersion } +// 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. +func requiresV100(_ *Spec) bool { + return false +} + // requiresV080 returns true if the spec uses v0.8.0 features. // Since the v0.8.0 spec bump was due to the removed .ToOCI functions on the -// spec types, there are explicit spec changes. -func requiresV080(_ *cdi.Spec) bool { +// spec types, there are no explicit spec changes. +func requiresV080(_ *Spec) bool { return false } // requiresV070 returns true if the spec uses v0.7.0 features -func requiresV070(spec *cdi.Spec) bool { +func requiresV070(spec *Spec) bool { if spec.ContainerEdits.IntelRdt != nil { return true } @@ -153,7 +178,7 @@ func requiresV070(spec *cdi.Spec) bool { } // requiresV060 returns true if the spec uses v0.6.0 features -func requiresV060(spec *cdi.Spec) bool { +func requiresV060(spec *Spec) bool { // The v0.6.0 spec allows annotations to be specified at a spec level for range spec.Annotations { return true @@ -167,23 +192,20 @@ func requiresV060(spec *cdi.Spec) bool { } // The v0.6.0 spec allows dots "." in Kind name label (class) - vendor, class := parser.ParseQualifier(spec.Kind) - if vendor != "" { - if strings.ContainsRune(class, '.') { - return true - } + if !strings.Contains(spec.Kind, "/") { + return false } - - return false + class := strings.SplitN(spec.Kind, "/", 2)[1] + return strings.Contains(class, ".") } // requiresV050 returns true if the spec uses v0.5.0 features -func requiresV050(spec *cdi.Spec) bool { - var edits []*cdi.ContainerEdits +func requiresV050(spec *Spec) bool { + var edits []*ContainerEdits for _, d := range spec.Devices { - // The v0.5.0 spec allowed device names to start with a digit instead of requiring a letter - if len(d.Name) > 0 && !parser.IsLetter(rune(d.Name[0])) { + // The v0.5.0 spec allowed device name to start with a digit + if len(d.Name) > 0 && '0' <= d.Name[0] && d.Name[0] <= '9' { return true } edits = append(edits, &d.ContainerEdits) @@ -202,8 +224,8 @@ func requiresV050(spec *cdi.Spec) bool { } // requiresV040 returns true if the spec uses v0.4.0 features -func requiresV040(spec *cdi.Spec) bool { - var edits []*cdi.ContainerEdits +func requiresV040(spec *Spec) bool { + var edits []*ContainerEdits for _, d := range spec.Devices { edits = append(edits, &d.ContainerEdits)