@@ -539,39 +539,59 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP
539539 g .SetProcessUsername (username )
540540 }
541541
542- // For both LCOW and WCOW, devices are passed through from the host to the
543- // container via the OCI Windows.Devices field
544- if err := addOCIWindowsDevices (& g , config .Devices ); err != nil {
542+ if err := addOCIDevices (& g , plat .OS , config .Devices ); err != nil {
545543 return nil , err
546544 }
547545
548546 return g .Config , nil
549547}
550548
551- // getWindowsDeviceInfo is a helper function that returns a spec specified device's
549+ // getCRIDeviceInfo is a helper function that returns a spec specified device's
552550// prefix and device identifier. A prefix is any string before "://" in the spec
553551// device's `HostPath`.
554- func getWindowsDeviceInfo (hostPath string ) (string , string , error ) {
552+ func getCRIDeviceInfo (hostPath string ) (string , string , error ) {
555553 substrings := strings .SplitN (hostPath , "://" , 2 )
556554 if len (substrings ) <= 1 {
557555 return "" , "" , fmt .Errorf ("failed to parse device information for %s" , hostPath )
558556 }
559557 return substrings [0 ], substrings [1 ], nil
560558}
561559
562- // addOCIWindowsDevices parses the devices field on the spec and creates corresponding
563- // `WindowsDevice` on the container config if valid.
564- func addOCIWindowsDevices (g * generator , devs []* runtime.Device ) error {
565- for _ , device := range devs {
566- prefix , deviceIdentifier , err := getWindowsDeviceInfo (device .HostPath )
567- if err != nil {
568- return err
569- }
570- device := runtimespec.WindowsDevice {
571- ID : deviceIdentifier ,
572- IDType : prefix ,
560+ // hasWindowsDevicePrefix returns true if the device's hostPath contains a prefix.
561+ // A prefix is any string before "://" in the spec device's `HostPath`.
562+ func hasWindowsDevicePrefix (hostPath string ) bool {
563+ return strings .Contains (hostPath , "://" )
564+ }
565+
566+ // addOCIDevices converts cri spec devices to `LinuxDevice`s or `WindowsDevice`s
567+ //
568+ // If the device's `HostPath` contains a prefix as returned by a call to `getCRIDeviceInfo`,
569+ // convert the cri device to a `WindowsDevice`. Otherwise, if we're running WCOW, convert
570+ // the cri device to a `WindowsDevice` with an unknown `IDType`. If we're running LCOW,
571+ // convert the cri device to a skeleton `LinuxDevice` where the remaining fields
572+ // must be filled out in the GCS.
573+ func addOCIDevices (g * generator , OS string , devices []* runtime.Device ) error {
574+ for _ , dev := range devices {
575+ if hasWindowsDevicePrefix (dev .HostPath ) {
576+ // handle as a WindowsDevice with known type
577+ prefix , identifier , err := getCRIDeviceInfo (dev .HostPath )
578+ if err != nil {
579+ return err
580+ }
581+ device := runtimespec.WindowsDevice {
582+ ID : identifier ,
583+ IDType : prefix ,
584+ }
585+ g .Config .Windows .Devices = append (g .Config .Windows .Devices , device )
586+ } else if OS == "linux" {
587+ // handle as a LinuxDevice, ignore cri device's `ContainerPath`
588+ rd := runtimespec.LinuxDevice {
589+ Path : dev .HostPath ,
590+ }
591+ g .AddDevice (rd )
592+ } else {
593+ return fmt .Errorf ("could not convert device %v into a spec device. OS: %s" , dev , OS )
573594 }
574- g .Config .Windows .Devices = append (g .Config .Windows .Devices , device )
575595 }
576596 return nil
577597}
0 commit comments