Skip to content

Commit

Permalink
Add logic to detect minimum spec version on save
Browse files Browse the repository at this point in the history
Signed-off-by: Evan Lezar <[email protected]>
  • Loading branch information
elezar committed Feb 4, 2025
1 parent 1dd9bff commit 0320276
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
15 changes: 12 additions & 3 deletions api/producer/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,18 @@ import (
type Option func(*options) error

type options struct {
specFormat SpecFormat
overwrite bool
permissions fs.FileMode
specFormat SpecFormat
overwrite bool
permissions fs.FileMode
detectMinimumVersion bool
}

// WithDetectMinimumVersion toggles whether a minimum version should be detected for a CDI specification.
func WithDetectMinimumVersion(detectMinimumVersion bool) Option {
return func(o *options) error {
o.detectMinimumVersion = detectMinimumVersion
return nil
}
}

// WithSpecFormat sets the output format of a CDI specification.
Expand Down
36 changes: 36 additions & 0 deletions api/producer/set-minimum-version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright © 2025 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 producer

import (
"fmt"

cdi "tags.cncf.io/container-device-interface/specs-go"
)

type setMinimumRequiredVersion struct{}

// transform detects the minimum required version required for the specified
// spec and sets the version field accordingly.
func (d setMinimumRequiredVersion) transform(spec *cdi.Spec) error {
minVersion, err := cdi.MinimumRequiredVersion(spec)
if err != nil {
return fmt.Errorf("failed to get minimum required CDI spec version: %w", err)
}
spec.Version = minVersion
return nil
}
13 changes: 13 additions & 0 deletions api/producer/spec-format.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,22 @@ func (p *specFormatter) validate() error {
return nil
}

// transform applies a transform to the spec associated with the CDI spec formatter.
// This is currently limited to detecting (and updating) the spec so that the minimum
// CDI spec version is used, but could be extended to apply other transformations.
func (p *specFormatter) transform() error {
if !p.detectMinimumVersion {
return nil
}
return (&setMinimumRequiredVersion{}).transform(p.Spec)
}

// contents returns the raw contents of a CDI specification.
// Validation is performed before marshalling the contentent based on the spec format.
func (p *specFormatter) contents() ([]byte, error) {
if err := p.transform(); err != nil {
return nil, fmt.Errorf("spec transform failed: %w", err)
}
if err := p.validate(); err != nil {
return nil, fmt.Errorf("spec validation failed: %w", err)
}
Expand Down
5 changes: 3 additions & 2 deletions api/producer/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ func NewSpecWriter(opts ...Option) (*SpecWriter, error) {
options: options{
overwrite: true,
// TODO: This could be updated to 0644 to be world-readable.
permissions: 0600,
specFormat: DefaultSpecFormat,
permissions: 0600,
specFormat: DefaultSpecFormat,
detectMinimumVersion: false,
},
}
for _, opt := range opts {
Expand Down
19 changes: 19 additions & 0 deletions api/producer/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@ devices: null
kind: example.com/class
`,
},
{
description: "minimum version is detected",
spec: cdi.Spec{
Version: cdi.CurrentVersion,
Kind: "example.com/class",
ContainerEdits: cdi.ContainerEdits{
DeviceNodes: []*cdi.DeviceNode{
{
Path: "/dev/foo",
},
},
},
},
options: []Option{WithDetectMinimumVersion(true)},
filename: "foo",
expectedFilename: "foo.yaml",
expectedPermissions: 0600,
expectedOutput: `---
cdiVersion: 0.3.0
containerEdits:
deviceNodes:
- path: /dev/foo
Expand Down

0 comments on commit 0320276

Please sign in to comment.