diff --git a/go.mod b/go.mod index 464154e85..6750cbe9d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/hybrid-cloud-patterns/patterns-operator -go 1.24.6 +go 1.26.0 require ( code.gitea.io/sdk/gitea v0.23.2 @@ -23,14 +23,14 @@ require ( gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.18.6 k8s.io/api v0.33.4 - k8s.io/apimachinery v0.36.0-alpha.1 + k8s.io/apimachinery v0.36.0-beta.0 k8s.io/client-go v12.0.0+incompatible sigs.k8s.io/controller-runtime v0.21.0 ) require ( github.com/argoproj/argo-cd/v3 v3.0.23 - sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86 + sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260331165415-bce0ec74ad73 sigs.k8s.io/controller-tools v0.16.4 ) @@ -190,7 +190,7 @@ require ( gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/grpc v1.79.3 // indirect - google.golang.org/protobuf v1.36.11 // indirect + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 1e93e2fb6..e4bc74441 100644 --- a/go.sum +++ b/go.sum @@ -664,8 +664,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -725,8 +725,8 @@ oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86 h1:96TA+X7D58V3065duUfj+p+Pp17q8U02+cSCmE3IsaU= -sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86/go.mod h1:IaDsO8xSPRxRG1/rm9CP7+jPmj0nMNAuNi/yiHnLX8k= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260331165415-bce0ec74ad73 h1:2l3wo/H6M2JGEnjqeRP3vIx1Ob9yzqjayoksc7YuEK4= +sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260331165415-bce0ec74ad73/go.mod h1:K1AkL5uTv9m0NMzQ+ULndYovO4u9vwO/voMwXt09cOg= sigs.k8s.io/controller-tools v0.16.4 h1:VXmar78eDXbx1by/H09ikEq1hiq3bqInxuV3lMr3GmQ= sigs.k8s.io/controller-tools v0.16.4/go.mod h1:kcsZyYMXiOFuBhofSPtkB90zTSxVRxVVyvtKQcx3q1A= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= diff --git a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go index 2ef36bbcf..ec63689e7 100644 --- a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go +++ b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go @@ -10,6 +10,7 @@ import ( "encoding/binary" "fmt" "io" + "math" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" @@ -117,7 +118,13 @@ func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error { if maxSize == 0 { maxSize = defaultMaxSize } - if maxSize != -1 && size > uint64(maxSize) { + if maxSize == -1 { + // No limit specified: Just check that size fits into an integer, + // otherwise the make([]byte, size) call below will panic. + if size > math.MaxInt { + return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: math.MaxInt}, "") + } + } else if size > uint64(maxSize) { return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: uint64(maxSize)}, "") } diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index b53805056..20ec09e19 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -8,6 +8,7 @@ import ( "fmt" "unicode/utf8" + "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/text" "google.golang.org/protobuf/internal/errors" @@ -49,12 +50,19 @@ type UnmarshalOptions struct { protoregistry.MessageTypeResolver protoregistry.ExtensionTypeResolver } + + // RecursionLimit limits how deeply messages may be nested. + // If zero, a default limit is applied. + RecursionLimit int } // Unmarshal reads the given []byte and populates the given [proto.Message] // using options in the UnmarshalOptions object. // The provided message must be mutable (e.g., a non-nil pointer to a message). func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error { + if o.RecursionLimit == 0 { + o.RecursionLimit = protowire.DefaultRecursionLimit + } return o.unmarshal(b, m) } @@ -102,8 +110,14 @@ func (d decoder) syntaxError(pos int, f string, x ...any) error { return errors.New(head+f, x...) } +var errRecursionDepth = errors.New("exceeded maximum recursion depth") + // unmarshalMessage unmarshals into the given protoreflect.Message. func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + messageDesc := m.Descriptor() if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { return errors.New("no support for proto1 MessageSets") @@ -437,6 +451,10 @@ func (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflec // unmarshalMap unmarshals into given protoreflect.Map. A map value is a // textproto message containing {key: , value: }. func (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + // Determine ahead whether map entry is a scalar type or a message type in // order to call the appropriate unmarshalMapValue func inside // unmarshalMapEntry. diff --git a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go index 87e46bd4d..0b0dfacbe 100644 --- a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go +++ b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go @@ -83,12 +83,13 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { case protoreflect.FileImports: for i := 0; i < vs.Len(); i++ { var rs records - rv := reflect.ValueOf(vs.Get(i)) - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPublic"), "IsPublic"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, + fi := vs.Get(i) + rv := reflect.ValueOf(fi) + rs.Append(rv, []attrAndName{ + {fi.Path(), "Path"}, + {fi.Package(), "Package"}, + {fi.IsPublic, "IsPublic"}, + {fi.IsWeak, "IsWeak"}, }...) ss = append(ss, "{"+rs.Join()+"}") } @@ -104,9 +105,9 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } } -type methodAndName struct { - method reflect.Value - name string +type attrAndName struct { + attr any + name string } func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) { @@ -126,58 +127,58 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu start = rt.Name() + "{" } - _, isFile := t.(protoreflect.FileDescriptor) + fd, isFile := t.(protoreflect.FileDescriptor) rs := records{ allowMulti: allowMulti, record: record, } if t.IsPlaceholder() { if isFile { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {fd.Path(), "Path"}, + {fd.Package(), "Package"}, + {fd.IsPlaceholder(), "IsPlaceholder"}, }...) } else { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("FullName"), "FullName"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {t.FullName(), "FullName"}, + {t.IsPlaceholder(), "IsPlaceholder"}, }...) } } else { switch { case isFile: - rs.Append(rv, methodAndName{rv.MethodByName("Syntax"), "Syntax"}) + rs.Append(rv, attrAndName{fd.Syntax(), "Syntax"}) case isRoot: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Syntax"), "Syntax"}, - {rv.MethodByName("FullName"), "FullName"}, + rs.Append(rv, []attrAndName{ + {t.Syntax(), "Syntax"}, + {t.FullName(), "FullName"}, }...) default: - rs.Append(rv, methodAndName{rv.MethodByName("Name"), "Name"}) + rs.Append(rv, attrAndName{t.Name(), "Name"}) } switch t := t.(type) { case protoreflect.FieldDescriptor: - accessors := []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - {rv.MethodByName("Cardinality"), "Cardinality"}, - {rv.MethodByName("Kind"), "Kind"}, - {rv.MethodByName("HasJSONName"), "HasJSONName"}, - {rv.MethodByName("JSONName"), "JSONName"}, - {rv.MethodByName("HasPresence"), "HasPresence"}, - {rv.MethodByName("IsExtension"), "IsExtension"}, - {rv.MethodByName("IsPacked"), "IsPacked"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, - {rv.MethodByName("IsList"), "IsList"}, - {rv.MethodByName("IsMap"), "IsMap"}, - {rv.MethodByName("MapKey"), "MapKey"}, - {rv.MethodByName("MapValue"), "MapValue"}, - {rv.MethodByName("HasDefault"), "HasDefault"}, - {rv.MethodByName("Default"), "Default"}, - {rv.MethodByName("ContainingOneof"), "ContainingOneof"}, - {rv.MethodByName("ContainingMessage"), "ContainingMessage"}, - {rv.MethodByName("Message"), "Message"}, - {rv.MethodByName("Enum"), "Enum"}, + accessors := []attrAndName{ + {t.Number(), "Number"}, + {t.Cardinality(), "Cardinality"}, + {t.Kind(), "Kind"}, + {t.HasJSONName(), "HasJSONName"}, + {t.JSONName(), "JSONName"}, + {t.HasPresence(), "HasPresence"}, + {t.IsExtension(), "IsExtension"}, + {t.IsPacked(), "IsPacked"}, + {t.IsWeak(), "IsWeak"}, + {t.IsList(), "IsList"}, + {t.IsMap(), "IsMap"}, + {t.MapKey(), "MapKey"}, + {t.MapValue(), "MapValue"}, + {t.HasDefault(), "HasDefault"}, + {t.Default(), "Default"}, + {t.ContainingOneof(), "ContainingOneof"}, + {t.ContainingMessage(), "ContainingMessage"}, + {t.Message(), "Message"}, + {t.Enum(), "Enum"}, } for _, s := range accessors { switch s.name { @@ -223,58 +224,54 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu } case protoreflect.FileDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("Imports"), "Imports"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, - {rv.MethodByName("Services"), "Services"}, + rs.Append(rv, []attrAndName{ + {t.Path(), "Path"}, + {t.Package(), "Package"}, + {t.Imports(), "Imports"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, + {t.Services(), "Services"}, }...) case protoreflect.MessageDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("IsMapEntry"), "IsMapEntry"}, - {rv.MethodByName("Fields"), "Fields"}, - {rv.MethodByName("Oneofs"), "Oneofs"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("RequiredNumbers"), "RequiredNumbers"}, - {rv.MethodByName("ExtensionRanges"), "ExtensionRanges"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, + rs.Append(rv, []attrAndName{ + {t.IsMapEntry(), "IsMapEntry"}, + {t.Fields(), "Fields"}, + {t.Oneofs(), "Oneofs"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.RequiredNumbers(), "RequiredNumbers"}, + {t.ExtensionRanges(), "ExtensionRanges"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, }...) case protoreflect.EnumDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Values"), "Values"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("IsClosed"), "IsClosed"}, + rs.Append(rv, []attrAndName{ + {t.Values(), "Values"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.IsClosed(), "IsClosed"}, }...) case protoreflect.EnumValueDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - }...) + rs.Append(rv, attrAndName{t.Number(), "Number"}) case protoreflect.ServiceDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Methods"), "Methods"}, - }...) + rs.Append(rv, attrAndName{t.Methods(), "Methods"}) case protoreflect.MethodDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Input"), "Input"}, - {rv.MethodByName("Output"), "Output"}, - {rv.MethodByName("IsStreamingClient"), "IsStreamingClient"}, - {rv.MethodByName("IsStreamingServer"), "IsStreamingServer"}, + rs.Append(rv, []attrAndName{ + {t.Input(), "Input"}, + {t.Output(), "Output"}, + {t.IsStreamingClient(), "IsStreamingClient"}, + {t.IsStreamingServer(), "IsStreamingServer"}, }...) } - if m := rv.MethodByName("GoType"); m.IsValid() { - rs.Append(rv, methodAndName{m, "GoType"}) + if m, ok := t.(interface{ GoType() reflect.Type }); ok { + rs.Append(rv, attrAndName{m.GoType(), "GoType"}) } } return start + rs.Join() + end @@ -297,68 +294,66 @@ func (rs *records) AppendRecs(fieldName string, newRecs [2]string) { rs.recs = append(rs.recs, newRecs) } -func (rs *records) Append(v reflect.Value, accessors ...methodAndName) { - for _, a := range accessors { - if rs.record != nil { - rs.record(a.name) - } - var rv reflect.Value - if a.method.IsValid() { - rv = a.method.Call(nil)[0] - } - if v.Kind() == reflect.Struct && !rv.IsValid() { - rv = v.FieldByName(a.name) - } - if !rv.IsValid() { - panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a.name)) - } - if _, ok := rv.Interface().(protoreflect.Value); ok { - rv = rv.MethodByName("Interface").Call(nil)[0] - if !rv.IsNil() { - rv = rv.Elem() - } - } +func (rs *records) Append(v reflect.Value, results ...attrAndName) { + for _, r := range results { + rs.appendAttribute(v, r.name, r.attr) + } +} - // Ignore zero values. - var isZero bool - switch rv.Kind() { - case reflect.Interface, reflect.Slice: - isZero = rv.IsNil() - case reflect.Bool: - isZero = rv.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - isZero = rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - isZero = rv.Uint() == 0 - case reflect.String: - isZero = rv.String() == "" - } - if n, ok := rv.Interface().(list); ok { - isZero = n.Len() == 0 - } - if isZero { - continue +func (rs *records) appendAttribute(val reflect.Value, name string, attrVal any) { + if rs.record != nil { + rs.record(name) + } + if attrVal == nil { + return + } + rv := reflect.ValueOf(attrVal) + if _, ok := rv.Interface().(protoreflect.Value); ok { + rv = rv.MethodByName("Interface").Call(nil)[0] + if !rv.IsNil() { + rv = rv.Elem() } + } - // Format the value. - var s string - v := rv.Interface() - switch v := v.(type) { - case list: - s = formatListOpt(v, false, rs.allowMulti) - case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: - s = string(v.(protoreflect.Descriptor).Name()) - case protoreflect.Descriptor: - s = string(v.FullName()) - case string: - s = strconv.Quote(v) - case []byte: - s = fmt.Sprintf("%q", v) - default: - s = fmt.Sprint(v) - } - rs.recs = append(rs.recs, [2]string{a.name, s}) + // Ignore zero values. + var isZero bool + switch rv.Kind() { + case reflect.Interface, reflect.Slice: + isZero = rv.IsNil() + case reflect.Bool: + isZero = rv.Bool() == false + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + isZero = rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + isZero = rv.Uint() == 0 + case reflect.String: + isZero = rv.String() == "" + } + if n, ok := rv.Interface().(list); ok { + isZero = n.Len() == 0 + } + if isZero { + return + } + + // Format the value. + var s string + v := rv.Interface() + switch v := v.(type) { + case list: + s = formatListOpt(v, false, rs.allowMulti) + case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: + s = string(v.(protoreflect.Descriptor).Name()) + case protoreflect.Descriptor: + s = string(v.FullName()) + case string: + s = strconv.Quote(v) + case []byte: + s = fmt.Sprintf("%q", v) + default: + s = fmt.Sprint(v) } + rs.recs = append(rs.recs, [2]string{name, s}) } func (rs *records) Join() string { diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 763fd8284..bfb2cfdea 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -53,7 +53,7 @@ const ( Major = 1 Minor = 36 Patch = 11 - PreRelease = "" + PreRelease = "devel" ) // String formats the version string for this module in semver format. diff --git a/vendor/modules.txt b/vendor/modules.txt index 51c236374..e463b5253 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -985,7 +985,7 @@ google.golang.org/grpc/internal google.golang.org/grpc/internal/status google.golang.org/grpc/serviceconfig google.golang.org/grpc/status -# google.golang.org/protobuf v1.36.11 +# google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af ## explicit; go 1.23 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/prototext @@ -1117,7 +1117,7 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1 k8s.io/apiextensions-apiserver/pkg/features -# k8s.io/apimachinery v0.36.0-alpha.1 => k8s.io/apimachinery v0.33.4 +# k8s.io/apimachinery v0.36.0-beta.0 => k8s.io/apimachinery v0.33.4 ## explicit; go 1.24.0 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -1841,12 +1841,13 @@ sigs.k8s.io/controller-runtime/pkg/webhook/admission sigs.k8s.io/controller-runtime/pkg/webhook/admission/metrics sigs.k8s.io/controller-runtime/pkg/webhook/conversion sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics -# sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86 -## explicit; go 1.22.0 +# sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20260331165415-bce0ec74ad73 +## explicit; go 1.26.0 sigs.k8s.io/controller-runtime/tools/setup-envtest sigs.k8s.io/controller-runtime/tools/setup-envtest/env sigs.k8s.io/controller-runtime/tools/setup-envtest/remote sigs.k8s.io/controller-runtime/tools/setup-envtest/store +sigs.k8s.io/controller-runtime/tools/setup-envtest/version sigs.k8s.io/controller-runtime/tools/setup-envtest/versions sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows # sigs.k8s.io/controller-tools v0.16.4 diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md index 0482dd316..9cbf185ce 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/README.md @@ -4,17 +4,20 @@ This is a small tool that manages binaries for envtest. It can be used to download new binaries, list currently installed and available ones, and clean up versions. -To use it, just go-install it with Golang 1.22+ (it's a separate, self-contained -module): +To use it, download the binary from the [release page.](https://github.com/kubernetes-sigs/controller-runtime/releases) + +If you want to install this with Golang, you can install a release by using a release branch instead. + +NOTE: Each release branch may prefer a different version of Golang when installing. ```shell -go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest +go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.22 ``` -If you are using Golang 1.20 or 1.21, use the `release-0.17` branch instead: +If you are using Golang 1.23, use the `release-0.20` branch instead: ```shell -go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.17 +go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.20 ``` For full documentation, run it with the `--help` flag, but here are some @@ -47,16 +50,11 @@ setup-envtest use -i --use-env # sideload a pre-downloaded tarball as Kubernetes 1.16.2 into our store setup-envtest sideload 1.16.2 < downloaded-envtest.tar.gz -# Per default envtest binaries are downloaded from: +# Per default envtest binaries are downloaded from: # https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/master/envtest-releases.yaml # To download from a custom index use the following: setup-envtest use --index https://custom.com/envtest-releases.yaml -# To download from the kubebuilder-tools GCS bucket: (default behavior before v0.18) -# Note: This is a Google-owned bucket and it might be shutdown at any time -# see: https://github.com/kubernetes/k8s.io/issues/2647#event-12439345373 -# Note: This flag will also be removed soon. -setup-envtest use --use-deprecated-gcs ``` ## Where does it put all those binaries? @@ -107,8 +105,7 @@ Then, you have a few options for managing your binaries: `--use-env` makes the command unconditionally use the value of KUBEBUILDER_ASSETS as long as it contains the required binaries, and - `-i` indicates that we only ever want to work with installed binaries - (no reaching out the remote GCS storage). + `-i` indicates that we only ever want to work with installed binaries. As noted about, you can use `ENVTEST_INSTALLED_ONLY=true` to switch `-i` on by default, and you can use `ENVTEST_USE_ENV=true` to switch @@ -123,25 +120,3 @@ Then, you have a few options for managing your binaries: - If you want to talk to some internal source via HTTP, you can simply set `--index` The index must contain references to envtest binary archives in the same format as: https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/master/envtest-releases.yaml - -- If you want to talk to some internal source in a GCS "style", you can use the - `--remote-bucket` and `--remote-server` options together with `--use-deprecated-gcs`. - Note: This is deprecated and will be removed soon. The former sets which - GCS bucket to download from, and the latter sets the host to talk to as - if it were a GCS endpoint. Theoretically, you could use the latter - version to run an internal "mirror" -- the tool expects - - - `HOST/storage/v1/b/BUCKET/o` to return JSON like - - ```json - {"items": [ - {"name": "kubebuilder-tools-X.Y.Z-os-arch.tar.gz", "md5Hash": ""}, - {"name": "kubebuilder-tools-X.Y.Z-os-arch.tar.gz", "md5Hash": ""} - ]} - ``` - - - `HOST/storage/v1/b/BUCKET/o/TARBALL_NAME` to return JSON like - `{"name": "kubebuilder-tools-X.Y.Z-os-arch.tar.gz", "md5Hash": ""}` - - - `HOST/storage/v1/b/BUCKET/o/TARBALL_NAME?alt=media` to return the - actual file contents diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go index 24857916d..cfcad3505 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/env.go @@ -10,7 +10,7 @@ import ( "io" "io/fs" "path/filepath" - "sort" + "slices" "strings" "text/tabwriter" @@ -42,10 +42,6 @@ type Env struct { // contact remote services & re-download. ForceDownload bool - // UseDeprecatedGCS signals if the GCS client is used. - // Note: This will be removed together with remote.GCSClient. - UseDeprecatedGCS bool - // Client is our remote client for contacting remote services. Client remote.Client @@ -125,9 +121,10 @@ func (e *Env) ListVersions(ctx context.Context) { if !e.Version.Matches(set.Version) { continue } - sort.Slice(set.Platforms, func(i, j int) bool { - return orderPlatforms(set.Platforms[i].Platform, set.Platforms[j].Platform) + slices.SortStableFunc(set.Platforms, func(i, j versions.PlatformItem) int { + return orderPlatforms(i.Platform, j.Platform) }) + for _, plat := range set.Platforms { if e.Platform.Matches(plat.Platform) { fmt.Fprintf(out, "(available)\tv%s\t%s\n", set.Version, plat) @@ -250,7 +247,7 @@ func (e *Env) EnsureVersionIsSet(ctx context.Context) { serverVer, platform := e.LatestVersion(ctx) // if we're not forcing a download, and we have a newer local version, just use that - if !e.ForceDownload && localVer != nil && localVer.NewerThan(serverVer) { + if !e.ForceDownload && localVer != nil && localVer.Compare(serverVer) > 0 { e.Platform.Platform = localPlat // update our data with hash e.Version.MakeConcrete(*localVer) return @@ -291,7 +288,7 @@ func (e *Env) Fetch(ctx context.Context) { } }) - archiveOut, err := e.FS.TempFile("", "*-"+e.Platform.ArchiveName(e.UseDeprecatedGCS, *e.Version.AsConcrete())) + archiveOut, err := e.FS.TempFile("", "*-"+e.Platform.ArchiveName(*e.Version.AsConcrete())) if err != nil { ExitCause(2, err, "unable to open file to write downloaded archive to") } diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go index ae393b593..640e65a4f 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/exit.go @@ -12,7 +12,7 @@ import ( // Exit exits with the given code and error message. // // Defer HandleExitWithCode in main to catch this and get the right behavior. -func Exit(code int, msg string, args ...interface{}) { +func Exit(code int, msg string, args ...any) { panic(&exitCode{ code: code, err: fmt.Errorf(msg, args...), @@ -23,7 +23,7 @@ func Exit(code int, msg string, args ...interface{}) { // wrapping the underlying error passed as well. // // Defer HandleExitWithCode in main to catch this and get the right behavior. -func ExitCause(code int, err error, msg string, args ...interface{}) { +func ExitCause(code int, err error, msg string, args ...any) { args = append(args, err) panic(&exitCode{ code: code, @@ -48,7 +48,7 @@ func (c *exitCode) Unwrap() error { // asExit checks if the given (panic) value is an exitCode error, // and if so stores it in the given pointer. It's roughly analogous // to errors.As, except it works on recover() values. -func asExit(val interface{}, exit **exitCode) bool { +func asExit(val any, exit **exitCode) bool { if val == nil { return false } @@ -81,7 +81,7 @@ func HandleExitWithCode() { // the cause. // // It's mainly useful for testing, normally you'd use HandleExitWithCode. -func CheckRecover(cause interface{}, cb func(int, error)) bool { +func CheckRecover(cause any, cb func(int, error)) bool { if cause == nil { return false } diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go index 2c98c88d9..857208851 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/env/helpers.go @@ -5,17 +5,18 @@ package env import ( "fmt" + "strings" "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" ) // orderPlatforms orders platforms by OS then arch. -func orderPlatforms(first, second versions.Platform) bool { +func orderPlatforms(first, second versions.Platform) int { // sort by OS, then arch if first.OS != second.OS { - return first.OS < second.OS + return strings.Compare(first.OS, second.OS) } - return first.Arch < second.Arch + return strings.Compare(first.Arch, second.Arch) } // PrintFormat indicates how to print out fetch and switch results. diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go index 7e2761a4f..7eb5ec43d 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/main.go @@ -50,16 +50,7 @@ var ( binDir = flag.String("bin-dir", "", "directory to store binary assets (default: $OS_SPECIFIC_DATA_DIR/envtest-binaries)") - useDeprecatedGCS = flag.Bool("use-deprecated-gcs", false, "use GCS to fetch envtest binaries. Note: This is deprecated and will be removed soon. For more details see: https://github.com/kubernetes-sigs/controller-runtime/pull/2811") - - // These flags are only used with --use-deprecated-gcs. - remoteBucket = flag.String("remote-bucket", "kubebuilder-tools", "remote GCS bucket to download from (only used with --use-deprecated-gcs)") - remoteServer = flag.String("remote-server", "storage.googleapis.com", - "remote server to query from. You can override this if you want to run "+ - "an internal storage server instead, or for testing. (only used with --use-deprecated-gcs)") - - // This flag is only used if --use-deprecated-gcs is not set or false (default). - index = flag.String("index", remote.DefaultIndexURL, "index to discover envtest binaries (only used if --use-deprecated-gcs is not set, or set to false)") + index = flag.String("index", remote.DefaultIndexURL, "index to discover envtest binaries") ) // TODO(directxman12): handle interrupts? @@ -88,29 +79,18 @@ func setupEnv(globalLog logr.Logger, version string) *envp.Env { } log.V(1).Info("using binaries directory", "dir", *binDir) - var client remote.Client - if useDeprecatedGCS != nil && *useDeprecatedGCS { - client = &remote.GCSClient{ //nolint:staticcheck // deprecation accepted for now - Log: globalLog.WithName("storage-client"), - Bucket: *remoteBucket, - Server: *remoteServer, - } - log.V(1).Info("using deprecated GCS client", "bucket", *remoteBucket, "server", *remoteServer) - } else { - client = &remote.HTTPClient{ - Log: globalLog.WithName("storage-client"), - IndexURL: *index, - } - log.V(1).Info("using HTTP client", "index", *index) + client := &remote.HTTPClient{ + Log: globalLog.WithName("storage-client"), + IndexURL: *index, } + log.V(1).Info("using HTTP client", "index", *index) env := &envp.Env{ - Log: globalLog, - UseDeprecatedGCS: useDeprecatedGCS != nil && *useDeprecatedGCS, - Client: client, - VerifySum: *verify, - ForceDownload: *force, - NoDownload: *installedOnly, + Log: globalLog, + Client: client, + VerifySum: *verify, + ForceDownload: *force, + NoDownload: *installedOnly, Platform: versions.PlatformItem{ Platform: versions.Platform{ OS: *targetOS, @@ -189,7 +169,7 @@ Commands: use: get information for the requested version, downloading it if necessary and allowed. - Needs a concrete platform (no wildcards), but wilcard versions are supported. + Needs a concrete platform (no wildcards), but wildcard versions are supported. list: list installed *and* available versions matching the given version & platform. @@ -204,6 +184,9 @@ Commands: reads a .tar.gz file from stdin and expand it into the store. must have a concrete version and platform. + version: + list the installed version of setup-envtest. + Versions: Versions take the form of a small subset of semver selectors. @@ -276,7 +259,6 @@ Environment Variables: version = flag.Arg(1) } env := setupEnv(globalLog, version) - // perform our main set of actions switch action := flag.Arg(0); action { case "use": @@ -294,6 +276,8 @@ Environment Variables: Input: os.Stdin, PrintFormat: printFormat, }.Do(env) + case "version": + workflows.Version{}.Do(env) default: flag.Usage() envp.Exit(2, "unknown action %q", action) diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/gcs_client.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/gcs_client.go deleted file mode 100644 index 85f321d5c..000000000 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/gcs_client.go +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2021 The Kubernetes Authors - -package remote - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "path" - "sort" - - "github.com/go-logr/logr" - "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" -) - -// objectList is the parts we need of the GCS "list-objects-in-bucket" endpoint. -type objectList struct { - Items []bucketObject `json:"items"` - NextPageToken string `json:"nextPageToken"` -} - -// bucketObject is the parts we need of the GCS object metadata. -type bucketObject struct { - Name string `json:"name"` - Hash string `json:"md5Hash"` -} - -var _ Client = &GCSClient{} - -// GCSClient is a basic client for fetching versions of the envtest binary archives -// from GCS. -// -// Deprecated: This client is deprecated and will be removed soon. -// The kubebuilder GCS bucket that we use with this client might be shutdown at any time, -// see: https://github.com/kubernetes/k8s.io/issues/2647. -type GCSClient struct { - // Bucket is the bucket to fetch from. - Bucket string - - // Server is the GCS-like storage server - Server string - - // Log allows us to log. - Log logr.Logger - - // Insecure uses http for testing - Insecure bool -} - -func (c *GCSClient) scheme() string { - if c.Insecure { - return "http" - } - return "https" -} - -// ListVersions lists all available tools versions in the given bucket, along -// with supported os/arch combos and the corresponding hash. -// -// The results are sorted with newer versions first. -func (c *GCSClient) ListVersions(ctx context.Context) ([]versions.Set, error) { - loc := &url.URL{ - Scheme: c.scheme(), - Host: c.Server, - Path: path.Join("/storage/v1/b/", c.Bucket, "o"), - } - query := make(url.Values) - - knownVersions := map[versions.Concrete][]versions.PlatformItem{} - for cont := true; cont; { - c.Log.V(1).Info("listing bucket to get versions", "bucket", c.Bucket) - - loc.RawQuery = query.Encode() - req, err := http.NewRequestWithContext(ctx, "GET", loc.String(), nil) - if err != nil { - return nil, fmt.Errorf("unable to construct request to list bucket items: %w", err) - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return nil, fmt.Errorf("unable to perform request to list bucket items: %w", err) - } - - err = func() error { - defer resp.Body.Close() - if resp.StatusCode != 200 { - return fmt.Errorf("unable list bucket items -- got status %q from GCS", resp.Status) - } - - var list objectList - if err := json.NewDecoder(resp.Body).Decode(&list); err != nil { - return fmt.Errorf("unable unmarshal bucket items list: %w", err) - } - - // continue listing if needed - cont = list.NextPageToken != "" - query.Set("pageToken", list.NextPageToken) - - for _, item := range list.Items { - ver, details := versions.ExtractWithPlatform(versions.ArchiveRE, item.Name) - if ver == nil { - c.Log.V(1).Info("skipping bucket object -- does not appear to be a versioned tools object", "name", item.Name) - continue - } - c.Log.V(1).Info("found version", "version", ver, "platform", details) - knownVersions[*ver] = append(knownVersions[*ver], versions.PlatformItem{ - Platform: details, - Hash: &versions.Hash{ - Type: versions.MD5HashType, - Encoding: versions.Base64HashEncoding, - Value: item.Hash, - }, - }) - } - - return nil - }() - if err != nil { - return nil, err - } - } - - res := make([]versions.Set, 0, len(knownVersions)) - for ver, details := range knownVersions { - res = append(res, versions.Set{Version: ver, Platforms: details}) - } - // sort in inverse order so that the newest one is first - sort.Slice(res, func(i, j int) bool { - first, second := res[i].Version, res[j].Version - return first.NewerThan(second) - }) - - return res, nil -} - -// GetVersion downloads the given concrete version for the given concrete platform, writing it to the out. -func (c *GCSClient) GetVersion(ctx context.Context, version versions.Concrete, platform versions.PlatformItem, out io.Writer) error { - itemName := platform.ArchiveName(true, version) - loc := &url.URL{ - Scheme: c.scheme(), - Host: c.Server, - Path: path.Join("/storage/v1/b/", c.Bucket, "o", itemName), - RawQuery: "alt=media", - } - - req, err := http.NewRequestWithContext(ctx, "GET", loc.String(), nil) - if err != nil { - return fmt.Errorf("unable to construct request to fetch %s: %w", itemName, err) - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - return fmt.Errorf("unable to fetch %s (%s): %w", itemName, req.URL, err) - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - return fmt.Errorf("unable fetch %s (%s) -- got status %q from GCS", itemName, req.URL, resp.Status) - } - - return readBody(resp, out, itemName, platform) -} - -// FetchSum fetches the checksum for the given concrete version & platform into -// the given platform item. -func (c *GCSClient) FetchSum(ctx context.Context, ver versions.Concrete, pl *versions.PlatformItem) error { - itemName := pl.ArchiveName(true, ver) - loc := &url.URL{ - Scheme: c.scheme(), - Host: c.Server, - Path: path.Join("/storage/v1/b/", c.Bucket, "o", itemName), - } - - req, err := http.NewRequestWithContext(ctx, "GET", loc.String(), nil) - if err != nil { - return fmt.Errorf("unable to construct request to fetch metadata for %s: %w", itemName, err) - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - return fmt.Errorf("unable to fetch metadata for %s: %w", itemName, err) - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - return fmt.Errorf("unable fetch metadata for %s -- got status %q from GCS", itemName, resp.Status) - } - - var item bucketObject - if err := json.NewDecoder(resp.Body).Decode(&item); err != nil { - return fmt.Errorf("unable to unmarshal metadata for %s: %w", itemName, err) - } - - pl.Hash = &versions.Hash{ - Type: versions.MD5HashType, - Encoding: versions.Base64HashEncoding, - Value: item.Hash, - } - return nil -} diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/http_client.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/http_client.go index 0339654a8..7cbe3ee1d 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/http_client.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/http_client.go @@ -9,7 +9,7 @@ import ( "io" "net/http" "net/url" - "sort" + "slices" "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/tools/setup-envtest/versions" @@ -87,9 +87,8 @@ func (c *HTTPClient) ListVersions(ctx context.Context) ([]versions.Set, error) { res = append(res, versions.Set{Version: ver, Platforms: details}) } // sort in inverse order so that the newest one is first - sort.Slice(res, func(i, j int) bool { - first, second := res[i].Version, res[j].Version - return first.NewerThan(second) + slices.SortStableFunc(res, func(i, j versions.Set) int { + return j.Version.Compare(i.Version) }) return res, nil diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/read_body.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/read_body.go index 650e41282..1c7110289 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/read_body.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/remote/read_body.go @@ -4,7 +4,6 @@ package remote import ( - //nolint:gosec // We're aware that md5 is a weak cryptographic primitive, but we don't have a choice here. "crypto/md5" "crypto/sha512" "encoding/base64" @@ -28,7 +27,7 @@ func readBody(resp *http.Response, out io.Writer, archiveName string, platform v case versions.SHA512HashType: hasher = sha512.New() case versions.MD5HashType: - hasher = md5.New() //nolint:gosec // We're aware that md5 is a weak cryptographic primitive, but we don't have a choice here. + hasher = md5.New() default: return fmt.Errorf("hash type %s not implemented", platform.Hash.Type) } diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go index 6001eb2a4..1e8053e0c 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/store/store.go @@ -12,7 +12,8 @@ import ( "io" "os" "path/filepath" - "sort" + "slices" + "strings" "github.com/go-logr/logr" "github.com/spf13/afero" @@ -38,7 +39,7 @@ func (i Item) String() string { } // Filter is a version spec & platform selector (i.e. platform -// potentially with wilcards) to filter store items. +// potentially with wildcards) to filter store items. type Filter struct { Version versions.Spec Platform versions.Platform @@ -102,11 +103,12 @@ func (s *Store) List(ctx context.Context, matching Filter) ([]Item, error) { return nil, fmt.Errorf("unable to list version-platform pairs in store: %w", err) } - sort.Slice(res, func(i, j int) bool { - if !res[i].Version.Matches(res[j].Version) { - return res[i].Version.NewerThan(res[j].Version) + slices.SortStableFunc(res, func(i, j Item) int { + if !i.Version.Matches(j.Version) { + // sort in inverse order so that the newest one is first + return j.Version.Compare(i.Version) } - return orderPlatforms(res[i].Platform, res[j].Platform) + return orderPlatforms(i.Platform, j.Platform) }) return res, nil @@ -174,7 +176,7 @@ func (s *Store) Add(ctx context.Context, item Item, contents io.Reader) (resErr } if err := func() error { // IIFE to get the defer properly in a loop defer binOut.Close() - if _, err := io.Copy(binOut, tarReader); err != nil { //nolint:gosec + if _, err := io.Copy(binOut, tarReader); err != nil { return fmt.Errorf("unable to write file %s from archive to disk for version-platform pair %s", targetPath, itemName) } return nil @@ -296,10 +298,10 @@ func (s *Store) removeItem(itemDir afero.Fs) error { } // orderPlatforms orders platforms by OS then arch. -func orderPlatforms(first, second versions.Platform) bool { +func orderPlatforms(first, second versions.Platform) int { // sort by OS, then arch if first.OS != second.OS { - return first.OS < second.OS + return strings.Compare(first.OS, second.OS) } - return first.Arch < second.Arch + return strings.Compare(first.Arch, second.Arch) } diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/version/version.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/version/version.go new file mode 100644 index 000000000..1d148b085 --- /dev/null +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/version/version.go @@ -0,0 +1,21 @@ +package version + +import "runtime/debug" + +// Version to be set using ldflags: +// -ldflags "-X sigs.k8s.io/controller-runtime/tools/setup-envtest/version.version=v1.0.0" +// falls back to module information is unse +var version = "" + +// Version returns the version of the main module +func Version() string { + if version != "" { + return version + } + info, ok := debug.ReadBuildInfo() + if !ok || info == nil || info.Main.Version == "" { + // binary has not been built with module support or doesn't contain a version. + return "(unknown)" + } + return info.Main.Version +} diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go index 21d38bb34..cd25710b2 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/parse.go @@ -107,7 +107,7 @@ func PatchSelectorFromMatch(match []string, re *regexp.Regexp) PatchSelector { panic("invalid input passed as patch selector (invalid state)") } - // patch is optional, means wilcard if left off + // patch is optional, means wildcard if left off patch := AnyPoint if patchRaw := match[re.SubexpIndex("patch")]; patchRaw != "" { patch = PointVersionFromValidString(patchRaw) diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/platform.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/platform.go index 8b32ccd5b..1cfbd05c0 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/platform.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/platform.go @@ -37,11 +37,7 @@ func (p Platform) BaseName(ver Concrete) string { } // ArchiveName returns the full archive name for this version and platform. -// useGCS is deprecated and will be removed when the remote.GCSClient is removed. -func (p Platform) ArchiveName(useGCS bool, ver Concrete) string { - if useGCS { - return "kubebuilder-tools-" + p.BaseName(ver) + ".tar.gz" - } +func (p Platform) ArchiveName(ver Concrete) string { return "envtest-v" + p.BaseName(ver) + ".tar.gz" } @@ -56,11 +52,11 @@ type PlatformItem struct { // Hash of an archive with envtest binaries. type Hash struct { // Type of the hash. - // GCS uses MD5HashType, controller-tools uses SHA512HashType. + // controller-tools uses SHA512HashType. Type HashType // Encoding of the hash value. - // GCS uses Base64HashEncoding, controller-tools uses HexHashEncoding. + // controller-tools uses HexHashEncoding. Encoding HashEncoding // Value of the hash. @@ -122,7 +118,6 @@ var ( // VersionPlatformRE matches concrete version-platform strings. VersionPlatformRE = regexp.MustCompile(`^` + versionPlatformREBase + `$`) // ArchiveRE matches concrete version-platform.tar.gz strings. - // The archives published to GCS by kubebuilder use the "kubebuilder-tools-" prefix (e.g. "kubebuilder-tools-1.30.0-darwin-amd64.tar.gz"). // The archives published to GitHub releases by controller-tools use the "envtest-v" prefix (e.g. "envtest-v1.30.0-darwin-amd64.tar.gz"). - ArchiveRE = regexp.MustCompile(`^(kubebuilder-tools-|envtest-v)` + versionPlatformREBase + `\.tar\.gz$`) + ArchiveRE = regexp.MustCompile(`^envtest-v` + versionPlatformREBase + `\.tar\.gz$`) ) diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/version.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/version.go index 582ed7794..bad05c321 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/version.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/versions/version.go @@ -27,15 +27,24 @@ func (c Concrete) AsConcrete() *Concrete { return &c } -// NewerThan checks if the given other version is newer than this one. -func (c Concrete) NewerThan(other Concrete) bool { +// Compare checks if the given other version is newer than this one. +func (c Concrete) Compare(other Concrete) int { + IntCompare := func(a, b int) int { + if a > b { + return 1 + } else if a < b { + return -1 + } + return 0 + } + if c.Major != other.Major { - return c.Major > other.Major + return IntCompare(c.Major, other.Major) } if c.Minor != other.Minor { - return c.Minor > other.Minor + return IntCompare(c.Minor, other.Minor) } - return c.Patch > other.Patch + return IntCompare(c.Patch, other.Patch) } // Matches checks if this version is equal to the other one. @@ -72,7 +81,7 @@ func (s PatchSelector) AsConcrete() *Concrete { return &Concrete{ Major: s.Major, Minor: s.Minor, - Patch: int(s.Patch), // safe to cast, we've just checked wilcards above + Patch: int(s.Patch), // safe to cast, we've just checked wildcards above } } diff --git a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go index fdabd995a..fb9123d26 100644 --- a/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go +++ b/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows/workflows.go @@ -5,11 +5,13 @@ package workflows import ( "context" + "fmt" "io" "github.com/go-logr/logr" envp "sigs.k8s.io/controller-runtime/tools/setup-envtest/env" + "sigs.k8s.io/controller-runtime/tools/setup-envtest/version" ) // Use is a workflow that prints out information about stored @@ -85,3 +87,12 @@ func (f Sideload) Do(env *envp.Env) { env.Sideload(ctx, f.Input) env.PrintInfo(f.PrintFormat) } + +// Version is the workflow that shows the current binary version +// of setup-envtest. +type Version struct{} + +// Do executes the workflow. +func (v Version) Do(env *envp.Env) { + fmt.Fprintf(env.Out, "setup-envtest version: %s\n", version.Version()) +}