Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions cmd/nvidia-container-runtime-hook/container_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"os"
"path"

"github.com/Masterminds/semver/v3"
"github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/mod/semver"

"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
)
Expand Down Expand Up @@ -107,8 +107,12 @@ func (s *Spec) GetCapabilities() []string {
var caps []string
// If v1.0.0-rc1 <= OCI version < v1.0.0-rc5 parse s.Process.Capabilities as:
// github.com/opencontainers/runtime-spec/blob/v1.0.0-rc1/specs-go/config.go#L30-L54
rc1cmp := semver.Compare("v"+*s.Version, "v1.0.0-rc1")
rc5cmp := semver.Compare("v"+*s.Version, "v1.0.0-rc5")
sv, err := semver.NewVersion(*s.Version)
if err != nil {
sv = semver.MustParse("0.0.0")
}
rc1cmp := sv.Compare(semver.MustParse("v1.0.0-rc1"))
rc5cmp := sv.Compare(semver.MustParse("v1.0.0-rc5"))
if (rc1cmp == 1 || rc1cmp == 0) && (rc5cmp == -1) {
err := json.Unmarshal(*s.Process.Capabilities, &caps)
if err != nil {
Expand All @@ -120,7 +124,7 @@ func (s *Spec) GetCapabilities() []string {
// Otherwise, parse s.Process.Capabilities as:
// github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L30-L54
capabilities := specs.LinuxCapabilities{}
err := json.Unmarshal(*s.Process.Capabilities, &capabilities)
err = json.Unmarshal(*s.Process.Capabilities, &capabilities)
if err != nil {
log.Panicln("could not decode Process.Capabilities in OCI spec:", err)
}
Expand Down
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ require (
github.com/stretchr/testify v1.12.1
github.com/urfave/cli-altsrc/v3 v3.1.0
github.com/urfave/cli/v3 v3.10.1
<<<<<<< HEAD
golang.org/x/mod v0.38.0
golang.org/x/sys v0.48.0
tags.cncf.io/container-device-interface v1.1.1
tags.cncf.io/container-device-interface/specs-go v1.1.1
=======
golang.org/x/sys v0.47.0
tags.cncf.io/container-device-interface v1.1.0
tags.cncf.io/container-device-interface/specs-go v1.1.0
>>>>>>> 36e84731 (use Masterminds/semver instead of x/mod)
)

require (
Expand All @@ -35,8 +41,15 @@ require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/knqyf263/go-plugin v0.9.0 // indirect
github.com/tetratelabs/wazero v1.11.0 // indirect
<<<<<<< HEAD
go.yaml.in/yaml/v3 v3.0.5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/grpc v1.83.1 // indirect
=======
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
golang.org/x/mod v0.38.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/grpc v1.82.1 // indirect
>>>>>>> 36e84731 (use Masterminds/semver instead of x/mod)
google.golang.org/protobuf v1.36.11 // indirect
)
14 changes: 6 additions & 8 deletions internal/config/image/cuda_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
"strconv"
"strings"

"github.com/Masterminds/semver/v3"
"github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/mod/semver"
"tags.cncf.io/container-device-interface/pkg/parser"

"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
Expand Down Expand Up @@ -201,16 +201,13 @@ func (i CUDA) legacyVersion() (string, error) {
}

func parseMajorMinorVersion(version string) (string, error) {
vVersion := "v" + strings.TrimPrefix(version, "v")

if !semver.IsValid(vVersion) {
return "", fmt.Errorf("invalid version string")
sv, err := semver.NewVersion(version)
if err != nil {
return "", fmt.Errorf("invalid version string: %w", err)
}

majorMinor := strings.TrimPrefix(semver.MajorMinor(vVersion), "v")
majorMinor := fmt.Sprintf("%d.%d", sv.Major(), sv.Minor())
parts := strings.Split(majorMinor, ".")

var err error
_, err = strconv.ParseUint(parts[0], 10, 32)
if err != nil {
return "", fmt.Errorf("invalid major version")
Expand All @@ -219,6 +216,7 @@ func parseMajorMinorVersion(version string) (string, error) {
if err != nil {
return "", fmt.Errorf("invalid minor version")
}

return majorMinor, nil
}

Expand Down
24 changes: 13 additions & 11 deletions internal/requirements/constraints/property.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ package constraints

import (
"fmt"
"strings"

"golang.org/x/mod/semver"
"github.com/Masterminds/semver/v3"
)

// Property represents a property that is used to check requirements
Expand Down Expand Up @@ -111,20 +110,23 @@ func (p versionProperty) CompareTo(other string) (int, error) {
return 0, fmt.Errorf("invailid value for %v: %v", p.name, err)
}

vValue := ensurePrefix(p.value, "v")
vOther := ensurePrefix(other, "v")
return semver.Compare(vValue, vOther), nil
value, err := semver.NewVersion(p.value)
if err != nil {
return 0, fmt.Errorf("invalid value for %v: %w", p.name, err)
}
otherVersion, err := semver.NewVersion(other)
if err != nil {
return 0, fmt.Errorf("invalid value for %v: %w", p.name, err)
}
return value.Compare(otherVersion), nil
}

// Validate checks whether the supplied value is a valid semantic version
func (p versionProperty) Validate(value string) error {
if !semver.IsValid(ensurePrefix(value, "v")) {
return fmt.Errorf("invailid value %v; expected a valid version string", value)
_, err := semver.NewVersion(value)
if err != nil {
return fmt.Errorf("invalid version string: %w", err)
}

return nil
}

func ensurePrefix(s string, prefix string) string {
return prefix + strings.TrimPrefix(s, prefix)
}
6 changes: 3 additions & 3 deletions tests/e2e/nvidia-container-toolkit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"golang.org/x/mod/semver"
"github.com/Masterminds/semver/v3"
)

// Integration tests for Docker runtime
Expand Down Expand Up @@ -491,7 +491,7 @@ EOF`)

It("should fail when using the nvidia-container-runtime-hook", Label("legacy"), func(ctx context.Context) {
// Prior to Docker v29.2.0, the --gpus flag would inject the nvidia-container-runtime-hook.
if semver.Compare(dockerVersion, "v29.2.0") >= 0 {
if semver.MustParse(dockerVersion).Compare(semver.MustParse("v29.2.0")) >= 0 {
Skip(fmt.Sprintf("This test requires Docker < v29.2.0. Found %s", dockerVersion))
}
output, stderr, err := runner.Run("docker run --rm --runtime=runc --gpus=all firmware-test")
Expand All @@ -503,7 +503,7 @@ EOF`)
It("should not fail when the --gpus flag is handled as a CDI request", func(ctx context.Context) {
// As of Docker v29.2.0, the --gpus flag is handled as a CDI
// device request if CDI specs are available.
if semver.Compare(dockerVersion, "v29.2.0") < 0 {
if semver.MustParse(dockerVersion).Compare(semver.MustParse("v29.2.0")) < 0 {
Skip(fmt.Sprintf("This test requires Docker >= v29.2.0. Found %s", dockerVersion))
}
output, stderr, err := runner.Run("docker run --rm --runtime=runc --gpus=all firmware-test")
Expand Down