diff --git a/.github/actions/deploy-operator/action.yaml b/.github/actions/deploy-operator/action.yaml index 4ba2778c4..de8ed8a5b 100644 --- a/.github/actions/deploy-operator/action.yaml +++ b/.github/actions/deploy-operator/action.yaml @@ -16,13 +16,39 @@ runs: - name: Install cert-manager shell: bash run: | + cert_manager_version="" + kube_min_version=$(kubectl version --output=yaml | yq '.serverVersion.minor') + if [ ${kube_min_version} -le 21 ]; then + cert_manager_version="v1.11.5" + fi + if [ ${kube_min_version} -le 20 ]; then + cert_manager_version="v1.10.2" + fi + if [ ${kube_min_version} -le 19 ]; then + cert_manager_version="v1.8.2" + fi + if [ ${kube_min_version} -le 18 ]; then + cert_manager_version="v1.7.3" + fi + if [ ${kube_min_version} -le 17 ]; then + cert_manager_version="v1.6.3" + fi + if [ ${kube_min_version} -le 16 ]; then + cert_manager_version="v1.5.5" + fi + if [ ${kube_min_version} -le 15 ]; then + echo "Kubernetes version is too low, please upgrade to 1.15+" + exit 1 + fi + helm repo add jetstack https://charts.jetstack.io helm repo update helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ - --set installCRDs=true + --set installCRDs=true \ + --version "$cert_manager_version" - name: Deploy operator by helm shell: bash run: | diff --git a/.github/workflows/build-reloader-image.yaml b/.github/workflows/build-reloader-image.yaml index 252d170f2..15c454591 100644 --- a/.github/workflows/build-reloader-image.yaml +++ b/.github/workflows/build-reloader-image.yaml @@ -28,21 +28,21 @@ jobs: else echo "::set-output name=registry::ghcr.io" fi - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 - - uses: docker/login-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 if: github.ref_type == 'tag' with: registry: docker.io username: ${{ secrets.DOCKER_HUB_USER }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - - uses: docker/login-action@v2 + - uses: docker/login-action@v3 if: github.ref_type == 'branch' with: registry: ghcr.io username: ${{ github.actor }} password: ${{ github.token }} - - uses: docker/metadata-action@v4 + - uses: docker/metadata-action@v5 id: meta with: images: ${{ steps.registry.outputs.registry }}/${{ github.repository }}-reloader @@ -50,7 +50,7 @@ jobs: latest=true tags: | type=semver,pattern={{version}},value=${{ steps.version.outputs.version }} - - uses: docker/build-push-action@v3 + - uses: docker/build-push-action@v5 with: push: true pull: true diff --git a/.github/workflows/cts.yaml b/.github/workflows/cts.yaml index 5e6282630..9d5d91827 100644 --- a/.github/workflows/cts.yaml +++ b/.github/workflows/cts.yaml @@ -18,6 +18,8 @@ jobs: - minikube - k3s kubernetes-version: + - "v1.20.0" + - "v1.21.0" - "v1.22.0" - "v1.23.0" - "v1.24.0" @@ -59,17 +61,17 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: docker/setup-buildx-action@v2 - - uses: docker/setup-qemu-action@v2 + - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-qemu-action@v3 with: image: tonistiigi/binfmt:latest platforms: all - - uses: docker/login-action@v2 + - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ github.token }} - - uses: docker/metadata-action@v4 + - uses: docker/metadata-action@v5 id: meta with: images: ghcr.io/${{ github.repository }} @@ -79,7 +81,7 @@ jobs: type=ref,event=branch type=ref,event=tag type=semver,pattern={{version}} - - uses: docker/build-push-action@v3 + - uses: docker/build-push-action@v5 with: push: true pull: true @@ -100,6 +102,8 @@ jobs: - minikube - k3s kubernetes-version: + - "v1.20.0" + - "v1.21.0" - "v1.22.0" - "v1.23.0" - "v1.24.0" @@ -144,7 +148,7 @@ jobs: - name: Make sure all of pods can be deleted run: | kubectl delete ${{ matrix.emqx[0] }} ${{ matrix.emqx[1] }} - kubectl wait --for=delete pods -l "apps.emqx.io/instance=${{ matrix.emqx[1] }}" + kubectl wait --for=delete pods -l "apps.emqx.io/instance=${{ matrix.emqx[1] }}" --timeout=300s - if: failure() run: kubectl logs -l "control-plane=controller-manager" -n emqx-operator-system -c manager --tail=1000 - if: failure() diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 773ecdb82..b7b22a600 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,9 +26,9 @@ jobs: echo "Need update appVersion for Chart.yaml" exit 1 fi - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 - - uses: docker/metadata-action@v4 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + - uses: docker/metadata-action@v5 id: meta with: images: ${{ github.repository_owner }}/emqx-operator-controller @@ -38,12 +38,12 @@ jobs: type=ref,event=tag type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - - uses: docker/login-action@v2 + - uses: docker/login-action@v3 if: startsWith(github.ref, 'refs/tags/') with: username: ${{ secrets.DOCKER_HUB_USER }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - - uses: docker/build-push-action@v3 + - uses: docker/build-push-action@v5 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 push: ${{ startsWith(github.ref, 'refs/tags/') }} diff --git a/config/samples/emqx/v2beta1/emqx-full.yaml b/config/samples/emqx/v2beta1/emqx-full.yaml index f19d7125b..eba9b272f 100644 --- a/config/samples/emqx/v2beta1/emqx-full.yaml +++ b/config/samples/emqx/v2beta1/emqx-full.yaml @@ -20,7 +20,6 @@ spec: apps.emqx.io/instance: emqx apps.emqx.io/managed-by: emqx-operator apps.emqx.io/db-role: core - annotations: spec: replicas: 2 volumeClaimTemplates: diff --git a/controllers/apps/v2beta1/add_pdb.go b/controllers/apps/v2beta1/add_pdb.go index 58cd15110..8b30ce658 100644 --- a/controllers/apps/v2beta1/add_pdb.go +++ b/controllers/apps/v2beta1/add_pdb.go @@ -4,14 +4,19 @@ import ( "context" emperror "emperror.dev/errors" + semver "github.com/Masterminds/semver/v3" appsv2beta1 "github.com/emqx/emqx-operator/apis/apps/v2beta1" innerReq "github.com/emqx/emqx-operator/internal/requester" "github.com/go-logr/logr" policyv1 "k8s.io/api/policy/v1" + policyv1beta1 "k8s.io/api/policy/v1beta1" k8sErrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/discovery" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + kubeConfig "sigs.k8s.io/controller-runtime/pkg/client/config" ) type addPdb struct { @@ -19,7 +24,25 @@ type addPdb struct { } func (a *addPdb) reconcile(ctx context.Context, logger logr.Logger, instance *appsv2beta1.EMQX, _ innerReq.RequesterInterface) subResult { - pdbList := generatePodDisruptionBudget(instance) + discoveryClient, _ := discovery.NewDiscoveryClientForConfig(kubeConfig.GetConfigOrDie()) + kubeVersion, _ := discoveryClient.ServerVersion() + v, _ := semver.NewVersion(kubeVersion.String()) + + pdbList := []client.Object{} + if v.LessThan(semver.MustParse("1.21")) { + corePdb, replPdb := generatePodDisruptionBudgetV1beta1(instance) + pdbList = append(pdbList, corePdb) + if replPdb != nil { + pdbList = append(pdbList, replPdb) + } + } else { + corePdb, replPdb := generatePodDisruptionBudget(instance) + pdbList = append(pdbList, corePdb) + if replPdb != nil { + pdbList = append(pdbList, replPdb) + } + } + for _, pdb := range pdbList { if err := ctrl.SetControllerReference(instance, pdb, a.Scheme); err != nil { return subResult{err: emperror.Wrap(err, "failed to set controller reference")} @@ -33,8 +56,7 @@ func (a *addPdb) reconcile(ctx context.Context, logger logr.Logger, instance *ap return subResult{} } -func generatePodDisruptionBudget(instance *appsv2beta1.EMQX) []*policyv1.PodDisruptionBudget { - pdbList := []*policyv1.PodDisruptionBudget{} +func generatePodDisruptionBudget(instance *appsv2beta1.EMQX) (*policyv1.PodDisruptionBudget, *policyv1.PodDisruptionBudget) { corePdb := &policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ APIVersion: "policy/v1", @@ -58,7 +80,6 @@ func generatePodDisruptionBudget(instance *appsv2beta1.EMQX) []*policyv1.PodDisr }, }, } - pdbList = append(pdbList, corePdb) if appsv2beta1.IsExistReplicant(instance) { replPdb := corePdb.DeepCopy() replPdb.Name = instance.ReplicantNamespacedName().Name @@ -66,7 +87,43 @@ func generatePodDisruptionBudget(instance *appsv2beta1.EMQX) []*policyv1.PodDisr appsv2beta1.DefaultReplicantLabels(instance), instance.Spec.ReplicantTemplate.Labels, ) - pdbList = append(pdbList, replPdb) + return corePdb, replPdb + } + return corePdb, nil +} + +func generatePodDisruptionBudgetV1beta1(instance *appsv2beta1.EMQX) (*policyv1beta1.PodDisruptionBudget, *policyv1beta1.PodDisruptionBudget) { + corePdb := &policyv1beta1.PodDisruptionBudget{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "policy/v1", + Kind: "PodDisruptionBudget", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: instance.Namespace, + Name: instance.CoreNamespacedName().Name, + Labels: appsv2beta1.CloneAndMergeMap(appsv2beta1.DefaultLabels(instance), instance.Labels), + }, + Spec: policyv1beta1.PodDisruptionBudgetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: appsv2beta1.CloneAndMergeMap( + appsv2beta1.DefaultCoreLabels(instance), + instance.Spec.CoreTemplate.Labels, + ), + }, + MinAvailable: &intstr.IntOrString{ + Type: intstr.Int, + IntVal: 1, + }, + }, + } + if appsv2beta1.IsExistReplicant(instance) { + replPdb := corePdb.DeepCopy() + replPdb.Name = instance.ReplicantNamespacedName().Name + replPdb.Spec.Selector.MatchLabels = appsv2beta1.CloneAndMergeMap( + appsv2beta1.DefaultReplicantLabels(instance), + instance.Spec.ReplicantTemplate.Labels, + ) + return corePdb, replPdb } - return pdbList + return corePdb, nil }