From 0b2bdcda7af1dd257c58f5391b8704c37b50ade3 Mon Sep 17 00:00:00 2001 From: raaizik <132667934+raaizik@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:25:35 +0300 Subject: [PATCH] controllers: create VRCs - Creates VolRepClass in response to changes made to DRClusterConfig - k8s csi addons bump Signed-off-by: raaizik <132667934+raaizik@users.noreply.github.com> --- ...client-operator.clusterserviceversion.yaml | 9 +- cmd/main.go | 2 + config/rbac/role.yaml | 9 +- go.mod | 18 +- go.sum | 30 +- .../controller/storageclaim_controller.go | 125 +++- pkg/utils/k8sutils.go | 10 + .../csi-addons/kubernetes-csi-addons/LICENSE | 202 +++++++ .../v1alpha1/groupversion_info.go | 36 ++ .../v1alpha1/volumegroupreplication_types.go | 105 ++++ .../volumegroupreplicationclass_types.go | 67 ++ .../volumegroupreplicationcontent_types.go | 101 ++++ .../v1alpha1/volumereplication_types.go | 173 ++++++ .../v1alpha1/volumereplicationclass_types.go | 69 +++ .../v1alpha1/zz_generated.deepcopy.go | 570 ++++++++++++++++++ vendor/github.com/onsi/gomega/CHANGELOG.md | 8 + vendor/github.com/onsi/gomega/gomega_dsl.go | 2 +- .../bipartitegraph/bipartitegraphmatching.go | 2 +- .../ramen/api/v1alpha1/drpolicy_types.go | 47 ++ .../v1alpha1/volumereplicationgroup_types.go | 16 +- .../api/v1alpha1/zz_generated.deepcopy.go | 87 ++- .../x/exp/constraints/constraints.go | 50 -- vendor/golang.org/x/exp/slices/cmp.go | 44 -- vendor/golang.org/x/exp/slices/slices.go | 515 ---------------- vendor/golang.org/x/exp/slices/sort.go | 197 ------ .../golang.org/x/exp/slices/zsortanyfunc.go | 479 --------------- .../golang.org/x/exp/slices/zsortordered.go | 481 --------------- .../api/resource/v1alpha3/generated.pb.go | 258 ++++---- .../api/resource/v1alpha3/generated.proto | 2 +- vendor/k8s.io/api/resource/v1alpha3/types.go | 2 +- .../v1alpha3/types_swagger_doc_generated.go | 2 +- vendor/modules.txt | 20 +- 32 files changed, 1800 insertions(+), 1938 deletions(-) create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go create mode 100644 vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/golang.org/x/exp/constraints/constraints.go delete mode 100644 vendor/golang.org/x/exp/slices/cmp.go delete mode 100644 vendor/golang.org/x/exp/slices/slices.go delete mode 100644 vendor/golang.org/x/exp/slices/sort.go delete mode 100644 vendor/golang.org/x/exp/slices/zsortanyfunc.go delete mode 100644 vendor/golang.org/x/exp/slices/zsortordered.go diff --git a/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml b/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml index 5521f0894..7fea5e76b 100644 --- a/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml +++ b/bundle/manifests/ocs-client-operator.clusterserviceversion.yaml @@ -309,11 +309,18 @@ spec: resources: - drclusterconfigs verbs: + - get + - list + - watch + - apiGroups: + - replication.storage.openshift.io + resources: + - volumereplicationclass + verbs: - create - delete - get - list - - update - watch - apiGroups: - security.openshift.io diff --git a/cmd/main.go b/cmd/main.go index e348a7772..9fc623fe0 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -31,6 +31,7 @@ import ( // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1" + replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1" snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" nbapis "github.com/noobaa/noobaa-operator/v5/pkg/apis" configv1 "github.com/openshift/api/config/v1" @@ -80,6 +81,7 @@ func init() { utilruntime.Must(csiopv1a1.AddToScheme(scheme)) utilruntime.Must(nbapis.AddToScheme(scheme)) utilruntime.Must(ramenv1alpha1.AddToScheme(scheme)) + utilruntime.Must(replicationv1alpha1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index a10832889..22157eb4f 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -266,11 +266,18 @@ rules: resources: - drclusterconfigs verbs: + - get + - list + - watch +- apiGroups: + - replication.storage.openshift.io + resources: + - volumereplicationclass + verbs: - create - delete - get - list - - update - watch - apiGroups: - security.openshift.io diff --git a/go.mod b/go.mod index c922468ab..0b4214171 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,11 @@ module github.com/red-hat-storage/ocs-client-operator -go 1.22.5 +go 1.22.6 replace ( github.com/portworx/sched-ops => github.com/portworx/sched-ops v0.20.4-openstorage-rc3 // required by Rook v1.12 github.com/red-hat-storage/ocs-client-operator/api => ./api + k8s.io/client-go v12.0.0+incompatible => k8s.io/client-go v0.29.0 vbom.ml/util => github.com/fvbommel/util v0.0.0-20180919145318-efcd4e0f9787 ) @@ -19,22 +20,25 @@ exclude ( require ( github.com/ceph/ceph-csi-operator/api v0.0.0-20240812072523-4d50cf3a32a0 + github.com/csi-addons/kubernetes-csi-addons v0.10.0 github.com/go-logr/logr v1.4.2 github.com/kubernetes-csi/external-snapshotter/client/v8 v8.0.0 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.34.1 + github.com/onsi/gomega v1.34.2 github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3 github.com/operator-framework/api v0.27.0 + github.com/pkg/errors v0.9.1 // indirect github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.76.0 - github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237 + github.com/ramendr/ramen/api v0.0.0-20241105140706-d8587766acb3 github.com/red-hat-storage/ocs-client-operator/api v0.0.0-00010101000000-000000000000 github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241113175552-201c936738fd github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.66.0 - k8s.io/api v0.31.0 + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/api v0.31.1 k8s.io/apiextensions-apiserver v0.31.0 - k8s.io/apimachinery v0.31.0 - k8s.io/client-go v0.31.0 + k8s.io/apimachinery v0.31.1 + k8s.io/client-go v0.31.1 k8s.io/klog/v2 v2.130.1 k8s.io/utils v0.0.0-20240821151609-f90d01438635 sigs.k8s.io/controller-runtime v0.19.0 @@ -45,10 +49,8 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1 // indirect github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/x448/float16 v0.8.4 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/component-base v0.31.0 // indirect sigs.k8s.io/container-object-storage-interface-api v0.1.0 // indirect ) diff --git a/go.sum b/go.sum index f92042139..3fe722a49 100644 --- a/go.sum +++ b/go.sum @@ -66,6 +66,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/csi-addons/kubernetes-csi-addons v0.10.0 h1:bBc6nb1oROz4RLhqoLFNeGymk2jIRXcx7LvAup9+3Jg= +github.com/csi-addons/kubernetes-csi-addons v0.10.0/go.mod h1:nqi369YuYMIdysBbHjtYJcWFpcxujPot1HS6tnNWBV4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -207,8 +209,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -291,15 +293,15 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -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/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3 h1:Igew1pwW1pAiBQj0KP7Ms0SaPr8neAvbUhjBuTtJsSo= github.com/openshift/api v0.0.0-20240828125535-01b3675ba7b3/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 h1:cHyxR+Y8rAMT6m1jQCaYGRwikqahI0OjjUDhFNf3ySQ= @@ -323,8 +325,8 @@ github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVho github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237 h1:ig6ePD0yopC5Qi5BRmhsIsKaOkdsGXTSmG3HTYIpquo= -github.com/ramendr/ramen/api v0.0.0-20241001141243-29d6f22ad237/go.mod h1:nO6VM/+PEhcPGyFIQJdhY6ip822cA61PAy/s6IjenAA= +github.com/ramendr/ramen/api v0.0.0-20241105140706-d8587766acb3 h1:q4UjNvv3jzKOeG/S+S1Ms2FV3WajBIE6266/7BIxdX4= +github.com/ramendr/ramen/api v0.0.0-20241105140706-d8587766acb3/go.mod h1:O7VpTy8MMrh31DF4fv+2SZBSouAr8NlzIY4KYx7K75U= github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241113175552-201c936738fd h1:WIdoP1CE/8yl9tnHFVY7g/h4ZDFk+2Y9Ri0PrHXfx1g= github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-20241113175552-201c936738fd/go.mod h1:t9GJk69TGXABBF8fFPB+ImpbA9mJyRS86wW6+Qn8xHo= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -765,17 +767,17 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ= k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= -k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= -k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU= +k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI= k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= k8s.io/apimachinery v0.23.3/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= -k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= +k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= -k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= -k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0= +k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg= k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/code-generator v0.23.3/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= diff --git a/internal/controller/storageclaim_controller.go b/internal/controller/storageclaim_controller.go index fe52bf50b..c6609d9f3 100644 --- a/internal/controller/storageclaim_controller.go +++ b/internal/controller/storageclaim_controller.go @@ -20,15 +20,20 @@ import ( "context" "encoding/json" "fmt" + "reflect" "slices" "strings" "time" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/event" + v1alpha1 "github.com/red-hat-storage/ocs-client-operator/api/v1alpha1" "github.com/red-hat-storage/ocs-client-operator/pkg/templates" "github.com/red-hat-storage/ocs-client-operator/pkg/utils" csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1" + replicationv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1" "github.com/go-logr/logr" snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" @@ -109,12 +114,57 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error { }); err != nil { return fmt.Errorf("unable to set up FieldIndexer for VSC csi driver name: %v", err) } + enqueueStorageClaim := handler.EnqueueRequestsFromMapFunc( + func(_ context.Context, _ client.Object) []reconcile.Request { + sclaims := &v1alpha1.StorageClaimList{} + err := r.list(sclaims) + if err != nil { + r.log.Error(err, "Unable to list StorageClaim objects") + return []reconcile.Request{} + } + + // Return name of the StorageClaim object + request := []reconcile.Request{} + for _, claim := range sclaims.Items { + request = append(request, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: claim.Name, + }, + }) + } + return request + }, + ) + drClusterConfigPredicate := predicate.Funcs{ + UpdateFunc: func(e event.UpdateEvent) bool { + if e.ObjectOld == nil || e.ObjectNew == nil { + return false + } + oldObj, ok := e.ObjectOld.(*ramenv1alpha1.DRClusterConfig) + if !ok { + return false + } + newObj, ok := e.ObjectNew.(*ramenv1alpha1.DRClusterConfig) + if !ok { + return false + } + return !reflect.DeepEqual(oldObj.Spec.ReplicationSchedules, newObj.Spec.ReplicationSchedules) + }, + DeleteFunc: func(e event.DeleteEvent) bool { + if e.Object == nil { + return false + } + _, ok := e.Object.(*ramenv1alpha1.DRClusterConfig) + return ok || e.DeleteStateUnknown + }, + } generationChangePredicate := predicate.GenerationChangedPredicate{} bldr := ctrl.NewControllerManagedBy(mgr). For(&v1alpha1.StorageClaim{}, builder.WithPredicates(generationChangePredicate)). Owns(&storagev1.StorageClass{}). Owns(&snapapi.VolumeSnapshotClass{}). + Owns(&replicationv1alpha1.VolumeReplicationClass{}, builder.WithPredicates(generationChangePredicate)). Owns(&csiopv1a1.ClientProfile{}, builder.WithPredicates(generationChangePredicate)). Watches( &extv1.CustomResourceDefinition{}, @@ -127,7 +177,8 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error { ) if r.AvailableCrds[drClusterConfigCRDName] { - bldr = bldr.Owns(&ramenv1alpha1.DRClusterConfig{}, builder.WithPredicates(generationChangePredicate)) + bldr = bldr.Watches(&ramenv1alpha1.DRClusterConfig{}, enqueueStorageClaim, + builder.WithPredicates(drClusterConfigPredicate)) } return bldr.Complete(r) @@ -141,8 +192,9 @@ func (r *StorageClaimReconciler) SetupWithManager(mgr ctrl.Manager) error { //+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotclasses,verbs=get;list;watch;create;delete //+kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch //+kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents,verbs=get;list;watch +//+kubebuilder:rbac:groups=ramendr.openshift.io,resources=drclusterconfigs,verbs=get;list;watch +//+kubebuilder:rbac:groups=replication.storage.openshift.io,resources=volumereplicationclass,verbs=get;list;watch;create;delete //+kubebuilder:rbac:groups=csi.ceph.io,resources=clientprofiles,verbs=get;list;update;create;watch;delete -//+kubebuilder:rbac:groups=ramendr.openshift.io,resources=drclusterconfigs,verbs=get;list;update;create;watch;delete // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -424,6 +476,75 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) { if err != nil { return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeSnapshotClass: %s", err) } + case "VolumeReplicationClass": + data := map[string]string{} + err = json.Unmarshal(resource.Data, &data) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to unmarshal StorageClaim configuration response: %v", err) + } + data["replication.storage.openshift.io/replication-secret-namespace"] = r.OperatorNamespace + // generate a new clusterID for cephfs subvolumegroup, as + // storageclaim is clusterscoped resources using its + // hash as the clusterID + data["clusterID"] = r.storageClaimHash + + // sanity check that there's a single DRClusterConfig per cluster + drclusterconfigs := &ramenv1alpha1.DRClusterConfigList{} + err = r.list(drclusterconfigs) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to get DRClusterConfigList: %v", err) + } + if len(drclusterconfigs.Items) > 1 { + return reconcile.Result{}, fmt.Errorf("there's more than one DRClusterConfig attached to the cluster") + } + vrcs := &replicationv1alpha1.VolumeReplicationClassList{} + err = r.list(vrcs) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to get VolumeReplicationClassList: %v", err) + } + // check if DRClusterConfig has been removed + if len(drclusterconfigs.Items) == 0 { + for _, vrc := range vrcs.Items { + err = r.Delete(r.ctx, &vrc) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to delete VolumeReplicationClass %v: %v", vrc.Name, err) + } + } + } + drclusterconfig := &drclusterconfigs.Items[0] + // check if Scheduling intervals have been deleted from DRClusterConfig + replicationSchedules := drclusterconfig.Spec.ReplicationSchedules + if len(replicationSchedules) < len(vrcs.Items) { + // delete VolumeReplicationClasses that have their replication schedule removed from DRClusterConfig + for _, vrc := range vrcs.Items { + if !slices.Contains(replicationSchedules, vrc.Spec.Parameters["schedulingInterval"]) { + err = r.Delete(r.ctx, &vrc) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to delete VolumeReplicationClass %v: %v", vrc.Name, err) + } + } + } + } + + for interval := range drclusterconfig.Spec.ReplicationSchedules { + volumeReplicationClass := &replicationv1alpha1.VolumeReplicationClass{} + volumeReplicationClass.Name = fmt.Sprintf("%s-%s", r.storageClaim.Name, drclusterconfig.Spec.ReplicationSchedules[interval]) + if strings.Contains(resource.Name, "flatten") { + volumeReplicationClass.Name = fmt.Sprintf("%s-%s", volumeReplicationClass.Name, "flatten") + } + err = utils.CreateOrReplace(r.ctx, r.Client, volumeReplicationClass, func() error { + data["schedulingInterval"] = drclusterconfig.Spec.ReplicationSchedules[interval] + utils.AddLabels(volumeReplicationClass, resource.Labels) + utils.AddAnnotation(volumeReplicationClass, storageClaimAnnotation, r.storageClaim.Name) + utils.AddAnnotations(volumeReplicationClass, resource.Annotations) + volumeReplicationClass.Spec.Parameters = data + volumeReplicationClass.Spec.Provisioner = templates.RBDDriverName + return nil + }) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to create or update VolumeReplicationClass: %s", err) + } + } case "ClientProfile": clientProfile := &csiopv1a1.ClientProfile{} clientProfile.Name = r.storageClaimHash diff --git a/pkg/utils/k8sutils.go b/pkg/utils/k8sutils.go index c3f97bbf3..ee91605c1 100644 --- a/pkg/utils/k8sutils.go +++ b/pkg/utils/k8sutils.go @@ -114,6 +114,16 @@ func AddAnnotation(obj metav1.Object, key string, value string) bool { return false } +// AddAnnotations adds values from newAnnotations to the keys on the supplied obj or overwrites values for existing keys on the obj +func AddAnnotations(obj metav1.Object, newAnnotations map[string]string) { + annotations := obj.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + obj.SetAnnotations(annotations) + } + maps.Copy(annotations, newAnnotations) +} + func GetMD5Hash(text string) string { hash := md5.Sum([]byte(text)) return hex.EncodeToString(hash[:]) diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE b/vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go new file mode 100644 index 000000000..37182b68d --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 The Kubernetes-CSI-Addons 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 v1alpha1 contains API Schema definitions for the replication.storage v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=replication.storage.openshift.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "replication.storage.openshift.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go new file mode 100644 index 000000000..8ad2bff70 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplication_types.go @@ -0,0 +1,105 @@ +/* +Copyright 2024 The Kubernetes-CSI-Addons 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeGroupReplicationSpec defines the desired state of VolumeGroupReplication +type VolumeGroupReplicationSpec struct { + // volumeGroupReplicationClassName is the volumeGroupReplicationClass name for this VolumeGroupReplication resource + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeGroupReplicationClassName is immutable" + VolumeGroupReplicationClassName string `json:"volumeGroupReplicationClassName"` + + // volumeReplicationClassName is the volumeReplicationClass name for VolumeReplication object + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumReplicationClassName is immutable" + VolumeReplicationClassName string `json:"volumeReplicationClassName"` + + // Name of the VolumeReplication object created for this volumeGroupReplication + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeReplicationName is immutable" + VolumeReplicationName string `json:"volumeReplicationName,omitempty"` + + // Name of the VolumeGroupReplicationContent object created for this volumeGroupReplication + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeGroupReplicationContentName is immutable" + VolumeGroupReplicationContentName string `json:"volumeGroupReplicationContentName,omitempty"` + + // Source specifies where a group replications will be created from. + // This field is immutable after creation. + // Required. + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="source is immutable" + Source VolumeGroupReplicationSource `json:"source"` + + // ReplicationState represents the replication operation to be performed on the group. + // Supported operations are "primary", "secondary" and "resync" + // +kubebuilder:validation:Required + ReplicationState ReplicationState `json:"replicationState"` + + // AutoResync represents the group to be auto resynced when + // ReplicationState is "secondary" + // +kubebuilder:default:=false + AutoResync bool `json:"autoResync"` +} + +// VolumeGroupReplicationSource specifies the source for the the volumeGroupReplication +type VolumeGroupReplicationSource struct { + // Selector is a label query over persistent volume claims that are to be + // grouped together for replication. + // +optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="selector is immutable" + Selector *metav1.LabelSelector `json:"selector,omitempty"` +} + +// VolumeGroupReplicationStatus defines the observed state of VolumeGroupReplication +type VolumeGroupReplicationStatus struct { + VolumeReplicationStatus `json:",inline"` + // PersistentVolumeClaimsRefList is the list of PVCs for the volume group replication. + // The maximum number of allowed PVCs in the group is 100. + // +optional + PersistentVolumeClaimsRefList []corev1.LocalObjectReference `json:"persistentVolumeClaimsRefList,omitempty"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// VolumeGroupReplication is the Schema for the volumegroupreplications API +type VolumeGroupReplication struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VolumeGroupReplicationSpec `json:"spec,omitempty"` + Status VolumeGroupReplicationStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VolumeGroupReplicationList contains a list of VolumeGroupReplication +type VolumeGroupReplicationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeGroupReplication `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeGroupReplication{}, &VolumeGroupReplicationList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go new file mode 100644 index 000000000..972bcd1ba --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationclass_types.go @@ -0,0 +1,67 @@ +/* +Copyright 2024 The Kubernetes-CSI-Addons 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeGroupReplicationClassSpec specifies parameters that an underlying storage system uses +// when creating a volumegroup replica. A specific VolumeGroupReplicationClass is used by specifying +// its name in a VolumeGroupReplication object. +// +kubebuilder:validation:XValidation:rule="has(self.parameters) == has(oldSelf.parameters)",message="parameters are immutable" +type VolumeGroupReplicationClassSpec struct { + // Provisioner is the name of storage provisioner + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="provisioner is immutable" + Provisioner string `json:"provisioner"` + // Parameters is a key-value map with storage provisioner specific configurations for + // creating volume group replicas + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="parameters are immutable" + Parameters map[string]string `json:"parameters,omitempty"` +} + +// VolumeGroupReplicationClassStatus defines the observed state of VolumeGroupReplicationClass +type VolumeGroupReplicationClassStatus struct { +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// VolumeGroupReplicationClass is the Schema for the volumegroupreplicationclasses API +type VolumeGroupReplicationClass struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VolumeGroupReplicationClassSpec `json:"spec,omitempty"` + Status VolumeGroupReplicationClassStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VolumeGroupReplicationClassList contains a list of VolumeGroupReplicationClass +type VolumeGroupReplicationClassList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeGroupReplicationClass `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeGroupReplicationClass{}, &VolumeGroupReplicationClassList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go new file mode 100644 index 000000000..fcbb7a95a --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumegroupreplicationcontent_types.go @@ -0,0 +1,101 @@ +/* +Copyright 2024 The Kubernetes-CSI-Addons 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeGroupReplicationContentSpec defines the desired state of VolumeGroupReplicationContent +type VolumeGroupReplicationContentSpec struct { + // VolumeGroupreplicationRef specifies the VolumeGroupReplication object to which this + // VolumeGroupReplicationContent object is bound. + // VolumeGroupReplication.Spec.VolumeGroupReplicationContentName field must reference to + // this VolumeGroupReplicationContent's name for the bidirectional binding to be valid. + // For a pre-existing VolumeGroupReplicationContent object, name and namespace of the + // VolumeGroupReplication object MUST be provided for binding to happen. + // This field is immutable after creation. + // Required. + // +kubebuilder:validation:XValidation:rule="has(self.name) && has(self.__namespace__)",message="both volumeGroupReplicationRef.name and volumeGroupReplicationRef.namespace must be set" + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeGroupReplicationRef is immutable" + VolumeGroupReplicationRef corev1.ObjectReference `json:"volumeGroupReplicationRef"` + + // VolumeGroupReplicationHandle is a unique id returned by the CSI driver + // to identify the VolumeGroupReplication on the storage system. + VolumeGroupReplicationHandle string `json:"volumeGroupReplicationHandle"` + + // provisioner is the name of the CSI driver used to create the physical + // volume group on + // the underlying storage system. + // This MUST be the same as the name returned by the CSI GetPluginName() call for + // that driver. + // Required. + Provisioner string `json:"provisioner"` + + // VolumeGroupReplicationClassName is the name of the VolumeGroupReplicationClass from + // which this group replication was (or will be) created. + // +optional + VolumeGroupReplicationClassName string `json:"volumeGroupReplicationClassName"` + + // Source specifies whether the snapshot is (or should be) dynamically provisioned + // or already exists, and just requires a Kubernetes object representation. + // This field is immutable after creation. + // Required. + Source VolumeGroupReplicationContentSource `json:"source"` +} + +// VolumeGroupReplicationContentSource represents the CSI source of a group replication. +type VolumeGroupReplicationContentSource struct { + // VolumeHandles is a list of volume handles on the backend to be grouped + // and replicated. + VolumeHandles []string `json:"volumeHandles"` +} + +// VolumeGroupReplicationContentStatus defines the status of VolumeGroupReplicationContent +type VolumeGroupReplicationContentStatus struct { + // PersistentVolumeRefList is the list of of PV for the group replication + // The maximum number of allowed PV in the group is 100. + // +optional + PersistentVolumeRefList []corev1.LocalObjectReference `json:"persistentVolumeRefList,omitempty"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// VolumeGroupReplicationContent is the Schema for the volumegroupreplicationcontents API +type VolumeGroupReplicationContent struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VolumeGroupReplicationContentSpec `json:"spec,omitempty"` + Status VolumeGroupReplicationContentStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VolumeGroupReplicationContentList contains a list of VolumeGroupReplicationContent +type VolumeGroupReplicationContentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeGroupReplicationContent `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeGroupReplicationContent{}, &VolumeGroupReplicationContentList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go new file mode 100644 index 000000000..0e777409b --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplication_types.go @@ -0,0 +1,173 @@ +/* +Copyright 2022 The Kubernetes-CSI-Addons 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + VolumeReplicationNameAnnotation = "replication.storage.openshift.io/volume-replication-name" +) + +// These are valid condition statuses. +// "ConditionCompleted" means the condition is fulfilled. +// "ConditionDegraded" means the condition is not fulfilled. +// "ConditionResyncing" means the condition is resyncing. +const ( + ConditionCompleted = "Completed" + ConditionDegraded = "Degraded" + ConditionResyncing = "Resyncing" + ConditionValidated = "Validated" +) + +// These are valid conditions. + +const ( + // Success condition represents the successful completion of the operation. + Success = "Success" + // Promoted condition represents the successful promotion of the volume. + Promoted = "Promoted" + // Demoted condition represents the successful demotion of the volume. + Demoted = "Demoted" + // FailedToPromote condition represents the failure to promote the volume. + FailedToPromote = "FailedToPromote" + // FailedToDemote condition represents the failure to demote the volume. + FailedToDemote = "FailedToDemote" + // Error condition represents the error in the operation. + Error = "Error" + // VolumeDegraded condition represents the volume is degraded. + VolumeDegraded = "VolumeDegraded" + // Healthy condition represents the volume is healthy. + Healthy = "Healthy" + // ResyncTriggered condition represents the resync operation is triggered. + ResyncTriggered = "ResyncTriggered" + // FailedToResync condition represents the failure to resync the volume. + FailedToResync = "FailedToResync" + // NotResyncing condition represents the volume is not resyncing. + NotResyncing = "NotResyncing" + // PrerequisiteMet condition represents that the prerequisite is met. + PrerequisiteMet = "PrerequisiteMet" + // PrerequisiteNotMet condition represents that the prerequisite is not met. + PrerequisiteNotMet = "PrerequisiteNotMet" +) + +// ReplicationState represents the replication operations to be performed on the volume. +// +kubebuilder:validation:Enum=primary;secondary;resync +type ReplicationState string + +const ( + // Primary ReplicationState enables mirroring and promotes the volume to primary. + Primary ReplicationState = "primary" + + // Secondary ReplicationState demotes the volume to secondary and resyncs the volume if out of sync. + Secondary ReplicationState = "secondary" + + // Resync option resyncs the volume. + Resync ReplicationState = "resync" +) + +// State captures the latest state of the replication operation. +type State string + +const ( + // PrimaryState represents the Primary replication state. + PrimaryState State = "Primary" + + // SecondaryState represents the Secondary replication state. + SecondaryState State = "Secondary" + + // UnknownState represents the Unknown replication state. + UnknownState State = "Unknown" +) + +// VolumeReplicationSpec defines the desired state of VolumeReplication. +type VolumeReplicationSpec struct { + // VolumeReplicationClass is the VolumeReplicationClass name for this VolumeReplication resource + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeReplicationClass is immutable" + VolumeReplicationClass string `json:"volumeReplicationClass"` + + // ReplicationState represents the replication operation to be performed on the volume. + // Supported operations are "primary", "secondary" and "resync" + // +kubebuilder:validation:Required + ReplicationState ReplicationState `json:"replicationState"` + + // DataSource represents the object associated with the volume + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="dataSource is immutable" + DataSource corev1.TypedLocalObjectReference `json:"dataSource"` + + // AutoResync represents the volume to be auto resynced when + // ReplicationState is "secondary" + // +kubebuilder:default:=false + AutoResync bool `json:"autoResync"` + + // replicationHandle represents an existing (but new) replication id + // +kubebuilder:validation:Optional + ReplicationHandle string `json:"replicationHandle"` +} + +// VolumeReplicationStatus defines the observed state of VolumeReplication. +type VolumeReplicationStatus struct { + State State `json:"state,omitempty"` + Message string `json:"message,omitempty"` + // Conditions are the list of conditions and their status. + Conditions []metav1.Condition `json:"conditions,omitempty"` + // observedGeneration is the last generation change the operator has dealt with + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + LastStartTime *metav1.Time `json:"lastStartTime,omitempty"` + LastCompletionTime *metav1.Time `json:"lastCompletionTime,omitempty"` + LastSyncTime *metav1.Time `json:"lastSyncTime,omitempty"` + LastSyncBytes *int64 `json:"lastSyncBytes,omitempty"` + LastSyncDuration *metav1.Duration `json:"lastSyncDuration,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name=Age,type=date +// +kubebuilder:printcolumn:JSONPath=".spec.volumeReplicationClass",name=volumeReplicationClass,type=string +// +kubebuilder:printcolumn:JSONPath=".spec.dataSource.name",name=pvcName,type=string +// +kubebuilder:printcolumn:JSONPath=".spec.replicationState",name=desiredState,type=string +// +kubebuilder:printcolumn:JSONPath=".status.state",name=currentState,type=string +// +kubebuilder:resource:shortName=vr + +// VolumeReplication is the Schema for the volumereplications API. +type VolumeReplication struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +kubebuilder:validation:Required + Spec VolumeReplicationSpec `json:"spec"` + + Status VolumeReplicationStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// VolumeReplicationList contains a list of VolumeReplication. +type VolumeReplicationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeReplication `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeReplication{}, &VolumeReplicationList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go new file mode 100644 index 000000000..25632a049 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/volumereplicationclass_types.go @@ -0,0 +1,69 @@ +/* +Copyright 2022 The Kubernetes-CSI-Addons 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// VolumeReplicationClassSpec specifies parameters that an underlying storage system uses +// when creating a volume replica. A specific VolumeReplicationClass is used by specifying +// its name in a VolumeReplication object. +// +kubebuilder:validation:XValidation:rule="has(self.parameters) == has(oldSelf.parameters)",message="parameters are immutable" +type VolumeReplicationClassSpec struct { + // Provisioner is the name of storage provisioner + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="provisioner is immutable" + Provisioner string `json:"provisioner"` + // Parameters is a key-value map with storage provisioner specific configurations for + // creating volume replicas + // +kubebuilder:validation:Optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="parameters are immutable" + Parameters map[string]string `json:"parameters,omitempty"` +} + +// VolumeReplicationClassStatus defines the observed state of VolumeReplicationClass. +type VolumeReplicationClassStatus struct{} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster,shortName=vrc +// +kubebuilder:printcolumn:JSONPath=".spec.provisioner",name=provisioner,type=string + +// VolumeReplicationClass is the Schema for the volumereplicationclasses API. +type VolumeReplicationClass struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +kubebuilder:validation:Required + Spec VolumeReplicationClassSpec `json:"spec"` + + Status VolumeReplicationClassStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// VolumeReplicationClassList contains a list of VolumeReplicationClass. +type VolumeReplicationClassList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VolumeReplicationClass `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VolumeReplicationClass{}, &VolumeReplicationClassList{}) +} diff --git a/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..dcfe62b46 --- /dev/null +++ b/vendor/github.com/csi-addons/kubernetes-csi-addons/api/replication.storage/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,570 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2022 The Kubernetes-CSI-Addons 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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplication) DeepCopyInto(out *VolumeGroupReplication) { + *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 VolumeGroupReplication. +func (in *VolumeGroupReplication) DeepCopy() *VolumeGroupReplication { + if in == nil { + return nil + } + out := new(VolumeGroupReplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplication) 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 *VolumeGroupReplicationClass) DeepCopyInto(out *VolumeGroupReplicationClass) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClass. +func (in *VolumeGroupReplicationClass) DeepCopy() *VolumeGroupReplicationClass { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClass) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationClass) 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 *VolumeGroupReplicationClassList) DeepCopyInto(out *VolumeGroupReplicationClassList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeGroupReplicationClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClassList. +func (in *VolumeGroupReplicationClassList) DeepCopy() *VolumeGroupReplicationClassList { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClassList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationClassList) 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 *VolumeGroupReplicationClassSpec) DeepCopyInto(out *VolumeGroupReplicationClassSpec) { + *out = *in + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClassSpec. +func (in *VolumeGroupReplicationClassSpec) DeepCopy() *VolumeGroupReplicationClassSpec { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClassSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationClassStatus) DeepCopyInto(out *VolumeGroupReplicationClassStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationClassStatus. +func (in *VolumeGroupReplicationClassStatus) DeepCopy() *VolumeGroupReplicationClassStatus { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationClassStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContent) DeepCopyInto(out *VolumeGroupReplicationContent) { + *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 VolumeGroupReplicationContent. +func (in *VolumeGroupReplicationContent) DeepCopy() *VolumeGroupReplicationContent { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationContent) 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 *VolumeGroupReplicationContentList) DeepCopyInto(out *VolumeGroupReplicationContentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeGroupReplicationContent, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentList. +func (in *VolumeGroupReplicationContentList) DeepCopy() *VolumeGroupReplicationContentList { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationContentList) 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 *VolumeGroupReplicationContentSource) DeepCopyInto(out *VolumeGroupReplicationContentSource) { + *out = *in + if in.VolumeHandles != nil { + in, out := &in.VolumeHandles, &out.VolumeHandles + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentSource. +func (in *VolumeGroupReplicationContentSource) DeepCopy() *VolumeGroupReplicationContentSource { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContentSpec) DeepCopyInto(out *VolumeGroupReplicationContentSpec) { + *out = *in + out.VolumeGroupReplicationRef = in.VolumeGroupReplicationRef + in.Source.DeepCopyInto(&out.Source) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentSpec. +func (in *VolumeGroupReplicationContentSpec) DeepCopy() *VolumeGroupReplicationContentSpec { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationContentStatus) DeepCopyInto(out *VolumeGroupReplicationContentStatus) { + *out = *in + if in.PersistentVolumeRefList != nil { + in, out := &in.PersistentVolumeRefList, &out.PersistentVolumeRefList + *out = make([]corev1.LocalObjectReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationContentStatus. +func (in *VolumeGroupReplicationContentStatus) DeepCopy() *VolumeGroupReplicationContentStatus { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationContentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationList) DeepCopyInto(out *VolumeGroupReplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeGroupReplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationList. +func (in *VolumeGroupReplicationList) DeepCopy() *VolumeGroupReplicationList { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeGroupReplicationList) 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 *VolumeGroupReplicationSource) DeepCopyInto(out *VolumeGroupReplicationSource) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationSource. +func (in *VolumeGroupReplicationSource) DeepCopy() *VolumeGroupReplicationSource { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationSpec) DeepCopyInto(out *VolumeGroupReplicationSpec) { + *out = *in + in.Source.DeepCopyInto(&out.Source) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationSpec. +func (in *VolumeGroupReplicationSpec) DeepCopy() *VolumeGroupReplicationSpec { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeGroupReplicationStatus) DeepCopyInto(out *VolumeGroupReplicationStatus) { + *out = *in + in.VolumeReplicationStatus.DeepCopyInto(&out.VolumeReplicationStatus) + if in.PersistentVolumeClaimsRefList != nil { + in, out := &in.PersistentVolumeClaimsRefList, &out.PersistentVolumeClaimsRefList + *out = make([]corev1.LocalObjectReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeGroupReplicationStatus. +func (in *VolumeGroupReplicationStatus) DeepCopy() *VolumeGroupReplicationStatus { + if in == nil { + return nil + } + out := new(VolumeGroupReplicationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplication) DeepCopyInto(out *VolumeReplication) { + *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 VolumeReplication. +func (in *VolumeReplication) DeepCopy() *VolumeReplication { + if in == nil { + return nil + } + out := new(VolumeReplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplication) 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 *VolumeReplicationClass) DeepCopyInto(out *VolumeReplicationClass) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClass. +func (in *VolumeReplicationClass) DeepCopy() *VolumeReplicationClass { + if in == nil { + return nil + } + out := new(VolumeReplicationClass) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplicationClass) 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 *VolumeReplicationClassList) DeepCopyInto(out *VolumeReplicationClassList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeReplicationClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClassList. +func (in *VolumeReplicationClassList) DeepCopy() *VolumeReplicationClassList { + if in == nil { + return nil + } + out := new(VolumeReplicationClassList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplicationClassList) 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 *VolumeReplicationClassSpec) DeepCopyInto(out *VolumeReplicationClassSpec) { + *out = *in + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClassSpec. +func (in *VolumeReplicationClassSpec) DeepCopy() *VolumeReplicationClassSpec { + if in == nil { + return nil + } + out := new(VolumeReplicationClassSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationClassStatus) DeepCopyInto(out *VolumeReplicationClassStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationClassStatus. +func (in *VolumeReplicationClassStatus) DeepCopy() *VolumeReplicationClassStatus { + if in == nil { + return nil + } + out := new(VolumeReplicationClassStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationList) DeepCopyInto(out *VolumeReplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VolumeReplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationList. +func (in *VolumeReplicationList) DeepCopy() *VolumeReplicationList { + if in == nil { + return nil + } + out := new(VolumeReplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VolumeReplicationList) 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 *VolumeReplicationSpec) DeepCopyInto(out *VolumeReplicationSpec) { + *out = *in + in.DataSource.DeepCopyInto(&out.DataSource) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationSpec. +func (in *VolumeReplicationSpec) DeepCopy() *VolumeReplicationSpec { + if in == nil { + return nil + } + out := new(VolumeReplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeReplicationStatus) DeepCopyInto(out *VolumeReplicationStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LastStartTime != nil { + in, out := &in.LastStartTime, &out.LastStartTime + *out = (*in).DeepCopy() + } + if in.LastCompletionTime != nil { + in, out := &in.LastCompletionTime, &out.LastCompletionTime + *out = (*in).DeepCopy() + } + if in.LastSyncTime != nil { + in, out := &in.LastSyncTime, &out.LastSyncTime + *out = (*in).DeepCopy() + } + if in.LastSyncBytes != nil { + in, out := &in.LastSyncBytes, &out.LastSyncBytes + *out = new(int64) + **out = **in + } + if in.LastSyncDuration != nil { + in, out := &in.LastSyncDuration, &out.LastSyncDuration + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeReplicationStatus. +func (in *VolumeReplicationStatus) DeepCopy() *VolumeReplicationStatus { + if in == nil { + return nil + } + out := new(VolumeReplicationStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index c6c34d65d..7972bbc3a 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.34.2 + +Require Go 1.22+ + +### Maintenance +- bump ginkgo as well [c59c6dc] +- bump to go 1.22 - remove x/exp dependency [8158b99] + ## 1.34.1 ### Maintenance diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 2546ccceb..edacf8c13 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.34.1" +const GOMEGA_VERSION = "1.34.2" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go index 4339acc64..44aa61d4b 100644 --- a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go +++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go @@ -1,7 +1,7 @@ package bipartitegraph import ( - "golang.org/x/exp/slices" + "slices" . "github.com/onsi/gomega/matchers/support/goraph/edge" . "github.com/onsi/gomega/matchers/support/goraph/node" diff --git a/vendor/github.com/ramendr/ramen/api/v1alpha1/drpolicy_types.go b/vendor/github.com/ramendr/ramen/api/v1alpha1/drpolicy_types.go index b53a06818..6ecac12ef 100644 --- a/vendor/github.com/ramendr/ramen/api/v1alpha1/drpolicy_types.go +++ b/vendor/github.com/ramendr/ramen/api/v1alpha1/drpolicy_types.go @@ -54,6 +54,53 @@ type DRPolicySpec struct { // DRPolicyStatus defines the observed state of DRPolicy type DRPolicyStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` + + // DRPolicyStatus.Async contains the status of observed + // async replication details between the clusters in the policy + //+optional + Async Async `json:"async,omitempty"` + + // DRPolicyStatus.Sync contains the status of observed + // sync replication details between the clusters in the policy + //+optional + Sync Sync `json:"sync,omitempty"` +} + +// for RDR +type Async struct { + // PeerClasses is a list of common StorageClasses across the clusters in a policy + // that have related async relationships. (one per pair of peers in the policy) + //+optional + PeerClasses []PeerClass `json:"peerClasses,omitempty"` +} + +// for MetroDR +type Sync struct { + // PeerClasses is a list of common StorageClasses across the clusters in a policy + // that have related sync relationships. (one per pair of peers in the policy) + //+optional + PeerClasses []PeerClass `json:"peerClasses,omitempty"` +} + +type PeerClass struct { + // ReplicationID is the common value for the label "ramendr.openshift.io/replicationID" on the corresponding + // VolumeReplicationClass or VolumeGroupReplicationClass on each peer for the matched StorageClassName. + //+optional + ReplicationID string `json:"replicationID,omitempty"` + + // StorageID is the collection of values for the label "ramendr.openshift.io/storageID" on the corresponding + // StorageClassName across the peers. It is singleton if the storage instance is shared across the peers, + // and distict if storage instances are different. + //+optional + StorageID []string `json:"storageID,omitempty"` + + // StorageClassName is the name of a StorageClass that is available across the peers + //+optional + StorageClassName string `json:"storageClassName,omitempty"` + + // ClusterIDs is a list of two clusterIDs that represent this peer relationship for a common StorageClassName + // The IDs are based on the value of the metadata.uid of the kube-system namespace + ClusterIDs []string `json:"clusterIDs,omitempty"` } const ( diff --git a/vendor/github.com/ramendr/ramen/api/v1alpha1/volumereplicationgroup_types.go b/vendor/github.com/ramendr/ramen/api/v1alpha1/volumereplicationgroup_types.go index 964362689..868c2bd20 100644 --- a/vendor/github.com/ramendr/ramen/api/v1alpha1/volumereplicationgroup_types.go +++ b/vendor/github.com/ramendr/ramen/api/v1alpha1/volumereplicationgroup_types.go @@ -62,10 +62,22 @@ type VRGAsyncSpec struct { // +kubebuilder:validation:Required // +kubebuilder:validation:Pattern=`^\d+[mhd]$` SchedulingInterval string `json:"schedulingInterval"` + + // PeerClasses is a list of common StorageClasses across the clusters in a policy that have related + // sync relationships. This is ONLY modified post creation, if the workload that is protected + // creates a PVC using a newer StorageClass that is determined to be common across the peers. + //+optional + PeerClasses []PeerClass `json:"peerClasses,omitempty"` } -// VRGSyncSpec has the parameters associated with MetroDR -type VRGSyncSpec struct{} +// VRGSyncSpec has the parameters associated with VE +type VRGSyncSpec struct { + // PeerClasses is a list of common StorageClasses across the clusters in a policy that have related + // async relationships. This is ONLY modified post creation, if the workload that is protected + // creates a PVC using a newer StorageClass that is determined to be common across the peers. + //+optional + PeerClasses []PeerClass `json:"peerClasses,omitempty"` +} // VolSyncReplicationDestinationSpec defines the configuration for the VolSync // protected PVC to be used by the destination cluster (Secondary) diff --git a/vendor/github.com/ramendr/ramen/api/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/ramendr/ramen/api/v1alpha1/zz_generated.deepcopy.go index 59059ff6e..687a5ccb8 100644 --- a/vendor/github.com/ramendr/ramen/api/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/ramendr/ramen/api/v1alpha1/zz_generated.deepcopy.go @@ -14,6 +14,28 @@ import ( configv1alpha1 "k8s.io/component-base/config/v1alpha1" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Async) DeepCopyInto(out *Async) { + *out = *in + if in.PeerClasses != nil { + in, out := &in.PeerClasses, &out.PeerClasses + *out = make([]PeerClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Async. +func (in *Async) DeepCopy() *Async { + if in == nil { + return nil + } + out := new(Async) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterMaintenanceMode) DeepCopyInto(out *ClusterMaintenanceMode) { *out = *in @@ -506,6 +528,8 @@ func (in *DRPolicyStatus) DeepCopyInto(out *DRPolicyStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + in.Async.DeepCopyInto(&out.Async) + in.Sync.DeepCopyInto(&out.Sync) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DRPolicyStatus. @@ -722,6 +746,31 @@ func (in *MaintenanceModeStatus) DeepCopy() *MaintenanceModeStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PeerClass) DeepCopyInto(out *PeerClass) { + *out = *in + if in.StorageID != nil { + in, out := &in.StorageID, &out.StorageID + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ClusterIDs != nil { + in, out := &in.ClusterIDs, &out.ClusterIDs + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeerClass. +func (in *PeerClass) DeepCopy() *PeerClass { + if in == nil { + return nil + } + out := new(PeerClass) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PlacementDecision) DeepCopyInto(out *PlacementDecision) { *out = *in @@ -1302,12 +1351,41 @@ func (in *StorageIdentifiers) DeepCopy() *StorageIdentifiers { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Sync) DeepCopyInto(out *Sync) { + *out = *in + if in.PeerClasses != nil { + in, out := &in.PeerClasses, &out.PeerClasses + *out = make([]PeerClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sync. +func (in *Sync) DeepCopy() *Sync { + if in == nil { + return nil + } + out := new(Sync) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VRGAsyncSpec) DeepCopyInto(out *VRGAsyncSpec) { *out = *in in.ReplicationClassSelector.DeepCopyInto(&out.ReplicationClassSelector) in.VolumeSnapshotClassSelector.DeepCopyInto(&out.VolumeSnapshotClassSelector) in.VolumeGroupSnapshotClassSelector.DeepCopyInto(&out.VolumeGroupSnapshotClassSelector) + if in.PeerClasses != nil { + in, out := &in.PeerClasses, &out.PeerClasses + *out = make([]PeerClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VRGAsyncSpec. @@ -1366,6 +1444,13 @@ func (in *VRGResourceMeta) DeepCopy() *VRGResourceMeta { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VRGSyncSpec) DeepCopyInto(out *VRGSyncSpec) { *out = *in + if in.PeerClasses != nil { + in, out := &in.PeerClasses, &out.PeerClasses + *out = make([]PeerClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VRGSyncSpec. @@ -1508,7 +1593,7 @@ func (in *VolumeReplicationGroupSpec) DeepCopyInto(out *VolumeReplicationGroupSp if in.Sync != nil { in, out := &in.Sync, &out.Sync *out = new(VRGSyncSpec) - **out = **in + (*in).DeepCopyInto(*out) } in.VolSync.DeepCopyInto(&out.VolSync) if in.KubeObjectProtection != nil { diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go deleted file mode 100644 index 2c033dff4..000000000 --- a/vendor/golang.org/x/exp/constraints/constraints.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package constraints defines a set of useful constraints to be used -// with type parameters. -package constraints - -// Signed is a constraint that permits any signed integer type. -// If future releases of Go add new predeclared signed integer types, -// this constraint will be modified to include them. -type Signed interface { - ~int | ~int8 | ~int16 | ~int32 | ~int64 -} - -// Unsigned is a constraint that permits any unsigned integer type. -// If future releases of Go add new predeclared unsigned integer types, -// this constraint will be modified to include them. -type Unsigned interface { - ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr -} - -// Integer is a constraint that permits any integer type. -// If future releases of Go add new predeclared integer types, -// this constraint will be modified to include them. -type Integer interface { - Signed | Unsigned -} - -// Float is a constraint that permits any floating-point type. -// If future releases of Go add new predeclared floating-point types, -// this constraint will be modified to include them. -type Float interface { - ~float32 | ~float64 -} - -// Complex is a constraint that permits any complex numeric type. -// If future releases of Go add new predeclared complex numeric types, -// this constraint will be modified to include them. -type Complex interface { - ~complex64 | ~complex128 -} - -// Ordered is a constraint that permits any ordered type: any type -// that supports the operators < <= >= >. -// If future releases of Go add new ordered types, -// this constraint will be modified to include them. -type Ordered interface { - Integer | Float | ~string -} diff --git a/vendor/golang.org/x/exp/slices/cmp.go b/vendor/golang.org/x/exp/slices/cmp.go deleted file mode 100644 index fbf1934a0..000000000 --- a/vendor/golang.org/x/exp/slices/cmp.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package slices - -import "golang.org/x/exp/constraints" - -// min is a version of the predeclared function from the Go 1.21 release. -func min[T constraints.Ordered](a, b T) T { - if a < b || isNaN(a) { - return a - } - return b -} - -// max is a version of the predeclared function from the Go 1.21 release. -func max[T constraints.Ordered](a, b T) T { - if a > b || isNaN(a) { - return a - } - return b -} - -// cmpLess is a copy of cmp.Less from the Go 1.21 release. -func cmpLess[T constraints.Ordered](x, y T) bool { - return (isNaN(x) && !isNaN(y)) || x < y -} - -// cmpCompare is a copy of cmp.Compare from the Go 1.21 release. -func cmpCompare[T constraints.Ordered](x, y T) int { - xNaN := isNaN(x) - yNaN := isNaN(y) - if xNaN && yNaN { - return 0 - } - if xNaN || x < y { - return -1 - } - if yNaN || x > y { - return +1 - } - return 0 -} diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go deleted file mode 100644 index 46ceac343..000000000 --- a/vendor/golang.org/x/exp/slices/slices.go +++ /dev/null @@ -1,515 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package slices defines various functions useful with slices of any type. -package slices - -import ( - "unsafe" - - "golang.org/x/exp/constraints" -) - -// Equal reports whether two slices are equal: the same length and all -// elements equal. If the lengths are different, Equal returns false. -// Otherwise, the elements are compared in increasing index order, and the -// comparison stops at the first unequal pair. -// Floating point NaNs are not considered equal. -func Equal[S ~[]E, E comparable](s1, s2 S) bool { - if len(s1) != len(s2) { - return false - } - for i := range s1 { - if s1[i] != s2[i] { - return false - } - } - return true -} - -// EqualFunc reports whether two slices are equal using an equality -// function on each pair of elements. If the lengths are different, -// EqualFunc returns false. Otherwise, the elements are compared in -// increasing index order, and the comparison stops at the first index -// for which eq returns false. -func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool { - if len(s1) != len(s2) { - return false - } - for i, v1 := range s1 { - v2 := s2[i] - if !eq(v1, v2) { - return false - } - } - return true -} - -// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair -// of elements. The elements are compared sequentially, starting at index 0, -// until one element is not equal to the other. -// The result of comparing the first non-matching elements is returned. -// If both slices are equal until one of them ends, the shorter slice is -// considered less than the longer one. -// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2. -func Compare[S ~[]E, E constraints.Ordered](s1, s2 S) int { - for i, v1 := range s1 { - if i >= len(s2) { - return +1 - } - v2 := s2[i] - if c := cmpCompare(v1, v2); c != 0 { - return c - } - } - if len(s1) < len(s2) { - return -1 - } - return 0 -} - -// CompareFunc is like [Compare] but uses a custom comparison function on each -// pair of elements. -// The result is the first non-zero result of cmp; if cmp always -// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2), -// and +1 if len(s1) > len(s2). -func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int { - for i, v1 := range s1 { - if i >= len(s2) { - return +1 - } - v2 := s2[i] - if c := cmp(v1, v2); c != 0 { - return c - } - } - if len(s1) < len(s2) { - return -1 - } - return 0 -} - -// Index returns the index of the first occurrence of v in s, -// or -1 if not present. -func Index[S ~[]E, E comparable](s S, v E) int { - for i := range s { - if v == s[i] { - return i - } - } - return -1 -} - -// IndexFunc returns the first index i satisfying f(s[i]), -// or -1 if none do. -func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { - for i := range s { - if f(s[i]) { - return i - } - } - return -1 -} - -// Contains reports whether v is present in s. -func Contains[S ~[]E, E comparable](s S, v E) bool { - return Index(s, v) >= 0 -} - -// ContainsFunc reports whether at least one -// element e of s satisfies f(e). -func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool { - return IndexFunc(s, f) >= 0 -} - -// Insert inserts the values v... into s at index i, -// returning the modified slice. -// The elements at s[i:] are shifted up to make room. -// In the returned slice r, r[i] == v[0], -// and r[i+len(v)] == value originally at r[i]. -// Insert panics if i is out of range. -// This function is O(len(s) + len(v)). -func Insert[S ~[]E, E any](s S, i int, v ...E) S { - m := len(v) - if m == 0 { - return s - } - n := len(s) - if i == n { - return append(s, v...) - } - if n+m > cap(s) { - // Use append rather than make so that we bump the size of - // the slice up to the next storage class. - // This is what Grow does but we don't call Grow because - // that might copy the values twice. - s2 := append(s[:i], make(S, n+m-i)...) - copy(s2[i:], v) - copy(s2[i+m:], s[i:]) - return s2 - } - s = s[:n+m] - - // before: - // s: aaaaaaaabbbbccccccccdddd - // ^ ^ ^ ^ - // i i+m n n+m - // after: - // s: aaaaaaaavvvvbbbbcccccccc - // ^ ^ ^ ^ - // i i+m n n+m - // - // a are the values that don't move in s. - // v are the values copied in from v. - // b and c are the values from s that are shifted up in index. - // d are the values that get overwritten, never to be seen again. - - if !overlaps(v, s[i+m:]) { - // Easy case - v does not overlap either the c or d regions. - // (It might be in some of a or b, or elsewhere entirely.) - // The data we copy up doesn't write to v at all, so just do it. - - copy(s[i+m:], s[i:]) - - // Now we have - // s: aaaaaaaabbbbbbbbcccccccc - // ^ ^ ^ ^ - // i i+m n n+m - // Note the b values are duplicated. - - copy(s[i:], v) - - // Now we have - // s: aaaaaaaavvvvbbbbcccccccc - // ^ ^ ^ ^ - // i i+m n n+m - // That's the result we want. - return s - } - - // The hard case - v overlaps c or d. We can't just shift up - // the data because we'd move or clobber the values we're trying - // to insert. - // So instead, write v on top of d, then rotate. - copy(s[n:], v) - - // Now we have - // s: aaaaaaaabbbbccccccccvvvv - // ^ ^ ^ ^ - // i i+m n n+m - - rotateRight(s[i:], m) - - // Now we have - // s: aaaaaaaavvvvbbbbcccccccc - // ^ ^ ^ ^ - // i i+m n n+m - // That's the result we want. - return s -} - -// clearSlice sets all elements up to the length of s to the zero value of E. -// We may use the builtin clear func instead, and remove clearSlice, when upgrading -// to Go 1.21+. -func clearSlice[S ~[]E, E any](s S) { - var zero E - for i := range s { - s[i] = zero - } -} - -// Delete removes the elements s[i:j] from s, returning the modified slice. -// Delete panics if j > len(s) or s[i:j] is not a valid slice of s. -// Delete is O(len(s)-i), so if many items must be deleted, it is better to -// make a single call deleting them all together than to delete one at a time. -// Delete zeroes the elements s[len(s)-(j-i):len(s)]. -func Delete[S ~[]E, E any](s S, i, j int) S { - _ = s[i:j:len(s)] // bounds check - - if i == j { - return s - } - - oldlen := len(s) - s = append(s[:i], s[j:]...) - clearSlice(s[len(s):oldlen]) // zero/nil out the obsolete elements, for GC - return s -} - -// DeleteFunc removes any elements from s for which del returns true, -// returning the modified slice. -// DeleteFunc zeroes the elements between the new length and the original length. -func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S { - i := IndexFunc(s, del) - if i == -1 { - return s - } - // Don't start copying elements until we find one to delete. - for j := i + 1; j < len(s); j++ { - if v := s[j]; !del(v) { - s[i] = v - i++ - } - } - clearSlice(s[i:]) // zero/nil out the obsolete elements, for GC - return s[:i] -} - -// Replace replaces the elements s[i:j] by the given v, and returns the -// modified slice. Replace panics if s[i:j] is not a valid slice of s. -// When len(v) < (j-i), Replace zeroes the elements between the new length and the original length. -func Replace[S ~[]E, E any](s S, i, j int, v ...E) S { - _ = s[i:j] // verify that i:j is a valid subslice - - if i == j { - return Insert(s, i, v...) - } - if j == len(s) { - return append(s[:i], v...) - } - - tot := len(s[:i]) + len(v) + len(s[j:]) - if tot > cap(s) { - // Too big to fit, allocate and copy over. - s2 := append(s[:i], make(S, tot-i)...) // See Insert - copy(s2[i:], v) - copy(s2[i+len(v):], s[j:]) - return s2 - } - - r := s[:tot] - - if i+len(v) <= j { - // Easy, as v fits in the deleted portion. - copy(r[i:], v) - if i+len(v) != j { - copy(r[i+len(v):], s[j:]) - } - clearSlice(s[tot:]) // zero/nil out the obsolete elements, for GC - return r - } - - // We are expanding (v is bigger than j-i). - // The situation is something like this: - // (example has i=4,j=8,len(s)=16,len(v)=6) - // s: aaaaxxxxbbbbbbbbyy - // ^ ^ ^ ^ - // i j len(s) tot - // a: prefix of s - // x: deleted range - // b: more of s - // y: area to expand into - - if !overlaps(r[i+len(v):], v) { - // Easy, as v is not clobbered by the first copy. - copy(r[i+len(v):], s[j:]) - copy(r[i:], v) - return r - } - - // This is a situation where we don't have a single place to which - // we can copy v. Parts of it need to go to two different places. - // We want to copy the prefix of v into y and the suffix into x, then - // rotate |y| spots to the right. - // - // v[2:] v[:2] - // | | - // s: aaaavvvvbbbbbbbbvv - // ^ ^ ^ ^ - // i j len(s) tot - // - // If either of those two destinations don't alias v, then we're good. - y := len(v) - (j - i) // length of y portion - - if !overlaps(r[i:j], v) { - copy(r[i:j], v[y:]) - copy(r[len(s):], v[:y]) - rotateRight(r[i:], y) - return r - } - if !overlaps(r[len(s):], v) { - copy(r[len(s):], v[:y]) - copy(r[i:j], v[y:]) - rotateRight(r[i:], y) - return r - } - - // Now we know that v overlaps both x and y. - // That means that the entirety of b is *inside* v. - // So we don't need to preserve b at all; instead we - // can copy v first, then copy the b part of v out of - // v to the right destination. - k := startIdx(v, s[j:]) - copy(r[i:], v) - copy(r[i+len(v):], r[i+k:]) - return r -} - -// Clone returns a copy of the slice. -// The elements are copied using assignment, so this is a shallow clone. -func Clone[S ~[]E, E any](s S) S { - // Preserve nil in case it matters. - if s == nil { - return nil - } - return append(S([]E{}), s...) -} - -// Compact replaces consecutive runs of equal elements with a single copy. -// This is like the uniq command found on Unix. -// Compact modifies the contents of the slice s and returns the modified slice, -// which may have a smaller length. -// Compact zeroes the elements between the new length and the original length. -func Compact[S ~[]E, E comparable](s S) S { - if len(s) < 2 { - return s - } - i := 1 - for k := 1; k < len(s); k++ { - if s[k] != s[k-1] { - if i != k { - s[i] = s[k] - } - i++ - } - } - clearSlice(s[i:]) // zero/nil out the obsolete elements, for GC - return s[:i] -} - -// CompactFunc is like [Compact] but uses an equality function to compare elements. -// For runs of elements that compare equal, CompactFunc keeps the first one. -// CompactFunc zeroes the elements between the new length and the original length. -func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { - if len(s) < 2 { - return s - } - i := 1 - for k := 1; k < len(s); k++ { - if !eq(s[k], s[k-1]) { - if i != k { - s[i] = s[k] - } - i++ - } - } - clearSlice(s[i:]) // zero/nil out the obsolete elements, for GC - return s[:i] -} - -// Grow increases the slice's capacity, if necessary, to guarantee space for -// another n elements. After Grow(n), at least n elements can be appended -// to the slice without another allocation. If n is negative or too large to -// allocate the memory, Grow panics. -func Grow[S ~[]E, E any](s S, n int) S { - if n < 0 { - panic("cannot be negative") - } - if n -= cap(s) - len(s); n > 0 { - // TODO(https://go.dev/issue/53888): Make using []E instead of S - // to workaround a compiler bug where the runtime.growslice optimization - // does not take effect. Revert when the compiler is fixed. - s = append([]E(s)[:cap(s)], make([]E, n)...)[:len(s)] - } - return s -} - -// Clip removes unused capacity from the slice, returning s[:len(s):len(s)]. -func Clip[S ~[]E, E any](s S) S { - return s[:len(s):len(s)] -} - -// Rotation algorithm explanation: -// -// rotate left by 2 -// start with -// 0123456789 -// split up like this -// 01 234567 89 -// swap first 2 and last 2 -// 89 234567 01 -// join first parts -// 89234567 01 -// recursively rotate first left part by 2 -// 23456789 01 -// join at the end -// 2345678901 -// -// rotate left by 8 -// start with -// 0123456789 -// split up like this -// 01 234567 89 -// swap first 2 and last 2 -// 89 234567 01 -// join last parts -// 89 23456701 -// recursively rotate second part left by 6 -// 89 01234567 -// join at the end -// 8901234567 - -// TODO: There are other rotate algorithms. -// This algorithm has the desirable property that it moves each element exactly twice. -// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes. -// The follow-cycles algorithm can be 1-write but it is not very cache friendly. - -// rotateLeft rotates b left by n spaces. -// s_final[i] = s_orig[i+r], wrapping around. -func rotateLeft[E any](s []E, r int) { - for r != 0 && r != len(s) { - if r*2 <= len(s) { - swap(s[:r], s[len(s)-r:]) - s = s[:len(s)-r] - } else { - swap(s[:len(s)-r], s[r:]) - s, r = s[len(s)-r:], r*2-len(s) - } - } -} -func rotateRight[E any](s []E, r int) { - rotateLeft(s, len(s)-r) -} - -// swap swaps the contents of x and y. x and y must be equal length and disjoint. -func swap[E any](x, y []E) { - for i := 0; i < len(x); i++ { - x[i], y[i] = y[i], x[i] - } -} - -// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap. -func overlaps[E any](a, b []E) bool { - if len(a) == 0 || len(b) == 0 { - return false - } - elemSize := unsafe.Sizeof(a[0]) - if elemSize == 0 { - return false - } - // TODO: use a runtime/unsafe facility once one becomes available. See issue 12445. - // Also see crypto/internal/alias/alias.go:AnyOverlap - return uintptr(unsafe.Pointer(&a[0])) <= uintptr(unsafe.Pointer(&b[len(b)-1]))+(elemSize-1) && - uintptr(unsafe.Pointer(&b[0])) <= uintptr(unsafe.Pointer(&a[len(a)-1]))+(elemSize-1) -} - -// startIdx returns the index in haystack where the needle starts. -// prerequisite: the needle must be aliased entirely inside the haystack. -func startIdx[E any](haystack, needle []E) int { - p := &needle[0] - for i := range haystack { - if p == &haystack[i] { - return i - } - } - // TODO: what if the overlap is by a non-integral number of Es? - panic("needle not found") -} - -// Reverse reverses the elements of the slice in place. -func Reverse[S ~[]E, E any](s S) { - for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { - s[i], s[j] = s[j], s[i] - } -} diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go deleted file mode 100644 index f58bbc7ba..000000000 --- a/vendor/golang.org/x/exp/slices/sort.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run $GOROOT/src/sort/gen_sort_variants.go -exp - -package slices - -import ( - "math/bits" - - "golang.org/x/exp/constraints" -) - -// Sort sorts a slice of any ordered type in ascending order. -// When sorting floating-point numbers, NaNs are ordered before other values. -func Sort[S ~[]E, E constraints.Ordered](x S) { - n := len(x) - pdqsortOrdered(x, 0, n, bits.Len(uint(n))) -} - -// SortFunc sorts the slice x in ascending order as determined by the cmp -// function. This sort is not guaranteed to be stable. -// cmp(a, b) should return a negative number when a < b, a positive number when -// a > b and zero when a == b or when a is not comparable to b in the sense -// of the formal definition of Strict Weak Ordering. -// -// SortFunc requires that cmp is a strict weak ordering. -// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings. -// To indicate 'uncomparable', return 0 from the function. -func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) { - n := len(x) - pdqsortCmpFunc(x, 0, n, bits.Len(uint(n)), cmp) -} - -// SortStableFunc sorts the slice x while keeping the original order of equal -// elements, using cmp to compare elements in the same way as [SortFunc]. -func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) { - stableCmpFunc(x, len(x), cmp) -} - -// IsSorted reports whether x is sorted in ascending order. -func IsSorted[S ~[]E, E constraints.Ordered](x S) bool { - for i := len(x) - 1; i > 0; i-- { - if cmpLess(x[i], x[i-1]) { - return false - } - } - return true -} - -// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the -// comparison function as defined by [SortFunc]. -func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool { - for i := len(x) - 1; i > 0; i-- { - if cmp(x[i], x[i-1]) < 0 { - return false - } - } - return true -} - -// Min returns the minimal value in x. It panics if x is empty. -// For floating-point numbers, Min propagates NaNs (any NaN value in x -// forces the output to be NaN). -func Min[S ~[]E, E constraints.Ordered](x S) E { - if len(x) < 1 { - panic("slices.Min: empty list") - } - m := x[0] - for i := 1; i < len(x); i++ { - m = min(m, x[i]) - } - return m -} - -// MinFunc returns the minimal value in x, using cmp to compare elements. -// It panics if x is empty. If there is more than one minimal element -// according to the cmp function, MinFunc returns the first one. -func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E { - if len(x) < 1 { - panic("slices.MinFunc: empty list") - } - m := x[0] - for i := 1; i < len(x); i++ { - if cmp(x[i], m) < 0 { - m = x[i] - } - } - return m -} - -// Max returns the maximal value in x. It panics if x is empty. -// For floating-point E, Max propagates NaNs (any NaN value in x -// forces the output to be NaN). -func Max[S ~[]E, E constraints.Ordered](x S) E { - if len(x) < 1 { - panic("slices.Max: empty list") - } - m := x[0] - for i := 1; i < len(x); i++ { - m = max(m, x[i]) - } - return m -} - -// MaxFunc returns the maximal value in x, using cmp to compare elements. -// It panics if x is empty. If there is more than one maximal element -// according to the cmp function, MaxFunc returns the first one. -func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E { - if len(x) < 1 { - panic("slices.MaxFunc: empty list") - } - m := x[0] - for i := 1; i < len(x); i++ { - if cmp(x[i], m) > 0 { - m = x[i] - } - } - return m -} - -// BinarySearch searches for target in a sorted slice and returns the position -// where target is found, or the position where target would appear in the -// sort order; it also returns a bool saying whether the target is really found -// in the slice. The slice must be sorted in increasing order. -func BinarySearch[S ~[]E, E constraints.Ordered](x S, target E) (int, bool) { - // Inlining is faster than calling BinarySearchFunc with a lambda. - n := len(x) - // Define x[-1] < target and x[n] >= target. - // Invariant: x[i-1] < target, x[j] >= target. - i, j := 0, n - for i < j { - h := int(uint(i+j) >> 1) // avoid overflow when computing h - // i ≤ h < j - if cmpLess(x[h], target) { - i = h + 1 // preserves x[i-1] < target - } else { - j = h // preserves x[j] >= target - } - } - // i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i. - return i, i < n && (x[i] == target || (isNaN(x[i]) && isNaN(target))) -} - -// BinarySearchFunc works like [BinarySearch], but uses a custom comparison -// function. The slice must be sorted in increasing order, where "increasing" -// is defined by cmp. cmp should return 0 if the slice element matches -// the target, a negative number if the slice element precedes the target, -// or a positive number if the slice element follows the target. -// cmp must implement the same ordering as the slice, such that if -// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice. -func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) { - n := len(x) - // Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 . - // Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0. - i, j := 0, n - for i < j { - h := int(uint(i+j) >> 1) // avoid overflow when computing h - // i ≤ h < j - if cmp(x[h], target) < 0 { - i = h + 1 // preserves cmp(x[i - 1], target) < 0 - } else { - j = h // preserves cmp(x[j], target) >= 0 - } - } - // i == j, cmp(x[i-1], target) < 0, and cmp(x[j], target) (= cmp(x[i], target)) >= 0 => answer is i. - return i, i < n && cmp(x[i], target) == 0 -} - -type sortedHint int // hint for pdqsort when choosing the pivot - -const ( - unknownHint sortedHint = iota - increasingHint - decreasingHint -) - -// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf -type xorshift uint64 - -func (r *xorshift) Next() uint64 { - *r ^= *r << 13 - *r ^= *r >> 17 - *r ^= *r << 5 - return uint64(*r) -} - -func nextPowerOfTwo(length int) uint { - return 1 << bits.Len(uint(length)) -} - -// isNaN reports whether x is a NaN without requiring the math package. -// This will always return false if T is not floating-point. -func isNaN[T constraints.Ordered](x T) bool { - return x != x -} diff --git a/vendor/golang.org/x/exp/slices/zsortanyfunc.go b/vendor/golang.org/x/exp/slices/zsortanyfunc.go deleted file mode 100644 index 06f2c7a24..000000000 --- a/vendor/golang.org/x/exp/slices/zsortanyfunc.go +++ /dev/null @@ -1,479 +0,0 @@ -// Code generated by gen_sort_variants.go; DO NOT EDIT. - -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package slices - -// insertionSortCmpFunc sorts data[a:b] using insertion sort. -func insertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) { - for i := a + 1; i < b; i++ { - for j := i; j > a && (cmp(data[j], data[j-1]) < 0); j-- { - data[j], data[j-1] = data[j-1], data[j] - } - } -} - -// siftDownCmpFunc implements the heap property on data[lo:hi]. -// first is an offset into the array where the root of the heap lies. -func siftDownCmpFunc[E any](data []E, lo, hi, first int, cmp func(a, b E) int) { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && (cmp(data[first+child], data[first+child+1]) < 0) { - child++ - } - if !(cmp(data[first+root], data[first+child]) < 0) { - return - } - data[first+root], data[first+child] = data[first+child], data[first+root] - root = child - } -} - -func heapSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) { - first := a - lo := 0 - hi := b - a - - // Build heap with greatest element at top. - for i := (hi - 1) / 2; i >= 0; i-- { - siftDownCmpFunc(data, i, hi, first, cmp) - } - - // Pop elements, largest first, into end of data. - for i := hi - 1; i >= 0; i-- { - data[first], data[first+i] = data[first+i], data[first] - siftDownCmpFunc(data, lo, i, first, cmp) - } -} - -// pdqsortCmpFunc sorts data[a:b]. -// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. -// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf -// C++ implementation: https://github.com/orlp/pdqsort -// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ -// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. -func pdqsortCmpFunc[E any](data []E, a, b, limit int, cmp func(a, b E) int) { - const maxInsertion = 12 - - var ( - wasBalanced = true // whether the last partitioning was reasonably balanced - wasPartitioned = true // whether the slice was already partitioned - ) - - for { - length := b - a - - if length <= maxInsertion { - insertionSortCmpFunc(data, a, b, cmp) - return - } - - // Fall back to heapsort if too many bad choices were made. - if limit == 0 { - heapSortCmpFunc(data, a, b, cmp) - return - } - - // If the last partitioning was imbalanced, we need to breaking patterns. - if !wasBalanced { - breakPatternsCmpFunc(data, a, b, cmp) - limit-- - } - - pivot, hint := choosePivotCmpFunc(data, a, b, cmp) - if hint == decreasingHint { - reverseRangeCmpFunc(data, a, b, cmp) - // The chosen pivot was pivot-a elements after the start of the array. - // After reversing it is pivot-a elements before the end of the array. - // The idea came from Rust's implementation. - pivot = (b - 1) - (pivot - a) - hint = increasingHint - } - - // The slice is likely already sorted. - if wasBalanced && wasPartitioned && hint == increasingHint { - if partialInsertionSortCmpFunc(data, a, b, cmp) { - return - } - } - - // Probably the slice contains many duplicate elements, partition the slice into - // elements equal to and elements greater than the pivot. - if a > 0 && !(cmp(data[a-1], data[pivot]) < 0) { - mid := partitionEqualCmpFunc(data, a, b, pivot, cmp) - a = mid - continue - } - - mid, alreadyPartitioned := partitionCmpFunc(data, a, b, pivot, cmp) - wasPartitioned = alreadyPartitioned - - leftLen, rightLen := mid-a, b-mid - balanceThreshold := length / 8 - if leftLen < rightLen { - wasBalanced = leftLen >= balanceThreshold - pdqsortCmpFunc(data, a, mid, limit, cmp) - a = mid + 1 - } else { - wasBalanced = rightLen >= balanceThreshold - pdqsortCmpFunc(data, mid+1, b, limit, cmp) - b = mid - } - } -} - -// partitionCmpFunc does one quicksort partition. -// Let p = data[pivot] -// Moves elements in data[a:b] around, so that data[i]
=p for i =p for i