1717package cdi
1818
1919import (
20+ "io/fs"
21+ "os"
2022 "path/filepath"
2123 "sort"
2224 "strings"
2325 "sync"
2426
27+ stderr "errors"
28+
2529 cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
2630 "github.com/fsnotify/fsnotify"
2731 "github.com/hashicorp/go-multierror"
@@ -255,6 +259,19 @@ func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, e
255259 return nil , nil
256260}
257261
262+ // highestPrioritySpecDir returns the Spec directory with highest priority
263+ // and its priority.
264+ func (c * Cache ) highestPrioritySpecDir () (string , int ) {
265+ if len (c .specDirs ) == 0 {
266+ return "" , - 1
267+ }
268+
269+ prio := len (c .specDirs ) - 1
270+ dir := c .specDirs [prio ]
271+
272+ return dir , prio
273+ }
274+
258275// WriteSpec writes a Spec file with the given content into the highest
259276// priority Spec directory. If name has a "json" or "yaml" extension it
260277// choses the encoding. Otherwise JSON encoding is used with a "json"
@@ -268,12 +285,11 @@ func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error {
268285 err error
269286 )
270287
271- if len (c .specDirs ) == 0 {
288+ specDir , prio = c .highestPrioritySpecDir ()
289+ if specDir == "" {
272290 return errors .New ("no Spec directories to write to" )
273291 }
274292
275- prio = len (c .specDirs ) - 1
276- specDir = c .specDirs [prio ]
277293 path = filepath .Join (specDir , name )
278294 if ext := filepath .Ext (path ); ext != ".json" && ext != ".yaml" {
279295 path += ".json"
@@ -287,6 +303,35 @@ func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error {
287303 return spec .Write (true )
288304}
289305
306+ // RemoveSpec removes a Spec with the given name from the highest
307+ // priority Spec directory. This function can be used to remove a
308+ // Spec previously written by WriteSpec(). If the file exists and
309+ // its removal fails RemoveSpec returns an error.
310+ func (c * Cache ) RemoveSpec (name string ) error {
311+ var (
312+ specDir string
313+ path string
314+ err error
315+ )
316+
317+ specDir , _ = c .highestPrioritySpecDir ()
318+ if specDir == "" {
319+ return errors .New ("no Spec directories to remove from" )
320+ }
321+
322+ path = filepath .Join (specDir , name )
323+ if ext := filepath .Ext (path ); ext != ".json" && ext != ".yaml" {
324+ path += ".json"
325+ }
326+
327+ err = os .Remove (path )
328+ if err != nil && stderr .Is (err , fs .ErrNotExist ) {
329+ err = nil
330+ }
331+
332+ return err
333+ }
334+
290335// GetDevice returns the cached device for the given qualified name.
291336func (c * Cache ) GetDevice (device string ) * Device {
292337 c .Lock ()
0 commit comments