diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ed89f1cd0..923b087e8 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ contact_links: - name: Question - url: https://github.com/topolvm/topolvm/discussions + url: https://github.com/syself/csi-topolvm/discussions about: Support request or question diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 98e19b250..2fb6c6051 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -9,7 +9,7 @@ assignees: '' **What should the feature do:** diff --git a/.github/ISSUE_TEMPLATE/update_supporting_kubernetes.md b/.github/ISSUE_TEMPLATE/update_supporting_kubernetes.md index e2e38fd08..952a52a58 100644 --- a/.github/ISSUE_TEMPLATE/update_supporting_kubernetes.md +++ b/.github/ISSUE_TEMPLATE/update_supporting_kubernetes.md @@ -9,7 +9,7 @@ assignees: '' ## Update Procedure -- Read [this document](https://github.com/topolvm/topolvm/blob/main/docs/maintenance.md). +- Read [this document](https://github.com/syself/csi-topolvm/blob/main/docs/maintenance.md). ## Before Check List @@ -20,44 +20,44 @@ There is a check list to confirm depending libraries or tools are released. The Must update Kubernetes with each new version of Kubernetes. - [ ] k8s.io/api - - https://github.com/kubernetes/api/tags + - - The supported Kubernetes version is written in the description of each tag. - [ ] k8s.io/apimachinery - - https://github.com/kubernetes/apimachinery/tags + - - The supported Kubernetes version is written in the description of each tag. - [ ] k8s.io/client-go - - https://github.com/kubernetes/client-go/tags + - - The supported Kubernetes version is written in the description of each tag. - [ ] k8s.io/mount-utils - - https://github.com/kubernetes/mount-utils/tags + - - The supported Kubernetes version is written in the description of each tag. - [ ] sigs.k8s.io/controller-runtime - - https://github.com/kubernetes-sigs/controller-runtime/releases + - - [ ] sigs.k8s.io/controller-tools - - https://github.com/kubernetes-sigs/controller-tools/releases + - - [ ] external provisioner - - https://github.com/kubernetes-csi/external-provisioner/tree/master/CHANGELOG + - - [ ] external resizer - - https://github.com/kubernetes-csi/external-resizer/tree/master/CHANGELOG + - - [ ] external snapshotter - - https://github.com/kubernetes-csi/external-snapshotter/tree/master/CHANGELOG + - - [ ] kind - - https://github.com/kubernetes-sigs/kind/releases + - - [ ] minikube - - https://github.com/kubernetes/minikube/releases + - - [ ] crictl - - https://github.com/kubernetes-sigs/cri-tools/releases + - ### Semi-required Dependencies These are not released on the occasion of a Kubernetes version upgrade, so if there is a release that corresponds to a Kubernetes version, use it. - [ ] node driver registrar - - https://github.com/kubernetes-csi/node-driver-registrar/tree/master/CHANGELOG + - - [ ] liveness probe - - https://github.com/kubernetes-csi/livenessprobe/tree/master/CHANGELOG + - - [ ] cri-docker - - https://github.com/Mirantis/cri-dockerd/releases + - ### Release notes check diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6cf679127..71d44497e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,9 +15,9 @@ Welcome! We are glad that you want to contribute to our project! As you get started, you are in the best position to give us feedback on areas of our project that we need help with including: -* Problems found during setting up a new developer environment -* Gaps in our Quickstart Guide or documentation -* Bugs in our automation scripts +- Problems found during setting up a new developer environment +- Gaps in our Quickstart Guide or documentation +- Bugs in our automation scripts If anything doesn't make sense, or doesn't work when you run it, please open a bug report and let us know! @@ -26,16 +26,16 @@ bug report and let us know! We welcome many different types of contributions including: -* New features -* Builds, CI/CD -* Bug fixes -* Documentation -* Issue Triage -* Answering questions on GitHub Discussions -* Communications / Social Media / Blog Posts -* Release management +- New features +- Builds, CI/CD +- Bug fixes +- Documentation +- Issue Triage +- Answering questions on GitHub Discussions +- Communications / Social Media / Blog Posts +- Release management -Not everything happens through a GitHub pull request. Please [contact us](https://github.com/topolvm/topolvm/discussions) +Not everything happens through a GitHub pull request. Please [contact us](https://github.com/syself/csi-topolvm/discussions) and let's discuss how we can work together. ## Find an Issue @@ -49,7 +49,7 @@ your first pull request. Sometimes there won’t be any issues with these labels. That’s ok! There is likely still something for you to work on. If you want to contribute but you don’t know where to start or can't find a suitable issue, you can ask for an -issue to work on the [Discussions](https://github.com/topolvm/topolvm/discussions). +issue to work on the [Discussions](https://github.com/syself/csi-topolvm/discussions). Once you see an issue that you'd like to work on, please post a comment saying that you want to work on it. Something like "I want to work on this" is fine. @@ -58,7 +58,7 @@ that you want to work on it. Something like "I want to work on this" is fine. The best way to reach us with a question when contributing is to ask on: -* The original github issue +- The original github issue ## Pull Request Lifecycle @@ -109,6 +109,7 @@ we suggest preparing a dedicated physical or virtual machine. ## Sign Your Commits ### DCO + Licensing is important to open source projects. It provides some assurances that the software will continue to be available based under the terms that the author(s) desired. We require that contributors sign off on commits submitted to @@ -128,7 +129,7 @@ Git has a `-s` command line option to do this automatically: git commit -s -m 'This is my commit message' If you forgot to do this and have not yet pushed your changes to the remote -repository, you can amend your commit with the sign-off by running +repository, you can amend your commit with the sign-off by running git commit --amend -s diff --git a/Dockerfile b/Dockerfile index fe820a425..42b00006d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build topolvm -FROM --platform=$BUILDPLATFORM golang:1.20-bullseye AS build-topolvm +FROM --platform=$BUILDPLATFORM golang:1.22-bullseye AS build-topolvm # Get argument ARG TOPOLVM_VERSION diff --git a/Makefile b/Makefile index df75ea072..7c92371ba 100644 --- a/Makefile +++ b/Makefile @@ -73,10 +73,10 @@ help: ## Display this help. ##@ Development pkg/lvmd/proto/lvmd.pb.go: pkg/lvmd/proto/lvmd.proto - $(PROTOC) --go_out=module=github.com/topolvm/topolvm:. $< + $(PROTOC) --go_out=module=github.com/syself/csi-topolvm:. $< pkg/lvmd/proto/lvmd_grpc.pb.go: pkg/lvmd/proto/lvmd.proto - $(PROTOC) --go-grpc_out=module=github.com/topolvm/topolvm:. $< + $(PROTOC) --go-grpc_out=module=github.com/syself/csi-topolvm:. $< docs/lvmd-protocol.md: pkg/lvmd/proto/lvmd.proto $(PROTOC) --doc_out=./docs --doc_opt=markdown,$@ $< @@ -95,7 +95,7 @@ manifests: generate-legacy-api ## Generate WebhookConfiguration, ClusterRole and cat config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml | xargs -d" " printf "$$LEGACY_CRD_TEMPLATE" > charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml .PHONY: generate-api ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. -generate-api: +generate-api: $(CONTROLLER_GEN) object:headerFile="./hack/boilerplate.go.txt" paths="./api/..." .PHONY: generate-legacy-api @@ -133,6 +133,7 @@ test: lint ## Run lint and unit tests. mkdir -p $(ENVTEST_ASSETS_DIR) source <($(BINDIR)/setup-envtest use $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p env); GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn go test -count=1 -race -v --timeout=120s ./... + ## hack source <($(BINDIR)/setup-envtest use $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p env); GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn go test -count=1 -race -v --timeout=120s ./internal/controller groupname-test: ## Run unit tests that depends on the groupname. go install ./... @@ -160,11 +161,11 @@ build-topolvm: build/hypertopolvm build/lvmd build/hypertopolvm: $(GO_FILES) mkdir -p build - GOARCH=$(GOARCH) go build -o $@ -ldflags "-w -s -X github.com/topolvm/topolvm.Version=$(TOPOLVM_VERSION)" ./cmd/hypertopolvm + GOARCH=$(GOARCH) go build -o $@ -ldflags "-w -s -X github.com/syself/csi-topolvm.Version=$(TOPOLVM_VERSION)" ./cmd/hypertopolvm build/lvmd: $(GO_FILES) mkdir -p build - GOARCH=$(GOARCH) CGO_ENABLED=0 go build -o $@ -ldflags "-w -s -X github.com/topolvm/topolvm.Version=$(TOPOLVM_VERSION)" ./cmd/lvmd + GOARCH=$(GOARCH) CGO_ENABLED=0 go build -o $@ -ldflags "-w -s -X github.com/syself/csi-topolvm.Version=$(TOPOLVM_VERSION)" ./cmd/lvmd .PHONY: csi-sidecars csi-sidecars: ## Build sidecar binaries. @@ -203,8 +204,12 @@ multi-platform-images: multi-platform-image-normal multi-platform-image-with-sid .PHONY: multi-platform-image-normal multi-platform-image-normal: mkdir -p build + # removed that: + # --platform linux/amd64,linux/arm64/v8,linux/ppc64le \ + # otherwise: + # ERROR: Multi-platform build is not supported for the docker driver. + # Switch to a different driver, or turn on the containerd image store, and try again. docker buildx build --no-cache $(BUILDX_PUSH_OPTIONS) \ - --platform linux/amd64,linux/arm64/v8,linux/ppc64le \ -t $(IMAGE_PREFIX)topolvm:$(IMAGE_TAG) \ --build-arg TOPOLVM_VERSION=$(TOPOLVM_VERSION) \ --target topolvm \ @@ -214,7 +219,6 @@ multi-platform-image-normal: multi-platform-image-with-sidecar: mkdir -p build docker buildx build --no-cache $(BUILDX_PUSH_OPTIONS) \ - --platform linux/amd64,linux/arm64/v8,linux/ppc64le \ -t $(IMAGE_PREFIX)topolvm-with-sidecar:$(IMAGE_TAG) \ --build-arg TOPOLVM_VERSION=$(TOPOLVM_VERSION) \ --target topolvm-with-sidecar \ diff --git a/PROJECT b/PROJECT index 875325619..5e772440d 100644 --- a/PROJECT +++ b/PROJECT @@ -6,7 +6,7 @@ domain: io layout: - go.kubebuilder.io/v4 projectName: topolvm -repo: github.com/topolvm/topolvm +repo: github.com/syself/csi-topolvm resources: - api: crdVersion: v1 @@ -14,7 +14,7 @@ resources: domain: io group: topolvm kind: LogicalVolume - path: github.com/topolvm/topolvm/api/v1 + path: github.com/syself/csi-topolvm/api/v1 version: v1 - controller: true group: core diff --git a/README.md b/README.md index 00c9008db..e1f08de4a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ![TopoLVM logo](./docs/img/TopoLVM_logo.svg) [![GitHub release](https://img.shields.io/github/v/release/topolvm/topolvm.svg?maxAge=60)][releases] -[![Main](https://github.com/topolvm/topolvm/workflows/Main/badge.svg)](https://github.com/topolvm/topolvm/actions) -[![PkgGoDev](https://pkg.go.dev/badge/github.com/topolvm/topolvm?tab=overview)](https://pkg.go.dev/github.com/topolvm/topolvm?tab=overview) -[![Go Report Card](https://goreportcard.com/badge/github.com/topolvm/topolvm)](https://goreportcard.com/badge/github.com/topolvm/topolvm) +[![Main](https://github.com/syself/csi-topolvm/workflows/Main/badge.svg)](https://github.com/syself/csi-topolvm/actions) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/syself/csi-topolvm?tab=overview)](https://pkg.go.dev/github.com/syself/csi-topolvm?tab=overview) +[![Go Report Card](https://goreportcard.com/badge/github.com/syself/csi-topolvm)](https://goreportcard.com/badge/github.com/syself/csi-topolvm) # TopoLVM @@ -20,11 +20,11 @@ Our supported platform are: - Filesystems: ext4, xfs, btrfs(experimental) - lvm version 2.02.163 or later (adds JSON output support) -\*1 The host's Linux Kernel must be v4.9 or later which supports `rmapbt` and `reflink`, if you use xfs filesystem with an official docker image. -\*2 Tier1 support. The official docker images are provided and all functionalities are tested by CI. -\*3 Tier2 support. The official docker images are provided, but no tests run by CI. +\*1 The host's Linux Kernel must be v4.9 or later which supports `rmapbt` and `reflink`, if you use xfs filesystem with an official docker image. +\*2 Tier1 support. The official docker images are provided and all functionalities are tested by CI. +\*3 Tier2 support. The official docker images are provided, but no tests run by CI. -Docker images are available on [ghcr.io](https://github.com/orgs/topolvm/packages). +Docker images are available on [ghcr.io](https://github.com/orgs/topolvm/packages). ## Getting Started @@ -49,7 +49,7 @@ started contributing, please see our [Contributing Guide](CONTRIBUTING.md). - Extended scheduler: TopoLVM extends the general Pod scheduler to prioritize Nodes having larger storage capacity. - Volume metrics: Usage stats are exported as Prometheus metrics from `kubelet`. - [Volume Expansion](https://kubernetes-csi.github.io/docs/volume-expansion.html): Volumes can be expanded by editing `PersistentVolumeClaim` objects. -- [Storage capacity tracking](https://github.com/topolvm/topolvm/tree/main/deploy#storage-capacity-tracking): You can enable Storage Capacity Tracking mode instead of using topolvm-scheduler. +- [Storage capacity tracking](https://github.com/syself/csi-topolvm/tree/main/deploy#storage-capacity-tracking): You can enable Storage Capacity Tracking mode instead of using topolvm-scheduler. - [Snapshot](https://kubernetes-csi.github.io/docs/snapshot-restore-feature.html): Snapshots can be taken when using thin provisioning. ### Planned Features @@ -58,7 +58,7 @@ started contributing, please see our [Contributing Guide](CONTRIBUTING.md). ## Communications -If you have any questions or ideas, please use [discussions](https://github.com/topolvm/topolvm/discussions). +If you have any questions or ideas, please use [discussions](https://github.com/syself/csi-topolvm/discussions). ## Resources @@ -66,12 +66,12 @@ If you have any questions or ideas, please use [discussions](https://github.com/ A diagram of components is available in [docs/design.md](docs/design.md#diagram). -TopoLVM maintainers presented the motivation and implementation of TopoLVM at KubeCon Europe 2020: https://kccnceu20.sched.com/event/ZerD +TopoLVM maintainers presented the motivation and implementation of TopoLVM at KubeCon Europe 2020: ## License This project is licensed under [Apache License 2.0](LICENSE). -[releases]: https://github.com/topolvm/topolvm/releases +[releases]: https://github.com/syself/csi-topolvm/releases [CSI]: https://github.com/container-storage-interface/spec [kind]: https://github.com/kubernetes-sigs/kind diff --git a/RELEASE.md b/RELEASE.md index 47c9f24ff..ad9931bcf 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -39,7 +39,7 @@ The result should look something like: Bump version ------------ -1. Determine a new version number by [checking the differences](https://github.com/topolvm/topolvm/compare/vX.Y.Z...main) since the last release. Then, define the `VERSION` variable. +1. Determine a new version number by [checking the differences](https://github.com/syself/csi-topolvm/compare/vX.Y.Z...main) since the last release. Then, define the `VERSION` variable. ```console VERSION=1.2.3 @@ -58,9 +58,9 @@ Bump version creates a draft release note for the tagged version, builds a tar archive for the new release, and attaches it to the release note. - - Visit https://github.com/topolvm/topolvm/releases to check - the result. + + Visit to check + the result. 4. Edit the auto-generated release note and remove PRs which contain changes only to the helm chart. @@ -72,15 +72,15 @@ Bump Chart Version TopoLVM Helm Chart will be released independently. This will prevent the TopoLVM version from going up just by modifying the Helm Chart. -1. Determine a new version number by [checking the differences](https://github.com/topolvm/topolvm/compare/topolvm-chart-vX.Y.Z...main) since the last release. Then, manually run the workflow to create a PR to update the Helm Chart. +1. Determine a new version number by [checking the differences](https://github.com/syself/csi-topolvm/compare/topolvm-chart-vX.Y.Z...main) since the last release. Then, manually run the workflow to create a PR to update the Helm Chart. - https://github.com/topolvm/topolvm/actions/workflows/create-chart-update-pr.yaml + 2. Review and merge the auto-created PR. 3. Manually run the GitHub Actions workflow for the release. - https://github.com/topolvm/topolvm/actions/workflows/helm-release.yaml + When you run workflow, [helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) will automatically create a GitHub Release. @@ -90,5 +90,4 @@ This will prevent the TopoLVM version from going up just by modifying the Helm C 3. Remove PRs which do not contain changes to the helm chart. [semver]: https://semver.org/spec/v2.0.0.html -[example]: https://github.com/cybozu-go/etcdpasswd/commit/77d95384ac6c97e7f48281eaf23cb94f68867f79 -[GitHub Actions]: https://github.com/topolvm/topolvm/actions +[GitHub Actions]: https://github.com/syself/csi-topolvm/actions diff --git a/api/legacy/v1/logicalvolume_types.go b/api/legacy/v1/logicalvolume_types.go index 97d601417..9648087d2 100644 --- a/api/legacy/v1/logicalvolume_types.go +++ b/api/legacy/v1/logicalvolume_types.go @@ -16,6 +16,7 @@ type LogicalVolumeSpec struct { Name string `json:"name"` NodeName string `json:"nodeName"` + ProviderID string `json:"providerID"` Size resource.Quantity `json:"size"` DeviceClass string `json:"deviceClass,omitempty"` LvcreateOptionClass string `json:"lvcreateOptionClass,omitempty"` diff --git a/api/v1/logicalvolume_types.go b/api/v1/logicalvolume_types.go index 97d601417..9648087d2 100644 --- a/api/v1/logicalvolume_types.go +++ b/api/v1/logicalvolume_types.go @@ -16,6 +16,7 @@ type LogicalVolumeSpec struct { Name string `json:"name"` NodeName string `json:"nodeName"` + ProviderID string `json:"providerID"` Size resource.Quantity `json:"size"` DeviceClass string `json:"deviceClass,omitempty"` LvcreateOptionClass string `json:"lvcreateOptionClass,omitempty"` diff --git a/charts/topolvm/Chart.yaml b/charts/topolvm/Chart.yaml index f73fe6c2b..cf611aeca 100644 --- a/charts/topolvm/Chart.yaml +++ b/charts/topolvm/Chart.yaml @@ -1,13 +1,13 @@ apiVersion: v2 type: application -home: https://github.com/topolvm/topolvm +home: https://github.com/syself/csi-topolvm name: topolvm description: Topolvm version: 14.1.1 appVersion: 0.28.0 sources: - - https://github.com/topolvm/topolvm + - https://github.com/syself/csi-topolvm dependencies: - name: cert-manager diff --git a/charts/topolvm/README.md b/charts/topolvm/README.md index e42a00c09..7dd1b738a 100644 --- a/charts/topolvm/README.md +++ b/charts/topolvm/README.md @@ -7,7 +7,7 @@ ## Installation -See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14.1.1/docs/getting-started.md). +See [Getting Started](https://github.com/syself/csi-topolvm/blob/topolvm-chart-v14.1.1/docs/getting-started.md). ## Values @@ -16,11 +16,12 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | cert-manager.enabled | bool | `false` | Install cert-manager together. # ref: https://cert-manager.io/docs/installation/kubernetes/#installing-with-helm | | controller.affinity | string | `"podAntiAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n - labelSelector:\n matchExpressions:\n - key: app.kubernetes.io/component\n operator: In\n values:\n - controller\n - key: app.kubernetes.io/name\n operator: In\n values:\n - {{ include \"topolvm.name\" . }}\n topologyKey: kubernetes.io/hostname\n"` | Specify affinity. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity | | controller.args | list | `[]` | Arguments to be passed to the command. | +| controller.attachRequired.enabled | bool | `true` | | | controller.initContainers | list | `[]` | Additional initContainers for the controller service. | | controller.labels | object | `{}` | Additional labels to be added to the Deployment. | | controller.leaderElection.enabled | bool | `true` | Enable leader election for controller and all sidecars. | | controller.minReadySeconds | int | `nil` | Specify minReadySeconds. | -| controller.nodeFinalize.skipped | bool | `false` | Skip automatic cleanup of PhysicalVolumeClaims when a Node is deleted. | +| controller.nodeFinalize.skipped | bool | `true` | Skip automatic cleanup of PhysicalVolumeClaims when a Node is deleted. | | controller.nodeSelector | object | `{}` | Specify nodeSelector. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | | controller.podDisruptionBudget.enabled | bool | `true` | Specify podDisruptionBudget enabled. | | controller.podLabels | object | `{}` | Additional labels to be set on the controller pod. | @@ -32,7 +33,7 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | controller.prometheus.podMonitor.namespace | string | `""` | Optional namespace in which to create PodMonitor. | | controller.prometheus.podMonitor.relabelings | list | `[]` | RelabelConfigs to apply to samples before scraping. | | controller.prometheus.podMonitor.scrapeTimeout | string | `""` | Scrape timeout. If not set, the Prometheus default scrape timeout is used. | -| controller.replicaCount | int | `2` | Number of replicas for CSI controller service. | +| controller.replicaCount | int | `1` | Number of replicas for CSI controller service. | | controller.securityContext.enabled | bool | `true` | Enable securityContext. | | controller.storageCapacityTracking.enabled | bool | `true` | Enable Storage Capacity Tracking for csi-provisioner. | | controller.terminationGracePeriodSeconds | int | `nil` | Specify terminationGracePeriodSeconds. | @@ -47,12 +48,13 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | env.topolvm_controller | list | `[]` | Specify environment variables for topolvm_controller container. | | env.topolvm_node | list | `[]` | Specify environment variables for topolvm_node container. | | env.topolvm_scheduler | list | `[]` | Specify environment variables for topolvm_scheduler container. | +| image.csi.csiAttacher | string | `"registry.k8s.io/sig-storage/csi-attacher:v4.5.1"` | Specify csi-attacher image. If not specified, `ghcr.io/topolvm/topolvm-with-sidecar:{{ .Values.image.tag }}` will be used. | | image.csi.csiProvisioner | string | `nil` | Specify csi-provisioner image. If not specified, `ghcr.io/topolvm/topolvm-with-sidecar:{{ .Values.image.tag }}` will be used. | | image.csi.csiResizer | string | `nil` | Specify csi-resizer image. If not specified, `ghcr.io/topolvm/topolvm-with-sidecar:{{ .Values.image.tag }}` will be used. | | image.csi.csiSnapshotter | string | `nil` | Specify csi-snapshot image. If not specified, `ghcr.io/topolvm/topolvm-with-sidecar:{{ .Values.image.tag }}` will be used. | | image.csi.livenessProbe | string | `nil` | Specify livenessprobe image. If not specified, `ghcr.io/topolvm/topolvm-with-sidecar:{{ .Values.image.tag }}` will be used. | | image.csi.nodeDriverRegistrar | string | `nil` | Specify csi-node-driver-registrar: image. If not specified, `ghcr.io/topolvm/topolvm-with-sidecar:{{ .Values.image.tag }}` will be used. | -| image.pullPolicy | string | `nil` | TopoLVM image pullPolicy. | +| image.pullPolicy | string | `"Always"` | TopoLVM image pullPolicy. | | image.pullSecrets | list | `[]` | List of imagePullSecrets. | | image.repository | string | `"ghcr.io/topolvm/topolvm-with-sidecar"` | TopoLVM image repository to use. | | image.tag | string | `{{ .Chart.AppVersion }}` | TopoLVM image tag to use. | @@ -71,7 +73,7 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | lvmd.labels | object | `{}` | Additional labels to be added to the Daemonset. | | lvmd.lvcreateOptionClasses | list | `[]` | Specify the lvcreate-option-class settings. | | lvmd.managed | bool | `true` | If true, set up lvmd service with DaemonSet. | -| lvmd.nodeSelector | object | `{}` | Specify nodeSelector. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | +| lvmd.nodeSelector | object | `{"instance.hetzner.cloud/is-root-server":"true"}` | Specify nodeSelector. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | | lvmd.podLabels | object | `{}` | Additional labels to be set on the lvmd service pods. | | lvmd.priorityClassName | string | `nil` | Specify priorityClassName. | | lvmd.socketName | string | `"/run/topolvm/lvmd.sock"` | Specify socketName. | @@ -89,7 +91,7 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | node.lvmdSocket | string | `"/run/topolvm/lvmd.sock"` | Specify the socket to be used for communication with lvmd. | | node.metrics.annotations | object | `{"prometheus.io/port":"metrics"}` | Annotations for Scrape used by Prometheus. | | node.metrics.enabled | bool | `true` | If true, enable scraping of metrics by Prometheus. | -| node.nodeSelector | object | `{}` | Specify nodeSelector. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | +| node.nodeSelector | object | `{"instance.hetzner.cloud/is-root-server":"true"}` | Specify nodeSelector. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ | | node.podLabels | object | `{}` | Additional labels to be set on the node pods. | | node.priorityClassName | string | `nil` | Specify priorityClassName. | | node.prometheus.podMonitor.additionalLabels | object | `{}` | Additional labels that can be used so PodMonitor will be discovered by Prometheus. | @@ -107,6 +109,7 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | priorityClass.enabled | bool | `true` | Install priorityClass. | | priorityClass.name | string | `"topolvm"` | Specify priorityClass resource name. | | priorityClass.value | int | `1000000` | | +| resources.csi_attacher | object | `{}` | Specify resources. # ref: https://kubernetes.io/docs/user-guide/compute-resources/ | | resources.csi_provisioner | object | `{}` | Specify resources. # ref: https://kubernetes.io/docs/user-guide/compute-resources/ | | resources.csi_registrar | object | `{}` | Specify resources. # ref: https://kubernetes.io/docs/user-guide/compute-resources/ | | resources.csi_resizer | object | `{}` | Specify resources. # ref: https://kubernetes.io/docs/user-guide/compute-resources/ | @@ -128,7 +131,7 @@ See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v14. | scheduler.podDisruptionBudget.enabled | bool | `true` | Specify podDisruptionBudget enabled. | | scheduler.podLabels | object | `{}` | Additional labels to be set on the scheduler pods. | | scheduler.priorityClassName | string | `nil` | Specify priorityClassName on the Deployment or DaemonSet. | -| scheduler.schedulerOptions | object | `{}` | Tune the Node scoring. ref: https://github.com/topolvm/topolvm/blob/master/deploy/README.md | +| scheduler.schedulerOptions | object | `{}` | Tune the Node scoring. ref: https://github.com/syself/csi-topolvm/blob/master/deploy/README.md | | scheduler.service.clusterIP | string | `nil` | Specify Service clusterIP. | | scheduler.service.nodePort | int | `nil` | Specify nodePort. | | scheduler.service.type | string | `"LoadBalancer"` | Specify Service type. | diff --git a/charts/topolvm/README.md.gotmpl b/charts/topolvm/README.md.gotmpl index d701ca528..a55e6398e 100644 --- a/charts/topolvm/README.md.gotmpl +++ b/charts/topolvm/README.md.gotmpl @@ -7,7 +7,7 @@ ## Installation -See [Getting Started](https://github.com/topolvm/topolvm/blob/topolvm-chart-v{{ template "chart.version" . }}/docs/getting-started.md). +See [Getting Started](https://github.com/syself/csi-topolvm/blob/topolvm-chart-v{{ template "chart.version" . }}/docs/getting-started.md). {{ template "chart.valuesSection" . }} diff --git a/charts/topolvm/templates/controller/clusterrolebindings.yaml b/charts/topolvm/templates/controller/clusterrolebindings.yaml index 7517fc70c..2e34223e6 100644 --- a/charts/topolvm/templates/controller/clusterrolebindings.yaml +++ b/charts/topolvm/templates/controller/clusterrolebindings.yaml @@ -27,6 +27,23 @@ roleRef: kind: ClusterRole name: {{ .Release.Namespace }}-external-provisioner-runner apiGroup: rbac.authorization.k8s.io +{{ if .Values.controller.attachRequired.enabled }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Namespace }}-csi-attacher-role + labels: + {{- include "topolvm.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + namespace: {{ .Release.Namespace }} + name: {{ template "topolvm.fullname" . }}-controller +roleRef: + kind: ClusterRole + name: {{ .Release.Namespace }}-external-attacher-runner + apiGroup: rbac.authorization.k8s.io +{{- end }} --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 diff --git a/charts/topolvm/templates/controller/clusterroles.yaml b/charts/topolvm/templates/controller/clusterroles.yaml index d6d98fc2b..73b2237ba 100644 --- a/charts/topolvm/templates/controller/clusterroles.yaml +++ b/charts/topolvm/templates/controller/clusterroles.yaml @@ -72,6 +72,36 @@ rules: #- apiGroups: ["gateway.networking.k8s.io"] # resources: ["referencegrants"] # verbs: ["get", "list", "watch"] +{{ if .Values.controller.attachRequired.enabled }} +--- +# Attacher must be able to work with PVs, CSINodes and VolumeAttachments +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Namespace }}-external-attacher-runner + labels: + {{- include "topolvm.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] +#Secret permission is optional. +#Enable it if you need value from secret. +#For example, you have key `csi.storage.k8s.io/controller-publish-secret-name` in StorageClass.parameters +#see https://kubernetes-csi.github.io/docs/secrets-and-credentials.html +# - apiGroups: [""] +# resources: ["secrets"] +# verbs: ["get", "list"] +{{- end }} --- # Copied from https://github.com/kubernetes-csi/external-resizer/blob/master/deploy/kubernetes/rbac.yaml kind: ClusterRole diff --git a/charts/topolvm/templates/controller/deployment.yaml b/charts/topolvm/templates/controller/deployment.yaml index 8a4e5e90c..303ac373b 100644 --- a/charts/topolvm/templates/controller/deployment.yaml +++ b/charts/topolvm/templates/controller/deployment.yaml @@ -187,7 +187,7 @@ spec: {{- with .Values.env.csi_attacher }} env: {{ toYaml . | nindent 12 }} {{- end }} - command: + args: - "--v=5" - "--reconcile-sync=30m" - "--timeout=45m" diff --git a/charts/topolvm/templates/controller/rolebinding.yaml b/charts/topolvm/templates/controller/rolebinding.yaml index 9514b32b2..6f401be96 100644 --- a/charts/topolvm/templates/controller/rolebinding.yaml +++ b/charts/topolvm/templates/controller/rolebinding.yaml @@ -29,6 +29,24 @@ roleRef: kind: Role name: external-provisioner-cfg apiGroup: rbac.authorization.k8s.io +{{ if .Values.controller.attachRequired.enabled }} +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-attacher-role-cfg + namespace: {{ .Release.Namespace }} + labels: + {{- include "topolvm.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + namespace: {{ .Release.Namespace }} + name: {{ template "topolvm.fullname" . }}-controller +roleRef: + kind: Role + name: external-attacher-cfg + apiGroup: rbac.authorization.k8s.io +{{- end }} --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 diff --git a/charts/topolvm/templates/controller/roles.yaml b/charts/topolvm/templates/controller/roles.yaml index d05502a8c..f1c582ced 100644 --- a/charts/topolvm/templates/controller/roles.yaml +++ b/charts/topolvm/templates/controller/roles.yaml @@ -42,6 +42,21 @@ rules: - apiGroups: ["apps"] resources: ["replicasets"] verbs: ["get"] +{{ if .Values.controller.attachRequired.enabled }} +--- +# Copied from https://github.com/kubernetes-csi/external-attacher/blob/master/deploy/kubernetes/rbac.yaml +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: external-attacher-cfg + namespace: {{ .Release.Namespace }} + labels: + {{- include "topolvm.labels" . | nindent 4 }} +rules: +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] +{{- end }} --- # Copied from https://github.com/kubernetes-csi/external-resizer/blob/master/deploy/kubernetes/rbac.yaml kind: Role diff --git a/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml b/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml index 80fc18fa8..0d62d1da4 100644 --- a/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml +++ b/charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: logicalvolumes.topolvm.cybozu.com spec: group: topolvm.cybozu.com @@ -21,14 +21,19 @@ spec: description: LogicalVolume is the Schema for the logicalvolumes API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -36,10 +41,10 @@ spec: description: LogicalVolumeSpec defines the desired state of LogicalVolume properties: accessType: - description: '''accessType'' specifies how the user intends to consume - the snapshot logical volume. Set to "ro" when creating a snapshot - and to "rw" when restoring a snapshot or creating a clone. This - field is populated only when LogicalVolume has a source.' + description: |- + 'accessType' specifies how the user intends to consume the snapshot logical volume. + Set to "ro" when creating a snapshot and to "rw" when restoring a snapshot or creating a clone. + This field is populated only when LogicalVolume has a source. type: string deviceClass: type: string @@ -49,6 +54,8 @@ spec: type: string nodeName: type: string + providerID: + type: string size: anyOf: - type: integer @@ -56,21 +63,30 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true source: - description: '''source'' specifies the logicalvolume name of the source; - if present. This field is populated only when LogicalVolume has - a source.' + description: |- + 'source' specifies the logicalvolume name of the source; if present. + This field is populated only when LogicalVolume has a source. type: string required: - name - nodeName + - providerID - size type: object status: description: LogicalVolumeStatus defines the observed state of LogicalVolume properties: code: - description: A Code is an unsigned 32-bit error code as defined in - the gRPC spec. + description: |- + A Code is a status code defined according to the [gRPC documentation]. + + + Only the codes defined as consts in this package are valid codes. Do not use + other code values. Behavior of other codes is implementation-specific and + interoperability between implementations is not guaranteed. + + + [gRPC documentation]: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md format: int32 type: integer currentSize: @@ -82,9 +98,9 @@ spec: message: type: string volumeID: - description: 'INSERT ADDITIONAL STATUS FIELD - define observed state - of cluster Important: Run "make" to regenerate code after modifying - this file' + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file type: string type: object type: object diff --git a/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml b/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml index 62e0a1ae1..8f83af6d5 100644 --- a/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml +++ b/charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: logicalvolumes.topolvm.io spec: group: topolvm.io @@ -21,14 +21,19 @@ spec: description: LogicalVolume is the Schema for the logicalvolumes API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -36,10 +41,10 @@ spec: description: LogicalVolumeSpec defines the desired state of LogicalVolume properties: accessType: - description: '''accessType'' specifies how the user intends to consume - the snapshot logical volume. Set to "ro" when creating a snapshot - and to "rw" when restoring a snapshot or creating a clone. This - field is populated only when LogicalVolume has a source.' + description: |- + 'accessType' specifies how the user intends to consume the snapshot logical volume. + Set to "ro" when creating a snapshot and to "rw" when restoring a snapshot or creating a clone. + This field is populated only when LogicalVolume has a source. type: string deviceClass: type: string @@ -49,6 +54,8 @@ spec: type: string nodeName: type: string + providerID: + type: string size: anyOf: - type: integer @@ -56,21 +63,30 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true source: - description: '''source'' specifies the logicalvolume name of the source; - if present. This field is populated only when LogicalVolume has - a source.' + description: |- + 'source' specifies the logicalvolume name of the source; if present. + This field is populated only when LogicalVolume has a source. type: string required: - name - nodeName + - providerID - size type: object status: description: LogicalVolumeStatus defines the observed state of LogicalVolume properties: code: - description: A Code is an unsigned 32-bit error code as defined in - the gRPC spec. + description: |- + A Code is a status code defined according to the [gRPC documentation]. + + + Only the codes defined as consts in this package are valid codes. Do not use + other code values. Behavior of other codes is implementation-specific and + interoperability between implementations is not guaranteed. + + + [gRPC documentation]: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md format: int32 type: integer currentSize: @@ -82,9 +98,9 @@ spec: message: type: string volumeID: - description: 'INSERT ADDITIONAL STATUS FIELD - define observed state - of cluster Important: Run "make" to regenerate code after modifying - this file' + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file type: string type: object type: object diff --git a/charts/topolvm/values.yaml b/charts/topolvm/values.yaml index feb214cc3..fcc275f30 100644 --- a/charts/topolvm/values.yaml +++ b/charts/topolvm/values.yaml @@ -3,14 +3,14 @@ useLegacy: false image: # image.repository -- TopoLVM image repository to use. - repository: ghcr.io/topolvm/topolvm-with-sidecar + repository: ghcr.io/syself/csi-topolvm-with-sidecar # image.tag -- TopoLVM image tag to use. # @default -- `{{ .Chart.AppVersion }}` - tag: # 0.18.1 + tag: latest # 0.18.1 # image.pullPolicy -- TopoLVM image pullPolicy. - pullPolicy: # Always + pullPolicy: Always # image.pullSecrets -- List of imagePullSecrets. pullSecrets: [] @@ -109,7 +109,7 @@ scheduler: priorityClassName: # scheduler.schedulerOptions -- Tune the Node scoring. - # ref: https://github.com/topolvm/topolvm/blob/master/deploy/README.md + # ref: https://github.com/syself/csi-topolvm/blob/master/deploy/README.md schedulerOptions: {} # default-divisor: 1 # divisors: @@ -161,7 +161,8 @@ lvmd: # lvmd.nodeSelector -- Specify nodeSelector. ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - nodeSelector: {} + nodeSelector: + instance.hetzner.cloud/is-root-server: "true" # lvmd.affinity -- Specify affinity. ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity @@ -287,7 +288,8 @@ node: # node.nodeSelector -- Specify nodeSelector. ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - nodeSelector: {} + nodeSelector: + instance.hetzner.cloud/is-root-server: "true" # node.affinity -- Specify affinity. ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity @@ -357,7 +359,7 @@ node: # CSI controller service controller: # controller.replicaCount -- Number of replicas for CSI controller service. - replicaCount: 2 + replicaCount: 1 # controller.args -- Arguments to be passed to the command. args: [] @@ -375,7 +377,7 @@ controller: nodeFinalize: # controller.nodeFinalize.skipped -- Skip automatic cleanup of PhysicalVolumeClaims when a Node is deleted. - skipped: false + skipped: true leaderElection: # controller.leaderElection.enabled -- Enable leader election for controller and all sidecars. diff --git a/cmd/hypertopolvm/main.go b/cmd/hypertopolvm/main.go index 85a79d6b7..f3abf2da4 100644 --- a/cmd/hypertopolvm/main.go +++ b/cmd/hypertopolvm/main.go @@ -5,10 +5,10 @@ import ( "os" "path/filepath" - lvmd "github.com/topolvm/topolvm/cmd/lvmd/app" - controller "github.com/topolvm/topolvm/cmd/topolvm-controller/app" - node "github.com/topolvm/topolvm/cmd/topolvm-node/app" - scheduler "github.com/topolvm/topolvm/cmd/topolvm-scheduler/app" + lvmd "github.com/syself/csi-topolvm/cmd/lvmd/app" + controller "github.com/syself/csi-topolvm/cmd/topolvm-controller/app" + node "github.com/syself/csi-topolvm/cmd/topolvm-node/app" + scheduler "github.com/syself/csi-topolvm/cmd/topolvm-scheduler/app" ) func usage() { diff --git a/cmd/lvmd/app/config.go b/cmd/lvmd/app/config.go index bc879ddb5..2551dc700 100644 --- a/cmd/lvmd/app/config.go +++ b/cmd/lvmd/app/config.go @@ -4,8 +4,8 @@ import ( "context" "os" - "github.com/topolvm/topolvm" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + topolvm "github.com/syself/csi-topolvm" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/yaml" ) diff --git a/cmd/lvmd/app/root.go b/cmd/lvmd/app/root.go index 21d450753..c5fd68c3c 100644 --- a/cmd/lvmd/app/root.go +++ b/cmd/lvmd/app/root.go @@ -12,11 +12,11 @@ import ( "time" "github.com/spf13/cobra" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/internal/lvmd" - "github.com/topolvm/topolvm/internal/lvmd/command" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/internal/lvmd" + "github.com/syself/csi-topolvm/internal/lvmd/command" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" "k8s.io/klog/v2" @@ -25,8 +25,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" ) -var cfgFilePath string -var zapOpts zap.Options +var ( + cfgFilePath string + zapOpts zap.Options +) // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ diff --git a/cmd/lvmd/main.go b/cmd/lvmd/main.go index 442131707..f653c1694 100644 --- a/cmd/lvmd/main.go +++ b/cmd/lvmd/main.go @@ -1,6 +1,6 @@ package main -import "github.com/topolvm/topolvm/cmd/lvmd/app" +import "github.com/syself/csi-topolvm/cmd/lvmd/app" func main() { app.Execute() diff --git a/cmd/topolvm-controller/app/root.go b/cmd/topolvm-controller/app/root.go index c4acb7dc6..d2f4645ea 100644 --- a/cmd/topolvm-controller/app/root.go +++ b/cmd/topolvm-controller/app/root.go @@ -7,8 +7,8 @@ import ( "time" "github.com/spf13/cobra" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/pkg/driver" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/pkg/driver" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -62,6 +62,7 @@ It also works as a custom Kubernetes controller.`, // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { + fmt.Println("starting syself patched controller (x5555) ###################") if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/topolvm-controller/app/run.go b/cmd/topolvm-controller/app/run.go index de0b1501d..344a3caa4 100644 --- a/cmd/topolvm-controller/app/run.go +++ b/cmd/topolvm-controller/app/run.go @@ -7,14 +7,13 @@ import ( "time" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - clientwrapper "github.com/topolvm/topolvm/internal/client" - "github.com/topolvm/topolvm/internal/hook" - "github.com/topolvm/topolvm/internal/runners" - "github.com/topolvm/topolvm/pkg/controller" - "github.com/topolvm/topolvm/pkg/driver" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + clientwrapper "github.com/syself/csi-topolvm/internal/client" + "github.com/syself/csi-topolvm/internal/hook" + "github.com/syself/csi-topolvm/internal/runners" + "github.com/syself/csi-topolvm/pkg/controller" + "github.com/syself/csi-topolvm/pkg/driver" "google.golang.org/grpc" storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/runtime" @@ -40,7 +39,6 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(topolvmv1.AddToScheme(scheme)) - utilruntime.Must(topolvmlegacyv1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/cmd/topolvm-controller/main.go b/cmd/topolvm-controller/main.go index 0ead77c2f..a529077de 100644 --- a/cmd/topolvm-controller/main.go +++ b/cmd/topolvm-controller/main.go @@ -1,6 +1,6 @@ package main -import "github.com/topolvm/topolvm/cmd/topolvm-controller/app" +import "github.com/syself/csi-topolvm/cmd/topolvm-controller/app" func main() { app.Execute() diff --git a/cmd/topolvm-node/app/root.go b/cmd/topolvm-node/app/root.go index 13878a5b0..5929f6e3e 100644 --- a/cmd/topolvm-node/app/root.go +++ b/cmd/topolvm-node/app/root.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/topolvm/topolvm" - lvmd "github.com/topolvm/topolvm/cmd/lvmd/app" + topolvm "github.com/syself/csi-topolvm" + lvmd "github.com/syself/csi-topolvm/cmd/lvmd/app" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/log/zap" ) diff --git a/cmd/topolvm-node/app/run.go b/cmd/topolvm-node/app/run.go index b1c8c147c..30018ed90 100644 --- a/cmd/topolvm-node/app/run.go +++ b/cmd/topolvm-node/app/run.go @@ -12,15 +12,15 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" "github.com/spf13/viper" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - clientwrapper "github.com/topolvm/topolvm/internal/client" - "github.com/topolvm/topolvm/internal/runners" - "github.com/topolvm/topolvm/pkg/controller" - "github.com/topolvm/topolvm/pkg/driver" - "github.com/topolvm/topolvm/pkg/lvmd" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + clientwrapper "github.com/syself/csi-topolvm/internal/client" + "github.com/syself/csi-topolvm/internal/runners" + "github.com/syself/csi-topolvm/pkg/controller" + "github.com/syself/csi-topolvm/pkg/driver" + "github.com/syself/csi-topolvm/pkg/lvmd" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + "github.com/syself/csi-topolvm/pkg/node" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health/grpc_health_v1" @@ -29,8 +29,9 @@ import ( "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/util/retry" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + ctrClient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/filters" @@ -49,15 +50,14 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(topolvmv1.AddToScheme(scheme)) - utilruntime.Must(topolvmlegacyv1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } func subMain(ctx context.Context) error { ctx, cancel := context.WithCancel(ctx) defer cancel() - nodename := viper.GetString("nodename") - if len(nodename) == 0 { + nodeName := viper.GetString("nodename") + if nodeName == "" { return errors.New("node name is not given") } @@ -112,7 +112,21 @@ func subMain(ctx context.Context) error { health = grpc_health_v1.NewHealthClient(conn) } - if err := controller.SetupLogicalVolumeReconcilerWithServices(mgr, client, nodename, vgService, lvService); err != nil { + uncachedClient, err := ctrClient.New(mgr.GetConfig(), ctrClient.Options{Scheme: mgr.GetScheme(), Mapper: mgr.GetRESTMapper()}) + if err != nil { + return fmt.Errorf("GetProviderID failed to create uncachedClient %q: %w", nodeName, err) + } + providerID, err := node.GetProviderIDByNodeName(context.Background(), uncachedClient, nodeName) + if err != nil { + return fmt.Errorf("GetProviderID failed for node %q: %w", nodeName, err) + } + + err = updateNodeSetProviderID(ctx, uncachedClient, nodeName, providerID) + if err != nil { + return err + } + + if err := controller.SetupLogicalVolumeReconcilerWithServices(mgr, client, nodeName, providerID, vgService, lvService); err != nil { setupLog.Error(err, "unable to create controller", "controller", "LogicalVolume") return err } @@ -127,17 +141,17 @@ func subMain(ctx context.Context) error { // Add metrics exporter to manager. // Note that grpc.ClientConn can be shared with multiple stubs/services. // https://github.com/grpc/grpc-go/tree/master/examples/features/multiplex - if err := mgr.Add(runners.NewMetricsExporter(vgService, client, nodename)); err != nil { // adjusted signature + if err := mgr.Add(runners.NewMetricsExporter(vgService, client, nodeName)); err != nil { // adjusted signature return err } // Add gRPC server to manager. - if err := os.MkdirAll(topolvm.DeviceDirectory, 0755); err != nil { + if err := os.MkdirAll(topolvm.DeviceDirectory, 0o755); err != nil { return err } grpcServer := grpc.NewServer(grpc.UnaryInterceptor(ErrorLoggingInterceptor)) csi.RegisterIdentityServer(grpcServer, driver.NewIdentityServer(checker.Ready)) - nodeServer, err := driver.NewNodeServer(nodename, vgService, lvService, mgr) // adjusted signature + nodeServer, err := driver.NewNodeServer(nodeName, providerID, vgService, lvService, mgr) // adjusted signature if err != nil { return err } @@ -167,7 +181,7 @@ func subMain(ctx context.Context) error { //+kubebuilder:rbac:groups=storage.k8s.io,resources=csidrivers,verbs=get;list;watch -func checkFunc(health grpc_health_v1.HealthClient, r client.Reader) func() error { +func checkFunc(health grpc_health_v1.HealthClient, r ctrClient.Reader) func() error { return func() error { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -210,3 +224,33 @@ func loadConfFile(ctx context.Context, cfgFilePath string) error { ) return nil } + +func updateNodeSetProviderID(ctx context.Context, client ctrClient.Client, nodeName string, providerID string) error { + log := ctrl.LoggerFrom(ctx) + + err := retry.RetryOnConflict(retry.DefaultRetry, + func() error { + nodeObj, err := node.GetNodeByName(context.Background(), client, nodeName) + if err != nil { + return fmt.Errorf("GetNodeByName failed in updateNodeSetProviderID: %w", err) + } + existingId := nodeObj.Labels[topolvm.ProviderIDLabel] + if existingId == providerID { + log.Info(fmt.Sprintf("########syself no need to update label %s=%s on node %s (already set)", + topolvm.ProviderIDLabel, providerID, nodeName)) + return nil + } + nodeObj.Labels[topolvm.ProviderIDLabel] = providerID + err = client.Update(ctx, nodeObj) + if err != nil { + return fmt.Errorf("failed to update node (set Label) in updateNodeSetProviderID: %w", err) + } + log.Info(fmt.Sprintf("########syself successfully updated label %s=%s on node %s", + topolvm.ProviderIDLabel, providerID, nodeName)) + return nil + }) + if err != nil { + return fmt.Errorf("failed to get node %q in updateNodeSetProviderID: %w", nodeName, err) + } + return nil +} diff --git a/cmd/topolvm-node/main.go b/cmd/topolvm-node/main.go index 0f145ae98..04015916b 100644 --- a/cmd/topolvm-node/main.go +++ b/cmd/topolvm-node/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/topolvm/topolvm/cmd/topolvm-node/app" + "github.com/syself/csi-topolvm/cmd/topolvm-node/app" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" ) diff --git a/cmd/topolvm-scheduler/app/root.go b/cmd/topolvm-scheduler/app/root.go index 8e04bb86f..bd8b3d1ec 100644 --- a/cmd/topolvm-scheduler/app/root.go +++ b/cmd/topolvm-scheduler/app/root.go @@ -12,19 +12,23 @@ import ( "time" "github.com/spf13/cobra" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/internal/scheduler" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/internal/scheduler" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/yaml" ) -var cfgFilePath string -var zapOpts zap.Options +var ( + cfgFilePath string + zapOpts zap.Options +) -const defaultDivisor = 1 -const defaultListenAddr = ":8000" +const ( + defaultDivisor = 1 + defaultListenAddr = ":8000" +) // Config represents configuration parameters for topolvm-scheduler type Config struct { diff --git a/cmd/topolvm-scheduler/main.go b/cmd/topolvm-scheduler/main.go index 265999626..ef9ddf93a 100644 --- a/cmd/topolvm-scheduler/main.go +++ b/cmd/topolvm-scheduler/main.go @@ -1,6 +1,6 @@ package main -import "github.com/topolvm/topolvm/cmd/topolvm-scheduler/app" +import "github.com/syself/csi-topolvm/cmd/topolvm-scheduler/app" func main() { app.Execute() diff --git a/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml b/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml index d22cd9c8b..790446f4e 100644 --- a/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml +++ b/config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: logicalvolumes.topolvm.cybozu.com spec: group: topolvm.cybozu.com @@ -20,14 +20,19 @@ spec: description: LogicalVolume is the Schema for the logicalvolumes API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -35,10 +40,10 @@ spec: description: LogicalVolumeSpec defines the desired state of LogicalVolume properties: accessType: - description: '''accessType'' specifies how the user intends to consume - the snapshot logical volume. Set to "ro" when creating a snapshot - and to "rw" when restoring a snapshot or creating a clone. This - field is populated only when LogicalVolume has a source.' + description: |- + 'accessType' specifies how the user intends to consume the snapshot logical volume. + Set to "ro" when creating a snapshot and to "rw" when restoring a snapshot or creating a clone. + This field is populated only when LogicalVolume has a source. type: string deviceClass: type: string @@ -48,6 +53,8 @@ spec: type: string nodeName: type: string + providerID: + type: string size: anyOf: - type: integer @@ -55,21 +62,30 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true source: - description: '''source'' specifies the logicalvolume name of the source; - if present. This field is populated only when LogicalVolume has - a source.' + description: |- + 'source' specifies the logicalvolume name of the source; if present. + This field is populated only when LogicalVolume has a source. type: string required: - name - nodeName + - providerID - size type: object status: description: LogicalVolumeStatus defines the observed state of LogicalVolume properties: code: - description: A Code is an unsigned 32-bit error code as defined in - the gRPC spec. + description: |- + A Code is a status code defined according to the [gRPC documentation]. + + + Only the codes defined as consts in this package are valid codes. Do not use + other code values. Behavior of other codes is implementation-specific and + interoperability between implementations is not guaranteed. + + + [gRPC documentation]: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md format: int32 type: integer currentSize: @@ -81,9 +97,9 @@ spec: message: type: string volumeID: - description: 'INSERT ADDITIONAL STATUS FIELD - define observed state - of cluster Important: Run "make" to regenerate code after modifying - this file' + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file type: string type: object type: object diff --git a/config/crd/bases/topolvm.io_logicalvolumes.yaml b/config/crd/bases/topolvm.io_logicalvolumes.yaml index 26deffee2..bd0e58491 100644 --- a/config/crd/bases/topolvm.io_logicalvolumes.yaml +++ b/config/crd/bases/topolvm.io_logicalvolumes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.15.0 name: logicalvolumes.topolvm.io spec: group: topolvm.io @@ -20,14 +20,19 @@ spec: description: LogicalVolume is the Schema for the logicalvolumes API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -35,10 +40,10 @@ spec: description: LogicalVolumeSpec defines the desired state of LogicalVolume properties: accessType: - description: '''accessType'' specifies how the user intends to consume - the snapshot logical volume. Set to "ro" when creating a snapshot - and to "rw" when restoring a snapshot or creating a clone. This - field is populated only when LogicalVolume has a source.' + description: |- + 'accessType' specifies how the user intends to consume the snapshot logical volume. + Set to "ro" when creating a snapshot and to "rw" when restoring a snapshot or creating a clone. + This field is populated only when LogicalVolume has a source. type: string deviceClass: type: string @@ -48,6 +53,8 @@ spec: type: string nodeName: type: string + providerID: + type: string size: anyOf: - type: integer @@ -55,21 +62,30 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true source: - description: '''source'' specifies the logicalvolume name of the source; - if present. This field is populated only when LogicalVolume has - a source.' + description: |- + 'source' specifies the logicalvolume name of the source; if present. + This field is populated only when LogicalVolume has a source. type: string required: - name - nodeName + - providerID - size type: object status: description: LogicalVolumeStatus defines the observed state of LogicalVolume properties: code: - description: A Code is an unsigned 32-bit error code as defined in - the gRPC spec. + description: |- + A Code is a status code defined according to the [gRPC documentation]. + + + Only the codes defined as consts in this package are valid codes. Do not use + other code values. Behavior of other codes is implementation-specific and + interoperability between implementations is not guaranteed. + + + [gRPC documentation]: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md format: int32 type: integer currentSize: @@ -81,9 +97,9 @@ spec: message: type: string volumeID: - description: 'INSERT ADDITIONAL STATUS FIELD - define observed state - of cluster Important: Run "make" to regenerate code after modifying - this file' + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file type: string type: object type: object diff --git a/constants.go b/constants.go index 531d85ba3..5f65e9bcc 100644 --- a/constants.go +++ b/constants.go @@ -2,27 +2,17 @@ package topolvm import ( "fmt" - "os" corev1 "k8s.io/api/core/v1" ) const ( - pluginName = "topolvm.io" - legacyPluginName = "topolvm.cybozu.com" + pluginName = "topolvm.io" ) -func UseLegacy() bool { - return os.Getenv("USE_LEGACY") != "" -} - // GetPluginName returns the name of the CSI plugin. func GetPluginName() string { - if UseLegacy() { - return legacyPluginName - } else { - return pluginName - } + return pluginName } // GetCapacityKeyPrefix returns the key prefix of Node annotation that represents VG free space. @@ -35,6 +25,10 @@ func GetCapacityResource() corev1.ResourceName { return corev1.ResourceName(fmt.Sprintf("%s/capacity", GetPluginName())) } +var ProviderIDLabel = "autopilot.syself.com/providerid" + +// Deprecated: GetTopologyNodeKey is deprecated, use ProviderIDLabel instead. +// // TopologyNodeKey returns the key of topology that represents node name. func GetTopologyNodeKey() string { return fmt.Sprintf("topology.%s/node", GetPluginName()) @@ -73,9 +67,6 @@ func GetNodeFinalizer() string { // PVCFinalizer is a finalizer of PVC. const PVCFinalizer = pluginName + "/pvc" -// LegacyPVCFinalizer is a legacy finalizer of PVC. -const LegacyPVCFinalizer = legacyPluginName + "/pvc" - // DefaultCSISocket is the default path of the CSI socket file. const DefaultCSISocket = "/run/topolvm/csi-topolvm.sock" diff --git a/constants_test.go b/constants_test.go deleted file mode 100644 index 3aa576bf2..000000000 --- a/constants_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package topolvm - -import ( - "fmt" - "os" - "strconv" - "strings" - "testing" - - testingutil "github.com/topolvm/topolvm/test/util" -) - -func TestUseLegacy(t *testing.T) { - testingutil.DoEnvCheck(t) - tests := []struct { - name string - envval string - expected bool - }{ - { - name: "return false if USE_LEGACY env value is empty", - envval: "", - expected: false, - }, - { - name: "return true if USE_LEGACY env value is not empty", - envval: "true", - expected: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - os.Setenv("USE_LEGACY", tt.envval) - if UseLegacy() != tt.expected { - t.Fatalf("return value is not %s", strconv.FormatBool(tt.expected)) - } - }) - } -} - -func TestGetPluginName(t *testing.T) { - testingutil.DoEnvCheck(t) - tests := []struct { - name string - envval string - expected string - }{ - { - name: fmt.Sprintf("return %q if USE_LEGACY env value is empty", pluginName), - envval: "", - expected: pluginName, - }, - { - name: fmt.Sprintf("return %q if USE_LEGACY env value is not empty", legacyPluginName), - envval: "true", - expected: legacyPluginName, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - os.Setenv("USE_LEGACY", tt.envval) - if GetPluginName() != tt.expected { - t.Fatalf("return value is not %s", tt.expected) - } - }) - } -} - -func TestGetCapacityKeyPrefix(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetCapacityKeyPrefix) -} - -func TestGetCapacityResource(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, func() string { - return string(GetCapacityResource()) - }) -} - -func TestGetTopologyNodeKey(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetTopologyNodeKey) -} - -func TestGetDeviceClassKey(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetDeviceClassKey) -} - -func TestGetResizeRequestedAtKey(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetResizeRequestedAtKey) -} - -func TestGetLVPendingDeletionKey(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetLVPendingDeletionKey) -} - -func TestGetLogicalVolumeFinalizer(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetLogicalVolumeFinalizer) -} - -func TestGetNodeFinalizer(t *testing.T) { - testingutil.DoEnvCheck(t) - doContainTest(t, GetNodeFinalizer) -} - -func doContainTest(t *testing.T, f func() string) { - tests := []struct { - name string - envval string - contained string - }{ - { - name: fmt.Sprintf("return strings containing %q if USE_LEGACY env value is empty", pluginName), - envval: "", - contained: pluginName, - }, - { - name: fmt.Sprintf("return strings containing %q if USE_LEGACY env value is not empty", legacyPluginName), - envval: "true", - contained: legacyPluginName, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - os.Setenv("USE_LEGACY", tt.envval) - val := f() - if !strings.Contains(val, tt.contained) { - t.Fatalf("return value %q does not contain strings: %s", val, tt.contained) - } - }) - } -} diff --git a/deploy/scheduler-config/scheduler-config-legacy.yaml b/deploy/scheduler-config/scheduler-config-legacy.yaml deleted file mode 100644 index df986fc77..000000000 --- a/deploy/scheduler-config/scheduler-config-legacy.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: kubescheduler.config.k8s.io/v1beta3 -kind: KubeSchedulerConfiguration -leaderElection: - leaderElect: true -clientConnection: - kubeconfig: /etc/kubernetes/scheduler.conf -extenders: -- urlPrefix: "http://127.0.0.1:9251" - filterVerb: "predicate" - prioritizeVerb: "prioritize" - nodeCacheCapable: false - weight: 1 - managedResources: - - name: "topolvm.cybozu.com/capacity" - ignoredByScheduler: true diff --git a/docs/advanced-setup.md b/docs/advanced-setup.md index 572c37f10..86aad98b9 100644 --- a/docs/advanced-setup.md +++ b/docs/advanced-setup.md @@ -113,7 +113,7 @@ node: ### Run LVMd as a Systemd Service Before setup, you need to get LMVd binary. -We provide pre-built binaries in the [releases page](https://github.com/topolvm/topolvm/releases) for x86 architecture. +We provide pre-built binaries in the [releases page](https://github.com/syself/csi-topolvm/releases) for x86 architecture. If you use other architecture or want to build it from source code, you can build it by `mkdir build; go build -o build/lvmd ./pkg/lvmd`. To setup LVMd as a systemd service: @@ -176,7 +176,7 @@ The default method is using cert-manager described in [Getting Started](getting- If you don't want to use cert-manager, you can use your own certificates as follows: -1. Prepare PEM encoded self-signed certificate and key files. +1. Prepare PEM encoded self-signed certificate and key files. The certificate must be valid for hostname like `topolvm-controller.topolvm-system.svc`. 2. Base64-encode the CA cert (in its PEM format) 3. Create Secret in `topolvm-system` namespace as follows: diff --git a/docs/deprecated/helm/MIGRATION.md b/docs/deprecated/helm/MIGRATION.md index 6e8880497..ea07daf5c 100644 --- a/docs/deprecated/helm/MIGRATION.md +++ b/docs/deprecated/helm/MIGRATION.md @@ -23,44 +23,44 @@ for example: | Kind | Kustomize Name | Helm Name | | ---- | -------------- | --------- | -| Issuer | [webhook-selfsign](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L1-L9) | `{{ template "topolvm.fullname" . }}-webhook-selfsign` | -| Certificate | [webhook-ca](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L11-L27) | `{{ template "topolvm.fullname" . }}-webhook-ca` | -| Issuer | [webhook-ca](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L29-L37) | `{{ template "topolvm.fullname" . }}-webhook-ca` | -| Certificate | [mutatingwebhook](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L39-L58) | `{{ template "topolvm.fullname" . }}-mutatingwebhook` | -| CSIDriver | [topolvm.io](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L2-L11) | [Please read here](./README.md#about-the-legacy-flag) | -| ServiceAccount | [controller](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L14-L18) | `{{ template "topolvm.fullname" . }}-controller` | -| ClusterRole | [topolvm-system:controller](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L20-L39) | `{{ .Release.Namespace }}:controller` | -| ClusterRoleBinding | [topolvm-system:controller](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L41-L52) | `{{ .Release.Namespace }}:controller` | -| Role | [leader-election](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L54-L80) | **NO CHANGED** | -| RoleBinding | [leader-election](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L82-L94) | **NO CHANGED** | -| ClusterRole | [topolvm-external-provisioner-runner](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L96-L127) | **NO CHANGED** | -| ClusterRoleBinding | [topolvm-csi-provisioner-role](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L129-L150) | **NO CHANGED** | -| RoleBinding | [csi-provisioner-role-cfg](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L152-L164) | **NO CHANGED** | -| ClusterRole | [topolvm-external-attacher-runner](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L166-L185) | **NO CHANGED** | -| ClusterRoleBinding | [topolvm-csi-attacher-role](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L187-L198) | **NO CHANGED** | -| RoleBinding | [csi-attacher-role-cfg](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L210-L222) | **NO CHANGED** | -| ClusterRole | [topolvm-external-resizer-runner](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L224-L240) | **NO CHANGED** | -| ClusterRoleBinding | [topolvm-csi-resizer-role](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L242-L253) | **NO CHANGED** | -| Role | [external-resizer-cfg](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L255-L263) | **NO CHANGED** | -| RoleBinding | [csi-resizer-role-cfg](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L265-L277) | **NO CHANGED** | -| Service | [controller](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L280-L291) | `{{ template "topolvm.fullname" . }}-controller` | -| Deployment | [controller](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L293-L399) | `{{ template "topolvm.fullname" . }}-controller` | -| MutatingWebhookConfiguration | [topolvm-hook](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/mutatingwebhooks.yaml#L1-L63) | `{{ template "topolvm.fullname" . }}-hook` | -| ServiceAccount | [node](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L1-L5) | `{{ template "topolvm.fullname" . }}-node` | -| ClusterRole | [topolvm-system:node](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L7-L24) | `{{ .Release.Namespace }}:node` | -| ClusterRoleBinding | [topolvm-system:node](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L26-L37) | `{{ .Release.Namespace }}:node` | -| DaemonSet | [node](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L40-L139) | `{{ template "topolvm.fullname" . }}-node` | -| StorageClass | [topolvm-provisioner](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/provisioner.yaml#L1-L9) | **NO CHANGED** | -| PodSecurityPolicy | [topolvm-node](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/psp.yaml#L1-L27) | `{{ template "topolvm.fullname" . }}-node` | -| PodSecurityPolicy | [topolvm-scheduler](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/psp.yaml#L29-L55) | `{{ template "topolvm.fullname" . }}-scheduler` | -| ServiceAccount | [topolvm-system](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/scheduler.yaml#L2-L6) | `{{ template "topolvm.fullname" . }}-scheduler` | -| Role | [psp:topolvm-scheduler](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/scheduler.yaml#L8-L17) | `psp:{{ template "topolvm.fullname" . }}-scheduler` | -| RoleBinding | [topolvm-scheduler:psp:topolvm-scheduler](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/base/scheduler.yaml#L19-L31) | `{{ template "topolvm.fullname" . }}-scheduler:psp:{{ template "topolvm.fullname" . }}-scheduler` | -| DaemonSet | [topolvm-scheduler](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/overlays/daemonset-scheduler/scheduler.yaml#L1-L54) | `{{ template "topolvm.fullname" . }}-scheduler` | -| Deployment | [topolvm-scheduler](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/overlays/deployment-scheduler/scheduler.yaml#L1-L36) | `{{ template "topolvm.fullname" . }}-scheduler` | -| Service | [topolvm-scheduler](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/overlays/deployment-scheduler/scheduler.yaml#L38-L49) | `{{ template "topolvm.fullname" . }}-scheduler` | -| ServiceAccount | [lvmd](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L2-L6) | `{{ template "topolvm.fullname" . }}-lvmd` | -| PodSecurityPolicy | [lvmd](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L8-L30) | `{{ template "topolvm.fullname" . }}-lvmd` | -| Role | [psp:lvmd](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L32-L41) | `psp:{{ template "topolvm.fullname" . }}-lvmd` | -| RoleBinding | [lvmd:psp:lvmd](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L43-L55) | `{{ template "topolvm.fullname" . }}-lvmd:psp:{{ template "topolvm.fullname" . }}-lvmd` | -| DaemonSet | [lvmd](https://github.com/topolvm/topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L57-L94) | `{{ template "topolvm.fullname" . }}-lvmd-{{ $lvmdidx }}` | +| Issuer | [webhook-selfsign](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L1-L9) | `{{ template "topolvm.fullname" . }}-webhook-selfsign` | +| Certificate | [webhook-ca](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L11-L27) | `{{ template "topolvm.fullname" . }}-webhook-ca` | +| Issuer | [webhook-ca](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L29-L37) | `{{ template "topolvm.fullname" . }}-webhook-ca` | +| Certificate | [mutatingwebhook](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/certificates.yaml#L39-L58) | `{{ template "topolvm.fullname" . }}-mutatingwebhook` | +| CSIDriver | [topolvm.io](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L2-L11) | [Please read here](./README.md#about-the-legacy-flag) | +| ServiceAccount | [controller](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L14-L18) | `{{ template "topolvm.fullname" . }}-controller` | +| ClusterRole | [topolvm-system:controller](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L20-L39) | `{{ .Release.Namespace }}:controller` | +| ClusterRoleBinding | [topolvm-system:controller](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L41-L52) | `{{ .Release.Namespace }}:controller` | +| Role | [leader-election](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L54-L80) | **NO CHANGED** | +| RoleBinding | [leader-election](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L82-L94) | **NO CHANGED** | +| ClusterRole | [topolvm-external-provisioner-runner](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L96-L127) | **NO CHANGED** | +| ClusterRoleBinding | [topolvm-csi-provisioner-role](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L129-L150) | **NO CHANGED** | +| RoleBinding | [csi-provisioner-role-cfg](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L152-L164) | **NO CHANGED** | +| ClusterRole | [topolvm-external-attacher-runner](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L166-L185) | **NO CHANGED** | +| ClusterRoleBinding | [topolvm-csi-attacher-role](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L187-L198) | **NO CHANGED** | +| RoleBinding | [csi-attacher-role-cfg](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L210-L222) | **NO CHANGED** | +| ClusterRole | [topolvm-external-resizer-runner](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L224-L240) | **NO CHANGED** | +| ClusterRoleBinding | [topolvm-csi-resizer-role](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L242-L253) | **NO CHANGED** | +| Role | [external-resizer-cfg](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L255-L263) | **NO CHANGED** | +| RoleBinding | [csi-resizer-role-cfg](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L265-L277) | **NO CHANGED** | +| Service | [controller](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L280-L291) | `{{ template "topolvm.fullname" . }}-controller` | +| Deployment | [controller](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/controller.yaml#L293-L399) | `{{ template "topolvm.fullname" . }}-controller` | +| MutatingWebhookConfiguration | [topolvm-hook](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/mutatingwebhooks.yaml#L1-L63) | `{{ template "topolvm.fullname" . }}-hook` | +| ServiceAccount | [node](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L1-L5) | `{{ template "topolvm.fullname" . }}-node` | +| ClusterRole | [topolvm-system:node](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L7-L24) | `{{ .Release.Namespace }}:node` | +| ClusterRoleBinding | [topolvm-system:node](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L26-L37) | `{{ .Release.Namespace }}:node` | +| DaemonSet | [node](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/node.yaml#L40-L139) | `{{ template "topolvm.fullname" . }}-node` | +| StorageClass | [topolvm-provisioner](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/provisioner.yaml#L1-L9) | **NO CHANGED** | +| PodSecurityPolicy | [topolvm-node](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/psp.yaml#L1-L27) | `{{ template "topolvm.fullname" . }}-node` | +| PodSecurityPolicy | [topolvm-scheduler](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/psp.yaml#L29-L55) | `{{ template "topolvm.fullname" . }}-scheduler` | +| ServiceAccount | [topolvm-system](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/scheduler.yaml#L2-L6) | `{{ template "topolvm.fullname" . }}-scheduler` | +| Role | [psp:topolvm-scheduler](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/scheduler.yaml#L8-L17) | `psp:{{ template "topolvm.fullname" . }}-scheduler` | +| RoleBinding | [topolvm-scheduler:psp:topolvm-scheduler](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/base/scheduler.yaml#L19-L31) | `{{ template "topolvm.fullname" . }}-scheduler:psp:{{ template "topolvm.fullname" . }}-scheduler` | +| DaemonSet | [topolvm-scheduler](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/overlays/daemonset-scheduler/scheduler.yaml#L1-L54) | `{{ template "topolvm.fullname" . }}-scheduler` | +| Deployment | [topolvm-scheduler](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/overlays/deployment-scheduler/scheduler.yaml#L1-L36) | `{{ template "topolvm.fullname" . }}-scheduler` | +| Service | [topolvm-scheduler](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/overlays/deployment-scheduler/scheduler.yaml#L38-L49) | `{{ template "topolvm.fullname" . }}-scheduler` | +| ServiceAccount | [lvmd](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L2-L6) | `{{ template "topolvm.fullname" . }}-lvmd` | +| PodSecurityPolicy | [lvmd](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L8-L30) | `{{ template "topolvm.fullname" . }}-lvmd` | +| Role | [psp:lvmd](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L32-L41) | `psp:{{ template "topolvm.fullname" . }}-lvmd` | +| RoleBinding | [lvmd:psp:lvmd](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L43-L55) | `{{ template "topolvm.fullname" . }}-lvmd:psp:{{ template "topolvm.fullname" . }}-lvmd` | +| DaemonSet | [lvmd](https://github.com/syself/csi-topolvm/blob/v0.8.3/deploy/manifests/lvmd/lvmd.yaml#L57-L94) | `{{ template "topolvm.fullname" . }}-lvmd-{{ $lvmdidx }}` | diff --git a/docs/deprecated/rancher/README.md b/docs/deprecated/rancher/README.md index c90335cbd..c79d717a8 100644 --- a/docs/deprecated/rancher/README.md +++ b/docs/deprecated/rancher/README.md @@ -148,7 +148,7 @@ gcloud compute ssh --zone ${ZONE} worker1 # Install lvmd TOPOLVM_VERSION=0.6.0 sudo mkdir -p /opt/sbin -curl -sSLf https://github.com/topolvm/topolvm/releases/download/v${TOPOLVM_VERSION}/lvmd-${TOPOLVM_VERSION}.tar.gz | sudo tar xzf - -C /opt/sbin +curl -sSLf https://github.com/syself/csi-topolvm/releases/download/v${TOPOLVM_VERSION}/lvmd-${TOPOLVM_VERSION}.tar.gz | sudo tar xzf - -C /opt/sbin # Put configuration file sudo mkdir -p /etc/topolvm @@ -167,7 +167,7 @@ gcloud compute ssh --zone ${ZONE} worker2 # Install lvmd TOPOLVM_VERSION=0.6.0 sudo mkdir -p /opt/sbin -curl -sSLf https://github.com/topolvm/topolvm/releases/download/v${TOPOLVM_VERSION}/lvmd-${TOPOLVM_VERSION}.tar.gz | sudo tar xzf - -C /opt/sbin +curl -sSLf https://github.com/syself/csi-topolvm/releases/download/v${TOPOLVM_VERSION}/lvmd-${TOPOLVM_VERSION}.tar.gz | sudo tar xzf - -C /opt/sbin # Put configuration file sudo mkdir -p /etc/topolvm @@ -183,17 +183,17 @@ exit ## 5. Deploy TopoLVM Before deploying TopoLVM, install `kustomize` by following the link below. -https://kubernetes-sigs.github.io/kustomize/installation/ + ```bash TOPOLVM_VERSION=0.6.0 -kustomize build https://github.com/topolvm/topolvm/deploy/manifests/overlays/daemonset-scheduler?ref=v${TOPOLVM_VERSION} | kubectl apply -f - +kustomize build https://github.com/syself/csi-topolvm/deploy/manifests/overlays/daemonset-scheduler?ref=v${TOPOLVM_VERSION} | kubectl apply -f - kubectl apply -f https://raw.githubusercontent.com/topolvm/topolvm/v${TOPOLVM_VERSION}/deploy/manifests/base/certificates.yaml ``` ## 6. Configure `topolvm-scheduler` -### Update `topolvm-scheduler` manifest +### Update `topolvm-scheduler` manifest First, `master` has the following label and taint. @@ -318,6 +318,7 @@ spec: claimName: topolvm-pvc EOF ``` + ## 8. Cleanup Do not forget to delete GCE instances. diff --git a/docs/proposals/pvcs-smaller-than-1gi.md b/docs/proposals/pvcs-smaller-than-1gi.md index d005aae59..0251f3359 100644 --- a/docs/proposals/pvcs-smaller-than-1gi.md +++ b/docs/proposals/pvcs-smaller-than-1gi.md @@ -22,18 +22,18 @@ last-updated: 2023-09-26 - [Summary](#summary) - [Motivation](#motivation) - - [Goals](#goals) + - [Goals](#goals) - [Proposal](#proposal) - - [Decision Outcome](#decision-outcome) - - [Open Questions](#open-questions) + - [Decision Outcome](#decision-outcome) + - [Open Questions](#open-questions) - [Design Details](#design-details) - - [How to pass byte-level capacities to TopoLVM?](#how-to-pass-byte-level-capacities-to-topolvm) - - [How to get around the `<<30`/`>>30` bit shifts](#how-to-get-around-the-3030-bit-shifts) - - [Impact Analysis on Existing PVC creation](#impact-analysis-on-existing-pvc-creation) - - [Changing how `LogicalVolumeService` is creating `LogicalVolumeSpec`](#changing-how-logicalvolumeservice-is-creating-logicalvolumespec) - - [Modifying `controllers/logicalvolume_controller` to create correct LVMD calls via gRPC](#modifying-controllerslogicalvolumecontroller-to-create-correct-lvmd-calls-via-grpc) - - [Switching all occurrences of `uint64` to `int64` in lvmd and change `size_gb` to `size` in protobuf messages.](#switching-all-occurrences-of-uint64-to-int64-in-lvmd-and-change-sizegb-to-size-in-protobuf-messages) - - [Dealing with less than 1Gi storage in the TopoLVM scheduler prioritization](#dealing-with-less-than-1gi-storage-in-the-topolvm-scheduler-prioritization) + - [How to pass byte-level capacities to TopoLVM?](#how-to-pass-byte-level-capacities-to-topolvm) + - [How to get around the `<<30`/`>>30` bit shifts](#how-to-get-around-the-3030-bit-shifts) + - [Impact Analysis on Existing PVC creation](#impact-analysis-on-existing-pvc-creation) + - [Changing how `LogicalVolumeService` is creating `LogicalVolumeSpec`](#changing-how-logicalvolumeservice-is-creating-logicalvolumespec) + - [Modifying `controllers/logicalvolume_controller` to create correct LVMD calls via gRPC](#modifying-controllerslogicalvolumecontroller-to-create-correct-lvmd-calls-via-grpc) + - [Switching all occurrences of `uint64` to `int64` in lvmd and change `size_gb` to `size` in protobuf messages.](#switching-all-occurrences-of-uint64-to-int64-in-lvmd-and-change-sizegb-to-size-in-protobuf-messages) + - [Dealing with less than 1Gi storage in the TopoLVM scheduler prioritization](#dealing-with-less-than-1gi-storage-in-the-topolvm-scheduler-prioritization) - [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy) - [Deprecation / Removal](#deprecation--removal) @@ -46,7 +46,7 @@ We need to remove this sizing limitation. ## Motivation -For most users of TopoLVM, local nodes are the focus. +For most users of TopoLVM, local nodes are the focus. While TopoLVM was designed to be run in datacenters where the lowest provisional unit might not be an issue, edge use cases require us to create many volumes in a small amount of storage which may only be a few gigabytes. To allow TopoLVM for proper use on edge devices and small form-factor use cases of Pods, we need to allow storage capacities that can supply storage lower than 1GB. @@ -60,6 +60,7 @@ To allow TopoLVM for proper use on edge devices and small form-factor use cases 1. TopoLVM administrator installs TopoLVM as usual 2. Cluster user creates PVCs with a Storage Class backed by TopoLVM following [the process of PVC creation during dynamic provisioning](../design.md#how-dynamic-provisioning-works): + ```bash $ cat <>30` bit shifts?](#how-to-get-around-the-3030-bit-shifts) +2. [How to get around the `<<30`/`>>30` bit shifts?](#how-to-get-around-the-3030-bit-shifts) This will allow us to use code paths in TopoLVM that do not require comparisons with Gi-level precision. We are showcasing how it is possible to get around the bitshift and how to replace it with byte-level comparisons. @@ -109,16 +112,17 @@ Additionally, as a result of an [Impact Analysis of the code path when creating 1. **Any request/response made with lvmd using a `size_gb` field needs to be changed to a different `size` because otherwise we cannot communicate less than 1Gi capacities to `lvmd`.** 2. **The [current prioritisation algorithm within the TopoLVM Scheduler Extension](../topolvm-scheduler.md#prioritize) needs to be adjusted and its current version needs to specify a limitation when working with storage less than 1Gi** -### Code Changes related to the API +### Code Changes related to the API We are proposing how to change the current codebase [considering the breaking changes in the API](#api-changes): + - How to deal with breaking changes in LVMD? - - [Switching all occurrences of `uint64` to `int64` in lvmd and change `size_gb` to `size` in protobuf messages.](#switching-all-occurrences-of-uint64-to-int64-in-lvmd-and-change-sizegb-to-size-in-protobuf-messages) + - [Switching all occurrences of `uint64` to `int64` in lvmd and change `size_gb` to `size` in protobuf messages.](#switching-all-occurrences-of-uint64-to-int64-in-lvmd-and-change-sizegb-to-size-in-protobuf-messages) - How to touch important components which are using bit shifts that were previously using `size_gb` - - [Changing how `LogicalVolumeService` is creating `LogicalVolumeSpec`](#changing-how-logicalvolumeservice-is-creating-logicalvolumespec) - - [Modifying `controllers/logicalvolume_controller` to create correct LVMD calls via gRPC](#modifying-controllerslogicalvolumecontroller-to-create-correct-lvmd-calls-via-grpc) + - [Changing how `LogicalVolumeService` is creating `LogicalVolumeSpec`](#changing-how-logicalvolumeservice-is-creating-logicalvolumespec) + - [Modifying `controllers/logicalvolume_controller` to create correct LVMD calls via gRPC](#modifying-controllerslogicalvolumecontroller-to-create-correct-lvmd-calls-via-grpc) - How to deal with breaking changes in the TopoLVM Scheduler? - - [Dealing with less than 1Gi storage in the TopoLVM scheduler prioritization](#dealing-with-less-than-1gi-storage-in-the-topolvm-scheduler-prioritization) + - [Dealing with less than 1Gi storage in the TopoLVM scheduler prioritization](#dealing-with-less-than-1gi-storage-in-the-topolvm-scheduler-prioritization) ### Decision Outcome @@ -134,7 +138,6 @@ Under the assumption that the change is deemed useful or accepted, we still need ## Design Details - ### How to pass byte-level capacities to TopoLVM? The answer to this question lies in `topolvm-controller` and `topolvm-node` when called by Kubernetes. @@ -146,15 +149,15 @@ With every call made to a volume request (e.g. `CreateVolume`), a `CapacityRange // `required_bytes` and `limit_bytes` SHALL be set to the same value. At // least one of the these fields MUST be specified. type CapacityRange struct { - // Volume MUST be at least this big. This field is OPTIONAL. - // A value of 0 is equal to an unspecified field value. - // The value of this field MUST NOT be negative. - RequiredBytes int64 `protobuf:"varint,1,opt,name=required_bytes,json=requiredBytes,proto3" json:"required_bytes,omitempty"` - // Volume MUST not be bigger than this. This field is OPTIONAL. - // A value of 0 is equal to an unspecified field value. - // The value of this field MUST NOT be negative. - LimitBytes int64 `protobuf:"varint,2,opt,name=limit_bytes,json=limitBytes,proto3" json:"limit_bytes,omitempty"` - // ... + // Volume MUST be at least this big. This field is OPTIONAL. + // A value of 0 is equal to an unspecified field value. + // The value of this field MUST NOT be negative. + RequiredBytes int64 `protobuf:"varint,1,opt,name=required_bytes,json=requiredBytes,proto3" json:"required_bytes,omitempty"` + // Volume MUST not be bigger than this. This field is OPTIONAL. + // A value of 0 is equal to an unspecified field value. + // The value of this field MUST NOT be negative. + LimitBytes int64 `protobuf:"varint,2,opt,name=limit_bytes,json=limitBytes,proto3" json:"limit_bytes,omitempty"` + // ... } ``` @@ -162,28 +165,27 @@ As a result, all capacity ranges in CSI are coming from `req.GetCapacityRange(). **Important here: both are raw byte counts in the form of `int64`.** - _However_, We currently convert all request capacity with the `convertRequestCapacity` method ```go func convertRequestCapacity(requestBytes, limitBytes int64) (int64, error) { - if requestBytes < 0 { - return 0, errors.New("required capacity must not be negative") - } - if limitBytes < 0 { - return 0, errors.New("capacity limit must not be negative") - } - - if limitBytes != 0 && requestBytes > limitBytes { - return 0, fmt.Errorf( - "requested capacity exceeds limit capacity: request=%d limit=%d", requestBytes, limitBytes, - ) - } - - if requestBytes == 0 { - return 1, nil - } - return (requestBytes-1)>>30 + 1, nil + if requestBytes < 0 { + return 0, errors.New("required capacity must not be negative") + } + if limitBytes < 0 { + return 0, errors.New("capacity limit must not be negative") + } + + if limitBytes != 0 && requestBytes > limitBytes { + return 0, fmt.Errorf( + "requested capacity exceeds limit capacity: request=%d limit=%d", requestBytes, limitBytes, + ) + } + + if requestBytes == 0 { + return 1, nil + } + return (requestBytes-1)>>30 + 1, nil } ``` @@ -200,25 +202,25 @@ As one can see below we can simply get around the bitshift by using the full byt package main import ( - "fmt" + "fmt" - . "k8s.io/apimachinery/pkg/api/resource" + . "k8s.io/apimachinery/pkg/api/resource" ) func main() { - var oldDefGi = int64(1) - var newDefGi = MustParse(fmt.Sprintf("%vGi", oldDefGi)) - var someGiBytes = int64(1073741824) + var oldDefGi = int64(1) + var newDefGi = MustParse(fmt.Sprintf("%vGi", oldDefGi)) + var someGiBytes = int64(1073741824) - var oldDefMi = int64(500) - var newDefMi = MustParse(fmt.Sprintf("%vMi", oldDefMi)) - var someMiBytes = int64(524288000) + var oldDefMi = int64(500) + var newDefMi = MustParse(fmt.Sprintf("%vMi", oldDefMi)) + var someMiBytes = int64(524288000) - println(someGiBytes == oldDefGi<<30) // always true - println(NewQuantity(someGiBytes, BinarySI).Cmp(newDefGi) == 0) // always true + println(someGiBytes == oldDefGi<<30) // always true + println(NewQuantity(someGiBytes, BinarySI).Cmp(newDefGi) == 0) // always true - println(someMiBytes == oldDefMi<<30) // always false - println(NewQuantity(someMiBytes, BinarySI).Cmp(newDefMi) == 0) // always true + println(someMiBytes == oldDefMi<<30) // always false + println(NewQuantity(someMiBytes, BinarySI).Cmp(newDefMi) == 0) // always true } ``` @@ -227,6 +229,7 @@ At the same time we already make use of the serialized Capacity in `LogicalVolum Since all CSI Driver values already work with bytes, we have no trouble taking in the new data, we will just accept more ranges. We will make 2 changes to LVMD: + 1. We will accept a breaking change in `lvmd` that moves from `size_gb` to a more flexible `size` when relating to request / response sizes. 2. We will move from `uint64` comparisons in `lvmd` to `int64` comparisons. This is the same level of precision as within CSI driver specifications. @@ -234,7 +237,6 @@ Together with changes in LVMD we can easily replace all bit shifted comparisons Within tests, we will write a small helper function that easily allows defining `int64` for any amount of Gi that we previously used bitshifts for. - ### Impact Analysis on Existing PVC creation When following the [architecture of a PVC creation during dynamic provisioning](../design.md#how-dynamic-provisioning-works), we can observe the following steps: @@ -258,7 +260,7 @@ When following the [architecture of a PVC creation during dynamic provisioning]( 5. > `topolvm-node` sends a volume create request to `lvmd`. **BREAKING**: We need to make sure that the request sent to lvmd via gRPC is able to convey capacities less than 1Gi, which is currently not possible. - Similarly, all responses must be able to work with less than 1Gi capacities. + Similarly, all responses must be able to work with less than 1Gi capacities. More details on this can be found in the section on the [Impact on LVMD protocol changes](#switching-all-occurrences-of-uint64-to-int64-in-lvmd-and-change-sizegb-to-size-in-protobuf-messages). 6. > `lvmd` creates an LVM logical volume as requested. @@ -281,7 +283,6 @@ When following the [architecture of a PVC creation during dynamic provisioning]( No changes are expected after sizing has been completed - Additionally, any TopoLVM user making use of the [scheduler extension](../topolvm-scheduler.md) will also be impacted by the following changes: 1. > `topolvm-node` exposes free storage capacity as `capacity.topolvm.io/` annotation of each Node. @@ -292,8 +293,9 @@ Additionally, any TopoLVM user making use of the [scheduler extension](../topolv > - The value of the annotation is the sum of the storage capacity requests of unbound TopoLVM PVCs for each volume group referenced by the pod. This logic currently rounds up to the next GB value and needs to be modified from `requested = ((req.Value()-1)>>30 + 1) << 30` to `requested = req.Value()` - for the [Mutating Webhook](https://github.com/topolvm/topolvm/blob/main/hook/mutate_pod.go#L248) in all places. + for the [Mutating Webhook](https://github.com/syself/csi-topolvm/blob/main/hook/mutate_pod.go#L248) in all places. Otherwise, the capacity annotation will be incorrect. + ```go requested int64 := topolvm.DefaultSize if req, ok := volumeClaimTemplate.Spec.Resources.Requests[corev1.ResourceStorage]; ok { @@ -338,7 +340,7 @@ Calls will directly include the request / response bytes like so: will have to have `SizeGb` replaced with `Size` and their raw values so we can get rid of the bitshift. This is only possible by introducing a breaking change to LVMD protocol. -### Switching all occurrences of `uint64` to `int64` in lvmd and change `size_gb` to `size` in protobuf messages. +### Switching all occurrences of `uint64` to `int64` in lvmd and change `size_gb` to `size` in protobuf messages Since lvmd currently includes various messages with a `uint64 size_gb` field, we should think of how to properly serialize new the capacity information in a scalable way. Here we have an inbuilt option with the kubernetes quantities as well. @@ -353,14 +355,14 @@ we could simply remove this limitation and pass requestBytes natively as its byt repeated string tags = 3; // Tags to add to the volume during creation string device_class = 4; string lvcreate_option_class = 5; - + + int64 size = 6; // Volume size in canonical bytes. } ``` Note that SizeGB is used as uint64 where we cast down to int64. This means that potentially, if someone had a volume before this change greater than `9.223.372.036.854.775.807 Gi`, he would now experience an overflow -that would break lvmd. *However*, we need to be aware that the CSIDriver capacity-ranges at most support values up to int64 limits, +that would break lvmd. _However_, we need to be aware that the CSIDriver capacity-ranges at most support values up to int64 limits, so we do not break any currently known path. This change from `size_gb` to `size` can be reused across all Requests/Responses and only needs minor adjustment. @@ -376,7 +378,7 @@ We can replace all occurrences during the parsing process to get arround this: +/- size int64 +/- free int64 } - + func (u *vg) UnmarshalJSON(data []byte) error { type vgInternal struct { Name string `json:"vg_name"` @@ -384,15 +386,15 @@ We can replace all occurrences during the parsing process to get arround this: Size string `json:"vg_size"` Free string `json:"vg_free"` } - + var temp vgInternal if err := json.Unmarshal(data, &temp); err != nil { return err } - + u.name = temp.Name u.uuid = temp.UUID - + var convErr error +/- u.size, convErr = strconv.ParseInt(temp.Size, 10, 64) if convErr != nil { @@ -402,12 +404,12 @@ We can replace all occurrences during the parsing process to get arround this: if convErr != nil { return convErr } - + return nil } ``` -Of course the same adjustments from `uint64` to `int64` be done for all methods using these structs and similar structs like `lv`. +Of course the same adjustments from `uint64` to `int64` be done for all methods using these structs and similar structs like `lv`. Then they can be reused in `lvmd/lvservice` and `lvmd/vgservice` to simplify the calls from uint64 bitshift comparisons to simple byte comparisons: The resulting `CreateLV` call for example would look almost exactly like the original `CreateLV`: @@ -476,38 +478,38 @@ Our simplest suggestion here, in order to not break anything, is to clearly mark a new lower bound for less than 1Gi storage in the method `capacityToScore`: ```go -// DEPRECATED: capacityToScore uses gi precision and a divisor as per formula +// DEPRECATED: capacityToScore uses gi precision and a divisor as per formula // min(10, max(0, log2(capacity >> 30 / divisor))) for (capacity>>30)>0 // Its limited to score capacities 1Gi>capacity>0 with 1 without any detailed precision. // Note that this is a legacy scheduler and should not be used for volumes smaller 1Gi due to this limitation. func capacityToScore(capacity uint64, divisor float64) int { -+/- gb := capacity >> 30 ++/- gb := capacity >> 30 +/- -+/- // we have a capacity that is greater than 0 but less than 1Gi, apply score 1 -+/- if capacity > 0 && gb == 0 { -+/- return 1 -+/- } - // avoid logarithm of zero, which diverges to negative infinity. - if gb == 0 { - return 0 - } - - converted := int(math.Log2(float64(gb) / divisor)) - switch { - case converted < 0: - return 0 - case converted > 10: - return 10 - default: - return converted - } ++/- // we have a capacity that is greater than 0 but less than 1Gi, apply score 1 ++/- if capacity > 0 && gb == 0 { ++/- return 1 ++/- } + // avoid logarithm of zero, which diverges to negative infinity. + if gb == 0 { + return 0 + } + + converted := int(math.Log2(float64(gb) / divisor)) + switch { + case converted < 0: + return 0 + case converted > 10: + return 10 + default: + return converted + } } ``` This leads to every free Capacity between 1 byte and 1GB free to get the score of `1`, which means they will be scored the same. The only downside to this algorithm is that its precision is 1GB. So if there are 2 nodes with `500Mi` and `700Mi` free storage, both would receive the same score. -The only way to get around this is by creating a new scoring algorithm side-by-side and allow users to switch. +The only way to get around this is by creating a new scoring algorithm side-by-side and allow users to switch. However, this proposal will only focus on solving the existing scheduling mechanism and will thus recommend to simply make the old scheduler work. A separate proposal should be created for the new scheduling algorithm. @@ -548,4 +550,4 @@ We can then easily remove the legacy `size_gb` field in a future release by maki string lvcreate_option_class = 5; + int64 size = 6; // Volume size in bytes } -``` \ No newline at end of file +``` diff --git a/docs/snapshot-and-restore.md b/docs/snapshot-and-restore.md index 7b5b4058e..99d287f38 100644 --- a/docs/snapshot-and-restore.md +++ b/docs/snapshot-and-restore.md @@ -1,12 +1,13 @@ # Snapshot and Restore -See also [the proposal of the functionality](https://github.com/topolvm/topolvm/blob/main/docs/proposals/thin-snapshots-restore.md). +See also [the proposal of the functionality](https://github.com/syself/csi-topolvm/blob/main/docs/proposals/thin-snapshots-restore.md). ## Getting Started ### Prerequisites You need to create a thin pool of LVM beforehand, because TopoLVM doesn't create one. For example: + ``` lvcreate -T -n pool0 -L 4G myvg1 ``` @@ -16,6 +17,7 @@ You also need to install the CRDs and the controller for volume snapshots. Pleas ### Set up a Device Class Change your lvmd settings to use the thin pool you've created. For example, if you are using the Helm charts, modify your values.yaml as follows: + ```yaml lvmd: deviceClasses: @@ -33,6 +35,7 @@ lvmd: ### Set up a Storage Class Create a storage class for the DeviceClass for the thin pool. For example, if you are using the Helm charts, modify your values.yaml as follows: + ```yaml storageClasses: # ... @@ -50,7 +53,7 @@ storageClasses: ### Deploy TopoLVM -Deploy TopoLVM with the settings you updated above. See also the [Getting Started](https://github.com/topolvm/topolvm/blob/main/docs/getting-started.md) guide. +Deploy TopoLVM with the settings you updated above. See also the [Getting Started](https://github.com/syself/csi-topolvm/blob/main/docs/getting-started.md) guide. Run the following command to deploy `my-pvc` and `my-pod`, which use `topolvm-provisioner-thin`. @@ -92,6 +95,7 @@ EOF ``` Write some data to the volume: + ```sh $ kubectl exec -it my-pod -- bash root@my-pod:/# echo hello > /data/world @@ -177,6 +181,7 @@ EOF ``` And check the content of the volume: + ```sh $ kubectl exec -it my-pod2 -- cat /data/world hello @@ -184,5 +189,5 @@ hello ## See Also -- [The proposal of the functionality](https://github.com/topolvm/topolvm/blob/main/docs/proposals/thin-snapshots-restore.md) +- [The proposal of the functionality](https://github.com/syself/csi-topolvm/blob/main/docs/proposals/thin-snapshots-restore.md) - Issue [#827](https://github.com/topolvm/topolvm/issues/827) diff --git a/go.mod b/go.mod index a1f246c2a..a445e65a5 100644 --- a/go.mod +++ b/go.mod @@ -1,61 +1,57 @@ -module github.com/topolvm/topolvm +module github.com/syself/csi-topolvm -go 1.20 +go 1.22 require ( - github.com/container-storage-interface/spec v1.6.0 - github.com/go-logr/logr v1.2.4 - github.com/go-logr/zapr v1.2.4 + github.com/container-storage-interface/spec v1.9.0 + github.com/go-logr/logr v1.4.1 + github.com/go-logr/zapr v1.3.0 github.com/golang/protobuf v1.5.4 - github.com/google/go-cmp v0.5.9 - github.com/kubernetes-csi/csi-test/v5 v5.0.0 + github.com/google/go-cmp v0.6.0 + github.com/kubernetes-csi/csi-test/v5 v5.2.0 github.com/kubernetes-csi/external-snapshotter/client/v6 v6.3.0 - github.com/onsi/ginkgo/v2 v2.11.0 - github.com/onsi/gomega v1.27.10 - github.com/prometheus/client_golang v1.16.0 - github.com/prometheus/client_model v0.4.0 - github.com/prometheus/common v0.44.0 - github.com/pseudomuto/protoc-gen-doc v1.5.0 - github.com/spf13/cobra v1.7.0 + github.com/onsi/ginkgo/v2 v2.17.1 + github.com/onsi/gomega v1.33.0 + github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_model v0.6.1 + github.com/prometheus/common v0.53.0 + github.com/pseudomuto/protoc-gen-doc v1.5.1 + github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.17.0 - go.uber.org/zap v1.25.0 + go.uber.org/zap v1.26.0 golang.org/x/sys v0.19.0 - google.golang.org/grpc v1.58.3 + google.golang.org/grpc v1.63.2 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.33.0 - k8s.io/api v0.28.6 - k8s.io/apimachinery v0.28.6 - k8s.io/client-go v0.28.6 - k8s.io/klog/v2 v2.100.1 - k8s.io/mount-utils v0.28.6 - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 - sigs.k8s.io/controller-runtime v0.16.3 - sigs.k8s.io/controller-tools v0.13.0 - sigs.k8s.io/yaml v1.3.0 + k8s.io/api v0.29.4 + k8s.io/apimachinery v0.29.4 + k8s.io/client-go v0.29.4 + k8s.io/klog/v2 v2.120.1 + k8s.io/mount-utils v0.29.4 + k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 + sigs.k8s.io/controller-runtime v0.17.2 + sigs.k8s.io/controller-tools v0.14.0 + sigs.k8s.io/yaml v1.4.0 ) require ( github.com/Masterminds/semver v1.4.2 // indirect github.com/Masterminds/sprig v2.15.0+incompatible // indirect - github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/aokoli/goutils v1.0.1 // indirect - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -64,12 +60,11 @@ require ( github.com/gobuffalo/flect v1.0.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/cel-go v0.16.1 // indirect + github.com/google/cel-go v0.17.8 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.0.0 // indirect @@ -80,8 +75,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -90,7 +84,7 @@ require ( github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/pseudomuto/protokit v0.2.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -99,10 +93,6 @@ require ( github.com/spf13/cast v1.5.1 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - go.etcd.io/etcd/api/v3 v3.5.9 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect - go.etcd.io/etcd/client/v3 v3.5.9 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect @@ -114,30 +104,28 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.14.0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/sync v0.5.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.20.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.28.3 // indirect - k8s.io/apiserver v0.28.3 // indirect - k8s.io/component-base v0.28.3 // indirect - k8s.io/kms v0.28.3 // indirect - k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect + k8s.io/apiextensions-apiserver v0.29.4 // indirect + k8s.io/apiserver v0.29.4 // indirect + k8s.io/component-base v0.29.4 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/go.sum b/go.sum index 4b0506dc0..a015d09b5 100644 --- a/go.sum +++ b/go.sum @@ -17,15 +17,12 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -45,17 +42,10 @@ github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITg github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.15.0+incompatible h1:0gSxPGWS9PAr7U2NsQ2YQg6juRDINkUyuvbb4b2Xm8w= github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/aokoli/goutils v1.0.1 h1:7fpzNGoJ3VA8qcrm++XEE1QUe0mIwNeLa02Nwq7RDkg= github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -63,7 +53,6 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -73,25 +62,14 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 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/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/container-storage-interface/spec v1.6.0 h1:vwN9uCciKygX/a0toYryoYD5+qI9ZFeAMuhEEKO+JBA= -github.com/container-storage-interface/spec v1.6.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s= -github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/container-storage-interface/spec v1.9.0 h1:zKtX4STsq31Knz3gciCYCi1SXtO2HJDecIjDVboYavY= +github.com/container-storage-interface/spec v1.9.0/go.mod h1:ZfDu+3ZRyeVqxZM0Ds19MVLkN2d1XJ5MAfi1L3VjlT0= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -99,54 +77,46 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.3.0-java/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -159,7 +129,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -180,9 +149,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/cel-go v0.16.1 h1:3hZfSNiAU3KOiNtxuFXVp5WFy4hf/Ly3Sa4/7F8SXNo= -github.com/google/cel-go v0.16.1/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= +github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= +github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -195,10 +163,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -215,41 +182,29 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0 h1:pO2K/gKgKaat5LdpAhxhluX2GPQMaI3W5FUz/I/UnWk= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -262,12 +217,13 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kubernetes-csi/csi-test/v5 v5.0.0 h1:GJ0M+ppcKgWhafXH3B2Ssfw1Egzly9GlMx3JOQApekM= -github.com/kubernetes-csi/csi-test/v5 v5.0.0/go.mod h1:jVEIqf8Nv1roo/4zhl/r6Tc68MAgRX/OQSQK0azTHyo= +github.com/kubernetes-csi/csi-test/v5 v5.2.0 h1:Z+sdARWC6VrONrxB24clCLCmnqCnZF7dzXtzx8eM35o= +github.com/kubernetes-csi/csi-test/v5 v5.2.0/go.mod h1:o/c5w+NU3RUNE+DbVRhEUTmkQVBGk+tFOB2yPXT8teo= github.com/kubernetes-csi/external-snapshotter/client/v6 v6.3.0 h1:qS4r4ljINLWKJ9m9Ge3Q3sGZ/eIoDVDT2RhAdQFHb1k= github.com/kubernetes-csi/external-snapshotter/client/v6 v6.3.0/go.mod h1:oGXx2XTEzs9ikW2V6IC1dD8trgjRsS/Mvc2JRiC618Y= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -277,10 +233,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= @@ -294,64 +248,51 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007 h1:28i1IjGcx8AofiB4N3q5Yls55VEaitzuEPkFJEVgGkA= github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/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.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= +github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/pseudomuto/protoc-gen-doc v1.5.0 h1:pHZp0MEiT68jrZV8js8BS7E9ZEnlSLegoQbbtXj5lfo= -github.com/pseudomuto/protoc-gen-doc v1.5.0/go.mod h1:exDTOVwqpp30eV/EDPFLZy3Pwr2sn6hBC1WIYH/UbIg= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/pseudomuto/protoc-gen-doc v1.5.1 h1:Ah259kcrio7Ix1Rhb6u8FCaOkzf9qRBqXnvAufg061w= +github.com/pseudomuto/protoc-gen-doc v1.5.1/go.mod h1:XpMKYg6zkcpgfpCfQ8GcWBDRtRxOmMR5w7pz4Xo+dYM= github.com/pseudomuto/protokit v0.2.0 h1:hlnBDcy3YEDXH7kc9gV+NLaN0cDzhDvD1s7Y6FZ8RpM= github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= @@ -361,7 +302,6 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -374,33 +314,17 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs= -go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k= -go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2IGsE= -go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= -go.etcd.io/etcd/client/v2 v2.305.9 h1:YZ2OLi0OvR0H75AcgSUajjd5uqKDKocQUqROTG11jIo= -go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E= -go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA= -go.etcd.io/etcd/pkg/v3 v3.5.9 h1:6R2jg/aWd/zB9+9JxmijDKStGJAPFsX3e6BeJkMi6eQ= -go.etcd.io/etcd/raft/v3 v3.5.9 h1:ZZ1GIHoUlHsn0QVqiRysAm3/81Xx7+i2d7nSdWxlOiI= -go.etcd.io/etcd/server/v3 v3.5.9 h1:vomEmmxeztLtS5OEH7d0hBAg4cjVIu9wXuNzUZx2ZA0= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 h1:xFSRQBbXF6VvYRf2lqMJXxoB72XI1K/azav8TekHHSw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= @@ -415,19 +339,14 @@ go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJ go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= -golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -473,13 +392,11 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -500,7 +417,6 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -510,13 +426,8 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -528,24 +439,22 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -554,10 +463,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -578,23 +484,15 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -609,6 +507,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -661,16 +560,13 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -702,10 +598,10 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -728,7 +624,6 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -738,17 +633,16 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201209185603-f92720507ed4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -762,14 +656,11 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -784,8 +675,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -793,18 +682,13 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -819,41 +703,38 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.28.6 h1:yy6u9CuIhmg55YvF/BavPBBXB+5QicB64njJXxVnzLo= -k8s.io/api v0.28.6/go.mod h1:AM6Ys6g9MY3dl/XNaNfg/GePI0FT7WBGu8efU/lirAo= -k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= -k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= -k8s.io/apimachinery v0.28.6 h1:RsTeR4z6S07srPg6XYrwXpTJVMXsjPXn0ODakMytSW0= -k8s.io/apimachinery v0.28.6/go.mod h1:QFNX/kCl/EMT2WTSz8k4WLCv2XnkOLMaL8GAVRMdpsA= -k8s.io/apiserver v0.28.3 h1:8Ov47O1cMyeDzTXz0rwcfIIGAP/dP7L8rWbEljRcg5w= -k8s.io/apiserver v0.28.3/go.mod h1:YIpM+9wngNAv8Ctt0rHG4vQuX/I5rvkEMtZtsxW2rNM= -k8s.io/client-go v0.28.6 h1:Gge6ziyIdafRchfoBKcpaARuz7jfrK1R1azuwORIsQI= -k8s.io/client-go v0.28.6/go.mod h1:+nu0Yp21Oeo/cBCsprNVXB2BfJTV51lFfe5tXl2rUL8= -k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= -k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= -k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kms v0.28.3 h1:jYwwAe96XELNjYWv1G4kNzizcFoZ50OOElvPansbw70= -k8s.io/kms v0.28.3/go.mod h1:kSMjU2tg7vjqqoWVVCcmPmNZ/CofPsoTbSxAipCvZuE= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= -k8s.io/mount-utils v0.28.6 h1:Ehe42uw7mjJume2pLt37CZl7oSIjiKGCngDCs5/otjo= -k8s.io/mount-utils v0.28.6/go.mod h1:pAnxhVbtMafSzAmFBgIfCdbM52+ObB7bBIN4MpuWk2o= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/api v0.29.4 h1:WEnF/XdxuCxdG3ayHNRR8yH3cI1B/llkWBma6bq4R3w= +k8s.io/api v0.29.4/go.mod h1:DetSv0t4FBTcEpfA84NJV3g9a7+rSzlUHk5ADAYHUv0= +k8s.io/apiextensions-apiserver v0.29.4 h1:M7hbuHU/ckbibR7yPbe6DyNWgTFKNmZDbdZKD8q1Smk= +k8s.io/apiextensions-apiserver v0.29.4/go.mod h1:TTDC9fB+0kHY2rogf5hgBR03KBKCwED+GHUsXGpR7SM= +k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q= +k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= +k8s.io/apiserver v0.29.4 h1:wPwGOO58GQOpRiZu59P5eRoDcB7QtV+QBglkRiXwCiM= +k8s.io/apiserver v0.29.4/go.mod h1:VqTF9t98HVfhKZVRohCPezsdUt9u2g3bHKftxGcXoRo= +k8s.io/client-go v0.29.4 h1:79ytIedxVfyXV8rpH3jCBW0u+un0fxHDwX5F9K8dPR8= +k8s.io/client-go v0.29.4/go.mod h1:kC1thZQ4zQWYwldsfI088BbK6RkxK+aF5ebV8y9Q4tk= +k8s.io/component-base v0.29.4 h1:xeKzuuHI/1tjleu5jycDAcYbhAxeGHCQBZUY2eRIkOo= +k8s.io/component-base v0.29.4/go.mod h1:pYjt+oEZP9gtmwSikwAJgfSBikqKX2gOqRat0QjmQt0= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/mount-utils v0.29.4 h1:tW/URea4gtXlaVW7VObr52NQhS+z3SXTg1GUaFZjRL4= +k8s.io/mount-utils v0.29.4/go.mod h1:SHUMR9n3b6tLgEmlyT36cL6fV6Sjwa5CJhc0guCXvb0= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 h1:ao5hUqGhsqdm+bYbjH/pRkCs0unBGe9UyDahzs9zQzQ= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 h1:trsWhjU5jZrx6UvFu4WzQDrN7Pga4a7Qg+zcfcj64PA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2/go.mod h1:+qG7ISXqCDVVcyO8hLn12AKVYYUjM7ftlqsqmrhMZE0= -sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= -sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= -sigs.k8s.io/controller-tools v0.13.0 h1:NfrvuZ4bxyolhDBt/rCZhDnx3M2hzlhgo5n3Iv2RykI= -sigs.k8s.io/controller-tools v0.13.0/go.mod h1:5vw3En2NazbejQGCeWKRrE7q4P+CW8/klfVqP8QZkgA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4= +sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= +sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= +sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/client/client.go b/internal/client/client.go index 85681e6f8..843b7804a 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -4,9 +4,7 @@ import ( "context" "fmt" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -15,15 +13,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -const ( - kind = "LogicalVolume" - kindList = "LogicalVolumeList" -) - -var ( - group = topolvmv1.GroupVersion.Group -) - type wrappedReader struct { client client.Reader scheme *runtime.Scheme @@ -39,74 +28,24 @@ func NewWrappedReader(c client.Reader, s *runtime.Scheme) client.Reader { } func (c *wrappedReader) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Get(ctx, key, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Get(ctx, key, obj, opts...) case *metav1.PartialObjectMetadata: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Get(ctx, key, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Get(ctx, key, obj, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.scheme.Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - if err := c.client.Get(ctx, key, u, opts...); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return c.scheme.Convert(u, obj, nil) - } return c.client.Get(ctx, key, obj, opts...) } return c.client.Get(ctx, key, obj, opts...) } func (c *wrappedReader) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { - gvk := list.GetObjectKind().GroupVersionKind() - switch o := list.(type) { + switch list.(type) { case *unstructured.UnstructuredList: - if gvk.Group == group && gvk.Kind == kindList && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kindList)) - err := c.client.List(ctx, list, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kindList)) - return err - } return c.client.List(ctx, list, opts...) case *metav1.PartialObjectMetadataList: - if gvk.Group == group && gvk.Kind == kindList && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kindList)) - err := c.client.List(ctx, list, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kindList)) - return err - } return c.client.List(ctx, list, opts...) case *topolvmv1.LogicalVolumeList: - if topolvm.UseLegacy() { - l := new(topolvmlegacyv1.LogicalVolumeList) - if err := c.client.List(ctx, l, opts...); err != nil { - return err - } - u := &unstructured.UnstructuredList{} - if err := c.scheme.Convert(l, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kindList)) - return c.scheme.Convert(u, list, nil) - } return c.client.List(ctx, list, opts...) } return c.client.List(ctx, list, opts...) @@ -135,95 +74,36 @@ func (c *wrappedClient) List(ctx context.Context, list client.ObjectList, opts . } func (c *wrappedClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Create(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Create(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return c.client.Create(ctx, obj, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - if err := c.client.Create(ctx, u, opts...); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return c.client.Scheme().Convert(u, obj, nil) - } return c.client.Create(ctx, obj, opts...) } return c.client.Create(ctx, obj, opts...) } func (c *wrappedClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Delete(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Delete(ctx, obj, opts...) case *metav1.PartialObjectMetadata: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Delete(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Delete(ctx, obj, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - return c.client.Delete(ctx, u, opts...) - } return c.client.Delete(ctx, obj, opts...) } return c.client.Delete(ctx, obj, opts...) } func (c *wrappedClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Update(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Update(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return c.client.Update(ctx, obj, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - if err := c.client.Update(ctx, u, opts...); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return c.client.Scheme().Convert(u, obj, nil) - } return c.client.Update(ctx, obj, opts...) } return c.client.Update(ctx, obj, opts...) @@ -233,69 +113,22 @@ func (c *wrappedClient) Update(ctx context.Context, obj client.Object, opts ...c // Since patch processes resources as Objects, even if the structs are different, if the Spec and Status are the same, there is no problem with patch processing. // ref: https://github.com/kubernetes-sigs/controller-runtime/blob/v0.12.1/pkg/client/patch.go#L114 func (c *wrappedClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Patch(ctx, o, patch, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.Patch(ctx, obj, patch, opts...) - case *metav1.PartialObjectMetadata: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.Patch(ctx, o, patch, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - if err := c.client.Patch(ctx, u, patch, opts...); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return c.client.Scheme().Convert(u, obj, nil) - } return c.client.Patch(ctx, obj, patch, opts...) } return c.client.Patch(ctx, obj, patch, opts...) } func (c *wrappedClient) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error { - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.DeleteAllOf(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.DeleteAllOf(ctx, obj, opts...) case *metav1.PartialObjectMetadata: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := c.client.DeleteAllOf(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return c.client.DeleteAllOf(ctx, obj, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - return c.client.DeleteAllOf(ctx, u, opts...) - } return c.client.DeleteAllOf(ctx, obj, opts...) } return c.client.DeleteAllOf(ctx, obj, opts...) @@ -324,19 +157,10 @@ func (c *wrappedClient) GroupVersionKindFor(obj runtime.Object) (schema.GroupVer gvk := obj.GetObjectKind().GroupVersionKind() switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - return topolvmlegacyv1.GroupVersion.WithKind(kind), nil - } return gvk, nil case *metav1.PartialObjectMetadata: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - return topolvmlegacyv1.GroupVersion.WithKind(kind), nil - } return gvk, nil case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - return topolvmlegacyv1.GroupVersion.WithKind(kind), nil - } return gvk, nil } return gvk, nil @@ -369,31 +193,12 @@ func (c *wrappedSubResourceClient) Create(ctx context.Context, obj client.Object func (c *wrappedSubResourceClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { sc := c.client.SubResource(c.subResource) - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := sc.Update(ctx, o, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return sc.Update(ctx, obj, opts...) case *metav1.PartialObjectMetadata: return sc.Update(ctx, obj, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - if err := sc.Update(ctx, u, opts...); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return c.client.Scheme().Convert(u, obj, nil) - } return sc.Update(ctx, obj, opts...) } return sc.Update(ctx, obj, opts...) @@ -404,37 +209,12 @@ func (c *wrappedSubResourceClient) Update(ctx context.Context, obj client.Object // ref: https://github.com/kubernetes-sigs/controller-runtime/blob/v0.12.1/pkg/client/patch.go#L114 func (c *wrappedSubResourceClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error { sc := c.client.SubResource(c.subResource) - gvk := obj.GetObjectKind().GroupVersionKind() - switch o := obj.(type) { + switch obj.(type) { case *unstructured.Unstructured: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := sc.Patch(ctx, o, patch, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return sc.Patch(ctx, obj, patch, opts...) case *metav1.PartialObjectMetadata: - if gvk.Group == group && gvk.Kind == kind && topolvm.UseLegacy() { - o.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - err := sc.Patch(ctx, o, patch, opts...) - o.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return err - } return sc.Patch(ctx, obj, patch, opts...) case *topolvmv1.LogicalVolume: - if topolvm.UseLegacy() { - u := &unstructured.Unstructured{} - if err := c.client.Scheme().Convert(obj, u, nil); err != nil { - return err - } - u.SetGroupVersionKind(topolvmlegacyv1.GroupVersion.WithKind(kind)) - if err := sc.Patch(ctx, u, patch, opts...); err != nil { - return err - } - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - return c.client.Scheme().Convert(u, obj, nil) - } return sc.Patch(ctx, obj, patch, opts...) } return sc.Patch(ctx, obj, patch, opts...) diff --git a/internal/client/client_test.go b/internal/client/client_test.go index 5941b77b8..ab948a926 100644 --- a/internal/client/client_test.go +++ b/internal/client/client_test.go @@ -2,55 +2,30 @@ package client import ( "fmt" - "os" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" "google.golang.org/grpc/codes" "sigs.k8s.io/controller-runtime/pkg/client" corev1 "k8s.io/api/core/v1" apierrs "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" ) -type fakeListOptions struct { - f func(opts *client.ListOptions) -} - -func (o *fakeListOptions) ApplyToList(opts *client.ListOptions) { - o.f(opts) -} - const ( configmapName = "test" configmapNamespace = "default" ) -var ( - configMapGVK = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} - configMapListGVK = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMapList"} - configmapKey = types.NamespacedName{ - Name: configmapName, - Namespace: configmapNamespace, - } -) - var _ = Describe("client", func() { Context("current env", func() { BeforeEach(func() { - os.Setenv("USE_LEGACY", "") err := k8sDelegatedClient.DeleteAllOf(testCtx, &topolvmv1.LogicalVolume{}) Expect(err).ShouldNot(HaveOccurred()) - err = k8sDelegatedClient.DeleteAllOf(testCtx, &topolvmlegacyv1.LogicalVolume{}) - Expect(err).ShouldNot(HaveOccurred()) cm := &corev1.ConfigMap{} cm.Name = configmapName cm.Namespace = configmapNamespace @@ -401,1340 +376,4 @@ var _ = Describe("client", func() { }) }) }) - - Context("legacy env", func() { - BeforeEach(func() { - os.Setenv("USE_LEGACY", "true") - err := k8sDelegatedClient.DeleteAllOf(testCtx, &topolvmv1.LogicalVolume{}) - Expect(err).ShouldNot(HaveOccurred()) - err = k8sDelegatedClient.DeleteAllOf(testCtx, &topolvmlegacyv1.LogicalVolume{}) - Expect(err).ShouldNot(HaveOccurred()) - cm := &corev1.ConfigMap{} - cm.Name = configmapName - cm.Namespace = configmapNamespace - k8sDelegatedClient.Delete(testCtx, cm) - }) - - Context("wrappedReader", func() { - Context("Get", func() { - get := func(doCheck bool, f func(*wrappedReader, *topolvmv1.LogicalVolume, string)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - setLegacyLVStatus(lv, i) - err = k8sDelegatedClient.Status().Update(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - checklv := new(topolvmv1.LogicalVolume) - c := NewWrappedReader(k8sAPIReader, scheme) - r := c.(*wrappedReader) - f(r, checklv, lv.Name) - - if doCheck { - Expect(checklv.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(checklv.Spec.AccessType).Should(Equal("rw")) - Expect(checklv.Status.VolumeID).Should(Equal(fmt.Sprintf("volume-%d", i))) - Expect(checklv.Status.Code).Should(Equal(codes.Unknown)) - Expect(checklv.Status.Message).Should(Equal(codes.Unknown.String())) - Expect(checklv.Status.CurrentSize.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - } - } - - It("typedClient", func() { - get(true, func(c *wrappedReader, lv *topolvmv1.LogicalVolume, name string) { - err := c.Get(testCtx, types.NamespacedName{Name: name}, lv) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - get(true, func(c *wrappedReader, lv *topolvmv1.LogicalVolume, name string) { - u := &unstructured.Unstructured{} - Expect(c.scheme.Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Get(testCtx, types.NamespacedName{Name: name}, u) - Expect(err).ShouldNot(HaveOccurred()) - Expect(c.scheme.Convert(u, lv, nil)).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - get(false, func(c *wrappedReader, lv *topolvmv1.LogicalVolume, name string) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Get(testCtx, types.NamespacedName{Name: name}, p) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - checkcm := new(corev1.ConfigMap) - c := NewWrappedReader(k8sAPIReader, scheme) - err = c.Get(testCtx, configmapKey, checkcm) - Expect(err).ShouldNot(HaveOccurred()) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(configMapGVK) - c := NewWrappedReader(k8sAPIReader, scheme) - err = c.Get(testCtx, configmapKey, u) - Expect(err).ShouldNot(HaveOccurred()) - }) - - It("non LogicalVolume metav1.PartialObjectMetadata", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(configMapGVK) - c := NewWrappedReader(k8sAPIReader, scheme) - err = c.Get(testCtx, configmapKey, p) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - Context("List", func() { - list := func(doCheck bool, f func(*wrappedReader, *topolvmv1.LogicalVolumeList)) { - for i := 0; i < 2; i++ { - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - setLegacyLVStatus(lv, i) - err = k8sDelegatedClient.Status().Update(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - } - - lvlist := new(topolvmv1.LogicalVolumeList) - c := NewWrappedReader(k8sAPIReader, scheme) - r := c.(*wrappedReader) - f(r, lvlist) - - if doCheck { - Expect(lvlist.Items).ShouldNot(HaveLen(0)) - for i, lv := range lvlist.Items { - Expect(lv.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(lv.Spec.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(lv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - Expect(lv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(lv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(lv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(lv.Spec.AccessType).Should(Equal("rw")) - Expect(lv.Status.VolumeID).Should(Equal(fmt.Sprintf("volume-%d", i))) - Expect(lv.Status.Code).Should(Equal(codes.Unknown)) - Expect(lv.Status.Message).Should(Equal(codes.Unknown.String())) - Expect(lv.Status.CurrentSize.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - } - } - } - - It("typedClient", func() { - list(true, func(c *wrappedReader, lvlist *topolvmv1.LogicalVolumeList) { - err := c.List(testCtx, lvlist) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - list(true, func(c *wrappedReader, lvlist *topolvmv1.LogicalVolumeList) { - u := &unstructured.UnstructuredList{} - Expect(c.scheme.Convert(lvlist, u, nil)).ShouldNot(HaveOccurred()) - err := c.List(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - Expect(c.scheme.Convert(u, lvlist, nil)).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - list(false, func(c *wrappedReader, lvlist *topolvmv1.LogicalVolumeList) { - p := &metav1.PartialObjectMetadataList{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - err := c.List(testCtx, p) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("option test", func() { - var opt1called bool - opt1 := &fakeListOptions{ - f: func(opts *client.ListOptions) { - opt1called = true - }, - } - var opt2called bool - opt2 := &fakeListOptions{ - f: func(opts *client.ListOptions) { - opt2called = true - }, - } - - c := NewWrappedReader(k8sAPIReader, scheme) - err := c.List(testCtx, new(topolvmv1.LogicalVolumeList), opt1, opt2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(opt1called).Should(BeTrue()) - Expect(opt2called).Should(BeTrue()) - }) - - It("non LogicalVolumeList object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - list := new(corev1.ConfigMapList) - c := NewWrappedReader(k8sAPIReader, scheme) - err = c.List(testCtx, list) - Expect(err).ShouldNot(HaveOccurred()) - list2 := new(corev1.ConfigMapList) - err = k8sAPIReader.List(testCtx, list2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(list.Items)).Should(Equal(len(list2.Items))) - }) - - It("non LogicalVolumeList unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - u := &unstructured.UnstructuredList{} - u.SetGroupVersionKind(configMapListGVK) - c := NewWrappedReader(k8sAPIReader, scheme) - err = c.List(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - list := new(corev1.ConfigMapList) - Expect(scheme.Convert(u, list, nil)).ShouldNot(HaveOccurred()) - list2 := new(corev1.ConfigMapList) - err = k8sAPIReader.List(testCtx, list2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(list.Items)).Should(Equal(len(list2.Items))) - }) - - It("non LogicalVolumeList metav1.PartialObjectMetadata", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - p := &metav1.PartialObjectMetadataList{} - p.SetGroupVersionKind(configMapListGVK) - c := NewWrappedReader(k8sAPIReader, scheme) - err = c.List(testCtx, p) - Expect(err).ShouldNot(HaveOccurred()) - list2 := new(corev1.ConfigMapList) - err = k8sAPIReader.List(testCtx, list2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(p.Items)).Should(Equal(len(list2.Items))) - }) - }) - }) - - Context("wrappedClient", func() { - Context("Get", func() { - get := func(doCheck bool, f func(Gomega, client.Client, *topolvmv1.LogicalVolume, string)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - setLegacyLVStatus(lv, i) - err = k8sDelegatedClient.Status().Update(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - Eventually(func(g Gomega) { - checklv := new(topolvmv1.LogicalVolume) - c := NewWrappedClient(k8sDelegatedClient) - f(g, c, checklv, lv.Name) - - if doCheck { - g.Expect(checklv.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - g.Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - g.Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - g.Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - g.Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - g.Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - g.Expect(checklv.Spec.AccessType).Should(Equal("rw")) - g.Expect(checklv.Status.VolumeID).Should(Equal(fmt.Sprintf("volume-%d", i))) - g.Expect(checklv.Status.Code).Should(Equal(codes.Unknown)) - g.Expect(checklv.Status.Message).Should(Equal(codes.Unknown.String())) - g.Expect(checklv.Status.CurrentSize.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - } - }).Should(Succeed()) - - } - - It("typedClient", func() { - get(true, func(g Gomega, c client.Client, lv *topolvmv1.LogicalVolume, name string) { - err := c.Get(testCtx, types.NamespacedName{Name: name}, lv) - g.Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - get(true, func(g Gomega, c client.Client, lv *topolvmv1.LogicalVolume, name string) { - u := &unstructured.Unstructured{} - g.Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Get(testCtx, types.NamespacedName{Name: name}, u) - g.Expect(err).ShouldNot(HaveOccurred()) - g.Expect(c.Scheme().Convert(u, lv, nil)).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - get(false, func(g Gomega, c client.Client, lv *topolvmv1.LogicalVolume, name string) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Get(testCtx, types.NamespacedName{Name: name}, p) - g.Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - checkcm := new(corev1.ConfigMap) - Eventually(func(g Gomega) { - c := NewWrappedClient(k8sDelegatedClient) - err = c.Get(testCtx, configmapKey, checkcm) - g.Expect(err).ShouldNot(HaveOccurred()) - }).Should(Succeed()) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(configMapGVK) - Eventually(func(g Gomega) { - c := NewWrappedClient(k8sDelegatedClient) - err = c.Get(testCtx, configmapKey, u) - g.Expect(err).ShouldNot(HaveOccurred()) - }).Should(Succeed()) - }) - - It("non LogicalVolume metav1.PartialObjectMetadata", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(configMapGVK) - Eventually(func(g Gomega) { - c := NewWrappedClient(k8sDelegatedClient) - err = c.Get(testCtx, configmapKey, p) - g.Expect(err).ShouldNot(HaveOccurred()) - }).Should(Succeed()) - }) - }) - - Context("List", func() { - list := func(doCheck bool, f func(Gomega, *wrappedReader, *topolvmv1.LogicalVolumeList)) { - for i := 0; i < 2; i++ { - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - setLegacyLVStatus(lv, i) - err = k8sDelegatedClient.Status().Update(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - } - - Eventually(func(g Gomega) { - lvlist := new(topolvmv1.LogicalVolumeList) - c := NewWrappedReader(k8sAPIReader, scheme) - r := c.(*wrappedReader) - f(g, r, lvlist) - - if doCheck { - for i, lv := range lvlist.Items { - Expect(lv.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(lv.Spec.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(lv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - Expect(lv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(lv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(lv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(lv.Spec.AccessType).Should(Equal("rw")) - Expect(lv.Status.VolumeID).Should(Equal(fmt.Sprintf("volume-%d", i))) - Expect(lv.Status.Code).Should(Equal(codes.Unknown)) - Expect(lv.Status.Message).Should(Equal(codes.Unknown.String())) - Expect(lv.Status.CurrentSize.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - } - } - }).Should(Succeed()) - - } - - It("typedClient", func() { - list(true, func(g Gomega, c *wrappedReader, lvlist *topolvmv1.LogicalVolumeList) { - err := c.List(testCtx, lvlist) - g.Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - list(true, func(g Gomega, c *wrappedReader, lvlist *topolvmv1.LogicalVolumeList) { - u := &unstructured.UnstructuredList{} - g.Expect(c.scheme.Convert(lvlist, u, nil)).ShouldNot(HaveOccurred()) - err := c.List(testCtx, u) - g.Expect(err).ShouldNot(HaveOccurred()) - g.Expect(c.scheme.Convert(u, lvlist, nil)).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - list(false, func(g Gomega, c *wrappedReader, lvlist *topolvmv1.LogicalVolumeList) { - p := &metav1.PartialObjectMetadataList{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - err := c.List(testCtx, p) - g.Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("option test", func() { - var opt1called bool - opt1 := &fakeListOptions{ - f: func(opts *client.ListOptions) { - opt1called = true - }, - } - var opt2called bool - opt2 := &fakeListOptions{ - f: func(opts *client.ListOptions) { - opt2called = true - }, - } - - c := NewWrappedClient(k8sDelegatedClient) - err := c.List(testCtx, new(topolvmv1.LogicalVolumeList), opt1, opt2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(opt1called).Should(BeTrue()) - Expect(opt2called).Should(BeTrue()) - }) - - It("non LogicalVolumeList object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - Eventually(func(g Gomega) { - list := new(corev1.ConfigMapList) - c := NewWrappedClient(k8sDelegatedClient) - err = c.List(testCtx, list) - g.Expect(err).ShouldNot(HaveOccurred()) - list2 := new(corev1.ConfigMapList) - err = k8sAPIReader.List(testCtx, list2) - g.Expect(err).ShouldNot(HaveOccurred()) - g.Expect(len(list.Items)).Should(Equal(len(list2.Items))) - }).Should(Succeed()) - }) - - It("non LogicalVolumeList unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - Eventually(func(g Gomega) { - u := &unstructured.UnstructuredList{} - u.SetGroupVersionKind(configMapGVK) - c := NewWrappedClient(k8sDelegatedClient) - err = c.List(testCtx, u) - g.Expect(err).ShouldNot(HaveOccurred()) - list2 := new(corev1.ConfigMapList) - err = k8sAPIReader.List(testCtx, list2) - g.Expect(err).ShouldNot(HaveOccurred()) - g.Expect(len(u.Items)).Should(Equal(len(list2.Items))) - }).Should(Succeed()) - }) - - It("non LogicalVolumeList metav1.PartialObjectMetadata", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - Eventually(func(g Gomega) { - p := &metav1.PartialObjectMetadataList{} - p.SetGroupVersionKind(configMapGVK) - c := NewWrappedClient(k8sDelegatedClient) - err = c.List(testCtx, p) - g.Expect(err).ShouldNot(HaveOccurred()) - list2 := new(corev1.ConfigMapList) - err = k8sAPIReader.List(testCtx, list2) - g.Expect(err).ShouldNot(HaveOccurred()) - g.Expect(len(p.Items)).Should(Equal(len(list2.Items))) - }).Should(Succeed()) - }) - }) - - Context("Create", func() { - create := func(doCheck bool, f func(client.Client, *topolvmv1.LogicalVolume)) { - i := 0 - lv := currentLV(i) - c := NewWrappedClient(k8sDelegatedClient) - f(c, lv) - - if doCheck { - checklv := new(topolvmlegacyv1.LogicalVolume) - err := k8sAPIReader.Get(testCtx, types.NamespacedName{Name: lv.Name}, checklv) - Expect(err).ShouldNot(HaveOccurred()) - Expect(checklv.Name).Should(Equal(fmt.Sprintf("current-%d", i))) - Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("current-%d", i))) - Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(checklv.Spec.AccessType).Should(Equal("rw")) - } - } - - It("typedClient", func() { - create(true, func(c client.Client, lv *topolvmv1.LogicalVolume) { - err := c.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - create(true, func(c client.Client, lv *topolvmv1.LogicalVolume) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Create(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - create(false, func(c client.Client, lv *topolvmv1.LogicalVolume) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Create(testCtx, p) - Expect(err).Should(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - c := NewWrappedClient(k8sDelegatedClient) - err := c.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - err = k8sAPIReader.Get(testCtx, configmapKey, cm) - Expect(err).ShouldNot(HaveOccurred()) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(configMapGVK) - u.SetName(configmapName) - u.SetNamespace(configmapNamespace) - c := NewWrappedClient(k8sDelegatedClient) - err := c.Create(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err = k8sAPIReader.Get(testCtx, configmapKey, cm) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - Context("Delete", func() { - delete := func(f func(client.Client, *topolvmv1.LogicalVolume)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - c := NewWrappedClient(k8sDelegatedClient) - f(c, convertToCurrent(lv)) - - checklv := new(topolvmlegacyv1.LogicalVolume) - err = k8sAPIReader.Get(testCtx, types.NamespacedName{Name: lv.Name}, checklv) - Expect(err).Should(HaveOccurred()) - Expect(apierrs.IsNotFound(err)).Should(BeTrue()) - } - - It("typedClient", func() { - delete(func(c client.Client, lv *topolvmv1.LogicalVolume) { - err := c.Delete(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - delete(func(c client.Client, lv *topolvmv1.LogicalVolume) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Delete(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - delete(func(c client.Client, lv *topolvmv1.LogicalVolume) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Delete(testCtx, p) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - c := NewWrappedClient(k8sDelegatedClient) - err = c.Delete(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - err = k8sAPIReader.Get(testCtx, configmapKey, cm) - Expect(err).Should(HaveOccurred()) - Expect(apierrs.IsNotFound(err)).Should(BeTrue()) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(configMapGVK) - u.SetName(configmapName) - u.SetNamespace(configmapNamespace) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Delete(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - - err = k8sAPIReader.Get(testCtx, configmapKey, cm) - Expect(err).Should(HaveOccurred()) - Expect(apierrs.IsNotFound(err)).Should(BeTrue()) - }) - - It("non LogicalVolume metav1.PartialObjectMetadata", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(configMapGVK) - p.SetName(configmapName) - p.SetNamespace(configmapNamespace) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Delete(testCtx, p) - Expect(err).ShouldNot(HaveOccurred()) - - err = k8sAPIReader.Get(testCtx, configmapKey, cm) - Expect(err).Should(HaveOccurred()) - Expect(apierrs.IsNotFound(err)).Should(BeTrue()) - }) - }) - - Context("Update", func() { - update := func(doCheck bool, f func(client.Client, *topolvmv1.LogicalVolume)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - lv2 := convertToCurrent(lv) - lv2.Annotations = ann - lv2.Spec.Name = fmt.Sprintf("updated-legacy-%d", i) - lv2.Spec.NodeName = fmt.Sprintf("updated-node-%d", i) - c := NewWrappedClient(k8sDelegatedClient) - f(c, lv2) - - if doCheck { - checklv := new(topolvmlegacyv1.LogicalVolume) - err = k8sAPIReader.Get(testCtx, types.NamespacedName{Name: lv.Name}, checklv) - Expect(err).ShouldNot(HaveOccurred()) - Expect(checklv.Annotations).Should(Equal(ann)) - Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("updated-legacy-%d", i))) - Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("updated-node-%d", i))) - Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(checklv.Spec.AccessType).Should(Equal("rw")) - } - } - - It("typedClient", func() { - update(true, func(c client.Client, lv *topolvmv1.LogicalVolume) { - err := c.Update(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - update(true, func(c client.Client, lv *topolvmv1.LogicalVolume) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Update(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - update(false, func(c client.Client, lv *topolvmv1.LogicalVolume) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Update(testCtx, p) - Expect(err).Should(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - cm2 := cm.DeepCopy() - cm2.Annotations = ann - c := NewWrappedClient(k8sDelegatedClient) - err = c.Update(testCtx, cm2) - Expect(err).ShouldNot(HaveOccurred()) - - cm3 := new(corev1.ConfigMap) - err = k8sAPIReader.Get(testCtx, configmapKey, cm3) - Expect(err).ShouldNot(HaveOccurred()) - Expect(cm3.Annotations).Should(Equal(ann)) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - cm2 := cm.DeepCopy() - cm2.Annotations = ann - u := &unstructured.Unstructured{} - Expect(scheme.Convert(cm2, u, nil)).ShouldNot(HaveOccurred()) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Update(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - - cm3 := new(corev1.ConfigMap) - err = k8sAPIReader.Get(testCtx, configmapKey, cm3) - Expect(err).ShouldNot(HaveOccurred()) - Expect(cm3.Annotations).Should(Equal(ann)) - }) - }) - - Context("Patch", func() { - patch := func(doCheck bool, f func(client.Client, *topolvmv1.LogicalVolume, client.Patch)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - lv2 := convertToCurrent(lv) - lv2.TypeMeta.APIVersion = topolvmlegacyv1.GroupVersion.String() - lv3 := lv2.DeepCopy() - lv3.Annotations = ann - lv3.Spec.Name = fmt.Sprintf("updated-legacy-%d", i) - lv3.Spec.NodeName = fmt.Sprintf("updated-node-%d", i) - patch := client.MergeFrom(lv2) - c := NewWrappedClient(k8sDelegatedClient) - f(c, lv3, patch) - - checklv := new(topolvmlegacyv1.LogicalVolume) - err = k8sAPIReader.Get(testCtx, types.NamespacedName{Name: lv.Name}, checklv) - Expect(err).ShouldNot(HaveOccurred()) - Expect(checklv.Annotations).Should(Equal(ann)) - if doCheck { - Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("updated-legacy-%d", i))) - Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("updated-node-%d", i))) - Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(checklv.Spec.AccessType).Should(Equal("rw")) - } - } - - It("typedClient", func() { - patch(true, func(c client.Client, lv *topolvmv1.LogicalVolume, patch client.Patch) { - err := c.Patch(testCtx, lv, patch) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - patch(true, func(c client.Client, lv *topolvmv1.LogicalVolume, patch client.Patch) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Patch(testCtx, u, patch) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - patch(false, func(c client.Client, lv *topolvmv1.LogicalVolume, patch client.Patch) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Patch(testCtx, p, patch) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - cm2 := cm.DeepCopy() - cm3 := cm2.DeepCopy() - cm3.Annotations = ann - patch := client.MergeFrom(cm2) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Patch(testCtx, cm3, patch) - Expect(err).ShouldNot(HaveOccurred()) - - cm4 := new(corev1.ConfigMap) - err = k8sAPIReader.Get(testCtx, configmapKey, cm4) - Expect(err).ShouldNot(HaveOccurred()) - Expect(cm4.Annotations).Should(Equal(ann)) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - cm2 := cm.DeepCopy() - cm3 := cm2.DeepCopy() - cm3.Annotations = ann - u := &unstructured.Unstructured{} - Expect(scheme.Convert(cm3, u, nil)).ShouldNot(HaveOccurred()) - patch := client.MergeFrom(cm2) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Patch(testCtx, u, patch) - Expect(err).ShouldNot(HaveOccurred()) - - cm4 := new(corev1.ConfigMap) - err = k8sAPIReader.Get(testCtx, configmapKey, cm4) - Expect(err).ShouldNot(HaveOccurred()) - Expect(cm4.Annotations).Should(Equal(ann)) - }) - - It("non LogicalVolume metav1.PartialObjectMetadata", func() { - cm := new(corev1.ConfigMap) - cm.Name = configmapName - cm.Namespace = configmapNamespace - err := k8sDelegatedClient.Create(testCtx, cm) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(configMapGVK) - p.SetName(configmapName) - p.SetNamespace(configmapNamespace) - p.SetAnnotations(ann) - patch := client.MergeFrom(cm) - p.SetAnnotations(ann) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Patch(testCtx, p, patch) - Expect(err).ShouldNot(HaveOccurred()) - - cm2 := new(corev1.ConfigMap) - err = k8sAPIReader.Get(testCtx, configmapKey, cm2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(cm2.Annotations).Should(Equal(ann)) - }) - }) - - Context("DeleteAllOf", func() { - deleteAllOf := func(f func(client.Client, *topolvmv1.LogicalVolume)) { - for i := 0; i < 2; i++ { - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - } - - checklvlist := new(topolvmlegacyv1.LogicalVolumeList) - err := k8sAPIReader.List(testCtx, checklvlist) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(checklvlist.Items)).Should(Equal(2)) - - lv := new(topolvmv1.LogicalVolume) - c := NewWrappedClient(k8sDelegatedClient) - f(c, lv) - - checklvlist = new(topolvmlegacyv1.LogicalVolumeList) - err = k8sAPIReader.List(testCtx, checklvlist) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(checklvlist.Items)).Should(Equal(0)) - } - - It("typedClient", func() { - deleteAllOf(func(c client.Client, lv *topolvmv1.LogicalVolume) { - err := c.DeleteAllOf(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - deleteAllOf(func(c client.Client, lv *topolvmv1.LogicalVolume) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.DeleteAllOf(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - deleteAllOf(func(c client.Client, lv *topolvmv1.LogicalVolume) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.DeleteAllOf(testCtx, p) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("typedClient", func() { - for i := 0; i < 2; i++ { - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - } - - checklvlist := new(topolvmlegacyv1.LogicalVolumeList) - err := k8sAPIReader.List(testCtx, checklvlist) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(checklvlist.Items)).Should(Equal(2)) - - lv := new(topolvmv1.LogicalVolume) - c := NewWrappedClient(k8sDelegatedClient) - err = c.DeleteAllOf(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - checklvlist = new(topolvmlegacyv1.LogicalVolumeList) - err = k8sAPIReader.List(testCtx, checklvlist) - Expect(err).ShouldNot(HaveOccurred()) - Expect(len(checklvlist.Items)).Should(Equal(0)) - }) - - It("non LogicalVolume object", func() { - Skip("If you found resources other than LogicalVolume resource what DeleteAllOf can be executed in the envtest environment, please write test cases for these resources.") - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - Skip("If you found resources other than LogicalVolume resource what DeleteAllOf can be executed in the envtest environment, please write test cases for these resources.") - }) - - It("non LogicalVolume metav1.PartialObjectMetadata", func() { - Skip("If you found resources other than LogicalVolume resource what DeleteAllOf can be executed in the envtest environment, please write test cases for these resources.") - }) - }) - - Context("SubResourceClient", func() { - Context("Get", func() { - It("should not be implemented", func() { - i := 0 - lv := currentLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - c := NewWrappedClient(k8sDelegatedClient) - err = c.SubResource("status").Get(testCtx, lv, nil) - Expect(err).Should(HaveOccurred()) - }) - }) - - Context("Create", func() { - It("should not be implemented", func() { - i := 0 - lv := currentLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - c := NewWrappedClient(k8sDelegatedClient) - err = c.SubResource("status").Create(testCtx, lv, nil) - Expect(err).Should(HaveOccurred()) - }) - }) - }) - - Context("SubResourceWriter", func() { - BeforeEach(func() { - svc := &corev1.Service{} - svc.Name = configmapName - svc.Namespace = configmapNamespace - k8sDelegatedClient.Delete(testCtx, svc) - }) - - Context("Update", func() { - update := func(doCheck bool, f func(client.Client, *topolvmv1.LogicalVolume)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - lv2 := convertToCurrent(lv) - setCurrentLVStatus(lv2, i) - c := NewWrappedClient(k8sDelegatedClient) - f(c, lv2) - - if doCheck { - checklv := new(topolvmlegacyv1.LogicalVolume) - err = k8sAPIReader.Get(testCtx, types.NamespacedName{Name: lv.Name}, checklv) - Expect(err).ShouldNot(HaveOccurred()) - Expect(checklv.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(checklv.Spec.AccessType).Should(Equal("rw")) - Expect(checklv.Status.VolumeID).Should(Equal(fmt.Sprintf("volume-%d", i))) - Expect(checklv.Status.Code).Should(Equal(codes.Unknown)) - Expect(checklv.Status.Message).Should(Equal(codes.Unknown.String())) - Expect(checklv.Status.CurrentSize.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - } - } - - It("typedClient", func() { - update(true, func(c client.Client, lv *topolvmv1.LogicalVolume) { - err := c.Status().Update(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - update(true, func(c client.Client, lv *topolvmv1.LogicalVolume) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Status().Update(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - update(false, func(c client.Client, lv *topolvmv1.LogicalVolume) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Status().Update(testCtx, p) - Expect(err).Should(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - svc := new(corev1.Service) - svc.Name = configmapName - svc.Namespace = configmapNamespace - svc.Spec = corev1.ServiceSpec{ - Selector: map[string]string{"app": "MyApp"}, - Ports: []corev1.ServicePort{ - { - Protocol: corev1.ProtocolTCP, - Port: 80, - }, - }, - } - err := k8sDelegatedClient.Create(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - defer func() { - err := k8sDelegatedClient.Delete(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - }() - - svc2 := svc.DeepCopy() - lbstatus := corev1.LoadBalancerStatus{ - Ingress: []corev1.LoadBalancerIngress{ - { - Hostname: "example.com", - }, - }, - } - svc2.Status.LoadBalancer = lbstatus - c := NewWrappedClient(k8sDelegatedClient) - err = c.Status().Update(testCtx, svc2) - Expect(err).ShouldNot(HaveOccurred()) - - svc3 := new(corev1.Service) - err = k8sAPIReader.Get(testCtx, configmapKey, svc3) - Expect(err).ShouldNot(HaveOccurred()) - Expect(svc3.Status.LoadBalancer).Should(Equal(lbstatus)) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - svc := new(corev1.Service) - svc.Name = configmapName - svc.Namespace = configmapNamespace - svc.Spec = corev1.ServiceSpec{ - Selector: map[string]string{"app": "MyApp"}, - Ports: []corev1.ServicePort{ - { - Protocol: corev1.ProtocolTCP, - Port: 80, - }, - }, - } - err := k8sDelegatedClient.Create(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - defer func() { - err := k8sDelegatedClient.Delete(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - }() - - svc2 := svc.DeepCopy() - lbstatus := corev1.LoadBalancerStatus{ - Ingress: []corev1.LoadBalancerIngress{ - { - Hostname: "example.com", - }, - }, - } - svc2.Status.LoadBalancer = lbstatus - u := &unstructured.Unstructured{} - u.SetGroupVersionKind(configMapGVK) - Expect(scheme.Convert(svc2, u, nil)).ShouldNot(HaveOccurred()) - - c := NewWrappedClient(k8sDelegatedClient) - err = c.Status().Update(testCtx, u) - Expect(err).ShouldNot(HaveOccurred()) - - svc3 := new(corev1.Service) - err = k8sAPIReader.Get(testCtx, configmapKey, svc3) - Expect(err).ShouldNot(HaveOccurred()) - Expect(svc3.Status.LoadBalancer).Should(Equal(lbstatus)) - }) - }) - - Context("Patch", func() { - patch := func(doCheck bool, f func(client.Client, *topolvmv1.LogicalVolume, client.Patch)) { - i := 0 - lv := legacyLV(i) - err := k8sDelegatedClient.Create(testCtx, lv) - Expect(err).ShouldNot(HaveOccurred()) - - lv2 := convertToCurrent(lv) - lv2.TypeMeta.APIVersion = topolvmlegacyv1.GroupVersion.String() - lv3 := lv2.DeepCopy() - setCurrentLVStatus(lv3, i) - patch := client.MergeFrom(lv2) - c := NewWrappedClient(k8sDelegatedClient) - f(c, lv3, patch) - - checklv := new(topolvmlegacyv1.LogicalVolume) - err = k8sAPIReader.Get(testCtx, types.NamespacedName{Name: lv.Name}, checklv) - Expect(err).ShouldNot(HaveOccurred()) - if doCheck { - Expect(checklv.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(checklv.Spec.Name).Should(Equal(fmt.Sprintf("legacy-%d", i))) - Expect(checklv.Spec.NodeName).Should(Equal(fmt.Sprintf("node-%d", i))) - Expect(checklv.Spec.DeviceClass).Should(Equal(topolvm.DefaultDeviceClassName)) - Expect(checklv.Spec.Size.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - Expect(checklv.Spec.Source).Should(Equal(fmt.Sprintf("source-%d", i))) - Expect(checklv.Spec.AccessType).Should(Equal("rw")) - Expect(checklv.Status.VolumeID).Should(Equal(fmt.Sprintf("volume-%d", i))) - Expect(checklv.Status.Code).Should(Equal(codes.Unknown)) - Expect(checklv.Status.Message).Should(Equal(codes.Unknown.String())) - Expect(checklv.Status.CurrentSize.Value()).Should(Equal(resource.NewQuantity(1<<30, resource.BinarySI).Value())) - } - } - - It("typedClient", func() { - patch(true, func(c client.Client, lv *topolvmv1.LogicalVolume, patch client.Patch) { - err := c.Status().Patch(testCtx, lv, patch) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("unstructured.Unstructured", func() { - patch(true, func(c client.Client, lv *topolvmv1.LogicalVolume, patch client.Patch) { - u := &unstructured.Unstructured{} - Expect(c.Scheme().Convert(lv, u, nil)).ShouldNot(HaveOccurred()) - err := c.Status().Patch(testCtx, u, patch) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("metav1.PartialObjectMetadata", func() { - patch(false, func(c client.Client, lv *topolvmv1.LogicalVolume, patch client.Patch) { - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - lv.ObjectMeta.DeepCopyInto(&p.ObjectMeta) - err := c.Status().Patch(testCtx, p, patch) - Expect(err).ShouldNot(HaveOccurred()) - }) - }) - - It("non LogicalVolume object", func() { - svc := new(corev1.Service) - svc.Name = configmapName - svc.Namespace = configmapNamespace - svc.Spec = corev1.ServiceSpec{ - Selector: map[string]string{"app": "MyApp"}, - Ports: []corev1.ServicePort{ - { - Protocol: corev1.ProtocolTCP, - Port: 80, - }, - }, - } - err := k8sDelegatedClient.Create(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - - svc2 := svc.DeepCopy() - svc3 := svc2.DeepCopy() - lbstatus := corev1.LoadBalancerStatus{ - Ingress: []corev1.LoadBalancerIngress{ - { - Hostname: "example.com", - }, - }, - } - svc3.Status.LoadBalancer = lbstatus - patch := client.MergeFrom(svc2) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Status().Patch(testCtx, svc3, patch) - Expect(err).ShouldNot(HaveOccurred()) - - svc4 := new(corev1.Service) - err = k8sAPIReader.Get(testCtx, configmapKey, svc4) - Expect(err).ShouldNot(HaveOccurred()) - Expect(svc4.Status.LoadBalancer).Should(Equal(lbstatus)) - }) - - It("non LogicalVolume unstructured.Unstructured", func() { - svc := new(corev1.Service) - svc.Name = configmapName - svc.Namespace = configmapNamespace - svc.Spec = corev1.ServiceSpec{ - Selector: map[string]string{"app": "MyApp"}, - Ports: []corev1.ServicePort{ - { - Protocol: corev1.ProtocolTCP, - Port: 80, - }, - }, - } - err := k8sDelegatedClient.Create(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - - svc2 := svc.DeepCopy() - svc3 := svc2.DeepCopy() - lbstatus := corev1.LoadBalancerStatus{ - Ingress: []corev1.LoadBalancerIngress{ - { - Hostname: "example.com", - }, - }, - } - svc3.Status.LoadBalancer = lbstatus - patch := client.MergeFrom(svc2) - u := &unstructured.Unstructured{} - Expect(scheme.Convert(svc3, u, nil)).ShouldNot(HaveOccurred()) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Status().Patch(testCtx, u, patch) - Expect(err).ShouldNot(HaveOccurred()) - - svc4 := new(corev1.Service) - err = k8sAPIReader.Get(testCtx, configmapKey, svc4) - Expect(err).ShouldNot(HaveOccurred()) - Expect(svc4.Status.LoadBalancer).Should(Equal(lbstatus)) - }) - - It("non LogicalVolume metav1.PartialObjectMetadata", func() { - svc := new(corev1.Service) - svc.Name = configmapName - svc.Namespace = configmapNamespace - svc.Spec = corev1.ServiceSpec{ - Selector: map[string]string{"app": "MyApp"}, - Ports: []corev1.ServicePort{ - { - Protocol: corev1.ProtocolTCP, - Port: 80, - }, - }, - } - err := k8sDelegatedClient.Create(testCtx, svc) - Expect(err).ShouldNot(HaveOccurred()) - - ann := map[string]string{"foo": "bar"} - svc2 := svc.DeepCopy() - svc2.Spec = corev1.ServiceSpec{} - svc2.Status = corev1.ServiceStatus{} - patch := client.MergeFrom(svc2) - p := &metav1.PartialObjectMetadata{} - p.SetGroupVersionKind(svc2.GroupVersionKind().GroupVersion().WithKind("Service")) - p.SetName(configmapName) - p.SetNamespace(configmapNamespace) - p.SetAnnotations(ann) - c := NewWrappedClient(k8sDelegatedClient) - err = c.Status().Patch(testCtx, p, patch) - Expect(err).ShouldNot(HaveOccurred()) - - svc4 := new(corev1.Service) - err = k8sAPIReader.Get(testCtx, configmapKey, svc4) - Expect(err).ShouldNot(HaveOccurred()) - Expect(svc4.Annotations).Should(Equal(ann)) - }) - }) - }) - }) - }) }) diff --git a/internal/client/suite_test.go b/internal/client/suite_test.go index 5b83c2e98..67b4b8c85 100644 --- a/internal/client/suite_test.go +++ b/internal/client/suite_test.go @@ -9,15 +9,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - testingutil "github.com/topolvm/topolvm/test/util" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" "google.golang.org/grpc/codes" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -35,15 +32,18 @@ import ( var scheme = runtime.NewScheme() -var k8sDelegatedClient client.Client -var k8sAPIReader client.Reader -var k8sCache cache.Cache +var ( + k8sDelegatedClient client.Client + k8sAPIReader client.Reader + k8sCache cache.Cache +) -var testEnv *envtest.Environment -var testCtx, testCancel = context.WithCancel(context.Background()) +var ( + testEnv *envtest.Environment + testCtx, testCancel = context.WithCancel(context.Background()) +) func TestAPIs(t *testing.T) { - testingutil.DoEnvCheck(t) RegisterFailHandler(Fail) SetDefaultEventuallyPollingInterval(time.Second) @@ -71,9 +71,6 @@ var _ = BeforeSuite(func() { err = topolvmv1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) - err = topolvmlegacyv1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:scheme c, err := cluster.New(cfg, func(clusterOptions *cluster.Options) { @@ -108,6 +105,7 @@ func currentLV(i int) *topolvmv1.LogicalVolume { Spec: topolvmv1.LogicalVolumeSpec{ Name: fmt.Sprintf("current-%d", i), NodeName: fmt.Sprintf("node-%d", i), + ProviderID: fmt.Sprintf("providerID-%d", i), DeviceClass: topolvm.DefaultDeviceClassName, Size: *resource.NewQuantity(1<<30, resource.BinarySI), Source: fmt.Sprintf("source-%d", i), @@ -122,28 +120,6 @@ func currentLV(i int) *topolvmv1.LogicalVolume { } } -func legacyLV(i int) *topolvmlegacyv1.LogicalVolume { - return &topolvmlegacyv1.LogicalVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("legacy-%d", i), - }, - Spec: topolvmlegacyv1.LogicalVolumeSpec{ - Name: fmt.Sprintf("legacy-%d", i), - NodeName: fmt.Sprintf("node-%d", i), - DeviceClass: topolvm.DefaultDeviceClassName, - Size: *resource.NewQuantity(1<<30, resource.BinarySI), - Source: fmt.Sprintf("source-%d", i), - AccessType: "rw", - }, - Status: topolvmlegacyv1.LogicalVolumeStatus{ - VolumeID: fmt.Sprintf("volume-%d", i), - Code: codes.Unknown, - Message: codes.Unknown.String(), - CurrentSize: resource.NewQuantity(1<<30, resource.BinarySI), - }, - } -} - func setCurrentLVStatus(lv *topolvmv1.LogicalVolume, i int) { lv.Status = topolvmv1.LogicalVolumeStatus{ VolumeID: fmt.Sprintf("volume-%d", i), @@ -152,23 +128,3 @@ func setCurrentLVStatus(lv *topolvmv1.LogicalVolume, i int) { CurrentSize: resource.NewQuantity(1<<30, resource.BinarySI), } } - -func setLegacyLVStatus(lv *topolvmlegacyv1.LogicalVolume, i int) { - lv.Status = topolvmlegacyv1.LogicalVolumeStatus{ - VolumeID: fmt.Sprintf("volume-%d", i), - Code: codes.Unknown, - Message: codes.Unknown.String(), - CurrentSize: resource.NewQuantity(1<<30, resource.BinarySI), - } -} - -func convertToCurrent(lv *topolvmlegacyv1.LogicalVolume) *topolvmv1.LogicalVolume { - u := &unstructured.Unstructured{} - err := k8sDelegatedClient.Scheme().Convert(lv, u, nil) - Expect(err).ShouldNot(HaveOccurred()) - u.SetGroupVersionKind(topolvmv1.GroupVersion.WithKind(kind)) - current := new(topolvmv1.LogicalVolume) - err = k8sDelegatedClient.Scheme().Convert(u, current, nil) - Expect(err).ShouldNot(HaveOccurred()) - return current -} diff --git a/internal/controller/constants.go b/internal/controller/constants.go index aa626fd6e..6d5a1ee96 100644 --- a/internal/controller/constants.go +++ b/internal/controller/constants.go @@ -4,8 +4,8 @@ const ( // keySelectedNode is a PVC resource indexing key for the controller keySelectedNode = "metadata.annotations.selected-node" - // keyLogicalVolumeNode is a Logical Volume resource indexing key for the controller - keyLogicalVolumeNode = "spec.nodeName" + // keyLogicalVolumeProviderID is a Logical Volume resource indexing key for the controller + keyLogicalVolumeProviderID = "spec.providerID" // AnnSelectedNode annotation is added to a PVC that has been triggered by scheduler to // be dynamically provisioned. Its value is the name of the selected node. diff --git a/internal/controller/logicalvolume_controller.go b/internal/controller/logicalvolume_controller.go index 7979f0cd1..cfb87d3d3 100644 --- a/internal/controller/logicalvolume_controller.go +++ b/internal/controller/logicalvolume_controller.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/go-logr/logr" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + topolvm "github.com/syself/csi-topolvm" + + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" apierrs "k8s.io/apimachinery/pkg/api/errors" @@ -23,22 +23,21 @@ import ( // LogicalVolumeReconciler reconciles a LogicalVolume object type LogicalVolumeReconciler struct { - client client.Client - nodeName string - vgService proto.VGServiceClient - lvService proto.LVServiceClient + client client.Client + providerID string + vgService proto.VGServiceClient + lvService proto.LVServiceClient } -//+kubebuilder:rbac:groups=topolvm.io,resources=logicalvolumes,verbs=get;list;watch;update;patch -//+kubebuilder:rbac:groups=topolvm.io,resources=logicalvolumes/status,verbs=get;update;patch - -func NewLogicalVolumeReconcilerWithServices(client client.Client, nodeName string, vgService proto.VGServiceClient, lvService proto.LVServiceClient) *LogicalVolumeReconciler { +// +kubebuilder:rbac:groups=topolvm.io,resources=logicalvolumes,verbs=get;list;watch;update;patch +// +kubebuilder:rbac:groups=topolvm.io,resources=logicalvolumes/status,verbs=get;update;patch +func NewLogicalVolumeReconcilerWithServices(client client.Client, nodeName string, providerID string, vgService proto.VGServiceClient, lvService proto.LVServiceClient) (*LogicalVolumeReconciler, error) { return &LogicalVolumeReconciler{ - client: client, - nodeName: nodeName, - vgService: vgService, - lvService: lvService, - } + client: client, + providerID: providerID, + vgService: vgService, + lvService: lvService, + }, nil } // Reconcile creates/deletes LVM logical volume for a LogicalVolume. @@ -53,8 +52,11 @@ func (r *LogicalVolumeReconciler) Reconcile(ctx context.Context, req ctrl.Reques } return ctrl.Result{}, nil } - if lv.Spec.NodeName != r.nodeName { - log.Info("unfiltered logical value", "nodeName", lv.Spec.NodeName) + if lv.Spec.ProviderID != r.providerID { + log.Info("unfiltered logical value", + "r.providerID", r.providerID, + "lv.Spec.ProviderID", lv.Spec.ProviderID, + "lv.Spec.NodeName", lv.Spec.NodeName) return ctrl.Result{}, nil } @@ -136,12 +138,8 @@ func (r *LogicalVolumeReconciler) Reconcile(ctx context.Context, req ctrl.Reques // SetupWithManager sets up the controller with the Manager. func (r *LogicalVolumeReconciler) SetupWithManager(mgr ctrl.Manager) error { builder := ctrl.NewControllerManagedBy(mgr) - if topolvm.UseLegacy() { - builder = builder.For(&topolvmlegacyv1.LogicalVolume{}) - } else { - builder = builder.For(&topolvmv1.LogicalVolume{}) - } - return builder.WithEventFilter(&logicalVolumeFilter{r.nodeName}).Complete(r) + builder = builder.For(&topolvmv1.LogicalVolume{}) + return builder.WithEventFilter(&logicalVolumeFilter{r.providerID}).Complete(r) } func (r *LogicalVolumeReconciler) removeLVIfExists(ctx context.Context, log logr.Logger, lv *topolvmv1.LogicalVolume) error { @@ -263,7 +261,6 @@ func (r *LogicalVolumeReconciler) createLV(ctx context.Context, log logr.Logger, lv.Status.Message = "" return nil }() - if err != nil { if err2 := r.client.Status().Update(ctx, lv); err2 != nil { // err2 is logged but not returned because err is more important @@ -319,7 +316,6 @@ func (r *LogicalVolumeReconciler) expandLV(ctx context.Context, log logr.Logger, lv.Status.Message = "" return nil }() - if err != nil { if err2 := r.client.Status().Update(ctx, lv); err2 != nil { // err2 is logged but not returned because err is more important @@ -339,28 +335,17 @@ func (r *LogicalVolumeReconciler) expandLV(ctx context.Context, log logr.Logger, } type logicalVolumeFilter struct { - nodeName string + provivderID string } func (f logicalVolumeFilter) filter(obj client.Object) bool { var name string - if topolvm.UseLegacy() { - lv, ok := obj.(*topolvmlegacyv1.LogicalVolume) - if !ok { - return false - } - name = lv.Spec.NodeName - } else { - lv, ok := obj.(*topolvmv1.LogicalVolume) - if !ok { - return false - } - name = lv.Spec.NodeName - } - if name == f.nodeName { - return true + lv, ok := obj.(*topolvmv1.LogicalVolume) + if !ok { + return false } - return false + name = lv.Spec.ProviderID + return name == f.provivderID } func (f logicalVolumeFilter) Create(e event.CreateEvent) bool { diff --git a/internal/controller/logicalvolume_controller_test.go b/internal/controller/logicalvolume_controller_test.go index 7c63841a2..bd728ceea 100644 --- a/internal/controller/logicalvolume_controller_test.go +++ b/internal/controller/logicalvolume_controller_test.go @@ -6,9 +6,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" "google.golang.org/grpc" corev1 "k8s.io/api/core/v1" storegev1 "k8s.io/api/storage/v1" @@ -21,8 +21,7 @@ import ( var volumes = &[]*proto.LogicalVolume{} -type MockVGServiceClient struct { -} +type MockVGServiceClient struct{} // GetFreeBytes implements proto.VGServiceClient. func (MockVGServiceClient) GetFreeBytes(ctx context.Context, in *proto.GetFreeBytesRequest, opts ...grpc.CallOption) (*proto.GetFreeBytesResponse, error) { @@ -41,8 +40,7 @@ func (MockVGServiceClient) Watch(ctx context.Context, in *proto.Empty, opts ...g panic("unimplemented") } -type MockLVServiceClient struct { -} +type MockLVServiceClient struct{} // CreateLV implements proto.LVServiceClient. func (c MockLVServiceClient) CreateLV(ctx context.Context, in *proto.CreateLVRequest, opts ...grpc.CallOption) (*proto.CreateLVResponse, error) { @@ -90,7 +88,8 @@ var _ = Describe("LogicalVolume controller", func() { vgService = MockVGServiceClient{} lvService = MockLVServiceClient{} - reconciler := NewLogicalVolumeReconcilerWithServices(mgr.GetClient(), "node"+suffix, vgService, lvService) + reconciler, err := NewLogicalVolumeReconcilerWithServices(mgr.GetClient(), "node"+suffix, "providerID"+suffix, vgService, lvService) + Expect(err).NotTo(HaveOccurred()) err = reconciler.SetupWithManager(mgr) Expect(err).NotTo(HaveOccurred()) @@ -108,15 +107,13 @@ var _ = Describe("LogicalVolume controller", func() { }) setupResources := func(ctx context.Context, suffix string) topolvmv1.LogicalVolume { - node := corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: "node" + suffix, - Finalizers: []string{ - topolvm.GetNodeFinalizer(), - }, + nodeObj := corev1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "node" + suffix, Finalizers: []string{topolvm.GetNodeFinalizer()}}, + Spec: corev1.NodeSpec{ + ProviderID: "providerID" + suffix, }, } - err := k8sClient.Create(ctx, &node) + err := k8sClient.Create(ctx, &nodeObj) Expect(err).NotTo(HaveOccurred()) sc := storegev1.StorageClass{ @@ -134,7 +131,7 @@ var _ = Describe("LogicalVolume controller", func() { Name: "pvc" + suffix, Namespace: ns, Annotations: map[string]string{ - AnnSelectedNode: node.Name, + AnnSelectedNode: nodeObj.Name, }, }, Spec: corev1.PersistentVolumeClaimSpec{ @@ -142,7 +139,7 @@ var _ = Describe("LogicalVolume controller", func() { AccessModes: []corev1.PersistentVolumeAccessMode{ corev1.ReadWriteOnce, }, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI), }, @@ -157,7 +154,8 @@ var _ = Describe("LogicalVolume controller", func() { Name: "lv" + suffix, }, Spec: topolvmv1.LogicalVolumeSpec{ - NodeName: node.Name, + NodeName: nodeObj.Name, + ProviderID: nodeObj.Spec.ProviderID, }, } err = k8sClient.Create(ctx, &lv) diff --git a/internal/controller/node_controller.go b/internal/controller/node_controller.go index 39b024297..0c569eb2b 100644 --- a/internal/controller/node_controller.go +++ b/internal/controller/node_controller.go @@ -4,13 +4,11 @@ import ( "context" "github.com/go-logr/logr" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" corev1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -43,9 +41,8 @@ func (r *NodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. log := crlog.FromContext(ctx) // your logic here - var node v1.PartialObjectMetadata - node.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("Node")) - err := r.client.Get(ctx, req.NamespacedName, &node) + node := &corev1.Node{} + err := r.client.Get(ctx, req.NamespacedName, node) switch { case err == nil: case apierrors.IsNotFound(err): @@ -58,17 +55,17 @@ func (r *NodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. return ctrl.Result{}, nil } - if !controllerutil.ContainsFinalizer(&node, topolvm.GetNodeFinalizer()) { + if !controllerutil.ContainsFinalizer(node, topolvm.GetNodeFinalizer()) { return ctrl.Result{}, nil } - if result, err := r.doFinalize(ctx, log, &node); result.Requeue || err != nil { + if result, err := r.doFinalize(ctx, log, node); result.Requeue || err != nil { return result, err } node2 := node.DeepCopy() controllerutil.RemoveFinalizer(node2, topolvm.GetNodeFinalizer()) - if err := r.client.Patch(ctx, node2, client.MergeFrom(&node)); err != nil { + if err := r.client.Patch(ctx, node2, client.MergeFrom(node)); err != nil { log.Error(err, "failed to remove finalizer", "name", node.Name) return ctrl.Result{}, err } @@ -92,7 +89,7 @@ func (r *NodeReconciler) targetStorageClasses(ctx context.Context) (map[string]b return targets, nil } -func (r *NodeReconciler) doFinalize(ctx context.Context, log logr.Logger, node client.Object) (ctrl.Result, error) { +func (r *NodeReconciler) doFinalize(ctx context.Context, log logr.Logger, nodeObj *corev1.Node) (ctrl.Result, error) { if r.skipNodeFinalize { log.Info("skipping node finalize") return ctrl.Result{}, nil @@ -105,9 +102,12 @@ func (r *NodeReconciler) doFinalize(ctx context.Context, log logr.Logger, node c } var pvcs corev1.PersistentVolumeClaimList - err = r.client.List(ctx, &pvcs, client.MatchingFields{keySelectedNode: node.GetName()}) + err = r.client.List(ctx, &pvcs, client.MatchingFields{keySelectedNode: nodeObj.Name}) if err != nil { - log.Error(err, "unable to fetch PersistentVolumeClaimList") + log.Error(err, "unable to fetch PersistentVolumeClaimList", + "keySelectedNode", keySelectedNode, + "nodeObj.Name", nodeObj.Name) // ööö + /// "Index with name field:metadata.annotations.selected-node does not exist return ctrl.Result{}, err } @@ -128,7 +128,7 @@ func (r *NodeReconciler) doFinalize(ctx context.Context, log logr.Logger, node c } lvList := &topolvmv1.LogicalVolumeList{} - err = r.client.List(ctx, lvList, client.MatchingFields{keyLogicalVolumeNode: node.GetName()}) + err = r.client.List(ctx, lvList, client.MatchingFields{keyLogicalVolumeProviderID: nodeObj.Spec.ProviderID}) if err != nil { log.Error(err, "failed to get LogicalVolumes") return ctrl.Result{}, err @@ -183,21 +183,11 @@ func (r *NodeReconciler) SetupWithManager(mgr ctrl.Manager) error { if err != nil { return err } - - if topolvm.UseLegacy() { - err = mgr.GetFieldIndexer().IndexField(ctx, &topolvmlegacyv1.LogicalVolume{}, keyLogicalVolumeNode, func(o client.Object) []string { - return []string{o.(*topolvmlegacyv1.LogicalVolume).Spec.NodeName} - }) - if err != nil { - return err - } - } else { - err = mgr.GetFieldIndexer().IndexField(ctx, &topolvmv1.LogicalVolume{}, keyLogicalVolumeNode, func(o client.Object) []string { - return []string{o.(*topolvmv1.LogicalVolume).Spec.NodeName} - }) - if err != nil { - return err - } + err = mgr.GetFieldIndexer().IndexField(ctx, &topolvmv1.LogicalVolume{}, keyLogicalVolumeProviderID, func(o client.Object) []string { + return []string{o.(*topolvmv1.LogicalVolume).Spec.ProviderID} + }) + if err != nil { + return err } pred := predicate.Funcs{ diff --git a/internal/controller/node_controller_test.go b/internal/controller/node_controller_test.go index 574c3c817..22d46847a 100644 --- a/internal/controller/node_controller_test.go +++ b/internal/controller/node_controller_test.go @@ -8,8 +8,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" corev1 "k8s.io/api/core/v1" storegev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -48,16 +48,15 @@ var _ = Describe("NodeController controller", func() { }) setupResources := func(ctx context.Context, suffix string) ( - corev1.Node, corev1.PersistentVolumeClaim, topolvmv1.LogicalVolume) { - node := corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: "node" + suffix, - Finalizers: []string{ - topolvm.GetNodeFinalizer(), - }, + corev1.Node, corev1.PersistentVolumeClaim, topolvmv1.LogicalVolume, + ) { + nodeObj := corev1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "node" + suffix, Finalizers: []string{topolvm.GetNodeFinalizer()}}, + Spec: corev1.NodeSpec{ + ProviderID: "providerID" + suffix, }, } - err := k8sClient.Create(ctx, &node) + err := k8sClient.Create(ctx, &nodeObj) Expect(err).NotTo(HaveOccurred()) sc := storegev1.StorageClass{ @@ -74,16 +73,13 @@ var _ = Describe("NodeController controller", func() { ObjectMeta: metav1.ObjectMeta{ Name: "pvc" + suffix, Namespace: ns, - Annotations: map[string]string{ - AnnSelectedNode: node.Name, - }, }, Spec: corev1.PersistentVolumeClaimSpec{ StorageClassName: &sc.Name, AccessModes: []corev1.PersistentVolumeAccessMode{ corev1.ReadWriteOnce, }, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI), }, @@ -98,13 +94,14 @@ var _ = Describe("NodeController controller", func() { Name: "lv" + suffix, }, Spec: topolvmv1.LogicalVolumeSpec{ - NodeName: node.Name, + NodeName: nodeObj.Name, + ProviderID: nodeObj.Spec.ProviderID, }, } err = k8sClient.Create(ctx, &lv) Expect(err).NotTo(HaveOccurred()) - return node, pvc, lv + return nodeObj, pvc, lv } It("should delete PVC and LogicalVolume when the node is deleted if the finalizer is not skipped", func() { diff --git a/internal/controller/persistentvolumeclaim_controller.go b/internal/controller/persistentvolumeclaim_controller.go index c29a12090..75f330c79 100644 --- a/internal/controller/persistentvolumeclaim_controller.go +++ b/internal/controller/persistentvolumeclaim_controller.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" @@ -55,17 +55,6 @@ func (r *PersistentVolumeClaimReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{}, err } - // Remove deprecated finalizer and requeue. - removed, err := r.removeDeprecatedFinalizer(ctx, pvc) - if err != nil { - log.Error(err, "failed to remove deprecated finalizer", "name", pvc.Name) - return ctrl.Result{}, err - } else if removed { - return ctrl.Result{ - Requeue: true, - }, nil - } - // Skip if the PVC is not deleted or PVC does not have TopoLVM's finalizer. if pvc.DeletionTimestamp == nil { return ctrl.Result{}, nil @@ -146,15 +135,3 @@ func (r *PersistentVolumeClaimReconciler) SetupWithManager(mgr ctrl.Manager) err For(&corev1.PersistentVolumeClaim{}). Complete(r) } - -func (r *PersistentVolumeClaimReconciler) removeDeprecatedFinalizer(ctx context.Context, pvc *corev1.PersistentVolumeClaim) (bool, error) { - // Due to the bug #310, multiple TopoLVM finalizers can exist in `pvc.Finalizers`. - // So we need to delete all of them. - removed := controllerutil.RemoveFinalizer(pvc, topolvm.LegacyPVCFinalizer) - if removed { - if err := r.client.Update(ctx, pvc); err != nil { - return false, err - } - } - return removed, nil -} diff --git a/internal/controller/persistentvolumeclaim_controller_test.go b/internal/controller/persistentvolumeclaim_controller_test.go index dc0b7ba72..23c4e40c7 100644 --- a/internal/controller/persistentvolumeclaim_controller_test.go +++ b/internal/controller/persistentvolumeclaim_controller_test.go @@ -261,135 +261,6 @@ var _ = Describe("PersistentVolumeClaimController controller", func() { } }) - It("should remove deprecated finalizer", func() { - ctx := context.Background() - ns := createNamespace() - testCases := []struct { - title string - pvcMeta metav1.ObjectMeta - expectFinalizers []string - }{ - { - title: "empty finalizers", - pvcMeta: metav1.ObjectMeta{ - Name: "pvc1", - Namespace: ns, - Finalizers: []string{}, - }, - expectFinalizers: []string{ - "kubernetes.io/pvc-protection", - }, - }, - { - title: "there is an only foreign finalizer", - pvcMeta: metav1.ObjectMeta{ - Name: "pvc2", - Namespace: ns, - Finalizers: []string{ - "dummy/dummy", - }, - }, - expectFinalizers: []string{ - "dummy/dummy", - "kubernetes.io/pvc-protection", - }, - }, - { - title: "combination of foreign and deprecated finalizers", - pvcMeta: metav1.ObjectMeta{ - Name: "pvc3", - Namespace: ns, - Finalizers: []string{ - "dummy/dummy", - "topolvm.cybozu.com/pvc", - }, - }, - expectFinalizers: []string{ - "dummy/dummy", - "kubernetes.io/pvc-protection", - }, - }, - { - title: "there is an only new finalizer", - pvcMeta: metav1.ObjectMeta{ - Name: "pvc4", - Namespace: ns, - Finalizers: []string{ - "topolvm.io/pvc", - }, - }, - expectFinalizers: []string{ - "topolvm.io/pvc", - "kubernetes.io/pvc-protection", - }, - }, - { - title: "there are same old finalizers", - pvcMeta: metav1.ObjectMeta{ - Name: "pvc5", - Namespace: ns, - Finalizers: []string{ - "dummy/dummy", - "topolvm.cybozu.com/pvc", - "topolvm.cybozu.com/pvc", - }, - }, - expectFinalizers: []string{ - "dummy/dummy", - "kubernetes.io/pvc-protection", - }, - }, - { - title: "there are old finalizer and new finalizer", - pvcMeta: metav1.ObjectMeta{ - Name: "pvc6", - Namespace: ns, - Finalizers: []string{ - "dummy/dummy", - "topolvm.cybozu.com/pvc", - "topolvm.io/pvc", - }, - }, - expectFinalizers: []string{ - "dummy/dummy", - "topolvm.io/pvc", - "kubernetes.io/pvc-protection", - }, - }, - } - - for _, testPVC := range testCases { - pvc := corev1.PersistentVolumeClaim{ - ObjectMeta: testPVC.pvcMeta, - Spec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{ - corev1.ReadWriteOnce, - }, - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - "storage": resource.MustParse("1Gi"), - }, - }, - }, - } - err := k8sClient.Create(ctx, &pvc) - Expect(err).NotTo(HaveOccurred()) - } - - for _, testPVC := range testCases { - pvc := corev1.PersistentVolumeClaim{} - - Eventually(func(g Gomega) []string { - - err := k8sClient.Get(ctx, client.ObjectKey{Name: testPVC.pvcMeta.Name, Namespace: ns}, &pvc) - g.Expect(err).NotTo(HaveOccurred()) - - return pvc.Finalizers - }).Should(Equal(testPVC.expectFinalizers), testPVC.title) - } - - }) - It("should be deleted Pods which is using PVC that has finalizer", func() { ctx := context.Background() ns1 := createNamespace() @@ -506,7 +377,7 @@ var _ = Describe("PersistentVolumeClaimController controller", func() { AccessModes: []corev1.PersistentVolumeAccessMode{ corev1.ReadWriteOnce, }, - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ "storage": resource.MustParse("1Gi"), }, diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index 2a4437ad5..ae04faff5 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -25,10 +25,12 @@ import ( // These tests use Ginkgo (BDD-style Go testing framework). Refer to // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment -var scheme = runtime.NewScheme() +var ( + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + scheme = runtime.NewScheme() +) var namespaceCounter = 0 // EnvTest cannot delete namespace. So, we have to use another new namespace. func createNamespace() string { diff --git a/internal/driver/allocation_settings.go b/internal/driver/allocation_settings.go index 3fec40fe8..dfb09feba 100644 --- a/internal/driver/allocation_settings.go +++ b/internal/driver/allocation_settings.go @@ -63,7 +63,7 @@ func (settings MinimumAllocationSettings) MinMaxAllocationsFromSettings( minimumSize := settings.GetMinimumAllocationSize(capabilities) if minimumSize.CmpInt64(required) > 0 { - ctrlLogger.Info("required size is less than minimum size, "+ + logger.Info("required size is less than minimum size, "+ "using minimum size as required size", "required", required, "minimum", minimumSize.Value()) required = minimumSize.Value() } diff --git a/internal/driver/controller.go b/internal/driver/controller.go index 04ef96be6..409b5fced 100644 --- a/internal/driver/controller.go +++ b/internal/driver/controller.go @@ -9,16 +9,18 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" "github.com/golang/protobuf/ptypes/timestamp" - "github.com/topolvm/topolvm" - v1 "github.com/topolvm/topolvm/api/v1" - "github.com/topolvm/topolvm/internal/driver/internal/k8s" + topolvm "github.com/syself/csi-topolvm" + v1 "github.com/syself/csi-topolvm/api/v1" + "github.com/syself/csi-topolvm/internal/driver/internal/k8s" + "github.com/syself/csi-topolvm/pkg/node" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" ) -var ctrlLogger = ctrl.Log.WithName("driver").WithName("controller") +var logger = ctrl.Log.WithName("driver").WithName("controller") var ( ErrNoNegativeRequestBytes = errors.New("required capacity must not be negative") @@ -46,6 +48,7 @@ func NewControllerServer(mgr manager.Manager, settings ControllerServerSettings) lvService: lvService, nodeService: k8s.NewNodeService(mgr.GetClient()), settings: settings, + kubeClient: mgr.GetClient(), }, }, nil } @@ -114,6 +117,46 @@ func (s *controllerServer) ControllerExpandVolume(ctx context.Context, req *csi. return s.server.ControllerExpandVolume(ctx, req) } +func (s *controllerServer) ControllerPublishVolume(ctx context.Context, req *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) { + logger.Info("######################### syself ControllerPublishVolume()", + "ControllerPublishVolumeRequest", req, + "node", req.NodeId, + "volume", req.VolumeId, + "context", req.VolumeContext, + "context+v", fmt.Sprintf("%+v", req.VolumeContext), + ) + + if req.VolumeId == "" { + return nil, status.Error(codes.InvalidArgument, "missing volume id") + } + if req.NodeId == "" { + return nil, status.Error(codes.InvalidArgument, "missing node id") + } + if req.VolumeCapability == nil { + return nil, status.Error(codes.InvalidArgument, "missing volume capabilities") + } + + err := s.server.lvService.UpdateNewNodeName(ctx, req.VolumeId, req.NodeId) + if err != nil { + return nil, status.Errorf(codes.Unknown, "failed to update crd logicalvolume with id %q (nodeName %s): %s", + req.VolumeId, req.NodeId, err.Error()) + } + + resp := &csi.ControllerPublishVolumeResponse{} + return resp, nil +} + +func (s *controllerServer) ControllerUnpublishVolume(ctx context.Context, req *csi.ControllerUnpublishVolumeRequest) (*csi.ControllerUnpublishVolumeResponse, error) { + logger.Info("######################### syself ControllerUnpublishVolume()", + "ControllerUnpublishVolumeRequest", req, + "node", req.NodeId, + "volume", req.VolumeId) + if req.VolumeId == "" { + return nil, status.Error(codes.InvalidArgument, "invalid volume id") + } + return &csi.ControllerUnpublishVolumeResponse{}, nil +} + // controllerServerNoLocked implements csi.ControllerServer. // It does not take any lock, gRPC calls may be interleaved. // Therefore, must not use it directly. @@ -122,8 +165,8 @@ type controllerServerNoLocked struct { lvService *k8s.LogicalVolumeService nodeService *k8s.NodeService - - settings ControllerServerSettings + kubeClient client.Client + settings ControllerServerSettings } func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { @@ -132,7 +175,7 @@ func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.Cre deviceClass := req.GetParameters()[topolvm.GetDeviceClassKey()] lvcreateOptionClass := req.GetParameters()[topolvm.GetLvcreateOptionClassKey()] - ctrlLogger.Info("CreateVolume called", + logger.Info("CreateVolume called", "name", req.GetName(), "device_class", deviceClass, "required", req.GetCapacityRange().GetRequiredBytes(), @@ -160,16 +203,12 @@ func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.Cre capabilities, ) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "failed to calculate minimum/maximum allocation bytes: %v", err) - } - // check required volume capabilities for _, capability := range capabilities { if block := capability.GetBlock(); block != nil { - ctrlLogger.Info("CreateVolume specifies volume capability", "access_type", "block") + logger.Info("CreateVolume specifies volume capability", "access_type", "block") } else if mount := capability.GetMount(); mount != nil { - ctrlLogger.Info("CreateVolume specifies volume capability", + logger.Info("CreateVolume specifies volume capability", "access_type", "mount", "fs_type", mount.GetFsType(), "flags", mount.GetMountFlags()) @@ -179,7 +218,7 @@ func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.Cre if mode := capability.GetAccessMode(); mode != nil { modeName := csi.VolumeCapability_AccessMode_Mode_name[int32(mode.GetMode())] - ctrlLogger.Info("CreateVolume specifies volume capability", "access_mode", modeName) + logger.Info("CreateVolume specifies volume capability", "access_mode", modeName) // we only support SINGLE_NODE_WRITER switch mode.GetMode() { case csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER: @@ -217,90 +256,113 @@ func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.Cre } // process topology - var node string + var providerID string requirements := req.GetAccessibilityRequirements() + // We want to avoid to loop through all nodes twice. + // If this is set, then we can have found a matching node. + var knownNodeName string + if source != nil { if requirements == nil { // In CSI spec, controllers are required that they response OK even if accessibility_requirements field is nil. // So we must create volume, and must not return error response in this case. // - https://github.com/container-storage-interface/spec/blob/release-1.1/spec.md#createvolume // - https://github.com/kubernetes-csi/csi-test/blob/6738ab2206eac88874f0a3ede59b40f680f59f43/pkg/sanity/controller.go#L404-L428 - ctrlLogger.Info("decide node because accessibility_requirements not found") + logger.Info("decide node because accessibility_requirements not found") // the snapshot must be created on the same node as the source - node = sourceVol.Spec.NodeName + providerID = sourceVol.Spec.ProviderID + knownNodeName = sourceVol.Spec.NodeName } else { - sourceNode := sourceVol.Spec.NodeName + sourceProviderID := sourceVol.Spec.ProviderID for _, topo := range requirements.Preferred { - if v, ok := topo.GetSegments()[topolvm.GetTopologyNodeKey()]; ok { - if v == sourceNode { - node = v + if v, ok := topo.GetSegments()[topolvm.ProviderIDLabel]; ok { + if v == sourceProviderID { + providerID = v break } } } - if node == "" { + if providerID == "" { for _, topo := range requirements.Requisite { - if v, ok := topo.GetSegments()[topolvm.GetTopologyNodeKey()]; ok { - if v == sourceNode { - node = v + if v, ok := topo.GetSegments()[topolvm.ProviderIDLabel]; ok { + if v == sourceProviderID { + providerID = v break } } } } - if node == "" { - return nil, status.Errorf(codes.InvalidArgument, "cannot find source volume's node '%s' in accessibility_requirements", sourceNode) + if providerID == "" { + return nil, status.Errorf(codes.InvalidArgument, "cannot find source volume's node in accessibility_requirements (node %q, providerID %q, volume %q)", + sourceVol.Spec.NodeName, sourceVol.Spec.ProviderID, sourceVol.Spec.Name) } } } else { + // source is nil if requirements == nil { // In CSI spec, controllers are required that they response OK even if accessibility_requirements field is nil. // So we must create volume, and must not return error response in this case. // - https://github.com/container-storage-interface/spec/blob/release-1.1/spec.md#createvolume // - https://github.com/kubernetes-csi/csi-test/blob/6738ab2206eac88874f0a3ede59b40f680f59f43/pkg/sanity/controller.go#L404-L428 - ctrlLogger.Info("decide node because accessibility_requirements not found") - nodeName, capacity, err := s.nodeService.GetMaxCapacity(ctx, deviceClass) - + logger.Info("decide node because accessibility_requirements not found") + knownNodeName, capacity, err := s.nodeService.GetMaxCapacity(ctx, deviceClass) if err != nil { return nil, status.Errorf(codes.Internal, "failed to get max capacity node %v", err) } - if nodeName == "" { + if knownNodeName == "" { return nil, status.Error(codes.Internal, "can not find any node") } if capacity < requestCapacityBytes { return nil, status.Errorf(codes.ResourceExhausted, "can not find enough volume space %d", capacity) } - node = nodeName } else { for _, topo := range requirements.Preferred { - if v, ok := topo.GetSegments()[topolvm.GetTopologyNodeKey()]; ok { - node = v + if v, ok := topo.GetSegments()[topolvm.ProviderIDLabel]; ok { + providerID = v break } } - if node == "" { + if providerID == "" { for _, topo := range requirements.Requisite { - if v, ok := topo.GetSegments()[topolvm.GetTopologyNodeKey()]; ok { - node = v + if v, ok := topo.GetSegments()[topolvm.ProviderIDLabel]; ok { + providerID = v break } } } - if node == "" { - return nil, status.Errorf(codes.InvalidArgument, "cannot find key '%s' in accessibility_requirements", topolvm.GetTopologyNodeKey()) + if providerID == "" { + return nil, status.Errorf(codes.InvalidArgument, "cannot find key %q in accessibility_requirements", topolvm.ProviderIDLabel) } } } + if providerID == "" && knownNodeName == "" { + // both knownNodeName and providerID are empty. + return nil, status.Error(codes.Unknown, fmt.Sprintf("CreateVolume failed. No providerID and nodeName found source=%+v requirements=%+v deviceClass=%+v sourceName=%+v", source, + requirements, deviceClass, sourceName)) + } + if knownNodeName != "" && providerID == "" { + providerID, err = node.GetProviderIDByNodeName(ctx, s.kubeClient, knownNodeName) + if err != nil { + return nil, status.Errorf(codes.Internal, "GetProviderID failed (node %q): %s", knownNodeName, err) + } + } + if knownNodeName == "" { + kubeNode, err := node.GetNodeByProviderID(ctx, s.kubeClient, providerID) + if err != nil { + return nil, status.Errorf(codes.Internal, "GetNodeByProviderID failed (providerID %q) %s", providerID, err) + } + knownNodeName = kubeNode.Name + } - name := req.GetName() - if name == "" { + lvName := req.GetName() + if lvName == "" { return nil, status.Error(codes.InvalidArgument, "invalid name") } - name = strings.ToLower(name) + lvName = strings.ToLower(lvName) - volumeID, err := s.lvService.CreateVolume(ctx, node, deviceClass, lvcreateOptionClass, name, sourceName, requestCapacityBytes) + volumeID, err := s.lvService.CreateVolume(ctx, knownNodeName, providerID, deviceClass, lvcreateOptionClass, lvName, sourceName, requestCapacityBytes) if err != nil { _, ok := status.FromError(err) if !ok { @@ -309,6 +371,10 @@ func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.Cre return nil, err } + logger.Info("#################### Syself, CreateVolumeResponse", + "node", knownNodeName, + "providerID", providerID, + "volumeID", volumeID) return &csi.CreateVolumeResponse{ Volume: &csi.Volume{ CapacityBytes: requestCapacityBytes, @@ -316,7 +382,7 @@ func (s controllerServerNoLocked) CreateVolume(ctx context.Context, req *csi.Cre ContentSource: source, AccessibleTopology: []*csi.Topology{ { - Segments: map[string]string{topolvm.GetTopologyNodeKey(): node}, + Segments: map[string]string{topolvm.ProviderIDLabel: providerID}, // syself-fork }, }, }, @@ -366,7 +432,7 @@ func (s controllerServerNoLocked) CreateSnapshot(ctx context.Context, req *csi.C // Since the kubernetes snapshots are Read-Only, we set accessType as 'ro' to activate thin-snapshots as read-only volumes accessType := "ro" - ctrlLogger.Info("CreateSnapshot called", + logger.Info("CreateSnapshot called", "name", req.GetName(), "source_volume_id", req.GetSourceVolumeId(), "parameters", req.GetParameters(), @@ -393,12 +459,11 @@ func (s controllerServerNoLocked) CreateSnapshot(ctx context.Context, req *csi.C Seconds: time.Now().Unix(), Nanos: 0, } - // the snapshots are required to be created in the same node and device class as the source volume. - node := sourceVol.Spec.NodeName + // the snapshots are required to be created in the same nodeName and device class as the source volume. deviceClass := sourceVol.Spec.DeviceClass size := sourceVol.Spec.Size sourceVolName := sourceVol.Spec.Name - snapshotID, err := s.lvService.CreateSnapshot(ctx, node, deviceClass, sourceVolName, name, accessType, size) + snapshotID, err := s.lvService.CreateSnapshot(ctx, sourceVol.Spec.NodeName, sourceVol.Spec.ProviderID, deviceClass, sourceVolName, name, accessType, size) if err != nil { _, ok := status.FromError(err) if !ok { @@ -420,7 +485,7 @@ func (s controllerServerNoLocked) CreateSnapshot(ctx context.Context, req *csi.C // DeleteSnapshot deletes an existing logical volume snapshot. func (s controllerServerNoLocked) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) { - ctrlLogger.Info("DeleteSnapshot called", + logger.Info("DeleteSnapshot called", "snapshot_id", req.GetSnapshotId(), "num_secrets", len(req.GetSecrets())) @@ -429,7 +494,7 @@ func (s controllerServerNoLocked) DeleteSnapshot(ctx context.Context, req *csi.D } if err := s.lvService.DeleteVolume(ctx, req.GetSnapshotId()); err != nil { - ctrlLogger.Error(err, "DeleteSnapshot failed", "snapshot_id", req.GetSnapshotId()) + logger.Error(err, "DeleteSnapshot failed", "snapshot_id", req.GetSnapshotId()) _, ok := status.FromError(err) if !ok { return nil, status.Error(codes.Internal, err.Error()) @@ -499,7 +564,7 @@ func roundDown(size int64, multiple int64) int64 { } func (s controllerServerNoLocked) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) { - ctrlLogger.Info("DeleteVolume called", + logger.Info("DeleteVolume called", "volume_id", req.GetVolumeId(), "num_secrets", len(req.GetSecrets())) if len(req.GetVolumeId()) == 0 { @@ -508,7 +573,7 @@ func (s controllerServerNoLocked) DeleteVolume(ctx context.Context, req *csi.Del err := s.lvService.DeleteVolume(ctx, req.GetVolumeId()) if err != nil { - ctrlLogger.Error(err, "DeleteVolume failed", "volume_id", req.GetVolumeId()) + logger.Error(err, "DeleteVolume failed", "volume_id", req.GetVolumeId()) _, ok := status.FromError(err) if !ok { return nil, status.Error(codes.Internal, err.Error()) @@ -520,7 +585,7 @@ func (s controllerServerNoLocked) DeleteVolume(ctx context.Context, req *csi.Del } func (s controllerServerNoLocked) ValidateVolumeCapabilities(ctx context.Context, req *csi.ValidateVolumeCapabilitiesRequest) (*csi.ValidateVolumeCapabilitiesResponse, error) { - ctrlLogger.Info("ValidateVolumeCapabilities called", + logger.Info("ValidateVolumeCapabilities called", "volume_id", req.GetVolumeId(), "volume_context", req.GetVolumeContext(), "volume_capabilities", req.GetVolumeCapabilities(), @@ -556,12 +621,12 @@ func (s controllerServerNoLocked) ValidateVolumeCapabilities(ctx context.Context func (s controllerServerNoLocked) GetCapacity(ctx context.Context, req *csi.GetCapacityRequest) (*csi.GetCapacityResponse, error) { topology := req.GetAccessibleTopology() capabilities := req.GetVolumeCapabilities() - ctrlLogger.V(1).Info("GetCapacity called", + logger.V(1).Info("GetCapacity called", "volume_capabilities", capabilities, "parameters", req.GetParameters(), "accessible_topology", topology) if capabilities != nil { - ctrlLogger.V(1).Info("capability argument is not nil, but TopoLVM ignores it") + logger.V(1).Info("capability argument is not nil, but TopoLVM ignores it") } deviceClass := req.GetParameters()[topolvm.GetDeviceClassKey()] @@ -575,20 +640,20 @@ func (s controllerServerNoLocked) GetCapacity(ctx context.Context, req *csi.GetC return nil, status.Error(codes.Internal, err.Error()) } default: - v, ok := topology.Segments[topolvm.GetTopologyNodeKey()] + providerID, ok := topology.Segments[topolvm.ProviderIDLabel] if !ok { - err := fmt.Errorf("%s is not found in req.AccessibleTopology", topolvm.GetTopologyNodeKey()) - ctrlLogger.Error(err, "target node key is not found") + err := fmt.Errorf("%s is not found in req.AccessibleTopology", topolvm.ProviderIDLabel) + logger.Error(err, "target node key is not found", "segements", topology.Segments) return &csi.GetCapacityResponse{AvailableCapacity: 0}, nil } var err error - capacity, err = s.nodeService.GetCapacityByTopologyLabel(ctx, v, deviceClass) + capacity, err = s.nodeService.GetCapacityByTopologyLabel(ctx, providerID, deviceClass) switch err { case k8s.ErrNodeNotFound: - ctrlLogger.Info("target is not found", "accessible_topology", req.AccessibleTopology) + logger.Info("target is not found", "accessible_topology", req.AccessibleTopology) return &csi.GetCapacityResponse{AvailableCapacity: 0}, nil case k8s.ErrDeviceClassNotFound: - ctrlLogger.Info("target device class is not found on the specified node", "accessible_topology", req.AccessibleTopology, "device-class", deviceClass) + logger.Info("target device class is not found on the specified node", "accessible_topology", req.AccessibleTopology, "device-class", deviceClass) return &csi.GetCapacityResponse{AvailableCapacity: 0}, nil case nil: default: @@ -604,6 +669,7 @@ func (s controllerServerNoLocked) GetCapacity(ctx context.Context, req *csi.GetC func (s controllerServerNoLocked) ControllerGetCapabilities(context.Context, *csi.ControllerGetCapabilitiesRequest) (*csi.ControllerGetCapabilitiesResponse, error) { capabilities := []csi.ControllerServiceCapability_RPC_Type{ csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME, + csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME, csi.ControllerServiceCapability_RPC_CLONE_VOLUME, csi.ControllerServiceCapability_RPC_GET_CAPACITY, csi.ControllerServiceCapability_RPC_EXPAND_VOLUME, @@ -628,7 +694,7 @@ func (s controllerServerNoLocked) ControllerGetCapabilities(context.Context, *cs func (s controllerServerNoLocked) ControllerExpandVolume(ctx context.Context, req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) { volumeID := req.GetVolumeId() - ctrlLogger.Info("ControllerExpandVolume called", + logger.Info("ControllerExpandVolume called", "volumeID", volumeID, "required", req.GetCapacityRange().GetRequiredBytes(), "limit", req.GetCapacityRange().GetLimitBytes(), diff --git a/internal/driver/controller_test.go b/internal/driver/controller_test.go index 2b32c518c..d6135bd35 100644 --- a/internal/driver/controller_test.go +++ b/internal/driver/controller_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" ) func Test_convertRequestCapacityBytes(t *testing.T) { diff --git a/internal/driver/identity.go b/internal/driver/identity.go index 9d7f425d7..148c3395d 100644 --- a/internal/driver/identity.go +++ b/internal/driver/identity.go @@ -4,7 +4,7 @@ import ( "context" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/wrapperspb" diff --git a/internal/driver/internal/k8s/logicalvolume_service.go b/internal/driver/internal/k8s/logicalvolume_service.go index 9abce1993..c5ff5d0e6 100644 --- a/internal/driver/internal/k8s/logicalvolume_service.go +++ b/internal/driver/internal/k8s/logicalvolume_service.go @@ -6,11 +6,10 @@ import ( "fmt" "time" - "github.com/topolvm/topolvm" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - clientwrapper "github.com/topolvm/topolvm/internal/client" - "github.com/topolvm/topolvm/internal/getter" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + clientwrapper "github.com/syself/csi-topolvm/internal/client" + "github.com/syself/csi-topolvm/internal/getter" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -39,9 +38,7 @@ const ( indexFieldVolumeID = "status.volumeID" ) -var ( - logger = ctrl.Log.WithName("LogicalVolume") -) +var logger = ctrl.Log.WithName("LogicalVolume") type retryMissingGetter struct { cacheReader client.Reader @@ -124,20 +121,11 @@ func (v *volumeGetter) Get(ctx context.Context, volumeID string) (*topolvmv1.Log // NewLogicalVolumeService returns LogicalVolumeService. func NewLogicalVolumeService(mgr manager.Manager) (*LogicalVolumeService, error) { ctx := context.Background() - if topolvm.UseLegacy() { - err := mgr.GetFieldIndexer().IndexField(ctx, &topolvmlegacyv1.LogicalVolume{}, indexFieldVolumeID, func(o client.Object) []string { - return []string{o.(*topolvmlegacyv1.LogicalVolume).Status.VolumeID} - }) - if err != nil { - return nil, err - } - } else { - err := mgr.GetFieldIndexer().IndexField(ctx, &topolvmv1.LogicalVolume{}, indexFieldVolumeID, func(o client.Object) []string { - return []string{o.(*topolvmv1.LogicalVolume).Status.VolumeID} - }) - if err != nil { - return nil, err - } + err := mgr.GetFieldIndexer().IndexField(ctx, &topolvmv1.LogicalVolume{}, indexFieldVolumeID, func(o client.Object) []string { + return []string{o.(*topolvmv1.LogicalVolume).Status.VolumeID} + }) + if err != nil { + return nil, err } client := clientwrapper.NewWrappedClient(mgr.GetClient()) @@ -150,35 +138,36 @@ func NewLogicalVolumeService(mgr manager.Manager) (*LogicalVolumeService, error) } // CreateVolume creates volume -func (s *LogicalVolumeService) CreateVolume(ctx context.Context, node, dc, oc, name, sourceName string, requestBytes int64) (string, error) { - logger.Info("k8s.CreateVolume called", "name", name, "node", node, "size", requestBytes, "sourceName", sourceName) +func (s *LogicalVolumeService) CreateVolume(ctx context.Context, nodeName, providerID, deviceClass, optionClass, lvName, sourceName string, requestBytes int64) (string, error) { + logger.Info("k8s.CreateVolume called", "lvName", lvName, "nodeName", nodeName, "size", requestBytes, "sourceName", sourceName) var lv *topolvmv1.LogicalVolume // if the create volume request has no source, proceed with regular lv creation. if sourceName == "" { lv = &topolvmv1.LogicalVolume{ ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: lvName, }, Spec: topolvmv1.LogicalVolumeSpec{ - Name: name, - NodeName: node, - DeviceClass: dc, - LvcreateOptionClass: oc, + Name: lvName, + NodeName: nodeName, + ProviderID: providerID, + DeviceClass: deviceClass, + LvcreateOptionClass: optionClass, Size: *resource.NewQuantity(requestBytes, resource.BinarySI), }, } - } else { // On the other hand, if a volume has a datasource, create a thin snapshot of the source volume with READ-WRITE access. lv = &topolvmv1.LogicalVolume{ ObjectMeta: metav1.ObjectMeta{ - Name: name, + Name: lvName, }, Spec: topolvmv1.LogicalVolumeSpec{ - Name: name, - NodeName: node, - DeviceClass: dc, - LvcreateOptionClass: oc, + Name: lvName, + NodeName: nodeName, + ProviderID: providerID, + DeviceClass: deviceClass, + LvcreateOptionClass: optionClass, Size: *resource.NewQuantity(requestBytes, resource.BinarySI), Source: sourceName, AccessType: "rw", @@ -187,7 +176,7 @@ func (s *LogicalVolumeService) CreateVolume(ctx context.Context, node, dc, oc, n } existingLV := new(topolvmv1.LogicalVolume) - err := s.getter.Get(ctx, client.ObjectKey{Name: name}, existingLV) + err := s.getter.Get(ctx, client.ObjectKey{Name: lvName}, existingLV) if err != nil { if !apierrors.IsNotFound(err) { return "", err @@ -197,7 +186,7 @@ func (s *LogicalVolumeService) CreateVolume(ctx context.Context, node, dc, oc, n if err != nil { return "", err } - logger.Info("created LogicalVolume CR", "name", name, "sourceID", lv.Spec.Source) + logger.Info("created LogicalVolume CR", "name", lvName, "sourceID", lv.Spec.Source) } else { // LV with same name was found; check compatibility // skip check of capabilities because (1) we allow both of two access types, and (2) we allow only one access mode @@ -207,7 +196,7 @@ func (s *LogicalVolumeService) CreateVolume(ctx context.Context, node, dc, oc, n } // compatible LV was found } - volumeID, err := s.waitForStatusUpdate(ctx, name) + volumeID, err := s.waitForStatusUpdate(ctx, lvName) if err != nil { return "", err } @@ -257,16 +246,23 @@ func (s *LogicalVolumeService) DeleteVolume(ctx context.Context, volumeID string } // CreateSnapshot creates a snapshot of existing volume. -func (s *LogicalVolumeService) CreateSnapshot(ctx context.Context, node, dc, sourceVol, sname, accessType string, snapSize resource.Quantity) (string, error) { - logger.Info("CreateSnapshot called", "name", sname) +func (s *LogicalVolumeService) CreateSnapshot(ctx context.Context, nodeName, providerID, deviceClass, sourceVol, sourceVolName, accessType string, snapSize resource.Quantity) (string, error) { + logger.Info("CreateSnapshot called", + "nodeName", nodeName, + "providerID", providerID, + "deviceClass", deviceClass, + "sourceVolName", sourceVolName, + "snapSize", snapSize, + ) snapshotLV := &topolvmv1.LogicalVolume{ ObjectMeta: metav1.ObjectMeta{ - Name: sname, + Name: sourceVolName, }, Spec: topolvmv1.LogicalVolumeSpec{ - Name: sname, - NodeName: node, - DeviceClass: dc, + Name: sourceVolName, + NodeName: nodeName, + ProviderID: providerID, + DeviceClass: deviceClass, Size: snapSize, Source: sourceVol, AccessType: accessType, @@ -274,7 +270,7 @@ func (s *LogicalVolumeService) CreateSnapshot(ctx context.Context, node, dc, sou } existingSnapshot := new(topolvmv1.LogicalVolume) - err := s.getter.Get(ctx, client.ObjectKey{Name: sname}, existingSnapshot) + err := s.getter.Get(ctx, client.ObjectKey{Name: sourceVolName}, existingSnapshot) if err != nil { if !apierrors.IsNotFound(err) { return "", err @@ -283,14 +279,14 @@ func (s *LogicalVolumeService) CreateSnapshot(ctx context.Context, node, dc, sou if err != nil { return "", err } - logger.Info("created LogicalVolume CR", "name", sname, "source", snapshotLV.Spec.Source, "accessType", snapshotLV.Spec.AccessType) + logger.Info("created LogicalVolume CR", "name", sourceVolName, "source", snapshotLV.Spec.Source, "accessType", snapshotLV.Spec.AccessType) } else { if !existingSnapshot.IsCompatibleWith(snapshotLV) { return "", status.Error(codes.AlreadyExists, "Incompatible LogicalVolume already exists") } } - volumeID, err := s.waitForStatusUpdate(ctx, sname) + volumeID, err := s.waitForStatusUpdate(ctx, sourceVolName) if err != nil { return "", err } @@ -349,6 +345,40 @@ func (s *LogicalVolumeService) GetVolume(ctx context.Context, volumeID string) ( return s.volumeGetter.Get(ctx, volumeID) } +// UpdateNewNodeName updates Updates the CRD LogicalVolume. Retries on conflict. +func (s *LogicalVolumeService) UpdateNewNodeName(ctx context.Context, volumeId string, newNodeName string) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(1 * time.Second): + } + + lv, err := s.GetVolume(ctx, volumeId) + if err != nil { + return fmt.Errorf("lvService.GetVolume failed to get crd logicalvolume with id %q: %s", volumeId, err) + } + oldNodeName := lv.Spec.NodeName + lv.Spec.NodeName = newNodeName + + if err := s.writer.Update(ctx, lv); err != nil { + if apierrors.IsConflict(err) { + logger.Info("detect conflict when LogicalVolume spec update", "name", lv.Name) + continue + } + logger.Error(err, "failed to update LogicalVolume spec", "name", lv.Name) + return err + } + logger.Info("Updated nodeName of crd logicalvolume", + "oldNodeName", oldNodeName, + "newNodeName", newNodeName, + "providerID", lv.Spec.ProviderID, + "volumeId", volumeId, + ) + return nil + } +} + // updateSpecSize updates .Spec.Size of LogicalVolume. func (s *LogicalVolumeService) updateSpecSize(ctx context.Context, volumeID string, size *resource.Quantity) error { for { diff --git a/internal/driver/internal/k8s/node_service.go b/internal/driver/internal/k8s/node_service.go index 4c27367db..bc4d60e1e 100644 --- a/internal/driver/internal/k8s/node_service.go +++ b/internal/driver/internal/k8s/node_service.go @@ -5,15 +5,17 @@ import ( "errors" "strconv" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) // ErrNodeNotFound represents the error that node is not found. -var ErrNodeNotFound = errors.New("node not found") -var ErrDeviceClassNotFound = errors.New("device class not found") +var ( + ErrNodeNotFound = errors.New("node not found") + ErrDeviceClassNotFound = errors.New("device class not found") +) // NodeService represents node service. type NodeService struct { @@ -59,16 +61,16 @@ func (s NodeService) GetCapacityByName(ctx context.Context, name, deviceClass st return s.extractCapacityFromAnnotation(n, deviceClass) } -// GetCapacityByTopologyLabel returns VG capacity of specified node by TopoLVM's topology label. -func (s NodeService) GetCapacityByTopologyLabel(ctx context.Context, topology, dc string) (int64, error) { +// GetCapacityByTopologyLabel returns VG capacity of specified node by TopoLVM's providerID label. +func (s NodeService) GetCapacityByTopologyLabel(ctx context.Context, providerID, dc string) (int64, error) { nl, err := s.getNodes(ctx) if err != nil { return 0, err } for _, node := range nl.Items { - if v, ok := node.Labels[topolvm.GetTopologyNodeKey()]; ok { - if v != topology { + if v, ok := node.Labels[topolvm.ProviderIDLabel]; ok { + if v != providerID { continue } return s.extractCapacityFromAnnotation(&node, dc) diff --git a/internal/driver/node.go b/internal/driver/node.go index 99f44a9eb..61790d09c 100644 --- a/internal/driver/node.go +++ b/internal/driver/node.go @@ -10,29 +10,30 @@ import ( "sync" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/internal/driver/internal/k8s" - "github.com/topolvm/topolvm/internal/filesystem" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/internal/driver/internal/k8s" + "github.com/syself/csi-topolvm/internal/filesystem" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" "golang.org/x/sys/unix" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" mountutil "k8s.io/mount-utils" utilexec "k8s.io/utils/exec" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" ) const ( findmntCmd = "/bin/findmnt" - deviceMode = 0600 | unix.S_IFBLK + deviceMode = 0o600 | unix.S_IFBLK ) var nodeLogger = ctrl.Log.WithName("driver").WithName("node") // NewNodeServer returns a new NodeServer. -func NewNodeServer(nodeName string, vgServiceClient proto.VGServiceClient, lvServiceClient proto.LVServiceClient, mgr manager.Manager) (csi.NodeServer, error) { +func NewNodeServer(nodeName string, providerID string, vgServiceClient proto.VGServiceClient, lvServiceClient proto.LVServiceClient, mgr manager.Manager) (csi.NodeServer, error) { lvService, err := k8s.NewLogicalVolumeService(mgr) if err != nil { return nil, err @@ -41,6 +42,8 @@ func NewNodeServer(nodeName string, vgServiceClient proto.VGServiceClient, lvSer return &nodeServer{ server: &nodeServerNoLocked{ nodeName: nodeName, + providerID: providerID, + kubeClient: mgr.GetClient(), client: vgServiceClient, lvService: lvServiceClient, k8sLVService: lvService, @@ -108,10 +111,12 @@ type nodeServerNoLocked struct { csi.UnimplementedNodeServer nodeName string + providerID string client proto.VGServiceClient lvService proto.LVServiceClient k8sLVService *k8s.LogicalVolumeService mounter mountutil.SafeFormatAndMount + kubeClient client.Client } func (s *nodeServerNoLocked) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) { @@ -216,7 +221,7 @@ func (s *nodeServerNoLocked) nodePublishFilesystemVolume(req *csi.NodePublishVol return err } - err = os.MkdirAll(req.GetTargetPath(), 0755) + err = os.MkdirAll(req.GetTargetPath(), 0o755) if err != nil { return status.Errorf(codes.Internal, "mkdir failed: target=%s, error=%v", req.GetTargetPath(), err) } @@ -239,7 +244,7 @@ func (s *nodeServerNoLocked) nodePublishFilesystemVolume(req *csi.NodePublishVol if err := s.mounter.FormatAndMount(device, req.GetTargetPath(), mountOption.FsType, mountOptions); err != nil { return status.Errorf(codes.Internal, "mount failed: volume=%s, error=%v", req.GetVolumeId(), err) } - if err := os.Chmod(req.GetTargetPath(), 0777|os.ModeSetgid); err != nil { + if err := os.Chmod(req.GetTargetPath(), 0o777|os.ModeSetgid); err != nil { return status.Errorf(codes.Internal, "chmod 2777 failed: target=%s, error=%v", req.GetTargetPath(), err) } } @@ -276,7 +281,7 @@ func (s *nodeServerNoLocked) createDeviceIfNeeded(device string, lv *proto.Logic } fallthrough case unix.ENOENT: - err = os.MkdirAll(path.Dir(device), 0755) + err = os.MkdirAll(path.Dir(device), 0o755) if err != nil { return status.Errorf(codes.Internal, "mkdir failed: target=%s, error=%v", path.Dir(device), err) } @@ -568,12 +573,13 @@ func (s *nodeServerNoLocked) NodeGetCapabilities(context.Context, *csi.NodeGetCa }, nil } +// NodeGetInfo returns the label which gets added to the node. func (s *nodeServerNoLocked) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) { return &csi.NodeGetInfoResponse{ NodeId: s.nodeName, AccessibleTopology: &csi.Topology{ Segments: map[string]string{ - topolvm.GetTopologyNodeKey(): s.nodeName, + topolvm.ProviderIDLabel: s.providerID, }, }, }, nil diff --git a/internal/hook/mutate_persistentvolumeclaim.go b/internal/hook/mutate_persistentvolumeclaim.go index bc082c398..cc6532b4b 100644 --- a/internal/hook/mutate_persistentvolumeclaim.go +++ b/internal/hook/mutate_persistentvolumeclaim.go @@ -5,8 +5,8 @@ import ( "encoding/json" "net/http" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/internal/getter" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/internal/getter" corev1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/internal/hook/mutate_persistentvolumeclaim_test.go b/internal/hook/mutate_persistentvolumeclaim_test.go index 8bd4ba779..7dcc52f93 100644 --- a/internal/hook/mutate_persistentvolumeclaim_test.go +++ b/internal/hook/mutate_persistentvolumeclaim_test.go @@ -3,7 +3,7 @@ package hook import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" diff --git a/internal/hook/mutate_pod.go b/internal/hook/mutate_pod.go index adf244d0c..186460412 100644 --- a/internal/hook/mutate_pod.go +++ b/internal/hook/mutate_pod.go @@ -6,8 +6,8 @@ import ( "net/http" "strconv" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/internal/getter" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/internal/getter" corev1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" apierrs "k8s.io/apimachinery/pkg/api/errors" @@ -208,7 +208,7 @@ func (m *podMutator) pvcCapacity( return "", 0, true, nil } - var requested = topolvm.DefaultSize + requested := topolvm.DefaultSize if req, ok := pvc.Spec.Resources.Requests[corev1.ResourceStorage]; ok { // Only use topolvm.DefaultSize if requested size is not available. // If it is available from spec, use that instead. @@ -244,7 +244,7 @@ func (m *podMutator) ephemeralCapacity( return "", 0, nil } - var requested = topolvm.DefaultSize + requested := topolvm.DefaultSize if req, ok := volumeClaimTemplate.Spec.Resources.Requests[corev1.ResourceStorage]; ok { // Only use topolvm.DefaultSize if requested size is not available. // If it is available from spec, use that instead. diff --git a/internal/hook/mutate_pod_test.go b/internal/hook/mutate_pod_test.go index e20497904..48fca4b2a 100644 --- a/internal/hook/mutate_pod_test.go +++ b/internal/hook/mutate_pod_test.go @@ -5,11 +5,11 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -267,8 +267,8 @@ var _ = Describe("pod mutation webhook", func() { VolumeClaimTemplate: &corev1.PersistentVolumeClaimTemplate{ Spec: corev1.PersistentVolumeClaimSpec{ AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, - StorageClassName: pointer.String(topolvmProvisionerStorageClassName), - Resources: corev1.ResourceRequirements{ + StorageClassName: ptr.To(topolvmProvisionerStorageClassName), + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ "storage": *resource.NewQuantity(100<<30, resource.BinarySI), }, diff --git a/internal/hook/suite_test.go b/internal/hook/suite_test.go index d70520b96..fe7c331b4 100644 --- a/internal/hook/suite_test.go +++ b/internal/hook/suite_test.go @@ -11,7 +11,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" admissionv1 "k8s.io/api/admissionregistration/v1" storagev1 "k8s.io/api/storage/v1" @@ -29,10 +29,12 @@ import ( // These tests use Ginkgo (BDD-style Go testing framework). Refer to // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment -var testCtx, testCancel = context.WithCancel(context.Background()) +var ( + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + testCtx, testCancel = context.WithCancel(context.Background()) +) const ( emptyStorageClassName = "" diff --git a/internal/lvmd/command/lvm.go b/internal/lvmd/command/lvm.go index 90d2aa51e..9f141c725 100644 --- a/internal/lvmd/command/lvm.go +++ b/internal/lvmd/command/lvm.go @@ -6,7 +6,7 @@ import ( "fmt" "path" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" ) const ( @@ -205,8 +205,8 @@ func (vg *VolumeGroup) convertLV(lv lv) *LogicalVolume { // list of tags to add to the volume. // lvcreateOptions are additional arguments to pass to lvcreate. func (vg *VolumeGroup) CreateVolume(ctx context.Context, name string, size uint64, tags []string, stripe uint, stripeSize string, - lvcreateOptions []string) error { - + lvcreateOptions []string, +) error { if size%uint64(topolvm.MinimumSectorSize) != 0 { return ErrNoMultipleOfSectorSize } diff --git a/internal/lvmd/command/lvm_command_test.go b/internal/lvmd/command/lvm_command_test.go index c78185c23..b5717915a 100644 --- a/internal/lvmd/command/lvm_command_test.go +++ b/internal/lvmd/command/lvm_command_test.go @@ -11,8 +11,8 @@ import ( "github.com/go-logr/logr/funcr" "github.com/go-logr/logr/testr" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/internal/lvmd/testutils" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/internal/lvmd/testutils" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log" ) diff --git a/internal/lvmd/command/lvm_state_json_test.go b/internal/lvmd/command/lvm_state_json_test.go index 87989abac..cefb994f0 100644 --- a/internal/lvmd/command/lvm_state_json_test.go +++ b/internal/lvmd/command/lvm_state_json_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/go-logr/logr/testr" - "github.com/topolvm/topolvm/internal/lvmd/testutils" + "github.com/syself/csi-topolvm/internal/lvmd/testutils" ctrl "sigs.k8s.io/controller-runtime" ) @@ -63,7 +63,6 @@ func TestLvmJSON(t *testing.T) { } ` vgs, lvs, err := parseFullReportResult(io.NopCloser(strings.NewReader(goodJSON))) - if err != nil { t.Fatal(err) } @@ -219,7 +218,6 @@ func TestLvmInactiveMajorMinor(t *testing.T) { } ` vgs, lvs, err := parseFullReportResult(io.NopCloser(strings.NewReader(inactiveMajorMinor))) - if err != nil { t.Fatal(err) } @@ -283,7 +281,6 @@ func TestLvmJSONBad(t *testing.T) { if err == nil { t.Fatal("Expected an err, got none") } - } func TestLvmRetrieval(t *testing.T) { @@ -308,7 +305,6 @@ func TestLvmRetrieval(t *testing.T) { defer testutils.CleanLoopbackVG(vgName, []string{loop}, []string{vgName}) vgs, lvs, err := getLVMState(ctx) - if err != nil { t.Fatal("Unexpected err returned: ", err) } diff --git a/internal/lvmd/device_class_manager.go b/internal/lvmd/device_class_manager.go index 55c67be2d..3d2c53d1a 100644 --- a/internal/lvmd/device_class_manager.go +++ b/internal/lvmd/device_class_manager.go @@ -5,8 +5,8 @@ import ( "fmt" "regexp" - "github.com/topolvm/topolvm" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + topolvm "github.com/syself/csi-topolvm" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" ) // ErrDeviceClassNotFound is returned when a VG or LV is not found. @@ -37,7 +37,7 @@ func ValidateDeviceClasses(deviceClasses []*lvmdTypes.DeviceClass) error { if len(deviceClasses) < 1 { return errors.New("should have at least one device-class") } - var countDefault = 0 + countDefault := 0 dcNames := make(map[string]bool) vgNames := make(map[string]bool) for _, dc := range deviceClasses { diff --git a/internal/lvmd/device_class_manager_test.go b/internal/lvmd/device_class_manager_test.go index fde99e2a7..60fc447ee 100644 --- a/internal/lvmd/device_class_manager_test.go +++ b/internal/lvmd/device_class_manager_test.go @@ -4,7 +4,7 @@ import ( "strconv" "testing" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" ) func TestValidateDeviceClasses(t *testing.T) { diff --git a/internal/lvmd/embed.go b/internal/lvmd/embed.go index 4ceccff97..ccc0a966d 100644 --- a/internal/lvmd/embed.go +++ b/internal/lvmd/embed.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" diff --git a/internal/lvmd/embed_test.go b/internal/lvmd/embed_test.go index d64a5b1ad..bae5657dc 100644 --- a/internal/lvmd/embed_test.go +++ b/internal/lvmd/embed_test.go @@ -4,8 +4,8 @@ import ( "context" "testing" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" ) func TestNewEmbeddedServiceClients(t *testing.T) { @@ -14,23 +14,26 @@ func TestNewEmbeddedServiceClients(t *testing.T) { name string deviceClasses []*lvmdTypes.DeviceClass }{ - - {"volumegroup", []*lvmdTypes.DeviceClass{ - { - Name: "dc", - VolumeGroup: "test_vgservice", - }}, + { + "volumegroup", []*lvmdTypes.DeviceClass{ + { + Name: "dc", + VolumeGroup: "test_vgservice", + }, + }, }, - {"thinpool", []*lvmdTypes.DeviceClass{ - { - Name: "dc", - VolumeGroup: "test_vgservice", - Type: lvmdTypes.TypeThin, - ThinPoolConfig: &lvmdTypes.ThinPoolConfig{ - Name: "test_pool", - OverprovisionRatio: overprovisionRatio, + { + "thinpool", []*lvmdTypes.DeviceClass{ + { + Name: "dc", + VolumeGroup: "test_vgservice", + Type: lvmdTypes.TypeThin, + ThinPoolConfig: &lvmdTypes.ThinPoolConfig{ + Name: "test_pool", + OverprovisionRatio: overprovisionRatio, + }, }, - }}, + }, }, } @@ -61,7 +64,6 @@ func TestNewEmbeddedServiceClients(t *testing.T) { if res.FreeBytes != 1 { t.Fatal("no free byte set") } - }) } } diff --git a/internal/lvmd/lvcreate_option_class_manager.go b/internal/lvmd/lvcreate_option_class_manager.go index 3dab93c30..8f21789bb 100644 --- a/internal/lvmd/lvcreate_option_class_manager.go +++ b/internal/lvmd/lvcreate_option_class_manager.go @@ -1,7 +1,7 @@ package lvmd import ( - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" ) type LvcreateOptionClassManager struct { diff --git a/internal/lvmd/lvcreate_option_class_manager_test.go b/internal/lvmd/lvcreate_option_class_manager_test.go index c840ba7d9..e8ac8779a 100644 --- a/internal/lvmd/lvcreate_option_class_manager_test.go +++ b/internal/lvmd/lvcreate_option_class_manager_test.go @@ -4,7 +4,7 @@ import ( "strconv" "testing" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" ) func TestLvcreateOptionClassManager(t *testing.T) { diff --git a/internal/lvmd/lvservice.go b/internal/lvmd/lvservice.go index bfd64d1f7..b83fb2b86 100644 --- a/internal/lvmd/lvservice.go +++ b/internal/lvmd/lvservice.go @@ -6,9 +6,9 @@ import ( "fmt" "math" - "github.com/topolvm/topolvm/internal/lvmd/command" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + "github.com/syself/csi-topolvm/internal/lvmd/command" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "sigs.k8s.io/controller-runtime/pkg/log" @@ -124,7 +124,6 @@ func (s *lvService) CreateLV(ctx context.Context, req *proto.CreateLVRequest) (* } lv, err := vg.FindVolume(ctx, req.GetName()) - if err != nil { logger.Error(err, "failed to find volume", "requested", requested, diff --git a/internal/lvmd/lvservice_test.go b/internal/lvmd/lvservice_test.go index fc252cf01..88c8947b5 100644 --- a/internal/lvmd/lvservice_test.go +++ b/internal/lvmd/lvservice_test.go @@ -8,10 +8,10 @@ import ( "testing" "github.com/go-logr/logr/testr" - "github.com/topolvm/topolvm/internal/lvmd/command" - "github.com/topolvm/topolvm/internal/lvmd/testutils" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + "github.com/syself/csi-topolvm/internal/lvmd/command" + "github.com/syself/csi-topolvm/internal/lvmd/testutils" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ctrl "sigs.k8s.io/controller-runtime" diff --git a/internal/lvmd/vgservice.go b/internal/lvmd/vgservice.go index 668738dea..c2db393f8 100644 --- a/internal/lvmd/vgservice.go +++ b/internal/lvmd/vgservice.go @@ -7,9 +7,9 @@ import ( "math" "sync" - "github.com/topolvm/topolvm/internal/lvmd/command" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + "github.com/syself/csi-topolvm/internal/lvmd/command" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "sigs.k8s.io/controller-runtime/pkg/log" diff --git a/internal/lvmd/vgservice_test.go b/internal/lvmd/vgservice_test.go index 718abbaf6..e556c6317 100644 --- a/internal/lvmd/vgservice_test.go +++ b/internal/lvmd/vgservice_test.go @@ -9,10 +9,10 @@ import ( "time" "github.com/go-logr/logr/testr" - "github.com/topolvm/topolvm/internal/lvmd/command" - "github.com/topolvm/topolvm/internal/lvmd/testutils" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + "github.com/syself/csi-topolvm/internal/lvmd/command" + "github.com/syself/csi-topolvm/internal/lvmd/testutils" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" "google.golang.org/grpc/metadata" ctrl "sigs.k8s.io/controller-runtime" ) @@ -59,23 +59,26 @@ func testWatch(t *testing.T) { name string deviceClasses []*lvmdTypes.DeviceClass }{ - - {"volumegroup", []*lvmdTypes.DeviceClass{ - { - Name: "dc", - VolumeGroup: "test_vgservice", - }}, + { + "volumegroup", []*lvmdTypes.DeviceClass{ + { + Name: "dc", + VolumeGroup: "test_vgservice", + }, + }, }, - {"thinpool", []*lvmdTypes.DeviceClass{ - { - Name: "dc", - VolumeGroup: "test_vgservice", - Type: lvmdTypes.TypeThin, - ThinPoolConfig: &lvmdTypes.ThinPoolConfig{ - Name: "test_pool", - OverprovisionRatio: overprovisionRatio, + { + "thinpool", []*lvmdTypes.DeviceClass{ + { + Name: "dc", + VolumeGroup: "test_vgservice", + Type: lvmdTypes.TypeThin, + ThinPoolConfig: &lvmdTypes.ThinPoolConfig{ + Name: "test_pool", + OverprovisionRatio: overprovisionRatio, + }, }, - }}, + }, }, } @@ -144,7 +147,6 @@ func testWatch(t *testing.T) { case <-time.After(waitDuration * time.Second): t.Fatal("not done") } - }) } } @@ -416,7 +418,6 @@ func testVGService(t *testing.T, vg *command.VolumeGroup) { // Remove thin volumes _ = vg.RemoveVolume(ctx, testp3Vol.Name()) _ = vg.RemoveVolume(ctx, testp4Vol.Name()) - }) } diff --git a/internal/runners/metrics_exporter.go b/internal/runners/metrics_exporter.go index a21903283..0cd7a7b37 100644 --- a/internal/runners/metrics_exporter.go +++ b/internal/runners/metrics_exporter.go @@ -6,8 +6,8 @@ import ( "strconv" "github.com/prometheus/client_golang/prometheus" - "github.com/topolvm/topolvm" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + topolvm "github.com/syself/csi-topolvm" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" diff --git a/internal/scheduler/predicate.go b/internal/scheduler/predicate.go index 29ed6eff0..6e7e6406d 100644 --- a/internal/scheduler/predicate.go +++ b/internal/scheduler/predicate.go @@ -7,7 +7,7 @@ import ( "strings" "sync" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" ) diff --git a/internal/scheduler/predicate_test.go b/internal/scheduler/predicate_test.go index 81bd9363b..ee002f377 100644 --- a/internal/scheduler/predicate_test.go +++ b/internal/scheduler/predicate_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/scheduler/prioritize.go b/internal/scheduler/prioritize.go index 953344807..b496de00a 100644 --- a/internal/scheduler/prioritize.go +++ b/internal/scheduler/prioritize.go @@ -8,7 +8,7 @@ import ( "strings" "sync" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" ) diff --git a/internal/scheduler/prioritize_test.go b/internal/scheduler/prioritize_test.go index d3eabd325..807fb9294 100644 --- a/internal/scheduler/prioritize_test.go +++ b/internal/scheduler/prioritize_test.go @@ -5,7 +5,7 @@ import ( "reflect" "testing" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/internal/scheduler/route_test.go b/internal/scheduler/route_test.go index 53bcc8011..e28fa2846 100644 --- a/internal/scheduler/route_test.go +++ b/internal/scheduler/route_test.go @@ -9,7 +9,7 @@ import ( "strconv" "testing" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/controller/logicalvolume_controller.go b/pkg/controller/logicalvolume_controller.go index 49cae8fab..f2bf60dff 100644 --- a/pkg/controller/logicalvolume_controller.go +++ b/pkg/controller/logicalvolume_controller.go @@ -1,14 +1,17 @@ package controller import ( - internalController "github.com/topolvm/topolvm/internal/controller" - "github.com/topolvm/topolvm/pkg/lvmd/proto" + internalController "github.com/syself/csi-topolvm/internal/controller" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + ctrClient "sigs.k8s.io/controller-runtime/pkg/client" ) // SetupLogicalVolumeReconcilerWithServices creates LogicalVolumeReconciler and sets up with manager. -func SetupLogicalVolumeReconcilerWithServices(mgr ctrl.Manager, client client.Client, nodeName string, vgService proto.VGServiceClient, lvService proto.LVServiceClient) error { - reconciler := internalController.NewLogicalVolumeReconcilerWithServices(client, nodeName, vgService, lvService) +func SetupLogicalVolumeReconcilerWithServices(mgr ctrl.Manager, client ctrClient.Client, nodeName string, providerID string, vgService proto.VGServiceClient, lvService proto.LVServiceClient) error { + reconciler, err := internalController.NewLogicalVolumeReconcilerWithServices(client, nodeName, providerID, vgService, lvService) + if err != nil { + return err + } return reconciler.SetupWithManager(mgr) } diff --git a/pkg/controller/node_controller.go b/pkg/controller/node_controller.go index 6d65e8bd6..b34869365 100644 --- a/pkg/controller/node_controller.go +++ b/pkg/controller/node_controller.go @@ -1,7 +1,7 @@ package controller import ( - internalController "github.com/topolvm/topolvm/internal/controller" + internalController "github.com/syself/csi-topolvm/internal/controller" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/pkg/controller/persistentvolumeclaim_controller.go b/pkg/controller/persistentvolumeclaim_controller.go index 85f285317..65bd9d3d6 100644 --- a/pkg/controller/persistentvolumeclaim_controller.go +++ b/pkg/controller/persistentvolumeclaim_controller.go @@ -1,7 +1,7 @@ package controller import ( - internalController "github.com/topolvm/topolvm/internal/controller" + internalController "github.com/syself/csi-topolvm/internal/controller" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 9cecba272..daed36393 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -1,7 +1,7 @@ package driver import ( - internalDriver "github.com/topolvm/topolvm/internal/driver" + internalDriver "github.com/syself/csi-topolvm/internal/driver" ) // NewControllerServer is an externally consumable wrapper. diff --git a/pkg/driver/identity.go b/pkg/driver/identity.go index f8123d896..f3e52c845 100644 --- a/pkg/driver/identity.go +++ b/pkg/driver/identity.go @@ -1,7 +1,7 @@ package driver import ( - internalDriver "github.com/topolvm/topolvm/internal/driver" + internalDriver "github.com/syself/csi-topolvm/internal/driver" ) var NewIdentityServer = internalDriver.NewIdentityServer diff --git a/pkg/driver/node.go b/pkg/driver/node.go index 0819ec565..6fc9f58ca 100644 --- a/pkg/driver/node.go +++ b/pkg/driver/node.go @@ -1,7 +1,7 @@ package driver import ( - internalDriver "github.com/topolvm/topolvm/internal/driver" + internalDriver "github.com/syself/csi-topolvm/internal/driver" ) var NewNodeServer = internalDriver.NewNodeServer diff --git a/pkg/lvmd/command.go b/pkg/lvmd/command.go index bbdb43b54..d0d916b9a 100644 --- a/pkg/lvmd/command.go +++ b/pkg/lvmd/command.go @@ -1,7 +1,7 @@ package lvmd import ( - internalLvmdCommand "github.com/topolvm/topolvm/internal/lvmd/command" + internalLvmdCommand "github.com/syself/csi-topolvm/internal/lvmd/command" ) func Containerized(sw bool) { diff --git a/pkg/lvmd/embed.go b/pkg/lvmd/embed.go index 83f9920e1..d0d450b5b 100644 --- a/pkg/lvmd/embed.go +++ b/pkg/lvmd/embed.go @@ -3,9 +3,9 @@ package lvmd import ( "context" - internalLvmd "github.com/topolvm/topolvm/internal/lvmd" - "github.com/topolvm/topolvm/pkg/lvmd/proto" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + internalLvmd "github.com/syself/csi-topolvm/internal/lvmd" + "github.com/syself/csi-topolvm/pkg/lvmd/proto" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" ) func NewEmbeddedServiceClients(ctx context.Context, deviceClasses []*lvmdTypes.DeviceClass, LvcreateOptionClasses []*lvmdTypes.LvcreateOptionClass) ( diff --git a/pkg/lvmd/proto/lvmd.pb.go b/pkg/lvmd/proto/lvmd.pb.go index a9e8000dc..c45e58187 100644 --- a/pkg/lvmd/proto/lvmd.pb.go +++ b/pkg/lvmd/proto/lvmd.pb.go @@ -7,7 +7,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: pkg/lvmd/proto/lvmd.proto @@ -1096,10 +1096,10 @@ var file_pkg_lvmd_proto_lvmd_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x30, 0x01, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x76, 0x6d, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x76, - 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6c, 0x76, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x30, 0x01, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x73, 0x79, 0x73, 0x65, 0x6c, 0x66, 0x2f, 0x63, 0x73, 0x69, 0x2d, 0x74, 0x6f, 0x70, + 0x6f, 0x6c, 0x76, 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6c, 0x76, 0x6d, 0x64, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/lvmd/proto/lvmd.proto b/pkg/lvmd/proto/lvmd.proto index 1e4713c33..647128b00 100644 --- a/pkg/lvmd/proto/lvmd.proto +++ b/pkg/lvmd/proto/lvmd.proto @@ -8,7 +8,7 @@ syntax = "proto3"; package proto; -option go_package = "github.com/topolvm/topolvm/pkg/lvmd/proto"; +option go_package = "github.com/syself/csi-topolvm/pkg/lvmd/proto"; message Empty {} diff --git a/pkg/node/node.go b/pkg/node/node.go new file mode 100644 index 000000000..f92047541 --- /dev/null +++ b/pkg/node/node.go @@ -0,0 +1,116 @@ +package node + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + "regexp" + "runtime/debug" + "strings" + "time" + + topolvm "github.com/syself/csi-topolvm" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/retry" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" +) + +func GetNodeByProviderID(ctx context.Context, kubeClient client.Client, providerID string) (*corev1.Node, error) { + if providerID == "" { + return nil, fmt.Errorf("GetNodeByProviderID failed. providerID is empty") + } + + nodeList := &corev1.NodeList{} + if err := kubeClient.List(ctx, nodeList, &client.MatchingLabels{topolvm.ProviderIDLabel: providerID}); err != nil { + return nil, fmt.Errorf("GetNodeByProviderID failed to list nodes: %v", err) + } + l := len(nodeList.Items) + if l == 0 { + // We expect that node has already the appropriate label. The label gets set + // by the node-driver-registrar. + return nil, fmt.Errorf("GetNodeByProviderID failed: No node found with label %s=%s", + topolvm.ProviderIDLabel, providerID) + } + + if l > 2 { + return nil, fmt.Errorf("GetNodeByProviderID failed: More than one node found with label %s=%s", + topolvm.ProviderIDLabel, providerID) + } + return &nodeList.Items[0], nil +} + +// GetProviderIDByNodeName gets the ProviderID from corresponding label of the node +func GetProviderIDByNodeName(ctx context.Context, kubeClient client.Client, nodeName string) (string, error) { + kubeNode, err := GetNodeByName(ctx, kubeClient, nodeName) + if err != nil { + return "", fmt.Errorf("GetNodeByName failed: %w", err) + } + return GetProviderIDByNodeObj(kubeNode) +} + +// GetProviderIDByNodeObj gets the ProviderID from corresponding label of the node +func GetProviderIDByNodeObj(kubeNode *corev1.Node) (string, error) { + labelValue, ok := kubeNode.Labels[topolvm.ProviderIDLabel] + if ok { + if labelValue == "" { + return "", fmt.Errorf("empty label %q Node %q", topolvm.ProviderIDLabel, kubeNode.Name) + } + return labelValue, nil + } + // Looks like the first volume on that node. The label does not exist yet. + if kubeNode.Spec.ProviderID == "" { + return "", fmt.Errorf("label %q not found on Node %q, and spec.providerID empty", topolvm.ProviderIDLabel, kubeNode.Name) + } + return sanitizeProviderIDLabelValue(kubeNode.Spec.ProviderID), nil +} + +// sanitizeProviderIDLabelValue converts an arbitrary string into a valid Kubernetes label value. +func sanitizeProviderIDLabelValue(input string) string { + if strings.HasPrefix(input, "hcloud://bm-") { + input = "hetzner-" + strings.TrimPrefix(input, "hcloud://bm-") + } + invalidCharRegex := regexp.MustCompile(`[^a-zA-Z0-9-_.]`) + transformed := invalidCharRegex.ReplaceAllString(input, "-") + transformed = regexp.MustCompile(`-+`).ReplaceAllString(transformed, "-") + transformed = strings.Trim(transformed, "-_.") + if len(transformed) > 63 { + hasher := sha256.New() + hasher.Write([]byte(transformed)) + hashed := hasher.Sum(nil) + transformed = hex.EncodeToString(hashed)[:63] + } + transformed = strings.TrimRight(transformed, "-_.") + return transformed +} + +// GetNodeByName returns the Node by name. +func GetNodeByName(ctx context.Context, kubeClient client.Client, nodeName string) (*corev1.Node, error) { + nodeObj := &corev1.Node{} + nn := types.NamespacedName{Name: nodeName} + + logger := log.FromContext(ctx) + err := retry.OnError(wait.Backoff{ + Steps: 10, + Duration: 100 * time.Millisecond, + Factor: 2.0, + Jitter: 0.1, + }, + func(err error) bool { + logger.Info("getNodeByName failed, retrying (just info)", + "err", err, + "stack", string(debug.Stack()), + ) + return true + }, func() error { + return kubeClient.Get(ctx, nn, nodeObj) + }) + if err != nil { + return nil, fmt.Errorf("failed to get node %q: %w", nodeName, err) + } + return nodeObj, nil +} diff --git a/pkg/node/node_test.go b/pkg/node/node_test.go new file mode 100644 index 000000000..5f62740dc --- /dev/null +++ b/pkg/node/node_test.go @@ -0,0 +1,22 @@ +package node + +import ( + "strings" + "testing" +) + +func Test_sanitizeProviderIDLabelValue(t *testing.T) { + for _, tt := range []struct { + providerID string + expected string + }{ + {"hcloud://bm-2105469", "hetzner-2105469"}, + {"--foo..bar--baz__bu//:ö_", "foo..bar-baz__bu"}, + {strings.Repeat("a", 65), "635361c48bb9eab14198e76ea8ab7f1a41685d6ad62aa9146d301d4f17eb0ae"}, + } { + actual := sanitizeProviderIDLabelValue(tt.providerID) + if actual != tt.expected { + t.Errorf("sanitizeProviderIDLabelValue(%q) -> %q is not good. Expected %q", tt.providerID, actual, tt.expected) + } + } +} diff --git a/pkg/runners/grpc.go b/pkg/runners/grpc.go index be3e48dbb..cb2e4382a 100644 --- a/pkg/runners/grpc.go +++ b/pkg/runners/grpc.go @@ -1,7 +1,7 @@ package runners import ( - internalRunners "github.com/topolvm/topolvm/internal/runners" + internalRunners "github.com/syself/csi-topolvm/internal/runners" ) var NewGRPCRunner = internalRunners.NewGRPCRunner diff --git a/pkg/runners/metrics_exporter.go b/pkg/runners/metrics_exporter.go index 65c207091..463850995 100644 --- a/pkg/runners/metrics_exporter.go +++ b/pkg/runners/metrics_exporter.go @@ -1,7 +1,7 @@ package runners import ( - internalRunners "github.com/topolvm/topolvm/internal/runners" + internalRunners "github.com/syself/csi-topolvm/internal/runners" ) var NewMetricsExporter = internalRunners.NewMetricsExporter diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index f6d7e2132..69e1f815e 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -11,9 +11,9 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - "github.com/topolvm/topolvm/cmd/topolvm-controller/app" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + "github.com/syself/csi-topolvm/cmd/topolvm-controller/app" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) diff --git a/test/e2e/helper_test.go b/test/e2e/helper_test.go index 6bb483d4f..84a77e9cd 100644 --- a/test/e2e/helper_test.go +++ b/test/e2e/helper_test.go @@ -15,8 +15,8 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" corev1 "k8s.io/api/core/v1" ) diff --git a/test/e2e/logical_volume_test.go b/test/e2e/logical_volume_test.go index e19d6a35d..5d7429562 100644 --- a/test/e2e/logical_volume_test.go +++ b/test/e2e/logical_volume_test.go @@ -8,9 +8,8 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" . "github.com/onsi/gomega" - topolvmlegacyv1 "github.com/topolvm/topolvm/api/legacy/v1" - topolvmv1 "github.com/topolvm/topolvm/api/v1" - clientwrapper "github.com/topolvm/topolvm/internal/client" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" + clientwrapper "github.com/syself/csi-topolvm/internal/client" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -108,7 +107,6 @@ func createK8sClient() client.Client { scheme := runtime.NewScheme() utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(topolvmv1.AddToScheme(scheme)) - utilruntime.Must(topolvmlegacyv1.AddToScheme(scheme)) k8sClient, err := client.New(config, client.Options{Scheme: scheme}) Expect(err).ShouldNot(HaveOccurred()) return clientwrapper.NewWrappedClient(k8sClient) diff --git a/test/e2e/lvcreate_options_test.go b/test/e2e/lvcreate_options_test.go index bd24b8a82..1253a1464 100644 --- a/test/e2e/lvcreate_options_test.go +++ b/test/e2e/lvcreate_options_test.go @@ -7,7 +7,7 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" . "github.com/onsi/gomega" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" corev1 "k8s.io/api/core/v1" ) diff --git a/test/e2e/manifests/values/legacy.yaml b/test/e2e/manifests/values/legacy.yaml deleted file mode 100644 index ae0efc2ba..000000000 --- a/test/e2e/manifests/values/legacy.yaml +++ /dev/null @@ -1,9 +0,0 @@ -controller: - # sanity test requires that the controller mounts this hostPath to communicate with it - volumes: - - name: socket-dir - hostPath: - path: /var/lib/kubelet/plugins/topolvm.cybozu.com/controller - type: DirectoryOrCreate - -useLegacy: true diff --git a/test/e2e/metrics_test.go b/test/e2e/metrics_test.go index 89026a4fe..6beb945ff 100644 --- a/test/e2e/metrics_test.go +++ b/test/e2e/metrics_test.go @@ -14,9 +14,9 @@ import ( . "github.com/onsi/gomega" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" - lvmdApp "github.com/topolvm/topolvm/cmd/lvmd/app" - "github.com/topolvm/topolvm/internal/lvmd" - lvmdTypes "github.com/topolvm/topolvm/pkg/lvmd/types" + lvmdApp "github.com/syself/csi-topolvm/cmd/lvmd/app" + "github.com/syself/csi-topolvm/internal/lvmd" + lvmdTypes "github.com/syself/csi-topolvm/pkg/lvmd/types" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/yaml" ) diff --git a/test/e2e/multiple_vg_test.go b/test/e2e/multiple_vg_test.go index 4e728e3cc..8b7bc25fc 100644 --- a/test/e2e/multiple_vg_test.go +++ b/test/e2e/multiple_vg_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" . "github.com/onsi/gomega" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" corev1 "k8s.io/api/core/v1" ) diff --git a/test/e2e/node_delete_test.go b/test/e2e/node_delete_test.go index 6f43ff19b..54250e696 100644 --- a/test/e2e/node_delete_test.go +++ b/test/e2e/node_delete_test.go @@ -7,8 +7,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" - topolvmv1 "github.com/topolvm/topolvm/api/v1" + topolvm "github.com/syself/csi-topolvm" + topolvmv1 "github.com/syself/csi-topolvm/api/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -20,7 +20,6 @@ const nsNodeDeleteTest = "node-delete-test" var statefulSetTemplateYAML string func testNodeDelete() { - BeforeEach(func() { skipIfSingleNode() diff --git a/test/e2e/sanity_test.go b/test/e2e/sanity_test.go index d08db9491..d5b14525f 100644 --- a/test/e2e/sanity_test.go +++ b/test/e2e/sanity_test.go @@ -6,7 +6,7 @@ import ( "github.com/kubernetes-csi/csi-test/v5/pkg/sanity" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" appsv1 "k8s.io/api/apps/v1" ) @@ -68,7 +68,7 @@ func testSanity() { } thinTC = tc - // csi.storage.k8s.io/fstype=xfs,topolvm.(io|cybozu.com)/device-class=thin + // csi.storage.k8s.io/fstype=xfs,topolvm.io/device-class=thin thinTC.TestVolumeParameters = map[string]string{ "csi.storage.k8s.io/fstype": "xfs", topolvm.GetDeviceClassKey(): "thin", diff --git a/test/e2e/scheduling_test.go b/test/e2e/scheduling_test.go index 93de2d6ea..dc77b34bb 100644 --- a/test/e2e/scheduling_test.go +++ b/test/e2e/scheduling_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/topolvm/topolvm" + topolvm "github.com/syself/csi-topolvm" corev1 "k8s.io/api/core/v1" ) diff --git a/test/util/testing.go b/test/util/testing.go deleted file mode 100644 index 34e1259e3..000000000 --- a/test/util/testing.go +++ /dev/null @@ -1,12 +0,0 @@ -package util - -import ( - "os" - "testing" -) - -func DoEnvCheck(t *testing.T) { - if os.Getenv("TEST_LEGACY") == "" { - t.Skip("Run test using TEST_LEGACY env") - } -}