From 130ab7c1f5ec7b6a68fefba523428ac8906f8634 Mon Sep 17 00:00:00 2001 From: Adam Kaplan Date: Tue, 10 Dec 2024 17:27:41 -0500 Subject: [PATCH] chore: Code and Tool Updates From Dep Bumps Updated `main.go` and the ShipwrightBuild controller test code to use latest controller-runtime APIs (update included breaking changes). Leaving the rest of the toolchain as is led to panics when generating manifests with controller-gen. Therefore decided to update the remaining tools to align with k8s 1.30.z: - controller-gen to v0.15.0 - setup-envtest to release-0.18 - kustomize to v5.5.0 (most recent version) This in turn required manifests to be regenerated. Operator-sdk was left intact, as this does not appear to break with these updates. Likewise updated Makefile and CI GitHub action to use golang 1.22 and k8s 1.30, to ensure the version of k8s the operator tests with matches the shipwright-io/build project version. Documentation for local and OLM development updated to use latest versions of tools/operators - notably updating Tekton Opertor to v0.74.0. Signed-off-by: Adam Kaplan --- .github/workflows/ci.yml | 10 +-- Makefile | 12 +-- api/v1alpha1/zz_generated.deepcopy.go | 1 - ...erator.shipwright.io_shipwrightbuilds.yaml | 82 +++++++++--------- ...erator.shipwright.io_shipwrightbuilds.yaml | 85 +++++++++---------- config/rbac/role.yaml | 1 - config/subscription/subscription.yaml | 2 +- .../shipwrightbuild_controller_test.go | 2 +- docs/development/local-development.md | 6 +- docs/development/olm-development.md | 2 +- main.go | 12 ++- 11 files changed, 112 insertions(+), 103 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58c44285..946d9cf1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x cache: true check-latest: true - name: Build @@ -37,7 +37,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x cache: true check-latest: true - name: Verify fmt @@ -60,7 +60,7 @@ jobs: # Kubernetes version must match a built KinD node image. # See release notes in https://github.com/kubernetes-sigs/kind/releases for supported # node image versions. - - v1.24.15 + - v1.30.6 max-parallel: 2 runs-on: ubuntu-latest steps: @@ -69,7 +69,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.21.x + go-version: 1.22.x cache: true check-latest: true - name: Install kubectl @@ -81,7 +81,7 @@ jobs: - name: Create KinD cluster uses: helm/kind-action@v1 with: - version: v0.20.0 + version: v0.25.0 node_image: kindest/node:${{ matrix.kubernetes }} cluster_name: kind config: test/kind/config.yaml diff --git a/Makefile b/Makefile index 70e1ad57..a170d682 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,7 @@ endif # Image URL to use all building/pushing image targets IMG ?= $(IMAGE_TAG_BASE):$(TAG) # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.27 +ENVTEST_K8S_VERSION = 1.30 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -205,19 +205,19 @@ bin-dir: ## Creates a local "bin" directory for helper applications. CONTROLLER_GEN = $(shell pwd)/bin/controller-gen .PHONY: controller-gen controller-gen: ## Download controller-gen locally if necessary. - $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0) + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.15.0) KUSTOMIZE = $(shell pwd)/bin/kustomize .PHONY: kustomize kustomize: ## Download kustomize locally if necessary. - $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v4@v4.5.4) + $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5@v5.5.0) -# Starting in 0.18, setup-envtest requires golang 1.22+. Pinning to `release-0.17`, which requires golang 1.20+. -# TODO: Return to using `@latest` once we upgrade golang to 1.22. +# Starting in 0.18, setup-envtest requires a golang that aligns with the associated k8s version +# For k8s 1.30.z, the golang version is v1.22 ENVTEST = $(shell pwd)/bin/setup-envtest .PHONY: envtest envtest: ## Download envtest-setup locally if necessary. - $(call go-get-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.17) + $(call go-get-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.18) OPERATOR_SDK = $(shell pwd)/bin/operator-sdk diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index f3b4c3a8..68890bb4 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Copyright The Shipwright Contributors // diff --git a/bundle/manifests/operator.shipwright.io_shipwrightbuilds.yaml b/bundle/manifests/operator.shipwright.io_shipwrightbuilds.yaml index 1bb04b7d..4e74d608 100644 --- a/bundle/manifests/operator.shipwright.io_shipwrightbuilds.yaml +++ b/bundle/manifests/operator.shipwright.io_shipwrightbuilds.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 + controller-gen.kubebuilder.io/version: v0.15.0 creationTimestamp: null name: shipwrightbuilds.operator.shipwright.io spec: @@ -21,14 +21,19 @@ spec: controller on a Kubernetes cluster. 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 @@ -49,42 +54,42 @@ spec: a resource's current state. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -98,11 +103,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -124,5 +130,5 @@ status: acceptedNames: kind: "" plural: "" - conditions: [] - storedVersions: [] + conditions: null + storedVersions: null diff --git a/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml b/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml index e2fc4e34..d9520acf 100644 --- a/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml +++ b/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: shipwrightbuilds.operator.shipwright.io spec: group: operator.shipwright.io @@ -22,14 +21,19 @@ spec: controller on a Kubernetes cluster. 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 @@ -50,42 +54,42 @@ spec: a resource's current state. items: description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -99,11 +103,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -121,9 +126,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 6616ac94..600eb5e8 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -2,7 +2,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: manager-role rules: - apiGroups: diff --git a/config/subscription/subscription.yaml b/config/subscription/subscription.yaml index 131bb63a..618d4877 100644 --- a/config/subscription/subscription.yaml +++ b/config/subscription/subscription.yaml @@ -9,4 +9,4 @@ spec: source: shipwright-operator sourceNamespace: shipwright-operator installPlanApproval: Automatic - startingCSV: shipwright-operator.v0.12.0 + startingCSV: shipwright-operator.v0.14.0-rc0 diff --git a/controllers/shipwrightbuild_controller_test.go b/controllers/shipwrightbuild_controller_test.go index 4031243e..6ca82927 100644 --- a/controllers/shipwrightbuild_controller_test.go +++ b/controllers/shipwrightbuild_controller_test.go @@ -47,7 +47,7 @@ func bootstrapShipwrightBuildReconciler( logger := zap.New() - c := fake.NewFakeClientWithScheme(s, b) //nolint:golint,staticcheck + c := fake.NewClientBuilder().WithScheme(s).WithObjects(b).Build() var crdClient *crdclientv1.Clientset var toClient *tektonoperatorv1alpha1client.Clientset if len(tcrds) > 0 { diff --git a/docs/development/local-development.md b/docs/development/local-development.md index 1a6961d1..fd6e4435 100644 --- a/docs/development/local-development.md +++ b/docs/development/local-development.md @@ -34,12 +34,12 @@ Refer to the [ko documentation](https://ko.build/) for more information. To test the operator on a Kubernetes cluster, you first must have the following: -* Access to a Kubernetes cluster v1.20 or higher, with cluster admin permissions. -* Install [Tekton operator](https://github.com/tektoncd/operator) v0.50 or higher on the cluster. +* Access to a Kubernetes cluster v1.30 or higher, with cluster admin permissions. +* Install [Tekton operator](https://github.com/tektoncd/operator) v0.74.0 or higher on the cluster. ```bash $ export KUBECONFIG=/path/to/kubeconfig -$ kubectl apply -f https://github.com/tektoncd/pipeline/releases/download/v0.21.0/release.notags.yaml +$ kubectl apply -f https://github.com/tektoncd/operator/releases/download/v0.74.0/release.notags.yaml ``` If pushing to an external image registry, you may need to provide credentials to ko: diff --git a/docs/development/olm-development.md b/docs/development/olm-development.md index 8b5478ef..0a21d5d8 100644 --- a/docs/development/olm-development.md +++ b/docs/development/olm-development.md @@ -9,7 +9,7 @@ Additional steps need to be taken to ensure the operator can be deployed with OL ## Prerequisites * Ensure you have access to a Kubernetes cluster via `kubectl` with cluster admin permissions. -* Install [Go](https://go.dev/doc/install) version 1.21 or higher. +* Install [Go](https://go.dev/doc/install) version 1.22 or higher. * Install OLM on your cluster. This can be done using the `make install-olm` command. * Ability to push to a container registry that is accessible inside your Kubernetes cluster. diff --git a/main.go b/main.go index c19dc685..a9e6d130 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,8 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" tektonoperatorv1alpha1client "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1" @@ -70,9 +72,13 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - MetricsBindAddress: metricsAddr, - Port: webhookPort, + Scheme: scheme, + Metrics: server.Options{ + BindAddress: metricsAddr, + }, + WebhookServer: webhook.NewServer(webhook.Options{ + Port: webhookPort, + }), HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "01a9b2d1.shipwright.io",