feat(operator): several updates (#806)
- prepare to switch from `master` to `main` - avoid to run workflow in case is not needed - add a way to bump the lts via make - use latest jenkins lts 2.387.1 - add the docker labels - update base plugins - fix #797 - Add more tests with bats - Update base plugin to latest version - Temporary revert #807 - Better nightly job
This commit is contained in:
		
							parent
							
								
									e36441a4a2
								
							
						
					
					
						commit
						9fd053b784
					
				|  | @ -5,6 +5,11 @@ on: | ||||||
|   push: |   push: | ||||||
|     branches: |     branches: | ||||||
|       - master |       - master | ||||||
|  |       - main | ||||||
|  |     paths: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   # Set the job key. The key is displayed as the job name |   # Set the job key. The key is displayed as the job name | ||||||
|  |  | ||||||
|  | @ -0,0 +1,61 @@ | ||||||
|  | name: Run bats tests | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |       - main | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
|  |       - 'backup/**' | ||||||
|  |       - '*.md' | ||||||
|  |   pull_request: | ||||||
|  |     types: [opened, synchronize, ready_for_review, reopened] | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
|  |       - 'backup/**' | ||||||
|  |       - '*.md' | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   run-tests: | ||||||
|  |     if: github.event.pull_request.draft == false | ||||||
|  |     name: Run automated bats tests | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Check out code | ||||||
|  |         uses: actions/checkout@v3 | ||||||
|  | 
 | ||||||
|  |       - name: Set up env vars | ||||||
|  |         run: | | ||||||
|  |           echo "GO111MODULE=on" >> $GITHUB_ENV | ||||||
|  |           echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|  |           echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|  |           echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|  |           echo "GOPATH=/home/runner/go" >> $GITHUB_ENV | ||||||
|  | 
 | ||||||
|  |       - name: Prepare go environment | ||||||
|  |         uses: actions/setup-go@v2 | ||||||
|  |         with: | ||||||
|  |           go-version: ${{ env.GO_VERSION }} | ||||||
|  | 
 | ||||||
|  |       - name: Ensure Golang runtime dependencies | ||||||
|  |         run: make go-dependencies | ||||||
|  | 
 | ||||||
|  |       - name: Setup BATS | ||||||
|  |         uses: mig4/setup-bats@v1 | ||||||
|  |         with: | ||||||
|  |           bats-version: 1.9.0 | ||||||
|  | 
 | ||||||
|  |       - name: Setup Bats libs | ||||||
|  |         uses: brokenpip3/setup-bats-libs@0.1.0 | ||||||
|  | 
 | ||||||
|  |       - name: Kind setup | ||||||
|  |         uses: helm/kind-action@v1.5.0 | ||||||
|  |         with: | ||||||
|  |           cluster_name: ${{env.KIND_CLUSTER_NAME}} | ||||||
|  | 
 | ||||||
|  |       - name: Jenkins Operator - bats tests | ||||||
|  |         run: make bats-tests | ||||||
|  | @ -0,0 +1,68 @@ | ||||||
|  | name: Run e2e tests | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |       - main | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
|  |       - 'backup/**' | ||||||
|  |       - '*.md' | ||||||
|  |   pull_request: | ||||||
|  |     types: [opened, synchronize, ready_for_review, reopened] | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
|  |       - 'backup/**' | ||||||
|  |       - '*.md' | ||||||
|  | 
 | ||||||
|  | env: | ||||||
|  |   MINIKUBE_CPUS_NUMBER: 2 | ||||||
|  |   MINIKUBE_MEMORY_AMOUNT: 6144 | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   run-tests: | ||||||
|  |     if: github.event.pull_request.draft == false | ||||||
|  |     name: Run automated tests | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Check out code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  | 
 | ||||||
|  |       - name: Set up env vars | ||||||
|  |         run: | | ||||||
|  |           echo "GO111MODULE=on" >> $GITHUB_ENV | ||||||
|  |           echo "CHANGE_MINIKUBE_NONE_USER=true" >> $GITHUB_ENV | ||||||
|  |           echo "MINIKUBE_WANTUPDATENOTIFICATION=false" >> $GITHUB_ENV | ||||||
|  |           echo "MINIKUBE_WANTREPORTERRORPROMPT=false" >> $GITHUB_ENV | ||||||
|  |           echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|  |           echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|  |           echo "GOPATH=/home/runner/go" >> $GITHUB_ENV | ||||||
|  | 
 | ||||||
|  |       - name: Prepare go environment | ||||||
|  |         uses: actions/setup-go@v2 | ||||||
|  |         with: | ||||||
|  |           go-version: ${{ env.GO_VERSION }} | ||||||
|  | 
 | ||||||
|  |       - name: Ensure Golang runtime dependencies | ||||||
|  |         run: make go-dependencies | ||||||
|  | 
 | ||||||
|  |       - name: Verify code formatting | ||||||
|  |         run: make verify | ||||||
|  | 
 | ||||||
|  |       - name: Prepare environment for e2e | ||||||
|  |         run: | | ||||||
|  |           sudo apt-get update | ||||||
|  |           sudo apt-get install socat | ||||||
|  |           sudo mkdir -p $HOME/.kube $HOME/.minikube | ||||||
|  |           sudo chown -R $USER $HOME/.kube $HOME/.minikube | ||||||
|  |           make minikube-start \ | ||||||
|  |             MINIKUBE_DRIVER='docker' \ | ||||||
|  |             MEMORY_AMOUNT=${{ env.MINIKUBE_MEMORY_AMOUNT }} \ | ||||||
|  |             CPUS_NUMBER=${{ env.MINIKUBE_CPUS_NUMBER }} | ||||||
|  | 
 | ||||||
|  |       - name: Jenkins Operator - e2e | ||||||
|  |         run: make e2e E2E_TEST_ARGS='-ginkgo.v' | ||||||
|  | @ -1,12 +1,23 @@ | ||||||
| name: Run tests | name: Run Helm e2e tests | ||||||
| on: | on: | ||||||
|   push: |   push: | ||||||
|     branches: |     branches: | ||||||
|       - master |       - master | ||||||
|  |       - main | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
|  |       - 'backup/**' | ||||||
|  |       - '*.md' | ||||||
|   pull_request: |   pull_request: | ||||||
|     types: [opened, synchronize, ready_for_review, reopened] |     types: [opened, synchronize, ready_for_review, reopened] | ||||||
|     branches: |     paths-ignore: | ||||||
|       - master |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - 'assets/**' | ||||||
|  |       - 'backup/**' | ||||||
|  |       - '*.md' | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|   MINIKUBE_CPUS_NUMBER: 2 |   MINIKUBE_CPUS_NUMBER: 2 | ||||||
|  | @ -53,9 +64,6 @@ jobs: | ||||||
|             MEMORY_AMOUNT=${{ env.MINIKUBE_MEMORY_AMOUNT }} \ |             MEMORY_AMOUNT=${{ env.MINIKUBE_MEMORY_AMOUNT }} \ | ||||||
|             CPUS_NUMBER=${{ env.MINIKUBE_CPUS_NUMBER }} |             CPUS_NUMBER=${{ env.MINIKUBE_CPUS_NUMBER }} | ||||||
| 
 | 
 | ||||||
|       - name: Jenkins Operator - e2e |  | ||||||
|         run: make e2e E2E_TEST_ARGS='-ginkgo.v' |  | ||||||
| 
 |  | ||||||
|       - name: Jenkins Operator - Helm Chart tests |       - name: Jenkins Operator - Helm Chart tests | ||||||
|         run: | |         run: | | ||||||
|           git reset --hard |           git reset --hard | ||||||
|  | @ -7,7 +7,9 @@ on: | ||||||
|       - 'backup/pvc/**' |       - 'backup/pvc/**' | ||||||
| 
 | 
 | ||||||
|   push: |   push: | ||||||
|     branches: ["master"] |     branches: | ||||||
|  |       - master | ||||||
|  |       - main | ||||||
|     tags: ["*"] |     tags: ["*"] | ||||||
|     paths: |     paths: | ||||||
|       - 'backup/pvc/**' |       - 'backup/pvc/**' | ||||||
|  |  | ||||||
|  | @ -17,10 +17,10 @@ jobs: | ||||||
|     name: Publish nightly snapshot |     name: Publish nightly snapshot | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Check out code |       - name: Prep - check out code | ||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
| 
 | 
 | ||||||
|       - name: Set up env vars |       - name: Prep - Set up env vars | ||||||
|         run: | |         run: | | ||||||
|           echo "GO111MODULE=on" >> $GITHUB_ENV |           echo "GO111MODULE=on" >> $GITHUB_ENV | ||||||
|           echo "CHANGE_MINIKUBE_NONE_USER=true" >> $GITHUB_ENV |           echo "CHANGE_MINIKUBE_NONE_USER=true" >> $GITHUB_ENV | ||||||
|  | @ -28,20 +28,31 @@ jobs: | ||||||
|           echo "MINIKUBE_WANTREPORTERRORPROMPT=false" >> $GITHUB_ENV |           echo "MINIKUBE_WANTREPORTERRORPROMPT=false" >> $GITHUB_ENV | ||||||
|           echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env)" >> $GITHUB_ENV |           echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|           echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env)" >> $GITHUB_ENV |           echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|  |           echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env)" >> $GITHUB_ENV | ||||||
|           echo "GOPATH=/home/runner/go" >> $GITHUB_ENV |           echo "GOPATH=/home/runner/go" >> $GITHUB_ENV | ||||||
| 
 | 
 | ||||||
|       - name: Prepare go environment |       - name: Prep - setup BATS | ||||||
|  |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|  |         uses: mig4/setup-bats@v1 | ||||||
|  |         with: | ||||||
|  |           bats-version: 1.9.0 | ||||||
|  | 
 | ||||||
|  |       - name: Prep - setup Bats libs | ||||||
|  |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|  |         uses: brokenpip3/setup-bats-libs@0.1.0 | ||||||
|  | 
 | ||||||
|  |       - name: Prep - go environment | ||||||
|         uses: actions/setup-go@v2 |         uses: actions/setup-go@v2 | ||||||
|         with: |         with: | ||||||
|           go-version: ${{ env.GO_VERSION }} |           go-version: ${{ env.GO_VERSION }} | ||||||
| 
 | 
 | ||||||
|       - name: Ensure Golang runtime dependencies |       - name: Prep - Ensure Golang runtime dependencies | ||||||
|         run: make go-dependencies |         run: make go-dependencies | ||||||
| 
 | 
 | ||||||
|       - name: Verify code formatting |       - name: Test - verify code formatting | ||||||
|         run: make verify |         run: make verify | ||||||
| 
 | 
 | ||||||
|       - name: Prepare environment for e2e |       - name: Prep - Minikube setup | ||||||
|         if: ${{ github.event.inputs.skipTests != 'true' }} |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|         run: | |         run: | | ||||||
|           sudo apt-get update |           sudo apt-get update | ||||||
|  | @ -53,11 +64,11 @@ jobs: | ||||||
|             MEMORY_AMOUNT=${{ env.MINIKUBE_MEMORY_AMOUNT }} \ |             MEMORY_AMOUNT=${{ env.MINIKUBE_MEMORY_AMOUNT }} \ | ||||||
|             CPUS_NUMBER=${{ env.MINIKUBE_CPUS_NUMBER }} |             CPUS_NUMBER=${{ env.MINIKUBE_CPUS_NUMBER }} | ||||||
| 
 | 
 | ||||||
|       - name: Jenkins Operator - e2e |       - name: Test - e2e | ||||||
|         if: ${{ github.event.inputs.skipTests != 'true' }} |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|         run: make e2e E2E_TEST_ARGS='-ginkgo.v' |         run: make e2e E2E_TEST_ARGS='-ginkgo.v' | ||||||
| 
 | 
 | ||||||
|       - name: Jenkins Operator - Helm Chart tests |       - name: Test - Helm Chart | ||||||
|         if: ${{ github.event.inputs.skipTests != 'true' }} |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|         run: | |         run: | | ||||||
|           git reset --hard |           git reset --hard | ||||||
|  | @ -65,14 +76,29 @@ jobs: | ||||||
|           eval $(bin/minikube docker-env) |           eval $(bin/minikube docker-env) | ||||||
|           make helm-e2e E2E_TEST_ARGS='-ginkgo.v' |           make helm-e2e E2E_TEST_ARGS='-ginkgo.v' | ||||||
| 
 | 
 | ||||||
|       - name: Login to Quay.io |       - name: Prep - Destroy minikube | ||||||
|  |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|  |         run: | | ||||||
|  |           make minikube-destroy | ||||||
|  | 
 | ||||||
|  |       - name: Prep - Kind setup | ||||||
|  |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|  |         uses: helm/kind-action@v1.5.0 | ||||||
|  |         with: | ||||||
|  |           cluster_name: ${{env.KIND_CLUSTER_NAME}} | ||||||
|  | 
 | ||||||
|  |       - name: Test - bats | ||||||
|  |         if: ${{ github.event.inputs.skipTests != 'true' }} | ||||||
|  |         run: make bats-tests | ||||||
|  | 
 | ||||||
|  |       - name: Post - Login to Quay.io | ||||||
|         uses: docker/login-action@v1 |         uses: docker/login-action@v1 | ||||||
|         with: |         with: | ||||||
|           registry: quay.io |           registry: quay.io | ||||||
|           username: ${{ secrets.QUAYIO_USERNAME }} |           username: ${{ secrets.QUAYIO_USERNAME }} | ||||||
|           password: ${{ secrets.QUAYIO_TOKEN }} |           password: ${{ secrets.QUAYIO_TOKEN }} | ||||||
| 
 | 
 | ||||||
|       - name: Release Container Runtime |       - name: Post - Push image | ||||||
|         run: | |         run: | | ||||||
|           git reset --hard |           git reset --hard | ||||||
|           make container-runtime-snapshot-push |           make container-runtime-snapshot-push | ||||||
|  | @ -91,3 +91,6 @@ tags | ||||||
| 
 | 
 | ||||||
| /bin | /bin | ||||||
| testbin/* | testbin/* | ||||||
|  | 
 | ||||||
|  | ### Bats | ||||||
|  | chart/jenkins-operator/deploy.tmp | ||||||
|  |  | ||||||
|  | @ -1,16 +1,21 @@ | ||||||
| repos: | repos: | ||||||
|   - repo: https://github.com/golangci/golangci-lint |  | ||||||
|     rev: v1.51.2 |  | ||||||
|     hooks: |  | ||||||
|       - id: golangci-lint |  | ||||||
|   - repo: https://github.com/sirosen/check-jsonschema |   - repo: https://github.com/sirosen/check-jsonschema | ||||||
|     rev: 0.21.0 |     rev: 0.22.0 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: check-github-workflows |       - id: check-github-workflows | ||||||
|   - repo: https://github.com/pre-commit/pre-commit-hooks |   - repo: https://github.com/pre-commit/pre-commit-hooks | ||||||
|     rev: v4.4.0 |     rev: v4.4.0 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: detect-private-key |       - id: detect-private-key | ||||||
|       - id: check-yaml |  | ||||||
|       - id: trailing-whitespace |       - id: trailing-whitespace | ||||||
|       - id: end-of-file-fixer |       - id: end-of-file-fixer | ||||||
|  |   - repo: https://github.com/gruntwork-io/pre-commit | ||||||
|  |     rev: "v0.1.19" | ||||||
|  |     hooks: | ||||||
|  |       - id: helmlint | ||||||
|  |   - repo: https://github.com/norwoodj/helm-docs | ||||||
|  |     rev: "v1.11.0" | ||||||
|  |     hooks: | ||||||
|  |       - id: helm-docs | ||||||
|  |         args: | ||||||
|  |           - --chart-search-root=chart/jenkins-operator | ||||||
|  |  | ||||||
|  | @ -28,6 +28,13 @@ RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldf | ||||||
| # Use distroless as minimal base image to package the manager binary | # Use distroless as minimal base image to package the manager binary | ||||||
| # Refer to https://github.com/GoogleContainerTools/distroless for more details | # Refer to https://github.com/GoogleContainerTools/distroless for more details | ||||||
| FROM gcr.io/distroless/static:nonroot | FROM gcr.io/distroless/static:nonroot | ||||||
|  | LABEL maintainer="Jenkins Kubernetes Operator Community" \ | ||||||
|  |       org.opencontainers.image.authors="Jenkins Kubernetes Operator Community" \ | ||||||
|  |       org.opencontainers.image.title="jenkins-kubernetes-operator" \ | ||||||
|  |       org.opencontainers.image.description="Kubernetes native Jenkins Operator" \ | ||||||
|  |       org.opencontainers.image.url="quay.io/jenkins-kubernetes-operator/operator" \ | ||||||
|  |       org.opencontainers.image.source="https://github.com/jenkinsci/kubernetes-operator/tree/master" \ | ||||||
|  |       org.opencontainers.image.base.name="gcr.io/distroless/static:nonroot" | ||||||
| WORKDIR / | WORKDIR / | ||||||
| COPY --from=builder /workspace/manager . | COPY --from=builder /workspace/manager . | ||||||
| USER 65532:65532 | USER 65532:65532 | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										47
									
								
								Makefile
								
								
								
								
							|  | @ -95,7 +95,7 @@ e2e: deepcopy-gen manifests ## Runs e2e tests, you can use EXTRA_ARGS | ||||||
| 		-jenkins-api-hostname=$(JENKINS_API_HOSTNAME) -jenkins-api-port=$(JENKINS_API_PORT) -jenkins-api-use-nodeport=$(JENKINS_API_USE_NODEPORT) $(E2E_TEST_ARGS) | 		-jenkins-api-hostname=$(JENKINS_API_HOSTNAME) -jenkins-api-port=$(JENKINS_API_PORT) -jenkins-api-use-nodeport=$(JENKINS_API_USE_NODEPORT) $(E2E_TEST_ARGS) | ||||||
| 
 | 
 | ||||||
| .PHONY: helm-e2e | .PHONY: helm-e2e | ||||||
| IMAGE_NAME := $(QUAY_REGISTRY):$(GITCOMMIT)-amd64 | IMAGE_NAME := quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)-amd64 | ||||||
| 
 | 
 | ||||||
| helm-e2e: helm container-runtime-build-amd64 ## Runs helm e2e tests, you can use EXTRA_ARGS
 | helm-e2e: helm container-runtime-build-amd64 ## Runs helm e2e tests, you can use EXTRA_ARGS
 | ||||||
| 	@echo "+ $@" | 	@echo "+ $@" | ||||||
|  | @ -140,6 +140,13 @@ install: ## Installs the executable | ||||||
| 	@echo "+ $@" | 	@echo "+ $@" | ||||||
| 	go install -tags "$(BUILDTAGS)" ${GO_LDFLAGS} $(BUILD_PATH) | 	go install -tags "$(BUILDTAGS)" ${GO_LDFLAGS} $(BUILD_PATH) | ||||||
| 
 | 
 | ||||||
|  | .PHONY: update-lts-version | ||||||
|  | update-lts-version: ## Update the latest lts version
 | ||||||
|  | 	@echo "+ $@" | ||||||
|  | 	sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' chart/jenkins-operator/values.yaml | ||||||
|  | 	sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' test/e2e/test_utility.go | ||||||
|  | 	sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' test/helm/helm_test.go | ||||||
|  | 
 | ||||||
| .PHONY: run | .PHONY: run | ||||||
| run: export WATCH_NAMESPACE = $(NAMESPACE) | run: export WATCH_NAMESPACE = $(NAMESPACE) | ||||||
| run: export OPERATOR_NAME = $(NAME) | run: export OPERATOR_NAME = $(NAME) | ||||||
|  | @ -214,7 +221,7 @@ container-runtime-build-%: ## Build the container | ||||||
| 		--output=type=docker --platform linux/$* \
 | 		--output=type=docker --platform linux/$* \
 | ||||||
| 		--build-arg GO_VERSION=$(GO_VERSION) \
 | 		--build-arg GO_VERSION=$(GO_VERSION) \
 | ||||||
| 		--build-arg CTIMEVAR="$(CTIMEVAR)" \
 | 		--build-arg CTIMEVAR="$(CTIMEVAR)" \
 | ||||||
| 		--tag $(QUAY_REGISTRY):$(GITCOMMIT)-$* . \
 | 		--tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)-$* . \
 | ||||||
| 		--file Dockerfile $(CONTAINER_RUNTIME_EXTRA_ARGS) | 		--file Dockerfile $(CONTAINER_RUNTIME_EXTRA_ARGS) | ||||||
| 
 | 
 | ||||||
| .PHONY: container-runtime-build | .PHONY: container-runtime-build | ||||||
|  | @ -282,7 +289,7 @@ container-runtime-run: ## Run the container in docker, you can use EXTRA_ARGS | ||||||
| 	@echo "+ $@" | 	@echo "+ $@" | ||||||
| 	$(CONTAINER_RUNTIME_COMMAND) run $(CONTAINER_RUNTIME_EXTRA_ARGS) --rm -i $(DOCKER_FLAGS) \
 | 	$(CONTAINER_RUNTIME_COMMAND) run $(CONTAINER_RUNTIME_EXTRA_ARGS) --rm -i $(DOCKER_FLAGS) \
 | ||||||
| 		--volume $(HOME)/.kube/config:/home/jenkins-operator/.kube/config \
 | 		--volume $(HOME)/.kube/config:/home/jenkins-operator/.kube/config \
 | ||||||
| 		$(QUAY_REGISTRY):$(GITCOMMIT) /usr/bin/jenkins-operator $(OPERATOR_ARGS) | 		quay.io/${QUAY_ORGANIZATION}/$(QUAY_REGISTRY):$(GITCOMMIT) /usr/bin/jenkins-operator $(OPERATOR_ARGS) | ||||||
| 
 | 
 | ||||||
| .PHONY: minikube-run | .PHONY: minikube-run | ||||||
| minikube-run: export WATCH_NAMESPACE = $(NAMESPACE) | minikube-run: export WATCH_NAMESPACE = $(NAMESPACE) | ||||||
|  | @ -356,6 +363,36 @@ minikube-start: minikube check-minikube ## Start minikube | ||||||
| 	bin/minikube status && exit 0 || \
 | 	bin/minikube status && exit 0 || \
 | ||||||
| 	bin/minikube start --kubernetes-version $(MINIKUBE_KUBERNETES_VERSION) --dns-domain=$(CLUSTER_DOMAIN) --extra-config=kubelet.cluster-domain=$(CLUSTER_DOMAIN) --driver=$(MINIKUBE_DRIVER) --memory $(MEMORY_AMOUNT) --cpus $(CPUS_NUMBER) | 	bin/minikube start --kubernetes-version $(MINIKUBE_KUBERNETES_VERSION) --dns-domain=$(CLUSTER_DOMAIN) --extra-config=kubelet.cluster-domain=$(CLUSTER_DOMAIN) --driver=$(MINIKUBE_DRIVER) --memory $(MEMORY_AMOUNT) --cpus $(CPUS_NUMBER) | ||||||
| 
 | 
 | ||||||
|  | .PHONY: minikube-destroy | ||||||
|  | minikube-destroy: ## Stop and destroy minikube
 | ||||||
|  | 	@echo "+ $@" | ||||||
|  | 	bin/minikube stop | ||||||
|  | 	bin/minikube delete | ||||||
|  | 
 | ||||||
|  | .PHONY: kind-setup | ||||||
|  | kind-setup: ## Setup kind cluster
 | ||||||
|  | 	@echo "+ $@" | ||||||
|  | 	kind create cluster --name $(KIND_CLUSTER_NAME) | ||||||
|  | 
 | ||||||
|  | .PHONY: kind-clean | ||||||
|  | kind-clean: ## Delete kind cluster
 | ||||||
|  | 	@echo "+ $@" | ||||||
|  | 	kind delete cluster --name $(KIND_CLUSTER_NAME) | ||||||
|  | 
 | ||||||
|  | .PHONY: bats-tests | ||||||
|  | IMAGE_NAME := quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)-amd64 | ||||||
|  | BUILD_PRESENT := $(shell docker images |grep -q ${IMAGE_NAME}) | ||||||
|  | ifndef BUILD_PRESENT | ||||||
|  | bats-tests: container-runtime-build-amd64 ## Run bats tests
 | ||||||
|  | 	@echo "+ $@" | ||||||
|  | 	kind load docker-image ${IMAGE_NAME} --name $(KIND_CLUSTER_NAME) | ||||||
|  | 	OPERATOR_IMAGE="${IMAGE_NAME}" TERM=xterm bats -T -p -x test/bats | ||||||
|  | else | ||||||
|  | bats-tests: ## Run bats tests
 | ||||||
|  | 	@echo "+ $@" | ||||||
|  | 	OPERATOR_IMAGE="${IMAGE_NAME}" TERM=xterm bats -T -p -x test/bats | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| .PHONY: crc-start | .PHONY: crc-start | ||||||
| crc-start: check-crc ## Start CodeReady Containers Kubernetes cluster
 | crc-start: check-crc ## Start CodeReady Containers Kubernetes cluster
 | ||||||
| 	@echo "+ $@" | 	@echo "+ $@" | ||||||
|  | @ -417,7 +454,7 @@ ifneq ($(GITUNTRACKEDCHANGES),) | ||||||
| endif | endif | ||||||
| ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),) | ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),) | ||||||
| 	@echo "Ignored but tracked files:" | 	@echo "Ignored but tracked files:" | ||||||
| 	@git ls-files -i --exclude-standard | 	@git ls-files -i -c --exclude-standard | ||||||
| 	@echo | 	@echo | ||||||
| endif | endif | ||||||
| 	@echo "Dependencies:" | 	@echo "Dependencies:" | ||||||
|  | @ -474,7 +511,7 @@ uninstall-crds: manifests kustomize | ||||||
| 
 | 
 | ||||||
| # Deploy controller in the configured Kubernetes cluster in ~/.kube/config
 | # Deploy controller in the configured Kubernetes cluster in ~/.kube/config
 | ||||||
| deploy: manifests kustomize | deploy: manifests kustomize | ||||||
| 	cd config/manager && $(KUSTOMIZE) edit set image controller=$(QUAY_REGISTRY):$(GITCOMMIT) | 	cd config/manager && $(KUSTOMIZE) edit set image controller=quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT) | ||||||
| 	$(KUSTOMIZE) build config/default | kubectl apply -f - | 	$(KUSTOMIZE) build config/default | kubectl apply -f - | ||||||
| 
 | 
 | ||||||
| # UnDeploy controller from the configured Kubernetes cluster in ~/.kube/config
 | # UnDeploy controller from the configured Kubernetes cluster in ~/.kube/config
 | ||||||
|  |  | ||||||
|  | @ -370,6 +370,11 @@ type JenkinsMaster struct { | ||||||
| 	// +optional
 | 	// +optional
 | ||||||
| 	Plugins []Plugin `json:"plugins,omitempty"` | 	Plugins []Plugin `json:"plugins,omitempty"` | ||||||
| 
 | 
 | ||||||
|  | 	// Allow to override jenkins-plugin-cli default behavior
 | ||||||
|  | 	// while downloading the plugin and dependencies
 | ||||||
|  | 	// see: https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options
 | ||||||
|  | 	LatestPlugins bool `json:"latestPlugins"` | ||||||
|  | 
 | ||||||
| 	// DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins
 | 	// DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins
 | ||||||
| 	DisableCSRFProtection bool `json:"disableCSRFProtection"` | 	DisableCSRFProtection bool `json:"disableCSRFProtection"` | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,12 @@ | ||||||
| FROM debian:buster-slim | FROM debian:bullseye-slim | ||||||
|  | 
 | ||||||
|  | LABEL maintainer="Jenkins Kubernetes Operator Community" \ | ||||||
|  |       org.opencontainers.image.authors="Jenkins Kubernetes Operator Community" \ | ||||||
|  |       org.opencontainers.image.title="backup-pvc" \ | ||||||
|  |       org.opencontainers.image.description="Jenkins Operator Backup img via pvc volume" \ | ||||||
|  |       org.opencontainers.image.url="quay.io/jenkins-kubernetes-operator/backup-pvc" \ | ||||||
|  |       org.opencontainers.image.source="https://github.com/jenkinsci/kubernetes-operator/tree/master/backup/pvc" \ | ||||||
|  |       org.opencontainers.image.base.name="debian:bullseye-slim" | ||||||
| 
 | 
 | ||||||
| ARG UID | ARG UID | ||||||
| ARG GID | ARG GID | ||||||
|  |  | ||||||
|  | @ -1 +1 @@ | ||||||
| v0.2.1 | v0.2.2 | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ set -eo pipefail | ||||||
| [[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1; | [[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1; | ||||||
| 
 | 
 | ||||||
| backup_number=$1 | backup_number=$1 | ||||||
| echo "Running restore backup" | echo "Running restore backup with backup number #${backup_number}" | ||||||
| 
 | 
 | ||||||
| tar -C ${JENKINS_HOME} -zxf "${BACKUP_DIR}/${backup_number}.tar.gz" | tar -C ${JENKINS_HOME} -zxf "${BACKUP_DIR}/${backup_number}.tar.gz" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,112 @@ | ||||||
|  | # jenkins-operator | ||||||
|  | 
 | ||||||
|  |   | ||||||
|  | 
 | ||||||
|  | Kubernetes native operator which fully manages Jenkins on Kubernetes | ||||||
|  | 
 | ||||||
|  | ## Requirements | ||||||
|  | 
 | ||||||
|  | | Repository | Name | Version | | ||||||
|  | |------------|------|---------| | ||||||
|  | | https://charts.jetstack.io | cert-manager | 1.5.1 | | ||||||
|  | 
 | ||||||
|  | ## Values | ||||||
|  | 
 | ||||||
|  | | Key | Type | Default | Description | | ||||||
|  | |-----|------|---------|-------------| | ||||||
|  | | cert-manager.startupapicheck.enabled | bool | `false` |  | | ||||||
|  | | jenkins.annotations | object | `{}` |  | | ||||||
|  | | jenkins.apiVersion | string | `"jenkins.io/v1alpha2"` |  | | ||||||
|  | | jenkins.authorizationStrategy | string | `"createUser"` |  | | ||||||
|  | | jenkins.backup.backupCommand[0] | string | `"/home/user/bin/backup.sh"` |  | | ||||||
|  | | jenkins.backup.containerName | string | `"backup"` |  | | ||||||
|  | | jenkins.backup.enabled | bool | `true` |  | | ||||||
|  | | jenkins.backup.env[0].name | string | `"BACKUP_DIR"` |  | | ||||||
|  | | jenkins.backup.env[0].value | string | `"/backup"` |  | | ||||||
|  | | jenkins.backup.env[1].name | string | `"JENKINS_HOME"` |  | | ||||||
|  | | jenkins.backup.env[1].value | string | `"/jenkins-home"` |  | | ||||||
|  | | jenkins.backup.env[2].name | string | `"BACKUP_COUNT"` |  | | ||||||
|  | | jenkins.backup.env[2].value | string | `"3"` |  | | ||||||
|  | | jenkins.backup.getLatestAction[0] | string | `"/home/user/bin/get-latest.sh"` |  | | ||||||
|  | | jenkins.backup.image | string | `"quay.io/jenkins-kubernetes-operator/backup-pvc:v0.2.1"` |  | | ||||||
|  | | jenkins.backup.interval | int | `30` |  | | ||||||
|  | | jenkins.backup.makeBackupBeforePodDeletion | bool | `true` |  | | ||||||
|  | | jenkins.backup.pvc.className | string | `""` |  | | ||||||
|  | | jenkins.backup.pvc.enabled | bool | `true` |  | | ||||||
|  | | jenkins.backup.pvc.size | string | `"5Gi"` |  | | ||||||
|  | | jenkins.backup.resources.limits.cpu | string | `"1000m"` |  | | ||||||
|  | | jenkins.backup.resources.limits.memory | string | `"2Gi"` |  | | ||||||
|  | | jenkins.backup.resources.requests.cpu | string | `"100m"` |  | | ||||||
|  | | jenkins.backup.resources.requests.memory | string | `"500Mi"` |  | | ||||||
|  | | jenkins.backup.restoreCommand[0] | string | `"/home/user/bin/restore.sh"` |  | | ||||||
|  | | jenkins.backup.volumeMounts[0].mountPath | string | `"/jenkins-home"` |  | | ||||||
|  | | jenkins.backup.volumeMounts[0].name | string | `"jenkins-home"` |  | | ||||||
|  | | jenkins.backup.volumeMounts[1].mountPath | string | `"/backup"` |  | | ||||||
|  | | jenkins.backup.volumeMounts[1].name | string | `"backup"` |  | | ||||||
|  | | jenkins.basePlugins | list | `[]` |  | | ||||||
|  | | jenkins.configuration.configurationAsCode | object | `{}` |  | | ||||||
|  | | jenkins.configuration.groovyScripts | object | `{}` |  | | ||||||
|  | | jenkins.configuration.secretData | object | `{}` |  | | ||||||
|  | | jenkins.configuration.secretRefName | string | `""` |  | | ||||||
|  | | jenkins.disableCSRFProtection | bool | `false` |  | | ||||||
|  | | jenkins.enabled | bool | `true` |  | | ||||||
|  | | jenkins.env | list | `[]` |  | | ||||||
|  | | jenkins.hostAliases | object | `{}` |  | | ||||||
|  | | jenkins.image | string | `"jenkins/jenkins:2.387.1-lts"` |  | | ||||||
|  | | jenkins.imagePullPolicy | string | `"Always"` |  | | ||||||
|  | | jenkins.imagePullSecrets | list | `[]` |  | | ||||||
|  | | jenkins.labels | object | `{}` |  | | ||||||
|  | | jenkins.latestPlugins | bool | `true` |  | | ||||||
|  | | jenkins.livenessProbe.failureThreshold | int | `20` |  | | ||||||
|  | | jenkins.livenessProbe.httpGet.path | string | `"/login"` |  | | ||||||
|  | | jenkins.livenessProbe.httpGet.port | string | `"http"` |  | | ||||||
|  | | jenkins.livenessProbe.httpGet.scheme | string | `"HTTP"` |  | | ||||||
|  | | jenkins.livenessProbe.initialDelaySeconds | int | `100` |  | | ||||||
|  | | jenkins.livenessProbe.periodSeconds | int | `10` |  | | ||||||
|  | | jenkins.livenessProbe.successThreshold | int | `1` |  | | ||||||
|  | | jenkins.livenessProbe.timeoutSeconds | int | `8` |  | | ||||||
|  | | jenkins.name | string | `"jenkins"` |  | | ||||||
|  | | jenkins.namespace | string | `"default"` |  | | ||||||
|  | | jenkins.nodeSelector | object | `{}` |  | | ||||||
|  | | jenkins.notifications | list | `[]` |  | | ||||||
|  | | jenkins.plugins | list | `[]` |  | | ||||||
|  | | jenkins.priorityClassName | string | `""` |  | | ||||||
|  | | jenkins.readinessProbe.failureThreshold | int | `60` |  | | ||||||
|  | | jenkins.readinessProbe.httpGet.path | string | `"/login"` |  | | ||||||
|  | | jenkins.readinessProbe.httpGet.port | string | `"http"` |  | | ||||||
|  | | jenkins.readinessProbe.httpGet.scheme | string | `"HTTP"` |  | | ||||||
|  | | jenkins.readinessProbe.initialDelaySeconds | int | `120` |  | | ||||||
|  | | jenkins.readinessProbe.periodSeconds | int | `10` |  | | ||||||
|  | | jenkins.readinessProbe.successThreshold | int | `1` |  | | ||||||
|  | | jenkins.readinessProbe.timeoutSeconds | int | `8` |  | | ||||||
|  | | jenkins.resources.limits.cpu | string | `"1000m"` |  | | ||||||
|  | | jenkins.resources.limits.memory | string | `"3Gi"` |  | | ||||||
|  | | jenkins.resources.requests.cpu | string | `"250m"` |  | | ||||||
|  | | jenkins.resources.requests.memory | string | `"500Mi"` |  | | ||||||
|  | | jenkins.securityContext.fsGroup | int | `1000` |  | | ||||||
|  | | jenkins.securityContext.runAsUser | int | `1000` |  | | ||||||
|  | | jenkins.seedJobAgentImage | string | `""` |  | | ||||||
|  | | jenkins.seedJobs | list | `[]` |  | | ||||||
|  | | jenkins.serviceAccount.annotations | object | `{}` |  | | ||||||
|  | | jenkins.tolerations | list | `[]` |  | | ||||||
|  | | jenkins.validateSecurityWarnings | bool | `false` |  | | ||||||
|  | | jenkins.volumeMounts | list | `[]` |  | | ||||||
|  | | jenkins.volumes[0].name | string | `"backup"` |  | | ||||||
|  | | jenkins.volumes[0].persistentVolumeClaim.claimName | string | `"jenkins-backup"` |  | | ||||||
|  | | operator.affinity | object | `{}` |  | | ||||||
|  | | operator.fullnameOverride | string | `""` |  | | ||||||
|  | | operator.image | string | `"quay.io/jenkins-kubernetes-operator/operator:d91a729"` |  | | ||||||
|  | | operator.imagePullPolicy | string | `"IfNotPresent"` |  | | ||||||
|  | | operator.imagePullSecrets | list | `[]` |  | | ||||||
|  | | operator.nameOverride | string | `""` |  | | ||||||
|  | | operator.nodeSelector | object | `{}` |  | | ||||||
|  | | operator.replicaCount | int | `1` |  | | ||||||
|  | | operator.resources | object | `{}` |  | | ||||||
|  | | operator.tolerations | list | `[]` |  | | ||||||
|  | | webhook.certificate.duration | string | `"2160h"` |  | | ||||||
|  | | webhook.certificate.name | string | `"webhook-certificate"` |  | | ||||||
|  | | webhook.certificate.renewbefore | string | `"360h"` |  | | ||||||
|  | | webhook.enabled | bool | `false` |  | | ||||||
|  | 
 | ||||||
|  | ---------------------------------------------- | ||||||
|  | Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) | ||||||
|  | @ -1100,6 +1100,11 @@ spec: | ||||||
|                       - resources |                       - resources | ||||||
|                       type: object |                       type: object | ||||||
|                     type: array |                     type: array | ||||||
|  |                   latestPlugins: | ||||||
|  |                     description: 'Allow to override jenkins-plugin-cli default behavior | ||||||
|  |                       while downloading the plugin and dependencies, see: | ||||||
|  |                       https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options' | ||||||
|  |                     type: boolean | ||||||
|                   disableCSRFProtection: |                   disableCSRFProtection: | ||||||
|                     description: DisableCSRFProtection allows you to toggle CSRF Protection |                     description: DisableCSRFProtection allows you to toggle CSRF Protection | ||||||
|                       on Jenkins |                       on Jenkins | ||||||
|  | @ -3119,8 +3124,8 @@ spec: | ||||||
|                   type: object |                   type: object | ||||||
|                 type: array |                 type: array | ||||||
|               seedJobAgentImage: |               seedJobAgentImage: | ||||||
|                   type: string |                 type: string | ||||||
|                   description: 'SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:4.10-3 will be used.' |                 description: 'SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:4.10-3 will be used.' | ||||||
|               seedJobs: |               seedJobs: | ||||||
|                 description: 'SeedJobs defines list of Jenkins Seed Job configurations |                 description: 'SeedJobs defines list of Jenkins Seed Job configurations | ||||||
|                   More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines' |                   More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines' | ||||||
|  |  | ||||||
|  | @ -95,9 +95,6 @@ spec: | ||||||
|     {{- with .Values.jenkins.nodeSelector }} |     {{- with .Values.jenkins.nodeSelector }} | ||||||
|     nodeSelector: {{ toYaml . | nindent 6 }} |     nodeSelector: {{ toYaml . | nindent 6 }} | ||||||
|     {{- end }} |     {{- end }} | ||||||
|     {{- with .Values.jenkins.tolerations }} |  | ||||||
|     tolerations: {{ toYaml . | nindent 6 }} |  | ||||||
|     {{- end }} |  | ||||||
|     {{- with .Values.jenkins.annotations }} |     {{- with .Values.jenkins.annotations }} | ||||||
|     annotations: {{ toYaml . | nindent 6 }} |     annotations: {{ toYaml . | nindent 6 }} | ||||||
|     {{- end }} |     {{- end }} | ||||||
|  | @ -107,6 +104,7 @@ spec: | ||||||
|     {{- with .Values.jenkins.plugins }} |     {{- with .Values.jenkins.plugins }} | ||||||
|     plugins: {{ toYaml . | nindent 4 }} |     plugins: {{ toYaml . | nindent 4 }} | ||||||
|     {{- end }} |     {{- end }} | ||||||
|  |     latestPlugins: {{ .Values.jenkins.latestPlugins }} | ||||||
|     {{- if .Values.jenkins.priorityClassName }} |     {{- if .Values.jenkins.priorityClassName }} | ||||||
|     priorityClassName: {{ .Values.jenkins.priorityClassName }} |     priorityClassName: {{ .Values.jenkins.priorityClassName }} | ||||||
|     {{- end }} |     {{- end }} | ||||||
|  |  | ||||||
|  | @ -27,16 +27,13 @@ jenkins: | ||||||
|   # nodeSelector are injected into metadata nodeSelector field |   # nodeSelector are injected into metadata nodeSelector field | ||||||
|   nodeSelector: {} |   nodeSelector: {} | ||||||
| 
 | 
 | ||||||
|   # tolerations are injected into metadata tolerations field |  | ||||||
|   tolerations: [] |  | ||||||
| 
 |  | ||||||
|   # annotations are injected into metadata annotations field |   # annotations are injected into metadata annotations field | ||||||
|   annotations: {} |   annotations: {} | ||||||
| 
 | 
 | ||||||
|   # image is the name (and tag) of the Jenkins instance |   # image is the name (and tag) of the Jenkins instance | ||||||
|   # Default: jenkins/jenkins:lts |   # Default: jenkins/jenkins:lts | ||||||
|   # It's recommended to use LTS (tag: "lts") version |   # It's recommended to use LTS (tag: "lts") version | ||||||
|   image: jenkins/jenkins:2.375.3-lts |   image: jenkins/jenkins:2.387.1-lts | ||||||
| 
 | 
 | ||||||
|   # env contains jenkins container environment variables |   # env contains jenkins container environment variables | ||||||
|   env: [] |   env: [] | ||||||
|  | @ -90,15 +87,15 @@ jenkins: | ||||||
|   # |   # | ||||||
|   # basePlugins: |   # basePlugins: | ||||||
|   # - name: kubernetes |   # - name: kubernetes | ||||||
|   #   version: 3883.v4d70a_a_a_df034 |   #   version: 3896.v19b_160fd9589 | ||||||
|   # - name: workflow-job |   # - name: workflow-job | ||||||
|   #   version: 1282.ve6d865025906 |   #   version: 1284.v2fe8ed4573d4 | ||||||
|   # - name: workflow-aggregator |   # - name: workflow-aggregator | ||||||
|   #   version: 590.v6a_d052e5a_a_b_5 |   #   version: 596.v8c21c963d92d | ||||||
|   # - name: git |   # - name: git | ||||||
|   #   version: 5.0.0 |   #   version: 5.0.0 | ||||||
|   # - name: job-dsl |   # - name: job-dsl | ||||||
|   #   version: "1.81" |   #   version: "1.82" | ||||||
|   # - name: configuration-as-code |   # - name: configuration-as-code | ||||||
|   #   version: 1569.vb_72405b_80249 |   #   version: 1569.vb_72405b_80249 | ||||||
|   # - name: kubernetes-credentials-provider |   # - name: kubernetes-credentials-provider | ||||||
|  | @ -117,6 +114,12 @@ jenkins: | ||||||
|   #   version: "0.6" |   #   version: "0.6" | ||||||
|   plugins: [] |   plugins: [] | ||||||
| 
 | 
 | ||||||
|  |   # latestPlugins: Allow to override jenkins-plugin-cli default behavior | ||||||
|  |   # while downloading the plugin and dependencies | ||||||
|  |   # see: https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options | ||||||
|  |   # default to true | ||||||
|  |   latestPlugins: true | ||||||
|  | 
 | ||||||
|   # seedJobs is placeholder for jenkins seed jobs |   # seedJobs is placeholder for jenkins seed jobs | ||||||
|   # For seed job creation tutorial, check https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/ |   # For seed job creation tutorial, check https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/ | ||||||
|   # Example: |   # Example: | ||||||
|  |  | ||||||
|  | @ -13,3 +13,5 @@ GEN_CRD_API=gen-crd-api-reference-docs | ||||||
| IMAGE_PULL_MODE=local | IMAGE_PULL_MODE=local | ||||||
| HELM_VERSION=3.1.2 | HELM_VERSION=3.1.2 | ||||||
| CLUSTER_DOMAIN=cluster.local | CLUSTER_DOMAIN=cluster.local | ||||||
|  | LATEST_LTS_VERSION=2.387.1 | ||||||
|  | KIND_CLUSTER_NAME=jenkins | ||||||
|  |  | ||||||
|  | @ -1100,6 +1100,11 @@ spec: | ||||||
|                       - resources |                       - resources | ||||||
|                       type: object |                       type: object | ||||||
|                     type: array |                     type: array | ||||||
|  |                   latestPlugins: | ||||||
|  |                     description: 'Allow to override jenkins-plugin-cli default behavior | ||||||
|  |                       while downloading the plugin and dependencies, see: | ||||||
|  |                       https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options' | ||||||
|  |                     type: boolean | ||||||
|                   disableCSRFProtection: |                   disableCSRFProtection: | ||||||
|                     description: DisableCSRFProtection allows you to toggle CSRF Protection |                     description: DisableCSRFProtection allows you to toggle CSRF Protection | ||||||
|                       on Jenkins |                       on Jenkins | ||||||
|  | @ -3120,7 +3125,7 @@ spec: | ||||||
|                 type: array |                 type: array | ||||||
|               seedJobAgentImage: |               seedJobAgentImage: | ||||||
|                 type: string |                 type: string | ||||||
|                 description: SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:4.10-3 will be used. |                 description: 'SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:4.10-3 will be used.' | ||||||
|               seedJobs: |               seedJobs: | ||||||
|                 description: 'SeedJobs defines list of Jenkins Seed Job configurations |                 description: 'SeedJobs defines list of Jenkins Seed Job configurations | ||||||
|                   More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines' |                   More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines' | ||||||
|  |  | ||||||
|  | @ -36,8 +36,7 @@ func (r *JenkinsBaseConfigurationReconciler) verifyPlugins(jenkinsClient jenkins | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			if found, ok := isPluginVersionCompatible(allPluginsInJenkins, plugin); !ok { | 			if found, ok := isPluginVersionCompatible(allPluginsInJenkins, plugin); !ok { | ||||||
| 				r.logger.V(log.VWarn).Info(fmt.Sprintf("Incompatible plugin '%s' version, actual '%+v'", plugin, found.Version)) | 				r.logger.V(log.VWarn).Info(fmt.Sprintf("The plugin you specified as code is incompatible with this jenkins version: plugin '%s' version, actual '%+v'", plugin, found.Version)) | ||||||
| 				status = false |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -340,7 +340,7 @@ func TestJenkinsBaseConfigurationReconciler_verifyPlugins(t *testing.T) { | ||||||
| 		got, err := r.verifyPlugins(jenkinsClient) | 		got, err := r.verifyPlugins(jenkinsClient) | ||||||
| 
 | 
 | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.False(t, got) | 		assert.True(t, got) | ||||||
| 	}) | 	}) | ||||||
| 	t.Run("plugin version matter for user plugins", func(t *testing.T) { | 	t.Run("plugin version matter for user plugins", func(t *testing.T) { | ||||||
| 		jenkins := &v1alpha2.Jenkins{ | 		jenkins := &v1alpha2.Jenkins{ | ||||||
|  | @ -377,7 +377,7 @@ func TestJenkinsBaseConfigurationReconciler_verifyPlugins(t *testing.T) { | ||||||
| 		got, err := r.verifyPlugins(jenkinsClient) | 		got, err := r.verifyPlugins(jenkinsClient) | ||||||
| 
 | 
 | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		assert.False(t, got) | 		assert.True(t, got) | ||||||
| 	}) | 	}) | ||||||
| 	t.Run("missing base plugin", func(t *testing.T) { | 	t.Run("missing base plugin", func(t *testing.T) { | ||||||
| 		jenkins := &v1alpha2.Jenkins{ | 		jenkins := &v1alpha2.Jenkins{ | ||||||
|  |  | ||||||
|  | @ -14,307 +14,6 @@ import ( | ||||||
| 
 | 
 | ||||||
| const installPluginsCommand = "jenkins-plugin-cli" | const installPluginsCommand = "jenkins-plugin-cli" | ||||||
| 
 | 
 | ||||||
| // bash scripts installs single jenkins plugin with specific version
 |  | ||||||
| const installPluginsBashScript = `#!/bin/bash -eu |  | ||||||
| 
 |  | ||||||
| # Resolve dependencies and download plugins given on the command line |  | ||||||
| # |  | ||||||
| # FROM jenkins |  | ||||||
| # RUN install-plugins.sh docker-slaves github-branch-source |  | ||||||
| # |  | ||||||
| # Environment variables: |  | ||||||
| # REF: directory with preinstalled plugins. Default: /usr/share/jenkins/ref/plugins |  | ||||||
| # JENKINS_WAR: full path to the jenkins.war. Default: /usr/share/jenkins/jenkins.war |  | ||||||
| # JENKINS_UC: url of the Update Center. Default: "" |  | ||||||
| # JENKINS_UC_EXPERIMENTAL: url of the Experimental Update Center for experimental versions of plugins. Default: "" |  | ||||||
| # JENKINS_INCREMENTALS_REPO_MIRROR: url of the incrementals repo mirror. Default: "" |  | ||||||
| # JENKINS_UC_DOWNLOAD: download url of the Update Center. Default: JENKINS_UC/download |  | ||||||
| # CURL_OPTIONS When downloading the plugins with curl. Curl options. Default: -sSfL |  | ||||||
| # CURL_CONNECTION_TIMEOUT When downloading the plugins with curl. <seconds> Maximum time allowed for connection. Default: 20 |  | ||||||
| # CURL_RETRY When downloading the plugins with curl. Retry request if transient problems occur. Default: 3 |  | ||||||
| # CURL_RETRY_DELAY When downloading the plugins with curl. <seconds> Wait time between retries. Default: 0 |  | ||||||
| # CURL_RETRY_MAX_TIME When downloading the plugins with curl. <seconds> Retry only within this period. Default: 60 |  | ||||||
| 
 |  | ||||||
| set -o pipefail |  | ||||||
| 
 |  | ||||||
| echo "WARN: install-plugins.sh is deprecated, please switch to jenkins-plugin-cli" |  | ||||||
| 
 |  | ||||||
| JENKINS_WAR=${JENKINS_WAR:-/usr/share/jenkins/jenkins.war} |  | ||||||
| 
 |  | ||||||
| . /usr/local/bin/jenkins-support |  | ||||||
| 
 |  | ||||||
| REF_DIR="${REF}/plugins" |  | ||||||
| FAILED="$REF_DIR/failed-plugins.txt" |  | ||||||
| 
 |  | ||||||
| getLockFile() { |  | ||||||
|     printf '%s' "$REF_DIR/${1}.lock" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| getArchiveFilename() { |  | ||||||
|     printf '%s' "$REF_DIR/${1}.jpi" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| download() { |  | ||||||
|     local plugin originalPlugin version lock ignoreLockFile url |  | ||||||
|     plugin="$1" |  | ||||||
|     version="${2:-latest}" |  | ||||||
|     ignoreLockFile="${3:-}" |  | ||||||
|     url="${4:-}" |  | ||||||
|     lock="$(getLockFile "$plugin")" |  | ||||||
| 
 |  | ||||||
|     if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then |  | ||||||
|         if ! doDownload "$plugin" "$version" "$url"; then |  | ||||||
|             # some plugin don't follow the rules about artifact ID |  | ||||||
|             # typically: docker-plugin |  | ||||||
|             originalPlugin="$plugin" |  | ||||||
|             plugin="${plugin}-plugin" |  | ||||||
|             if ! doDownload "$plugin" "$version" "$url"; then |  | ||||||
|                 echo "Failed to download plugin: $originalPlugin or $plugin" >&2 |  | ||||||
|                 echo "Not downloaded: ${originalPlugin}" >> "$FAILED" |  | ||||||
|                 return 1 |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
| 
 |  | ||||||
|         if ! checkIntegrity "$plugin"; then |  | ||||||
|             echo "Downloaded file is not a valid ZIP: $(getArchiveFilename "$plugin")" >&2 |  | ||||||
|             echo "Download integrity: ${plugin}" >> "$FAILED" |  | ||||||
|             rm $(getArchiveFilename "$plugin") |  | ||||||
|             return 1 |  | ||||||
|         fi |  | ||||||
| 
 |  | ||||||
|         resolveDependencies "$plugin" |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| doDownload() { |  | ||||||
|     local plugin version url jpi |  | ||||||
|     plugin="$1" |  | ||||||
|     version="$2" |  | ||||||
|     url="$3" |  | ||||||
|     jpi="$(getArchiveFilename "$plugin")" |  | ||||||
| 
 |  | ||||||
|     # If plugin already exists and is the same version do not download |  | ||||||
|     if test -f "$jpi" && unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | grep "^Plugin-Version: ${version}$" > /dev/null; then |  | ||||||
|         echo "Using provided plugin: $plugin" |  | ||||||
|         return 0 |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     if [[ -n $url ]] ; then |  | ||||||
|         echo "Will use url=$url" |  | ||||||
|     elif [[ "$version" == "latest" && -n "$JENKINS_UC_LATEST" ]]; then |  | ||||||
|         # If version-specific Update Center is available, which is the case for LTS versions, |  | ||||||
|         # use it to resolve latest versions. |  | ||||||
|         url="$JENKINS_UC_LATEST/latest/${plugin}.hpi" |  | ||||||
|     elif [[ "$version" == "experimental" && -n "$JENKINS_UC_EXPERIMENTAL" ]]; then |  | ||||||
|         # Download from the experimental update center |  | ||||||
|         url="$JENKINS_UC_EXPERIMENTAL/latest/${plugin}.hpi" |  | ||||||
|     elif [[ "$version" == incrementals* ]] ; then |  | ||||||
|         # Download from Incrementals repo: https://jenkins.io/blog/2018/05/15/incremental-deployment/
 |  | ||||||
|         # Example URL: https://repo.jenkins-ci.org/incrementals/org/jenkins-ci/plugins/workflow/workflow-support/2.19-rc289.d09828a05a74/workflow-support-2.19-rc289.d09828a05a74.hpi
 |  | ||||||
|         local groupId incrementalsVersion |  | ||||||
|         # add a trailing ; so the \n gets added to the end |  | ||||||
|         readarray -t "-d;" arrIN <<<"${version};"; |  | ||||||
|         unset 'arrIN[-1]'; |  | ||||||
|         groupId=${arrIN[1]} |  | ||||||
|         incrementalsVersion=${arrIN[2]} |  | ||||||
|         url="${JENKINS_INCREMENTALS_REPO_MIRROR}/$(echo "${groupId}" | tr '.' '/')/${plugin}/${incrementalsVersion}/${plugin}-${incrementalsVersion}.hpi" |  | ||||||
|     else |  | ||||||
|         JENKINS_UC_DOWNLOAD=${JENKINS_UC_DOWNLOAD:-"$JENKINS_UC/download"} |  | ||||||
|         url="$JENKINS_UC_DOWNLOAD/plugins/$plugin/$version/${plugin}.hpi" |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     echo "Downloading plugin: $plugin from $url" |  | ||||||
|     # We actually want to allow variable value to be split into multiple options passed to curl. |  | ||||||
|     # This is needed to allow long options and any options that take value. |  | ||||||
|     # shellcheck disable=SC2086 |  | ||||||
|     retry_command curl ${CURL_OPTIONS:--sSfL} --connect-timeout "${CURL_CONNECTION_TIMEOUT:-20}" --retry "${CURL_RETRY:-3}" --retry-delay "${CURL_RETRY_DELAY:-0}" --retry-max-time "${CURL_RETRY_MAX_TIME:-60}" "$url" -o "$jpi" |  | ||||||
|     return $? |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| checkIntegrity() { |  | ||||||
|     local plugin jpi |  | ||||||
|     plugin="$1" |  | ||||||
|     jpi="$(getArchiveFilename "$plugin")" |  | ||||||
| 
 |  | ||||||
|     unzip -t -qq "$jpi" >/dev/null |  | ||||||
|     return $? |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| resolveDependencies() { |  | ||||||
|     local plugin jpi dependencies |  | ||||||
|     plugin="$1" |  | ||||||
|     jpi="$(getArchiveFilename "$plugin")" |  | ||||||
| 
 |  | ||||||
|     dependencies="$(unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | tr '\n' '|' | sed -e 's#| ##g' | tr '|' '\n' | grep "^Plugin-Dependencies: " | sed -e 's#^Plugin-Dependencies: ##')" |  | ||||||
| 
 |  | ||||||
|     if [[ ! $dependencies ]]; then |  | ||||||
|         echo " > $plugin has no dependencies" |  | ||||||
|         return |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     echo " > $plugin depends on $dependencies" |  | ||||||
| 
 |  | ||||||
|     IFS=',' read -r -a array <<< "$dependencies" |  | ||||||
| 
 |  | ||||||
|     for d in "${array[@]}" |  | ||||||
|     do |  | ||||||
|         plugin="$(cut -d':' -f1 - <<< "$d")" |  | ||||||
|         if [[ $d == *"resolution:=optional"* ]]; then |  | ||||||
|             echo "Skipping optional dependency $plugin" |  | ||||||
|         else |  | ||||||
|             local pluginInstalled |  | ||||||
|             if pluginInstalled="$(echo -e "${bundledPlugins}\n${installedPlugins}" | grep "^${plugin}:")"; then |  | ||||||
|                 pluginInstalled="${pluginInstalled//[$'\r']}" |  | ||||||
|                 local versionInstalled; versionInstalled=$(versionFromPlugin "${pluginInstalled}") |  | ||||||
|                 local minVersion; minVersion=$(versionFromPlugin "${d}") |  | ||||||
|                 if versionLT "${versionInstalled}" "${minVersion}"; then |  | ||||||
|                     echo "Upgrading bundled dependency $d ($minVersion > $versionInstalled)" |  | ||||||
|                     download "$plugin" & |  | ||||||
|                 else |  | ||||||
|                     echo "Skipping already installed dependency $d ($minVersion <= $versionInstalled)" |  | ||||||
|                 fi |  | ||||||
|             else |  | ||||||
|                 download "$plugin" & |  | ||||||
|             fi |  | ||||||
|         fi |  | ||||||
|     done |  | ||||||
|     wait |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bundledPlugins() { |  | ||||||
|     if [ -f "$JENKINS_WAR" ] |  | ||||||
|     then |  | ||||||
|         TEMP_PLUGIN_DIR=/tmp/plugintemp.$$ |  | ||||||
|         for i in $(jar tf "$JENKINS_WAR" | grep -E '[^detached-]plugins.*\..pi' | sort) |  | ||||||
|         do |  | ||||||
|             rm -fr $TEMP_PLUGIN_DIR |  | ||||||
|             mkdir -p $TEMP_PLUGIN_DIR |  | ||||||
|             PLUGIN=$(basename "$i"|cut -f1 -d'.') |  | ||||||
|             (cd $TEMP_PLUGIN_DIR;jar xf "$JENKINS_WAR" "$i";jar xvf "$TEMP_PLUGIN_DIR/$i" META-INF/MANIFEST.MF >/dev/null 2>&1) |  | ||||||
|             VER=$(grep -E -i Plugin-Version "$TEMP_PLUGIN_DIR/META-INF/MANIFEST.MF"|cut -d: -f2|sed 's/ //')
 |  | ||||||
|             echo "$PLUGIN:$VER" |  | ||||||
|         done |  | ||||||
|         rm -fr $TEMP_PLUGIN_DIR |  | ||||||
|     else |  | ||||||
|         echo "war not found, installing all plugins: $JENKINS_WAR" |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| versionFromPlugin() { |  | ||||||
|     local plugin=$1 |  | ||||||
|     if [[ $plugin =~ .*:.* ]]; then |  | ||||||
|         echo "${plugin##*:}" |  | ||||||
|     else |  | ||||||
|         echo "latest" |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| installedPlugins() { |  | ||||||
|     for f in "$REF_DIR"/*.jpi; do |  | ||||||
|         echo "$(basename "$f" | sed -e 's/\.jpi//'):$(get_plugin_version "$f")" |  | ||||||
|     done |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| jenkinsMajorMinorVersion() { |  | ||||||
|     if [[ -f "$JENKINS_WAR" ]]; then |  | ||||||
|         local version major minor |  | ||||||
|         version="$(java -jar "$JENKINS_WAR" --version)" |  | ||||||
|         major="$(echo "$version" | cut -d '.' -f 1)" |  | ||||||
|         minor="$(echo "$version" | cut -d '.' -f 2)" |  | ||||||
|         echo "$major.$minor" |  | ||||||
|     else |  | ||||||
|         echo "" |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| main() { |  | ||||||
|     local plugin jenkinsVersion |  | ||||||
|     local plugins=() |  | ||||||
| 
 |  | ||||||
|     mkdir -p "$REF_DIR" || exit 1 |  | ||||||
|     rm -f "$FAILED" |  | ||||||
| 
 |  | ||||||
| 	echo "Cleaning up locks" |  | ||||||
| 	find "$REF_DIR" -regex ".*.lock" | while read -r filepath; do |  | ||||||
| 		rm -r "$filepath" |  | ||||||
| 	done |  | ||||||
| 
 |  | ||||||
|     # Read plugins from stdin or from the command line arguments |  | ||||||
|     if [[ ($# -eq 0) ]]; then |  | ||||||
|         while read -r line || [ "$line" != "" ]; do |  | ||||||
|             # Remove leading/trailing spaces, comments, and empty lines |  | ||||||
|             plugin=$(echo "${line}" | tr -d '\r' | sed -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ \t]*#.*$//g' -e '/^[ \t]*$/d')
 |  | ||||||
| 
 |  | ||||||
|             # Avoid adding empty plugin into array |  | ||||||
|             if [ ${#plugin} -ne 0 ]; then |  | ||||||
|                 plugins+=("${plugin}") |  | ||||||
|             fi |  | ||||||
|         done |  | ||||||
|     else |  | ||||||
|         plugins=("$@") |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     # Create lockfile manually before first run to make sure any explicit version set is used. |  | ||||||
|     echo "Creating initial locks..." |  | ||||||
|     for plugin in "${plugins[@]}"; do |  | ||||||
|         mkdir "$(getLockFile "${plugin%%:*}")" |  | ||||||
|     done |  | ||||||
| 
 |  | ||||||
|     echo "Analyzing war $JENKINS_WAR..." |  | ||||||
|     bundledPlugins="$(bundledPlugins)" |  | ||||||
| 
 |  | ||||||
|     echo "Registering preinstalled plugins..." |  | ||||||
|     installedPlugins="$(installedPlugins)" |  | ||||||
| 
 |  | ||||||
|     # Get the update center URL based on the jenkins version |  | ||||||
|     jenkinsVersion="$(jenkinsMajorMinorVersion)" |  | ||||||
|     # shellcheck disable=SC2086 |  | ||||||
|     jenkinsUcJson=$(curl ${CURL_OPTIONS:--sSfL} -o /dev/null -w "%{url_effective}" "${JENKINS_UC}/update-center.json?version=${jenkinsVersion}") |  | ||||||
|     if [ -n "${jenkinsUcJson}" ]; then |  | ||||||
|         JENKINS_UC_LATEST=${jenkinsUcJson//update-center.json/}
 |  | ||||||
|         echo "Using version-specific update center: $JENKINS_UC_LATEST..." |  | ||||||
|     else |  | ||||||
|         JENKINS_UC_LATEST= |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     echo "Downloading plugins..." |  | ||||||
|     for plugin in "${plugins[@]}"; do |  | ||||||
|         local reg='^([^:]+):?([^:]+)?:?([^:]+)?:?(http.+)?' |  | ||||||
|         if [[ $plugin =~ $reg ]]; then |  | ||||||
|             local pluginId="${BASH_REMATCH[1]}" |  | ||||||
|             local version="${BASH_REMATCH[2]}" |  | ||||||
|             local lock="${BASH_REMATCH[3]}" |  | ||||||
|             local url="${BASH_REMATCH[4]}" |  | ||||||
|             download "$pluginId" "$version" "${lock:-true}" "${url}" & |  | ||||||
|         else |  | ||||||
|           echo "Skipping the line '${plugin}' as it does not look like a reference to a plugin" |  | ||||||
|         fi |  | ||||||
|     done |  | ||||||
|     wait |  | ||||||
| 
 |  | ||||||
|     echo |  | ||||||
|     echo "WAR bundled plugins:" |  | ||||||
|     echo "${bundledPlugins}" |  | ||||||
|     echo |  | ||||||
|     echo "Installed plugins:" |  | ||||||
|     installedPlugins |  | ||||||
| 
 |  | ||||||
|     if [[ -f $FAILED ]]; then |  | ||||||
|         echo "Some plugins failed to download!" "$(<"$FAILED")" >&2 |  | ||||||
|         exit 1 |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     echo "Cleaning up locks" |  | ||||||
|     find "$REF_DIR" -regex ".*.lock" | while read -r filepath; do |  | ||||||
|         rm -r "$filepath" |  | ||||||
|     done |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| main "$@" |  | ||||||
| ` |  | ||||||
| 
 |  | ||||||
| var initBashTemplate = template.Must(template.New(InitScriptName).Parse(`#!/usr/bin/env bash | var initBashTemplate = template.Must(template.New(InitScriptName).Parse(`#!/usr/bin/env bash | ||||||
| set -e | set -e | ||||||
| set -x | set -x | ||||||
|  | @ -347,7 +46,7 @@ cat > {{ .JenkinsHomePath }}/base-plugins.txt << EOF | ||||||
| {{ end }} | {{ end }} | ||||||
| EOF | EOF | ||||||
| 
 | 
 | ||||||
| {{ $installPluginsCommand }} --verbose -f {{ .JenkinsHomePath }}/base-plugins.txt | {{ $installPluginsCommand }} --verbose --latest {{ .LatestPlugins }} -f {{ .JenkinsHomePath }}/base-plugins.txt | ||||||
| echo "Installing plugins required by Operator - end" | echo "Installing plugins required by Operator - end" | ||||||
| 
 | 
 | ||||||
| echo "Installing plugins required by user - begin" | echo "Installing plugins required by user - begin" | ||||||
|  | @ -357,7 +56,7 @@ cat > {{ .JenkinsHomePath }}/user-plugins.txt << EOF | ||||||
| {{ end }} | {{ end }} | ||||||
| EOF | EOF | ||||||
| 
 | 
 | ||||||
| {{ $installPluginsCommand }} --verbose -f {{ .JenkinsHomePath }}/user-plugins.txt | {{ $installPluginsCommand }} --verbose --latest {{ .LatestPlugins }} -f {{ .JenkinsHomePath }}/user-plugins.txt | ||||||
| echo "Installing plugins required by user - end" | echo "Installing plugins required by user - end" | ||||||
| `)) | `)) | ||||||
| 
 | 
 | ||||||
|  | @ -369,6 +68,13 @@ func buildConfigMapTypeMeta() metav1.TypeMeta { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) { | func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) { | ||||||
|  | 	defaultlatestPlugin := true | ||||||
|  | 
 | ||||||
|  | 	latestP := jenkins.Spec.Master.LatestPlugins | ||||||
|  | 	if !latestP { | ||||||
|  | 		latestP = defaultlatestPlugin | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	data := struct { | 	data := struct { | ||||||
| 		JenkinsHomePath          string | 		JenkinsHomePath          string | ||||||
| 		InitConfigurationPath    string | 		InitConfigurationPath    string | ||||||
|  | @ -376,6 +82,7 @@ func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) { | ||||||
| 		JenkinsScriptsVolumePath string | 		JenkinsScriptsVolumePath string | ||||||
| 		BasePlugins              []v1alpha2.Plugin | 		BasePlugins              []v1alpha2.Plugin | ||||||
| 		UserPlugins              []v1alpha2.Plugin | 		UserPlugins              []v1alpha2.Plugin | ||||||
|  | 		LatestPlugins            bool | ||||||
| 	}{ | 	}{ | ||||||
| 		JenkinsHomePath:          getJenkinsHomePath(jenkins), | 		JenkinsHomePath:          getJenkinsHomePath(jenkins), | ||||||
| 		InitConfigurationPath:    jenkinsInitConfigurationVolumePath, | 		InitConfigurationPath:    jenkinsInitConfigurationVolumePath, | ||||||
|  | @ -383,6 +90,7 @@ func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) { | ||||||
| 		UserPlugins:              jenkins.Spec.Master.Plugins, | 		UserPlugins:              jenkins.Spec.Master.Plugins, | ||||||
| 		InstallPluginsCommand:    installPluginsCommand, | 		InstallPluginsCommand:    installPluginsCommand, | ||||||
| 		JenkinsScriptsVolumePath: JenkinsScriptsVolumePath, | 		JenkinsScriptsVolumePath: JenkinsScriptsVolumePath, | ||||||
|  | 		LatestPlugins:            latestP, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	output, err := render.Render(initBashTemplate, data) | 	output, err := render.Render(initBashTemplate, data) | ||||||
|  | @ -410,8 +118,7 @@ func NewScriptsConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha2.Jenkins) (*co | ||||||
| 		TypeMeta:   buildConfigMapTypeMeta(), | 		TypeMeta:   buildConfigMapTypeMeta(), | ||||||
| 		ObjectMeta: meta, | 		ObjectMeta: meta, | ||||||
| 		Data: map[string]string{ | 		Data: map[string]string{ | ||||||
| 			InitScriptName:        *initBashScript, | 			InitScriptName: *initBashScript, | ||||||
| 			installPluginsCommand: installPluginsBashScript, |  | ||||||
| 		}, | 		}, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,11 +3,11 @@ package plugins | ||||||
| const ( | const ( | ||||||
| 	configurationAsCodePlugin           = "configuration-as-code:1569.vb_72405b_80249" | 	configurationAsCodePlugin           = "configuration-as-code:1569.vb_72405b_80249" | ||||||
| 	gitPlugin                           = "git:5.0.0" | 	gitPlugin                           = "git:5.0.0" | ||||||
| 	jobDslPlugin                        = "job-dsl:1.81" | 	jobDslPlugin                        = "job-dsl:1.82" | ||||||
| 	kubernetesPlugin                    = "kubernetes:3883.v4d70a_a_a_df034" | 	kubernetesPlugin                    = "kubernetes:3896.v19b_160fd9589" | ||||||
| 	kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:1.209.v862c6e5fb_1ef" | 	kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:1.209.v862c6e5fb_1ef" | ||||||
| 	workflowAggregatorPlugin            = "workflow-aggregator:590.v6a_d052e5a_a_b_5" | 	workflowAggregatorPlugin            = "workflow-aggregator:596.v8c21c963d92d" | ||||||
| 	workflowJobPlugin                   = "workflow-job:1282.ve6d865025906" | 	workflowJobPlugin                   = "workflow-job:1284.v2fe8ed4573d4" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // basePluginsList contains plugins to install by operator.
 | // basePluginsList contains plugins to install by operator.
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,103 @@ | ||||||
|  | setup() { | ||||||
|  |   load 'test_helper' | ||||||
|  |   _common_setup | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | diag() { | ||||||
|  |   echo "# DEBUG $@" >&3 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:setup | ||||||
|  | @test "1.0 Create namespace" { | ||||||
|  |   ${KUBECTL} get ns ${DETIK_CLIENT_NAMESPACE} && skip "Namespace ${DETIK_CLIENT_NAMESPACE} already exists" | ||||||
|  |   run ${KUBECTL} create ns ${DETIK_CLIENT_NAMESPACE} | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.1 Vanilla install helm chart" { | ||||||
|  |   run echo ${DETIK_CLIENT_NAMESPACE} | ||||||
|  |   run echo ${OPERATOR_IMAGE} | ||||||
|  |   ${HELM} status default && skip "Helm release 'default' already exists" | ||||||
|  |   run ${HELM} install default \ | ||||||
|  |     --set jenkins.namespace=${DETIK_CLIENT_NAMESPACE} \ | ||||||
|  |     --set namespace=${DETIK_CLIENT_NAMESPACE} \ | ||||||
|  |     --set operator.image=${OPERATOR_IMAGE} \ | ||||||
|  |     chart/jenkins-operator | ||||||
|  |   assert_success | ||||||
|  |   assert ${HELM} status default | ||||||
|  |   touch "chart/jenkins-operator/deploy.tmp" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.2 Helm: check Jenkins operator pods status" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run verify "there is 1 deployment named 'default-jenkins-operator'" | ||||||
|  |   assert_success | ||||||
|  | 
 | ||||||
|  |   run verify "there is 1 pod named 'default-jenkins-operator-'" | ||||||
|  |   assert_success | ||||||
|  | 
 | ||||||
|  |   run try "at most 20 times every 10s to get pods named 'default-jenkins-operator-' and verify that '.status.containerStatuses[?(@.name==\"jenkins-operator\")].ready' is 'true'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.3 Helm: check Jenkins Pod status" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run try "at most 20 times every 10s to get pods named 'jenkins-jenkins' and verify that '.status.containerStatuses[?(@.name==\"jenkins-master\")].ready' is 'true'" | ||||||
|  |   assert_success | ||||||
|  | 
 | ||||||
|  |   run try "at most 20 times every 5s to get pods named 'jenkins-jenkins' and verify that '.status.containerStatuses[?(@.name==\"jenkins-master\")].ready' is 'true'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.4 Helm: check Jenkins service status" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run verify "there is 1 service named 'jenkins-operator-http-jenkins'" | ||||||
|  |   assert_success | ||||||
|  | 
 | ||||||
|  |   run verify "there is 1 service named 'jenkins-operator-slave-jenkins'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.5 Helm: check Jenkins configmaps created" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run verify "there is 1 configmap named 'jenkins-operator-base-configuration-jenkins'" | ||||||
|  |   assert_success | ||||||
|  |   run verify "there is 1 configmap named 'jenkins-operator-init-configuration-jenkins'" | ||||||
|  |   assert_success | ||||||
|  |   run verify "there is 1 configmap named 'jenkins-operator-scripts-jenkins'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.6 Helm: check Jenkins operator role status" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run verify "there are 2 role named 'jenkins-operator*'" | ||||||
|  |   assert_success | ||||||
|  |   run verify "there is 1 role named 'leader-election-role'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.7 Helm: check Jenkins operator role binding status" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run verify "there is 1 rolebinding named 'jenkins-operator-jenkins'" | ||||||
|  |   assert_success | ||||||
|  |   run verify "there is 1 rolebinding named 'leader-election-rolebinding'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #bats test_tags=phase:helm | ||||||
|  | @test "1.8 Helm: check Jenkins operator service account status" { | ||||||
|  |   [[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly" | ||||||
|  |   run verify "there are 2 serviceaccount named 'jenkins-operator*'" | ||||||
|  |   assert_success | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @test "1.9 Helm: Clean" { | ||||||
|  |   rm "chart/jenkins-operator/deploy.tmp" | ||||||
|  | } | ||||||
|  | @ -0,0 +1,13 @@ | ||||||
|  | _common_setup() { | ||||||
|  |     export BATS_LIB_PATH="/usr/lib/" | ||||||
|  |     bats_load_library bats-support | ||||||
|  |     bats_load_library bats-assert | ||||||
|  |     bats_load_library bats-file | ||||||
|  |     bats_load_library bats-detik/detik.bash | ||||||
|  | 
 | ||||||
|  |     CONTEXT="kind-jenkins" | ||||||
|  |     export DETIK_CLIENT_NAME="kubectl" | ||||||
|  |     export DETIK_CLIENT_NAMESPACE="ns-$(git rev-parse --verify HEAD --short)" | ||||||
|  |     export KUBECTL="kubectl --context=${CONTEXT} -n ${DETIK_CLIENT_NAMESPACE}" | ||||||
|  |     export HELM="helm --kube-context=${CONTEXT} -n ${DETIK_CLIENT_NAMESPACE}" | ||||||
|  | } | ||||||
|  | @ -26,11 +26,11 @@ const e2e = "e2e" | ||||||
| var expectedBasePluginsList = []plugins.Plugin{ | var expectedBasePluginsList = []plugins.Plugin{ | ||||||
| 	plugins.Must(plugins.New("configuration-as-code:1569.vb_72405b_80249")), | 	plugins.Must(plugins.New("configuration-as-code:1569.vb_72405b_80249")), | ||||||
| 	plugins.Must(plugins.New("git:5.0.0")), | 	plugins.Must(plugins.New("git:5.0.0")), | ||||||
| 	plugins.Must(plugins.New("kubernetes:3883.v4d70a_a_a_df034")), | 	plugins.Must(plugins.New("kubernetes:3896.v19b_160fd9589")), | ||||||
| 	plugins.Must(plugins.New("kubernetes-credentials-provider:1.209.v862c6e5fb_1ef")), | 	plugins.Must(plugins.New("kubernetes-credentials-provider:1.209.v862c6e5fb_1ef")), | ||||||
| 	plugins.Must(plugins.New("job-dsl:1.81")), | 	plugins.Must(plugins.New("job-dsl:1.82")), | ||||||
| 	plugins.Must(plugins.New("workflow-aggregator:590.v6a_d052e5a_a_b_5")), | 	plugins.Must(plugins.New("workflow-aggregator:596.v8c21c963d92d")), | ||||||
| 	plugins.Must(plugins.New("workflow-job:1282.ve6d865025906")), | 	plugins.Must(plugins.New("workflow-job:1284.v2fe8ed4573d4")), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func createUserConfigurationSecret(namespace string, stringData map[string]string) { | func createUserConfigurationSecret(namespace string, stringData map[string]string) { | ||||||
|  |  | ||||||
|  | @ -97,7 +97,7 @@ var _ = Describe("Jenkins controller", func() { | ||||||
| 
 | 
 | ||||||
| 	Context("when running Jenkins safe restart", func() { | 	Context("when running Jenkins safe restart", func() { | ||||||
| 		It("authorization strategy is not overwritten", func() { | 		It("authorization strategy is not overwritten", func() { | ||||||
|            // TODO: @brokenpip3 temporary disable this flaky test
 | 			// TODO: @brokenpip3 temporary disable this flaky test
 | ||||||
| 			Skip("Temporary skipping this test") | 			Skip("Temporary skipping this test") | ||||||
| 			WaitForJenkinsBaseConfigurationToComplete(jenkins) | 			WaitForJenkinsBaseConfigurationToComplete(jenkins) | ||||||
| 			WaitForJenkinsUserConfigurationToComplete(jenkins) | 			WaitForJenkinsUserConfigurationToComplete(jenkins) | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ import ( | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/envtest" | 	"sigs.k8s.io/controller-runtime/pkg/envtest" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const JenkinsTestImage = "jenkins/jenkins:2.375.3-lts" | const JenkinsTestImage = "jenkins/jenkins:2.387.1-lts" | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	Cfg       *rest.Config | 	Cfg       *rest.Config | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ var _ = Describe("Jenkins Controller", func() { | ||||||
| 
 | 
 | ||||||
| 			cmd := exec.Command("../../bin/helm", "upgrade", "jenkins", "../../chart/jenkins-operator", "--namespace", namespace.Name, "--debug", | 			cmd := exec.Command("../../bin/helm", "upgrade", "jenkins", "../../chart/jenkins-operator", "--namespace", namespace.Name, "--debug", | ||||||
| 				"--set-string", fmt.Sprintf("jenkins.namespace=%s", namespace.Name), | 				"--set-string", fmt.Sprintf("jenkins.namespace=%s", namespace.Name), | ||||||
| 				"--set-string", fmt.Sprintf("jenkins.image=%s", "jenkins/jenkins:2.375.3-lts"), | 				"--set-string", fmt.Sprintf("jenkins.image=%s", "jenkins/jenkins:2.387.1-lts"), | ||||||
| 				"--set-string", fmt.Sprintf("operator.image=%s", *imageName), "--install") | 				"--set-string", fmt.Sprintf("operator.image=%s", *imageName), "--install") | ||||||
| 			output, err := cmd.CombinedOutput() | 			output, err := cmd.CombinedOutput() | ||||||
| 			Expect(err).NotTo(HaveOccurred(), string(output)) | 			Expect(err).NotTo(HaveOccurred(), string(output)) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue