Generate all device using merged transform

The nvcid api is extended to allow for merged device options to
be specified. If any options are specified, then a merged device
is generated.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar 2023-03-17 11:47:31 +02:00
parent ba44c50f4e
commit fe37196788
5 changed files with 46 additions and 23 deletions

View File

@ -6,6 +6,7 @@
* Create file in `etc/ld.so.conf.d` with permissions `644` to support non-root containers.
* Generate CDI specification files with `644` permissions to allow rootless applications (e.g. podman)
* Add `nvidia-ctk cdi list` command to show the known CDI devices.
* Add support for generating merged devices (e.g. `all` device) to the nvcdi API.
## v1.13.1

View File

@ -230,28 +230,16 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
return nil, fmt.Errorf("failed to create edits common for entities: %v", err)
}
spec, err := spec.New(
return spec.New(
spec.WithVendor(opts.vendor),
spec.WithClass(opts.class),
spec.WithDeviceSpecs(deviceSpecs),
spec.WithEdits(*commonEdits.ContainerEdits),
spec.WithFormat(opts.format),
spec.WithMergedDeviceOptions(
transform.WithName(allDeviceName),
transform.WithSkipIfExists(true),
),
spec.WithPermissions(0644),
)
if err != nil {
return nil, fmt.Errorf("failed to create CDI spec: %v", err)
}
addAllDevice, err := transform.NewMergedDevice(
transform.WithName(allDeviceName),
transform.WithSkipIfExists(true),
)
if err != nil {
return nil, fmt.Errorf("failed to create merged device: %v", err)
}
if err := addAllDevice.Transform(spec.Raw()); err != nil {
return nil, fmt.Errorf("failed to add merged device: %v", err)
}
return spec, nil
}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
"github.com/sirupsen/logrus"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/device"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/info"
@ -31,6 +32,8 @@ type wrapper struct {
vendor string
class string
mergedDeviceOptions []transform.MergedDeviceOption
}
type nvcdilib struct {
@ -46,6 +49,8 @@ type nvcdilib struct {
class string
infolib info.Interface
mergedDeviceOptions []transform.MergedDeviceOption
}
// New creates a new nvcdi library
@ -106,9 +111,10 @@ func New(opts ...Option) (Interface, error) {
}
w := wrapper{
Interface: lib,
vendor: l.vendor,
class: l.class,
Interface: lib,
vendor: l.vendor,
class: l.class,
mergedDeviceOptions: l.mergedDeviceOptions,
}
return &w, nil
}
@ -130,8 +136,8 @@ func (l *wrapper) GetSpec() (spec.Interface, error) {
spec.WithEdits(*edits.ContainerEdits),
spec.WithVendor(l.vendor),
spec.WithClass(l.class),
spec.WithMergedDeviceOptions(l.mergedDeviceOptions...),
)
}
// resolveMode resolves the mode for CDI spec generation based on the current system.

View File

@ -17,6 +17,7 @@
package nvcdi
import (
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/transform"
"github.com/sirupsen/logrus"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvlib/device"
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvml"
@ -87,3 +88,11 @@ func WithClass(class string) Option {
o.class = class
}
}
// WithMergedDeviceOptions sets the merged device options for the library
// If these are not set, no merged device will be generated.
func WithMergedDeviceOptions(opts ...transform.MergedDeviceOption) Option {
return func(o *nvcdilib) {
o.mergedDeviceOptions = opts
}
}

View File

@ -33,8 +33,10 @@ type builder struct {
deviceSpecs []specs.Device
edits specs.ContainerEdits
format string
noSimplify bool
permissions os.FileMode
mergedDeviceOptions []transform.MergedDeviceOption
noSimplify bool
permissions os.FileMode
}
// newBuilder creates a new spec builder with the supplied options
@ -95,6 +97,16 @@ func (o *builder) Build() (*spec, error) {
}
}
if len(o.mergedDeviceOptions) > 0 {
merge, err := transform.NewMergedDevice(o.mergedDeviceOptions...)
if err != nil {
return nil, fmt.Errorf("failed to create merged device transformer: %v", err)
}
if err := merge.Transform(raw); err != nil {
return nil, fmt.Errorf("failed to merge devices: %v", err)
}
}
s := spec{
Spec: raw,
format: o.format,
@ -169,3 +181,10 @@ func WithPermissions(permissions os.FileMode) Option {
o.permissions = permissions
}
}
// WithMergedDeviceOptions sets the options for generating a merged device.
func WithMergedDeviceOptions(opts ...transform.MergedDeviceOption) Option {
return func(o *builder) {
o.mergedDeviceOptions = opts
}
}