Merge remote-tracking branch 'origin/master' into version-9.0
This commit is contained in:
commit
e7dcbb6ad3
|
|
@ -1,4 +0,0 @@
|
|||
# Configuration for devbots-needs-triage - https://devbots.xyz/documentation/needs-triage/
|
||||
|
||||
enabled: true
|
||||
label: "needs triage"
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json
|
||||
{
|
||||
"name": "Jenkins kubernetes operator devcontainer",
|
||||
"image": "mcr.microsoft.com/devcontainers/base:bookworm",
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
||||
"enableNonRootDocker": "true",
|
||||
"moby": "true"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {
|
||||
"version": "latest",
|
||||
"helm": "latest",
|
||||
"minikube": "none"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/go:1": {
|
||||
"version": "1.15",
|
||||
"golangciLintVersion": "1.26.0"
|
||||
},
|
||||
"ghcr.io/mpriscella/features/kind:1": {
|
||||
"version": "latest"
|
||||
},
|
||||
"ghcr.io/edouard-lopez/devcontainer-features/bats:0": {
|
||||
"version": "latest"
|
||||
},
|
||||
"ghcr.io/brokenpip3/devcontainers-bats/bats-libs:0": {
|
||||
}
|
||||
},
|
||||
// "forwardPorts": [],
|
||||
|
||||
"postCreateCommand": "go version",
|
||||
|
||||
// "postStartCommand": "nohup bash -c 'minikube start &' > minikube.log 2>&1",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"codespaces": {
|
||||
"openFiles": [
|
||||
"Makefile"
|
||||
]
|
||||
},
|
||||
// install some vscode extensions
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"golang.Go",
|
||||
"jetmartin.bats",
|
||||
"ms-kubernetes-tools.vscode-kubernetes-tools",
|
||||
"budparr.language-hugo-vscode",
|
||||
"GitHub.copilot",
|
||||
"GitHub.copilot-chat"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
|
|
@ -4,11 +4,25 @@ updates:
|
|||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
golang:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
directory: "/website"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
npm:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
interval: "daily"
|
||||
groups:
|
||||
actions:
|
||||
patterns:
|
||||
- "*"
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 30
|
||||
|
||||
# Number of days of inactivity before a stale Issue or Pull Request is closed.
|
||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 30
|
||||
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- frozen
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
|
||||
issues:
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs.
|
||||
If this issue is still affecting you, just comment with any updates and we'll keep it open.
|
||||
Thank you for your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
Closing this issue after a prolonged period of inactivity.
|
||||
If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!
|
||||
|
||||
pulls:
|
||||
# Comment to post when marking a pull request as stale.
|
||||
markComment: >
|
||||
This pull request has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs.
|
||||
If this pull request is still relevant, just comment with any updates and we'll keep it open.
|
||||
Thank you for your contributions.
|
||||
|
||||
# Comment to post when closing a stale pull request. Set to `false` to disable
|
||||
closeComment: >
|
||||
Closing this pull request after a prolonged period of inactivity.
|
||||
If this issue is still present in the latest release, please ask for this pull request to be reopened. Thank you!
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
|
@ -18,4 +18,4 @@ jobs:
|
|||
with:
|
||||
check_filenames: true
|
||||
ignore_words_list: aks,ags,startin
|
||||
skip: "*.js,package-lock.json,*.lock,*/Font-Awesome/*,*.toml,*.svg,*assets/vendor/bootstrap*"
|
||||
skip: "*.js,package-lock.json,*.lock,*/Font-Awesome/*,*.toml,*.svg,*assets/vendor/bootstrap*,cert-manager.crds.yaml"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ jobs:
|
|||
steps:
|
||||
# Checks out a copy of your repository on the ubuntu-latest machine
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive # Fetch the Docsy theme
|
||||
fetch-depth: 0
|
||||
|
|
@ -39,7 +39,7 @@ jobs:
|
|||
if: env.IS_CHANGED == 'true'
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: '0.62.2'
|
||||
hugo-version: '0.113.0'
|
||||
extended: true
|
||||
|
||||
# Sets up node - required by Hugo
|
||||
|
|
@ -77,7 +77,7 @@ jobs:
|
|||
# Creates pull request with generated docs
|
||||
- name: Create Pull Request
|
||||
if: env.IS_CHANGED == 'true'
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Auto-updated docs
|
||||
branch: docs-generator
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
name: Update k8s manifests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- 'website/**'
|
||||
- 'assets/**'
|
||||
- 'backup/**'
|
||||
- '*.md'
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
update-manifest:
|
||||
name: Update k8s manifests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up env vars
|
||||
run: |
|
||||
echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env)" >> $GITHUB_ENV
|
||||
|
||||
- name: Helm lint
|
||||
run: make helm-lint
|
||||
|
||||
#TODO: add also the webhook part and understand if is necessary
|
||||
- name: Helm update plain manifests
|
||||
run: |
|
||||
helm template --set fullnameOverride=jenkins-operator \
|
||||
--set jenkins.enabled=false \
|
||||
--set jenkins.backup.enabled=false \
|
||||
--set jenkins.backup.pvc.enabled=false \
|
||||
--set operator.resources.limits.cpu=100m \
|
||||
--set operator.resources.limits.memory=120Mi \
|
||||
--set operator.resources.requests.cpu=100m \
|
||||
--set operator.resources.requests.memory=120Mi \
|
||||
chart/jenkins-operator/ > deploy/all-in-one-v1alpha2.yaml
|
||||
sed -i '/namespace: default/d' deploy/all-in-one-v1alpha2.yaml
|
||||
sed -i 's/# Source: .*//g' deploy/all-in-one-v1alpha2.yaml
|
||||
sed -i 's/app\.kubernetes\.io\/instance: release-name//g' deploy/all-in-one-v1alpha2.yaml
|
||||
sed -i 's/app\.kubernetes\.io\/managed-by: Helm//g' deploy/all-in-one-v1alpha2.yaml
|
||||
sed -i 's/helm\.sh\/chart: [a-zA-Z0-9]+//g' deploy/all-in-one-v1alpha2.yaml
|
||||
sed -i '/^[[:space:]]*$/d' deploy/all-in-one-v1alpha2.yaml
|
||||
|
||||
cp chart/jenkins-operator/crds/jenkins-crd.yaml deploy/crds/jenkins.io_jenkins_crd.yaml
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Auto-updated Kubernetes Manifests
|
||||
branch: manifest-deploy-update
|
||||
title: Auto-updated Kubernetes Manifests
|
||||
body: |
|
||||
Auto-updated Kubernetes Manifests from master commit ${{ github.sha }}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
name: "Stale issue automation"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 9 * * *"
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
operations-per-run: 200
|
||||
days-before-issue-stale: 60
|
||||
days-before-issue-close: 10
|
||||
exempt-pr-labels: "not-stale"
|
||||
exempt-issue-labels: "not-stale"
|
||||
|
|
@ -44,13 +44,13 @@ jobs:
|
|||
- name: Ensure Golang runtime dependencies
|
||||
run: make go-dependencies
|
||||
|
||||
- name: Setup BATS
|
||||
uses: mig4/setup-bats@v1
|
||||
- name: Setup Bats and libs
|
||||
uses: brokenpip3/setup-bats-libs@1.5.2
|
||||
with:
|
||||
bats-version: 1.9.0
|
||||
|
||||
- name: Setup Bats libs
|
||||
uses: brokenpip3/setup-bats-libs@0.1.0
|
||||
support-path: "${{ github.workspace }}/.bats/bats-support"
|
||||
assert-path: "${{ github.workspace }}/.bats/bats-assert"
|
||||
detik-path: "${{ github.workspace }}/.bats/bats-detik"
|
||||
file-path: "${{ github.workspace }}/.bats/bats-file"
|
||||
|
||||
- name: Kind setup
|
||||
uses: helm/kind-action@v1.5.0
|
||||
|
|
@ -58,4 +58,6 @@ jobs:
|
|||
cluster_name: ${{env.KIND_CLUSTER_NAME}}
|
||||
|
||||
- name: Jenkins Operator - bats tests
|
||||
env:
|
||||
BATS_LIB_PATH: "${{ github.workspace }}/.bats"
|
||||
run: make bats-tests
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up env vars
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up env vars
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check envs
|
||||
run: make -C backup/pvc check-env
|
||||
|
|
@ -40,11 +40,13 @@ jobs:
|
|||
- name: Bump the version
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
run: make -C backup/pvc sembump && make -C backup/pvc bump-version
|
||||
run: |
|
||||
make -C backup/pvc sembump
|
||||
make -C backup/pvc bump-version
|
||||
|
||||
- name: Login to Quay.io
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAYIO_USERNAME }}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Deploy Helm chart
|
||||
run: |
|
||||
|
|
@ -31,7 +31,7 @@ jobs:
|
|||
|
||||
# Creates pull request with new chart version
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Release Helm chart ${{ github.event.inputs.chartVersion }}
|
||||
branch: helm-chart-release-${{ github.event.inputs.chartVersion }}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Prep - check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prep - Set up env vars
|
||||
run: |
|
||||
|
|
@ -92,7 +92,7 @@ jobs:
|
|||
run: make bats-tests
|
||||
|
||||
- name: Post - Login to Quay.io
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAYIO_USERNAME }}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
tag_name: ${{ env.VERSION }}
|
||||
|
||||
- name: Login to Quay.io
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAYIO_USERNAME }}
|
||||
|
|
|
|||
7
Makefile
7
Makefile
|
|
@ -147,6 +147,7 @@ update-lts-version: ## Update the latest lts version
|
|||
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
|
||||
sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' pkg/constants/constants.go
|
||||
|
||||
.PHONY: run
|
||||
run: export WATCH_NAMESPACE = $(NAMESPACE)
|
||||
|
|
@ -387,11 +388,11 @@ 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
|
||||
OPERATOR_IMAGE="${IMAGE_NAME}" TERM=xterm bats -T -p test/bats
|
||||
else
|
||||
bats-tests: ## Run bats tests
|
||||
@echo "+ $@"
|
||||
OPERATOR_IMAGE="${IMAGE_NAME}" TERM=xterm bats -T -p -x test/bats
|
||||
OPERATOR_IMAGE="${IMAGE_NAME}" TERM=xterm bats -T -p test/bats
|
||||
endif
|
||||
|
||||
.PHONY: crc-start
|
||||
|
|
@ -479,7 +480,7 @@ helm-release-latest: helm
|
|||
|
||||
# Download and build hugo extended locally if necessary
|
||||
HUGO_PATH = $(shell pwd)/bin/hugo
|
||||
HUGO_VERSION = v0.111.3
|
||||
HUGO_VERSION = v0.113.0
|
||||
HAS_HUGO := $(shell $(HUGO_PATH)/hugo version 2>&- | grep $(HUGO_VERSION))
|
||||
.PHONY: hugo
|
||||
hugo:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
# Jenkins Operator
|
||||
|
||||
[](https://github.com/jenkinsci/kubernetes-operator/releases/tag/v0.7.1)
|
||||
[](https://github.com/jenkinsci/kubernetes-operator/releases/tag/v0.8.0)
|
||||
[](https://github.com/jenkinsci/kubernetes-operator/actions/workflows/auto-tests-e2e.yaml)
|
||||
[](https://goreportcard.com/report/github.com/jenkinsci/kubernetes-operator)
|
||||
[](https://gitter.im/jenkinsci/kubernetes-operator)
|
||||
|
||||

|
||||
<a href="">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins_gopher_wide_exp_dark.png">
|
||||
<img src="https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins_gopher_wide_exp.png">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
## What's the Jenkins Operator?
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
v0.8.0-beta
|
||||
v0.8.0
|
||||
|
|
|
|||
|
|
@ -373,7 +373,8 @@ type JenkinsMaster struct {
|
|||
// 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"`
|
||||
// +optional
|
||||
LatestPlugins *bool `json:"latestPlugins,omitempty"`
|
||||
|
||||
// DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins
|
||||
DisableCSRFProtection bool `json:"disableCSRFProtection"`
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
|
|
@ -1,4 +1,4 @@
|
|||
FROM debian:bullseye-slim
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
LABEL maintainer="Jenkins Kubernetes Operator Community" \
|
||||
org.opencontainers.image.authors="Jenkins Kubernetes Operator Community" \
|
||||
|
|
@ -6,14 +6,17 @@ LABEL maintainer="Jenkins Kubernetes Operator Community" \
|
|||
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"
|
||||
org.opencontainers.image.base.name="debian:bookworm-slim"
|
||||
|
||||
ARG UID
|
||||
ARG GID
|
||||
|
||||
ENV USER=user
|
||||
|
||||
RUN addgroup --gid "$GID" "$USER" && \
|
||||
RUN apt update \
|
||||
&& apt install -y procps zstd \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& addgroup --gid "$GID" "$USER" && \
|
||||
adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
|
|
@ -21,9 +24,9 @@ RUN addgroup --gid "$GID" "$USER" && \
|
|||
--uid "$UID" \
|
||||
"$USER"
|
||||
|
||||
COPY bin/*.sh /home/user/bin/
|
||||
RUN chmod +x /home/user/bin/*.sh
|
||||
WORKDIR /home/user/bin
|
||||
COPY bin .
|
||||
RUN chmod +x *.sh
|
||||
USER user
|
||||
|
||||
CMD ./run.sh
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
v0.2.2
|
||||
v0.2.5
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ set -eo pipefail
|
|||
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
|
||||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
||||
BACKUP_TMP_DIR=$(mktemp -d)
|
||||
trap "test -d "${BACKUP_TMP_DIR}" && rm -fr "${BACKUP_TMP_DIR}"" EXIT ERR SIGINT SIGTERM
|
||||
trap "test -d "${BACKUP_TMP_DIR}" && rm -fr "${BACKUP_TMP_DIR}"" EXIT SIGINT SIGTERM
|
||||
|
||||
backup_number=$1
|
||||
echo "Running backup"
|
||||
|
|
@ -15,12 +15,22 @@ echo "Running backup"
|
|||
# config.xml in child directories is state that should. For example-
|
||||
# branches/myorg/branches/myrepo/branches/master/config.xml should be retained while
|
||||
# branches/myorg/config.xml should not
|
||||
tar -C "${JENKINS_HOME}" -czf "${BACKUP_TMP_DIR}/${backup_number}.tar.gz" --exclude jobs/*/workspace* --no-wildcards-match-slash --anchored --exclude jobs/*/config.xml -c jobs && \
|
||||
mv "${BACKUP_TMP_DIR}/${backup_number}.tar.gz" "${BACKUP_DIR}/${backup_number}.tar.gz"
|
||||
tar --zstd -C "${JENKINS_HOME}" -cf "${BACKUP_TMP_DIR}/${backup_number}.tar.zstd" \
|
||||
--exclude jobs/*/workspace* \
|
||||
--no-wildcards-match-slash --anchored \
|
||||
--ignore-failed-read \
|
||||
--exclude jobs/*/config.xml -c jobs || ret=$?
|
||||
|
||||
if [[ "$ret" -eq 0 ]]; then
|
||||
echo "Backup was completed without warnings"
|
||||
mv "${BACKUP_TMP_DIR}/${backup_number}.tar.zstd" "${BACKUP_DIR}/${backup_number}.tar.zstd"
|
||||
elif [[ "$ret" -eq 1 ]]; then
|
||||
echo "Backup was completed with some warnings"
|
||||
mv "${BACKUP_TMP_DIR}/${backup_number}.tar.zstd" "${BACKUP_DIR}/${backup_number}.tar.zstd"
|
||||
fi
|
||||
|
||||
rm -rf "${BACKUP_TMP_DIR}"
|
||||
|
||||
[[ ! -s ${BACKUP_DIR}/${backup_number}.tar.gz ]] && echo "backup file '${BACKUP_DIR}/${backup_number}.tar.gz' is empty" && exit 1;
|
||||
[[ ! -s ${BACKUP_DIR}/${backup_number}.tar.zstd ]] && echo "backup file '${BACKUP_DIR}/${backup_number}.tar.zstd' is empty" && exit 1;
|
||||
|
||||
echo Done
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
set -eo pipefail
|
||||
|
||||
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1
|
||||
|
||||
latest=$(find ${BACKUP_DIR} -name '*.tar.gz' -exec basename {} \; | sort -g | tail -n 1)
|
||||
# Search for all the tar.* inside the backup dir to support the migration between gzip vs zstd
|
||||
latest=$(find ${BACKUP_DIR} -name '*.tar.*' -exec basename {} \; | sort -g | tail -n 1)
|
||||
|
||||
if [[ "${latest}" == "" ]]; then
|
||||
echo "-1"
|
||||
|
|
|
|||
|
|
@ -7,9 +7,23 @@ set -eo pipefail
|
|||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
||||
|
||||
backup_number=$1
|
||||
backup_file="${BACKUP_DIR}/${backup_number}"
|
||||
echo "Running restore backup with backup number #${backup_number}"
|
||||
|
||||
tar -C ${JENKINS_HOME} -zxf "${BACKUP_DIR}/${backup_number}.tar.gz"
|
||||
if [[ -f "$backup_file.tar.gz" ]]; then
|
||||
echo "Old format tar.gz found, restoring it"
|
||||
OPTS=""
|
||||
EXT="tar.gz"
|
||||
elif [[ -f "$backup_file.tar.zstd" ]]; then
|
||||
echo "Backup file found, proceeding"
|
||||
OPTS="--zstd"
|
||||
EXT="tar.zstd"
|
||||
else
|
||||
echo "ERR: Backup file not found: $backup_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar $OPTS -C "${JENKINS_HOME}" -xf "${BACKUP_DIR}/${backup_number}.${EXT}"
|
||||
|
||||
echo Done
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ do
|
|||
if [[ ! -z "${BACKUP_COUNT}" ]]; then
|
||||
echo "Trimming to only ${BACKUP_COUNT} recent backups in preparation for new backup"
|
||||
#TODO: add the list of exceeding backup before delete
|
||||
find ${BACKUP_DIR} -maxdepth 1 -name '*.tar.gz' -exec basename {} \; | sort -gr | tail -n +$((BACKUP_COUNT +1)) | xargs -I '{}' rm ${BACKUP_DIR}/'{}'
|
||||
find ${BACKUP_DIR} -maxdepth 1 -name '*.tar.zstd' -exec basename {} \; | sort -gr | tail -n +$((BACKUP_COUNT +1)) | xargs -I '{}' rm ${BACKUP_DIR}/'{}'
|
||||
fi
|
||||
done
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${RESTORE_FOLDE
|
|||
backup_number=1
|
||||
docker exec ${cid} /home/user/bin/backup.sh ${backup_number}
|
||||
|
||||
backup_file="${BACKUP_DIR}/${backup_number}.tar.gz"
|
||||
backup_file="${BACKUP_DIR}/${backup_number}.tar.zstd"
|
||||
[[ ! -f ${backup_file} ]] && echo "Backup file ${backup_file} not found" && exit 1;
|
||||
|
||||
docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/restore.sh ${backup_number}"
|
||||
|
|
@ -38,4 +38,4 @@ docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/r
|
|||
echo "Compare directories"
|
||||
diff --brief --recursive "${RESTORE_FOLDER}" "${JENKINS_HOME_AFTER_RESTORE}"
|
||||
echo "Directories are the same"
|
||||
echo PASS
|
||||
echo PASS
|
||||
|
|
|
|||
|
|
@ -19,17 +19,17 @@ mkdir -p ${BACKUP_DIR}
|
|||
mkdir -p ${JENKINS_HOME}
|
||||
|
||||
mkdir -p ${BACKUP_DIR}/lost+found
|
||||
touch ${BACKUP_DIR}/1.tar.gz
|
||||
touch ${BACKUP_DIR}/2.tar.gz
|
||||
touch ${BACKUP_DIR}/3.tar.gz
|
||||
touch ${BACKUP_DIR}/4.tar.gz
|
||||
touch ${BACKUP_DIR}/5.tar.gz
|
||||
touch ${BACKUP_DIR}/6.tar.gz
|
||||
touch ${BACKUP_DIR}/7.tar.gz
|
||||
touch ${BACKUP_DIR}/8.tar.gz
|
||||
touch ${BACKUP_DIR}/9.tar.gz
|
||||
touch ${BACKUP_DIR}/10.tar.gz
|
||||
touch ${BACKUP_DIR}/11.tar.gz
|
||||
touch ${BACKUP_DIR}/1.tar.zstd
|
||||
touch ${BACKUP_DIR}/2.tar.zstd
|
||||
touch ${BACKUP_DIR}/3.tar.zstd
|
||||
touch ${BACKUP_DIR}/4.tar.zstd
|
||||
touch ${BACKUP_DIR}/5.tar.zstd
|
||||
touch ${BACKUP_DIR}/6.tar.zstd
|
||||
touch ${BACKUP_DIR}/7.tar.zstd
|
||||
touch ${BACKUP_DIR}/8.tar.zstd
|
||||
touch ${BACKUP_DIR}/9.tar.zstd
|
||||
touch ${BACKUP_DIR}/10.tar.zstd
|
||||
touch ${BACKUP_DIR}/11.tar.zstd
|
||||
|
||||
# Create an instance of the container under testing
|
||||
cid="$(docker run -e JENKINS_HOME=${JENKINS_HOME} -v ${JENKINS_HOME}:${JENKINS_HOME}:ro -e BACKUP_DIR=${BACKUP_DIR} -v ${BACKUP_DIR}:${BACKUP_DIR}:rw -d ${docker_image})"
|
||||
|
|
@ -39,7 +39,7 @@ echo "Docker container ID '${cid}'"
|
|||
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
|
||||
|
||||
latest=$(docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/get-latest.sh")
|
||||
rm ${BACKUP_DIR}/*.tar.gz
|
||||
rm ${BACKUP_DIR}/*.tar.zstd
|
||||
empty_latest=$(docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/get-latest.sh")
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
|
|
|
|||
|
|
@ -19,17 +19,17 @@ mkdir -p ${BACKUP_DIR}
|
|||
mkdir -p ${JENKINS_HOME}
|
||||
|
||||
mkdir -p ${BACKUP_DIR}/lost+found
|
||||
touch ${BACKUP_DIR}/1.tar.gz
|
||||
touch ${BACKUP_DIR}/2.tar.gz
|
||||
touch ${BACKUP_DIR}/3.tar.gz
|
||||
touch ${BACKUP_DIR}/4.tar.gz
|
||||
touch ${BACKUP_DIR}/5.tar.gz
|
||||
touch ${BACKUP_DIR}/6.tar.gz
|
||||
touch ${BACKUP_DIR}/7.tar.gz
|
||||
touch ${BACKUP_DIR}/8.tar.gz
|
||||
touch ${BACKUP_DIR}/9.tar.gz
|
||||
touch ${BACKUP_DIR}/10.tar.gz
|
||||
touch ${BACKUP_DIR}/11.tar.gz
|
||||
touch ${BACKUP_DIR}/1.tar.zstd
|
||||
touch ${BACKUP_DIR}/2.tar.zstd
|
||||
touch ${BACKUP_DIR}/3.tar.zstd
|
||||
touch ${BACKUP_DIR}/4.tar.zstd
|
||||
touch ${BACKUP_DIR}/5.tar.zstd
|
||||
touch ${BACKUP_DIR}/6.tar.zstd
|
||||
touch ${BACKUP_DIR}/7.tar.zstd
|
||||
touch ${BACKUP_DIR}/8.tar.zstd
|
||||
touch ${BACKUP_DIR}/9.tar.zstd
|
||||
touch ${BACKUP_DIR}/10.tar.zstd
|
||||
touch ${BACKUP_DIR}/11.tar.zstd
|
||||
|
||||
# Create an instance of the container under testing
|
||||
cid="$(docker run -e BACKUP_COUNT=2 -e JENKINS_HOME=${JENKINS_HOME} -v ${JENKINS_HOME}:${JENKINS_HOME}:ro -e BACKUP_DIR=${BACKUP_DIR} -v ${BACKUP_DIR}:${BACKUP_DIR}:rw -d ${docker_image})"
|
||||
|
|
@ -39,7 +39,7 @@ echo "Docker container ID '${cid}'"
|
|||
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
|
||||
|
||||
sleep 11
|
||||
touch ${BACKUP_DIR}/12.tar.gz
|
||||
touch ${BACKUP_DIR}/12.tar.zstd
|
||||
sleep 11
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
|
|
@ -48,7 +48,7 @@ if [[ "${DEBUG}" ]]; then
|
|||
fi
|
||||
|
||||
# only two latest backup should exists
|
||||
[[ $(ls -1 ${BACKUP_DIR} | grep 'tar.gz' | wc -l) -eq 2 ]] || exit 1
|
||||
[[ -f ${BACKUP_DIR}/11.tar.gz ]] || exit 2
|
||||
[[ -f ${BACKUP_DIR}/12.tar.gz ]] || exit 3
|
||||
[[ $(ls -1 ${BACKUP_DIR} | grep 'tar.zstd' | wc -l) -eq 2 ]] || exit 1
|
||||
[[ -f ${BACKUP_DIR}/11.tar.zstd ]] || exit 2
|
||||
[[ -f ${BACKUP_DIR}/12.tar.zstd ]] || exit 3
|
||||
echo PASS
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ docker exec ${cid} /home/user/bin/backup.sh ${backup_number}
|
|||
|
||||
[ "$(docker exec ${cid} ls /tmp | grep 'tmp')" ] && echo "tmp directory not empty" && exit 1;
|
||||
|
||||
backup_file="${BACKUP_DIR}/${backup_number}.tar.gz"
|
||||
backup_file="${BACKUP_DIR}/${backup_number}.tar.zstd"
|
||||
[[ ! -f ${backup_file} ]] && echo "Backup file ${backup_file} not found" && exit 1;
|
||||
|
||||
echo "tmp directory empty, backup in backup directory present"
|
||||
echo PASS
|
||||
echo PASS
|
||||
|
|
|
|||
|
|
@ -1,6 +1,36 @@
|
|||
apiVersion: v1
|
||||
entries:
|
||||
jenkins-operator:
|
||||
- apiVersion: v2
|
||||
appVersion: 0.8.0
|
||||
created: "2023-09-13T06:54:41.369295961Z"
|
||||
dependencies:
|
||||
- condition: webhook.enabled
|
||||
name: cert-manager
|
||||
repository: https://charts.jetstack.io
|
||||
version: 1.5.1
|
||||
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||
digest: da8ae04166cb1b64a9dd3d741c6a50d63846ebe8e2e92f09313ad3c6a0dd9ca4
|
||||
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
|
||||
name: jenkins-operator
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.8.0.tgz
|
||||
version: 0.8.0
|
||||
- apiVersion: v2
|
||||
appVersion: 0.8.0-beta.2
|
||||
created: "2023-06-30T21:22:53.308590035Z"
|
||||
dependencies:
|
||||
- condition: webhook.enabled
|
||||
name: cert-manager
|
||||
repository: https://charts.jetstack.io
|
||||
version: 1.5.1
|
||||
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||
digest: b2502f91dffa1136190a8a98d73ac997c70387e100d79200b7403039ca98411e
|
||||
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
|
||||
name: jenkins-operator
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.8.0-beta.2.tgz
|
||||
version: 0.8.0-beta.2
|
||||
- apiVersion: v2
|
||||
appVersion: v0.8.0-beta
|
||||
created: "2023-04-17T22:11:04.706959723Z"
|
||||
|
|
@ -348,4 +378,4 @@ entries:
|
|||
urls:
|
||||
- https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.0.1.tgz
|
||||
version: 0.0.1
|
||||
generated: "2023-04-17T22:11:04.68789848Z"
|
||||
generated: "2023-09-13T06:54:41.354056045Z"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
apiVersion: v2
|
||||
appVersion: "v0.8.0-beta"
|
||||
appVersion: "0.8.0"
|
||||
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||
name: jenkins-operator
|
||||
version: v0.8.0-beta
|
||||
version: 0.8.0
|
||||
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
|
||||
dependencies:
|
||||
- name: cert-manager
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# jenkins-operator
|
||||
|
||||
 
|
||||
 
|
||||
|
||||
Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ Kubernetes native operator which fully manages Jenkins on Kubernetes
|
|||
| 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.image | string | `"quay.io/jenkins-kubernetes-operator/backup-pvc:v0.2.6"` | |
|
||||
| jenkins.backup.interval | int | `30` | |
|
||||
| jenkins.backup.makeBackupBeforePodDeletion | bool | `true` | |
|
||||
| jenkins.backup.pvc.className | string | `""` | |
|
||||
|
|
@ -52,7 +52,7 @@ Kubernetes native operator which fully manages Jenkins on Kubernetes
|
|||
| jenkins.enabled | bool | `true` | |
|
||||
| jenkins.env | list | `[]` | |
|
||||
| jenkins.hostAliases | object | `{}` | |
|
||||
| jenkins.image | string | `"jenkins/jenkins:2.387.2-lts"` | |
|
||||
| jenkins.image | string | `"jenkins/jenkins:2.414.1-lts"` | |
|
||||
| jenkins.imagePullPolicy | string | `"Always"` | |
|
||||
| jenkins.imagePullSecrets | list | `[]` | |
|
||||
| jenkins.labels | object | `{}` | |
|
||||
|
|
@ -88,13 +88,14 @@ Kubernetes native operator which fully manages Jenkins on Kubernetes
|
|||
| 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:v0.8.0-beta"` | |
|
||||
| operator.image | string | `"quay.io/jenkins-kubernetes-operator/operator:v0.8.0"` | |
|
||||
| operator.imagePullPolicy | string | `"IfNotPresent"` | |
|
||||
| operator.imagePullSecrets | list | `[]` | |
|
||||
| operator.nameOverride | string | `""` | |
|
||||
|
|
|
|||
|
|
@ -157,11 +157,11 @@ spec:
|
|||
type: object
|
||||
basePlugins:
|
||||
description: 'BasePlugins contains plugins required by operator
|
||||
Defaults to : - name: kubernetes version: "1.31.3" - name:
|
||||
workflow-job version: "1145.v7f2433caa07f" - name: workflow-aggregator version:
|
||||
"2.6" - name: git version: "4.11.3" - name: job-dsl version:
|
||||
"1.78.1" - name: configuration-as-code version: "1346.ve8cfa_3473c94" - name:
|
||||
kubernetes-credentials-provider version: "0.20"'
|
||||
Defaults to : - name: configuration-as-code version: "1625.v27444588cc3d"
|
||||
- name: git version: "5.0.0" - name: job-dsl version: "1.83"
|
||||
- name: kubernetes version: "3909.v1f2c633e8590" - name: kubernetes-credentials-provider
|
||||
version: "1.211.vc236a_f5a_2f3c" - name: workflow-aggregator
|
||||
version: "596.v8c21c963d92d" - name: workflow-job version: "1289.vd1c337fd5354"'
|
||||
items:
|
||||
description: Plugin defines Jenkins plugin.
|
||||
properties:
|
||||
|
|
@ -1100,11 +1100,6 @@ spec:
|
|||
- resources
|
||||
type: object
|
||||
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:
|
||||
description: DisableCSRFProtection allows you to toggle CSRF Protection
|
||||
on Jenkins
|
||||
|
|
@ -1150,6 +1145,10 @@ spec:
|
|||
selectors of replication controllers and services. More info:
|
||||
http://kubernetes.io/docs/user-guide/labels'
|
||||
type: object
|
||||
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
|
||||
nodeSelector:
|
||||
additionalProperties:
|
||||
type: string
|
||||
|
|
@ -3124,8 +3123,10 @@ spec:
|
|||
type: object
|
||||
type: array
|
||||
seedJobAgentImage:
|
||||
description: SeedJobAgentImage defines the image that will be used
|
||||
by the seed job agent. If not defined jenkins/inbound-agent:4.9-1
|
||||
will be used.
|
||||
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.'
|
||||
seedJobs:
|
||||
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'
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -95,6 +95,9 @@ spec:
|
|||
{{- with .Values.jenkins.nodeSelector }}
|
||||
nodeSelector: {{ toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .Values.jenkins.tolerations }}
|
||||
tolerations: {{ toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .Values.jenkins.annotations }}
|
||||
annotations: {{ toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
|
|
@ -134,7 +137,7 @@ spec:
|
|||
{{- if .Values.jenkins.backup.enabled }}
|
||||
- name: {{ .Values.jenkins.backup.containerName }}
|
||||
image: {{ .Values.jenkins.backup.image }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }}
|
||||
{{- with .Values.jenkins.backup.resources }}
|
||||
resources: {{ toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ spec:
|
|||
protocol: TCP
|
||||
command:
|
||||
- /manager
|
||||
args:
|
||||
args:
|
||||
{{- if .Values.webhook.enabled }}
|
||||
- --validate-security-warnings
|
||||
{{- end }}
|
||||
|
|
@ -41,9 +41,29 @@ spec:
|
|||
name: webhook-certs
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
env:
|
||||
- name: WATCH_NAMESPACE
|
||||
{{- if .Values.jenkins.enabled }}
|
||||
value: {{ .Values.jenkins.namespace }}
|
||||
{{- else if .Values.operator.watchNamespace }}
|
||||
value: {{ .Values.operator.watchNamespace }}
|
||||
{{- else }}
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- end }}
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
|
|
@ -71,4 +91,4 @@ spec:
|
|||
defaultMode: 420
|
||||
secretName: jenkins-{{ .Values.webhook.certificate.name }}
|
||||
terminationGracePeriodSeconds: 10
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,16 @@ jenkins:
|
|||
# nodeSelector are injected into metadata nodeSelector field
|
||||
nodeSelector: {}
|
||||
|
||||
# tolerations are injected into metadata tolerations field
|
||||
tolerations: []
|
||||
|
||||
# annotations are injected into metadata annotations field
|
||||
annotations: {}
|
||||
|
||||
# image is the name (and tag) of the Jenkins instance
|
||||
# Default: jenkins/jenkins:lts
|
||||
# It's recommended to use LTS (tag: "lts") version
|
||||
image: jenkins/jenkins:2.387.2-lts
|
||||
image: jenkins/jenkins:2.414.1-lts
|
||||
|
||||
# env contains jenkins container environment variables
|
||||
env: []
|
||||
|
|
@ -87,19 +90,19 @@ jenkins:
|
|||
#
|
||||
# basePlugins:
|
||||
# - name: kubernetes
|
||||
# version: 3909.v1f2c633e8590
|
||||
# version: 4029.v5712230ccb_f8
|
||||
# - name: workflow-job
|
||||
# version: 1289.vd1c337fd5354
|
||||
# version: 1342.v046651d5b_dfe
|
||||
# - name: workflow-aggregator
|
||||
# version: 596.v8c21c963d92d
|
||||
# - name: git
|
||||
# version: 5.0.0
|
||||
# version: 5.2.1
|
||||
# - name: job-dsl
|
||||
# version: "1.83"
|
||||
# version: "1.85"
|
||||
# - name: configuration-as-code
|
||||
# version: 1625.v27444588cc3d
|
||||
# version: 1647.ve39ca_b_829b_42
|
||||
# - name: kubernetes-credentials-provider
|
||||
# version: 1.211.vc236a_f5a_2f3c
|
||||
# version: 1.234.vf3013b_35f5b_a
|
||||
|
||||
basePlugins: []
|
||||
|
||||
|
|
@ -207,7 +210,7 @@ jenkins:
|
|||
|
||||
# image used by backup feature
|
||||
# By default using prebuilt backup PVC image
|
||||
image: quay.io/jenkins-kubernetes-operator/backup-pvc:v0.2.1
|
||||
image: quay.io/jenkins-kubernetes-operator/backup-pvc:v0.2.6
|
||||
|
||||
# containerName is backup container name
|
||||
containerName: backup
|
||||
|
|
@ -273,10 +276,10 @@ jenkins:
|
|||
# configuration is section where we can configure Jenkins instance
|
||||
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/ for details
|
||||
configuration:
|
||||
configurationAsCode: {}
|
||||
configurationAsCode: []
|
||||
# - configMapName: jenkins-casc
|
||||
# content: {}
|
||||
groovyScripts: {}
|
||||
groovyScripts: []
|
||||
# - configMapName: jenkins-gs
|
||||
# content: {}
|
||||
|
||||
|
|
@ -291,7 +294,7 @@ operator:
|
|||
replicaCount: 1
|
||||
|
||||
# image is the name (and tag) of the Jenkins Operator image
|
||||
image: quay.io/jenkins-kubernetes-operator/operator:v0.8.0-beta
|
||||
image: quay.io/jenkins-kubernetes-operator/operator:v0.8.0
|
||||
|
||||
# imagePullPolicy defines policy for pulling images
|
||||
imagePullPolicy: IfNotPresent
|
||||
|
|
@ -305,6 +308,10 @@ operator:
|
|||
# fullnameOverride overrides the deployment name
|
||||
fullnameOverride: ""
|
||||
|
||||
# Select a different namespace to look for the Jenkins CR and deploy Jenkins in. Defaults to the same namespace as
|
||||
# the operator.
|
||||
# watchNamespace: "jenkins-namespace"
|
||||
|
||||
resources: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ API_VERSION_NEXT=v1alpha3
|
|||
ALL_IN_ONE_DEPLOY_FILE_PREFIX=all-in-one
|
||||
GEN_CRD_API=gen-crd-api-reference-docs
|
||||
IMAGE_PULL_MODE=local
|
||||
HELM_VERSION=3.1.2
|
||||
HELM_VERSION=3.12.3
|
||||
CLUSTER_DOMAIN=cluster.local
|
||||
LATEST_LTS_VERSION=2.387.2
|
||||
LATEST_LTS_VERSION=2.414.1
|
||||
KIND_CLUSTER_NAME=jenkins
|
||||
|
|
|
|||
|
|
@ -32,6 +32,176 @@ rules:
|
|||
- create
|
||||
- patch
|
||||
---
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- replicasets
|
||||
- statefulsets
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
- jenkins-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- build.openshift.io
|
||||
resources:
|
||||
- buildconfigs
|
||||
- builds
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- secrets
|
||||
- services
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/log
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/portforward
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- image.openshift.io
|
||||
resources:
|
||||
- imagestreams
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- "route.openshift.io"
|
||||
resources:
|
||||
- routes
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- "image.openshift.io"
|
||||
resources:
|
||||
- imagestreams
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- "build.openshift.io"
|
||||
resources:
|
||||
- builds
|
||||
- buildconfigs
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
|
|
@ -43,236 +213,76 @@ roleRef:
|
|||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: jenkins-operator
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- replicasets
|
||||
- statefulsets
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
- jenkins-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- build.openshift.io
|
||||
resources:
|
||||
- buildconfigs
|
||||
- builds
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- secrets
|
||||
- services
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/log
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/portforward
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- image.openshift.io
|
||||
resources:
|
||||
- imagestreams
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: jenkins-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
- kind: ServiceAccount
|
||||
name: jenkins-operator
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: jenkins-operator
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
app.kubernetes.io/name: jenkins-operator
|
||||
helm.sh/chart: jenkins-operator-0.8.0
|
||||
app.kubernetes.io/version: "0.8.0"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
control-plane: controller-manager
|
||||
replicas: 1
|
||||
app.kubernetes.io/name: jenkins-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
app.kubernetes.io/name: jenkins-operator
|
||||
spec:
|
||||
serviceAccountName: jenkins-operator
|
||||
securityContext:
|
||||
runAsUser: 65532
|
||||
containers:
|
||||
- command:
|
||||
- /manager
|
||||
args:
|
||||
- --leader-elect
|
||||
image: virtuslab/jenkins-operator:v0.7.1
|
||||
name: jenkins-operator
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 90Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 60Mi
|
||||
env:
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
terminationGracePeriodSeconds: 10
|
||||
- name: jenkins-operator
|
||||
image: quay.io/jenkins-kubernetes-operator/operator:v0.8.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
command:
|
||||
- /manager
|
||||
args:
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
env:
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: OPERATOR_NAME
|
||||
value: "jenkins-operator"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 120Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 120Mi
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -68,13 +68,11 @@ func buildConfigMapTypeMeta() metav1.TypeMeta {
|
|||
}
|
||||
|
||||
func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) {
|
||||
defaultlatestPlugin := true
|
||||
|
||||
latestP := jenkins.Spec.Master.LatestPlugins
|
||||
if !latestP {
|
||||
latestP = defaultlatestPlugin
|
||||
if latestP == nil {
|
||||
latestP = new(bool)
|
||||
*latestP = true
|
||||
}
|
||||
|
||||
data := struct {
|
||||
JenkinsHomePath string
|
||||
InitConfigurationPath string
|
||||
|
|
@ -90,7 +88,7 @@ func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) {
|
|||
UserPlugins: jenkins.Spec.Master.Plugins,
|
||||
InstallPluginsCommand: installPluginsCommand,
|
||||
JenkinsScriptsVolumePath: JenkinsScriptsVolumePath,
|
||||
LatestPlugins: latestP,
|
||||
LatestPlugins: *latestP,
|
||||
}
|
||||
|
||||
output, err := render.Render(initBashTemplate, data)
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ func (r *reconcileUserConfiguration) ReconcileCasc() (reconcile.Result, error) {
|
|||
func (r *reconcileUserConfiguration) ReconcileOthers() (reconcile.Result, error) {
|
||||
backupAndRestore := backuprestore.New(r.Configuration, r.logger)
|
||||
|
||||
if err := backupAndRestore.Restore(r.jenkinsClient); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
result, err := r.ensureSeedJobs()
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
|
|
@ -64,10 +68,6 @@ func (r *reconcileUserConfiguration) ReconcileOthers() (reconcile.Result, error)
|
|||
return result, nil
|
||||
}
|
||||
|
||||
if err := backupAndRestore.Restore(r.jenkinsClient); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
if err := backupAndRestore.Backup(false); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const (
|
|||
// SeedJobSuffix is a suffix added for all seed jobs
|
||||
SeedJobSuffix = "job-dsl-seed"
|
||||
// DefaultJenkinsMasterImage is the default Jenkins master docker image
|
||||
DefaultJenkinsMasterImage = "jenkins/jenkins:2.319.3-lts"
|
||||
DefaultJenkinsMasterImage = "jenkins/jenkins:2.414.1-lts"
|
||||
// DefaultHTTPPortInt32 is the default Jenkins HTTP port
|
||||
DefaultHTTPPortInt32 = int32(8080)
|
||||
// DefaultSlavePortInt32 is the default Jenkins port for slaves
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package plugins
|
||||
|
||||
const (
|
||||
configurationAsCodePlugin = "configuration-as-code:1625.v27444588cc3d"
|
||||
gitPlugin = "git:5.0.0"
|
||||
jobDslPlugin = "job-dsl:1.83"
|
||||
kubernetesPlugin = "kubernetes:3909.v1f2c633e8590"
|
||||
kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:1.211.vc236a_f5a_2f3c"
|
||||
configurationAsCodePlugin = "configuration-as-code:1700.v6f448841296e"
|
||||
gitPlugin = "git:5.2.1"
|
||||
jobDslPlugin = "job-dsl:1.85"
|
||||
kubernetesPlugin = "kubernetes:4029.v5712230ccb_f8"
|
||||
kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:1.234.vf3013b_35f5b_a"
|
||||
workflowAggregatorPlugin = "workflow-aggregator:596.v8c21c963d92d"
|
||||
workflowJobPlugin = "workflow-job:1289.vd1c337fd5354"
|
||||
workflowJobPlugin = "workflow-job:1342.v046651d5b_dfe"
|
||||
)
|
||||
|
||||
// basePluginsList contains plugins to install by operator.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ diag() {
|
|||
--set jenkins.namespace=${DETIK_CLIENT_NAMESPACE} \
|
||||
--set namespace=${DETIK_CLIENT_NAMESPACE} \
|
||||
--set operator.image=${OPERATOR_IMAGE} \
|
||||
--set jenkins.latestPlugins=true \
|
||||
--set jenkins.backup.makeBackupBeforePodDeletion=false \
|
||||
chart/jenkins-operator
|
||||
assert_success
|
||||
assert ${HELM} status default
|
||||
|
|
@ -98,6 +100,19 @@ diag() {
|
|||
assert_success
|
||||
}
|
||||
|
||||
#bats test_tags=phase:helm
|
||||
@test "1.9 Helm: check Jenkins crd" {
|
||||
[[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly"
|
||||
run verify "there is 1 crd named 'jenkins.jenkins.io'"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "1.9 Helm: Clean" {
|
||||
run ${HELM} uninstall default
|
||||
assert_success
|
||||
# Wait for the complete removal
|
||||
sleep 30
|
||||
run verify "there is 0 pvc named 'jenkins backup'"
|
||||
assert_success
|
||||
rm "chart/jenkins-operator/deploy.tmp"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
setup() {
|
||||
load 'test_helper'
|
||||
_common_setup
|
||||
}
|
||||
|
||||
#bats test_tags=phase:helm
|
||||
@test "2.1 Install helm chart with options" {
|
||||
# The kind storage class provider needs some sec to delete the old pvc
|
||||
sleep 30
|
||||
run ${HELM} dependency update chart/jenkins-operator
|
||||
assert_success
|
||||
run ${KUBECTL} label node jenkins-control-plane batstest=yep
|
||||
${HELM} status options && skip "Helm release 'options' already exists"
|
||||
run ${HELM} install options \
|
||||
--set jenkins.namespace=${DETIK_CLIENT_NAMESPACE} \
|
||||
--set namespace=${DETIK_CLIENT_NAMESPACE} \
|
||||
--set operator.image=${OPERATOR_IMAGE} \
|
||||
--set jenkins.latestPlugins=true \
|
||||
--set jenkins.nodeSelector.batstest=yep \
|
||||
--set jenkins.backup.makeBackupBeforePodDeletion=false \
|
||||
chart/jenkins-operator
|
||||
assert_success
|
||||
assert ${HELM} status options
|
||||
touch "chart/jenkins-operator/deploy.tmp"
|
||||
}
|
||||
|
||||
#bats test_tags=phase:helm
|
||||
@test "2.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 'options-jenkins-operator'"
|
||||
assert_success
|
||||
|
||||
run verify "there is 1 pod named 'options-jenkins-operator-'"
|
||||
assert_success
|
||||
|
||||
run try "at most 20 times every 10s to get pods named 'options-jenkins-operator-' and verify that '.status.containerStatuses[?(@.name==\"jenkins-operator\")].ready' is 'true'"
|
||||
assert_success
|
||||
}
|
||||
|
||||
#bats test_tags=phase:helm
|
||||
@test "2.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
|
||||
}
|
||||
|
||||
@test "2.4 check node selector" {
|
||||
[[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly"
|
||||
|
||||
NODENAME=$(${KUBECTL} get pod jenkins-jenkins -o jsonpath={.spec.nodeName})
|
||||
|
||||
run ${KUBECTL} get node -l batstest=yep -o name
|
||||
assert_success
|
||||
assert_output "node/$NODENAME"
|
||||
}
|
||||
|
||||
@test "2.5 check jenkins-plugin-cli command" {
|
||||
[[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly"
|
||||
|
||||
run ${KUBECTL} logs -c jenkins-master jenkins-jenkins
|
||||
assert_success
|
||||
assert_output --partial 'jenkins-plugin-cli --verbose --latest true -f /var/lib/jenkins/base-plugins.txt'
|
||||
assert_output --partial 'jenkins-plugin-cli --verbose --latest true -f /var/lib/jenkins/user-plugins.txt'
|
||||
}
|
||||
|
||||
|
||||
@test "2.7 check backup" {
|
||||
[[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly"
|
||||
sleep 120
|
||||
run ${KUBECTL} logs -l app.kubernetes.io/name=jenkins-operator --tail 10000
|
||||
assert_success
|
||||
assert_output --partial "Performing backup '1'"
|
||||
assert_output --partial "Backup completed '1', updating status"
|
||||
}
|
||||
|
||||
|
||||
@test "2. Helm: Clean" {
|
||||
skip
|
||||
[[ ! -f "chart/jenkins-operator/deploy.tmp" ]] && skip "Jenkins helm chart have not been deployed correctly"
|
||||
|
||||
run ${HELM} uninstall options
|
||||
assert_success
|
||||
|
||||
rm "chart/jenkins-operator/deploy.tmp"
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
_common_setup() {
|
||||
export BATS_LIB_PATH="/usr/lib/"
|
||||
export BATS_LIB_PATH="${BATS_LIB_PATH}:/usr/lib"
|
||||
bats_load_library bats-support
|
||||
bats_load_library bats-assert
|
||||
bats_load_library bats-file
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ import (
|
|||
const e2e = "e2e"
|
||||
|
||||
var expectedBasePluginsList = []plugins.Plugin{
|
||||
plugins.Must(plugins.New("configuration-as-code:1625.v27444588cc3d")),
|
||||
plugins.Must(plugins.New("git:5.0.0")),
|
||||
plugins.Must(plugins.New("kubernetes:3909.v1f2c633e8590")),
|
||||
plugins.Must(plugins.New("kubernetes-credentials-provider:1.211.vc236a_f5a_2f3c")),
|
||||
plugins.Must(plugins.New("job-dsl:1.83")),
|
||||
plugins.Must(plugins.New("configuration-as-code:1700.v6f448841296e")),
|
||||
plugins.Must(plugins.New("git:5.2.1")),
|
||||
plugins.Must(plugins.New("kubernetes:4029.v5712230ccb_f8")),
|
||||
plugins.Must(plugins.New("kubernetes-credentials-provider:1.234.vf3013b_35f5b_a")),
|
||||
plugins.Must(plugins.New("job-dsl:1.85")),
|
||||
plugins.Must(plugins.New("workflow-aggregator:596.v8c21c963d92d")),
|
||||
plugins.Must(plugins.New("workflow-job:1289.vd1c337fd5354")),
|
||||
plugins.Must(plugins.New("workflow-job:1342.v046651d5b_dfe")),
|
||||
}
|
||||
|
||||
func createUserConfigurationSecret(namespace string, stringData map[string]string) {
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ func restartJenkinsMasterPod(jenkins *v1alpha2.Jenkins) {
|
|||
Eventually(func() (bool, error) {
|
||||
jenkinsPod = getJenkinsMasterPod(jenkins)
|
||||
return jenkinsPod.DeletionTimestamp != nil, nil
|
||||
}, 30*retryInterval, retryInterval).Should(BeTrue())
|
||||
}, 45*retryInterval, retryInterval).Should(BeTrue())
|
||||
|
||||
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins master pod has been restarted\n")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
)
|
||||
|
||||
const JenkinsTestImage = "jenkins/jenkins:2.387.2-lts"
|
||||
const JenkinsTestImage = "jenkins/jenkins:2.414.1-lts"
|
||||
|
||||
var (
|
||||
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",
|
||||
"--set-string", fmt.Sprintf("jenkins.namespace=%s", namespace.Name),
|
||||
"--set-string", fmt.Sprintf("jenkins.image=%s", "jenkins/jenkins:2.387.2-lts"),
|
||||
"--set-string", fmt.Sprintf("jenkins.image=%s", "jenkins/jenkins:2.414.1-lts"),
|
||||
"--set-string", fmt.Sprintf("operator.image=%s", *imageName), "--install")
|
||||
output, err := cmd.CombinedOutput()
|
||||
Expect(err).NotTo(HaveOccurred(), string(output))
|
||||
|
|
@ -77,12 +77,12 @@ var _ = Describe("Jenkins Controller with security validator", func() {
|
|||
invalidPlugins = []v1alpha2.Plugin{
|
||||
{Name: "simple-theme-plugin", Version: "0.6"},
|
||||
{Name: "audit-trail", Version: "3.8"},
|
||||
{Name: "github", Version: "1.31.0"},
|
||||
{Name: "github", Version: "1.36.0"},
|
||||
}
|
||||
validPlugins = []v1alpha2.Plugin{
|
||||
{Name: "simple-theme-plugin", Version: "136.v23a_15f86c53d"},
|
||||
{Name: "audit-trail", Version: "3.11"},
|
||||
{Name: "github", Version: "1.36.0"},
|
||||
{Name: "github", Version: "1.37.3.1"},
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ var _ = Describe("Jenkins Controller with security validator", func() {
|
|||
jenkins := e2e.RenderJenkinsCR(jenkinsCRName, namespace.Name, seedJobs, groovyScripts, casc, "")
|
||||
jenkins.Spec.Master.Plugins = invalidPlugins
|
||||
jenkins.Spec.ValidateSecurityWarnings = true
|
||||
Expect(e2e.K8sClient.Create(context.TODO(), jenkins)).Should(MatchError("admission webhook \"vjenkins.kb.io\" denied the request: security vulnerabilities detected in the following user-defined plugins: \ngithub:1.31.0"))
|
||||
Expect(e2e.K8sClient.Create(context.TODO(), jenkins)).Should(MatchError("admission webhook \"vjenkins.kb.io\" denied the request: security vulnerabilities detected in the following user-defined plugins: \ngithub:1.36.0"))
|
||||
})
|
||||
})
|
||||
Context("When Jenkins CR doesn't contain plugins with security warnings", func() {
|
||||
|
|
@ -127,6 +127,7 @@ var _ = Describe("Jenkins Controller with security validator", func() {
|
|||
"--set-string", fmt.Sprintf("jenkins.namespace=%s", namespace.Name),
|
||||
"--set-string", fmt.Sprintf("operator.image=%s", *imageName),
|
||||
"--set", fmt.Sprintf("webhook.enabled=%t", true),
|
||||
"--set", fmt.Sprintf("jenkins.latestPlugins=%t", true),
|
||||
"--set", fmt.Sprintf("jenkins.enabled=%t", false), "--install")
|
||||
output, err := cmd.CombinedOutput()
|
||||
Expect(err).NotTo(HaveOccurred(), string(output))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
title: "Getting Started"
|
||||
linkTitle: "Getting Started"
|
||||
weight: 2
|
||||
date: 2021-08-19
|
||||
date: 2023-06-04
|
||||
description: >
|
||||
How to work with Jenkins Operator
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
---
|
||||
title: "Latest (v0.7.x)"
|
||||
linkTitle: "Latest (v0.7.x)"
|
||||
title: "Latest (v0.8.x)"
|
||||
linkTitle: "Latest (v0.8.x)"
|
||||
weight: 1
|
||||
date: 2021-12-08
|
||||
date: 2023-31-05
|
||||
description: >
|
||||
How to work with the latest, currently supported Jenkins Operator version.
|
||||
---
|
||||
|
||||
{{% pageinfo %}}
|
||||
This document describes a getting started guide for **Jenkins Operator** `v0.7.x` and also additional configuration.
|
||||
This document describes a getting started guide for **Jenkins Operator** `v0.8.x` and also additional configuration.
|
||||
{{% /pageinfo %}}
|
||||
|
||||
## First Steps
|
||||
|
||||
Prepare your Kubernetes cluster and set up your `kubectl` access.
|
||||
|
||||
Once you have a running Kubernetes cluster you can focus on installing **Jenkins Operator** according to the
|
||||
Once you have a running Kubernetes cluster you can focus on installing **Jenkins Operator** according to the
|
||||
[Installation](/kubernetes-operator/docs/getting-started/latest/installing-the-operator/) guide.
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ description: >
|
|||
Prevent loss of job history
|
||||
---
|
||||
|
||||
> Because of Jenkins Operator's architecture, the configuration of Jenkins should be done using ConfigurationAsCode
|
||||
> or GroovyScripts and jobs should be defined as SeedJobs. It means that there is no point in backing up any job configuration
|
||||
> Because of Jenkins Operator's architecture, the configuration of Jenkins should be done using ConfigurationAsCode
|
||||
> or GroovyScripts and jobs should be defined as SeedJobs. It means that there is no point in backing up any job configuration
|
||||
> up. Therefore, the backup script makes a copy of jobs history only.
|
||||
|
||||
Backup and restore is done by a container sidecar.
|
||||
|
|
@ -54,7 +54,7 @@ spec:
|
|||
disableCSRFProtection: false
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
image: jenkins/jenkins:2.277.4-lts-alpine
|
||||
image: jenkins/jenkins:2.401.1-lts
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
limits:
|
||||
|
|
@ -71,7 +71,7 @@ spec:
|
|||
value: /jenkins-home
|
||||
- name: BACKUP_COUNT
|
||||
value: "3" # keep only the 2 most recent backups
|
||||
image: virtuslab/jenkins-operator-backup-pvc:v0.1.1 # look at backup/pvc directory
|
||||
image: quay.io/jenkins-kubernetes-operator/backup-pvc:v0.2.3 # look at backup/pvc directory
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- mountPath: /jenkins-home # Jenkins home volume
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ This document describes the procedure for deploying Jenkins.
|
|||
|
||||
## Prerequisites
|
||||
The Operator needs to have been deployed beforehand. The procedure for deploying Jenkins described here doesn't apply to
|
||||
installation of Operator via Helm chart unless `jenkins.enabled` was set to false.
|
||||
installation of Operator via Helm chart unless `jenkins.enabled` was set to false.
|
||||
That’s because by default, installation via Helm chart also covers deploying Jenkins.
|
||||
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ spec:
|
|||
disableCSRFProtection: false
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
image: jenkins/jenkins:2.319.1-lts-alpine
|
||||
image: jenkins/jenkins:2.401.1-lts
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 12
|
||||
|
|
|
|||
|
|
@ -127,11 +127,13 @@ Name of resource. The pod name will be <code>jenkins-<name></code> (name w
|
|||
<code>namespace</code>
|
||||
</td>
|
||||
<td>
|
||||
default
|
||||
""
|
||||
</td>
|
||||
<td>
|
||||
Namespace the resources will be deployed to. It's not recommended to use default namespace.
|
||||
Create new namespace for jenkins (e.g. <code>kubectl create -n jenkins</code>)
|
||||
Namespace the resources will be deployed to. If omitted, the resources will be deployed to the same namespace as the operator.
|
||||
It's not recommended to use default namespace. Create new namespace for jenkins (e.g. <code>kubectl create -n jenkins</code>).
|
||||
|
||||
<b>Note:</b> If the Jenkins instance is disabled, this property will be ignored. Use the `operator.watchNamespace` property instead.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -941,7 +943,7 @@ spec:
|
|||
args:
|
||||
- --leader-elect
|
||||
<b>- --validate-security-warnings</b>
|
||||
image: virtuslab/jenkins-operator:v0.7.0
|
||||
image: quay.io/jenkins-kubernetes-operator/operator:v0.8.0
|
||||
name: jenkins-operator
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
|
|
|
|||
|
|
@ -7,4 +7,6 @@ description: >
|
|||
Additional configuration for OpenShift
|
||||
---
|
||||
|
||||
## Release 0.7.0 is not compatible with OpenShift.
|
||||
## Release 0.8.0 is not compatible with jenkins image shipped by redhat in OpenShift.
|
||||
|
||||
But probably it will run correctly with the jenkins lts version. If you find any issue please report it here: https://github.com/jenkinsci/kubernetes-operator/issues/826.
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ spec:
|
|||
- /manager
|
||||
args:
|
||||
- --leader-elect
|
||||
image: virtuslab/jenkins-operator:v0.7.0
|
||||
image: image: quay.io/jenkins-kubernetes-operator/operator:v0.8.0
|
||||
name: jenkins-operator
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
|
|
@ -536,7 +536,7 @@ spec:
|
|||
disableCSRFProtection: false
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
image: jenkins/jenkins:2.319.1-lts-alpine
|
||||
image: jenkins/jenkins:2.401.1-lts
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 12
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: "Latest (v0.8.x)"
|
||||
linkTitle: "Latest (v0.8.x)"
|
||||
weight: 1
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
How to work with the latest, currently supported Jenkins Operator version.
|
||||
---
|
||||
|
||||
{{% pageinfo %}}
|
||||
This document describes a getting started guide for **Jenkins Operator** `v0.8.x` and also additional configuration.
|
||||
{{% /pageinfo %}}
|
||||
|
||||
## First Steps
|
||||
|
||||
Prepare your Kubernetes cluster and set up your `kubectl` access.
|
||||
|
||||
Once you have a running Kubernetes cluster you can focus on installing **Jenkins Operator** according to the
|
||||
[Installation](/kubernetes-operator/docs/getting-started/latest/installing-the-operator/) guide.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
title: "AKS"
|
||||
linkTitle: "AKS"
|
||||
weight: 8
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
Additional configuration for Azure Kubernetes Service
|
||||
---
|
||||
|
||||
Azure AKS managed Kubernetes service adds to every pod the following environment variables:
|
||||
|
||||
```yaml
|
||||
- name: KUBERNETES_PORT_443_TCP_ADDR
|
||||
value:
|
||||
- name: KUBERNETES_PORT
|
||||
value: tcp://
|
||||
- name: KUBERNETES_PORT_443_TCP
|
||||
value: tcp://
|
||||
- name: KUBERNETES_SERVICE_HOST
|
||||
value:
|
||||
```
|
||||
|
||||
The operator is aware of it and omits these environment variables when checking if a Jenkins pod environment has been changed. It prevents the
|
||||
restart of a Jenkins pod over and over again.
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
---
|
||||
title: "Configuring backup and restore"
|
||||
linkTitle: "Configuring backup and restore"
|
||||
weight: 5
|
||||
date: 2023-01-08
|
||||
description: >
|
||||
Prevent loss of job history
|
||||
---
|
||||
|
||||
> Because of Jenkins Operator's architecture, the configuration of Jenkins should be done using ConfigurationAsCode
|
||||
> or GroovyScripts and jobs should be defined as SeedJobs. It means that there is no point in backing up any job configuration
|
||||
> up. Therefore, the backup script makes a copy of jobs history only.
|
||||
|
||||
Backup and restore is done by a container sidecar.
|
||||
|
||||
### PVC
|
||||
|
||||
#### Create PVC
|
||||
|
||||
Save to the file named pvc.yaml:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: <pvc_name>
|
||||
namespace: <namespace>
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 500Gi
|
||||
```
|
||||
|
||||
Run the following command:
|
||||
```bash
|
||||
$ kubectl -n <namespace> create -f pvc.yaml
|
||||
```
|
||||
|
||||
#### Configure Jenkins CR
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: jenkins-cr
|
||||
spec:
|
||||
jenkinsAPISettings:
|
||||
authorizationStrategy: createUser
|
||||
master:
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
disableCSRFProtection: false
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
image: jenkins/jenkins:2.277.4-lts-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 3Gi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 500Mi
|
||||
- name: backup # container responsible for the backup and restore
|
||||
env:
|
||||
- name: BACKUP_DIR
|
||||
value: /backup
|
||||
- name: JENKINS_HOME
|
||||
value: /jenkins-home
|
||||
- name: BACKUP_COUNT
|
||||
value: "3" # keep only the 2 most recent backups
|
||||
image: virtuslab/jenkins-operator-backup-pvc:v0.1.1 # look at backup/pvc directory
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- mountPath: /jenkins-home # Jenkins home volume
|
||||
name: jenkins-home
|
||||
- mountPath: /backup # backup volume
|
||||
name: backup
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 3Gi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 500Mi
|
||||
volumes:
|
||||
- name: backup # PVC volume where backups will be stored
|
||||
persistentVolumeClaim:
|
||||
claimName: <pvc_name>
|
||||
backup:
|
||||
containerName: backup # container name is responsible for backup
|
||||
action:
|
||||
exec:
|
||||
command:
|
||||
- /home/user/bin/backup.sh # this command is invoked on "backup" container to make backup, for example /home/user/bin/backup.sh <backup_number>, <backup_number> is passed by operator
|
||||
interval: 30 # how often make backup in seconds
|
||||
makeBackupBeforePodDeletion: true # make a backup before pod deletion
|
||||
restore:
|
||||
containerName: backup # container name is responsible for restore backup
|
||||
action:
|
||||
exec:
|
||||
command:
|
||||
- /home/user/bin/restore.sh # this command is invoked on "backup" container to make restore backup, for example /home/user/bin/restore.sh <backup_number>, <backup_number> is passed by operator
|
||||
#recoveryOnce: <backup_number> # if want to restore specific backup configure this field and then Jenkins will be restarted and desired backup will be restored
|
||||
getLatestAction:
|
||||
exec:
|
||||
command:
|
||||
- /home/user/bin/get-latest.sh # this command is invoked on "backup" container to get last backup number before pod deletion; not having it in the CR may cause loss of data
|
||||
```
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
---
|
||||
title: "Configuring Seed Jobs and Pipelines"
|
||||
linkTitle: "Configuring Seed Jobs and Pipelines"
|
||||
weight: 4
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
How to configure Jenkins with Operator
|
||||
---
|
||||
|
||||
## Configure Seed Jobs and Pipelines
|
||||
|
||||
Jenkins operator uses [job-dsl][job-dsl] and [kubernetes-credentials-provider][kubernetes-credentials-provider] plugins for configuring jobs
|
||||
and deploy keys.
|
||||
|
||||
## Prepare job definitions and pipelines
|
||||
|
||||
First you have to prepare pipelines and job definition in your GitHub repository using the following structure:
|
||||
|
||||
```
|
||||
cicd/
|
||||
├── jobs
|
||||
│ └── k8s.jenkins
|
||||
└── pipelines
|
||||
└── k8s.jenkins
|
||||
```
|
||||
|
||||
**`cicd/jobs/k8s.jenkins`** is a job definition:
|
||||
|
||||
```
|
||||
#!/usr/bin/env groovy
|
||||
|
||||
pipelineJob('k8s-e2e') {
|
||||
displayName('Kubernetes Plugin E2E Test')
|
||||
|
||||
logRotator {
|
||||
numToKeep(10)
|
||||
daysToKeep(30)
|
||||
}
|
||||
|
||||
configure { project ->
|
||||
project / 'properties' / 'org.jenkinsci.plugins.workflow.job.properties.DurabilityHintJobProperty' {
|
||||
hint('PERFORMANCE_OPTIMIZED')
|
||||
}
|
||||
}
|
||||
|
||||
definition {
|
||||
cpsScm {
|
||||
scm {
|
||||
git {
|
||||
remote {
|
||||
url('https://github.com/jenkinsci/kubernetes-operator.git')
|
||||
credentials('jenkins-operator')
|
||||
}
|
||||
branches('*/master')
|
||||
}
|
||||
}
|
||||
scriptPath('cicd/pipelines/k8s.jenkins')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**`cicd/pipelines/k8s.jenkins`** is an actual Jenkins pipeline:
|
||||
|
||||
```
|
||||
#!/usr/bin/env groovy
|
||||
|
||||
def label = "k8s-${UUID.randomUUID().toString()}"
|
||||
def home = "/home/jenkins"
|
||||
def workspace = "${home}/workspace/build-jenkins-operator"
|
||||
def workdir = "${workspace}/src/github.com/jenkinsci/kubernetes-operator/"
|
||||
|
||||
podTemplate(label: label,
|
||||
containers: [
|
||||
containerTemplate(name: 'alpine', image: 'alpine:3.11', ttyEnabled: true, command: 'cat'),
|
||||
],
|
||||
) {
|
||||
node(label) {
|
||||
stage('Run shell') {
|
||||
container('alpine') {
|
||||
sh 'echo "hello world"'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configure Seed Jobs
|
||||
|
||||
Jenkins Seed Jobs are configured using `Jenkins.spec.seedJobs` section from your custom resource manifest:
|
||||
|
||||
```
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
seedJobs:
|
||||
- id: jenkins-operator
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
||||
```
|
||||
|
||||
**Jenkins Operator** will automatically discover and configure all the seed jobs.
|
||||
|
||||
You can verify if deploy keys were successfully configured in the Jenkins **Credentials** tab.
|
||||
|
||||

|
||||
|
||||
You can verify if your pipelines were successfully configured in the Jenkins Seed Job console output.
|
||||
|
||||

|
||||
|
||||
If your GitHub repository is **private** you have to configure SSH or username/password authentication.
|
||||
|
||||
### SSH authentication
|
||||
|
||||
#### Generate SSH Keys
|
||||
|
||||
There are two methods of SSH private key generation:
|
||||
|
||||
```bash
|
||||
$ openssl genrsa -out <filename> 2048
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
$ ssh-keygen -t rsa -b 2048
|
||||
$ ssh-keygen -p -f <filename> -m pem
|
||||
```
|
||||
|
||||
Then copy content from generated file.
|
||||
|
||||
#### Public key
|
||||
|
||||
If you want to upload your public key to your Git server you need to extract it.
|
||||
|
||||
If key was generated by `openssl` then you need to type this to extract public key:
|
||||
|
||||
```bash
|
||||
$ openssl rsa -in <filename> -pubout > <filename>.pub
|
||||
```
|
||||
|
||||
If key was generated by `ssh-keygen` the public key content is located in <filename>.pub and there is no need to extract public key
|
||||
|
||||
#### Configure SSH authentication
|
||||
|
||||
Configure a seed job like this:
|
||||
|
||||
```
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
seedJobs:
|
||||
- id: jenkins-operator-ssh
|
||||
credentialType: basicSSHUserPrivateKey
|
||||
credentialID: k8s-ssh
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git
|
||||
```
|
||||
|
||||
and create a Kubernetes Secret (name of secret should be the same from `credentialID` field):
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: k8s-ssh
|
||||
labels:
|
||||
"jenkins.io/credentials-type": "basicSSHUserPrivateKey"
|
||||
annotations:
|
||||
"jenkins.io/credentials-description" : "ssh github.com:jenkinsci/kubernetes-operator"
|
||||
stringData:
|
||||
privateKey: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIJKAIBAAKCAgEAxxDpleJjMCN5nusfW/AtBAZhx8UVVlhhhIKXvQ+dFODQIdzO
|
||||
oDXybs1zVHWOj31zqbbJnsfsVZ9Uf3p9k6xpJ3WFY9b85WasqTDN1xmSd6swD4N8
|
||||
...
|
||||
username: github_user_name
|
||||
```
|
||||
|
||||
### Username & password authentication
|
||||
|
||||
Configure the seed job like:
|
||||
|
||||
```
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
seedJobs:
|
||||
- id: jenkins-operator-user-pass
|
||||
credentialType: usernamePassword
|
||||
credentialID: k8s-user-pass
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
||||
```
|
||||
|
||||
and create a Kubernetes Secret (name of secret should be the same from `credentialID` field):
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: k8s-user-pass
|
||||
stringData:
|
||||
username: github_user_name
|
||||
password: password_or_token
|
||||
```
|
||||
|
||||
### External authentication
|
||||
You can use `external` credential type if you want to configure authentication using Configuration As Code or Groovy Script.
|
||||
|
||||
Example:
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
seedJobs:
|
||||
- id: jenkins-operator-external
|
||||
credentialType: external
|
||||
credentialID: k8s-external
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
||||
```
|
||||
|
||||
Remember that `credentialID` must match the id of the credentials configured in Jenkins. Consult the
|
||||
[Jenkins docs for using credentials][jenkins-using-credentials] for details.
|
||||
|
||||
## HTTP Proxy for downloading plugins
|
||||
|
||||
To use forwarding proxy with an operator to download plugins you need to add the following environment variable to Jenkins Custom Resource (CR), e.g.:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
master:
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
env:
|
||||
- name: CURL_OPTIONS
|
||||
value: -L -x <proxy_url>
|
||||
```
|
||||
|
||||
In `CURL_OPTIONS` var you can set additional arguments to `curl` command.
|
||||
|
||||
## Pulling Docker images from private repositories
|
||||
|
||||
To pull a Docker Image from private repository you can use `imagePullSecrets`.
|
||||
|
||||
Please follow the instructions on [creating a secret with a docker config](https://kubernetes.io/docs/concepts/containers/images/?origin_team=T42NTAGHM#creating-a-secret-with-a-docker-config).
|
||||
|
||||
### Docker Hub Configuration
|
||||
To use Docker Hub additional steps are required.
|
||||
|
||||
Edit the previously created secret:
|
||||
```bash
|
||||
kubectl -n <namespace> edit secret <name>
|
||||
```
|
||||
|
||||
The `.dockerconfigjson` key's value needs to be replaced with a modified version.
|
||||
|
||||
After modifications, it needs to be encoded as a Base64 value before setting the `.dockerconfigjson` key.
|
||||
|
||||
Example config file to modify and use:
|
||||
```
|
||||
{
|
||||
"auths":{
|
||||
"https://index.docker.io/v1/":{
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"auth.docker.io":{
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"registry.docker.io":{
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"docker.io":{
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"https://registry-1.docker.io/v2/": {
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"registry-1.docker.io/v2/": {
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"registry-1.docker.io": {
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
},
|
||||
"https://registry-1.docker.io": {
|
||||
"username":"user",
|
||||
"password":"password",
|
||||
"email":"yourdockeremail@gmail.com",
|
||||
"auth":"base64 of string user:password"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[job-dsl]:https://github.com/jenkinsci/job-dsl-plugin
|
||||
[kubernetes-credentials-provider]:https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/
|
||||
[jenkins-using-credentials]:https://www.jenkins.io/doc/book/using/using-credentials/
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
---
|
||||
title: "Custom backup and restore providers"
|
||||
linkTitle: "Custom backup and restore providers"
|
||||
weight: 7
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
Custom backup and restore provider
|
||||
---
|
||||
|
||||
With enough effort one can create a custom backup and restore provider
|
||||
for the Jenkins Operator.
|
||||
|
||||
## Requirements
|
||||
|
||||
Two commands (e.g. scripts) are required:
|
||||
|
||||
- a backup command, e.g. `backup.sh` that takes one argument, a **backup number**
|
||||
- a restore command, e.g. `backup.sh` that takes one argument, a **backup number**
|
||||
|
||||
Both scripts need to return an exit code of `0` on success and `1` or greater for failure.
|
||||
|
||||
One of those scripts (or the entry point of the container) needs to be responsible
|
||||
for backup cleanup or rotation if required, or an external system.
|
||||
|
||||
## How it works
|
||||
|
||||
The mechanism relies on basic Kubernetes and UNIX functionalities.
|
||||
|
||||
The backup (and restore) container runs as a sidecar in the same
|
||||
Kubernetes pod as the Jenkins master.
|
||||
|
||||
Name of the backup and restore containers can be set as necessary using
|
||||
`spec.backup.containerName` and `spec.restore.containerName`.
|
||||
In most cases it will be the same container, but we allow for less common use cases.
|
||||
|
||||
The operator will call a backup or restore commands inside a sidecar container when necessary:
|
||||
|
||||
- backup command (defined in `spec.backup.action.exec.command`)
|
||||
will be called every `N` seconds configurable in: `spec.backup.interval`
|
||||
and on pod shutdown (if enabled in `spec.backup.makeBackupBeforePodDeletion`)
|
||||
with an integer representing the current backup number as first and only argument
|
||||
- restore command (defined in `spec.restore.action.exec.command`)
|
||||
will be called at Jenkins startup
|
||||
with an integer representing the backup number to restore as first and only argument
|
||||
(can be overridden using `spec.restore.recoveryOnce`)
|
||||
|
||||
## Example AWS S3 backup using the CLI
|
||||
|
||||
This example shows abbreviated version of a simple AWS S3 backup implementation
|
||||
using: `aws-cli`, `bash` and `kube2iam`.
|
||||
|
||||
In addition to your normal `Jenkins` `CustomResource` some additional settings
|
||||
for backup and restore are required, e.g.:
|
||||
|
||||
```yaml
|
||||
kind: Jenkins
|
||||
apiVersion: jenkins.io/v1alpha1
|
||||
metadata:
|
||||
name: example
|
||||
namespace: jenkins
|
||||
spec:
|
||||
master:
|
||||
masterAnnotations:
|
||||
iam.amazonaws.com/role: "my-example-backup-role" # tell kube2iam where the AWS IAM role is
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
...
|
||||
- name: backup # container responsible for backup and restore
|
||||
image: quay.io/virtuslab/aws-cli:1.16.263-2
|
||||
workingDir: /home/user/bin/
|
||||
command: # our container entry point
|
||||
- sleep
|
||||
- infinity
|
||||
env:
|
||||
- name: BACKUP_BUCKET
|
||||
value: my-example-bucket # the S3 bucket name to use
|
||||
- name: BACKUP_PATH
|
||||
value: my-backup-path # the S3 bucket path prefix to use
|
||||
- name: JENKINS_HOME
|
||||
value: /jenkins-home # the path to mount jenkins home dir in the backup container
|
||||
volumeMounts:
|
||||
- mountPath: /jenkins-home # Jenkins home volume
|
||||
name: jenkins-home
|
||||
- mountPath: /home/user/bin/backup.sh
|
||||
name: backup-scripts
|
||||
subPath: backup.sh
|
||||
readOnly: true
|
||||
- mountPath: /home/user/bin/restore.sh
|
||||
name: backup-scripts
|
||||
subPath: restore.sh
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: backup-scripts
|
||||
configMap:
|
||||
defaultMode: 0754
|
||||
name: jenkins-operator-backup-s3
|
||||
securityContext: # make sure both containers use the same UID and GUID
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
...
|
||||
backup:
|
||||
containerName: backup # container name responsible for backup
|
||||
interval: 3600 # how often make a backup in seconds
|
||||
makeBackupBeforePodDeletion: true # trigger backup just before deleting the pod
|
||||
action:
|
||||
exec:
|
||||
command:
|
||||
# this command is invoked on "backup" container to create a backup,
|
||||
# <backup_number> is passed by operator,
|
||||
# for example /home/user/bin/backup.sh <backup_number>
|
||||
- /home/user/bin/backup.sh
|
||||
restore:
|
||||
containerName: backup # container name is responsible for restore backup
|
||||
action:
|
||||
exec:
|
||||
command:
|
||||
# this command is invoked on "backup" container to restore a backup,
|
||||
# <backup_number> is passed by operator
|
||||
# for example /home/user/bin/restore.sh <backup_number>
|
||||
- /home/user/bin/restore.sh
|
||||
# recoveryOnce: <backup_number> # if want to restore specific backup configure this field and then Jenkins will be restarted and desired backup will be restored
|
||||
```
|
||||
|
||||
The actual backup and restore scripts will be provided in a `ConfigMap`:
|
||||
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: jenkins-operator-backup-s3
|
||||
namespace: jenkins
|
||||
labels:
|
||||
app: jenkins-operator
|
||||
data:
|
||||
backup.sh: |-
|
||||
#!/bin/bash -xeu
|
||||
[[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1;
|
||||
[[ -z "${BACKUP_BUCKET}" ]] && echo "Required 'BACKUP_BUCKET' env not set" && exit 1;
|
||||
[[ -z "${BACKUP_PATH}" ]] && echo "Required 'BACKUP_PATH' env not set" && exit 1;
|
||||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
||||
|
||||
backup_number=$1
|
||||
echo "Running backup #${backup_number}"
|
||||
|
||||
BACKUP_TMP_DIR=$(mktemp -d)
|
||||
tar -C ${JENKINS_HOME} -czf "${BACKUP_TMP_DIR}/${backup_number}.tar.gz" --exclude jobs/*/workspace* -c jobs && \
|
||||
|
||||
aws s3 cp ${BACKUP_TMP_DIR}/${backup_number}.tar.gz s3://${BACKUP_BUCKET}/${BACKUP_PATH}/${backup_number}.tar.gz
|
||||
echo Done
|
||||
|
||||
restore.sh: |-
|
||||
#!/bin/bash -xeu
|
||||
[[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1
|
||||
[[ -z "${BACKUP_BUCKET}" ]] && echo "Required 'BACKUP_BUCKET' env not set" && exit 1;
|
||||
[[ -z "${BACKUP_PATH}" ]] && echo "Required 'BACKUP_PATH' env not set" && exit 1;
|
||||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
||||
|
||||
backup_number=$1
|
||||
echo "Running restore #${backup_number}"
|
||||
|
||||
BACKUP_TMP_DIR=$(mktemp -d)
|
||||
aws s3 cp s3://${BACKUP_BUCKET}/${BACKUP_PATH}/${backup_number}.tar.gz ${BACKUP_TMP_DIR}/${backup_number}.tar.gz
|
||||
|
||||
tar -C ${JENKINS_HOME} -zxf "${BACKUP_TMP_DIR}/${backup_number}.tar.gz"
|
||||
echo Done
|
||||
```
|
||||
|
||||
In our example we will use S3 bucket lifecycle policy to keep
|
||||
the number of backups under control, e.g. Cloud Formation fragment:
|
||||
```yaml
|
||||
Type: AWS::S3::Bucket
|
||||
Properties:
|
||||
BucketName: my-example-bucket
|
||||
...
|
||||
LifecycleConfiguration:
|
||||
Rules:
|
||||
- Id: BackupCleanup
|
||||
Status: Enabled
|
||||
Prefix: my-backup-path
|
||||
ExpirationInDays: 7
|
||||
NoncurrentVersionExpirationInDays: 14
|
||||
AbortIncompleteMultipartUpload:
|
||||
DaysAfterInitiation: 3
|
||||
```
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
---
|
||||
title: "Customizing Jenkins"
|
||||
linkTitle: "Customizing Jenkins"
|
||||
weight: 3
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
How to customize Jenkins
|
||||
---
|
||||
|
||||
## How to customize Jenkins
|
||||
Jenkins can be customized with plugins.
|
||||
Plugin's configuration is applied as groovy scripts or the [configuration as code plugin](https://github.com/jenkinsci/configuration-as-code-plugin).
|
||||
Any plugin working for Jenkins can be installed by the Jenkins Operator.
|
||||
|
||||
Pre-installed plugins:
|
||||
|
||||
* configuration-as-code v1.55
|
||||
* git v4.10.0
|
||||
* job-dsl v1.78.1
|
||||
* kubernetes-credentials-provider v0.20
|
||||
* kubernetes v1.30.11
|
||||
* workflow-aggregator v2.6
|
||||
* workflow-job v2.42
|
||||
|
||||
Rest of the plugins can be found in [plugins repository](https://plugins.jenkins.io/).
|
||||
|
||||
|
||||
#### Install plugins
|
||||
|
||||
Edit Custom Resource under `spec.master.plugins`:
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
master:
|
||||
plugins:
|
||||
- name: simple-theme-plugin
|
||||
version: "0.7"
|
||||
```
|
||||
|
||||
Under `spec.master.basePlugins` you can find plugins for a valid **Jenkins Operator**:
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
master:
|
||||
basePlugins:
|
||||
- name: kubernetes
|
||||
version: "1.30.11"
|
||||
- name: workflow-job
|
||||
version: "2.42"
|
||||
- name: workflow-aggregator
|
||||
version: "2.6"
|
||||
- name: git
|
||||
version: "4.10.0"
|
||||
- name: job-dsl
|
||||
version: "1.78.1"
|
||||
- name: configuration-as-code
|
||||
version: "1.55"
|
||||
- name: kubernetes-credentials-provider
|
||||
version: "0.20"
|
||||
```
|
||||
|
||||
You can change their versions.
|
||||
|
||||
The **Jenkins Operator** will then automatically install plugins after the Jenkins master pod restart.
|
||||
|
||||
#### Apply plugin's config
|
||||
|
||||
By using a [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) you can create your own **Jenkins** customized configuration.
|
||||
Then you must reference the **`ConfigMap`** in the **Jenkins** pod customization file in `spec.groovyScripts` or `spec.configurationAsCode`
|
||||
|
||||
Create a **`ConfigMap`** with specific name (eg. `jenkins-operator-user-configuration`). Then, modify the **Jenkins** manifest:
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
configurationAsCode:
|
||||
configurations:
|
||||
- name: jenkins-operator-user-configuration
|
||||
groovyScripts:
|
||||
configurations:
|
||||
- name: jenkins-operator-user-configuration
|
||||
```
|
||||
|
||||
Here is an example of `jenkins-operator-user-configuration`:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: jenkins-operator-user-configuration
|
||||
data:
|
||||
1-configure-theme.groovy: |
|
||||
import jenkins.*
|
||||
import jenkins.model.*
|
||||
import hudson.*
|
||||
import hudson.model.*
|
||||
import org.jenkinsci.plugins.simpletheme.ThemeElement
|
||||
import org.jenkinsci.plugins.simpletheme.CssTextThemeElement
|
||||
import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement
|
||||
|
||||
Jenkins jenkins = Jenkins.getInstance()
|
||||
|
||||
def decorator = Jenkins.instance.getDescriptorByType(org.codefirst.SimpleThemeDecorator.class)
|
||||
|
||||
List<ThemeElement> configElements = new ArrayList<>();
|
||||
configElements.add(new CssTextThemeElement("DEFAULT"));
|
||||
configElements.add(new CssUrlThemeElement("https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-light-green.css"));
|
||||
decorator.setElements(configElements);
|
||||
decorator.save();
|
||||
|
||||
jenkins.save()
|
||||
1-system-message.yaml: |
|
||||
jenkins:
|
||||
systemMessage: "Configuration as Code integration works!!!"
|
||||
```
|
||||
|
||||
* `*.groovy` is Groovy script configuration
|
||||
* `*.yaml is` configuration as code
|
||||
|
||||
If you want to correct your configuration you can edit it while the **Jenkins Operator** is running.
|
||||
Jenkins will reconcile and apply the new configuration.
|
||||
|
||||
## How to use secrets from a Groovy scripts
|
||||
|
||||
If you configured `spec.groovyScripts.secret.name`, then this secret is available to use from map Groovy scripts.
|
||||
The secrets are loaded to `secrets` map.
|
||||
|
||||
Create a [secret](https://kubernetes.io/docs/concepts/configuration/secret/) with for example the name `jenkins-conf-secrets`.
|
||||
|
||||
```yaml
|
||||
kind: Secret
|
||||
apiVersion: v1
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: jenkins-conf-secrets
|
||||
namespace: default
|
||||
data:
|
||||
SYSTEM_MESSAGE: SGVsbG8gd29ybGQ=
|
||||
```
|
||||
|
||||
Then modify the **Jenkins** pod manifest by changing `spec.groovyScripts.secret.name` to `jenkins-conf-secrets`.
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
configurationAsCode:
|
||||
configurations:
|
||||
- name: jenkins-operator-user-configuration
|
||||
secret:
|
||||
name: jenkins-conf-secrets
|
||||
groovyScripts:
|
||||
configurations:
|
||||
- name: jenkins-operator-user-configuration
|
||||
secret:
|
||||
name: jenkins-conf-secrets
|
||||
```
|
||||
|
||||
Now you can test that the secret is mounted by applying this `ConfigMap` for Groovy script:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: jenkins-operator-user-configuration
|
||||
data:
|
||||
1-system-message.groovy: |
|
||||
import jenkins.*
|
||||
import jenkins.model.*
|
||||
import hudson.*
|
||||
import hudson.model.*
|
||||
Jenkins jenkins = Jenkins.getInstance()
|
||||
|
||||
jenkins.setSystemMessage(secrets["SYSTEM_MESSAGE"])
|
||||
jenkins.save()
|
||||
```
|
||||
|
||||
Or by applying this configuration as code:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: jenkins-operator-user-configuration
|
||||
data:
|
||||
1-system-message.yaml: |
|
||||
jenkins:
|
||||
systemMessage: ${SYSTEM_MESSAGE}
|
||||
```
|
||||
|
||||
|
||||
After this, you should see the `Hello world` system message from the **Jenkins** homepage.
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
title: "Deploying Jenkins"
|
||||
linkTitle: "Deploying Jenkins"
|
||||
weight: 2
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
Deploy production ready Jenkins manifest
|
||||
---
|
||||
|
||||
{{% pageinfo %}}
|
||||
This document describes the procedure for deploying Jenkins.
|
||||
{{% /pageinfo %}}
|
||||
|
||||
|
||||
## Prerequisites
|
||||
The Operator needs to have been deployed beforehand. The procedure for deploying Jenkins described here doesn't apply to
|
||||
installation of Operator via Helm chart unless `jenkins.enabled` was set to false.
|
||||
That’s because by default, installation via Helm chart also covers deploying Jenkins.
|
||||
|
||||
|
||||
## Deploying Jenkins instance
|
||||
Once Jenkins Operator is up and running let's deploy actual Jenkins instance.
|
||||
Create manifest e.g. **`jenkins_instance.yaml`** with following data and save it on drive.
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
namespace: default
|
||||
spec:
|
||||
configurationAsCode:
|
||||
configurations: []
|
||||
secret:
|
||||
name: ""
|
||||
groovyScripts:
|
||||
configurations: []
|
||||
secret:
|
||||
name: ""
|
||||
jenkinsAPISettings:
|
||||
authorizationStrategy: createUser
|
||||
master:
|
||||
disableCSRFProtection: false
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
image: jenkins/jenkins:2.319.1-lts-alpine
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 12
|
||||
httpGet:
|
||||
path: /login
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
readinessProbe:
|
||||
failureThreshold: 10
|
||||
httpGet:
|
||||
path: /login
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 80
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 3Gi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 500Mi
|
||||
seedJobs:
|
||||
- id: jenkins-operator
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
||||
```
|
||||
|
||||
Deploy a Jenkins to Kubernetes:
|
||||
|
||||
```bash
|
||||
kubectl create -f jenkins_instance.yaml
|
||||
```
|
||||
Watch the Jenkins instance being created:
|
||||
|
||||
```bash
|
||||
kubectl get pods -w
|
||||
```
|
||||
|
||||
Get the Jenkins credentials:
|
||||
|
||||
```bash
|
||||
kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.user}' | base64 -d
|
||||
kubectl get secret jenkins-operator-credentials-<cr_name> -o 'jsonpath={.data.password}' | base64 -d
|
||||
```
|
||||
|
||||
Connect to the Jenkins instance (minikube):
|
||||
|
||||
```bash
|
||||
minikube service jenkins-operator-http-<cr_name> --url
|
||||
```
|
||||
|
||||
Connect to the Jenkins instance (actual Kubernetes cluster):
|
||||
|
||||
```bash
|
||||
kubectl port-forward jenkins-<cr_name> 8080:8080
|
||||
```
|
||||
Then open browser with address `http://localhost:8080`.
|
||||
|
||||

|
||||
|
|
@ -0,0 +1,988 @@
|
|||
---
|
||||
title: "Installing the Operator"
|
||||
linkTitle: "Installing the Operator"
|
||||
weight: 1
|
||||
date: 2023-01-08
|
||||
description: >
|
||||
How to install Jenkins Operator
|
||||
---
|
||||
|
||||
{{% pageinfo %}}
|
||||
This document describes installation procedure for **Jenkins Operator**.
|
||||
All container images can be found at [virtuslab/jenkins-operator](https://hub.docker.com/r/virtuslab/jenkins-operator) Docker Hub repository.
|
||||
{{% /pageinfo %}}
|
||||
|
||||
## Requirements
|
||||
|
||||
To run **Jenkins Operator**, you will need:
|
||||
|
||||
- access to a Kubernetes cluster version `1.17+`
|
||||
- `kubectl` version `1.17+`
|
||||
|
||||
|
||||
Listed below are the two ways to deploy Jenkins Operator.
|
||||
|
||||
## Deploy Jenkins Operator using YAML's
|
||||
|
||||
First, install Jenkins Custom Resource Definition:
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/config/crd/bases/jenkins.io_jenkins.yaml
|
||||
```
|
||||
|
||||
Then, install the Operator and other required resources:
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-v1alpha2.yaml
|
||||
```
|
||||
|
||||
Watch **Jenkins Operator** instance being created:
|
||||
|
||||
```bash
|
||||
kubectl get pods -w
|
||||
```
|
||||
|
||||
Now **Jenkins Operator** should be up and running in the `default` namespace.
|
||||
For deploying Jenkins, refer to [Deploy Jenkins section](/kubernetes-operator/docs/getting-started/latest/deploying-jenkins/).
|
||||
|
||||
## Deploy Jenkins Operator using Helm Chart
|
||||
|
||||
Alternatively, you can also use Helm to install the Operator (and optionally, by default, Jenkins). It requires the Helm 3+ for deployment.
|
||||
|
||||
Create a namespace for the operator:
|
||||
|
||||
```bash
|
||||
$ kubectl create namespace <your-namespace>
|
||||
```
|
||||
|
||||
To install, you need only to type these commands:
|
||||
|
||||
```bash
|
||||
$ helm repo add jenkins https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart
|
||||
$ helm install <name> jenkins/jenkins-operator -n <your-namespace>
|
||||
```
|
||||
|
||||
To add custom labels and annotations, you can use `values.yaml` file or pass them into `helm install` command, e.g.:
|
||||
|
||||
```bash
|
||||
$ helm install <name> jenkins/jenkins-operator -n <your-namespace> --set jenkins.labels.LabelKey=LabelValue,jenkins.annotations.AnnotationKey=AnnotationValue
|
||||
```
|
||||
You can further customize Jenkins using `values.yaml`:
|
||||
<h3 id="JenkinsConfiguration">Jenkins instance configuration
|
||||
</h3>
|
||||
|
||||
<table aria-colspan="4">
|
||||
<thead aria-colspan="4">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Field</th>
|
||||
<th>Default value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody aria-colspan="4">
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<code>jenkins</code>
|
||||
</td>
|
||||
<td colspan="3">
|
||||
<p>operator is section for configuring operator deployment</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<code>enabled</code>
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
<td>
|
||||
Enabled can enable or disable the Jenkins instance.
|
||||
Set to false if you have configured CR already and/or you want to deploy an operator only.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>apiVersion</code>
|
||||
</td>
|
||||
<td>jenkins.io/v1alpha2</td>
|
||||
<td>
|
||||
Version of the CR manifest. The recommended and default value is <code>jenkins.io/v1alpha2</code>.
|
||||
<a href="#github.io/kubernetes-operator/docs/getting-started/v0.1.x/migration-guide-v1alpha1-to-v1alpha2/">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>name</code>
|
||||
</td>
|
||||
<td>
|
||||
jenkins
|
||||
</td>
|
||||
<td>
|
||||
Name of resource. The pod name will be <code>jenkins-<name></code> (name will be set as suffix).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>namespace</code>
|
||||
</td>
|
||||
<td>
|
||||
default
|
||||
</td>
|
||||
<td>
|
||||
Namespace the resources will be deployed to. It's not recommended to use default namespace.
|
||||
Create new namespace for jenkins (e.g. <code>kubectl create -n jenkins</code>)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>labels</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
Labels are injected into metadata labels field.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>annotations</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
Annotations are injected into metadata annotations field.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>image</code>
|
||||
</td>
|
||||
<td>
|
||||
jenkins/jenkins:lts
|
||||
</td>
|
||||
<td>
|
||||
Image is the name (and tag) of the Jenkins instance.
|
||||
It's recommended to use LTS (tag: "lts") version.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>env</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
Env contains jenkins container environment variables.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>imagePullPolicy</code>
|
||||
</td>
|
||||
<td>
|
||||
Always
|
||||
</td>
|
||||
<td>
|
||||
Defines policy for pulling images
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>priorityClassName</code>
|
||||
</td>
|
||||
<td>
|
||||
""
|
||||
</td>
|
||||
<td>
|
||||
PriorityClassName indicates the importance of a Pod relative to other Pods.
|
||||
<a href="https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>disableCSRFProtection</code>
|
||||
</td>
|
||||
<td>
|
||||
false
|
||||
</td>
|
||||
<td>
|
||||
disableCSRFProtection can enable or disable operator built-in CSRF protection.
|
||||
Set it to true if you are using OpenShift Jenkins Plugin.
|
||||
<a href="https://github.com/jenkinsci/kubernetes-operator/pull/193">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>imagePullSecrets</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
Used if you want to pull images from private repository
|
||||
<a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#pulling-docker-images-from-private-repositories">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>notifications</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
Notifications is feature that notify user about Jenkins reconciliation status
|
||||
<a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/notifications/">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>basePlugins</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
- name: kubernetes
|
||||
version: "1.25.2"
|
||||
- name: workflow-job
|
||||
version: "2.39"
|
||||
- name: workflow-aggregator
|
||||
version: "2.6"
|
||||
- name: git
|
||||
version: "4.2.2"
|
||||
- name: job-dsl
|
||||
version: "1.77"
|
||||
- name: configuration-as-code
|
||||
version: "1.38"
|
||||
- name: kubernetes-credentials
|
||||
-provider
|
||||
version: "0.13"
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
Plugins installed and required by the operator
|
||||
shouldn't contain plugins defined by user
|
||||
You can change their versions here
|
||||
<a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/#install-plugins">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>plugins</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
Plugins required by the user. You can define plugins here.
|
||||
<a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/#install-plugins">More info</a>
|
||||
Example:
|
||||
<pre>
|
||||
plugins:
|
||||
- name: simple-theme-plugin
|
||||
version: 0.5.1
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>seedJobs</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
Placeholder for jenkins seed jobs
|
||||
For seed job creation tutorial, check:<br /> <a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/#prepare-job-definitions-and-pipelines">Prepare seed jobs</a>
|
||||
<br /><a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/#configure-seed-jobs">Configure seed jobs</a>
|
||||
<br />Example:
|
||||
<code>
|
||||
<pre>
|
||||
seedJobs:
|
||||
- id: jenkins-operator
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl:
|
||||
- https://github.com/jenkinsci/kubernetes-operator.git
|
||||
</pre>
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>resources</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 3Gi
|
||||
requests:
|
||||
cpu: 1
|
||||
memory: 500M
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
Resource limit/request for Jenkins
|
||||
<a href="https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>volumes</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
- name: backup
|
||||
persistentVolumeClaim:
|
||||
claimName: jenkins-backup
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
Volumes used by Jenkins
|
||||
By default, we are only using PVC volume for storing backups.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>volumeMounts</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
volumeMounts are mounts for Jenkins pod.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>securityContext</code>
|
||||
</td>
|
||||
<td>
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
</td>
|
||||
<td>
|
||||
SecurityContext for pod.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>service</code></td>
|
||||
<td>not implemented</td>
|
||||
<td>Http Jenkins service. See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/schema/#github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Service for details.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>slaveService</code></td>
|
||||
<td>not implemented</td>
|
||||
<td>Slave Jenkins service. See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/schema/#github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Service for details.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>livenessProbe</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
livenessProbe:
|
||||
failureThreshold: 12
|
||||
httpGet:
|
||||
path: /login
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 80
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
livenessProbe for Pod
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>readinessProbe</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /login
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
readinessProbe for Pod
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>
|
||||
backup
|
||||
</code>
|
||||
<p>
|
||||
<em>
|
||||
<a href="#Backup">
|
||||
Backup
|
||||
</a>
|
||||
</em>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
Backup is section for configuring operator's backup feature
|
||||
By default backup feature is enabled and pre-configured
|
||||
This section simplifies the configuration described here: <a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-backup-and-restore/">Configuring backup and restore</a>
|
||||
For customization tips see <a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/custom-backup-and-restore">Custom backup and restore</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>configuration</code>
|
||||
<p>
|
||||
<em>
|
||||
<a href="#Configuration">
|
||||
Configuration
|
||||
</a>
|
||||
</em>
|
||||
</p>
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
Section where we can configure Jenkins instance.
|
||||
See <a href="https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customizing-jenkins/">Customizing Jenkins</a> for details
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Configuring operator deployment
|
||||
|
||||
<table aria-colspan="4">
|
||||
<thead aria-colspan="4">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Field</th>
|
||||
<th>Default value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody aria-colspan="4">
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<code>operator</code>
|
||||
</td>
|
||||
<td colspan="3">
|
||||
<p>operator is section for configuring operator deployment</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<code>replicaCount</code></br>
|
||||
</td>
|
||||
<td>
|
||||
1
|
||||
</td>
|
||||
<td>
|
||||
Number of Replicas.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>image</code>
|
||||
</td>
|
||||
<td>
|
||||
virtuslab/jenkins-operator:v0.4.0
|
||||
</td>
|
||||
<td>
|
||||
Name (and tag) of the Jenkins Operator image.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>imagePullPolicy</code>
|
||||
</td>
|
||||
<td>
|
||||
IfNotPresent
|
||||
</td>
|
||||
<td>
|
||||
Defines policy for pulling images.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>imagePullSecrets</code>
|
||||
</td>
|
||||
<td>
|
||||
[]
|
||||
</td>
|
||||
<td>
|
||||
Used if you want to pull images from private repository.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>nameOverride</code>
|
||||
</td>
|
||||
<td>
|
||||
""
|
||||
</td>
|
||||
<td>
|
||||
nameOverride overrides the app name.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>fullnameOverride</code>
|
||||
</td>
|
||||
<td>
|
||||
""
|
||||
</td>
|
||||
<td>
|
||||
fullnameOverride overrides the deployment name
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>resources</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>nodeSelector</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>tolerations</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>affinity</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<h3 id="Backup">Backup
|
||||
</h3>
|
||||
<p>
|
||||
(<em>Appears on:</em>
|
||||
<a href="#JenkinsConfiguration">JenkinsConfiguration</a>)
|
||||
</p>
|
||||
<p>
|
||||
Backup defines configuration of Jenkins backup.
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Default value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>enabled</code>
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
<td>
|
||||
Enabled is enable/disable switch for backup feature.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>image</code>
|
||||
</td>
|
||||
<td>
|
||||
virtuslab/jenkins-operator-backup-pvc:v0.1.1
|
||||
</td>
|
||||
<td>
|
||||
Image used by backup feature.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>containerName</code>
|
||||
</td>
|
||||
<td>
|
||||
backup
|
||||
</td>
|
||||
<td>
|
||||
Backup container name.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>interval</code>
|
||||
</td>
|
||||
<td>
|
||||
30
|
||||
</td>
|
||||
<td>
|
||||
Defines how often make backup in seconds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>makeBackupBeforePodDeletion</code>
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
<td>
|
||||
When enabled will make backup before pod deletion.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>backupCommand</code>
|
||||
</td>
|
||||
<td>
|
||||
/home/user/bin/backup.sh
|
||||
</td>
|
||||
<td>
|
||||
Backup container command.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>restoreCommand</code>
|
||||
</td>
|
||||
<td>
|
||||
/home/user/bin/restore.sh
|
||||
</td>
|
||||
<td>
|
||||
Backup restore command.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>pvc</code>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<p>Persistent Volume Claim Kubernetes resource</p>
|
||||
<br/>
|
||||
<table colspan="2" style="width:100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>enabled</code>
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
<td>
|
||||
Enable/disable switch for PVC
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>enabled</code>
|
||||
</td>
|
||||
<td>
|
||||
true
|
||||
</td>
|
||||
<td>
|
||||
Enable/disable switch for PVC
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>size</code>
|
||||
</td>
|
||||
<td>
|
||||
5Gi
|
||||
</td>
|
||||
<td>
|
||||
Size of PVC
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>className</code>
|
||||
</td>
|
||||
<td>
|
||||
""
|
||||
</td>
|
||||
<td>
|
||||
StorageClassName for PVC
|
||||
<a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1">More info</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>env</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
- name: BACKUP_DIR
|
||||
value: /backup
|
||||
- name: JENKINS_HOME
|
||||
value: /jenkins-home
|
||||
- name: BACKUP_COUNT
|
||||
value: "3"
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
Contains container environment variables.
|
||||
PVC backup provider handles these variables:<br />
|
||||
BACKUP_DIR - path for storing backup files (default: "/backup")<br />
|
||||
JENKINS_HOME - path to jenkins home (default: "/jenkins-home")<br />
|
||||
BACKUP_COUNT - define how much recent backups will be kept<br />
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>volumeMounts</code>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
- name: jenkins-home
|
||||
mountPath: /jenkins-home
|
||||
- mountPath: /backup
|
||||
name: backup
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
Holds the mount points for volumes.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h4 id="Configuration">Configuration
|
||||
</h3>
|
||||
<p>
|
||||
(<em>Appears on:</em>
|
||||
<a href="#JenkinsConfiguration">Jenkins instance configuration</a>)
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Default value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>configurationAsCode</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
ConfigurationAsCode defines configuration of Jenkins customization via Configuration as Code Jenkins plugin.
|
||||
Example:<br />
|
||||
<pre>
|
||||
- configMapName: jenkins-casc
|
||||
content: {}
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>groovyScripts</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
GroovyScripts defines configuration of Jenkins customization via groovy scripts.
|
||||
Example:<br />
|
||||
<pre>
|
||||
- configMapName: jenkins-gs
|
||||
content: {}
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>secretRefName</code>
|
||||
</td>
|
||||
<td>
|
||||
""
|
||||
</td>
|
||||
<td>
|
||||
secretRefName of existing secret (previously created).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>secretData</code>
|
||||
</td>
|
||||
<td>
|
||||
{}
|
||||
</td>
|
||||
<td>
|
||||
If secretRefName is empty, secretData creates new secret and fills with data provided in secretData.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Note on Operator's nightly built images
|
||||
If you wish to use the newest, not yet released version of the Operator, you can use one of nightly built snapshot images, however the maintainers of this project cannot guarantee their stability.
|
||||
|
||||
You can find nightly built images by heading to [virtuslab/jenkins-operator](https://hub.docker.com/r/virtuslab/jenkins-operator) Docker Hub repository and looking for images with tag in the form of `{git-hash}`, {git-hash} being the hash of master branch commit that you want to use snapshot of.
|
||||
|
||||
## Note on restricted Jenkins controller pod volumeMounts
|
||||
Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
|
||||
One of the key points of this design is maintaining an immutable state of Jenkins.
|
||||
|
||||
One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
|
||||
(jenkins-home) as Jenkins home directory.
|
||||
It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
|
||||
as attempting to do so will result in Operator error.
|
||||
|
||||
jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
|
||||
below is the full list of those volumeMounts:
|
||||
|
||||
* jenkins-home
|
||||
* scripts
|
||||
* init-configuration
|
||||
* operator-credentials
|
||||
|
||||
## Validating Webhook
|
||||
Validating webhook can be used in order to increase the Operator's capabilities to monitor security issues. It will look for security vulnerabilities in the base and requested plugins. It can be easily installed via Helm charts by setting webhook.enabled in values.yaml.
|
||||
|
||||
|
||||
**Note**: The webhook takes some time to get up and running. It's recommended to first deploy the Operator and later Jenkins Custom Resource by using toggles in `values.yaml`.
|
||||
For the installation with yaml manifests (without using Helm chart), first, install cert-manager:
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.yaml
|
||||
```
|
||||
|
||||
It takes some time to get cert-manager up and running.
|
||||
Then, install the webhook and other required resources:
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-webhook.yaml
|
||||
```
|
||||
|
||||
Now, download the manifests for the operator and other resources from [here](https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-v1alpha2.yaml) and provide these additional fields in the Operator manifest:
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
control-plane: controller-manager
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
serviceAccountName: jenkins-operator
|
||||
securityContext:
|
||||
runAsUser: 65532
|
||||
containers:
|
||||
- command:
|
||||
- /manager
|
||||
args:
|
||||
- --leader-elect
|
||||
<b>- --validate-security-warnings</b>
|
||||
image: virtuslab/jenkins-operator:v0.7.0
|
||||
name: jenkins-operator
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 100Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 20Mi
|
||||
env:
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
<b>volumeMounts:
|
||||
- mountPath: /tmp/k8s-webhook-server/serving-certs
|
||||
name: webhook-certs
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: webhook-certs
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: jenkins-webhook-certificate
|
||||
terminationGracePeriodSeconds: 10</b>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
To enable security validation in the Jenkins Custom Resource, set
|
||||
|
||||
>jenkins.ValidateSecurityWarnings=true
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
---
|
||||
title: "LDAP"
|
||||
linkTitle: "LDAP"
|
||||
weight: 9
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
Additional configuration for LDAP
|
||||
---
|
||||
|
||||
Configuring LDAP is not supported out of the box, but can be achieved through
|
||||
plugins and some well tuned configurations.
|
||||
|
||||
The plugin we will use is: <https://plugins.jenkins.io/ldap/>
|
||||
|
||||
> Note: This is an example of how LDAP authentication can be achieved. The LDAP
|
||||
> plugin is from a third-party, and there may be other alternatives that suits
|
||||
> your use case better. Use this guide with a grain of salt.
|
||||
|
||||
## Requirements
|
||||
|
||||
- LDAP server accessible from the Kubernetes cluster where your Jenkins
|
||||
instance will live.
|
||||
|
||||
- Credentials to a manager account in your AD. Jenkins Operator will use
|
||||
this account to authenticate with Jenkins for health checks, seed jobs, etc.
|
||||
|
||||
## Steps
|
||||
|
||||
In your Jenkins configuration, add the following plugin:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
# Check https://plugins.jenkins.io/ldap/ to find the latest version.
|
||||
- name: ldap
|
||||
version: "2.7"
|
||||
```
|
||||
|
||||
Easiest step is to then start up Jenkins then navigate to your instance's
|
||||
"Configure Global Security" page and configure it accordingly.
|
||||
|
||||
`http://jenkins.example.com/configureSecurity/`
|
||||
|
||||
Once it's set up and tested, you can navigate to your JCasC page and export
|
||||
the LDAP settings.
|
||||
|
||||
`https://jenkins.example.com/configuration-as-code/`
|
||||
|
||||
Feed the relevant new settings into your Kubernetes ConfigMap for your JCasC
|
||||
settings.
|
||||
|
||||
Here's a snippet of the LDAP-related configurations:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: jenkins-casc
|
||||
data:
|
||||
ldap.yaml: |
|
||||
jenkins:
|
||||
securityRealm:
|
||||
ldap:
|
||||
configurations:
|
||||
- displayNameAttributeName: "name"
|
||||
groupSearchBase: "OU=Groups,OU=MyCompany"
|
||||
groupSearchFilter: "(& (cn={0}) (objectclass=group) )"
|
||||
inhibitInferRootDN: false
|
||||
managerDN: "CN=Jenkins Admin,OU=UsersSystem,OU=UsersOther,OU=MyCompany,DC=mycompany,DC=local"
|
||||
managerPasswordSecret: "${LDAP_MANAGER_PASSWORD}"
|
||||
rootDN: "DC=mycompany,DC=local"
|
||||
server: "MyCompany.local"
|
||||
userSearch: "SamAccountName={0}"
|
||||
userSearchBase: "OU=MyCompany"
|
||||
disableMailAddressResolver: false
|
||||
disableRolePrefixing: true
|
||||
groupIdStrategy: "caseInsensitive"
|
||||
userIdStrategy: "caseInsensitive"
|
||||
```
|
||||
|
||||
>Note the use of `${LDAP_MANAGER_PASSWORD}` above. You can reference
|
||||
>Kubernetes secrets in your JCasC ConfigMaps by adding the following to your
|
||||
|
||||
Jenkins object:
|
||||
|
||||
```yaml
|
||||
kind: Jenkins
|
||||
spec:
|
||||
configurationAsCode:
|
||||
configurations:
|
||||
- name: jenkins-casc
|
||||
secret:
|
||||
# This here
|
||||
name: jenkins-casc-secrets
|
||||
```
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: jenkins-cred-conf-secrets
|
||||
stringData:
|
||||
LDAP_MANAGER_PASSWORD: <password-for-manager-created-in-ldap>
|
||||
```
|
||||
Schema reference: [v1alpha2.ConfigurationAsCode](./schema/#github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.ConfigurationAsCode)
|
||||
|
||||
Finally you must configure the Jenkins operator to use the manager's
|
||||
credentials from the AD.
|
||||
|
||||
This is because this procedure will disable Jenkins' own user database, and the
|
||||
Jenkins operator still needs to be able to talk to Jenkins in an authorized
|
||||
manner.
|
||||
|
||||
Create the following Kubernetes secret:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: jenkins-operator-credentials-<jenkins-cr-name>
|
||||
namespace: <jenkins-cr-namespace>
|
||||
stringData:
|
||||
user: <username-for-manager-created-in-ldap>
|
||||
password: <password-for-manager-created-in-ldap>
|
||||
```
|
||||
|
||||
> Note: Values in stringData do not need to be base64 encoded. They are
|
||||
> encoded by Kubernetes when the manifest is applied.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: "OpenShift"
|
||||
linkTitle: "OpenShift"
|
||||
weight: 10
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
Additional configuration for OpenShift
|
||||
---
|
||||
|
||||
## Release 0.7.0 is not compatible with OpenShift.
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,583 @@
|
|||
---
|
||||
title: "Separate namespaces for Jenkins and Operator"
|
||||
linkTitle: "Separate namespaces for Jenkins and Operator"
|
||||
weight: 6
|
||||
date: 2021-12-08
|
||||
description: >
|
||||
How to install Jenkins and Jenkins Operator in separate namespaces
|
||||
---
|
||||
|
||||
## Create namespaces
|
||||
|
||||
You need to create two namespaces, for example we'll call them **jenkins** for Jenkins and **jenkins-operator** for Jenkins Operator.
|
||||
```bash
|
||||
$ kubectl create ns jenkins-operator
|
||||
$ kubectl create ns jenkins
|
||||
```
|
||||
|
||||
## Create necessary resources in Jenkins Operator namespace
|
||||
|
||||
Next, you need to install resources necessary for the Operator to work in the `jenkins-operator` namespace. To do that,
|
||||
copy the manifest you see below to `jenkins-operator-rbac.yaml`file.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
---
|
||||
# permissions to do leader election.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: leader-election-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- configmaps
|
||||
- leases
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: leader-election-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: leader-election-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: jenkins-operator
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- replicasets
|
||||
- statefulsets
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
- jenkins-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- build.openshift.io
|
||||
resources:
|
||||
- buildconfigs
|
||||
- builds
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- secrets
|
||||
- services
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/log
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/portforward
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- image.openshift.io
|
||||
resources:
|
||||
- imagestreams
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: jenkins-operator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: jenkins-operator
|
||||
```
|
||||
|
||||
Now install the required resources in `jenkins-operator` namespace with:
|
||||
```bash
|
||||
kubectl apply -n jenkins-operator -f jenkins-operator-rbac.yaml
|
||||
```
|
||||
|
||||
There's only one thing left to install in `jenkins-operator` namespace, and that is the Operator itself. The manifest
|
||||
below contains the Operator as defined in all-in-one manifest found in [Installing the Operator](/kubernetes-operator/docs/getting-started/latest/installing-the-operator/)
|
||||
page, the only difference is that the one here sets `WATCH_NAMESPACE` to the `jenkins` namespace we created.
|
||||
|
||||
Copy its content to `jenkins-operator.yaml` file.
|
||||
|
||||
```bash
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
control-plane: controller-manager
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
serviceAccountName: jenkins-operator
|
||||
securityContext:
|
||||
runAsUser: 65532
|
||||
containers:
|
||||
- command:
|
||||
- /manager
|
||||
args:
|
||||
- --leader-elect
|
||||
image: virtuslab/jenkins-operator:v0.7.0
|
||||
name: jenkins-operator
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 30Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 20Mi
|
||||
env:
|
||||
- name: WATCH_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
terminationGracePeriodSeconds: 10
|
||||
```
|
||||
|
||||
Install the Operator in `jenkins-operator` namespace with:
|
||||
|
||||
```bash
|
||||
kubectl apply -n jenkins-operator -f jenkins-operator.yaml
|
||||
```
|
||||
|
||||
You have installed the Operator in `jenkins-operator` namespace, watching for Jenkins in `jenkins` namespace. Now
|
||||
there are two things left to do: creating necessary Role and RoleBinding for the Operator in `jenkins` namespace, and
|
||||
deploying actual Jenkins instance there.
|
||||
|
||||
## Create necessary resources in Jenkins namespace
|
||||
|
||||
Below you can find manifest with RBAC that needs to be created in `jenkins` namespace. Copy its content to `jenkins-ns-rbac.yaml` file.
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
- replicasets
|
||||
- statefulsets
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
- jenkins-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- build.openshift.io
|
||||
resources:
|
||||
- buildconfigs
|
||||
- builds
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- secrets
|
||||
- services
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/exec
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/log
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/portforward
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- image.openshift.io
|
||||
resources:
|
||||
- imagestreams
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- jenkins.io
|
||||
resources:
|
||||
- jenkins/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
resources:
|
||||
- routes
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: jenkins-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: jenkins-operator
|
||||
namespace: jenkins-operator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: jenkins-operator
|
||||
```
|
||||
|
||||
Now apply it with:
|
||||
```bash
|
||||
kubectl apply -n jenkins -f jenkins-ns-rbac.yaml
|
||||
```
|
||||
|
||||
The last thing to do is to deploy Jenkins. Below you can find an example Jenkins resource manifest.
|
||||
It's the same as one used in [Deploying Jenkins](/kubernetes-operator/docs/getting-started/latest/deploying-jenkins/).
|
||||
Copy it to `jenkins-instance.yaml`
|
||||
|
||||
```yaml
|
||||
apiVersion: jenkins.io/v1alpha2
|
||||
kind: Jenkins
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
configurationAsCode:
|
||||
configurations: []
|
||||
secret:
|
||||
name: ""
|
||||
groovyScripts:
|
||||
configurations: []
|
||||
secret:
|
||||
name: ""
|
||||
jenkinsAPISettings:
|
||||
authorizationStrategy: createUser
|
||||
master:
|
||||
disableCSRFProtection: false
|
||||
containers:
|
||||
- name: jenkins-master
|
||||
image: jenkins/jenkins:2.319.1-lts-alpine
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 12
|
||||
httpGet:
|
||||
path: /login
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 100
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
readinessProbe:
|
||||
failureThreshold: 10
|
||||
httpGet:
|
||||
path: /login
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 80
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 3Gi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 500Mi
|
||||
seedJobs:
|
||||
- id: jenkins-operator
|
||||
targets: "cicd/jobs/*.jenkins"
|
||||
description: "Jenkins Operator repository"
|
||||
repositoryBranch: master
|
||||
repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
||||
```
|
||||
|
||||
Now you can deploy it with:
|
||||
|
||||
```bash
|
||||
kubectl apply -n jenkins -f jenkins-instance.yaml
|
||||
```
|
||||
|
||||
With this, you have just set up Jenkins Operator and Jenkins in separate namespaces. Now the Operator will run in
|
||||
its own namespace (`jenkins-operator`), watch for CRs in `jenkins` namespace, and deploy Jenkins there.
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,7 +17,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/bep/tech-doc-hugo#readme",
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^9.8.8",
|
||||
"postcss-cli": "^5.0.1"
|
||||
"autoprefixer": "^10.4.17",
|
||||
"postcss-cli": "^11.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue