diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index cf91a13d7b..4643f96c11 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -154,7 +154,7 @@ | [github.com/envoyproxy/go-control-plane@v0.9.4](https://github.com/envoyproxy/go-control-plane/releases/tag/v0.9.4.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/envoyproxy/go-control-plane/ba8e577f987f6676343cac84525b92ed1b2d86fe) | | [github.com/envoyproxy/protoc-gen-validate@9eff07ddfcb4001aa1aab280648153f46e1a8ddc](https://github.com/envoyproxy/protoc-gen-validate.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23307) | | [github.com/fsnotify/fsnotify@v1.4.7](https://github.com/fsnotify/fsnotify.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/fsnotify/fsnotify/c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9) | -| [github.com/go-logr/logr@v1.2.4](https://github.com/go-logr/logr.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgo-logr/logr/v1.2.4) | +| [github.com/go-logr/logr@v1.4.1](https://github.com/go-logr/logr.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgo-logr/logr/v1.4.1) | | [github.com/go-openapi/jsonpointer@v0.19.3](https://github.com/go-openapi/jsonpointer.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23304) | | [github.com/go-openapi/jsonreference@v0.19.3](https://github.com/go-openapi/jsonreference.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23303) | | [github.com/go-openapi/spec@v0.19.3](https://github.com/go-openapi/spec.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23302) | @@ -189,9 +189,9 @@ | [go.opencensus.io@v0.22.3](https://github.com/census-instrumentation/opencensus-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/census-instrumentation/opencensus-go/d835ff86be02193d324330acdb7d65546b05f814) | | [google.golang.org/api@v0.20.0](https://github.com/googleapis/google-api-go-client.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-api-go-client/c24765c18bb761c90df819dcdfdd62f9a7f6fa22) | | [google.golang.org/appengine@v1.6.5](https://github.com/golang/appengine.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23310) | -| [google.golang.org/genproto@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | -| [google.golang.org/genproto/googleapis/api@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | -| [google.golang.org/genproto/googleapis/rpc@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | +| [google.golang.org/genproto@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | +| [google.golang.org/genproto/googleapis/api@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | +| [google.golang.org/genproto/googleapis/rpc@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | | [google.golang.org/grpc@v1.58.3](https://github.com/grpc/grpc-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/grpc/grpc-go/bf05b9558c16677e362d231120f8213eb276d406) | | [google.golang.org/protobuf@v1.34.1](https://github.com/protocolbuffers/protobuf-go.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/protocolbuffers/protobuf-go/4a76e11653e368b9331815e1eb98e0cedc28997f) | | [gopkg.in/errgo.v2@v2.1.0](https://github.com/go-errgo/errgo/releases/tag/v2.1.0.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-errgo/errgo/f768c5ab0476c50e978b039312180859c10fe8c0) | @@ -210,7 +210,7 @@ | [github.com/mailru/easyjson@8edcc4e51f39ddbd3505a3386aff3f435a7fd028](https://github.com/mailru/easyjson.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mailru/easyjson/8edcc4e51f39ddbd3505a3386aff3f435a7fd028) | | [github.com/mattn/go-isatty@v0.0.3](https://github.com/mattn/go-isatty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mattn/go-isatty/0360b2af4f38e8d38c7fce2a9f4e702702d73a39) | | [github.com/munnerz/goautoneg@a547fc61f48d567d5b4ec6f8aee5573d8efce11d](https://github.com/munnerz/goautoneg/commits/a547fc61f48d567d5b4ec6f8aee5573d8efce11d.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23267) | -| [github.com/onsi/ginkgo@v1.11.0](https://github.com/onsi/ginkgo.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/onsi/ginkgo/388ac7e50a3abf0798010091d5094171f4aefc0b) | +| [github.com/onsi/ginkgo@v2.19.0](https://github.com/onsi/ginkgo.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/onsi/ginkgo/28fb5d613e96c8f11ca813e1d467117b50662215) | | [github.com/onsi/gomega@v1.7.0](https://github.com/onsi/gomega/releases/tag/v1.7.0.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/onsi/gomega/bdebf9e0ece900259084cfa4121b97ce1a540939) | | [github.com/peterbourgon/diskv@0646ccaebea1ed1539efcab30cae44019090093f](https://github.com/peterbourgon/diskv.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/peterbourgon/diskv/0646ccaebea1ed1539efcab30cae44019090093f) | | [github.com/pkg/errors@614d223910a179a466c1767a985424175c39b465](https://github.com/pkg/errors.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/pkg/errors/614d223910a179a466c1767a985424175c39b465) | @@ -466,7 +466,7 @@ | [go.etcd.io/etcd@dd1b699fc4895de8cc23c3cac5a428c37eee384a](https://github.com/etcd-io/etcd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23592) | | [github.com/remyoudompheng/bigfft@6a916e37a237384e18eefa3270c09247db1ecf50](https://github.com/remyoudompheng/bigfft.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23591) | | [github.com/operator-framework/operator-registry@v1.13.6](https://github.com/operator-framework/operator-registry.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23590) | -| [github.com/openshift/api@88b476f987ed90f7b0e1fdc851859c35161b1ff5](https://github.com/openshift/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/openshift/api/88b476f987ed90f7b0e1fdc851859c35161b1ff5) | +| [github.com/openshift/api@88b476f987ed90f7b0e1fdc851859c35161b1ff5](https://github.com/openshift/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/openshift/api/88b476f987ed90f7b0e1fdc851859c35161b1ff5) | | [github.com/chai2010/gettext-go@c6fed771bfd517099caf0f7a961671fa8ed08723](https://github.com/chai2010/gettext-go.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23551) | | [github.com/cloudflare/golz4@ef862a3cdc58a6f1fee4e3af3d44fbe279194cde](https://github.com/cloudflare/golz4.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23552) | | [github.com/coreos/go-systemd@fd7a80b32e1fc73e890fde45604ed5009dc817a3](https://github.com/coreos/go-systemd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23553) | @@ -524,7 +524,7 @@ | [github.com/go-kit/log@v0.1.0](https://github.com/go-kit/log.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23739) | | [github.com/jpillora/backoff@v1.0.0](https://github.com/jpillora/backoff.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23731) | | [github.com/moby/spdystream@v0.2.0](https://github.com/moby/spdystream.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23294) | -| [github.com/operator-framework/api@v0.10.0](https://github.com/operator-framework/api.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23754) | +| [github.com/operator-framework/api@v0.15.0](https://github.com/operator-framework/api.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23754) | | [github.com/redhat-cop/operator-utils@v1.1.4](https://github.com/redhat-cop/operator-utils.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23755) | | [github.com/scylladb/go-set@v1.0.2](https://github.com/scylladb/go-set.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23757) | | [go.uber.org/goleak@v1.1.10](https://github.com/uber-go/goleak.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23758) | @@ -560,7 +560,7 @@ | [golang.org/x/crypto@v0.35.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [golang.org/x/exp@956cc1757749645f24cefb2ef2a41b0ec4514cf8](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [golang.org/x/image@0694c2d4d067f97ebef574d63a763ee8ab559da7](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/lint@738671d3881b9731cc63024d5d88cf28db875626](https://cs.opensource.google/go) | BSD-3-Clause | N/A | +| [golang.org/x/lint@6edffad5e6160f5949cdefc81710b2706fbcd4f6](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [golang.org/x/mod@v0.17.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [golang.org/x/net@v0.36.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [golang.org/x/sync@v0.10.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | @@ -575,7 +575,7 @@ | [golang.org/x/mobile@d3739f865fa66d07c1f506505c18aac71a8ead6e](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [github.com/devfile/api/v2@v2.2.2](https://github.com/devfile/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/api/a6ec0a38307b63a29fad2eea945cc69bee97a683) | | [github.com/che-incubator/kubernetes-image-puller-operator@0128446f5af78587c0427a35d693bbb8d24036bc](https://github.com/che-incubator/kubernetes-image-puller-operator.git) | EPL-2.0 | todo | -| [github.com/devfile/devworkspace-operator@v0.31.0](https://github.com/devfile/devworkspace-operator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/devworkspace-operator/419adb5eb92b6bdcd4ab33887455c59dc790529e) | +| [github.com/devfile/devworkspace-operator@v0.35.0](https://github.com/devfile/devworkspace-operator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/devworkspace-operator/4823c6cf920e33d4d3101a53ef3b98517b3f8349) | | [github.com/gophercloud/gophercloud@v0.1.0](https://github.com/gophercloud/gophercloud) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgophercloud/gophercloud/v0.1.0) | | [gopkg.in/imdario/mergo.v0@v0.3.7](https://github.com/imdario/mergo/) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fimdario/mergo/v0.3.7) | | [github.com/mikefarah/yq/v2@v2.4.1](https://github.com/mikefarah/yq) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mikefarah/yq/b8b2c9de6189471c0cdbd459b5b0b49a57844bd4) | @@ -590,4 +590,5 @@ | [sigs.k8s.io/json@v0.0.0-20220713155537-f223a00ba0e2](https://github.com/kubernetes-sigs/json) | Apache-2.0 AND BSD-3-Clause AND NOASSERTION | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes-sigs/json/f223a00ba0e27f539157f69f9c919c204ea7f40b) | | [github.com/google/gnostic@v0.5.7-v3refs](https://github.com/kubernetes-sigs/json) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgoogle/gnostic/v0.5.7-v3refs) | | [github.com/go-task/slim-sprig@v0.0.0-20230315185526-52ccab3ef572](https://github.com/go-task/slim-sprig.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-task/slim-sprig/52ccab3ef572c7e1a2c258be183f9a9296d60152) | -| [github.com/josharian/intern@v1.0.0](https://github.com/josharian/intern.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/josharian/intern/8e6ff32b3e7c0b018c43953085fe2ac330fe9acd) | +| [github.com/go-task/slim-sprig/v3@v3.0.0](https://github.com/go-task/slim-sprig.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-task/slim-sprig/b05cce61fffa5c6dea6ac8b9a1f12b6e3fb7c894) | +| [github.com/josharian/intern@v1.0.0](https://github.com/josharian/intern.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/josharian/intern/8e6ff32b3e7c0b018c43953085fe2ac330fe9acd) | diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index 645501d9ce..85e42a65bc 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -661,6 +661,13 @@ type PVC struct { // Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class is used. // +optional StorageClass string `json:"storageClass,omitempty"` + // StorageAccessMode are the desired access modes the volume should have. + // It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + // user to re-use volume across multiple workspaces. + // + // It defaults to ReadWriteOnce if not specified + // +optional + StorageAccessMode []corev1.PersistentVolumeAccessMode `json:"storageAccessMode,omitempty"` } // External devfile registries configuration. diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 5c0f068f93..4ec0fc3fba 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -906,6 +906,11 @@ func (in *OAuthProxy) DeepCopy() *OAuthProxy { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PVC) DeepCopyInto(out *PVC) { *out = *in + if in.StorageAccessMode != nil { + in, out := &in.StorageAccessMode, &out.StorageAccessMode + *out = make([]v1.PersistentVolumeAccessMode, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PVC. @@ -1189,12 +1194,12 @@ func (in *WorkspaceStorage) DeepCopyInto(out *WorkspaceStorage) { if in.PerUserStrategyPvcConfig != nil { in, out := &in.PerUserStrategyPvcConfig, &out.PerUserStrategyPvcConfig *out = new(PVC) - **out = **in + (*in).DeepCopyInto(*out) } if in.PerWorkspaceStrategyPvcConfig != nil { in, out := &in.PerWorkspaceStrategyPvcConfig, &out.PerWorkspaceStrategyPvcConfig *out = new(PVC) - **out = **in + (*in).DeepCopyInto(*out) } } diff --git a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml index 2ea3c53c61..57ef49c1c4 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -7926,6 +7926,17 @@ spec: the claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage @@ -7941,6 +7952,17 @@ spec: the claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index e757c4c5de..fa4c1d9e1b 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -7877,6 +7877,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class @@ -7892,6 +7903,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index 36c3be0125..ad66130a0e 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -7898,6 +7898,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class @@ -7913,6 +7924,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class diff --git a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 4eac45b936..578336c5e8 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -7893,6 +7893,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class @@ -7908,6 +7919,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 67720f371e..036c27cf1e 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -7898,6 +7898,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class @@ -7913,6 +7924,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class diff --git a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 583b504dec..05bf3a0bff 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -7893,6 +7893,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class @@ -7908,6 +7919,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class diff --git a/go.mod b/go.mod index 9dfa3f02ce..73bf869968 100644 --- a/go.mod +++ b/go.mod @@ -7,16 +7,16 @@ toolchain go1.23.8 require ( github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20210929175054-0128446f5af7 github.com/devfile/api/v2 v2.2.2 - github.com/devfile/devworkspace-operator v0.31.0 - github.com/go-logr/logr v1.2.4 + github.com/devfile/devworkspace-operator v0.35.0 + github.com/go-logr/logr v1.4.1 github.com/google/go-cmp v0.6.0 github.com/openshift/api v0.0.0-20230120182048-88b476f987ed - github.com/operator-framework/api v0.10.0 + github.com/operator-framework/api v0.15.0 github.com/operator-framework/operator-lifecycle-manager v0.18.1 github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.24.0 - golang.org/x/net v0.36.0 + golang.org/x/net v0.38.0 k8s.io/api v0.26.1 k8s.io/apiextensions-apiserver v0.26.1 k8s.io/apimachinery v0.26.1 @@ -48,12 +48,12 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/gomega v1.27.10 // indirect + github.com/onsi/gomega v1.34.1 // indirect github.com/operator-framework/operator-registry v1.13.6 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -65,9 +65,9 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.29.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/grpc v1.58.3 // indirect @@ -89,10 +89,10 @@ require ( github.com/Shopify/logrus-bugsnag v0.0.0-00010101000000-000000000000 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect - golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect honnef.co/go/tools v0.0.1-2020.1.3 // indirect diff --git a/go.sum b/go.sum index 5ab4eec00d..d8abffc1ec 100644 --- a/go.sum +++ b/go.sum @@ -714,8 +714,8 @@ github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= github.com/devfile/api/v2 v2.2.2 h1:DXRCPWFlZhTIE38Of2jzTRjQHadfbxBC8GS+m+EjoCU= github.com/devfile/api/v2 v2.2.2/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM= -github.com/devfile/devworkspace-operator v0.31.0 h1:mrlBqo1wRR3dzhJm2IL3FmX3eHp8N8z/DobP6goN1qY= -github.com/devfile/devworkspace-operator v0.31.0/go.mod h1:b2fBHTA6szY4uN46w0PlPKLJO/dzA8N2vvepBxSFmYk= +github.com/devfile/devworkspace-operator v0.35.0 h1:EY1EVIYa5kYsy8xxfnaWH7qyVmRYRMjDi1lENyuMVY4= +github.com/devfile/devworkspace-operator v0.35.0/go.mod h1:sq9bQSIVkt2c3pEBEgslCMA+xSt3hFur7tR5eE6h/+A= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dhui/dktest v0.3.2/go.mod h1:l1/ib23a/CmxAe7yixtrYPc8Iy90Zy2udyaHINM5p58= github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw= @@ -772,8 +772,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= @@ -796,9 +796,10 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y= @@ -976,8 +977,8 @@ github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -993,8 +994,8 @@ github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/operator-framework/api v0.3.7-0.20200602203552-431198de9fc2/go.mod h1:Xbje9x0SHmh0nihE21kpesB38vk3cyxnE6JdDS8Jo1Q= github.com/operator-framework/api v0.8.0/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY= -github.com/operator-framework/api v0.10.0 h1:TaxbgbrV8D3wnKNyrImZ2zjQVVHMQRc7piWLDmlGoEE= -github.com/operator-framework/api v0.10.0/go.mod h1:tV0BUNvly7szq28ZPBXhjp1Sqg5yHCOeX19ui9K4vjI= +github.com/operator-framework/api v0.15.0 h1:4f9i0drtqHj7ykLoHxv92GR43S7MmQHhmFQkfm5YaGI= +github.com/operator-framework/api v0.15.0/go.mod h1:scnY9xqSeCsOdtJtNoHIXd7OtHZ14gj1hkDA4+DlgLY= github.com/operator-framework/operator-lifecycle-manager v0.18.1 h1:Sp5EqkUR3udHysNAHQAFLAhnZBdZ4Gzhl9+nxL+sOjc= github.com/operator-framework/operator-lifecycle-manager v0.18.1/go.mod h1:zFexXul1dzWyM1fe6ZymNvTo9nqPCFJ370AVmZB43lc= github.com/operator-framework/operator-registry v1.13.6 h1:h/dIjQQS7uneQNRifrSz7h0xg4Xyjg6C9f6XZofbMPg= @@ -1098,8 +1099,9 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= @@ -1330,7 +1332,6 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= @@ -1356,7 +1357,6 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyz sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= sigs.k8s.io/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4= sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU= -sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8= sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M= sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 4eac45b936..578336c5e8 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -7893,6 +7893,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class @@ -7908,6 +7919,17 @@ spec: claim size, the storage class that provisions it must support resizing. type: string + storageAccessMode: + description: |- + StorageAccessMode are the desired access modes the volume should have. + It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing + user to re-use volume across multiple workspaces. + + + It defaults to ReadWriteOnce if not specified + items: + type: string + type: array storageClass: description: Storage class for the Persistent Volume Claim. When omitted or left blank, a default storage class diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config.go b/pkg/deploy/dev-workspace-config/dev_workspace_config.go index cae5483b08..7b4688d8c9 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config.go @@ -161,6 +161,7 @@ func updateWorkspaceStorageConfig(devEnvironments *chev2.CheClusterDevEnvironmen }[pvcStrategy] if pvc != nil { + workspaceConfig.StorageAccessMode = pvc.StorageAccessMode if pvc.StorageClass != "" { workspaceConfig.StorageClassName = &pvc.StorageClass } diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go index 9ba81f8325..e3df2abbbd 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go @@ -145,6 +145,62 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { }, }, }, + { + name: "Create DevWorkspaceOperatorConfig with non empty StorageAccessMode", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.Bool(true), + Storage: chev2.WorkspaceStorage{ + PvcStrategy: constants.PerUserPVCStorageStrategy, + PerUserStrategyPvcConfig: &chev2.PVC{ + StorageAccessMode: []corev1.PersistentVolumeAccessMode{ + corev1.ReadWriteMany, + }, + }, + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageAccessMode: []corev1.PersistentVolumeAccessMode{ + corev1.ReadWriteMany, + }, + DeploymentStrategy: "Recreate", + }, + }, + }, + { + name: "Create DevWorkspaceOperatorConfig with nil StorageAccessMode", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.Bool(true), + Storage: chev2.WorkspaceStorage{ + PvcStrategy: constants.PerUserPVCStorageStrategy, + PerUserStrategyPvcConfig: &chev2.PVC{ + StorageAccessMode: nil, + }, + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageAccessMode: nil, + DeploymentStrategy: "Recreate", + }, + }, + }, { name: "Create DevWorkspaceOperatorConfig with per-user storage strategy", cheCluster: &chev2.CheCluster{ diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/attributes.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/attributes.go index 0f77bd2a43..604fcdf604 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/attributes.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/attributes.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/common.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/common.go index cad580d01c..526c0f25dc 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/common.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/common.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devfile.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devfile.go index 87ec1d1827..2e294bde74 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devfile.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devfile.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go index 04bd20dc4f..4d03036300 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 @@ -49,6 +49,29 @@ type OperatorConfiguration struct { EnableExperimentalFeatures *bool `json:"enableExperimentalFeatures,omitempty"` } +type CleanupCronJobConfig struct { + // Enable determines whether the cleanup cron job is enabled. + // Defaults to false if not specified. + // +kubebuilder:validation:Optional + Enable *bool `json:"enable,omitempty"` + // RetainTime specifies the minimum time (in seconds) since a DevWorkspace was last started before it is considered stale and eligible for cleanup. + // For example, a value of 2592000 (30 days) would mean that any DevWorkspace that has not been started in the last 30 days will be deleted. + // Defaults to 2592000 seconds (30 days) if not specified. + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default:=2592000 + // +kubebuilder:validation:Optional + RetainTime *int32 `json:"retainTime,omitempty"` + // DryRun determines whether the cleanup cron job should be run in dry-run mode. + // If set to true, the cron job will not delete any DevWorkspaces, but will log the DevWorkspaces that would have been deleted. + // Defaults to false if not specified. + // +kubebuilder:validation:Optional + DryRun *bool `json:"dryRun,omitempty"` + // Schedule specifies the cron schedule for the cleanup cron job. + // +kubebuilder:default:="0 0 1 * *" + // +kubebuilder:validation:Optional + Schedule string `json:"schedule,omitempty"` +} + type RoutingConfig struct { // DefaultRoutingClass specifies the routingClass to be used when a DevWorkspace // specifies an empty `.spec.routingClass`. Supported routingClasses can be defined @@ -112,6 +135,9 @@ type WorkspaceConfig struct { // DefaultStorageSize defines an optional struct with fields to specify the sizes of Persistent Volume Claims for storage // classes used by DevWorkspaces. DefaultStorageSize *StorageSizes `json:"defaultStorageSize,omitempty"` + // StorageAccessMode are the desired access modes the volume should have. It defaults + // to ReadWriteOnce if not specified + StorageAccessMode []corev1.PersistentVolumeAccessMode `json:"storageAccessMode,omitempty"` // PersistUserHome defines configuration options for persisting the `/home/user/` // directory in workspaces. PersistUserHome *PersistentHomeConfig `json:"persistUserHome,omitempty"` @@ -161,6 +187,8 @@ type WorkspaceConfig struct { PodAnnotations map[string]string `json:"podAnnotations,omitempty"` // RuntimeClassName defines the spec.runtimeClassName for DevWorkspace pods created by the DevWorkspace Operator. RuntimeClassName *string `json:"runtimeClassName,omitempty"` + // CleanupCronJobConfig defines configuration options for a cron job that automatically cleans up stale DevWorkspaces. + CleanupCronJob *CleanupCronJobConfig `json:"cleanupCronJob,omitempty"` } type WebhookConfig struct { diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspacerouting_types.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspacerouting_types.go index 4b364d203d..6db93e48a5 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspacerouting_types.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspacerouting_types.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/doc.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/doc.go index 708cf9a73d..db4ea643a3 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/doc.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/doc.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/errors.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/errors.go index 709972cb90..77f43fe2d4 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/errors.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/errors.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/groupversion_info.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/groupversion_info.go index 5504a28c3e..c952dae6e6 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/groupversion_info.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/groupversion_info.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go index 7180ab5a08..b049043193 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go @@ -1,8 +1,7 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 @@ -47,6 +46,36 @@ func (in Attributes) DeepCopy() Attributes { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CleanupCronJobConfig) DeepCopyInto(out *CleanupCronJobConfig) { + *out = *in + if in.Enable != nil { + in, out := &in.Enable, &out.Enable + *out = new(bool) + **out = **in + } + if in.RetainTime != nil { + in, out := &in.RetainTime, &out.RetainTime + *out = new(int32) + **out = **in + } + if in.DryRun != nil { + in, out := &in.DryRun, &out.DryRun + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CleanupCronJobConfig. +func (in *CleanupCronJobConfig) DeepCopy() *CleanupCronJobConfig { + if in == nil { + return nil + } + out := new(CleanupCronJobConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConfigmapReference) DeepCopyInto(out *ConfigmapReference) { *out = *in @@ -194,7 +223,8 @@ func (in *DevWorkspaceRoutingSpec) DeepCopyInto(out *DevWorkspaceRoutingSpec) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make(EndpointList, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) @@ -238,7 +268,8 @@ func (in *DevWorkspaceRoutingStatus) DeepCopyInto(out *DevWorkspaceRoutingStatus if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make(ExposedEndpointList, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) @@ -700,6 +731,11 @@ func (in *WorkspaceConfig) DeepCopyInto(out *WorkspaceConfig) { *out = new(StorageSizes) (*in).DeepCopyInto(*out) } + if in.StorageAccessMode != nil { + in, out := &in.StorageAccessMode, &out.StorageAccessMode + *out = make([]v1.PersistentVolumeAccessMode, len(*in)) + copy(*out, *in) + } if in.PersistUserHome != nil { in, out := &in.PersistUserHome, &out.PersistUserHome *out = new(PersistentHomeConfig) @@ -747,6 +783,11 @@ func (in *WorkspaceConfig) DeepCopyInto(out *WorkspaceConfig) { *out = new(string) **out = **in } + if in.CleanupCronJob != nil { + in, out := &in.CleanupCronJob, &out.CleanupCronJob + *out = new(CleanupCronJobConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceConfig. diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/devworkspacerouting_controller.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/devworkspacerouting_controller.go index 0f80a01111..367da93d03 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/devworkspacerouting_controller.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/devworkspacerouting_controller.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/predicates.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/predicates.go index 185356d983..7a545fa3f4 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/predicates.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/predicates.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/basic_solver.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/basic_solver.go index 9cbafc1f0c..50df27fa10 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/basic_solver.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/basic_solver.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/cluster_solver.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/cluster_solver.go index 305133d6ba..7c54622524 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/cluster_solver.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/cluster_solver.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/common.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/common.go index b642874ec8..b55367ad8e 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/common.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/common.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/errors.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/errors.go index 1b598f0275..ffcdd7b7b5 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/errors.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/errors.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/resolve_endpoints.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/resolve_endpoints.go index 23645108b0..0ba164263a 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/resolve_endpoints.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/resolve_endpoints.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/solver.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/solver.go index a5c3a3872d..c5c5a5c877 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/solver.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers/solver.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_ingresses.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_ingresses.go index 4c30c28291..6d21fae5ad 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_ingresses.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_ingresses.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_routes.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_routes.go index bee9393266..4a542a1400 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_routes.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_routes.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_services.go b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_services.go index 1902626e4f..41b8925c76 100644 --- a/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_services.go +++ b/vendor/github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/sync_services.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/internal/map/map.go b/vendor/github.com/devfile/devworkspace-operator/internal/map/map.go index d885abe9d9..a1b38e49fe 100644 --- a/vendor/github.com/devfile/devworkspace-operator/internal/map/map.go +++ b/vendor/github.com/devfile/devworkspace-operator/internal/map/map.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/common/naming.go b/vendor/github.com/devfile/devworkspace-operator/pkg/common/naming.go index 56b0c6516a..1e7cb8c7eb 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/common/naming.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/common/naming.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/common/types.go b/vendor/github.com/devfile/devworkspace-operator/pkg/common/types.go index d33ae545e9..cacf468441 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/common/types.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/common/types.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/config.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/config.go index cf638c4f69..05be88b2b3 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/config.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/config.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/doc.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/doc.go index 1a09e62227..3a0b3a1207 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/doc.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/doc.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/property.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/property.go index 60c392098f..3bdd842ed1 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/property.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/configmap/property.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go index 5e1c2eba0c..024a629ddf 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 @@ -76,6 +76,12 @@ var defaultConfig = &v1alpha1.OperatorConfiguration{ corev1.ResourceMemory: resource.MustParse("64Mi"), }, }, + CleanupCronJob: &v1alpha1.CleanupCronJobConfig{ + Enable: pointer.Bool(false), + DryRun: pointer.Bool(false), + RetainTime: pointer.Int32(2592000), + Schedule: "0 0 1 * *", + }, }, } diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/env.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/env.go index aace3202d7..95974be477 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/env.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/env.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/migrate.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/migrate.go index e3620fe810..0f27053049 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/migrate.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/migrate.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/predicates.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/predicates.go index 2389792a8c..a5f68bd6b1 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/predicates.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/predicates.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/proxy/openshift.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/proxy/openshift.go index 4424dd2203..5c79e655da 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/proxy/openshift.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/proxy/openshift.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go index 483c820ec4..c5b8150f7a 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 @@ -341,6 +341,9 @@ func mergeConfig(from, to *controller.OperatorConfiguration) { if from.Workspace.ContainerSecurityContext != nil { to.Workspace.ContainerSecurityContext = mergeContainerSecurityContext(to.Workspace.ContainerSecurityContext, from.Workspace.ContainerSecurityContext) } + if from.Workspace.StorageAccessMode != nil { + to.Workspace.StorageAccessMode = from.Workspace.StorageAccessMode + } if from.Workspace.DefaultStorageSize != nil { if to.Workspace.DefaultStorageSize == nil { to.Workspace.DefaultStorageSize = &controller.StorageSizes{} @@ -410,6 +413,24 @@ func mergeConfig(from, to *controller.OperatorConfiguration) { to.Workspace.PodAnnotations[key] = value } } + + if from.Workspace.CleanupCronJob != nil { + if to.Workspace.CleanupCronJob == nil { + to.Workspace.CleanupCronJob = &controller.CleanupCronJobConfig{} + } + if from.Workspace.CleanupCronJob.Enable != nil { + to.Workspace.CleanupCronJob.Enable = from.Workspace.CleanupCronJob.Enable + } + if from.Workspace.CleanupCronJob.DryRun != nil { + to.Workspace.CleanupCronJob.DryRun = from.Workspace.CleanupCronJob.DryRun + } + if from.Workspace.CleanupCronJob.RetainTime != nil { + to.Workspace.CleanupCronJob.RetainTime = from.Workspace.CleanupCronJob.RetainTime + } + if from.Workspace.CleanupCronJob.Schedule != "" { + to.Workspace.CleanupCronJob.Schedule = from.Workspace.CleanupCronJob.Schedule + } + } } } @@ -638,6 +659,20 @@ func GetCurrentConfigString(currConfig *controller.OperatorConfiguration) string if !reflect.DeepEqual(workspace.PodAnnotations, defaultConfig.Workspace.PodAnnotations) { config = append(config, "workspace.podAnnotations is set") } + if workspace.CleanupCronJob != nil { + if workspace.CleanupCronJob.Enable != nil && *workspace.CleanupCronJob.Enable != *defaultConfig.Workspace.CleanupCronJob.Enable { + config = append(config, fmt.Sprintf("workspace.cleanupCronJob.enable=%t", *workspace.CleanupCronJob.Enable)) + } + if workspace.CleanupCronJob.DryRun != nil && *workspace.CleanupCronJob.DryRun != *defaultConfig.Workspace.CleanupCronJob.DryRun { + config = append(config, fmt.Sprintf("workspace.cleanupCronJob.dryRun=%t", *workspace.CleanupCronJob.DryRun)) + } + if workspace.CleanupCronJob.RetainTime != nil && *workspace.CleanupCronJob.RetainTime != *defaultConfig.Workspace.CleanupCronJob.RetainTime { + config = append(config, fmt.Sprintf("workspace.cleanupCronJob.retainTime=%d", *workspace.CleanupCronJob.RetainTime)) + } + if workspace.CleanupCronJob.Schedule != defaultConfig.Workspace.CleanupCronJob.Schedule { + config = append(config, fmt.Sprintf("workspace.cleanupCronJob.cronJobScript=%s", workspace.CleanupCronJob.Schedule)) + } + } } if currConfig.EnableExperimentalFeatures != nil && *currConfig.EnableExperimentalFeatures { config = append(config, "enableExperimentalFeatures=true") diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/attributes.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/attributes.go index e5f8f8d85b..484c7c8852 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/attributes.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/attributes.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go index d50079c2c9..b638306593 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 @@ -45,7 +45,7 @@ const ( HomeInitEventId = "init-persistent-home" - SshAgentStartEventId = "init-ssh-agent" + SshAgentStartEventId = "init-ssh-agent-command" ServiceAccount = "devworkspace" @@ -96,3 +96,8 @@ const ( // ProjectCloneDisable specifies that project cloning should be disabled. ProjectCloneDisable = "disable" ) + +const ( + // SelectedNodeAnnotation annotation is added to a PVC that is triggered by a scheduler to be dynamically provisioned. Its value is the name of the selected node. + SelectedNodeAnnotation = "volume.kubernetes.io/selected-node" +) diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/env.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/env.go index bad2a63d6c..c80a743e3b 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/env.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/env.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/finalizers.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/finalizers.go index 9baddab413..b53669d558 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/finalizers.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/finalizers.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/metadata.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/metadata.go index 03f31b6819..092dddeab7 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/metadata.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/metadata.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 @@ -34,6 +34,10 @@ const ( // DevWorkspaceNameLabel is the label key to store workspace name DevWorkspaceNameLabel = "controller.devfile.io/devworkspace_name" + // DevWorkspaceWatchCronJobLabel marks a cronjob so that it is watched by the controller. This label is required on all + // cronjobs that should be seen by the controller + DevWorkspaceWatchCronJobLabel = "controller.devfile.io/watch-cronjob" + // DevWorkspaceWatchConfigMapLabel marks a configmap so that it is watched by the controller. This label is required on all // configmaps that should be seen by the controller DevWorkspaceWatchConfigMapLabel = "controller.devfile.io/watch-configmap" @@ -87,6 +91,15 @@ const ( // in a given namespace. It is used when e.g. adding Git credentials via secret GitCredentialsConfigMapName = "devworkspace-gitconfig" + // SSHSecretName is the name used for the secret that stores the SSH key data for workspaces in a given namespace. + // TODO: This is a workaround for https://github.com/devfile/devworkspace-operator/issues/1340. + // We do not enforce the SSH secret to have this name, but it is used by the Che Dashboard and this allows us + // to detect if the user has provided an SSH key with a passhprase. + SSHSecretName = "git-ssh-key" + + // SSHSecretPassphraseKey is the key used to retrieve the optional passphrase stored inside the SSH secret. + SSHSecretPassphraseKey = "passphrase" + SshAskPassConfigMapName = "devworkspace-ssh-askpass" // GitCredentialsMergedSecretName is the name for the merged Git credentials secret that is mounted to workspaces diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/cluster.go b/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/cluster.go index a40038f3f5..702d6e1ab0 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/cluster.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/cluster.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/namespace.go b/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/namespace.go index 5572ad7562..d904b39b98 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/namespace.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/namespace.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/webhook.go b/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/webhook.go index 10bf4894f5..4b69ed4a24 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/webhook.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/infrastructure/webhook.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/cluster_api.go b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/cluster_api.go index 6e9df6d721..fb27edcad7 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/cluster_api.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/cluster_api.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diff.go b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diff.go index 7670d5de11..83e115deab 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diff.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diff.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diffopts.go b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diffopts.go index c843b82679..536e82f771 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diffopts.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/diffopts.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go index 5e69d1f81e..a231e45f80 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/update.go b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/update.go index d954ab0afb..f84a91d02a 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/update.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/update.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // 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 diff --git a/vendor/github.com/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md index ab59311813..8969526a6e 100644 --- a/vendor/github.com/go-logr/logr/README.md +++ b/vendor/github.com/go-logr/logr/README.md @@ -1,6 +1,7 @@ # A minimal logging API for Go [![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr) logr offers an(other) opinion on how Go programs and libraries can do logging without becoming coupled to a particular logging implementation. This is not @@ -73,6 +74,30 @@ received: If the Go standard library had defined an interface for logging, this project probably would not be needed. Alas, here we are. +When the Go developers started developing such an interface with +[slog](https://github.com/golang/go/issues/56345), they adopted some of the +logr design but also left out some parts and changed others: + +| Feature | logr | slog | +|---------|------|------| +| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) | +| Low-level API | `LogSink` | `Handler` | +| Stack unwinding | done by `LogSink` | done by `Logger` | +| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) | +| Generating a value for logging on demand | `Marshaler` | `LogValuer` | +| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" | +| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` | +| Passing logger via context | `NewContext`, `FromContext` | no API | +| Adding a name to a logger | `WithName` | no API | +| Modify verbosity of log entries in a call chain | `V` | no API | +| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` | +| Pass context for extracting additional values | no API | API variants like `InfoCtx` | + +The high-level slog API is explicitly meant to be one of many different APIs +that can be layered on top of a shared `slog.Handler`. logr is one such +alternative API, with [interoperability](#slog-interoperability) provided by +some conversion functions. + ### Inspiration Before you consider this package, please read [this blog post by the @@ -118,6 +143,103 @@ There are implementations for the following logging libraries: - **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0) - **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing) +## slog interoperability + +Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler` +and using the `slog.Logger` API with a `logr.LogSink`. `FromSlogHandler` and +`ToSlogHandler` convert between a `logr.Logger` and a `slog.Handler`. +As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level +slog API. + +### Using a `logr.LogSink` as backend for slog + +Ideally, a logr sink implementation should support both logr and slog by +implementing both the normal logr interface(s) and `SlogSink`. Because +of a conflict in the parameters of the common `Enabled` method, it is [not +possible to implement both slog.Handler and logr.Sink in the same +type](https://github.com/golang/go/issues/59110). + +If both are supported, log calls can go from the high-level APIs to the backend +without the need to convert parameters. `FromSlogHandler` and `ToSlogHandler` can +convert back and forth without adding additional wrappers, with one exception: +when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then +`ToSlogHandler` has to use a wrapper which adjusts the verbosity for future +log calls. + +Such an implementation should also support values that implement specific +interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`, +`slog.GroupValue`). logr does not convert those. + +Not supporting slog has several drawbacks: +- Recording source code locations works correctly if the handler gets called + through `slog.Logger`, but may be wrong in other cases. That's because a + `logr.Sink` does its own stack unwinding instead of using the program counter + provided by the high-level API. +- slog levels <= 0 can be mapped to logr levels by negating the level without a + loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as + used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink + because logr does not support "more important than info" levels. +- The slog group concept is supported by prefixing each key in a key/value + pair with the group names, separated by a dot. For structured output like + JSON it would be better to group the key/value pairs inside an object. +- Special slog values and interfaces don't work as expected. +- The overhead is likely to be higher. + +These drawbacks are severe enough that applications using a mixture of slog and +logr should switch to a different backend. + +### Using a `slog.Handler` as backend for logr + +Using a plain `slog.Handler` without support for logr works better than the +other direction: +- All logr verbosity levels can be mapped 1:1 to their corresponding slog level + by negating them. +- Stack unwinding is done by the `SlogSink` and the resulting program + counter is passed to the `slog.Handler`. +- Names added via `Logger.WithName` are gathered and recorded in an additional + attribute with `logger` as key and the names separated by slash as value. +- `Logger.Error` is turned into a log record with `slog.LevelError` as level + and an additional attribute with `err` as key, if an error was provided. + +The main drawback is that `logr.Marshaler` will not be supported. Types should +ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility +with logr implementations without slog support is not important, then +`slog.Valuer` is sufficient. + +### Context support for slog + +Storing a logger in a `context.Context` is not supported by +slog. `NewContextWithSlogLogger` and `FromContextAsSlogLogger` can be +used to fill this gap. They store and retrieve a `slog.Logger` pointer +under the same context key that is also used by `NewContext` and +`FromContext` for `logr.Logger` value. + +When `NewContextWithSlogLogger` is followed by `FromContext`, the latter will +automatically convert the `slog.Logger` to a +`logr.Logger`. `FromContextAsSlogLogger` does the same for the other direction. + +With this approach, binaries which use either slog or logr are as efficient as +possible with no unnecessary allocations. This is also why the API stores a +`slog.Logger` pointer: when storing a `slog.Handler`, creating a `slog.Logger` +on retrieval would need to allocate one. + +The downside is that switching back and forth needs more allocations. Because +logr is the API that is already in use by different packages, in particular +Kubernetes, the recommendation is to use the `logr.Logger` API in code which +uses contextual logging. + +An alternative to adding values to a logger and storing that logger in the +context is to store the values in the context and to configure a logging +backend to extract those values when emitting log entries. This only works when +log calls are passed the context, which is not supported by the logr API. + +With the slog API, it is possible, but not +required. https://github.com/veqryn/slog-context is a package for slog which +provides additional support code for this approach. It also contains wrappers +for the context functions in logr, so developers who prefer to not use the logr +APIs directly can use those instead and the resulting code will still be +interoperable with logr. + ## FAQ ### Conceptual @@ -241,7 +363,9 @@ Otherwise, you can start out with `0` as "you always want to see this", Then gradually choose levels in between as you need them, working your way down from 10 (for debug and trace style logs) and up from 1 (for chattier -info-type logs.) +info-type logs). For reference, slog pre-defines -4 for debug logs +(corresponds to 4 in logr), which matches what is +[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). #### How do I choose my keys? diff --git a/vendor/github.com/go-logr/logr/SECURITY.md b/vendor/github.com/go-logr/logr/SECURITY.md new file mode 100644 index 0000000000..1ca756fc7b --- /dev/null +++ b/vendor/github.com/go-logr/logr/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +If you have discovered a security vulnerability in this project, please report it +privately. **Do not disclose it as a public issue.** This gives us time to work with you +to fix the issue before public exposure, reducing the chance that the exploit will be +used before a patch is released. + +You may submit the report in the following ways: + +- send an email to go-logr-security@googlegroups.com +- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new) + +Please provide the following information in your report: + +- A description of the vulnerability and its impact +- How to reproduce the issue + +We ask that you give us 90 days to work on a fix before public exposure. diff --git a/vendor/github.com/go-logr/logr/context.go b/vendor/github.com/go-logr/logr/context.go new file mode 100644 index 0000000000..de8bcc3ad8 --- /dev/null +++ b/vendor/github.com/go-logr/logr/context.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The logr 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 logr + +// contextKey is how we find Loggers in a context.Context. With Go < 1.21, +// the value is always a Logger value. With Go >= 1.21, the value can be a +// Logger value or a slog.Logger pointer. +type contextKey struct{} + +// notFoundError exists to carry an IsNotFound method. +type notFoundError struct{} + +func (notFoundError) Error() string { + return "no logr.Logger was present" +} + +func (notFoundError) IsNotFound() bool { + return true +} diff --git a/vendor/github.com/go-logr/logr/context_noslog.go b/vendor/github.com/go-logr/logr/context_noslog.go new file mode 100644 index 0000000000..f012f9a18e --- /dev/null +++ b/vendor/github.com/go-logr/logr/context_noslog.go @@ -0,0 +1,49 @@ +//go:build !go1.21 +// +build !go1.21 + +/* +Copyright 2019 The logr 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 logr + +import ( + "context" +) + +// FromContext returns a Logger from ctx or an error if no Logger is found. +func FromContext(ctx context.Context) (Logger, error) { + if v, ok := ctx.Value(contextKey{}).(Logger); ok { + return v, nil + } + + return Logger{}, notFoundError{} +} + +// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this +// returns a Logger that discards all log messages. +func FromContextOrDiscard(ctx context.Context) Logger { + if v, ok := ctx.Value(contextKey{}).(Logger); ok { + return v + } + + return Discard() +} + +// NewContext returns a new Context, derived from ctx, which carries the +// provided Logger. +func NewContext(ctx context.Context, logger Logger) context.Context { + return context.WithValue(ctx, contextKey{}, logger) +} diff --git a/vendor/github.com/go-logr/logr/context_slog.go b/vendor/github.com/go-logr/logr/context_slog.go new file mode 100644 index 0000000000..065ef0b828 --- /dev/null +++ b/vendor/github.com/go-logr/logr/context_slog.go @@ -0,0 +1,83 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2019 The logr 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 logr + +import ( + "context" + "fmt" + "log/slog" +) + +// FromContext returns a Logger from ctx or an error if no Logger is found. +func FromContext(ctx context.Context) (Logger, error) { + v := ctx.Value(contextKey{}) + if v == nil { + return Logger{}, notFoundError{} + } + + switch v := v.(type) { + case Logger: + return v, nil + case *slog.Logger: + return FromSlogHandler(v.Handler()), nil + default: + // Not reached. + panic(fmt.Sprintf("unexpected value type for logr context key: %T", v)) + } +} + +// FromContextAsSlogLogger returns a slog.Logger from ctx or nil if no such Logger is found. +func FromContextAsSlogLogger(ctx context.Context) *slog.Logger { + v := ctx.Value(contextKey{}) + if v == nil { + return nil + } + + switch v := v.(type) { + case Logger: + return slog.New(ToSlogHandler(v)) + case *slog.Logger: + return v + default: + // Not reached. + panic(fmt.Sprintf("unexpected value type for logr context key: %T", v)) + } +} + +// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this +// returns a Logger that discards all log messages. +func FromContextOrDiscard(ctx context.Context) Logger { + if logger, err := FromContext(ctx); err == nil { + return logger + } + return Discard() +} + +// NewContext returns a new Context, derived from ctx, which carries the +// provided Logger. +func NewContext(ctx context.Context, logger Logger) context.Context { + return context.WithValue(ctx, contextKey{}, logger) +} + +// NewContextWithSlogLogger returns a new Context, derived from ctx, which carries the +// provided slog.Logger. +func NewContextWithSlogLogger(ctx context.Context, logger *slog.Logger) context.Context { + return context.WithValue(ctx, contextKey{}, logger) +} diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go index e027aea3fd..b4428e105b 100644 --- a/vendor/github.com/go-logr/logr/logr.go +++ b/vendor/github.com/go-logr/logr/logr.go @@ -127,9 +127,9 @@ limitations under the License. // such a value can call its methods without having to check whether the // instance is ready for use. // -// Calling methods with the null logger (Logger{}) as instance will crash -// because it has no LogSink. Therefore this null logger should never be passed -// around. For cases where passing a logger is optional, a pointer to Logger +// The zero logger (= Logger{}) is identical to Discard() and discards all log +// entries. Code that receives a Logger by value can simply call it, the methods +// will never crash. For cases where passing a logger is optional, a pointer to Logger // should be used. // // # Key Naming Conventions @@ -207,10 +207,6 @@ limitations under the License. // those. package logr -import ( - "context" -) - // New returns a new Logger instance. This is primarily used by libraries // implementing LogSink, rather than end users. Passing a nil sink will create // a Logger which discards all log lines. @@ -258,6 +254,12 @@ type Logger struct { // Enabled tests whether this Logger is enabled. For example, commandline // flags might be used to set the logging verbosity and disable some info logs. func (l Logger) Enabled() bool { + // Some implementations of LogSink look at the caller in Enabled (e.g. + // different verbosity levels per package or file), but we only pass one + // CallDepth in (via Init). This means that all calls from Logger to the + // LogSink's Enabled, Info, and Error methods must have the same number of + // frames. In other words, Logger methods can't call other Logger methods + // which call these LogSink methods unless we do it the same in all paths. return l.sink != nil && l.sink.Enabled(l.level) } @@ -267,11 +269,11 @@ func (l Logger) Enabled() bool { // line. The key/value pairs can then be used to add additional variable // information. The key/value pairs must alternate string keys and arbitrary // values. -func (l Logger) Info(msg string, keysAndValues ...interface{}) { +func (l Logger) Info(msg string, keysAndValues ...any) { if l.sink == nil { return } - if l.Enabled() { + if l.sink.Enabled(l.level) { // see comment in Enabled if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { withHelper.GetCallStackHelper()() } @@ -289,7 +291,7 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) { // while the err argument should be used to attach the actual error that // triggered this log line, if present. The err parameter is optional // and nil may be passed instead of an error instance. -func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { +func (l Logger) Error(err error, msg string, keysAndValues ...any) { if l.sink == nil { return } @@ -314,9 +316,16 @@ func (l Logger) V(level int) Logger { return l } +// GetV returns the verbosity level of the logger. If the logger's LogSink is +// nil as in the Discard logger, this will always return 0. +func (l Logger) GetV() int { + // 0 if l.sink nil because of the if check in V above. + return l.level +} + // WithValues returns a new Logger instance with additional key/value pairs. // See Info for documentation on how key/value pairs work. -func (l Logger) WithValues(keysAndValues ...interface{}) Logger { +func (l Logger) WithValues(keysAndValues ...any) Logger { if l.sink == nil { return l } @@ -397,45 +406,6 @@ func (l Logger) IsZero() bool { return l.sink == nil } -// contextKey is how we find Loggers in a context.Context. -type contextKey struct{} - -// FromContext returns a Logger from ctx or an error if no Logger is found. -func FromContext(ctx context.Context) (Logger, error) { - if v, ok := ctx.Value(contextKey{}).(Logger); ok { - return v, nil - } - - return Logger{}, notFoundError{} -} - -// notFoundError exists to carry an IsNotFound method. -type notFoundError struct{} - -func (notFoundError) Error() string { - return "no logr.Logger was present" -} - -func (notFoundError) IsNotFound() bool { - return true -} - -// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this -// returns a Logger that discards all log messages. -func FromContextOrDiscard(ctx context.Context) Logger { - if v, ok := ctx.Value(contextKey{}).(Logger); ok { - return v - } - - return Discard() -} - -// NewContext returns a new Context, derived from ctx, which carries the -// provided Logger. -func NewContext(ctx context.Context, logger Logger) context.Context { - return context.WithValue(ctx, contextKey{}, logger) -} - // RuntimeInfo holds information that the logr "core" library knows which // LogSinks might want to know. type RuntimeInfo struct { @@ -467,15 +437,15 @@ type LogSink interface { // The level argument is provided for optional logging. This method will // only be called when Enabled(level) is true. See Logger.Info for more // details. - Info(level int, msg string, keysAndValues ...interface{}) + Info(level int, msg string, keysAndValues ...any) // Error logs an error, with the given message and key/value pairs as // context. See Logger.Error for more details. - Error(err error, msg string, keysAndValues ...interface{}) + Error(err error, msg string, keysAndValues ...any) // WithValues returns a new LogSink with additional key/value pairs. See // Logger.WithValues for more details. - WithValues(keysAndValues ...interface{}) LogSink + WithValues(keysAndValues ...any) LogSink // WithName returns a new LogSink with the specified name appended. See // Logger.WithName for more details. @@ -546,5 +516,5 @@ type Marshaler interface { // with exported fields // // It may return any value of any type. - MarshalLog() interface{} + MarshalLog() any } diff --git a/vendor/github.com/go-logr/logr/sloghandler.go b/vendor/github.com/go-logr/logr/sloghandler.go new file mode 100644 index 0000000000..82d1ba4948 --- /dev/null +++ b/vendor/github.com/go-logr/logr/sloghandler.go @@ -0,0 +1,192 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The logr 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 logr + +import ( + "context" + "log/slog" +) + +type slogHandler struct { + // May be nil, in which case all logs get discarded. + sink LogSink + // Non-nil if sink is non-nil and implements SlogSink. + slogSink SlogSink + + // groupPrefix collects values from WithGroup calls. It gets added as + // prefix to value keys when handling a log record. + groupPrefix string + + // levelBias can be set when constructing the handler to influence the + // slog.Level of log records. A positive levelBias reduces the + // slog.Level value. slog has no API to influence this value after the + // handler got created, so it can only be set indirectly through + // Logger.V. + levelBias slog.Level +} + +var _ slog.Handler = &slogHandler{} + +// groupSeparator is used to concatenate WithGroup names and attribute keys. +const groupSeparator = "." + +// GetLevel is used for black box unit testing. +func (l *slogHandler) GetLevel() slog.Level { + return l.levelBias +} + +func (l *slogHandler) Enabled(_ context.Context, level slog.Level) bool { + return l.sink != nil && (level >= slog.LevelError || l.sink.Enabled(l.levelFromSlog(level))) +} + +func (l *slogHandler) Handle(ctx context.Context, record slog.Record) error { + if l.slogSink != nil { + // Only adjust verbosity level of log entries < slog.LevelError. + if record.Level < slog.LevelError { + record.Level -= l.levelBias + } + return l.slogSink.Handle(ctx, record) + } + + // No need to check for nil sink here because Handle will only be called + // when Enabled returned true. + + kvList := make([]any, 0, 2*record.NumAttrs()) + record.Attrs(func(attr slog.Attr) bool { + kvList = attrToKVs(attr, l.groupPrefix, kvList) + return true + }) + if record.Level >= slog.LevelError { + l.sinkWithCallDepth().Error(nil, record.Message, kvList...) + } else { + level := l.levelFromSlog(record.Level) + l.sinkWithCallDepth().Info(level, record.Message, kvList...) + } + return nil +} + +// sinkWithCallDepth adjusts the stack unwinding so that when Error or Info +// are called by Handle, code in slog gets skipped. +// +// This offset currently (Go 1.21.0) works for calls through +// slog.New(ToSlogHandler(...)). There's no guarantee that the call +// chain won't change. Wrapping the handler will also break unwinding. It's +// still better than not adjusting at all.... +// +// This cannot be done when constructing the handler because FromSlogHandler needs +// access to the original sink without this adjustment. A second copy would +// work, but then WithAttrs would have to be called for both of them. +func (l *slogHandler) sinkWithCallDepth() LogSink { + if sink, ok := l.sink.(CallDepthLogSink); ok { + return sink.WithCallDepth(2) + } + return l.sink +} + +func (l *slogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + if l.sink == nil || len(attrs) == 0 { + return l + } + + clone := *l + if l.slogSink != nil { + clone.slogSink = l.slogSink.WithAttrs(attrs) + clone.sink = clone.slogSink + } else { + kvList := make([]any, 0, 2*len(attrs)) + for _, attr := range attrs { + kvList = attrToKVs(attr, l.groupPrefix, kvList) + } + clone.sink = l.sink.WithValues(kvList...) + } + return &clone +} + +func (l *slogHandler) WithGroup(name string) slog.Handler { + if l.sink == nil { + return l + } + if name == "" { + // slog says to inline empty groups + return l + } + clone := *l + if l.slogSink != nil { + clone.slogSink = l.slogSink.WithGroup(name) + clone.sink = clone.slogSink + } else { + clone.groupPrefix = addPrefix(clone.groupPrefix, name) + } + return &clone +} + +// attrToKVs appends a slog.Attr to a logr-style kvList. It handle slog Groups +// and other details of slog. +func attrToKVs(attr slog.Attr, groupPrefix string, kvList []any) []any { + attrVal := attr.Value.Resolve() + if attrVal.Kind() == slog.KindGroup { + groupVal := attrVal.Group() + grpKVs := make([]any, 0, 2*len(groupVal)) + prefix := groupPrefix + if attr.Key != "" { + prefix = addPrefix(groupPrefix, attr.Key) + } + for _, attr := range groupVal { + grpKVs = attrToKVs(attr, prefix, grpKVs) + } + kvList = append(kvList, grpKVs...) + } else if attr.Key != "" { + kvList = append(kvList, addPrefix(groupPrefix, attr.Key), attrVal.Any()) + } + + return kvList +} + +func addPrefix(prefix, name string) string { + if prefix == "" { + return name + } + if name == "" { + return prefix + } + return prefix + groupSeparator + name +} + +// levelFromSlog adjusts the level by the logger's verbosity and negates it. +// It ensures that the result is >= 0. This is necessary because the result is +// passed to a LogSink and that API did not historically document whether +// levels could be negative or what that meant. +// +// Some example usage: +// +// logrV0 := getMyLogger() +// logrV2 := logrV0.V(2) +// slogV2 := slog.New(logr.ToSlogHandler(logrV2)) +// slogV2.Debug("msg") // =~ logrV2.V(4) =~ logrV0.V(6) +// slogV2.Info("msg") // =~ logrV2.V(0) =~ logrV0.V(2) +// slogv2.Warn("msg") // =~ logrV2.V(-4) =~ logrV0.V(0) +func (l *slogHandler) levelFromSlog(level slog.Level) int { + result := -level + result += l.levelBias // in case the original Logger had a V level + if result < 0 { + result = 0 // because LogSink doesn't expect negative V levels + } + return int(result) +} diff --git a/vendor/github.com/go-logr/logr/slogr.go b/vendor/github.com/go-logr/logr/slogr.go new file mode 100644 index 0000000000..28a83d0243 --- /dev/null +++ b/vendor/github.com/go-logr/logr/slogr.go @@ -0,0 +1,100 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The logr 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 logr + +import ( + "context" + "log/slog" +) + +// FromSlogHandler returns a Logger which writes to the slog.Handler. +// +// The logr verbosity level is mapped to slog levels such that V(0) becomes +// slog.LevelInfo and V(4) becomes slog.LevelDebug. +func FromSlogHandler(handler slog.Handler) Logger { + if handler, ok := handler.(*slogHandler); ok { + if handler.sink == nil { + return Discard() + } + return New(handler.sink).V(int(handler.levelBias)) + } + return New(&slogSink{handler: handler}) +} + +// ToSlogHandler returns a slog.Handler which writes to the same sink as the Logger. +// +// The returned logger writes all records with level >= slog.LevelError as +// error log entries with LogSink.Error, regardless of the verbosity level of +// the Logger: +// +// logger := +// slog.New(ToSlogHandler(logger.V(10))).Error(...) -> logSink.Error(...) +// +// The level of all other records gets reduced by the verbosity +// level of the Logger and the result is negated. If it happens +// to be negative, then it gets replaced by zero because a LogSink +// is not expected to handled negative levels: +// +// slog.New(ToSlogHandler(logger)).Debug(...) -> logger.GetSink().Info(level=4, ...) +// slog.New(ToSlogHandler(logger)).Warning(...) -> logger.GetSink().Info(level=0, ...) +// slog.New(ToSlogHandler(logger)).Info(...) -> logger.GetSink().Info(level=0, ...) +// slog.New(ToSlogHandler(logger.V(4))).Info(...) -> logger.GetSink().Info(level=4, ...) +func ToSlogHandler(logger Logger) slog.Handler { + if sink, ok := logger.GetSink().(*slogSink); ok && logger.GetV() == 0 { + return sink.handler + } + + handler := &slogHandler{sink: logger.GetSink(), levelBias: slog.Level(logger.GetV())} + if slogSink, ok := handler.sink.(SlogSink); ok { + handler.slogSink = slogSink + } + return handler +} + +// SlogSink is an optional interface that a LogSink can implement to support +// logging through the slog.Logger or slog.Handler APIs better. It then should +// also support special slog values like slog.Group. When used as a +// slog.Handler, the advantages are: +// +// - stack unwinding gets avoided in favor of logging the pre-recorded PC, +// as intended by slog +// - proper grouping of key/value pairs via WithGroup +// - verbosity levels > slog.LevelInfo can be recorded +// - less overhead +// +// Both APIs (Logger and slog.Logger/Handler) then are supported equally +// well. Developers can pick whatever API suits them better and/or mix +// packages which use either API in the same binary with a common logging +// implementation. +// +// This interface is necessary because the type implementing the LogSink +// interface cannot also implement the slog.Handler interface due to the +// different prototype of the common Enabled method. +// +// An implementation could support both interfaces in two different types, but then +// additional interfaces would be needed to convert between those types in FromSlogHandler +// and ToSlogHandler. +type SlogSink interface { + LogSink + + Handle(ctx context.Context, record slog.Record) error + WithAttrs(attrs []slog.Attr) SlogSink + WithGroup(name string) SlogSink +} diff --git a/vendor/github.com/go-logr/logr/slogsink.go b/vendor/github.com/go-logr/logr/slogsink.go new file mode 100644 index 0000000000..4060fcbc2b --- /dev/null +++ b/vendor/github.com/go-logr/logr/slogsink.go @@ -0,0 +1,120 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The logr 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 logr + +import ( + "context" + "log/slog" + "runtime" + "time" +) + +var ( + _ LogSink = &slogSink{} + _ CallDepthLogSink = &slogSink{} + _ Underlier = &slogSink{} +) + +// Underlier is implemented by the LogSink returned by NewFromLogHandler. +type Underlier interface { + // GetUnderlying returns the Handler used by the LogSink. + GetUnderlying() slog.Handler +} + +const ( + // nameKey is used to log the `WithName` values as an additional attribute. + nameKey = "logger" + + // errKey is used to log the error parameter of Error as an additional attribute. + errKey = "err" +) + +type slogSink struct { + callDepth int + name string + handler slog.Handler +} + +func (l *slogSink) Init(info RuntimeInfo) { + l.callDepth = info.CallDepth +} + +func (l *slogSink) GetUnderlying() slog.Handler { + return l.handler +} + +func (l *slogSink) WithCallDepth(depth int) LogSink { + newLogger := *l + newLogger.callDepth += depth + return &newLogger +} + +func (l *slogSink) Enabled(level int) bool { + return l.handler.Enabled(context.Background(), slog.Level(-level)) +} + +func (l *slogSink) Info(level int, msg string, kvList ...interface{}) { + l.log(nil, msg, slog.Level(-level), kvList...) +} + +func (l *slogSink) Error(err error, msg string, kvList ...interface{}) { + l.log(err, msg, slog.LevelError, kvList...) +} + +func (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) { + var pcs [1]uintptr + // skip runtime.Callers, this function, Info/Error, and all helper functions above that. + runtime.Callers(3+l.callDepth, pcs[:]) + + record := slog.NewRecord(time.Now(), level, msg, pcs[0]) + if l.name != "" { + record.AddAttrs(slog.String(nameKey, l.name)) + } + if err != nil { + record.AddAttrs(slog.Any(errKey, err)) + } + record.Add(kvList...) + _ = l.handler.Handle(context.Background(), record) +} + +func (l slogSink) WithName(name string) LogSink { + if l.name != "" { + l.name += "/" + } + l.name += name + return &l +} + +func (l slogSink) WithValues(kvList ...interface{}) LogSink { + l.handler = l.handler.WithAttrs(kvListToAttrs(kvList...)) + return &l +} + +func kvListToAttrs(kvList ...interface{}) []slog.Attr { + // We don't need the record itself, only its Add method. + record := slog.NewRecord(time.Time{}, 0, "", 0) + record.Add(kvList...) + attrs := make([]slog.Attr, 0, record.NumAttrs()) + record.Attrs(func(attr slog.Attr) bool { + attrs = append(attrs, attr) + return true + }) + return attrs +} diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1/olmconfig_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1/olmconfig_types.go new file mode 100644 index 0000000000..f1135e6a3a --- /dev/null +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1/olmconfig_types.go @@ -0,0 +1,71 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + DisabledCopiedCSVsConditionType = "DisabledCopiedCSVs" +) + +// OLMConfigSpec is the spec for an OLMConfig resource. +type OLMConfigSpec struct { + Features *Features `json:"features,omitempty"` +} + +// Features contains the list of configurable OLM features. +type Features struct { + + // DisableCopiedCSVs is used to disable OLM's "Copied CSV" feature + // for operators installed at the cluster scope, where a cluster + // scoped operator is one that has been installed in an + // OperatorGroup that targets all namespaces. + // When reenabled, OLM will recreate the "Copied CSVs" for each + // cluster scoped operator. + DisableCopiedCSVs *bool `json:"disableCopiedCSVs,omitempty"` +} + +// OLMConfigStatus is the status for an OLMConfig resource. +type OLMConfigStatus struct { + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:storageversion +// +kubebuilder:resource:categories=olm,scope=Cluster +// +kubebuilder:subresource:status + +// OLMConfig is a resource responsible for configuring OLM. +type OLMConfig struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + Spec OLMConfigSpec `json:"spec,omitempty"` + Status OLMConfigStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OLMConfigList is a list of OLMConfig resources. +type OLMConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + // +listType=set + Items []OLMConfig `json:"items"` +} + +func init() { + SchemeBuilder.Register(&OLMConfig{}, &OLMConfigList{}) +} + +// CopiedCSVsAreEnabled returns true if and only if the olmConfigs DisableCopiedCSVs is set and true, +// otherwise false is returned +func (config *OLMConfig) CopiedCSVsAreEnabled() bool { + if config == nil || config.Spec.Features == nil || config.Spec.Features.DisableCopiedCSVs == nil { + return true + } + + return !*config.Spec.Features.DisableCopiedCSVs +} diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1/operatorgroup_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1/operatorgroup_types.go index f5d112668c..81ad352d4e 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1/operatorgroup_types.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1/operatorgroup_types.go @@ -19,8 +19,34 @@ const ( OperatorGroupLabelPrefix = "olm.operatorgroup.uid/" OperatorGroupLabelTemplate = OperatorGroupLabelPrefix + "%s" + + OperatorGroupServiceAccountCondition = "OperatorGroupServiceAccount" + MutlipleOperatorGroupCondition = "MultipleOperatorGroup" + MultipleOperatorGroupsReason = "MultipleOperatorGroupsFound" + OperatorGroupServiceAccountReason = "ServiceAccountNotFound" + + // UpgradeStrategyDefault configures OLM such that it will only allow + // clusterServiceVersions to move to the replacing phase to the succeeded + // phase. This effectively means that OLM will not allow operators to move + // to the next version if an installation or upgrade has failed. + UpgradeStrategyDefault UpgradeStrategy = "Default" + + // UpgradeStrategyUnsafeFailForward configures OLM such that it will allow + // clusterServiceVersions to move to the replacing phase from the succeeded + // phase or from the failed phase. Additionally, OLM will generate new + // installPlans when a subscription references a failed installPlan and the + // catalog has been updated with a new upgrade for the existing set of + // operators. + // + // WARNING: The UpgradeStrategyUnsafeFailForward upgrade strategy is unsafe + // and may result in unexpected behavior or unrecoverable data loss unless + // you have deep understanding of the set of operators being managed in the + // namespace. + UpgradeStrategyUnsafeFailForward UpgradeStrategy = "TechPreviewUnsafeFailForward" ) +type UpgradeStrategy string + // OperatorGroupSpec is the spec for an OperatorGroup resource. type OperatorGroupSpec struct { // Selector selects the OperatorGroup's target namespaces. @@ -40,6 +66,29 @@ type OperatorGroupSpec struct { // Static tells OLM not to update the OperatorGroup's providedAPIs annotation // +optional StaticProvidedAPIs bool `json:"staticProvidedAPIs,omitempty"` + + // UpgradeStrategy defines the upgrade strategy for operators in the namespace. + // There are currently two supported upgrade strategies: + // + // Default: OLM will only allow clusterServiceVersions to move to the replacing + // phase from the succeeded phase. This effectively means that OLM will not + // allow operators to move to the next version if an installation or upgrade + // has failed. + // + // TechPreviewUnsafeFailForward: OLM will allow clusterServiceVersions to move to the + // replacing phase from the succeeded phase or from the failed phase. + // Additionally, OLM will generate new installPlans when a subscription references + // a failed installPlan and the catalog has been updated with a new upgrade for + // the existing set of operators. + // + // WARNING: The TechPreviewUnsafeFailForward upgrade strategy is unsafe and may result + // in unexpected behavior or unrecoverable data loss unless you have deep + // understanding of the set of operators being managed in the namespace. + // + // +kubebuilder:validation:Enum=Default;TechPreviewUnsafeFailForward + // +kubebuilder:default=Default + // +optional + UpgradeStrategy UpgradeStrategy `json:"upgradeStrategy,omitempty"` } // OperatorGroupStatus is the status for an OperatorGroupResource. @@ -53,6 +102,9 @@ type OperatorGroupStatus struct { // LastUpdated is a timestamp of the last time the OperatorGroup's status was Updated. LastUpdated *metav1.Time `json:"lastUpdated"` + + // Conditions is an array of the OperatorGroup's conditions. + Conditions []metav1.Condition `json:"conditions,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -68,6 +120,7 @@ type OperatorGroup struct { metav1.ObjectMeta `json:"metadata"` // +optional + // +kubebuilder:default={upgradeStrategy:Default} Spec OperatorGroupSpec `json:"spec"` Status OperatorGroupStatus `json:"status,omitempty"` } @@ -90,6 +143,17 @@ func (o *OperatorGroup) BuildTargetNamespaces() string { return strings.Join(ns, ",") } +// UpgradeStrategy returns the UpgradeStrategy specified or the default value otherwise. +func (o *OperatorGroup) UpgradeStrategy() UpgradeStrategy { + strategyName := o.Spec.UpgradeStrategy + switch { + case strategyName == UpgradeStrategyUnsafeFailForward: + return strategyName + default: + return UpgradeStrategyDefault + } +} + // IsServiceAccountSpecified returns true if the spec has a service account name specified. func (o *OperatorGroup) IsServiceAccountSpecified() bool { if o.Spec.ServiceAccountName == "" { diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/api/pkg/operators/v1/zz_generated.deepcopy.go index bf9402457d..89a3007bc1 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* @@ -75,6 +76,127 @@ func (in *Condition) DeepCopy() *Condition { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Features) DeepCopyInto(out *Features) { + *out = *in + if in.DisableCopiedCSVs != nil { + in, out := &in.DisableCopiedCSVs, &out.DisableCopiedCSVs + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Features. +func (in *Features) DeepCopy() *Features { + if in == nil { + return nil + } + out := new(Features) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OLMConfig) DeepCopyInto(out *OLMConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OLMConfig. +func (in *OLMConfig) DeepCopy() *OLMConfig { + if in == nil { + return nil + } + out := new(OLMConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OLMConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OLMConfigList) DeepCopyInto(out *OLMConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OLMConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OLMConfigList. +func (in *OLMConfigList) DeepCopy() *OLMConfigList { + if in == nil { + return nil + } + out := new(OLMConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OLMConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OLMConfigSpec) DeepCopyInto(out *OLMConfigSpec) { + *out = *in + if in.Features != nil { + in, out := &in.Features, &out.Features + *out = new(Features) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OLMConfigSpec. +func (in *OLMConfigSpec) DeepCopy() *OLMConfigSpec { + if in == nil { + return nil + } + out := new(OLMConfigSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OLMConfigStatus) DeepCopyInto(out *OLMConfigStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OLMConfigStatus. +func (in *OLMConfigStatus) DeepCopy() *OLMConfigStatus { + if in == nil { + return nil + } + out := new(OLMConfigStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Operator) DeepCopyInto(out *Operator) { *out = *in @@ -316,6 +438,13 @@ func (in *OperatorGroupStatus) DeepCopyInto(out *OperatorGroupStatus) { in, out := &in.LastUpdated, &out.LastUpdated *out = (*in).DeepCopy() } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorGroupStatus. diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go index da273e70ad..726f8e1aa1 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/catalogsource_types.go @@ -1,17 +1,19 @@ package v1alpha1 import ( + "encoding/json" "fmt" - "time" - "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "time" ) const ( - CatalogSourceCRDAPIVersion = GroupName + "/" + GroupVersion - CatalogSourceKind = "CatalogSource" + CatalogSourceCRDAPIVersion = GroupName + "/" + GroupVersion + CatalogSourceKind = "CatalogSource" + DefaultRegistryPollDuration = 15 * time.Minute ) // SourceType indicates the type of backing store for a CatalogSource @@ -36,6 +38,8 @@ const ( CatalogSourceConfigMapError ConditionReason = "ConfigMapError" // CatalogSourceRegistryServerError denotes when there is an issue querying the specified registry server. CatalogSourceRegistryServerError ConditionReason = "RegistryServerError" + // CatalogSourceIntervalInvalidError denotes if the registry polling interval is invalid. + CatalogSourceIntervalInvalidError ConditionReason = "InvalidIntervalError" ) type CatalogSourceSpec struct { @@ -48,35 +52,40 @@ type CatalogSourceSpec struct { // The range of the priority value can go from positive to negative in the range of int32. // The default value to a catalog source with unassigned priority would be 0. // The catalog source with the same priority values will be ranked lexicographically based on its name. - // +Optional + // +optional Priority int `json:"priority,omitempty"` // ConfigMap is the name of the ConfigMap to be used to back a configmap-server registry. // Only used when SourceType = SourceTypeConfigmap or SourceTypeInternal. - // +Optional + // +optional ConfigMap string `json:"configMap,omitempty"` // Address is a host that OLM can use to connect to a pre-existing registry. // Format: : // Only used when SourceType = SourceTypeGrpc. // Ignored when the Image field is set. - // +Optional + // +optional Address string `json:"address,omitempty"` // Image is an operator-registry container image to instantiate a registry-server with. // Only used when SourceType = SourceTypeGrpc. // If present, the address field is ignored. - // +Optional + // +optional Image string `json:"image,omitempty"` + // GrpcPodConfig exposes different overrides for the pod spec of the CatalogSource Pod. + // Only used when SourceType = SourceTypeGrpc and Image is set. + // +optional + GrpcPodConfig *GrpcPodConfig `json:"grpcPodConfig,omitempty"` + // UpdateStrategy defines how updated catalog source images can be discovered // Consists of an interval that defines polling duration and an embedded strategy type - // +Optional + // +optional UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"` // Secrets represent set of secrets that can be used to access the contents of the catalog. // It is best to keep this list small, since each will need to be tried for every catalog entry. - // +Optional + // +optional Secrets []string `json:"secrets,omitempty"` // Metadata @@ -86,6 +95,24 @@ type CatalogSourceSpec struct { Icon Icon `json:"icon,omitempty"` } +// GrpcPodConfig contains configuration specified for a catalog source +type GrpcPodConfig struct { + // NodeSelector is a selector which must be true for the pod to fit on a node. + // Selector which must match a node's labels for the pod to be scheduled on that node. + // +optional + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + + // Tolerations are the catalog source's pod's tolerations. + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + + // If specified, indicates the pod's priority. + // If not specified, the pod priority will be default or zero if there is no + // default. + // +optional + PriorityClassName *string `json:"priorityClassName,omitempty"` +} + // UpdateStrategy holds all the different types of catalog source update strategies // Currently only registry polling strategy is implemented type UpdateStrategy struct { @@ -96,7 +123,32 @@ type RegistryPoll struct { // Interval is used to determine the time interval between checks of the latest catalog source version. // The catalog operator polls to see if a new version of the catalog source is available. // If available, the latest image is pulled and gRPC traffic is directed to the latest catalog source. - Interval *metav1.Duration `json:"interval,omitempty"` + RawInterval string `json:"interval,omitempty"` + Interval *metav1.Duration `json:"-"` + ParsingError string `json:"-"` +} + +// UnmarshalJSON implements the encoding/json.Unmarshaler interface. +func (u *UpdateStrategy) UnmarshalJSON(data []byte) (err error) { + type alias struct { + *RegistryPoll `json:"registryPoll,omitempty"` + } + us := alias{} + if err = json.Unmarshal(data, &us); err != nil { + return err + } + registryPoll := &RegistryPoll{ + RawInterval: us.RegistryPoll.RawInterval, + } + duration, err := time.ParseDuration(registryPoll.RawInterval) + if err != nil { + registryPoll.ParsingError = fmt.Sprintf("error parsing spec.updateStrategy.registryPoll.interval. Using the default value of %s instead. Error: %s", DefaultRegistryPollDuration, err) + registryPoll.Interval = &metav1.Duration{Duration: DefaultRegistryPollDuration} + } else { + registryPoll.Interval = &metav1.Duration{Duration: duration} + } + u.RegistryPoll = registryPoll + return nil } type RegistryServiceStatus struct { @@ -131,6 +183,16 @@ type CatalogSourceStatus struct { ConfigMapResource *ConfigMapResourceReference `json:"configMapReference,omitempty"` RegistryServiceStatus *RegistryServiceStatus `json:"registryService,omitempty"` GRPCConnectionState *GRPCConnectionState `json:"connectionState,omitempty"` + + // Represents the state of a CatalogSource. Note that Message and Reason represent the original + // status information, which may be migrated to be conditions based in the future. Any new features + // introduced will use conditions. + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` } type ConfigMapResourceReference struct { diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/clusterserviceversion_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/clusterserviceversion_types.go index 9389ef5288..eb4d1635ea 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/clusterserviceversion_types.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/clusterserviceversion_types.go @@ -50,18 +50,21 @@ type InstallModeSet map[InstallModeType]bool // NamedInstallStrategy represents the block of an ClusterServiceVersion resource // where the install strategy is specified. +// +k8s:openapi-gen=true type NamedInstallStrategy struct { StrategyName string `json:"strategy"` StrategySpec StrategyDetailsDeployment `json:"spec,omitempty"` } // StrategyDeploymentPermissions describe the rbac rules and service account needed by the install strategy +// +k8s:openapi-gen=true type StrategyDeploymentPermissions struct { ServiceAccountName string `json:"serviceAccountName"` Rules []rbac.PolicyRule `json:"rules"` } // StrategyDeploymentSpec contains the name, spec and labels for the deployment ALM should create +// +k8s:openapi-gen=true type StrategyDeploymentSpec struct { Name string `json:"name"` Spec appsv1.DeploymentSpec `json:"spec"` @@ -70,6 +73,7 @@ type StrategyDeploymentSpec struct { // StrategyDetailsDeployment represents the parsed details of a Deployment // InstallStrategy. +// +k8s:openapi-gen=true type StrategyDetailsDeployment struct { DeploymentSpecs []StrategyDeploymentSpec `json:"deployments"` Permissions []StrategyDeploymentPermissions `json:"permissions,omitempty"` @@ -265,6 +269,7 @@ type APIServiceDefinitions struct { // ClusterServiceVersionSpec declarations tell OLM how to install an operator // that can manage apps for a given version. +// +k8s:openapi-gen=true type ClusterServiceVersionSpec struct { InstallStrategy NamedInstallStrategy `json:"install"` Version version.OperatorVersion `json:"version,omitempty"` @@ -321,25 +326,30 @@ type ClusterServiceVersionSpec struct { RelatedImages []RelatedImage `json:"relatedImages,omitempty"` } +// +k8s:openapi-gen=true type CleanupSpec struct { Enabled bool `json:"enabled"` } +// +k8s:openapi-gen=true type Maintainer struct { Name string `json:"name,omitempty"` Email string `json:"email,omitempty"` } +// +k8s:openapi-gen=true type AppLink struct { Name string `json:"name,omitempty"` URL string `json:"url,omitempty"` } +// +k8s:openapi-gen=true type Icon struct { Data string `json:"base64data"` MediaType string `json:"mediatype"` } +// +k8s:openapi-gen=true type RelatedImage struct { Name string `json:"name"` Image string `json:"image"` @@ -418,6 +428,7 @@ func (c *ClusterServiceVersion) HasCAResources() bool { } // Conditions appear in the status as a record of state transitions on the ClusterServiceVersion +// +k8s:openapi-gen=true type ClusterServiceVersionCondition struct { // Condition of the ClusterServiceVersion Phase ClusterServiceVersionPhase `json:"phase,omitempty"` @@ -473,6 +484,7 @@ const ( ) // DependentStatus is the status for a dependent requirement (to prevent infinite nesting) +// +k8s:openapi-gen=true type DependentStatus struct { Group string `json:"group"` Version string `json:"version"` @@ -482,6 +494,7 @@ type DependentStatus struct { Message string `json:"message,omitempty"` } +// +k8s:openapi-gen=true type RequirementStatus struct { Group string `json:"group"` Version string `json:"version"` @@ -495,6 +508,7 @@ type RequirementStatus struct { // ClusterServiceVersionStatus represents information about the status of a CSV. Status may trail the actual // state of a system. +// +k8s:openapi-gen=true type ClusterServiceVersionStatus struct { // Current condition of the ClusterServiceVersion Phase ClusterServiceVersionPhase `json:"phase,omitempty"` @@ -527,6 +541,7 @@ type ClusterServiceVersionStatus struct { } // CleanupStatus represents information about the status of cleanup while a CSV is pending deletion +// +k8s:openapi-gen=true type CleanupStatus struct { // PendingDeletion is the list of custom resource objects that are pending deletion and blocked on finalizers. // This indicates the progress of cleanup that is blocking CSV deletion or operator uninstall. @@ -535,12 +550,14 @@ type CleanupStatus struct { } // ResourceList represents a list of resources which are of the same Group/Kind +// +k8s:openapi-gen=true type ResourceList struct { Group string `json:"group"` Kind string `json:"kind"` Instances []ResourceInstance `json:"instances"` } +// +k8s:openapi-gen=true type ResourceInstance struct { Name string `json:"name"` // Namespace can be empty for cluster-scoped resources diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/installplan_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/installplan_types.go index 6b56a5d727..5210436d98 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/installplan_types.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/installplan_types.go @@ -71,6 +71,7 @@ const ( StepStatusNotPresent StepStatus = "NotPresent" StepStatusPresent StepStatus = "Present" StepStatusCreated StepStatus = "Created" + StepStatusNotCreated StepStatus = "NotCreated" StepStatusWaitingForAPI StepStatus = "WaitingForApi" StepStatusUnsupportedResource StepStatus = "UnsupportedResource" ) @@ -227,6 +228,7 @@ func ConditionMet(cond InstallPlanConditionType, now *metav1.Time) InstallPlanCo type Step struct { Resolving string `json:"resolving"` Resource StepResource `json:"resource"` + Optional bool `json:"optional,omitempty"` Status StepStatus `json:"status"` } diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go index 7eaae1e68c..e048d4988c 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/subscription_types.go @@ -102,6 +102,9 @@ const ( // SubscriptionInstallPlanFailed indicates that the installation of a Subscription's InstallPlan has failed. SubscriptionInstallPlanFailed SubscriptionConditionType = "InstallPlanFailed" + + // SubscriptionResolutionFailed indicates that the dependency resolution in the namespace in which the subscription is created has failed + SubscriptionResolutionFailed SubscriptionConditionType = "ResolutionFailed" ) const ( diff --git a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go index 7e00067107..c094738eed 100644 --- a/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/operator-framework/api/pkg/operators/v1alpha1/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* @@ -22,9 +23,9 @@ package v1alpha1 import ( "encoding/json" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - corev1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" @@ -160,7 +161,7 @@ func (in *BundleLookup) DeepCopyInto(out *BundleLookup) { *out = *in if in.CatalogSourceRef != nil { in, out := &in.CatalogSourceRef, &out.CatalogSourceRef - *out = new(corev1.ObjectReference) + *out = new(v1.ObjectReference) **out = **in } if in.Conditions != nil { @@ -308,6 +309,11 @@ func (in *CatalogSourceList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CatalogSourceSpec) DeepCopyInto(out *CatalogSourceSpec) { *out = *in + if in.GrpcPodConfig != nil { + in, out := &in.GrpcPodConfig, &out.GrpcPodConfig + *out = new(GrpcPodConfig) + (*in).DeepCopyInto(*out) + } if in.UpdateStrategy != nil { in, out := &in.UpdateStrategy, &out.UpdateStrategy *out = new(UpdateStrategy) @@ -353,6 +359,13 @@ func (in *CatalogSourceStatus) DeepCopyInto(out *CatalogSourceStatus) { *out = new(GRPCConnectionState) (*in).DeepCopyInto(*out) } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogSourceStatus. @@ -500,7 +513,7 @@ func (in *ClusterServiceVersionSpec) DeepCopyInto(out *ClusterServiceVersionSpec } if in.NativeAPIs != nil { in, out := &in.NativeAPIs, &out.NativeAPIs - *out = make([]v1.GroupVersionKind, len(*in)) + *out = make([]metav1.GroupVersionKind, len(*in)) copy(*out, *in) } if in.Keywords != nil { @@ -545,7 +558,7 @@ func (in *ClusterServiceVersionSpec) DeepCopyInto(out *ClusterServiceVersionSpec } if in.Selector != nil { in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } out.Cleanup = in.Cleanup @@ -693,6 +706,40 @@ func (in *GRPCConnectionState) DeepCopy() *GRPCConnectionState { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GrpcPodConfig) DeepCopyInto(out *GrpcPodConfig) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PriorityClassName != nil { + in, out := &in.PriorityClassName, &out.PriorityClassName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrpcPodConfig. +func (in *GrpcPodConfig) DeepCopy() *GrpcPodConfig { + if in == nil { + return nil + } + out := new(GrpcPodConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Icon) DeepCopyInto(out *Icon) { *out = *in @@ -896,7 +943,7 @@ func (in *InstallPlanStatus) DeepCopyInto(out *InstallPlanStatus) { } if in.AttenuatedServiceAccountRef != nil { in, out := &in.AttenuatedServiceAccountRef, &out.AttenuatedServiceAccountRef - *out = new(corev1.ObjectReference) + *out = new(v1.ObjectReference) **out = **in } if in.StartTime != nil { @@ -951,7 +998,7 @@ func (in *RegistryPoll) DeepCopyInto(out *RegistryPoll) { *out = *in if in.Interval != nil { in, out := &in.Interval, &out.Interval - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } } @@ -1250,7 +1297,7 @@ func (in *SubscriptionCatalogHealth) DeepCopyInto(out *SubscriptionCatalogHealth *out = *in if in.CatalogSourceRef != nil { in, out := &in.CatalogSourceRef, &out.CatalogSourceRef - *out = new(corev1.ObjectReference) + *out = new(v1.ObjectReference) **out = **in } if in.LastUpdated != nil { @@ -1297,7 +1344,7 @@ func (in *SubscriptionConfig) DeepCopyInto(out *SubscriptionConfig) { *out = *in if in.Selector != nil { in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } if in.NodeSelector != nil { @@ -1309,40 +1356,40 @@ func (in *SubscriptionConfig) DeepCopyInto(out *SubscriptionConfig) { } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) + *out = make([]v1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = new(corev1.ResourceRequirements) + *out = new(v1.ResourceRequirements) (*in).DeepCopyInto(*out) } if in.EnvFrom != nil { in, out := &in.EnvFrom, &out.EnvFrom - *out = make([]corev1.EnvFromSource, len(*in)) + *out = make([]v1.EnvFromSource, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]corev1.EnvVar, len(*in)) + *out = make([]v1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes - *out = make([]corev1.Volume, len(*in)) + *out = make([]v1.Volume, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts - *out = make([]corev1.VolumeMount, len(*in)) + *out = make([]v1.VolumeMount, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1421,7 +1468,7 @@ func (in *SubscriptionStatus) DeepCopyInto(out *SubscriptionStatus) { } if in.InstallPlanRef != nil { in, out := &in.InstallPlanRef, &out.InstallPlanRef - *out = new(corev1.ObjectReference) + *out = new(v1.ObjectReference) **out = **in } if in.CatalogHealth != nil { @@ -1498,7 +1545,7 @@ func (in *WebhookDescription) DeepCopyInto(out *WebhookDescription) { } if in.ObjectSelector != nil { in, out := &in.ObjectSelector, &out.ObjectSelector - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } if in.SideEffects != nil { diff --git a/vendor/golang.org/x/lint/README.md b/vendor/golang.org/x/lint/README.md index 4968b13aef..989b1dc238 100644 --- a/vendor/golang.org/x/lint/README.md +++ b/vendor/golang.org/x/lint/README.md @@ -1,5 +1,10 @@ +**NOTE:** Golint is [deprecated and frozen](https://github.com/golang/go/issues/38968). +There's no drop-in replacement for it, but tools such as [Staticcheck](https://staticcheck.io/) +and `go vet` should be used instead. + Golint is a linter for Go source code. +[![Go Reference](https://pkg.go.dev/badge/golang.org/x/lint.svg)](https://pkg.go.dev/golang.org/x/lint) [![Build Status](https://travis-ci.org/golang/lint.svg?branch=master)](https://travis-ci.org/golang/lint) ## Installation diff --git a/vendor/modules.txt b/vendor/modules.txt index f341e3cd15..d37fdba9ae 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -32,8 +32,8 @@ github.com/davecgh/go-spew/spew github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2 github.com/devfile/api/v2/pkg/attributes github.com/devfile/api/v2/pkg/devfile -# github.com/devfile/devworkspace-operator v0.31.0 -## explicit; go 1.20 +# github.com/devfile/devworkspace-operator v0.35.0 +## explicit; go 1.23.0 github.com/devfile/devworkspace-operator/apis/controller/v1alpha1 github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers @@ -58,8 +58,8 @@ github.com/evanphx/json-patch/v5 # github.com/fsnotify/fsnotify v1.6.0 => github.com/fsnotify/fsnotify v1.4.7 ## explicit github.com/fsnotify/fsnotify -# github.com/go-logr/logr v1.2.4 -## explicit; go 1.16 +# github.com/go-logr/logr v1.4.1 +## explicit; go 1.18 github.com/go-logr/logr # github.com/go-logr/zapr v1.2.3 ## explicit; go 1.16 @@ -118,7 +118,7 @@ github.com/json-iterator/go # github.com/konsorten/go-windows-terminal-sequences v1.0.2 => github.com/konsorten/go-windows-terminal-sequences v1.0.1 ## explicit github.com/konsorten/go-windows-terminal-sequences -# github.com/mailru/easyjson v0.7.6 => github.com/mailru/easyjson v0.0.0-20200218084223-8edcc4e51f39 +# github.com/mailru/easyjson v0.7.7 => github.com/mailru/easyjson v0.0.0-20200218084223-8edcc4e51f39 ## explicit; go 1.12 github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer @@ -135,7 +135,7 @@ github.com/modern-go/reflect2 # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 => github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d ## explicit github.com/munnerz/goautoneg -# github.com/onsi/gomega v1.27.10 => github.com/onsi/gomega v1.7.0 +# github.com/onsi/gomega v1.34.1 => github.com/onsi/gomega v1.7.0 ## explicit github.com/onsi/gomega/gstruct/errors github.com/onsi/gomega/types @@ -150,8 +150,8 @@ github.com/openshift/api/route/v1 github.com/openshift/api/security/v1 github.com/openshift/api/template/v1 github.com/openshift/api/user/v1 -# github.com/operator-framework/api v0.10.0 -## explicit; go 1.15 +# github.com/operator-framework/api v0.15.0 +## explicit; go 1.17 github.com/operator-framework/api/pkg/lib/version github.com/operator-framework/api/pkg/operators github.com/operator-framework/api/pkg/operators/v1 @@ -196,7 +196,7 @@ github.com/sirupsen/logrus # github.com/spf13/pflag v1.0.5 => github.com/spf13/pflag v1.0.5 ## explicit; go 1.12 github.com/spf13/pflag -# github.com/stretchr/testify v1.8.4 => github.com/stretchr/testify v1.4.0 +# github.com/stretchr/testify v1.10.0 => github.com/stretchr/testify v1.4.0 ## explicit github.com/stretchr/testify/assert # go.uber.org/atomic v1.7.0 => go.uber.org/atomic v1.7.0 @@ -216,14 +216,14 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# golang.org/x/lint v0.0.0-20200302205851-738671d3881b +# golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 ## explicit; go 1.11 golang.org/x/lint golang.org/x/lint/golint -# golang.org/x/mod v0.17.0 => golang.org/x/mod v0.17.0 +# golang.org/x/mod v0.19.0 => golang.org/x/mod v0.17.0 ## explicit; go 1.18 golang.org/x/mod/semver -# golang.org/x/net v0.36.0 => golang.org/x/net v0.36.0 +# golang.org/x/net v0.38.0 => golang.org/x/net v0.36.0 ## explicit; go 1.23.0 golang.org/x/net/http/httpguts golang.org/x/net/http/httpproxy @@ -237,18 +237,18 @@ golang.org/x/net/trace ## explicit; go 1.23.0 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.10.0 => golang.org/x/sync v0.10.0 +# golang.org/x/sync v0.12.0 => golang.org/x/sync v0.10.0 ## explicit; go 1.18 golang.org/x/sync/errgroup -# golang.org/x/sys v0.30.0 => golang.org/x/sys v0.28.0 +# golang.org/x/sys v0.31.0 => golang.org/x/sys v0.28.0 ## explicit; go 1.18 golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.29.0 => golang.org/x/term v0.27.0 +# golang.org/x/term v0.30.0 => golang.org/x/term v0.27.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.22.0 => golang.org/x/text v0.21.0 +# golang.org/x/text v0.23.0 => golang.org/x/text v0.21.0 ## explicit; go 1.18 golang.org/x/text/secure/bidirule golang.org/x/text/transform @@ -258,7 +258,7 @@ golang.org/x/text/width # golang.org/x/time v0.3.0 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d => golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d +# golang.org/x/tools v0.23.0 => golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d ## explicit; go 1.19 golang.org/x/tools/go/analysis golang.org/x/tools/go/analysis/passes/inspect