diff --git a/go.mod b/go.mod index 7db5f93b..54a00fe0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/containernetworking/cni go 1.21 require ( - github.com/Masterminds/semver/v3 v3.2.1 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 github.com/vishvananda/netns v0.0.4 diff --git a/go.sum b/go.sum index ecbacb80..ca00b627 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= diff --git a/libcni/conf.go b/libcni/conf.go index daab839f..1d1b821c 100644 --- a/libcni/conf.go +++ b/libcni/conf.go @@ -20,11 +20,10 @@ import ( "fmt" "os" "path/filepath" + "slices" "sort" "strings" - "github.com/Masterminds/semver/v3" - "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/version" ) @@ -92,24 +91,20 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { rawVersions, ok := rawList["cniVersions"] if ok { // Parse the current package CNI version - currentVersion, err := semver.NewVersion(version.Current()) - if err != nil { - panic("CNI version is invalid semver!") - } - rvs, ok := rawVersions.([]interface{}) if !ok { return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions: %T", rvs) } - vs := make([]*semver.Version, 0, len(rvs)) + vs := make([]string, 0, len(rvs)) for i, rv := range rvs { v, ok := rv.(string) if !ok { return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions index %d: %T", i, rv) } - if v, err := semver.NewVersion(v); err != nil { + gt, err := version.GreaterThan(v, version.Current()) + if err != nil { return nil, fmt.Errorf("error parsing configuration list: invalid cniVersions entry %s at index %d: %w", v, i, err) - } else if !v.GreaterThan(currentVersion) { + } else if !gt { // Skip versions "greater" than this implementation of the spec vs = append(vs, v) } @@ -117,16 +112,25 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { // if cniVersion was already set, append it to the list for sorting. if cniVersion != "" { - if v, err := semver.NewVersion(cniVersion); err != nil { + gt, err := version.GreaterThan(cniVersion, version.Current()) + if err != nil { return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion %s: %w", cniVersion, err) - } else if !v.GreaterThan(currentVersion) { + } else if !gt { // ignore any versions higher than the current implemented spec version - vs = append(vs, v) + vs = append(vs, cniVersion) } } - sort.Sort(semver.Collection(vs)) + slices.SortFunc[[]string](vs, func(v1, v2 string) int { + if v1 == v2 { + return 0 + } + if gt, _ := version.GreaterThan(v1, v2); gt { + return 1 + } + return -1 + }) if len(vs) > 0 { - cniVersion = vs[len(vs)-1].String() + cniVersion = vs[len(vs)-1] } } diff --git a/pkg/version/plugin.go b/pkg/version/plugin.go index 17b22b6b..e3bd375b 100644 --- a/pkg/version/plugin.go +++ b/pkg/version/plugin.go @@ -142,3 +142,27 @@ func GreaterThanOrEqualTo(version, otherVersion string) (bool, error) { } return false, nil } + +// GreaterThan returns true if the first version is greater than the second +func GreaterThan(version, otherVersion string) (bool, error) { + firstMajor, firstMinor, firstMicro, err := ParseVersion(version) + if err != nil { + return false, err + } + + secondMajor, secondMinor, secondMicro, err := ParseVersion(otherVersion) + if err != nil { + return false, err + } + + if firstMajor > secondMajor { + return true, nil + } else if firstMajor == secondMajor { + if firstMinor > secondMinor { + return true, nil + } else if firstMinor == secondMinor && firstMicro > secondMicro { + return true, nil + } + } + return false, nil +} diff --git a/pkg/version/version_test.go b/pkg/version/version_test.go index 2ddf5eb4..3f8f85e9 100644 --- a/pkg/version/version_test.go +++ b/pkg/version/version_test.go @@ -139,4 +139,22 @@ var _ = Describe("Version operations", func() { Expect(conf.PrevResult).To(BeNil()) }) }) + + Context("version parsing", func() { + It("parses versions correctly", func() { + v1 := "1.1.0" + v2 := "1.1.1" + + check := func(a, b string, want bool) { + GinkgoHelper() + gt, err := version.GreaterThan(a, b) + Expect(err).NotTo(HaveOccurred()) + Expect(gt).To(Equal(want)) + } + + check(v1, v2, false) + check(v2, v1, true) + check(v2, v2, false) + }) + }) })