Compare commits
314 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
08f0a74771 | |
|
|
bf040e1188 | |
|
|
b8a756909f | |
|
|
697dc1b370 | |
|
|
ac3db2fbc6 | |
|
|
ae9cb0c7f5 | |
|
|
3300775a1d | |
|
|
8a66d658eb | |
|
|
69bdd916d5 | |
|
|
132fcb22dc | |
|
|
ee191bfc4e | |
|
|
191caefbbe | |
|
|
627d3d2af2 | |
|
|
17d3c0bf4b | |
|
|
faf812a0ce | |
|
|
832debbd45 | |
|
|
4b3600ff0e | |
|
|
3b61208f2e | |
|
|
bec1c61e27 | |
|
|
2864a85364 | |
|
|
9c09db8031 | |
|
|
1ec83b9de9 | |
|
|
f0da3494ae | |
|
|
d919a2a11c | |
|
|
a4fa09b2ed | |
|
|
bb33b8ffa0 | |
|
|
7cdffbe716 | |
|
|
24eac18564 | |
|
|
3a5b7f6b4f | |
|
|
6abbd56e77 | |
|
|
b63b31a398 | |
|
|
7c6616b2bf | |
|
|
57a1b6bfb9 | |
|
|
5e962b26ae | |
|
|
0911dfe64a | |
|
|
b722ef11ae | |
|
|
5ef6c730de | |
|
|
e0f52b5bdf | |
|
|
f98b0bc5ee | |
|
|
e40032497b | |
|
|
18197e66b7 | |
|
|
061995a65c | |
|
|
25b329aa13 | |
|
|
3f036bdea7 | |
|
|
cf49a4a28f | |
|
|
6dd45eebf0 | |
|
|
1a7dc9107a | |
|
|
036b20c01b | |
|
|
48aa102342 | |
|
|
4f03cefda0 | |
|
|
cee202004d | |
|
|
be737522f0 | |
|
|
ec20bbe630 | |
|
|
81251d3ddc | |
|
|
95f0215c37 | |
|
|
bfda3c8cf9 | |
|
|
332eabe8d7 | |
|
|
2ba5334c10 | |
|
|
50c7217daa | |
|
|
8d61604b03 | |
|
|
63e8a76b95 | |
|
|
138e569841 | |
|
|
3682468b5f | |
|
|
d70f70f0f4 | |
|
|
a6e32fde98 | |
|
|
8268c1e4c5 | |
|
|
2c88fe13a8 | |
|
|
1b6e944ae6 | |
|
|
01a3990d66 | |
|
|
b95ccec075 | |
|
|
0fe4456abc | |
|
|
181bcc3316 | |
|
|
6065f012ee | |
|
|
7233d82237 | |
|
|
e79b06024a | |
|
|
5ddcf1075d | |
|
|
0abc758dc3 | |
|
|
97892a4cbd | |
|
|
c2c249aa48 | |
|
|
6cceedba77 | |
|
|
3fe842fff4 | |
|
|
813cbc812e | |
|
|
93d3e9eb9f | |
|
|
e6bd8c3f14 | |
|
|
936dbc4713 | |
|
|
dab511fed3 | |
|
|
1e4ffd4718 | |
|
|
4e5f9d562f | |
|
|
d9ea2ee83b | |
|
|
00bb04745b | |
|
|
3275be357a | |
|
|
44a7d2460a | |
|
|
7bccdc21b1 | |
|
|
5058fc2a6e | |
|
|
a690c7cc6c | |
|
|
f97badca9c | |
|
|
38eaa0fc55 | |
|
|
00fc29e772 | |
|
|
605669de0d | |
|
|
901100a759 | |
|
|
9fd053b784 | |
|
|
e36441a4a2 | |
|
|
6932b61ff9 | |
|
|
2f90db9dc9 | |
|
|
d91a729ccf | |
|
|
e9fbe575a6 | |
|
|
cd2efd6722 | |
|
|
1adaf00ca7 | |
|
|
c39eaa95b7 | |
|
|
fc3fe04581 | |
|
|
7a72939de8 | |
|
|
60b8ee56de | |
|
|
6e03948b09 | |
|
|
fbe70f11ca | |
|
|
3ce8a49d26 | |
|
|
410c403452 | |
|
|
a8065cc038 | |
|
|
addb94f83e | |
|
|
94b1473c63 | |
|
|
bef796af8a | |
|
|
4c2671c1a3 | |
|
|
e1b1e9cb3c | |
|
|
4079d4e93e | |
|
|
63e96c9715 | |
|
|
8fee7f2806 | |
|
|
b734b6d74f | |
|
|
3362aae2a3 | |
|
|
a97f283fb9 | |
|
|
56b65aed16 | |
|
|
46f64fea6a | |
|
|
13f871b1e4 | |
|
|
4fde1df8d8 | |
|
|
49bdf518de | |
|
|
d3b1fd8172 | |
|
|
47eb115219 | |
|
|
4c60936da2 | |
|
|
202d7a87b7 | |
|
|
29c5b1e705 | |
|
|
17a5bfec3e | |
|
|
e8414c09a8 | |
|
|
424ec3fbc2 | |
|
|
0f507409cc | |
|
|
2724ec2f70 | |
|
|
7fb4add0b2 | |
|
|
64de9aad91 | |
|
|
dd6e48c8d5 | |
|
|
2b158d5bda | |
|
|
445d48ab54 | |
|
|
8d953ae457 | |
|
|
76078d5ff2 | |
|
|
e2f19454b1 | |
|
|
7e94bc623f | |
|
|
89fa53ae08 | |
|
|
907be3a214 | |
|
|
93072ae7b3 | |
|
|
b3e06ad85a | |
|
|
e27992ba9e | |
|
|
e03ca0674a | |
|
|
75826d5367 | |
|
|
7092beabdc | |
|
|
d6f1dcbb54 | |
|
|
90d26f0548 | |
|
|
b1a388b6d6 | |
|
|
b3a4a6ca80 | |
|
|
2663555170 | |
|
|
b4345b2905 | |
|
|
14b0018a7f | |
|
|
273eab0a69 | |
|
|
266c2aa50d | |
|
|
768d1ac617 | |
|
|
764a144c5a | |
|
|
31c8368c55 | |
|
|
dfae860ca8 | |
|
|
b4aed5c154 | |
|
|
c8d640cc8c | |
|
|
225448b965 | |
|
|
2e8fed4e59 | |
|
|
78d33977a7 | |
|
|
7ae767ac84 | |
|
|
51f7ec8248 | |
|
|
4aa34157c3 | |
|
|
626246ac4d | |
|
|
b8f5157906 | |
|
|
55c3e88037 | |
|
|
d4917b46dd | |
|
|
126b02aaab | |
|
|
5423173340 | |
|
|
586515b212 | |
|
|
34c9ee3cd5 | |
|
|
ba66ba4c4d | |
|
|
95c29d4994 | |
|
|
9594c8e7cd | |
|
|
de02559c68 | |
|
|
9761d6a576 | |
|
|
f527a8c5cb | |
|
|
2c240538e0 | |
|
|
a1d98a73e7 | |
|
|
b84617b1ba | |
|
|
03cfa758f5 | |
|
|
f8621fcb81 | |
|
|
4657ed6d65 | |
|
|
e88d63fdf7 | |
|
|
e2ec2ea329 | |
|
|
38e46a13dd | |
|
|
39ec91da29 | |
|
|
4e046280a3 | |
|
|
16b4723b79 | |
|
|
5ca4e0a90c | |
|
|
ff6e03539c | |
|
|
b11ca32d1a | |
|
|
058ea61d70 | |
|
|
90b685db9b | |
|
|
851fb0d3e9 | |
|
|
65bc574cb8 | |
|
|
ba78896ea6 | |
|
|
9106582a9e | |
|
|
aedc2aff59 | |
|
|
3e5d80269d | |
|
|
2d1a67afb9 | |
|
|
853f485746 | |
|
|
1d2651d43f | |
|
|
b400a420e5 | |
|
|
b82fc7c764 | |
|
|
858f0f4c72 | |
|
|
8453b3e9fe | |
|
|
37d0eac4e3 | |
|
|
17dba087b8 | |
|
|
dfd25e822c | |
|
|
935b60b6d8 | |
|
|
9d5c525ace | |
|
|
bd32624fe1 | |
|
|
463cad3b07 | |
|
|
7ce9d1f077 | |
|
|
35dfd47ec7 | |
|
|
800c1a7d5d | |
|
|
db0978c4d4 | |
|
|
52fe5fe95e | |
|
|
b407e51bba | |
|
|
16a1ad8314 | |
|
|
e87c7cac5f | |
|
|
63370a55cc | |
|
|
eb256fec76 | |
|
|
222af51cb9 | |
|
|
6cc53704e8 | |
|
|
ec6e288673 | |
|
|
040fbbfea5 | |
|
|
b9059bc26b | |
|
|
27213fdc48 | |
|
|
985517b04f | |
|
|
485abaad8d | |
|
|
46ee392a7c | |
|
|
20b1bb7169 | |
|
|
cd3dbeb0a5 | |
|
|
fbea1ed790 | |
|
|
e762957cc1 | |
|
|
38fcdf5d37 | |
|
|
59d522c5d2 | |
|
|
30723cf6f8 | |
|
|
8a42cdc1ee | |
|
|
81374d0857 | |
|
|
a7fb199f98 | |
|
|
41dac85ea1 | |
|
|
332c08ccf2 | |
|
|
c74606a2ee | |
|
|
223119b62d | |
|
|
0d118bf046 | |
|
|
07d2e5e129 | |
|
|
6595462398 | |
|
|
84b5499755 | |
|
|
57bb20bd41 | |
|
|
53802eb60b | |
|
|
212bbe2896 | |
|
|
d8e05db017 | |
|
|
9197c29a30 | |
|
|
4bf5c63e2e | |
|
|
892b2c8dd9 | |
|
|
b720176afa | |
|
|
bf4bf4ecdd | |
|
|
652580c0a5 | |
|
|
3dab502234 | |
|
|
f1ea9d8ce9 | |
|
|
ce081bfd28 | |
|
|
a78b9ea77b | |
|
|
d225cc113e | |
|
|
77a79e8f97 | |
|
|
021ebb4745 | |
|
|
b69d1d4a23 | |
|
|
5bbd1585af | |
|
|
5f1b28f539 | |
|
|
4410ad6b88 | |
|
|
545c7b99b3 | |
|
|
294be87c64 | |
|
|
814f5d77c1 | |
|
|
ea861d8bd5 | |
|
|
e03b3f25a5 | |
|
|
53961d7bde | |
|
|
34ffdde054 | |
|
|
363b9e0fc0 | |
|
|
524d0b861f | |
|
|
5f45777554 | |
|
|
3157b29373 | |
|
|
73db2e0fc9 | |
|
|
9713375a37 | |
|
|
e6e00af4d9 | |
|
|
57ecbee244 | |
|
|
e4e2d91a35 | |
|
|
134c88fde7 | |
|
|
b6bf47b949 | |
|
|
cb26623f5f | |
|
|
aa45c79c56 | |
|
|
ae0fe371ba | |
|
|
0c253e7753 | |
|
|
8f7af2a149 | |
|
|
9f261169f0 |
|
|
@ -0,0 +1,63 @@
|
||||||
|
// 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.22",
|
||||||
|
"golangciLintVersion": "1.58.2"
|
||||||
|
},
|
||||||
|
"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": {
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/nix:1": {
|
||||||
|
"multiUser": "false",
|
||||||
|
"extraNixConfig": "experimental-features = nix-command flakes"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/hugo:1": {
|
||||||
|
"version": "v0.99.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// "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"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
|
||||||
|
# Ignore all files which are not go type
|
||||||
|
!**/*.go
|
||||||
|
!**/*.mod
|
||||||
|
!**/*.sum
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
name: "🐛 Bug report"
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: 'bug'
|
||||||
|
projects: ''
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior.
|
||||||
|
|
||||||
|
**Additional information**
|
||||||
|
|
||||||
|
Kubernetes version:
|
||||||
|
Jenkins Operator version:
|
||||||
|
|
||||||
|
|
||||||
|
Add error logs about the problem here (operator logs and Kubernetes events).
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
name: "📚 Documentation issue"
|
||||||
|
about: Suggest changes to project's documentation
|
||||||
|
title: ''
|
||||||
|
labels: 'documentation'
|
||||||
|
projects: ''
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
**Relevant links**
|
||||||
|
Link(s) to the section(s) of documentation that are outdated or otherwise wrong
|
||||||
|
|
||||||
|
**Description**
|
||||||
|
Description of the changes you would like to see
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
name: "🚀 Feature request"
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: 'enhancement'
|
||||||
|
projects: ''
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the feature request here e.g. external links or diagrams, etc.
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "gomod"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
groups:
|
||||||
|
golang:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/website"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
groups:
|
||||||
|
npm:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
groups:
|
||||||
|
actions:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# Expected Behavior
|
|
||||||
|
|
||||||
# Actual Behavior
|
|
||||||
|
|
||||||
# Steps to Reproduce the Problem
|
|
||||||
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
|
|
||||||
# Additional Info
|
|
||||||
|
|
||||||
- Kubernetes version:
|
|
||||||
|
|
||||||
**Output of `kubectl version`:**
|
|
||||||
|
|
||||||
```
|
|
||||||
(paste your output here)
|
|
||||||
```
|
|
||||||
|
|
||||||
- Jenkins Operator version:
|
|
||||||
|
|
||||||
```
|
|
||||||
(paste your output here)
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- Any other additional information -->
|
|
||||||
|
|
@ -15,20 +15,3 @@ review them:
|
||||||
- [ ] Commit messages follow [commit message best practices](https://github.com/jenkinsci/kubernetes-operator/blob/master/CONTRIBUTING.md#commit-messages)
|
- [ ] Commit messages follow [commit message best practices](https://github.com/jenkinsci/kubernetes-operator/blob/master/CONTRIBUTING.md#commit-messages)
|
||||||
|
|
||||||
_See [the contribution guide](https://github.com/jenkinsci/kubernetes-operator/blob/master/CONTRIBUTING.md) for more details._
|
_See [the contribution guide](https://github.com/jenkinsci/kubernetes-operator/blob/master/CONTRIBUTING.md) for more details._
|
||||||
|
|
||||||
|
|
||||||
## Reviewer Notes
|
|
||||||
|
|
||||||
If API changes are included, additive changes must be approved by at least two [OWNERS](https://github.com/jenkinsci/kubernetes-operator/blob/master/OWNERS) and backwards incompatible changes must be approved by [more than 50% of the OWNERS](https://github.com/jenkinsci/kubernetes-operator/blob/master/OWNERS).
|
|
||||||
|
|
||||||
# Release Notes
|
|
||||||
|
|
||||||
```
|
|
||||||
Describe any user facing changes here, or delete this block.
|
|
||||||
|
|
||||||
Examples of user facing changes:
|
|
||||||
- API changes
|
|
||||||
- Bug fixes
|
|
||||||
- Any changes in behavior
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
name: Website
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, ready_for_review, reopened]
|
||||||
|
paths:
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: "website"
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-date:
|
||||||
|
name: Auto update dates
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'pull_request' || (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
|
||||||
|
steps:
|
||||||
|
- uses: DeterminateSystems/nix-installer-action@e50d5f73bfe71c2dd0aa4218de8f4afa59f8f81d # v16
|
||||||
|
with:
|
||||||
|
diagnostic-endpoint: ""
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
run: |
|
||||||
|
IS_CHANGED=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -Ec "^website*" || :)
|
||||||
|
[[ $IS_CHANGED -gt 0 ]] && echo "IS_CHANGED=true" >> $GITHUB_ENV || echo "IS_CHANGED=false" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Update last modified date in modified docs
|
||||||
|
if: env.IS_CHANGED == 'true'
|
||||||
|
run: |
|
||||||
|
git diff --name-only --diff-filter=d ${{ github.event.before }} ${{ github.sha }} | grep -E "^website*" \
|
||||||
|
| sed -e 's/\(.*\)/"\1"/' | xargs sed -i "/date:/c\date: $(date +'%Y-%m-%d')"
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v6
|
||||||
|
if: env.IS_CHANGED == 'true' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
|
||||||
|
with:
|
||||||
|
commit-message: Auto-updated docs
|
||||||
|
branch: docs-generator
|
||||||
|
title: Auto-generated docs update
|
||||||
|
body: |
|
||||||
|
Auto generated docs from master commit ${{ github.sha }}
|
||||||
|
|
||||||
|
website-generate:
|
||||||
|
name: Auto generate website
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'pull_request' || (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
|
||||||
|
steps:
|
||||||
|
- uses: DeterminateSystems/nix-installer-action@e50d5f73bfe71c2dd0aa4218de8f4afa59f8f81d # v16
|
||||||
|
with:
|
||||||
|
diagnostic-endpoint: ""
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
- name: nix checks
|
||||||
|
run: nix flake check
|
||||||
|
- name: nix build
|
||||||
|
env:
|
||||||
|
HUGO_ENVIRONMENT: production
|
||||||
|
HUGO_ENV: production
|
||||||
|
run: nix build .#website
|
||||||
|
- name: Setup Pages
|
||||||
|
id: pages
|
||||||
|
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
|
||||||
|
with:
|
||||||
|
path: ./result
|
||||||
|
|
||||||
|
website-deploy:
|
||||||
|
name: Deploy website
|
||||||
|
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: website-generate
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
|
||||||
|
|
@ -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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- 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@271a8d0340265f705b14b6d32b9829c1cb33d45e # v6
|
||||||
|
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@5bef64f19d7facfb25b37b414482c7164d639639 # v9
|
||||||
|
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"
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
name: Tests BATS
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- 'backup/**'
|
||||||
|
- '*.md'
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, ready_for_review, reopened]
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- 'backup/**'
|
||||||
|
- '*.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-tests:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: BATS test ${{ matrix.test-file }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
test-file: ["1-deploy", "2-deploy-with-more-options", "3-deploy-with-webhook"]
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Setup Bats and libs
|
||||||
|
uses: bats-core/bats-action@e412797c46257a2dbf3775f6f6010b33ee6cb99f # 3.0.1
|
||||||
|
with:
|
||||||
|
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@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
||||||
|
with:
|
||||||
|
cluster_name: ${{env.KIND_CLUSTER_NAME}}
|
||||||
|
|
||||||
|
- name: Jenkins Operator - bats tests
|
||||||
|
env:
|
||||||
|
BATS_LIB_PATH: "${{ github.workspace }}/.bats"
|
||||||
|
run: BATS_TEST_PATH=${{matrix.test-file}}.bats make bats-tests
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
name: Tests E2E
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- 'backup/**'
|
||||||
|
- '*.md'
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, ready_for_review, reopened]
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- 'backup/**'
|
||||||
|
- '*.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-e2e-list:
|
||||||
|
name: E2E Create tests list
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.matrix.outputs.matrix }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
- id: matrix
|
||||||
|
run: |
|
||||||
|
script=$(./test/make_matrix_ginkgo.sh e2e)
|
||||||
|
echo "matrix=${script}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
verify-code:
|
||||||
|
name: E2E Verify code before tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [create-e2e-list]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Verify code formatting
|
||||||
|
run: make verify
|
||||||
|
|
||||||
|
run-e2e-tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [create-e2e-list, verify-code]
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: E2E ${{ matrix.test }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJSON(needs.create-e2e-list.outputs.matrix) }}
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Kind setup
|
||||||
|
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
||||||
|
with:
|
||||||
|
cluster_name: ${{env.KIND_CLUSTER_NAME}}
|
||||||
|
config: kind-cluster.yaml
|
||||||
|
|
||||||
|
- name: Prepare environment for e2e
|
||||||
|
run: |
|
||||||
|
sudo apt-get update && sudo apt-get install -y socat
|
||||||
|
sudo mkdir -p $HOME/.kube
|
||||||
|
sudo chown -R $USER $HOME/.kube
|
||||||
|
|
||||||
|
- name: Jenkins Operator - e2e Chart tests
|
||||||
|
env:
|
||||||
|
TNAME: ${{ matrix.test }}
|
||||||
|
TFILE: ${{ matrix.file }}
|
||||||
|
TLINE: ${{ matrix.line }}
|
||||||
|
run: |
|
||||||
|
git reset --hard
|
||||||
|
printf "\n \n > Running test: %s from file: $s line: %s\n" "${TNAME}" "${TFILE}" "${TLINE}"
|
||||||
|
make e2e E2E_TEST_ARGS='-ginkgo.v -ginkgo.focus="${TNAME}"'
|
||||||
|
|
||||||
|
- name: Debug
|
||||||
|
if: failure()
|
||||||
|
shell: bash
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
randomns=$(kubectl get ns| grep -i 'ns[0-9]\+' |cut -d ' ' -f 1)
|
||||||
|
kubectl get pods -n ${randomns}
|
||||||
|
kubectl get events -n ${randomns}
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
name: Tests HELM
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- 'backup/**'
|
||||||
|
- '*.md'
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, ready_for_review, reopened]
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'website/**'
|
||||||
|
- 'assets/**'
|
||||||
|
- 'backup/**'
|
||||||
|
- '*.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-helm-list:
|
||||||
|
name: HELM Create tests list
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.matrix.outputs.matrix }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
- id: matrix
|
||||||
|
run: |
|
||||||
|
script=$(./test/make_matrix_ginkgo.sh helm)
|
||||||
|
echo "matrix=${script}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
verify-code:
|
||||||
|
name: HELM Verify code before tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [create-helm-list]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Verify code formatting
|
||||||
|
run: make verify
|
||||||
|
|
||||||
|
run-helm-tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [create-helm-list, verify-code]
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
name: HELM ${{ matrix.test }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJSON(needs.create-helm-list.outputs.matrix) }}
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Kind setup
|
||||||
|
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
||||||
|
with:
|
||||||
|
cluster_name: ${{env.KIND_CLUSTER_NAME}}
|
||||||
|
config: kind-cluster.yaml
|
||||||
|
|
||||||
|
- name: Prepare environment for e2e
|
||||||
|
run: |
|
||||||
|
sudo apt-get update && sudo apt-get install -y socat
|
||||||
|
sudo mkdir -p $HOME/.kube
|
||||||
|
sudo chown -R $USER $HOME/.kube
|
||||||
|
|
||||||
|
- name: Jenkins Operator - Helm Chart tests
|
||||||
|
env:
|
||||||
|
TNAME: ${{ matrix.test }}
|
||||||
|
TFILE: ${{ matrix.file }}
|
||||||
|
TLINE: ${{ matrix.line }}
|
||||||
|
run: |
|
||||||
|
git reset --hard
|
||||||
|
make helm-lint
|
||||||
|
printf "\n \n > Running test: %s from file: $s line: %s\n" "${TNAME}" "${TFILE}" "${TLINE}"
|
||||||
|
make helm-e2e E2E_TEST_ARGS='-ginkgo.v -ginkgo.focus="${TNAME}"'
|
||||||
|
|
||||||
|
- name: Debug
|
||||||
|
if: failure()
|
||||||
|
shell: bash
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
randomns=$(kubectl get ns| grep -i 'ns[0-9]\+' |cut -d ' ' -f 1)
|
||||||
|
kubectl get pods -n ${randomns}
|
||||||
|
kubectl get events -n ${randomns}
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
name: Run tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, ready_for_review, reopened]
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
jobs:
|
|
||||||
run-tests:
|
|
||||||
if: github.event.pull_request.draft == false
|
|
||||||
name: Run automated tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up env vars
|
|
||||||
run: |
|
|
||||||
echo "GO111MODULE=on" >> $GITHUB_ENV
|
|
||||||
echo "CHANGE_MINIKUBE_NONE_USER=true" >> $GITHUB_ENV
|
|
||||||
echo "MINIKUBE_WANTUPDATENOTIFICATION=false" >> $GITHUB_ENV
|
|
||||||
echo "MINIKUBE_WANTREPORTERRORPROMPT=false" >> $GITHUB_ENV
|
|
||||||
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env)" >> $GITHUB_ENV
|
|
||||||
echo "MINIKUBE_VERSION=v$(sed -n 's/MINIKUBE_VERSION=//p' config.minikube.env)" >> $GITHUB_ENV
|
|
||||||
echo "OPERATOR_SDK_VERSION=v$(sed -n 's/OPERATOR_SDK_VERSION=//p' config.base.env)" >> $GITHUB_ENV
|
|
||||||
echo "MINIKUBE_KUBERNETES_VERSION=$(sed -n 's/MINIKUBE_KUBERNETES_VERSION=//p' config.minikube.env)" >> $GITHUB_ENV
|
|
||||||
echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env)" >> $GITHUB_ENV
|
|
||||||
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Prepare go environment
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Ensure Golang runtime dependencies
|
|
||||||
run: make go-dependencies
|
|
||||||
|
|
||||||
- name: Verify code formatting
|
|
||||||
run: make verify
|
|
||||||
|
|
||||||
- name: Prepare environment for e2e
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install socat
|
|
||||||
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/$MINIKUBE_KUBERNETES_VERSION/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
|
||||||
curl -Lo minikube https://storage.googleapis.com/minikube/releases/$MINIKUBE_VERSION/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
|
|
||||||
curl -Lo operator-sdk https://github.com/operator-framework/operator-sdk/releases/download/$OPERATOR_SDK_VERSION/operator-sdk-$OPERATOR_SDK_VERSION-x86_64-linux-gnu && chmod +x operator-sdk && sudo mv operator-sdk /usr/local/bin/
|
|
||||||
curl -Lo helm.tar.gz https://get.helm.sh/helm-$HELM_VERSION-linux-amd64.tar.gz && tar xzfv helm.tar.gz && sudo mv linux-amd64/helm /usr/local/bin/
|
|
||||||
sudo mkdir -p $HOME/.kube $HOME/.minikube
|
|
||||||
touch KUBECONFIG
|
|
||||||
sudo minikube start --vm-driver=none --kubernetes-version=$MINIKUBE_KUBERNETES_VERSION
|
|
||||||
sudo chown -R $USER $HOME/.kube $HOME/.minikube
|
|
||||||
|
|
||||||
- name: Jenkins Operator - e2e
|
|
||||||
run: make build e2e
|
|
||||||
|
|
||||||
- name: Jenkins Operator Helm Chart - e2e
|
|
||||||
run: make e2e BUILDTAGS=Helm E2E_TEST_SELECTOR='^.*Helm.*$'
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
name: auto-update-jenkins-lts
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 7 * * 0'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-and-update-jenkins-lts:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Check if update needed
|
||||||
|
id: check
|
||||||
|
run: |
|
||||||
|
CURRENT=$(sed -n 's/LATEST_LTS_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')
|
||||||
|
LATEST=$(curl -s https://www.jenkins.io/changelog-stable/ | grep -oP 'changelog/\K\d+\.\d+\.\d+' | head -1)
|
||||||
|
|
||||||
|
echo "current=$CURRENT" >> $GITHUB_OUTPUT
|
||||||
|
echo "latest=$LATEST" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
if [ "$CURRENT" != "$LATEST" ]; then
|
||||||
|
echo "needs_update=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "needs_update=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
if: steps.check.outputs.needs_update == 'true'
|
||||||
|
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
if: steps.check.outputs.needs_update == 'true'
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Update Jenkins lts version
|
||||||
|
if: steps.check.outputs.needs_update == 'true'
|
||||||
|
run: make update-jenkins-lts
|
||||||
|
|
||||||
|
- name: Update Jenkins base plugins
|
||||||
|
if: steps.check.outputs.needs_update == 'true'
|
||||||
|
run: make update-plugins
|
||||||
|
|
||||||
|
- name: Run verify
|
||||||
|
if: steps.check.outputs.needs_update == 'true'
|
||||||
|
run: make verify
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
if: steps.check.outputs.needs_update == 'true'
|
||||||
|
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
commit-message: "chore: update Jenkins lts version to ${{ steps.check.outputs.latest }}"
|
||||||
|
title: "chore: update Jenkins lts version to ${{ steps.check.outputs.latest }}"
|
||||||
|
body: "auto-update Jenkins lts version from ${{ steps.check.outputs.current }} to ${{ steps.check.outputs.latest }}"
|
||||||
|
branch: auto-update-jenkins-lts-${{ steps.check.outputs.latest }}
|
||||||
|
delete-branch: true
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
name: Release Backup Pvc
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
types: [edited, opened, reopened, synchronize]
|
||||||
|
paths:
|
||||||
|
- 'backup/pvc/**'
|
||||||
|
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- main
|
||||||
|
tags: ["*"]
|
||||||
|
paths:
|
||||||
|
- 'backup/pvc/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release-backup:
|
||||||
|
name: Release Backup Pvc, build, bump and push new image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Check envs
|
||||||
|
run: make -C backup/pvc check-env
|
||||||
|
|
||||||
|
- name: Build the e2e image
|
||||||
|
run: make -C backup/pvc docker-build-e2e
|
||||||
|
|
||||||
|
- name: Run the e2e tests
|
||||||
|
run: make -C backup/pvc docker-e2e
|
||||||
|
|
||||||
|
- name: Configure Git
|
||||||
|
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
|
||||||
|
run: |
|
||||||
|
git config user.name "$GITHUB_ACTOR"
|
||||||
|
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- name: Login to Quay.io
|
||||||
|
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
||||||
|
with:
|
||||||
|
registry: quay.io
|
||||||
|
username: ${{ secrets.QUAYIO_USERNAME }}
|
||||||
|
password: ${{ secrets.QUAYIO_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push the image to Quay.io
|
||||||
|
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
|
||||||
|
run: |
|
||||||
|
git reset --hard
|
||||||
|
make -C backup/pvc docker-build
|
||||||
|
make -C backup/pvc docker-release
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
name: Release Helm chart
|
||||||
|
|
||||||
|
# Run this workflow manually
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
chartVersion:
|
||||||
|
description: "Helm chart version to release. eg. 0.4.1"
|
||||||
|
required: true
|
||||||
|
appVersion:
|
||||||
|
description: "Operator app version without quotes, eg. 0.5.1 . If not provided, the one in Chart.yaml won't be overwritten."
|
||||||
|
required: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-helm-chart:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Deploy Helm chart
|
||||||
|
run: |
|
||||||
|
sed -i '0,/version:.*/s//version: ${{ github.event.inputs.chartVersion }}/' chart/jenkins-operator/Chart.yaml
|
||||||
|
|
||||||
|
if [ ${{ github.event.inputs.appVersion }} ] ; then
|
||||||
|
sed -i '/appVersion:.*/s//appVersion: "${{ github.event.inputs.appVersion }}"/' chart/jenkins-operator/Chart.yaml
|
||||||
|
fi
|
||||||
|
|
||||||
|
make helm-release-latest
|
||||||
|
|
||||||
|
# Creates pull request with new chart version
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v6
|
||||||
|
with:
|
||||||
|
commit-message: Release Helm chart ${{ github.event.inputs.chartVersion }}
|
||||||
|
branch: helm-chart-release-${{ github.event.inputs.chartVersion }}
|
||||||
|
title: Release ${{ github.event.inputs.chartVersion }} Helm Chart
|
||||||
|
body: |
|
||||||
|
Release ${{ github.event.inputs.chartVersion }} Helm Chart
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
name: Publish nightly snapshot
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 2 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
skipTests:
|
||||||
|
description: "Flag for skipping the tests. If set to true (without quotation marks), the workflow will skip tests and go straight to releasing the nightly build. Use with caution!"
|
||||||
|
required: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-image:
|
||||||
|
name: Publish nightly snapshot
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Prep - check out code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
|
||||||
|
- name: Prep - Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "HELM_VERSION=v$(sed -n 's/HELM_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "KIND_CLUSTER_NAME=$(sed -n 's/KIND_CLUSTER_NAME=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prep - setup Bats and bats libs
|
||||||
|
if: ${{ github.event.inputs.skipTests != 'true' }}
|
||||||
|
uses: bats-core/bats-action@472edde1138d59aca53ff162fb8d996666d21e4a # 2.0.0
|
||||||
|
with:
|
||||||
|
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: Prep - go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Prep - Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Test - verify code formatting
|
||||||
|
run: make verify
|
||||||
|
|
||||||
|
- name: Prep - Minikube setup
|
||||||
|
if: ${{ github.event.inputs.skipTests != 'true' }}
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install socat
|
||||||
|
sudo mkdir -p $HOME/.kube
|
||||||
|
sudo chown -R $USER $HOME/.kube
|
||||||
|
|
||||||
|
- name: Prep - Kind setup
|
||||||
|
if: ${{ github.event.inputs.skipTests != 'true' }}
|
||||||
|
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
||||||
|
with:
|
||||||
|
cluster_name: ${{env.KIND_CLUSTER_NAME}}
|
||||||
|
config: kind-cluster.yaml
|
||||||
|
|
||||||
|
- name: Test - e2e
|
||||||
|
if: ${{ github.event.inputs.skipTests != 'true' }}
|
||||||
|
run: make e2e E2E_TEST_ARGS='-ginkgo.v'
|
||||||
|
|
||||||
|
- name: Test - Helm Chart
|
||||||
|
if: ${{ github.event.inputs.skipTests != 'true' }}
|
||||||
|
run: |
|
||||||
|
git reset --hard
|
||||||
|
make helm-lint
|
||||||
|
make helm-e2e E2E_TEST_ARGS='-ginkgo.v'
|
||||||
|
|
||||||
|
- name: Test - bats
|
||||||
|
env:
|
||||||
|
BATS_LIB_PATH: "${{ github.workspace }}/.bats"
|
||||||
|
if: ${{ github.event.inputs.skipTests != 'true' }}
|
||||||
|
run: make bats-tests
|
||||||
|
|
||||||
|
- name: Post - Login to Quay.io
|
||||||
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
||||||
|
with:
|
||||||
|
registry: quay.io
|
||||||
|
username: ${{ secrets.QUAYIO_USERNAME }}
|
||||||
|
password: ${{ secrets.QUAYIO_TOKEN }}
|
||||||
|
|
||||||
|
- name: Post - Push image
|
||||||
|
run: |
|
||||||
|
git reset --hard
|
||||||
|
make container-runtime-snapshot-push
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
name: Release Operator
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release:
|
||||||
|
name: Release Operator, build and push newest image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up env vars
|
||||||
|
run: |
|
||||||
|
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||||
|
echo "GO_VERSION=v$(sed -n 's/GO_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"')" >> $GITHUB_ENV
|
||||||
|
echo "GOPATH=/home/runner/go" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Prepare go environment
|
||||||
|
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
|
||||||
|
- name: Ensure Golang runtime dependencies
|
||||||
|
run: make go-dependencies
|
||||||
|
|
||||||
|
- name: Configure Git
|
||||||
|
run: |
|
||||||
|
git config user.name "$GITHUB_ACTOR"
|
||||||
|
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||||
|
|
||||||
|
- name: Tag the release
|
||||||
|
run: make tag
|
||||||
|
|
||||||
|
- name: Set version for release tag name
|
||||||
|
run: |
|
||||||
|
echo "VERSION=$(cat VERSION.txt)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ env.VERSION }}
|
||||||
|
|
||||||
|
- name: Login to Quay.io
|
||||||
|
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
||||||
|
with:
|
||||||
|
registry: quay.io
|
||||||
|
username: ${{ secrets.QUAYIO_USERNAME }}
|
||||||
|
password: ${{ secrets.QUAYIO_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push the image to Quay.io
|
||||||
|
run: |
|
||||||
|
git reset --hard
|
||||||
|
make container-runtime-release
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../" && pwd)"
|
||||||
|
|
||||||
|
PLUGINS=(
|
||||||
|
"configuration-as-code"
|
||||||
|
"git"
|
||||||
|
"job-dsl"
|
||||||
|
"kubernetes"
|
||||||
|
"kubernetes-credentials-provider"
|
||||||
|
"workflow-aggregator"
|
||||||
|
)
|
||||||
|
|
||||||
|
version_compare() {
|
||||||
|
local ver1="$1"
|
||||||
|
local ver2="$2"
|
||||||
|
|
||||||
|
ver1=$(echo "$ver1" | sed 's/\([0-9.]*\).*/\1/')
|
||||||
|
ver2=$(echo "$ver2" | sed 's/\([0-9.]*\).*/\1/')
|
||||||
|
|
||||||
|
if [ "$ver1" = "$ver2" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local sorted=$(printf '%s\n%s' "$ver1" "$ver2" | sort -V)
|
||||||
|
local first=$(echo "$sorted" | head -n1)
|
||||||
|
|
||||||
|
if [ "$first" = "$ver1" ]; then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_update_center_data() {
|
||||||
|
local jenkins_version="$1"
|
||||||
|
local url="https://updates.jenkins.io/update-center.actual.json?version=${jenkins_version}"
|
||||||
|
local data=$(curl -s -L -f "$url")
|
||||||
|
|
||||||
|
if ! echo "$data" | jq . > /dev/null 2>&1; then
|
||||||
|
echo "error something happened" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$data"
|
||||||
|
}
|
||||||
|
|
||||||
|
find_compatible_version() {
|
||||||
|
local plugin_id="$1"
|
||||||
|
local jenkins_version="$2"
|
||||||
|
local update_data="$3"
|
||||||
|
local plugin_data=$(echo "$update_data" | jq ".plugins[\"$plugin_id\"]")
|
||||||
|
local plugin_version=$(echo "$plugin_data" | jq -r '.version')
|
||||||
|
local compatible_since=$(echo "$plugin_data" | jq -r '.compatibleSinceVersion // empty')
|
||||||
|
|
||||||
|
if [ -n "$compatible_since" ]; then
|
||||||
|
version_compare "$jenkins_version" "$compatible_since"
|
||||||
|
local result=$?
|
||||||
|
if [ $result -eq 1 ]; then
|
||||||
|
echo "Error: Plugin '$plugin_id' requires Jenkins $compatible_since or newer" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$plugin_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
update_go_file() {
|
||||||
|
local file_path="$1"
|
||||||
|
local plugin_id="$2"
|
||||||
|
local new_version="$3"
|
||||||
|
local dry_run="$4"
|
||||||
|
|
||||||
|
local var_name=""
|
||||||
|
case "$plugin_id" in
|
||||||
|
"configuration-as-code") var_name="configurationAsCodePlugin" ;;
|
||||||
|
"git") var_name="gitPlugin" ;;
|
||||||
|
"job-dsl") var_name="jobDslPlugin" ;;
|
||||||
|
"kubernetes") var_name="kubernetesPlugin" ;;
|
||||||
|
"kubernetes-credentials-provider") var_name="kubernetesCredentialsProviderPlugin" ;;
|
||||||
|
"workflow-aggregator") var_name="workflowAggregatorPlugin" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local relative_path=$(realpath --relative-to="$PROJECT_ROOT" "$file_path")
|
||||||
|
local new_line=" ${var_name} = \"${plugin_id}:${new_version}\""
|
||||||
|
|
||||||
|
if [ "$dry_run" = "true" ]; then
|
||||||
|
echo "$relative_path: $plugin_id:$new_version"
|
||||||
|
else
|
||||||
|
sed -i "s|^[[:space:]]*${var_name}[[:space:]]*=.*|${new_line}|" "$file_path"
|
||||||
|
echo "$relative_path: $var_name -> $plugin_id:$new_version"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
echo "usage: $0 <jenkins-version> [--dry-run]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local jenkins_version="$1"
|
||||||
|
local dry_run="false"
|
||||||
|
|
||||||
|
if [ $# -gt 1 ] && [ "$2" = "--dry-run" ]; then
|
||||||
|
dry_run="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local update_data
|
||||||
|
if ! update_data=$(fetch_update_center_data "$jenkins_version"); then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for plugin_id in "${PLUGINS[@]}"; do
|
||||||
|
local compatible_version
|
||||||
|
if compatible_version=$(find_compatible_version "$plugin_id" "$jenkins_version" "$update_data"); then
|
||||||
|
#printf "%-35s %-30s\n" "$plugin_id" "$compatible_version"
|
||||||
|
update_go_file "$PROJECT_ROOT/pkg/plugins/base_plugins.go" "$plugin_id" "$compatible_version" "$dry_run"
|
||||||
|
update_go_file "$PROJECT_ROOT/test/e2e/configuration_test.go" "$plugin_id" "$compatible_version" "$dry_run"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|
@ -88,3 +88,17 @@ tags
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
### IntelliJ IDEA ###
|
||||||
*.iml
|
*.iml
|
||||||
|
|
||||||
|
/bin
|
||||||
|
testbin/*
|
||||||
|
|
||||||
|
### Bats
|
||||||
|
chart/jenkins-operator/deploy.tmp
|
||||||
|
|
||||||
|
### Nix
|
||||||
|
result
|
||||||
|
|
||||||
|
### website
|
||||||
|
website/node_modules
|
||||||
|
website/public
|
||||||
|
website/.hugo_build.lock
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,41 @@
|
||||||
run:
|
run:
|
||||||
deadline: 10m
|
deadline: 5m
|
||||||
linters-settings:
|
allow-parallel-runners: true
|
||||||
errcheck:
|
skip-files:
|
||||||
check-blank: false
|
- api/v1alpha2/zz_generated.deepcopy.go
|
||||||
ignore: fmt:.*,io/ioutil:^Read.*,Write
|
issues:
|
||||||
|
exclude-use-default: false
|
||||||
|
exclude-rules:
|
||||||
|
- path: "internal/*"
|
||||||
|
linters:
|
||||||
|
- dupl
|
||||||
|
- path: (.+)_test.go
|
||||||
|
linters:
|
||||||
|
- dupl
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
disable-all: true
|
||||||
disable:
|
enable:
|
||||||
- funlen
|
|
||||||
- gocognit
|
|
||||||
- godox
|
|
||||||
- gomnd
|
|
||||||
- gochecknoglobals
|
|
||||||
- gochecknoinits
|
|
||||||
- lll
|
|
||||||
- prealloc
|
|
||||||
- wsl
|
|
||||||
- gocyclo
|
|
||||||
- scopelint
|
|
||||||
- dupl
|
- dupl
|
||||||
- gosec
|
- errcheck
|
||||||
- maligned
|
- exportloopref
|
||||||
- testpackage
|
- goconst
|
||||||
- goerr113
|
- gocyclo
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- loggercheck
|
||||||
|
- misspell
|
||||||
- nakedret
|
- nakedret
|
||||||
- nestif
|
- staticcheck
|
||||||
- godot
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
output:
|
||||||
|
sort-results: true
|
||||||
|
sort-order:
|
||||||
|
- file
|
||||||
|
- severity
|
||||||
|
- linter
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/sirosen/check-jsonschema
|
||||||
|
rev: a167de9d5f4e87e1cdb16cb560aa704b79b6f655 # frozen: 0.32.1
|
||||||
|
hooks:
|
||||||
|
- id: check-github-workflows
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
|
||||||
|
hooks:
|
||||||
|
- id: detect-private-key
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- repo: https://github.com/gruntwork-io/pre-commit
|
||||||
|
rev: "d9196b3a0a6fbc530f2bacea36c11a3b0214ff13" # frozen: v0.1.28
|
||||||
|
hooks:
|
||||||
|
- id: helmlint
|
||||||
|
- repo: https://github.com/norwoodj/helm-docs
|
||||||
|
rev: "37d3055fece566105cf8cff7c17b7b2355a01677" # frozen: v1.14.2
|
||||||
|
hooks:
|
||||||
|
- id: helm-docs
|
||||||
|
args:
|
||||||
|
- --chart-search-root=chart/jenkins-operator
|
||||||
|
- repo: https://github.com/brokenpip3/pre-commit-hooks
|
||||||
|
rev: dd7b3821637ba3c3a8628ad487fd84edec8006f2 # frozen: 0.0.1
|
||||||
|
hooks:
|
||||||
|
- id: github-actions-hash
|
||||||
|
files: ^.github/workflows/.*\.(yml|yaml)$ # limit only to github workflows
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
* @brokenpip3
|
||||||
|
|
@ -2,5 +2,4 @@
|
||||||
|
|
||||||
You can find the Jenkins Code of Conduct [on jenkins.io](https://jenkins.io/project/conduct/).
|
You can find the Jenkins Code of Conduct [on jenkins.io](https://jenkins.io/project/conduct/).
|
||||||
|
|
||||||
It applies to the entire `jenkinsci` GitHub organization, among other community spaces.
|
It applies to the entire `jenkinsci` GitHub organization, among other community spaces.
|
||||||
[version]: http://contributor-covenant.org/version/1/4/
|
|
||||||
|
|
@ -1,46 +1,50 @@
|
||||||
# Contributing
|
# Contribution Model
|
||||||
|
|
||||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
Thanks for taking the time to contribute!
|
||||||
|
|
||||||
The following is a set of guidelines for contributing to the Jenkins Operator. These are mostly guidelines, not rules.
|
|
||||||
Use your best judgment, and feel free to propose changes to this document in a pull request.
|
|
||||||
|
|
||||||
In this project we appreciate any kind of contributions: code, documentation, design, etc.
|
|
||||||
Any contribution counts, and the size does not matter!
|
|
||||||
|
|
||||||
## Newcomers
|
|
||||||
|
|
||||||
If you are a newcomer contributor and have any questions, please do not hesitate to ask in the `#jenkins-operator` [Slack](https://virtuslab-oss.slack.com) Channel.
|
|
||||||
|
|
||||||
#### Table Of Contents
|
|
||||||
|
|
||||||
[Code of Conduct](#code-of-conduct)
|
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
|
|
||||||
This project and everyone participating in it is governed by the [Atom Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
|
This project and everyone participating in it is governed by the [Jenkins Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
|
||||||
|
|
||||||
## Commit Messages
|
## We Develop with GitHub
|
||||||
|
We use GitHub to host code, to track issues and feature requests, as well as accept pull requests.
|
||||||
|
|
||||||
All commit messages should follow
|
## We Use GitHub Flow, So All Code Changes Happen Through Pull Requests
|
||||||
[these best practices](https://chris.beams.io/posts/git-commit/), specifically:
|
Pull requests are the best way to propose changes to the codebase (we use GitHub Flow). We actively welcome your pull requests:
|
||||||
|
|
||||||
- Start with a subject line
|
- Create feature requests and discuss the scope.
|
||||||
- Contain a body that explains _why_ you're making the change you're making
|
- Fork the repo and create your branch from master.
|
||||||
- Reference an issue number one exists, closing it if applicable (with text such
|
- If you’ve added code that should be tested, add tests.
|
||||||
as
|
- If you’ve changed APIs or design, update the documentation.
|
||||||
["Fixes #245" or "Closes #111"](https://help.github.com/articles/closing-issues-using-keywords/))
|
- Create a draft pull request (not yet ready for review, triggers CI build).
|
||||||
|
- Ensure the e2e tests pass (wait for GitHub status checks).
|
||||||
|
- Mark that pull request as ready for review.
|
||||||
|
|
||||||
Not sure what to put? Try to Include:
|
## Quality Standards
|
||||||
|
It is important to keep the quality bar high and ensure all of us follow best practices and security, so the code is solid and can be reused by other people. Below you can find some quality standards.
|
||||||
|
|
||||||
- What is the problem being solved?
|
### General Contribution
|
||||||
- Why is this the best approach?
|
|
||||||
- What other approaches did you consider?
|
|
||||||
- What side effects will this approach have?
|
|
||||||
- What future work remains to be done?
|
|
||||||
|
|
||||||
## Coding standards
|
- Break down your pull request into smaller pieces, less code is easier to review. Most of PRs should fall under 200 lines of code changes unless specifically justified otherwise.
|
||||||
|
- Add descriptive comments and labels to pull requests and issues.
|
||||||
|
- Ensure end to end tests are passing.
|
||||||
|
- commit message should follow [these best practices](https://chris.beams.io/posts/git-commit/), specifically: start with a subject line and reference an issue number e.g. ["Fixes #245" or "Closes #111"](https://help.github.com/articles/closing-issues-using-keywords/)
|
||||||
|
|
||||||
### Go
|
### Large Architectural Changes
|
||||||
|
In case of large change which requires significant engineering effort and introduces side effects, we suggest writing a design proposal document first.
|
||||||
|
|
||||||
- [Go code review comments](https://github.com/golang/go/wiki/CodeReviewComments)
|
Design proposal is simply a document that states what you propose to do including:
|
||||||
|
|
||||||
|
- Problem statement
|
||||||
|
- Description of potential solution
|
||||||
|
- Side effects
|
||||||
|
- Breaking changes
|
||||||
|
|
||||||
|
Keep in mind that a proposal is not a pitch, it needs to be technical.
|
||||||
|
|
||||||
|
### Proposing changes to Helm Chart
|
||||||
|
When issuing a PR that modifies the project's Helm Chart, please do not include in your PR changes that would release a new package version when merged.
|
||||||
|
|
||||||
|
Specifically, please do not update `chart/index.yaml` and `chart/jenkins-operator/Chart.yaml` files and do not build chart archive package.
|
||||||
|
|
||||||
|
For the sake of PR's brevity and security, Project's maintainers will issue a separate PR that releases new version of the Chart after your PR has been merged.
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
ARG GO_VERSION
|
||||||
|
|
||||||
|
# Build the manager binary
|
||||||
|
FROM golang:$GO_VERSION as builder
|
||||||
|
ARG CTIMEVAR
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
|
# Copy the Go Modules manifests
|
||||||
|
COPY go.mod go.mod
|
||||||
|
COPY go.sum go.sum
|
||||||
|
# cache deps before building and copying source so that we don't need to re-download as much
|
||||||
|
# and so that source changes don't invalidate our downloaded layer
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# Copy the go source
|
||||||
|
COPY api/ api/
|
||||||
|
COPY internal/controller/ internal/controller/
|
||||||
|
COPY internal/ internal/
|
||||||
|
COPY pkg/ pkg/
|
||||||
|
COPY version/ version/
|
||||||
|
COPY cmd/main.go cmd/main.go
|
||||||
|
|
||||||
|
# Build
|
||||||
|
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
|
||||||
|
|
||||||
|
# Use distroless as minimal base image to package the manager binary
|
||||||
|
# Refer to https://github.com/GoogleContainerTools/distroless for more details
|
||||||
|
FROM gcr.io/distroless/static:nonroot
|
||||||
|
LABEL maintainer="Jenkins Kubernetes Operator Community" \
|
||||||
|
org.opencontainers.image.authors="Jenkins Kubernetes Operator Community" \
|
||||||
|
org.opencontainers.image.title="jenkins-kubernetes-operator" \
|
||||||
|
org.opencontainers.image.description="Kubernetes native Jenkins Operator" \
|
||||||
|
org.opencontainers.image.url="quay.io/jenkins-kubernetes-operator/operator" \
|
||||||
|
org.opencontainers.image.source="https://github.com/jenkinsci/kubernetes-operator/tree/master" \
|
||||||
|
org.opencontainers.image.base.name="gcr.io/distroless/static:nonroot"
|
||||||
|
WORKDIR /
|
||||||
|
COPY --from=builder /workspace/manager .
|
||||||
|
USER 65532:65532
|
||||||
|
|
||||||
|
ENTRYPOINT ["/manager"]
|
||||||
603
Makefile
603
Makefile
|
|
@ -1,74 +1,4 @@
|
||||||
# Set POSIX sh for maximum interoperability
|
include variables.mk
|
||||||
SHELL := /bin/sh
|
|
||||||
PATH := $(GOPATH)/bin:$(PATH)
|
|
||||||
|
|
||||||
OSFLAG :=
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
OSFLAG = WIN32
|
|
||||||
else
|
|
||||||
UNAME_S := $(shell uname -s)
|
|
||||||
ifeq ($(UNAME_S),Linux)
|
|
||||||
OSFLAG = LINUX
|
|
||||||
endif
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
|
||||||
OSFLAG = OSX
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
include config.base.env
|
|
||||||
|
|
||||||
# Import config
|
|
||||||
# You can change the default config with `make config="config_special.env" build`
|
|
||||||
config ?= config.minikube.env
|
|
||||||
include $(config)
|
|
||||||
|
|
||||||
# Set an output prefix, which is the local directory if not specified
|
|
||||||
PREFIX?=$(shell pwd)
|
|
||||||
|
|
||||||
VERSION := $(shell cat VERSION.txt)
|
|
||||||
GITCOMMIT := $(shell git rev-parse --short HEAD)
|
|
||||||
GITBRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
|
||||||
GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
|
|
||||||
GITIGNOREDBUTTRACKEDCHANGES := $(shell git ls-files -i --exclude-standard)
|
|
||||||
ifneq ($(GITUNTRACKEDCHANGES),)
|
|
||||||
GITCOMMIT := $(GITCOMMIT)-dirty
|
|
||||||
endif
|
|
||||||
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
|
|
||||||
GITCOMMIT := $(GITCOMMIT)-dirty
|
|
||||||
endif
|
|
||||||
|
|
||||||
VERSION_TAG := $(VERSION)
|
|
||||||
LATEST_TAG := latest
|
|
||||||
BUILD_TAG := $(GITBRANCH)-$(GITCOMMIT)
|
|
||||||
|
|
||||||
BUILD_PATH := ./cmd/manager
|
|
||||||
|
|
||||||
# CONTAINER_RUNTIME_COMMAND is Container Runtime - it could be docker or podman
|
|
||||||
CONTAINER_RUNTIME_COMMAND := docker
|
|
||||||
|
|
||||||
# Set any default go build tags
|
|
||||||
BUILDTAGS :=
|
|
||||||
|
|
||||||
# Set the build dir, where built cross-compiled binaries will be output
|
|
||||||
BUILDDIR := ${PREFIX}/cross
|
|
||||||
|
|
||||||
CTIMEVAR=-X $(PKG)/version.GitCommit=$(GITCOMMIT) -X $(PKG)/version.Version=$(VERSION)
|
|
||||||
GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
|
|
||||||
GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
|
|
||||||
|
|
||||||
# List the GOOS and GOARCH to build
|
|
||||||
GOOSARCHES = linux/amd64
|
|
||||||
|
|
||||||
PACKAGES = $(shell go list -f '{{.ImportPath}}/' ./... | grep -v vendor)
|
|
||||||
PACKAGES_FOR_UNIT_TESTS = $(shell go list -f '{{.ImportPath}}/' ./... | grep -v vendor | grep -v e2e)
|
|
||||||
|
|
||||||
# Run all the e2e tests by default
|
|
||||||
E2E_TEST_SELECTOR ?= .*
|
|
||||||
|
|
||||||
JENKINS_API_HOSTNAME := $(shell $(JENKINS_API_HOSTNAME_COMMAND) 2> /dev/null || echo "" )
|
|
||||||
OPERATOR_ARGS ?= --jenkins-api-hostname=$(JENKINS_API_HOSTNAME) --jenkins-api-port=$(JENKINS_API_PORT) --jenkins-api-use-nodeport=$(JENKINS_API_USE_NODEPORT) --cluster-domain=$(CLUSTER_DOMAIN) $(OPERATOR_EXTRA_ARGS)
|
|
||||||
|
|
||||||
.DEFAULT_GOAL := help
|
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: status checkmake clean build verify install container-runtime-build container-runtime-images ## Build the image
|
all: status checkmake clean build verify install container-runtime-build container-runtime-images ## Build the image
|
||||||
|
|
@ -121,7 +51,7 @@ build: deepcopy-gen $(NAME) ## Builds a dynamic executable or package
|
||||||
.PHONY: $(NAME)
|
.PHONY: $(NAME)
|
||||||
$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
|
$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
CGO_ENABLED=0 go build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o build/_output/bin/jenkins-operator $(BUILD_PATH)
|
CGO_ENABLED=0 go build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o bin/manager $(BUILD_PATH)
|
||||||
|
|
||||||
.PHONY: static
|
.PHONY: static
|
||||||
static: ## Builds a static executable
|
static: ## Builds a static executable
|
||||||
|
|
@ -136,22 +66,26 @@ fmt: ## Verifies all files have been `gofmt`ed
|
||||||
@go fmt $(PACKAGES)
|
@go fmt $(PACKAGES)
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
HAS_GOLINT := $(shell which golangci-lint)
|
HAS_GOLINT := $(shell which $(PROJECT_DIR)/bin/golangci-lint)
|
||||||
lint: ## Verifies `golint` passes
|
lint: ## Verifies `golint` passes
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
ifndef HAS_GOLINT
|
ifndef HAS_GOLINT
|
||||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.26.0
|
GOBIN=$(PROJECT_DIR)/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.0
|
||||||
endif
|
endif
|
||||||
@golangci-lint run
|
@bin/golangci-lint run
|
||||||
|
|
||||||
|
.PHONY: lint-fix
|
||||||
|
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
|
||||||
|
@bin/golangci-lint run --fix
|
||||||
|
|
||||||
.PHONY: goimports
|
.PHONY: goimports
|
||||||
HAS_GOIMPORTS := $(shell which goimports)
|
HAS_GOIMPORTS := $(shell which $(PROJECT_DIR)/bin/goimports)
|
||||||
goimports: ## Verifies `goimports` passes
|
goimports: ## Verifies `goimports` passes
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
ifndef HAS_GOIMPORTS
|
ifndef HAS_GOIMPORTS
|
||||||
go get -u golang.org/x/tools/cmd/goimports
|
$(call GOBIN=$(PROJECT_DIR)/bin go install golang.org/x/tools/cmd/goimports@v0.1.0)
|
||||||
endif
|
endif
|
||||||
@goimports -l -e $(shell find . -type f -name '*.go' -not -path "./vendor/*")
|
@bin/goimports -l -e $(shell find . -type f -name '*.go' -not -path "./vendor/*")
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: ## Runs the go tests
|
test: ## Runs the go tests
|
||||||
|
|
@ -159,47 +93,63 @@ test: ## Runs the go tests
|
||||||
@RUNNING_TESTS=1 go test -tags "$(BUILDTAGS) cgo" $(PACKAGES_FOR_UNIT_TESTS)
|
@RUNNING_TESTS=1 go test -tags "$(BUILDTAGS) cgo" $(PACKAGES_FOR_UNIT_TESTS)
|
||||||
|
|
||||||
.PHONY: e2e
|
.PHONY: e2e
|
||||||
CURRENT_DIRECTORY := $(shell pwd)
|
e2e: deepcopy-gen manifests backup-kind-load jenkins-kind-load ## Runs e2e tests, you can use EXTRA_ARGS
|
||||||
e2e: container-runtime-build ## Runs e2e tests, you can use EXTRA_ARGS
|
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
@echo "Docker image: $(DOCKER_REGISTRY):$(GITCOMMIT)"
|
RUNNING_TESTS=1 go test -parallel=1 "./test/e2e/" -ginkgo.v -tags "$(BUILDTAGS) cgo" -v -timeout 60m -run "$(E2E_TEST_SELECTOR)" \
|
||||||
ifeq ($(KUBERNETES_PROVIDER),minikube)
|
-jenkins-api-hostname=$(JENKINS_API_HOSTNAME) -jenkins-api-port=$(JENKINS_API_PORT) -jenkins-api-use-nodeport=$(JENKINS_API_USE_NODEPORT) $(E2E_TEST_ARGS)
|
||||||
kubectl config use-context $(KUBECTL_CONTEXT)
|
|
||||||
endif
|
.PHONY: jenkins-kind-load
|
||||||
ifeq ($(KUBERNETES_PROVIDER),crc)
|
jenkins-kind-load: ## Load the jenkins lts version in kind to speed up tests
|
||||||
oc project $(CRC_OC_PROJECT)
|
@echo "+ $@"
|
||||||
endif
|
docker pull jenkins/jenkins:$(LATEST_LTS_VERSION)
|
||||||
cp deploy/service_account.yaml deploy/namespace-init.yaml
|
kind load docker-image jenkins/jenkins:$(LATEST_LTS_VERSION) --name $(KIND_CLUSTER_NAME)
|
||||||
cat deploy/role.yaml >> deploy/namespace-init.yaml
|
|
||||||
cat deploy/role_binding.yaml >> deploy/namespace-init.yaml
|
## Backup Section
|
||||||
cat deploy/operator.yaml >> deploy/namespace-init.yaml
|
|
||||||
ifeq ($(OSFLAG), LINUX)
|
.PHONY: backup-kind-load
|
||||||
ifeq ($(IMAGE_PULL_MODE), remote)
|
backup-kind-load: ## Load latest backup image in the cluster
|
||||||
sed -i 's|\(image:\).*|\1 $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT)|g' deploy/namespace-init.yaml
|
@echo "+ $@"
|
||||||
sed -i 's|\(imagePullPolicy\): IfNotPresent|\1: Always|g' deploy/namespace-init.yaml
|
make -C backup/pvc backup-kind-load
|
||||||
|
|
||||||
|
## HELM Section
|
||||||
|
|
||||||
|
.PHONY: helm
|
||||||
|
HAS_HELM := $(shell command -v helm 2> /dev/null)
|
||||||
|
helm: ## Download helm if it's not present, otherwise symlink
|
||||||
|
@echo "+ $@"
|
||||||
|
ifeq ($(strip $(HAS_HELM)),)
|
||||||
|
mkdir -p $(PROJECT_DIR)/bin
|
||||||
|
curl -Lo $(PROJECT_DIR)/bin/helm.tar.gz https://get.helm.sh/helm-v$(HELM_VERSION)-$(PLATFORM)-amd64.tar.gz && tar xzfv $(PROJECT_DIR)/bin/helm.tar.gz -C $(PROJECT_DIR)/bin
|
||||||
|
mv $(PROJECT_DIR)/bin/$(PLATFORM)-amd64/helm $(PROJECT_DIR)/bin/helm
|
||||||
|
rm -rf $(PROJECT_DIR)/bin/$(PLATFORM)-amd64
|
||||||
|
rm -rf $(PROJECT_DIR)/bin/helm.tar.gz
|
||||||
else
|
else
|
||||||
sed -i 's|\(image:\).*|\1 $(DOCKER_REGISTRY):$(GITCOMMIT)|g' deploy/namespace-init.yaml
|
mkdir -p $(PROJECT_DIR)/bin
|
||||||
endif
|
test -L $(PROJECT_DIR)/bin/helm || ln -sf $(shell command -v helm) $(PROJECT_DIR)/bin/helm
|
||||||
ifeq ($(KUBERNETES_PROVIDER),minikube)
|
|
||||||
sed -i 's|\(imagePullPolicy\): IfNotPresent|\1: Never|g' deploy/namespace-init.yaml
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OSFLAG), OSX)
|
.PHONY: helm-lint
|
||||||
ifeq ($(IMAGE_PULL_MODE), remote)
|
helm-lint: helm
|
||||||
sed -i '' 's|\(image:\).*|\1 $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT)|g' deploy/namespace-init.yaml
|
bin/helm lint chart/jenkins-operator
|
||||||
sed -i '' 's|\(imagePullPolicy\): IfNotPresent|\1: Always|g' deploy/namespace-init.yaml
|
|
||||||
else
|
|
||||||
sed -i '' 's|\(image:\).*|\1 $(DOCKER_REGISTRY):$(GITCOMMIT)|g' deploy/namespace-init.yaml
|
|
||||||
endif
|
|
||||||
ifeq ($(KUBERNETES_PROVIDER),minikube)
|
|
||||||
sed -i '' 's|\(imagePullPolicy\): IfNotPresent|\1: Never|g' deploy/namespace-init.yaml
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
RUNNING_TESTS=1 go test -parallel=1 "./test/e2e/" -tags "$(BUILDTAGS) cgo" -v -timeout 60m -run "$(E2E_TEST_SELECTOR)" \
|
.PHONY: helm-release-latest
|
||||||
-root=$(CURRENT_DIRECTORY) -kubeconfig=$(HOME)/.kube/config -globalMan deploy/crds/jenkins_$(API_VERSION)_jenkins_crd.yaml \
|
helm-release-latest: helm
|
||||||
-namespacedMan deploy/namespace-init.yaml $(TEST_ARGS)
|
mkdir -p /tmp/jenkins-operator-charts
|
||||||
|
mv chart/jenkins-operator/*.tgz /tmp/jenkins-operator-charts
|
||||||
|
cd chart && ../bin/helm package jenkins-operator
|
||||||
|
mv chart/jenkins-operator-*.tgz chart/jenkins-operator/
|
||||||
|
bin/helm repo index chart/ --url https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/ --merge chart/index.yaml
|
||||||
|
mv /tmp/jenkins-operator-charts/*.tgz chart/jenkins-operator/
|
||||||
|
|
||||||
|
.PHONY: helm-e2e
|
||||||
|
IMAGE_NAME := quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)-amd64
|
||||||
|
|
||||||
|
helm-e2e: helm container-runtime-build-amd64 backup-kind-load ## Runs helm e2e tests, you can use EXTRA_ARGS
|
||||||
|
kind load docker-image ${IMAGE_NAME} --name $(KIND_CLUSTER_NAME)
|
||||||
|
@echo "+ $@"
|
||||||
|
RUNNING_TESTS=1 go test -parallel=1 "./test/helm/" -ginkgo.v -tags "$(BUILDTAGS) cgo" -v -timeout 60m -run "$(E2E_TEST_SELECTOR)" -image-name=$(IMAGE_NAME) $(E2E_TEST_ARGS)
|
||||||
|
|
||||||
|
## CODE CHECKS section
|
||||||
|
|
||||||
.PHONY: vet
|
.PHONY: vet
|
||||||
vet: ## Verifies `go vet` passes
|
vet: ## Verifies `go vet` passes
|
||||||
|
|
@ -207,23 +157,25 @@ vet: ## Verifies `go vet` passes
|
||||||
@go vet $(PACKAGES)
|
@go vet $(PACKAGES)
|
||||||
|
|
||||||
.PHONY: staticcheck
|
.PHONY: staticcheck
|
||||||
HAS_STATICCHECK := $(shell which staticcheck)
|
HAS_STATICCHECK := $(shell which $(PROJECT_DIR)/bin/staticcheck)
|
||||||
PLATFORM = $(shell echo $(UNAME_S) | tr A-Z a-z)
|
|
||||||
staticcheck: ## Verifies `staticcheck` passes
|
staticcheck: ## Verifies `staticcheck` passes
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
ifndef HAS_STATICCHECK
|
ifndef HAS_STATICCHECK
|
||||||
wget -O staticcheck_$(PLATFORM)_amd64.tar.gz https://github.com/dominikh/go-tools/releases/download/2020.1.3/staticcheck_$(PLATFORM)_amd64.tar.gz
|
$(eval TMP_DIR := $(shell mktemp -d))
|
||||||
tar zxvf staticcheck_$(PLATFORM)_amd64.tar.gz
|
wget -O $(TMP_DIR)/staticcheck_$(PLATFORM)_amd64.tar.gz https://github.com/dominikh/go-tools/releases/download/2023.1.7/staticcheck_$(PLATFORM)_amd64.tar.gz
|
||||||
mkdir -p $(GOPATH)/bin
|
tar zxvf $(TMP_DIR)/staticcheck_$(PLATFORM)_amd64.tar.gz -C $(TMP_DIR)
|
||||||
mv staticcheck/staticcheck $(GOPATH)/bin
|
mkdir -p $(PROJECT_DIR)/bin
|
||||||
|
mv $(TMP_DIR)/staticcheck/staticcheck $(PROJECT_DIR)/bin
|
||||||
|
rm -rf $(TMP_DIR)
|
||||||
endif
|
endif
|
||||||
@staticcheck $(PACKAGES)
|
@$(PROJECT_DIR)/bin/staticcheck $(PACKAGES)
|
||||||
|
|
||||||
.PHONY: cover
|
.PHONY: cover
|
||||||
cover: ## Runs go test with coverage
|
cover: ## Runs go test with coverage
|
||||||
@echo "" > coverage.txt
|
@echo "" > coverage.txt
|
||||||
@for d in $(PACKAGES); do \
|
@for d in $(PACKAGES); do \
|
||||||
IMG_RUNNING_TESTS=1 go test -race -coverprofile=profile.out -covermode=atomic "$$d"; \
|
ENVTEST_K8S_VERSION = 1.26
|
||||||
|
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" IMG_RUNNING_TESTS=1 go test -race -coverprofile=profile.out -covermode=atomic "$$d"; \
|
||||||
if [ -f profile.out ]; then \
|
if [ -f profile.out ]; then \
|
||||||
cat profile.out >> coverage.txt; \
|
cat profile.out >> coverage.txt; \
|
||||||
rm profile.out; \
|
rm profile.out; \
|
||||||
|
|
@ -239,21 +191,62 @@ install: ## Installs the executable
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
go install -tags "$(BUILDTAGS)" ${GO_LDFLAGS} $(BUILD_PATH)
|
go install -tags "$(BUILDTAGS)" ${GO_LDFLAGS} $(BUILD_PATH)
|
||||||
|
|
||||||
|
.PHONY: update-plugins
|
||||||
|
update-plugins: ## Update jenkins base plugins
|
||||||
|
@echo "+ $@"
|
||||||
|
@JENKINS_VERSION=$$(sed -n 's/LATEST_LTS_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"'); \
|
||||||
|
echo "updating plugins for Jenkins $$JENKINS_VERSION"; \
|
||||||
|
./.github/workflows/update-plugins.sh "$$JENKINS_VERSION"
|
||||||
|
|
||||||
|
.PHONY: update-plugins-dry-run
|
||||||
|
update-plugins-dry-run: ## Update jenkins base plugin -- dry run
|
||||||
|
@echo "+ $@"
|
||||||
|
@JENKINS_VERSION=$$(sed -n 's/LATEST_LTS_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"'); \
|
||||||
|
echo "checking plugins for Jenkins $$JENKINS_VERSION -- dry run"; \
|
||||||
|
./.github/workflows/update-plugins.sh "$$JENKINS_VERSION" --dry-run
|
||||||
|
|
||||||
|
.PHONY: update-jenkins-lts
|
||||||
|
update-jenkins-lts: ## Fetch latest Jenkins lts version and update if necessary
|
||||||
|
@echo "+ $@"
|
||||||
|
@LATEST_VERSION=$$(curl -s https://www.jenkins.io/changelog-stable/ | grep -oP 'changelog/\K\d+\.\d+\.\d+' | head -1); \
|
||||||
|
CURRENT_VERSION=$$(sed -n 's/LATEST_LTS_VERSION=//p' config.base.env | tr -d '\n' | tr -d '"'); \
|
||||||
|
echo "current version: $$CURRENT_VERSION"; \
|
||||||
|
echo "latest version: $$LATEST_VERSION"; \
|
||||||
|
if [ "$$CURRENT_VERSION" != "$$LATEST_VERSION" ]; then \
|
||||||
|
echo "updating Jenkins lts version from $$CURRENT_VERSION to $$LATEST_VERSION"; \
|
||||||
|
sed -i "s/LATEST_LTS_VERSION=\".*\"/LATEST_LTS_VERSION=\"$$LATEST_VERSION\"/" config.base.env; \
|
||||||
|
$(MAKE) update-lts-version LATEST_LTS_VERSION=$$LATEST_VERSION; \
|
||||||
|
echo "updated Jenkins LTS version to $$LATEST_VERSION"; \
|
||||||
|
else \
|
||||||
|
echo "up to date"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: update-lts-version
|
||||||
|
update-lts-version: ## Update the latest lts version
|
||||||
|
@echo "+ $@"
|
||||||
|
echo $(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
|
||||||
|
#TODO: source the version from config.base.env for bats test, no need of hardcoded version
|
||||||
|
sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' test/bats/1-deploy.bats
|
||||||
|
sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' test/bats/2-deploy-with-more-options.bats
|
||||||
|
sed -i 's|jenkins/jenkins:[0-9]\+.[0-9]\+.[0-9]\+|jenkins/jenkins:$(LATEST_LTS_VERSION)|g' test/bats/3-deploy-with-webhook.bats
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: export WATCH_NAMESPACE = $(NAMESPACE)
|
run: export WATCH_NAMESPACE = $(NAMESPACE)
|
||||||
run: export OPERATOR_NAME = $(NAME)
|
run: export OPERATOR_NAME = $(NAME)
|
||||||
run: build ## Run the executable, you can use EXTRA_ARGS
|
run: fmt vet install-crds build ## Run the executable, you can use EXTRA_ARGS
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
ifeq ($(KUBERNETES_PROVIDER),minikube)
|
ifeq ($(KUBERNETES_PROVIDER),kind)
|
||||||
kubectl config use-context $(KUBECTL_CONTEXT)
|
kubectl config use-context $(KUBECTL_CONTEXT)
|
||||||
endif
|
endif
|
||||||
ifeq ($(KUBERNETES_PROVIDER),crc)
|
ifeq ($(KUBERNETES_PROVIDER),crc)
|
||||||
oc project $(CRC_OC_PROJECT)
|
oc project $(CRC_OC_PROJECT)
|
||||||
endif
|
endif
|
||||||
kubectl apply -f deploy/crds/jenkins_$(API_VERSION)_jenkins_crd.yaml
|
|
||||||
kubectl apply -f deploy/crds/jenkins_$(API_VERSION)_jenkinsimage_crd.yaml
|
|
||||||
@echo "Watching '$(WATCH_NAMESPACE)' namespace"
|
@echo "Watching '$(WATCH_NAMESPACE)' namespace"
|
||||||
build/_output/bin/jenkins-operator $(OPERATOR_ARGS)
|
bin/manager $(OPERATOR_ARGS)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: ## Cleanup any build binaries or packages
|
clean: ## Cleanup any build binaries or packages
|
||||||
|
|
@ -308,46 +301,66 @@ endif
|
||||||
container-runtime-login: ## Log in into the Docker repository
|
container-runtime-login: ## Log in into the Docker repository
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
|
|
||||||
.PHONY: container-runtime-build
|
.PHONY: container-runtime-build-%
|
||||||
container-runtime-build: check-env ## Build the container
|
container-runtime-build-%: ## Build the container
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) build \
|
$(CONTAINER_RUNTIME_COMMAND) buildx build \
|
||||||
--build-arg GO_VERSION=$(GO_VERSION) \
|
--output=type=docker --platform linux/$* \
|
||||||
--build-arg OPERATOR_SDK_VERSION=$(OPERATOR_SDK_VERSION) \
|
--build-arg GO_VERSION=$(GO_VERSION) \
|
||||||
-t $(DOCKER_REGISTRY):$(GITCOMMIT) . \
|
--build-arg CTIMEVAR="$(CTIMEVAR)" \
|
||||||
--file build/Dockerfile $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
--tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)-$* . \
|
||||||
|
--file Dockerfile $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
||||||
|
|
||||||
|
.PHONY: container-runtime-build
|
||||||
|
container-runtime-build: check-env deepcopy-gen container-runtime-build-amd64 container-runtime-build-arm64
|
||||||
|
|
||||||
.PHONY: container-runtime-images
|
.PHONY: container-runtime-images
|
||||||
container-runtime-images: ## List all local containers
|
container-runtime-images: ## List all local containers
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) images $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(CONTAINER_RUNTIME_COMMAND) images $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
||||||
|
|
||||||
|
define buildx-create-command
|
||||||
|
$(CONTAINER_RUNTIME_COMMAND) buildx create \
|
||||||
|
--driver=docker-container \
|
||||||
|
--use
|
||||||
|
endef
|
||||||
|
|
||||||
|
## Parameter is version
|
||||||
|
define container-runtime-push-command
|
||||||
|
$(CONTAINER_RUNTIME_COMMAND) buildx build \
|
||||||
|
--output=type=registry --platform linux/amd64,linux/arm64 \
|
||||||
|
--build-arg GO_VERSION=$(GO_VERSION) \
|
||||||
|
--build-arg CTIMEVAR="$(CTIMEVAR)" \
|
||||||
|
--tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(1) . \
|
||||||
|
--file Dockerfile $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
||||||
|
endef
|
||||||
|
|
||||||
.PHONY: container-runtime-push
|
.PHONY: container-runtime-push
|
||||||
container-runtime-push: ## Push the container
|
container-runtime-push: check-env deepcopy-gen ## Push the container
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(BUILD_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call buildx-create-command)
|
||||||
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(BUILD_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call container-runtime-push-command,$(BUILD_TAG))
|
||||||
|
|
||||||
.PHONY: container-runtime-snapshot-push
|
.PHONY: container-runtime-snapshot-push
|
||||||
container-runtime-snapshot-push:
|
container-runtime-snapshot-push: check-env deepcopy-gen
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call buildx-create-command)
|
||||||
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call container-runtime-push-command,$(GITCOMMIT))
|
||||||
|
|
||||||
.PHONY: container-runtime-release-version
|
.PHONY: container-runtime-release-version
|
||||||
container-runtime-release-version: ## Release image with version tag (in addition to build tag)
|
container-runtime-release-version: check-env deepcopy-gen ## Release image with version tag (in addition to build tag)
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(VERSION_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call buildx-create-command)
|
||||||
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(VERSION_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call container-runtime-push-command,$(VERSION_TAG))
|
||||||
|
|
||||||
.PHONY: container-runtime-release-latest
|
.PHONY: container-runtime-release-latest
|
||||||
container-runtime-release-latest: ## Release image with latest tags (in addition to build tag)
|
container-runtime-release-latest: check-env deepcopy-gen ## Release image with latest tags (in addition to build tag)
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(LATEST_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call buildx-create-command)
|
||||||
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(LATEST_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
|
$(call container-runtime-push-command,$(LATEST_TAG))
|
||||||
|
|
||||||
.PHONY: container-runtime-release
|
.PHONY: container-runtime-release
|
||||||
container-runtime-release: container-runtime-build container-runtime-release-version container-runtime-release-latest ## Release image with version and latest tags (in addition to build tag)
|
container-runtime-release: container-runtime-release-version container-runtime-release-latest ## Release image with version and latest tags (in addition to build tag)
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
|
|
||||||
# if this session isn't interactive, then we don't want to allocate a
|
# if this session isn't interactive, then we don't want to allocate a
|
||||||
|
|
@ -355,7 +368,7 @@ container-runtime-release: container-runtime-build container-runtime-release-ver
|
||||||
# so that the user can send e.g. ^C through.
|
# so that the user can send e.g. ^C through.
|
||||||
INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
|
INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
|
||||||
ifeq ($(INTERACTIVE), 1)
|
ifeq ($(INTERACTIVE), 1)
|
||||||
DOCKER_FLAGS += -t
|
DOCKER_FLAGS += -t
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: container-runtime-run
|
.PHONY: container-runtime-run
|
||||||
|
|
@ -363,52 +376,29 @@ container-runtime-run: ## Run the container in docker, you can use EXTRA_ARGS
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(CONTAINER_RUNTIME_COMMAND) run $(CONTAINER_RUNTIME_EXTRA_ARGS) --rm -i $(DOCKER_FLAGS) \
|
$(CONTAINER_RUNTIME_COMMAND) run $(CONTAINER_RUNTIME_EXTRA_ARGS) --rm -i $(DOCKER_FLAGS) \
|
||||||
--volume $(HOME)/.kube/config:/home/jenkins-operator/.kube/config \
|
--volume $(HOME)/.kube/config:/home/jenkins-operator/.kube/config \
|
||||||
$(DOCKER_REGISTRY):$(GITCOMMIT) /usr/bin/jenkins-operator $(OPERATOR_ARGS)
|
quay.io/${QUAY_ORGANIZATION}/$(QUAY_REGISTRY):$(GITCOMMIT) /usr/bin/jenkins-operator $(OPERATOR_ARGS)
|
||||||
|
|
||||||
.PHONY: minikube-run
|
|
||||||
minikube-run: export WATCH_NAMESPACE = $(NAMESPACE)
|
|
||||||
minikube-run: export OPERATOR_NAME = $(NAME)
|
|
||||||
minikube-run: minikube-start ## Run the operator locally and use minikube as Kubernetes cluster, you can use OPERATOR_ARGS
|
|
||||||
@echo "+ $@"
|
|
||||||
kubectl config use-context minikube
|
|
||||||
kubectl apply -f deploy/crds/jenkins_$(API_VERSION)_jenkins_crd.yaml
|
|
||||||
@echo "Watching '$(WATCH_NAMESPACE)' namespace"
|
|
||||||
build/_output/bin/jenkins-operator $(OPERATOR_ARGS)
|
|
||||||
|
|
||||||
.PHONY: crc-run
|
.PHONY: crc-run
|
||||||
crc-run: export WATCH_NAMESPACE = $(NAMESPACE)
|
crc-run: export WATCH_NAMESPACE = $(NAMESPACE)
|
||||||
crc-run: export OPERATOR_NAME = $(NAME)
|
crc-run: export OPERATOR_NAME = $(NAME)
|
||||||
crc-run: crc-start ## Run the operator locally and use CodeReady Containers as Kubernetes cluster, you can use OPERATOR_ARGS
|
crc-run: crc-start run ## Run the operator locally and use CodeReady Containers as Kubernetes cluster, you can use OPERATOR_ARGS
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
oc project $(CRC_OC_PROJECT)
|
|
||||||
kubectl apply -f deploy/crds/jenkins_$(API_VERSION)_jenkins_crd.yaml
|
|
||||||
@echo "Watching '$(WATCH_NAMESPACE)' namespace"
|
|
||||||
build/_output/bin/jenkins-operator $(OPERATOR_ARGS)
|
|
||||||
|
|
||||||
.PHONY: deepcopy-gen
|
.PHONY: deepcopy-gen
|
||||||
deepcopy-gen: ## Generate deepcopy golang code
|
deepcopy-gen: generate ## Generate deepcopy golang code
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
operator-sdk generate k8s
|
|
||||||
|
|
||||||
.PHONY: scheme-doc-gen
|
.PHONY: scheme-doc-gen
|
||||||
HAS_GEN_CRD_API_REFERENCE_DOCS := $(shell ls gen-crd-api-reference-docs 2> /dev/null)
|
HAS_GEN_CRD_API_REFERENCE_DOCS := $(shell ls gen-crd-api-reference-docs 2> /dev/null)
|
||||||
scheme-doc-gen: ## Generate Jenkins CRD scheme doc
|
scheme-doc-gen: ## Generate Jenkins CRD scheme doc
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
ifndef HAS_GEN_CRD_API_REFERENCE_DOCS
|
ifndef HAS_GEN_CRD_API_REFERENCE_DOCS
|
||||||
@wget https://github.com/ahmetb/$(GEN_CRD_API)/releases/download/v0.1.2/$(GEN_CRD_API)_linux_amd64.tar.gz
|
@wget https://github.com/ahmetb/$(GEN_CRD_API)/releases/download/v0.1.2/$(GEN_CRD_API)_$(PLATFORM)_amd64.tar.gz
|
||||||
@mkdir -p $(GEN_CRD_API)
|
@mkdir -p $(GEN_CRD_API)
|
||||||
@tar -C $(GEN_CRD_API) -zxf $(GEN_CRD_API)_linux_amd64.tar.gz
|
@tar -C $(GEN_CRD_API) -zxf $(GEN_CRD_API)_$(PLATFORM)_amd64.tar.gz
|
||||||
@rm $(GEN_CRD_API)_linux_amd64.tar.gz
|
@rm $(GEN_CRD_API)_$(PLATFORM)_amd64.tar.gz
|
||||||
endif
|
|
||||||
$(GEN_CRD_API)/$(GEN_CRD_API) -config gen-crd-api-config.json -api-dir github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/$(API_VERSION) -template-dir $(GEN_CRD_API)/template -out-file documentation/$(VERSION)/jenkins-$(API_VERSION)-scheme.md
|
|
||||||
|
|
||||||
.PHONY: check-minikube
|
|
||||||
check-minikube: ## Checks if KUBERNETES_PROVIDER is set to minikube
|
|
||||||
@echo "+ $@"
|
|
||||||
@echo "KUBERNETES_PROVIDER '$(KUBERNETES_PROVIDER)'"
|
|
||||||
ifneq ($(KUBERNETES_PROVIDER),minikube)
|
|
||||||
$(error KUBERNETES_PROVIDER not set to 'minikube')
|
|
||||||
endif
|
endif
|
||||||
|
$(GEN_CRD_API)/$(GEN_CRD_API) -config gen-crd-api-config.json -api-dir $(PKG)/api/$(API_VERSION) -template-dir $(GEN_CRD_API)/template -out-file documentation/$(VERSION)/jenkins-$(API_VERSION)-scheme.md
|
||||||
|
|
||||||
.PHONY: check-crc
|
.PHONY: check-crc
|
||||||
check-crc: ## Checks if KUBERNETES_PROVIDER is set to crc
|
check-crc: ## Checks if KUBERNETES_PROVIDER is set to crc
|
||||||
|
|
@ -418,41 +408,77 @@ ifneq ($(KUBERNETES_PROVIDER),crc)
|
||||||
$(error KUBERNETES_PROVIDER not set to 'crc')
|
$(error KUBERNETES_PROVIDER not set to 'crc')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: minikube-start
|
.PHONY: kind-setup
|
||||||
minikube-start: check-minikube ## Start minikube
|
kind-setup: ## Setup kind cluster
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
@minikube status && exit 0 || \
|
kind create cluster --config kind-cluster.yaml --name $(KIND_CLUSTER_NAME)
|
||||||
minikube start --kubernetes-version $(MINIKUBE_KUBERNETES_VERSION) --dns-domain=$(CLUSTER_DOMAIN) --extra-config=kubelet.cluster-domain=$(CLUSTER_DOMAIN) --vm-driver=$(MINIKUBE_DRIVER) --memory 4096 --cpus 3
|
|
||||||
|
.PHONY: kind-clean
|
||||||
|
kind-clean: ## Delete kind cluster
|
||||||
|
@echo "+ $@"
|
||||||
|
kind delete cluster --name $(KIND_CLUSTER_NAME)
|
||||||
|
|
||||||
|
.PHONY: kind-revamp
|
||||||
|
kind-revamp: kind-clean kind-setup ## Delete and recreate kind cluster
|
||||||
|
@echo "+ $@"
|
||||||
|
|
||||||
|
.PHONY: bats-tests ## Run bats tests
|
||||||
|
IMAGE_NAME := quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)-amd64
|
||||||
|
BUILD_PRESENT := $(shell docker images |grep -q ${IMAGE_NAME})
|
||||||
|
ifndef BUILD_PRESENT
|
||||||
|
bats-tests: backup-kind-load 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 test/bats$(if $(BATS_TEST_PATH),/${BATS_TEST_PATH})
|
||||||
|
else
|
||||||
|
bats-tests: backup-kind-load
|
||||||
|
@echo "+ $@"
|
||||||
|
OPERATOR_IMAGE="${IMAGE_NAME}" TERM=xterm bats -T -p test/bats$(if $(BATS_TEST_PATH),/${BATS_TEST_PATH})
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: crc-start
|
.PHONY: crc-start
|
||||||
crc-start: check-crc ## Start CodeReady Containers Kubernetes cluster
|
crc-start: check-crc ## Start CodeReady Containers Kubernetes cluster
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
crc start
|
crc start
|
||||||
|
|
||||||
|
.PHONY: sembump
|
||||||
|
HAS_SEMBUMP := $(shell which $(PROJECT_DIR)/bin/sembump)
|
||||||
|
sembump: # Download sembump locally if necessary
|
||||||
|
@echo "+ $@"
|
||||||
|
ifndef HAS_SEMBUMP
|
||||||
|
mkdir -p $(PROJECT_DIR)/bin
|
||||||
|
wget -O $(PROJECT_DIR)/bin/sembump https://github.com/justintout/sembump/releases/download/v0.1.0/sembump-$(PLATFORM)-amd64
|
||||||
|
chmod +x $(PROJECT_DIR)/bin/sembump
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: bump-version
|
.PHONY: bump-version
|
||||||
BUMP := patch
|
BUMP := patch
|
||||||
bump-version: ## Bump the version in the version file. Set BUMP to [ patch | major | minor ]
|
bump-version: sembump ## Bump the version in the version file. Set BUMP to [ patch | major | minor ]
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
#@go get -u github.com/jessfraz/junk/sembump # update sembump tool FIXME
|
$(eval NEW_VERSION=$(shell bin/sembump --kind $(BUMP) $(VERSION)))
|
||||||
$(eval NEW_VERSION=$(shell sembump --kind $(BUMP) $(VERSION)))
|
|
||||||
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
|
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
|
||||||
echo $(NEW_VERSION) > VERSION.txt
|
echo $(NEW_VERSION) > VERSION.txt
|
||||||
@echo "Updating version from $(VERSION) to $(NEW_VERSION) in README.md"
|
@echo "Updating version from $(VERSION) to $(NEW_VERSION) in README.md"
|
||||||
sed -i s/$(VERSION)/$(NEW_VERSION)/g README.md
|
sed -i.bak 's/$(VERSION)/$(NEW_VERSION)/g' README.md
|
||||||
sed -i s/$(VERSION)/$(NEW_VERSION)/g deploy/operator.yaml
|
sed -i.bak 's/$(VERSION)/$(NEW_VERSION)/g' config/manager/manager.yaml
|
||||||
sed -i s/$(VERSION)/$(NEW_VERSION)/g deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
sed -i.bak 's/$(VERSION)/$(NEW_VERSION)/g' deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
cp deploy/service_account.yaml deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
rm */*/**.bak
|
||||||
cat deploy/role.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
rm */**.bak
|
||||||
cat deploy/role_binding.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
rm *.bak
|
||||||
cat deploy/operator.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
cp config/service_account.yaml deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
git add VERSION.txt README.md deploy/operator.yaml deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
cat config/rbac/leader_election_role.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
|
cat config/rbac/leader_election_role_binding.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
|
cat config/rbac/role.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
|
cat config/rbac/role_binding.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
|
cat config/manager/manager.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
|
git add VERSION.txt README.md config/manager/manager.yaml deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
|
||||||
git commit -vaem "Bump version to $(NEW_VERSION)"
|
git commit -vaem "Bump version to $(NEW_VERSION)"
|
||||||
@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
|
@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
|
||||||
|
|
||||||
.PHONY: tag
|
.PHONY: tag
|
||||||
tag: ## Create a new git tag to prepare to build a release
|
tag: ## Create a new git tag to prepare to build a release
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
git tag -s -a $(VERSION) -m "$(VERSION)"
|
git tag -a $(VERSION) -m "$(VERSION)"
|
||||||
git push origin $(VERSION)
|
git push origin $(VERSION)
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
|
|
@ -471,30 +497,187 @@ ifneq ($(GITUNTRACKEDCHANGES),)
|
||||||
endif
|
endif
|
||||||
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
|
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
|
||||||
@echo "Ignored but tracked files:"
|
@echo "Ignored but tracked files:"
|
||||||
@git ls-files -i --exclude-standard
|
@git ls-files -i -o --exclude-standard
|
||||||
@echo
|
@echo
|
||||||
endif
|
endif
|
||||||
@echo "Dependencies:"
|
@echo "Dependencies:"
|
||||||
go mod vendor -v
|
go mod vendor -v
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
.PHONY: helm-package
|
|
||||||
helm-package:
|
|
||||||
@echo "+ $@"
|
|
||||||
mkdir -p /tmp/jenkins-operator-charts
|
|
||||||
mv chart/jenkins-operator/*.tgz /tmp/jenkins-operator-charts
|
|
||||||
cd chart && helm package jenkins-operator
|
|
||||||
mv /tmp/jenkins-operator-charts/*.tgz chart/jenkins-operator/
|
|
||||||
rm -rf /tmp/jenkins-operator-charts/
|
|
||||||
|
|
||||||
.PHONY: helm-deploy
|
# Download and build hugo extended locally if necessary
|
||||||
helm-deploy: helm-package
|
HUGO_PATH = $(shell pwd)/bin/hugo
|
||||||
@echo "+ $@"
|
HUGO_VERSION = v0.99.1
|
||||||
helm repo index chart/ --url https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/
|
HAS_HUGO := $(shell $(HUGO_PATH)/hugo version 2>&- | grep $(HUGO_VERSION))
|
||||||
cd chart/ && mv jenkins-operator-*.tgz jenkins-operator
|
.PHONY: hugo
|
||||||
|
hugo:
|
||||||
|
ifeq ($(HAS_HUGO), )
|
||||||
|
@echo "Installing Hugo $(HUGO_VERSION)"
|
||||||
|
rm -rf $(HUGO_PATH)
|
||||||
|
git clone https://github.com/gohugoio/hugo.git --depth=1 --branch $(HUGO_VERSION) $(HUGO_PATH)
|
||||||
|
cd $(HUGO_PATH) && go build --tags extended -o hugo main.go
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: generate-docs
|
.PHONY: generate-docs
|
||||||
generate-docs: ## Re-generate docs directory from the website directory
|
generate-docs: hugo ## Re-generate docs directory from the website directory
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
rm -rf docs || echo "Cannot remove docs dir, ignoring"
|
rm -rf docs || echo "Cannot remove docs dir, ignoring"
|
||||||
hugo -s website -d ../docs
|
cd website && npm install
|
||||||
|
$(HUGO_PATH)/hugo -s website -d ../docs
|
||||||
|
|
||||||
|
.PHONY: run-docs
|
||||||
|
run-docs: hugo
|
||||||
|
@echo "+ $@"
|
||||||
|
cd website && $(HUGO_PATH)/hugo server -D
|
||||||
|
|
||||||
|
##################### FROM OPERATOR SDK ########################
|
||||||
|
# Install CRDs into a cluster
|
||||||
|
.PHONY: install-crds
|
||||||
|
install-crds: manifests kustomize
|
||||||
|
$(KUSTOMIZE) build config/crd | kubectl apply -f -
|
||||||
|
|
||||||
|
# Uninstall CRDs from a cluster
|
||||||
|
ifndef ignore-not-found
|
||||||
|
ignore-not-found = false
|
||||||
|
endif
|
||||||
|
.PHONY: uninstall-crds
|
||||||
|
uninstall-crds: manifests kustomize
|
||||||
|
$(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
|
||||||
|
|
||||||
|
# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
|
||||||
|
.PHONY: deploy
|
||||||
|
deploy: manifests kustomize
|
||||||
|
cd config/manager && $(KUSTOMIZE) edit set image controller=quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(GITCOMMIT)
|
||||||
|
$(KUSTOMIZE) build config/default | kubectl apply -f -
|
||||||
|
|
||||||
|
# UnDeploy controller from the configured Kubernetes cluster in ~/.kube/config
|
||||||
|
.PHONY: undeploy
|
||||||
|
undeploy:
|
||||||
|
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
|
||||||
|
|
||||||
|
# Generate manifests e.g. CRD, RBAC etc.
|
||||||
|
.PHONY: manifests
|
||||||
|
manifests: controller-gen
|
||||||
|
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
|
||||||
|
|
||||||
|
# Generate code
|
||||||
|
.PHONY: generate
|
||||||
|
generate: controller-gen
|
||||||
|
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
||||||
|
|
||||||
|
##@ Build Dependencies
|
||||||
|
|
||||||
|
## Location to install dependencies to
|
||||||
|
LOCALBIN ?= $(shell pwd)/bin
|
||||||
|
$(LOCALBIN):
|
||||||
|
mkdir -p $(LOCALBIN)
|
||||||
|
|
||||||
|
## Tool Binaries
|
||||||
|
KUSTOMIZE ?= $(LOCALBIN)/kustomize
|
||||||
|
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
|
||||||
|
ENVTEST ?= $(LOCALBIN)/setup-envtest
|
||||||
|
|
||||||
|
## Tool Versions
|
||||||
|
KUSTOMIZE_VERSION ?= v5.3.0
|
||||||
|
CONTROLLER_TOOLS_VERSION ?= v0.14.0
|
||||||
|
|
||||||
|
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
|
||||||
|
.PHONY: kustomize
|
||||||
|
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
|
||||||
|
$(KUSTOMIZE): $(LOCALBIN)
|
||||||
|
test -s $(LOCALBIN)/kustomize || { curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); }
|
||||||
|
|
||||||
|
.PHONY: controller-gen
|
||||||
|
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
|
||||||
|
$(CONTROLLER_GEN): $(LOCALBIN)
|
||||||
|
test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
|
||||||
|
|
||||||
|
.PHONY: envtest
|
||||||
|
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
|
||||||
|
$(ENVTEST): $(LOCALBIN)
|
||||||
|
test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.17
|
||||||
|
|
||||||
|
.PHONY: operator-sdk
|
||||||
|
HAS_OPERATOR_SDK := $(shell which $(PROJECT_DIR)/bin/operator-sdk)
|
||||||
|
operator-sdk: # Download operator-sdk locally if necessary
|
||||||
|
@echo "+ $@"
|
||||||
|
ifndef HAS_OPERATOR_SDK
|
||||||
|
wget -O $(PROJECT_DIR)/bin/operator-sdk https://github.com/operator-framework/operator-sdk/releases/download/v${OPERATOR_SDK_VERSION}/operator-sdk_$(PLATFORM)_amd64
|
||||||
|
chmod +x $(PROJECT_DIR)/bin/operator-sdk
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Generate bundle manifests and metadata, then validate generated files.
|
||||||
|
.PHONY: bundle
|
||||||
|
bundle: manifests operator-sdk kustomize
|
||||||
|
bin/operator-sdk generate kustomize manifests -q
|
||||||
|
cd config/manager && $(KUSTOMIZE) edit set image controller=quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY):$(VERSION_TAG)
|
||||||
|
$(KUSTOMIZE) build config/manifests | bin/operator-sdk generate bundle $(BUNDLE_GEN_FLAGS)
|
||||||
|
bin/operator-sdk bundle validate ./bundle
|
||||||
|
|
||||||
|
# Build the bundle image.
|
||||||
|
.PHONY: bundle-build
|
||||||
|
bundle-build:
|
||||||
|
docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .
|
||||||
|
|
||||||
|
# Download kubebuilder
|
||||||
|
.PHONY: kubebuilder
|
||||||
|
kubebuilder:
|
||||||
|
mkdir -p ${ENVTEST_ASSETS_DIR}
|
||||||
|
test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.0/hack/setup-envtest.sh
|
||||||
|
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR);
|
||||||
|
|
||||||
|
# install cert-manager v1.5.1
|
||||||
|
install-cert-manager: kind-setup
|
||||||
|
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.yaml
|
||||||
|
|
||||||
|
uninstall-cert-manager: kind-setup
|
||||||
|
kubectl delete -f https://github.com/jetstack/cert-manager/releases/download/v1.5.1/cert-manager.yaml
|
||||||
|
|
||||||
|
# Deploy the operator locally along with webhook using helm charts
|
||||||
|
.PHONY: deploy-webhook
|
||||||
|
deploy-webhook: container-runtime-build-amd64
|
||||||
|
@echo "+ $@"
|
||||||
|
bin/helm upgrade jenkins chart/jenkins-operator --install --set-string operator.image=${IMAGE_NAME} --set webhook.enabled=true --set jenkins.enabled=false
|
||||||
|
|
||||||
|
# https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.6.1/#gov2-gov3-ansiblev1-helmv1-add-opm-and-catalog-build-makefile-targets
|
||||||
|
.PHONY: opm
|
||||||
|
OPM = ./bin/opm
|
||||||
|
opm:
|
||||||
|
ifeq (,$(wildcard $(OPM)))
|
||||||
|
ifeq (,$(shell which opm 2>/dev/null))
|
||||||
|
@{ \
|
||||||
|
set -e ;\
|
||||||
|
mkdir -p $(dir $(OPM)) ;\
|
||||||
|
curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\
|
||||||
|
chmod +x $(OPM) ;\
|
||||||
|
}
|
||||||
|
else
|
||||||
|
OPM = $(shell which opm)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
BUNDLE_IMGS ?= $(BUNDLE_IMG)
|
||||||
|
CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION) ifneq ($(origin CATALOG_BASE_IMG), undefined) FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) endif
|
||||||
|
.PHONY: catalog-build
|
||||||
|
catalog-build: opm
|
||||||
|
$(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)
|
||||||
|
|
||||||
|
.PHONY: catalog-push
|
||||||
|
catalog-push: ## Push the catalog image.
|
||||||
|
$(MAKE) docker-push IMG=$(CATALOG_IMG)
|
||||||
|
|
||||||
|
# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
|
||||||
|
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
|
||||||
|
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
|
||||||
|
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
|
||||||
|
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> than the export will fail)
|
||||||
|
# To properly provided solutions that supports more than one platform you should use this option.
|
||||||
|
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
|
||||||
|
.PHONY: docker-buildx
|
||||||
|
docker-buildx: test ## Build and push docker image for the manager for cross-platform support
|
||||||
|
# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
|
||||||
|
sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
|
||||||
|
- docker buildx create --name project-v3-builder
|
||||||
|
docker buildx use project-v3-builder
|
||||||
|
- docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross
|
||||||
|
- docker buildx rm project-v3-builder
|
||||||
|
rm Dockerfile.cross
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
domain: jenkins.io
|
||||||
|
layout: go.kubebuilder.io/v4
|
||||||
|
projectName: jenkins-operator
|
||||||
|
repo: github.com/jenkinsci/kubernetes-operator
|
||||||
|
resources:
|
||||||
|
- api:
|
||||||
|
crdVersion: v1
|
||||||
|
namespaced: true
|
||||||
|
# TODO(user): Uncomment the below line if this resource implements a controller, else delete it.
|
||||||
|
# controller: true
|
||||||
|
domain: jenkins.io
|
||||||
|
group: jenkins.io
|
||||||
|
kind: Jenkins
|
||||||
|
path: github.com/jenkinsci/kubernetes-operator/api/v1alpha2
|
||||||
|
version: v1alpha2
|
||||||
|
webhooks:
|
||||||
|
webhookVersion: v1
|
||||||
|
version: "3"
|
||||||
|
plugins:
|
||||||
|
manifests.sdk.operatorframework.io/v2: {}
|
||||||
|
scorecard.sdk.operatorframework.io/v2: {}
|
||||||
56
README.md
56
README.md
|
|
@ -1,11 +1,16 @@
|
||||||
# Jenkins Operator
|
# Jenkins Operator
|
||||||
|
|
||||||
[](https://github.com/jenkinsci/kubernetes-operator/releases/tag/v0.5.0)
|
[](https://github.com/jenkinsci/kubernetes-operator/releases/tag/v0.8.0)
|
||||||
[](https://travis-ci.org/jenkinsci/kubernetes-operator)
|
[](https://github.com/jenkinsci/kubernetes-operator/actions/workflows/auto-tests-e2e.yaml)
|
||||||
[](https://goreportcard.com/report/github.com/jenkinsci/kubernetes-operator)
|
[](https://goreportcard.com/report/github.com/jenkinsci/kubernetes-operator)
|
||||||
[](https://hub.docker.com/r/virtuslab/jenkins-operator/tags)
|
[](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?
|
## What's the Jenkins Operator?
|
||||||
|
|
||||||
|
|
@ -15,9 +20,9 @@ It has been built with Immutability and declarative Configuration as Code in min
|
||||||
|
|
||||||
## Preliminaries
|
## Preliminaries
|
||||||
|
|
||||||
Considering that this Operator is created for managing instances for Jenkins,
|
Considering that this Operator is created for managing instances for Jenkins,
|
||||||
it is important to understand what
|
it is important to understand what
|
||||||
- [Jenkins Pipelines](https://jenkins.io/doc/book/pipeline/) and
|
- [Jenkins Pipelines](https://jenkins.io/doc/book/pipeline/) and
|
||||||
- CasC ([Configuration as Code](https://github.com/jenkinsci/configuration-as-code-plugin)) are.
|
- CasC ([Configuration as Code](https://github.com/jenkinsci/configuration-as-code-plugin)) are.
|
||||||
|
|
||||||
Jenkins Pipelines use Scripts written in [Groovy](https://groovy-lang.org/) which aid in the CasC aspect of Jenkins.
|
Jenkins Pipelines use Scripts written in [Groovy](https://groovy-lang.org/) which aid in the CasC aspect of Jenkins.
|
||||||
|
|
@ -33,14 +38,13 @@ Jenkins uses [plugins](https://plugins.jenkins.io/) like CasC to extend it's sol
|
||||||
## Problem statement and goals
|
## Problem statement and goals
|
||||||
|
|
||||||
The main reason why we decided to implement the **Jenkins Operator** is the fact that we faced a lot of problems with standard Jenkins deployment.
|
The main reason why we decided to implement the **Jenkins Operator** is the fact that we faced a lot of problems with standard Jenkins deployment.
|
||||||
We want to make Jenkins more robust, suitable for dynamic and multi-tenant environments.
|
We want to make Jenkins more robust, suitable for dynamic and multi-tenant environments.
|
||||||
|
|
||||||
Some of the problems we want to solve:
|
Some of the problems we want to solve:
|
||||||
- [installing plugins with incompatible versions or security vulnerabilities](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/#install-plugins)
|
- [installing plugins with incompatible versions or security vulnerabilities](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customizing-jenkins/#install-plugins/)
|
||||||
- [better configuration as code](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/)
|
- [better configuration as code](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customizing-jenkins/)
|
||||||
- [security and hardening out of the box](https://jenkinsci.github.io/kubernetes-operator/docs/security/)
|
- [security and hardening out of the box](https://jenkinsci.github.io/kubernetes-operator/docs/security/)
|
||||||
- [make errors more visible for end users](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/diagnostics/)
|
- [make errors more visible for end users](https://jenkinsci.github.io/kubernetes-operator/docs/troubleshooting/)
|
||||||
- [backup and restore for jobs history](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/)
|
|
||||||
- orphaned jobs with no JNLP connection
|
- orphaned jobs with no JNLP connection
|
||||||
- handle graceful shutdown properly
|
- handle graceful shutdown properly
|
||||||
- proper end to end tests for Jenkins lifecycle
|
- proper end to end tests for Jenkins lifecycle
|
||||||
|
|
@ -50,27 +54,38 @@ Some of the problems we want to solve:
|
||||||
Go to [**our documentation website**](https://jenkinsci.github.io/kubernetes-operator/) for more information.
|
Go to [**our documentation website**](https://jenkinsci.github.io/kubernetes-operator/) for more information.
|
||||||
|
|
||||||
Selected content:
|
Selected content:
|
||||||
1. [Installation](https://jenkinsci.github.io/kubernetes-operator/docs/installation/)
|
1. [How it works](https://jenkinsci.github.io/kubernetes-operator/docs/how-it-works/)
|
||||||
2. [Getting Started](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/)
|
2. [Getting Started](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/)
|
||||||
3. [How it works](https://jenkinsci.github.io/kubernetes-operator/docs/how-it-works/)
|
3. [Security](https://jenkinsci.github.io/kubernetes-operator/docs/security/)
|
||||||
4. [Security](https://jenkinsci.github.io/kubernetes-operator/docs/security/)
|
4. [Troubleshooting](https://jenkinsci.github.io/kubernetes-operator/docs/troubleshooting/)
|
||||||
5. [Developer Guide](https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/)
|
5. [Developer Guide](https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/)
|
||||||
5. [Jenkins Custom Resource Definition scheme](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/scheme/)
|
6. [FAQ](https://jenkinsci.github.io/kubernetes-operator/docs/faq/)
|
||||||
|
7. [Jenkins Custom Resource Definition Schema](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/schema/)
|
||||||
|
|
||||||
## Common Issues and Workarounds
|
## Common Issues and Workarounds
|
||||||
|
|
||||||
- Multibranch Pipelines and Backup Issues: https://github.com/jenkinsci/kubernetes-operator/issues/104#issuecomment-554289768
|
- Multibranch Pipelines and Backup Issues: https://github.com/jenkinsci/kubernetes-operator/issues/104#issuecomment-554289768
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
Main channel of communication on topics related to Jenkins Operator is [Jenkins Operator Category](https://community.jenkins.io/c/contributing/jenkins-operator/20) on [Jenkins Community Discourse](https://community.jenkins.io/).
|
||||||
|
|
||||||
We have a dedicated channel called `#jenkins-operator` on [virtuslab-oss.slack.com](https://virtuslab-oss.slack.com)
|
Here you can ask questions about the project, discuss best practices on using it, and talk to other users of the Operator, contributors and project's maintainers.
|
||||||
Fill out ([Invite form](https://forms.gle/X3X8qA1XMirdBuEH7)) and come say hi !
|
|
||||||
|
|
||||||
Every Thursday we have a community call at 16:30 CET on [Google Meet](https://meet.google.com/rsf-nhte-gnq). Feel free to join, ask questions and have fun :)
|
We also have a [gitter](https://gitter.im/jenkinsci/kubernetes-operator)/[matrix](https://matrix.to/#/#jenkinsci_kubernetes-operator:gitter.im) channel, come to say hi!
|
||||||
|
|
||||||
|
## Snapshots between releases
|
||||||
|
|
||||||
|
We are trying our best to resolve issues quickly, but they have to wait to be released. If you can't wait for an official
|
||||||
|
docker image release and acknowledge the risk, you can use our unofficial images, which are built nightly.
|
||||||
|
|
||||||
|
You can find the project's Quay.io repository [here](https://quay.io/organization/jenkins-kubernetes-operator).
|
||||||
|
|
||||||
|
Look for the images with tag "{git-hash}", where {git-hash} is the hash of the master commit that interests you.
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
Feel free to file [issues](https://github.com/jenkinsci/kubernetes-operator/issues) or [pull requests](https://github.com/jenkinsci/kubernetes-operator/pulls).
|
Feel free to file [issues](https://github.com/jenkinsci/kubernetes-operator/issues) or [pull requests](https://github.com/jenkinsci/kubernetes-operator/pulls),
|
||||||
|
but please consult [CONTRIBUTING](https://github.com/jenkinsci/kubernetes-operator/blob/master/CONTRIBUTING.md) document beforehand.
|
||||||
|
|
||||||
Before any big pull request please consult the maintainers to ensure a common direction.
|
Before any big pull request please consult the maintainers to ensure a common direction.
|
||||||
|
|
||||||
|
|
@ -78,6 +93,7 @@ Before any big pull request please consult the maintainers to ensure a common di
|
||||||
|
|
||||||
- [Jenkins World 2019 Lisbon](assets/Jenkins_World_Lisbon_2019%20-Jenkins_Kubernetes_Operator.pdf)
|
- [Jenkins World 2019 Lisbon](assets/Jenkins_World_Lisbon_2019%20-Jenkins_Kubernetes_Operator.pdf)
|
||||||
- [Jenkins Online Meetup 2020](assets/Jenkins_Online_Meetup-Jenkins_Kubernetes_Operator.pdf)
|
- [Jenkins Online Meetup 2020](assets/Jenkins_Online_Meetup-Jenkins_Kubernetes_Operator.pdf)
|
||||||
|
- [Jenkins Online Meetup 2021](https://www.youtube.com/watch?v=BsYYVkophsk)
|
||||||
|
|
||||||
## About the authors
|
## About the authors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Jenkins Operator Roadmap
|
||||||
|
|
||||||
|
This document outlines the vision and technical roadmap for [jenkinsci/kubernetes-operator](https://github.com/jenkinsci/kubernetes-operator) project.
|
||||||
|
|
||||||
|
## Project Vision
|
||||||
|
|
||||||
|
With Jenkins Operator project we want to enable our community to run Jenkins in cloud-native environments. Also, support most of the public cloud providers (AWS, Azure, GCP) in terms of additional capabilities like backups, observability and cloud security.
|
||||||
|
|
||||||
|
With declarative configuration and full lifecycle management based on [Operator Framework](https://operatorframework.io/) this can become the de facto standard for running Jenkins on top of Kubernetes.
|
||||||
|
|
||||||
|
## Technical Roadmap
|
||||||
|
- Break down Jenkins Custom Resource into smaller parts, support multiple Custom Resource Definitions [#495](https://github.com/jenkinsci/kubernetes-operator/issues/495)
|
||||||
|
- Introduce more granular schema for configuring Jenkins
|
||||||
|
- Introduce independent reconciliation controllers
|
||||||
|
- Refactor e2e tests to support testing individual reconciliation controllers
|
||||||
|
- Migrate Jenkins instance from Pod to Deployment [#497](https://github.com/jenkinsci/kubernetes-operator/issues/497)
|
||||||
|
- Unblock easier integration with 3rd party systems e.g. sidecars injection
|
||||||
|
- Improve contribution process and establish governance model [#496](https://github.com/jenkinsci/kubernetes-operator/issues/496)
|
||||||
|
- Improve CONTRIBUTING.md
|
||||||
|
- Introduce architecture decision proposals process
|
||||||
|
- Introduce governance model
|
||||||
|
- Engage with community more
|
||||||
|
- After releasing Operator version with new API, gather feedback from users on where the Operator should go next
|
||||||
|
- Reference Architecture - Jenkins on Kubernetes
|
||||||
|
- Bridge the gap between Jenkins and Kubernetes
|
||||||
|
- https://www.jenkins.io/blog/2020/12/04/gsod-project-report/
|
||||||
|
|
||||||
|
|
||||||
|
## Have a Question?
|
||||||
|
|
||||||
|
In case of questions, feel free to create a thread on [Jenkins Operator Category](https://community.jenkins.io/c/contributing/jenkins-operator/20) of Jenkins Community Discourse or contact us directly.
|
||||||
19
SECURITY.md
19
SECURITY.md
|
|
@ -1,19 +0,0 @@
|
||||||
# Security Policy
|
|
||||||
|
|
||||||
The Jenkins project takes security seriously.
|
|
||||||
We make every possible effort to ensure users can adequately secure their automation infrastructure.
|
|
||||||
To that end, we work with Jenkins core and plugin developers, as well as security researchers, to fix security vulnerabilities in Jenkins in a timely manner, and to improve the security of Jenkins in general.
|
|
||||||
|
|
||||||
## Reporting Security Vulnerabilities
|
|
||||||
|
|
||||||
Please report security vulnerabilities in the Jenkins issue tracker under the [SECURITY project](https://issues.jenkins-ci.org/browse/SECURITY).
|
|
||||||
This project is configured in such a way that only the reporter and the security team can see the details.
|
|
||||||
By restricting access to this potentially sensitive information, we can work on a fix and deliver it before the method of attack becomes well-known.
|
|
||||||
|
|
||||||
If you are unable to report using our issue tracker, you can also send your report to the private Jenkins security team mailing list: `jenkinsci-cert@googlegroups.com`
|
|
||||||
|
|
||||||
The Jenkins security team will then file an issue on your behalf, and will work with the maintainers of the affected component(s) to get the issue resolved.
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
For further details about our scope, issue handling process, or disclosure process, see [Reporting Security Vulnerabilities on jenkins.io](https://jenkins.io/security/reporting/).
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
v0.5.0
|
v0.9.0-beta1
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Package v1alpha2 contains API Schema definitions for the jenkins.io v1alpha2 API group
|
// Package v1alpha2 contains API Schema definitions for the jenkins.io v1alpha2 API group
|
||||||
// +k8s:deepcopy-gen=package,register
|
// +k8s:deepcopy-gen=package,register
|
||||||
|
// +kubebuilder:object:generate=true
|
||||||
// +groupName=jenkins.io
|
// +groupName=jenkins.io
|
||||||
package v1alpha2
|
package v1alpha2
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// JenkinsSpec defines the desired state of the Jenkins.
|
// JenkinsSpec defines the desired state of Jenkins
|
||||||
// +k8s:openapi-gen=true
|
// +k8s:openapi-gen=true
|
||||||
type JenkinsSpec struct {
|
type JenkinsSpec struct {
|
||||||
// Master represents Jenkins master pod properties and Jenkins plugins.
|
// Master represents Jenkins master pod properties and Jenkins plugins.
|
||||||
|
|
@ -14,10 +14,18 @@ type JenkinsSpec struct {
|
||||||
Master JenkinsMaster `json:"master"`
|
Master JenkinsMaster `json:"master"`
|
||||||
|
|
||||||
// SeedJobs defines list of Jenkins Seed Job configurations
|
// SeedJobs defines list of Jenkins Seed Job configurations
|
||||||
// More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines
|
// More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/
|
||||||
// +optional
|
// +optional
|
||||||
SeedJobs []SeedJob `json:"seedJobs,omitempty"`
|
SeedJobs []SeedJob `json:"seedJobs,omitempty"`
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// +optional
|
||||||
|
SeedJobAgentImage string `json:"seedJobAgentImage,omitempty"`
|
||||||
|
|
||||||
|
// ValidateSecurityWarnings enables or disables validating potential security warnings in Jenkins plugins via admission webhooks.
|
||||||
|
//+optional
|
||||||
|
ValidateSecurityWarnings bool `json:"validateSecurityWarnings,omitempty"`
|
||||||
|
|
||||||
// Notifications defines list of a services which are used to inform about Jenkins status
|
// Notifications defines list of a services which are used to inform about Jenkins status
|
||||||
// Can be used to integrate chat services like Slack, Microsoft Teams or Mailgun
|
// Can be used to integrate chat services like Slack, Microsoft Teams or Mailgun
|
||||||
// +optional
|
// +optional
|
||||||
|
|
@ -38,12 +46,12 @@ type JenkinsSpec struct {
|
||||||
SlaveService Service `json:"slaveService,omitempty"`
|
SlaveService Service `json:"slaveService,omitempty"`
|
||||||
|
|
||||||
// Backup defines configuration of Jenkins backup
|
// Backup defines configuration of Jenkins backup
|
||||||
// More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/
|
// More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-backup-and-restore/
|
||||||
// +optional
|
// +optional
|
||||||
Backup Backup `json:"backup,omitempty"`
|
Backup Backup `json:"backup,omitempty"`
|
||||||
|
|
||||||
// Backup defines configuration of Jenkins backup restore
|
// Backup defines configuration of Jenkins backup restore
|
||||||
// More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/
|
// More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-backup-and-restore/
|
||||||
// +optional
|
// +optional
|
||||||
Restore Restore `json:"restore,omitempty"`
|
Restore Restore `json:"restore,omitempty"`
|
||||||
|
|
||||||
|
|
@ -264,14 +272,6 @@ type JenkinsMaster struct {
|
||||||
// +optional
|
// +optional
|
||||||
Annotations map[string]string `json:"annotations,omitempty"`
|
Annotations map[string]string `json:"annotations,omitempty"`
|
||||||
|
|
||||||
// Annotations is an unstructured key value map stored with a resource that may be
|
|
||||||
// set by external tools to store and retrieve arbitrary metadata. They are not
|
|
||||||
// queryable and should be preserved when modifying objects.
|
|
||||||
// More info: http://kubernetes.io/docs/user-guide/annotations
|
|
||||||
// Deprecated: will be removed in the future, please use Annotations(annotations)
|
|
||||||
// +optional
|
|
||||||
AnnotationsDeprecated map[string]string `json:"masterAnnotations,omitempty"`
|
|
||||||
|
|
||||||
// Map of string keys and values that can be used to organize and categorize
|
// Map of string keys and values that can be used to organize and categorize
|
||||||
// (scope and select) objects. May match selectors of replication controllers
|
// (scope and select) objects. May match selectors of replication controllers
|
||||||
// and services.
|
// and services.
|
||||||
|
|
@ -311,6 +311,7 @@ type JenkinsMaster struct {
|
||||||
// periodSeconds: 10
|
// periodSeconds: 10
|
||||||
// successThreshold: 1
|
// successThreshold: 1
|
||||||
// timeoutSeconds: 5
|
// timeoutSeconds: 5
|
||||||
|
// lifecycle: {}
|
||||||
// name: jenkins-master
|
// name: jenkins-master
|
||||||
// readinessProbe:
|
// readinessProbe:
|
||||||
// failureThreshold: 3
|
// failureThreshold: 3
|
||||||
|
|
@ -350,32 +351,55 @@ type JenkinsMaster struct {
|
||||||
// BasePlugins contains plugins required by operator
|
// BasePlugins contains plugins required by operator
|
||||||
// +optional
|
// +optional
|
||||||
// Defaults to :
|
// Defaults to :
|
||||||
// - name: kubernetes
|
|
||||||
// version: "1.28.6"
|
|
||||||
// - name: workflow-job
|
|
||||||
// version: "2.40"
|
|
||||||
// - name: workflow-aggregator
|
|
||||||
// version: "2.6"
|
|
||||||
// - name: git
|
|
||||||
// version: "4.5.0"
|
|
||||||
// - name: job-dsl
|
|
||||||
// version: "1.77"
|
|
||||||
// - name: configuration-as-code
|
// - name: configuration-as-code
|
||||||
// version: "1.46"
|
// version: "1625.v27444588cc3d"
|
||||||
|
// - name: git
|
||||||
|
// version: "5.0.0"
|
||||||
|
// - name: job-dsl
|
||||||
|
// version: "1.83"
|
||||||
|
// - name: kubernetes
|
||||||
|
// version: "3909.v1f2c633e8590"
|
||||||
// - name: kubernetes-credentials-provider
|
// - name: kubernetes-credentials-provider
|
||||||
// version: "0.15"
|
// version: "1.211.vc236a_f5a_2f3c"
|
||||||
|
// - name: workflow-aggregator
|
||||||
|
// version: "596.v8c21c963d92d"
|
||||||
|
// - name: workflow-job
|
||||||
|
// version: "1289.vd1c337fd5354"
|
||||||
BasePlugins []Plugin `json:"basePlugins,omitempty"`
|
BasePlugins []Plugin `json:"basePlugins,omitempty"`
|
||||||
|
|
||||||
// Plugins contains plugins required by user
|
// Plugins contains plugins required by user
|
||||||
// +optional
|
// +optional
|
||||||
Plugins []Plugin `json:"plugins,omitempty"`
|
Plugins []Plugin `json:"plugins,omitempty"`
|
||||||
|
|
||||||
|
// Allow to override jenkins-plugin-cli default behavior
|
||||||
|
// while downloading the plugin and dependencies
|
||||||
|
// see: https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options
|
||||||
|
// +optional
|
||||||
|
LatestPlugins *bool `json:"latestPlugins,omitempty"`
|
||||||
|
|
||||||
|
// Allow to skip installation of both BasePlugins and Plugins.
|
||||||
|
// Requires using a custom image which includes the BasePlugins.
|
||||||
|
// Defaults to false.
|
||||||
|
// +optional
|
||||||
|
SkipPlugins *bool `json:"skipPlugins,omitempty"`
|
||||||
|
|
||||||
// DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins
|
// DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins
|
||||||
DisableCSRFProtection bool `json:"disableCSRFProtection"`
|
DisableCSRFProtection bool `json:"disableCSRFProtection"`
|
||||||
|
|
||||||
// PriorityClassName for Jenkins master pod
|
// PriorityClassName for Jenkins master pod
|
||||||
// +optional
|
// +optional
|
||||||
PriorityClassName string `json:"priorityClassName,omitempty"`
|
PriorityClassName string `json:"priorityClassName,omitempty"`
|
||||||
|
|
||||||
|
// HostAliases for Jenkins master pod and SeedJob agent
|
||||||
|
// +optional
|
||||||
|
HostAliases []corev1.HostAlias `json:"hostAliases,omitempty"`
|
||||||
|
|
||||||
|
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||||
|
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||||
|
// Set this value longer than the expected cleanup time for your process.
|
||||||
|
// Defaults to 30 seconds.
|
||||||
|
// +optional
|
||||||
|
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service defines Kubernetes service attributes
|
// Service defines Kubernetes service attributes
|
||||||
|
|
@ -489,12 +513,13 @@ type JenkinsStatus struct {
|
||||||
AppliedGroovyScripts []AppliedGroovyScript `json:"appliedGroovyScripts,omitempty"`
|
AppliedGroovyScripts []AppliedGroovyScript `json:"appliedGroovyScripts,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
// +genclient
|
// +genclient
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
// Jenkins is the Schema for the jenkins API
|
// Jenkins is the Schema for the jenkins API
|
||||||
// +k8s:openapi-gen=true
|
// +k8s:openapi-gen=true
|
||||||
// +kubebuilder:subresource:status
|
|
||||||
type Jenkins struct {
|
type Jenkins struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
@ -506,9 +531,10 @@ type Jenkins struct {
|
||||||
Status JenkinsStatus `json:"status,omitempty"`
|
Status JenkinsStatus `json:"status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
||||||
// JenkinsList contains a list of Jenkins.
|
// JenkinsList contains a list of Jenkins
|
||||||
type JenkinsList struct {
|
type JenkinsList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ListMeta `json:"metadata,omitempty"`
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
|
@ -525,6 +551,7 @@ const (
|
||||||
BasicSSHCredentialType JenkinsCredentialType = "basicSSHUserPrivateKey"
|
BasicSSHCredentialType JenkinsCredentialType = "basicSSHUserPrivateKey"
|
||||||
// UsernamePasswordCredentialType define username & password Jenkins credential type
|
// UsernamePasswordCredentialType define username & password Jenkins credential type
|
||||||
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
|
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
|
||||||
|
GithubAppCredentialType JenkinsCredentialType = "githubApp"
|
||||||
// ExternalCredentialType defines other credential type
|
// ExternalCredentialType defines other credential type
|
||||||
ExternalCredentialType JenkinsCredentialType = "external"
|
ExternalCredentialType JenkinsCredentialType = "external"
|
||||||
)
|
)
|
||||||
|
|
@ -534,6 +561,7 @@ var AllowedJenkinsCredentialMap = map[string]string{
|
||||||
string(NoJenkinsCredentialCredentialType): "",
|
string(NoJenkinsCredentialCredentialType): "",
|
||||||
string(BasicSSHCredentialType): "",
|
string(BasicSSHCredentialType): "",
|
||||||
string(UsernamePasswordCredentialType): "",
|
string(UsernamePasswordCredentialType): "",
|
||||||
|
string(GithubAppCredentialType): "",
|
||||||
string(ExternalCredentialType): "",
|
string(ExternalCredentialType): "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package v1alpha2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||||
|
"github.com/jenkinsci/kubernetes-operator/pkg/plugins"
|
||||||
|
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
|
||||||
|
SecValidator = *NewSecurityValidator()
|
||||||
|
_ webhook.Validator = &Jenkins{}
|
||||||
|
initialSecurityWarningsDownloadSucceded = false
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Hosturl = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip"
|
||||||
|
PluginDataFileCompressedPath = "/tmp/plugins.json.gzip"
|
||||||
|
PluginDataFile = "/tmp/plugins.json"
|
||||||
|
shortenedCheckingPeriod = 1 * time.Hour
|
||||||
|
defaultCheckingPeriod = 12 * time.Minute
|
||||||
|
)
|
||||||
|
|
||||||
|
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
|
||||||
|
return ctrl.NewWebhookManagedBy(mgr).
|
||||||
|
For(in).
|
||||||
|
Complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
|
||||||
|
// +kubebuilder:webhook:path=/validate-jenkins-io-jenkins-io-v1alpha2-jenkins,mutating=false,failurePolicy=fail,sideEffects=None,groups=jenkins.io.jenkins.io,resources=jenkins,verbs=create;update,versions=v1alpha2,name=vjenkins.kb.io,admissionReviewVersions={v1}
|
||||||
|
|
||||||
|
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
|
||||||
|
func (in *Jenkins) ValidateCreate() (admission.Warnings, error) {
|
||||||
|
if in.Spec.ValidateSecurityWarnings {
|
||||||
|
jenkinslog.Info("validate create", "name", in.Name)
|
||||||
|
err := Validate(*in)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
|
||||||
|
func (in *Jenkins) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
|
||||||
|
if in.Spec.ValidateSecurityWarnings {
|
||||||
|
jenkinslog.Info("validate update", "name", in.Name)
|
||||||
|
return nil, Validate(*in)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *Jenkins) ValidateDelete() (admission.Warnings, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecurityValidator struct {
|
||||||
|
PluginDataCache PluginsInfo
|
||||||
|
isCached bool
|
||||||
|
Attempts int
|
||||||
|
checkingPeriod time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginsInfo struct {
|
||||||
|
Plugins []PluginInfo `json:"plugins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
SecurityWarnings []Warning `json:"securityWarnings"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Warning struct {
|
||||||
|
Versions []Version `json:"versions"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Version struct {
|
||||||
|
FirstVersion string `json:"firstVersion"`
|
||||||
|
LastVersion string `json:"lastVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginData struct {
|
||||||
|
Version string
|
||||||
|
Kind string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates security warnings for both updating and creating a Jenkins CR
|
||||||
|
func Validate(r Jenkins) error {
|
||||||
|
if !SecValidator.isCached {
|
||||||
|
return errors.New("plugins data has not been fetched")
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginSet := make(map[string]PluginData)
|
||||||
|
var faultyBasePlugins string
|
||||||
|
var faultyUserPlugins string
|
||||||
|
basePlugins := plugins.BasePlugins()
|
||||||
|
|
||||||
|
for _, plugin := range basePlugins {
|
||||||
|
// Only Update the map if the plugin is not present or a lower version is being used
|
||||||
|
if pluginData, ispresent := pluginSet[plugin.Name]; !ispresent || semver.Compare(makeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
|
||||||
|
pluginSet[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, plugin := range r.Spec.Master.Plugins {
|
||||||
|
if pluginData, ispresent := pluginSet[plugin.Name]; !ispresent || semver.Compare(makeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
|
||||||
|
pluginSet[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, plugin := range SecValidator.PluginDataCache.Plugins {
|
||||||
|
if pluginData, ispresent := pluginSet[plugin.Name]; ispresent {
|
||||||
|
var hasVulnerabilities bool
|
||||||
|
for _, warning := range plugin.SecurityWarnings {
|
||||||
|
for _, version := range warning.Versions {
|
||||||
|
firstVersion := version.FirstVersion
|
||||||
|
lastVersion := version.LastVersion
|
||||||
|
if len(firstVersion) == 0 {
|
||||||
|
firstVersion = "0" // setting default value in case of empty string
|
||||||
|
}
|
||||||
|
if len(lastVersion) == 0 {
|
||||||
|
lastVersion = pluginData.Version // setting default value in case of empty string
|
||||||
|
}
|
||||||
|
// checking if this warning applies to our version as well
|
||||||
|
if compareVersions(firstVersion, lastVersion, pluginData.Version) {
|
||||||
|
jenkinslog.Info("Security Vulnerability detected in "+pluginData.Kind+" "+plugin.Name+":"+pluginData.Version, "Warning message", warning.Message, "For more details,check security advisory", warning.URL)
|
||||||
|
hasVulnerabilities = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasVulnerabilities {
|
||||||
|
if pluginData.Kind == "base" {
|
||||||
|
faultyBasePlugins += "\n" + plugin.Name + ":" + pluginData.Version
|
||||||
|
} else {
|
||||||
|
faultyUserPlugins += "\n" + plugin.Name + ":" + pluginData.Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(faultyBasePlugins) > 0 || len(faultyUserPlugins) > 0 {
|
||||||
|
var errormsg string
|
||||||
|
if len(faultyBasePlugins) > 0 {
|
||||||
|
errormsg += "security vulnerabilities detected in the following base plugins: " + faultyBasePlugins
|
||||||
|
}
|
||||||
|
if len(faultyUserPlugins) > 0 {
|
||||||
|
errormsg += "security vulnerabilities detected in the following user-defined plugins: " + faultyUserPlugins
|
||||||
|
}
|
||||||
|
return errors.New(errormsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMonitor creates a new worker and instantiates all the data structures required
|
||||||
|
func NewSecurityValidator() *SecurityValidator {
|
||||||
|
return &SecurityValidator{
|
||||||
|
isCached: false,
|
||||||
|
Attempts: 0,
|
||||||
|
checkingPeriod: shortenedCheckingPeriod,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *SecurityValidator) MonitorSecurityWarnings(securityWarningsFetched chan bool) {
|
||||||
|
jenkinslog.Info("Security warnings check: enabled\n")
|
||||||
|
for {
|
||||||
|
in.checkForSecurityVulnerabilities(securityWarningsFetched)
|
||||||
|
<-time.After(in.checkingPeriod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *SecurityValidator) checkForSecurityVulnerabilities(securityWarningsFetched chan bool) {
|
||||||
|
err := in.fetchPluginData()
|
||||||
|
if err != nil {
|
||||||
|
jenkinslog.Info("Cache plugin data", "failed to fetch plugin data", err)
|
||||||
|
in.checkingPeriod = shortenedCheckingPeriod
|
||||||
|
return
|
||||||
|
}
|
||||||
|
in.isCached = true
|
||||||
|
in.checkingPeriod = defaultCheckingPeriod
|
||||||
|
|
||||||
|
// should only be executed once when the operator starts
|
||||||
|
if !initialSecurityWarningsDownloadSucceded {
|
||||||
|
securityWarningsFetched <- in.isCached
|
||||||
|
initialSecurityWarningsDownloadSucceded = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Downloads extracts and reads the JSON data in every 12 hours
|
||||||
|
func (in *SecurityValidator) fetchPluginData() error {
|
||||||
|
jenkinslog.Info("Initializing/Updating the plugin data cache")
|
||||||
|
var err error
|
||||||
|
for in.Attempts = 0; in.Attempts < 5; in.Attempts++ {
|
||||||
|
err = in.download()
|
||||||
|
if err != nil {
|
||||||
|
jenkinslog.V(log.VDebug).Info("Cache Plugin Data", "failed to download file", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for in.Attempts = 0; in.Attempts < 5; in.Attempts++ {
|
||||||
|
err = in.extract()
|
||||||
|
if err != nil {
|
||||||
|
jenkinslog.V(log.VDebug).Info("Cache Plugin Data", "failed to extract file", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for in.Attempts = 0; in.Attempts < 5; in.Attempts++ {
|
||||||
|
err = in.cache()
|
||||||
|
if err != nil {
|
||||||
|
jenkinslog.V(log.VDebug).Info("Cache Plugin Data", "failed to read plugin data file", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *SecurityValidator) download() error {
|
||||||
|
pluginDataFileCompressed, err := os.Create(PluginDataFileCompressedPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure pluginDataFileCompressed is closed
|
||||||
|
defer func() {
|
||||||
|
if err := pluginDataFileCompressed.Close(); err != nil {
|
||||||
|
jenkinslog.V(log.VDebug).Info("Failed to close SecurityValidator.download io", "error", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodGet, Hosturl, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
Client := http.Client{
|
||||||
|
Timeout: 1 * time.Minute,
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := Client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer httpResponseCloser(response)
|
||||||
|
|
||||||
|
_, err = io.Copy(pluginDataFileCompressed, response.Body)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in *SecurityValidator) extract() error {
|
||||||
|
reader, err := os.Open(PluginDataFileCompressedPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := reader.Close(); err != nil {
|
||||||
|
log.Log.Error(err, "failed to close SecurityValidator.extract.reader ")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
archive, err := gzip.NewReader(reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err := archive.Close(); err != nil {
|
||||||
|
log.Log.Error(err, "failed to close SecurityValidator.extract.archive ")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
writer, err := os.Create(PluginDataFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err := writer.Close(); err != nil {
|
||||||
|
log.Log.Error(err, "failed to close SecurityValidator.extract.writer")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = io.Copy(writer, archive)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads the JSON data into memory and stores it
|
||||||
|
func (in *SecurityValidator) cache() error {
|
||||||
|
jsonFile, err := os.Open(PluginDataFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := jsonFile.Close(); err != nil {
|
||||||
|
log.Log.Error(err, "failed to close SecurityValidator.cache.jsonFile")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
byteValue, err := io.ReadAll(jsonFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(byteValue, &in.PluginDataCache)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a semantic version that can be used for comparison, allowed versioning format vMAJOR.MINOR.PATCH or MAJOR.MINOR.PATCH
|
||||||
|
func makeSemanticVersion(version string) string {
|
||||||
|
if version[0] != 'v' {
|
||||||
|
version = "v" + version
|
||||||
|
}
|
||||||
|
return semver.Canonical(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare if the current version lies between first version and last version
|
||||||
|
func compareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
|
||||||
|
firstSemVer := makeSemanticVersion(firstVersion)
|
||||||
|
lastSemVer := makeSemanticVersion(lastVersion)
|
||||||
|
pluginSemVer := makeSemanticVersion(pluginVersion)
|
||||||
|
if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func httpResponseCloser(response *http.Response) {
|
||||||
|
if err := response.Body.Close(); err != nil {
|
||||||
|
log.Log.Error(err, "failed to close http response body")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
package v1alpha2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMakeSemanticVersion(t *testing.T) {
|
||||||
|
t.Run("only major version specified", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("1")
|
||||||
|
assert.Equal(t, got, "v1.0.0")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("major and minor version specified", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("1.2")
|
||||||
|
assert.Equal(t, got, "v1.2.0")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("major,minor and patch version specified", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("1.2.3")
|
||||||
|
assert.Equal(t, got, "v1.2.3")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("semantic versions begin with a leading v and no patch version", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("v2.5")
|
||||||
|
assert.Equal(t, got, "v2.5.0")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("semantic versions with prerelease versions", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("2.1.2-alpha.1")
|
||||||
|
assert.Equal(t, got, "v2.1.2-alpha.1")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("semantic versions with prerelease versions", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("0.11.2-9.c8b45b8bb173")
|
||||||
|
assert.Equal(t, got, "v0.11.2-9.c8b45b8bb173")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("semantic versions with build suffix", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("1.7.9+meta")
|
||||||
|
assert.Equal(t, got, "v1.7.9")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("invalid semantic version", func(t *testing.T) {
|
||||||
|
got := makeSemanticVersion("google-login-1.2")
|
||||||
|
assert.Equal(t, got, "")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareVersions(t *testing.T) {
|
||||||
|
t.Run("Plugin Version lies between first and last version", func(t *testing.T) {
|
||||||
|
got := compareVersions("1.2", "1.6", "1.4")
|
||||||
|
assert.Equal(t, got, true)
|
||||||
|
})
|
||||||
|
t.Run("Plugin Version is greater than the last version", func(t *testing.T) {
|
||||||
|
got := compareVersions("1", "2", "3")
|
||||||
|
assert.Equal(t, got, false)
|
||||||
|
})
|
||||||
|
t.Run("Plugin Version is less than the first version", func(t *testing.T) {
|
||||||
|
got := compareVersions("1.4", "2.5", "1.1")
|
||||||
|
assert.Equal(t, got, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Plugins Versions have prerelease version and it lies between first and last version", func(t *testing.T) {
|
||||||
|
got := compareVersions("1.2.1-alpha", "1.2.1", "1.2.1-beta")
|
||||||
|
assert.Equal(t, got, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Plugins Versions have prerelease version and it is greater than the last version", func(t *testing.T) {
|
||||||
|
got := compareVersions("v2.2.1-alpha", "v2.5.1-beta.1", "v2.5.1-beta.2")
|
||||||
|
assert.Equal(t, got, false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidate(t *testing.T) {
|
||||||
|
t.Run("Validating when plugins data file is not fetched", func(t *testing.T) {
|
||||||
|
userplugins := []Plugin{{Name: "script-security", Version: "1.77"}, {Name: "git-client", Version: "3.9"}, {Name: "git", Version: "4.8.1"}, {Name: "plain-credentials", Version: "1.7"}}
|
||||||
|
jenkinscr := *createJenkinsCR(userplugins, true)
|
||||||
|
_, got := jenkinscr.ValidateCreate()
|
||||||
|
assert.Equal(t, got, errors.New("plugins data has not been fetched"))
|
||||||
|
})
|
||||||
|
|
||||||
|
SecValidator.isCached = true
|
||||||
|
t.Run("Validating a Jenkins CR with plugins not having security warnings and validation is turned on", func(t *testing.T) {
|
||||||
|
SecValidator.PluginDataCache = PluginsInfo{Plugins: []PluginInfo{
|
||||||
|
{Name: "security-script"},
|
||||||
|
{Name: "git-client"},
|
||||||
|
{Name: "git"},
|
||||||
|
{Name: "google-login", SecurityWarnings: createSecurityWarnings("", "1.2")},
|
||||||
|
{Name: "sample-plugin", SecurityWarnings: createSecurityWarnings("", "0.8")},
|
||||||
|
{Name: "mailer"},
|
||||||
|
{Name: "plain-credentials"}}}
|
||||||
|
userplugins := []Plugin{{Name: "script-security", Version: "1.77"}, {Name: "git-client", Version: "3.9"}, {Name: "git", Version: "4.8.1"}, {Name: "plain-credentials", Version: "1.7"}}
|
||||||
|
jenkinscr := *createJenkinsCR(userplugins, true)
|
||||||
|
_, got := jenkinscr.ValidateCreate()
|
||||||
|
assert.Nil(t, got)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Validating a Jenkins CR with some of the plugins having security warnings and validation is turned on", func(t *testing.T) {
|
||||||
|
SecValidator.PluginDataCache = PluginsInfo{Plugins: []PluginInfo{
|
||||||
|
{Name: "security-script", SecurityWarnings: createSecurityWarnings("1.2", "2.2")},
|
||||||
|
{Name: "workflow-cps", SecurityWarnings: createSecurityWarnings("2.59", "")},
|
||||||
|
{Name: "git-client"},
|
||||||
|
{Name: "git"},
|
||||||
|
{Name: "sample-plugin", SecurityWarnings: createSecurityWarnings("0.8", "")},
|
||||||
|
{Name: "command-launcher", SecurityWarnings: createSecurityWarnings("1.2", "1.4")},
|
||||||
|
{Name: "plain-credentials"},
|
||||||
|
{Name: "google-login", SecurityWarnings: createSecurityWarnings("1.1", "1.3")},
|
||||||
|
{Name: "mailer", SecurityWarnings: createSecurityWarnings("1.0.3", "1.1.4")},
|
||||||
|
}}
|
||||||
|
userplugins := []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}}
|
||||||
|
jenkinscr := *createJenkinsCR(userplugins, true)
|
||||||
|
_, got := jenkinscr.ValidateCreate()
|
||||||
|
assert.Equal(t, got, errors.New("security vulnerabilities detected in the following user-defined plugins: \nworkflow-cps:2.59\ngoogle-login:1.2\nmailer:1.1"))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Updating a Jenkins CR with some of the plugins having security warnings and validation is turned on", func(t *testing.T) {
|
||||||
|
SecValidator.PluginDataCache = PluginsInfo{Plugins: []PluginInfo{
|
||||||
|
{Name: "handy-uri-templates-2-api", SecurityWarnings: createSecurityWarnings("2.1.8-1.0", "2.2.8-1.0")},
|
||||||
|
{Name: "workflow-cps", SecurityWarnings: createSecurityWarnings("2.59", "")},
|
||||||
|
{Name: "resource-disposer", SecurityWarnings: createSecurityWarnings("0.7", "1.2")},
|
||||||
|
{Name: "git"},
|
||||||
|
{Name: "jjwt-api"},
|
||||||
|
{Name: "blueocean-github-pipeline", SecurityWarnings: createSecurityWarnings("1.2.0-alpha-2", "1.2.0-beta-5")},
|
||||||
|
{Name: "command-launcher", SecurityWarnings: createSecurityWarnings("1.2", "1.4")},
|
||||||
|
{Name: "plain-credentials"},
|
||||||
|
{Name: "ghprb", SecurityWarnings: createSecurityWarnings("1.1", "1.43")},
|
||||||
|
{Name: "mailer", SecurityWarnings: createSecurityWarnings("1.0.3", "1.1.4")},
|
||||||
|
}}
|
||||||
|
|
||||||
|
userplugins := []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}}
|
||||||
|
oldjenkinscr := *createJenkinsCR(userplugins, true)
|
||||||
|
|
||||||
|
userplugins = []Plugin{{Name: "handy-uri-templates-2-api", Version: "2.1.8-1.0"}, {Name: "resource-disposer", Version: "0.8"}, {Name: "jjwt-api", Version: "0.11.2-9.c8b45b8bb173"}, {Name: "blueocean-github-pipeline", Version: "1.2.0-beta-3"}, {Name: "ghprb", Version: "1.39"}}
|
||||||
|
newjenkinscr := *createJenkinsCR(userplugins, true)
|
||||||
|
_, got := newjenkinscr.ValidateUpdate(&oldjenkinscr)
|
||||||
|
assert.Equal(t, got, errors.New("security vulnerabilities detected in the following user-defined plugins: \nhandy-uri-templates-2-api:2.1.8-1.0\nresource-disposer:0.8\nblueocean-github-pipeline:1.2.0-beta-3\nghprb:1.39"))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Validation is turned off", func(t *testing.T) {
|
||||||
|
userplugins := []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}}
|
||||||
|
jenkinscr := *createJenkinsCR(userplugins, false)
|
||||||
|
_, got := jenkinscr.ValidateCreate()
|
||||||
|
assert.Nil(t, got)
|
||||||
|
|
||||||
|
userplugins = []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}}
|
||||||
|
newjenkinscr := *createJenkinsCR(userplugins, false)
|
||||||
|
_, got = newjenkinscr.ValidateUpdate(&jenkinscr)
|
||||||
|
assert.Nil(t, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func createJenkinsCR(userPlugins []Plugin, validateSecurityWarnings bool) *Jenkins {
|
||||||
|
jenkins := &Jenkins{
|
||||||
|
TypeMeta: JenkinsTypeMeta(),
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "jenkins",
|
||||||
|
Namespace: "test",
|
||||||
|
},
|
||||||
|
Spec: JenkinsSpec{
|
||||||
|
Master: JenkinsMaster{
|
||||||
|
Plugins: userPlugins,
|
||||||
|
DisableCSRFProtection: false,
|
||||||
|
},
|
||||||
|
ValidateSecurityWarnings: validateSecurityWarnings,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return jenkins
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSecurityWarnings(firstVersion string, lastVersion string) []Warning {
|
||||||
|
return []Warning{{Versions: []Version{{FirstVersion: firstVersion, LastVersion: lastVersion}}, ID: "null", Message: "unit testing", URL: "null", Active: false}}
|
||||||
|
}
|
||||||
|
|
@ -15,11 +15,17 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// GroupVersion is group version used to register these objects
|
||||||
|
GroupVersion = schema.GroupVersion{Group: "jenkins.io", Version: "v1alpha2"}
|
||||||
|
|
||||||
// SchemeGroupVersion is group version used to register these objects
|
// SchemeGroupVersion is group version used to register these objects
|
||||||
SchemeGroupVersion = schema.GroupVersion{Group: "jenkins.io", Version: "v1alpha2"}
|
SchemeGroupVersion = schema.GroupVersion{Group: "jenkins.io", Version: "v1alpha2"}
|
||||||
|
|
||||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||||
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||||
|
|
||||||
|
// AddToScheme adds the types in this group-version to the given scheme.
|
||||||
|
AddToScheme = SchemeBuilder.AddToScheme
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetObjectKind returns Jenkins object kind
|
// GetObjectKind returns Jenkins object kind
|
||||||
|
|
@ -47,5 +53,4 @@ func JenkinsTypeMeta() metav1.TypeMeta {
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
SchemeBuilder.Register(&Jenkins{}, &JenkinsList{})
|
SchemeBuilder.Register(&Jenkins{}, &JenkinsList{})
|
||||||
SchemeBuilder.Register(&JenkinsImage{}, &JenkinsImageList{})
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,19 +1,34 @@
|
||||||
// +build !ignore_autogenerated
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
// Code generated by operator-sdk. DO NOT EDIT.
|
/*
|
||||||
|
Copyright 2021.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
package v1alpha2
|
package v1alpha2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
v1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
rbacv1 "k8s.io/api/rbac/v1"
|
"k8s.io/api/rbac/v1"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *AppliedGroovyScript) DeepCopyInto(out *AppliedGroovyScript) {
|
func (in *AppliedGroovyScript) DeepCopyInto(out *AppliedGroovyScript) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedGroovyScript.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedGroovyScript.
|
||||||
|
|
@ -30,7 +45,6 @@ func (in *AppliedGroovyScript) DeepCopy() *AppliedGroovyScript {
|
||||||
func (in *Backup) DeepCopyInto(out *Backup) {
|
func (in *Backup) DeepCopyInto(out *Backup) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Action.DeepCopyInto(&out.Action)
|
in.Action.DeepCopyInto(&out.Action)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backup.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backup.
|
||||||
|
|
@ -46,7 +60,6 @@ func (in *Backup) DeepCopy() *Backup {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ConfigMapRef) DeepCopyInto(out *ConfigMapRef) {
|
func (in *ConfigMapRef) DeepCopyInto(out *ConfigMapRef) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapRef.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapRef.
|
||||||
|
|
@ -63,7 +76,6 @@ func (in *ConfigMapRef) DeepCopy() *ConfigMapRef {
|
||||||
func (in *ConfigurationAsCode) DeepCopyInto(out *ConfigurationAsCode) {
|
func (in *ConfigurationAsCode) DeepCopyInto(out *ConfigurationAsCode) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Customization.DeepCopyInto(&out.Customization)
|
in.Customization.DeepCopyInto(&out.Customization)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationAsCode.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationAsCode.
|
||||||
|
|
@ -92,51 +104,50 @@ func (in *Container) DeepCopyInto(out *Container) {
|
||||||
}
|
}
|
||||||
if in.Ports != nil {
|
if in.Ports != nil {
|
||||||
in, out := &in.Ports, &out.Ports
|
in, out := &in.Ports, &out.Ports
|
||||||
*out = make([]v1.ContainerPort, len(*in))
|
*out = make([]corev1.ContainerPort, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
if in.EnvFrom != nil {
|
if in.EnvFrom != nil {
|
||||||
in, out := &in.EnvFrom, &out.EnvFrom
|
in, out := &in.EnvFrom, &out.EnvFrom
|
||||||
*out = make([]v1.EnvFromSource, len(*in))
|
*out = make([]corev1.EnvFromSource, len(*in))
|
||||||
for i := range *in {
|
for i := range *in {
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if in.Env != nil {
|
if in.Env != nil {
|
||||||
in, out := &in.Env, &out.Env
|
in, out := &in.Env, &out.Env
|
||||||
*out = make([]v1.EnvVar, len(*in))
|
*out = make([]corev1.EnvVar, len(*in))
|
||||||
for i := range *in {
|
for i := range *in {
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if in.VolumeMounts != nil {
|
if in.VolumeMounts != nil {
|
||||||
in, out := &in.VolumeMounts, &out.VolumeMounts
|
in, out := &in.VolumeMounts, &out.VolumeMounts
|
||||||
*out = make([]v1.VolumeMount, len(*in))
|
*out = make([]corev1.VolumeMount, len(*in))
|
||||||
for i := range *in {
|
for i := range *in {
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if in.LivenessProbe != nil {
|
if in.LivenessProbe != nil {
|
||||||
in, out := &in.LivenessProbe, &out.LivenessProbe
|
in, out := &in.LivenessProbe, &out.LivenessProbe
|
||||||
*out = new(v1.Probe)
|
*out = new(corev1.Probe)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.ReadinessProbe != nil {
|
if in.ReadinessProbe != nil {
|
||||||
in, out := &in.ReadinessProbe, &out.ReadinessProbe
|
in, out := &in.ReadinessProbe, &out.ReadinessProbe
|
||||||
*out = new(v1.Probe)
|
*out = new(corev1.Probe)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.Lifecycle != nil {
|
if in.Lifecycle != nil {
|
||||||
in, out := &in.Lifecycle, &out.Lifecycle
|
in, out := &in.Lifecycle, &out.Lifecycle
|
||||||
*out = new(v1.Lifecycle)
|
*out = new(corev1.Lifecycle)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.SecurityContext != nil {
|
if in.SecurityContext != nil {
|
||||||
in, out := &in.SecurityContext, &out.SecurityContext
|
in, out := &in.SecurityContext, &out.SecurityContext
|
||||||
*out = new(v1.SecurityContext)
|
*out = new(corev1.SecurityContext)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Container.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Container.
|
||||||
|
|
@ -158,7 +169,6 @@ func (in *Customization) DeepCopyInto(out *Customization) {
|
||||||
*out = make([]ConfigMapRef, len(*in))
|
*out = make([]ConfigMapRef, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Customization.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Customization.
|
||||||
|
|
@ -175,7 +185,6 @@ func (in *Customization) DeepCopy() *Customization {
|
||||||
func (in *GroovyScripts) DeepCopyInto(out *GroovyScripts) {
|
func (in *GroovyScripts) DeepCopyInto(out *GroovyScripts) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Customization.DeepCopyInto(&out.Customization)
|
in.Customization.DeepCopyInto(&out.Customization)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroovyScripts.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroovyScripts.
|
||||||
|
|
@ -193,10 +202,9 @@ func (in *Handler) DeepCopyInto(out *Handler) {
|
||||||
*out = *in
|
*out = *in
|
||||||
if in.Exec != nil {
|
if in.Exec != nil {
|
||||||
in, out := &in.Exec, &out.Exec
|
in, out := &in.Exec, &out.Exec
|
||||||
*out = new(v1.ExecAction)
|
*out = new(corev1.ExecAction)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Handler.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Handler.
|
||||||
|
|
@ -209,22 +217,6 @@ func (in *Handler) DeepCopy() *Handler {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *Image) DeepCopyInto(out *Image) {
|
|
||||||
*out = *in
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image.
|
|
||||||
func (in *Image) DeepCopy() *Image {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(Image)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Jenkins) DeepCopyInto(out *Jenkins) {
|
func (in *Jenkins) DeepCopyInto(out *Jenkins) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
@ -232,7 +224,6 @@ func (in *Jenkins) DeepCopyInto(out *Jenkins) {
|
||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
in.Spec.DeepCopyInto(&out.Spec)
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
in.Status.DeepCopyInto(&out.Status)
|
in.Status.DeepCopyInto(&out.Status)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Jenkins.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Jenkins.
|
||||||
|
|
@ -256,7 +247,6 @@ func (in *Jenkins) DeepCopyObject() runtime.Object {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *JenkinsAPISettings) DeepCopyInto(out *JenkinsAPISettings) {
|
func (in *JenkinsAPISettings) DeepCopyInto(out *JenkinsAPISettings) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsAPISettings.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsAPISettings.
|
||||||
|
|
@ -269,110 +259,6 @@ func (in *JenkinsAPISettings) DeepCopy() *JenkinsAPISettings {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *JenkinsImage) DeepCopyInto(out *JenkinsImage) {
|
|
||||||
*out = *in
|
|
||||||
out.TypeMeta = in.TypeMeta
|
|
||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
|
||||||
in.Spec.DeepCopyInto(&out.Spec)
|
|
||||||
in.Status.DeepCopyInto(&out.Status)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsImage.
|
|
||||||
func (in *JenkinsImage) DeepCopy() *JenkinsImage {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(JenkinsImage)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
|
||||||
func (in *JenkinsImage) DeepCopyObject() runtime.Object {
|
|
||||||
if c := in.DeepCopy(); c != nil {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *JenkinsImageList) DeepCopyInto(out *JenkinsImageList) {
|
|
||||||
*out = *in
|
|
||||||
out.TypeMeta = in.TypeMeta
|
|
||||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
|
||||||
if in.Items != nil {
|
|
||||||
in, out := &in.Items, &out.Items
|
|
||||||
*out = make([]JenkinsImage, len(*in))
|
|
||||||
for i := range *in {
|
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsImageList.
|
|
||||||
func (in *JenkinsImageList) DeepCopy() *JenkinsImageList {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(JenkinsImageList)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
|
||||||
func (in *JenkinsImageList) DeepCopyObject() runtime.Object {
|
|
||||||
if c := in.DeepCopy(); c != nil {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *JenkinsImageSpec) DeepCopyInto(out *JenkinsImageSpec) {
|
|
||||||
*out = *in
|
|
||||||
out.BaseImage = in.BaseImage
|
|
||||||
if in.Plugins != nil {
|
|
||||||
in, out := &in.Plugins, &out.Plugins
|
|
||||||
*out = make([]JenkinsPlugin, len(*in))
|
|
||||||
copy(*out, *in)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsImageSpec.
|
|
||||||
func (in *JenkinsImageSpec) DeepCopy() *JenkinsImageSpec {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(JenkinsImageSpec)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *JenkinsImageStatus) DeepCopyInto(out *JenkinsImageStatus) {
|
|
||||||
*out = *in
|
|
||||||
if in.InstalledPlugins != nil {
|
|
||||||
in, out := &in.InstalledPlugins, &out.InstalledPlugins
|
|
||||||
*out = make([]JenkinsPlugin, len(*in))
|
|
||||||
copy(*out, *in)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsImageStatus.
|
|
||||||
func (in *JenkinsImageStatus) DeepCopy() *JenkinsImageStatus {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(JenkinsImageStatus)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *JenkinsList) DeepCopyInto(out *JenkinsList) {
|
func (in *JenkinsList) DeepCopyInto(out *JenkinsList) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
@ -385,7 +271,6 @@ func (in *JenkinsList) DeepCopyInto(out *JenkinsList) {
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsList.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsList.
|
||||||
|
|
@ -416,13 +301,6 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
||||||
(*out)[key] = val
|
(*out)[key] = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if in.AnnotationsDeprecated != nil {
|
|
||||||
in, out := &in.AnnotationsDeprecated, &out.AnnotationsDeprecated
|
|
||||||
*out = make(map[string]string, len(*in))
|
|
||||||
for key, val := range *in {
|
|
||||||
(*out)[key] = val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if in.Labels != nil {
|
if in.Labels != nil {
|
||||||
in, out := &in.Labels, &out.Labels
|
in, out := &in.Labels, &out.Labels
|
||||||
*out = make(map[string]string, len(*in))
|
*out = make(map[string]string, len(*in))
|
||||||
|
|
@ -439,7 +317,7 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
||||||
}
|
}
|
||||||
if in.SecurityContext != nil {
|
if in.SecurityContext != nil {
|
||||||
in, out := &in.SecurityContext, &out.SecurityContext
|
in, out := &in.SecurityContext, &out.SecurityContext
|
||||||
*out = new(v1.PodSecurityContext)
|
*out = new(corev1.PodSecurityContext)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.Containers != nil {
|
if in.Containers != nil {
|
||||||
|
|
@ -451,19 +329,19 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
||||||
}
|
}
|
||||||
if in.ImagePullSecrets != nil {
|
if in.ImagePullSecrets != nil {
|
||||||
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
|
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
|
||||||
*out = make([]v1.LocalObjectReference, len(*in))
|
*out = make([]corev1.LocalObjectReference, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
if in.Volumes != nil {
|
if in.Volumes != nil {
|
||||||
in, out := &in.Volumes, &out.Volumes
|
in, out := &in.Volumes, &out.Volumes
|
||||||
*out = make([]v1.Volume, len(*in))
|
*out = make([]corev1.Volume, len(*in))
|
||||||
for i := range *in {
|
for i := range *in {
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if in.Tolerations != nil {
|
if in.Tolerations != nil {
|
||||||
in, out := &in.Tolerations, &out.Tolerations
|
in, out := &in.Tolerations, &out.Tolerations
|
||||||
*out = make([]v1.Toleration, len(*in))
|
*out = make([]corev1.Toleration, len(*in))
|
||||||
for i := range *in {
|
for i := range *in {
|
||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
|
|
@ -478,7 +356,28 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
|
||||||
*out = make([]Plugin, len(*in))
|
*out = make([]Plugin, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
return
|
if in.LatestPlugins != nil {
|
||||||
|
in, out := &in.LatestPlugins, &out.LatestPlugins
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.SkipPlugins != nil {
|
||||||
|
in, out := &in.SkipPlugins, &out.SkipPlugins
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.HostAliases != nil {
|
||||||
|
in, out := &in.HostAliases, &out.HostAliases
|
||||||
|
*out = make([]corev1.HostAlias, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.TerminationGracePeriodSeconds != nil {
|
||||||
|
in, out := &in.TerminationGracePeriodSeconds, &out.TerminationGracePeriodSeconds
|
||||||
|
*out = new(int64)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsMaster.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsMaster.
|
||||||
|
|
@ -491,22 +390,6 @@ func (in *JenkinsMaster) DeepCopy() *JenkinsMaster {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *JenkinsPlugin) DeepCopyInto(out *JenkinsPlugin) {
|
|
||||||
*out = *in
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsPlugin.
|
|
||||||
func (in *JenkinsPlugin) DeepCopy() *JenkinsPlugin {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(JenkinsPlugin)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
|
func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
@ -531,12 +414,11 @@ func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
|
||||||
in.ConfigurationAsCode.DeepCopyInto(&out.ConfigurationAsCode)
|
in.ConfigurationAsCode.DeepCopyInto(&out.ConfigurationAsCode)
|
||||||
if in.Roles != nil {
|
if in.Roles != nil {
|
||||||
in, out := &in.Roles, &out.Roles
|
in, out := &in.Roles, &out.Roles
|
||||||
*out = make([]rbacv1.RoleRef, len(*in))
|
*out = make([]v1.RoleRef, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
in.ServiceAccount.DeepCopyInto(&out.ServiceAccount)
|
in.ServiceAccount.DeepCopyInto(&out.ServiceAccount)
|
||||||
out.JenkinsAPISettings = in.JenkinsAPISettings
|
out.JenkinsAPISettings = in.JenkinsAPISettings
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsSpec.
|
||||||
|
|
@ -574,7 +456,6 @@ func (in *JenkinsStatus) DeepCopyInto(out *JenkinsStatus) {
|
||||||
*out = make([]AppliedGroovyScript, len(*in))
|
*out = make([]AppliedGroovyScript, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsStatus.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsStatus.
|
||||||
|
|
@ -591,7 +472,6 @@ func (in *JenkinsStatus) DeepCopy() *JenkinsStatus {
|
||||||
func (in *Mailgun) DeepCopyInto(out *Mailgun) {
|
func (in *Mailgun) DeepCopyInto(out *Mailgun) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.APIKeySecretKeySelector = in.APIKeySecretKeySelector
|
out.APIKeySecretKeySelector = in.APIKeySecretKeySelector
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mailgun.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mailgun.
|
||||||
|
|
@ -608,7 +488,6 @@ func (in *Mailgun) DeepCopy() *Mailgun {
|
||||||
func (in *MicrosoftTeams) DeepCopyInto(out *MicrosoftTeams) {
|
func (in *MicrosoftTeams) DeepCopyInto(out *MicrosoftTeams) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
|
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrosoftTeams.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrosoftTeams.
|
||||||
|
|
@ -644,7 +523,6 @@ func (in *Notification) DeepCopyInto(out *Notification) {
|
||||||
*out = new(SMTP)
|
*out = new(SMTP)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Notification.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Notification.
|
||||||
|
|
@ -660,7 +538,6 @@ func (in *Notification) DeepCopy() *Notification {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Plugin) DeepCopyInto(out *Plugin) {
|
func (in *Plugin) DeepCopyInto(out *Plugin) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin.
|
||||||
|
|
@ -673,12 +550,70 @@ func (in *Plugin) DeepCopy() *Plugin {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PluginData) DeepCopyInto(out *PluginData) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginData.
|
||||||
|
func (in *PluginData) DeepCopy() *PluginData {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PluginData)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PluginInfo) DeepCopyInto(out *PluginInfo) {
|
||||||
|
*out = *in
|
||||||
|
if in.SecurityWarnings != nil {
|
||||||
|
in, out := &in.SecurityWarnings, &out.SecurityWarnings
|
||||||
|
*out = make([]Warning, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginInfo.
|
||||||
|
func (in *PluginInfo) DeepCopy() *PluginInfo {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PluginInfo)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PluginsInfo) DeepCopyInto(out *PluginsInfo) {
|
||||||
|
*out = *in
|
||||||
|
if in.Plugins != nil {
|
||||||
|
in, out := &in.Plugins, &out.Plugins
|
||||||
|
*out = make([]PluginInfo, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginsInfo.
|
||||||
|
func (in *PluginsInfo) DeepCopy() *PluginsInfo {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PluginsInfo)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Restore) DeepCopyInto(out *Restore) {
|
func (in *Restore) DeepCopyInto(out *Restore) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Action.DeepCopyInto(&out.Action)
|
in.Action.DeepCopyInto(&out.Action)
|
||||||
in.GetLatestAction.DeepCopyInto(&out.GetLatestAction)
|
in.GetLatestAction.DeepCopyInto(&out.GetLatestAction)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Restore.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Restore.
|
||||||
|
|
@ -696,7 +631,6 @@ func (in *SMTP) DeepCopyInto(out *SMTP) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.UsernameSecretKeySelector = in.UsernameSecretKeySelector
|
out.UsernameSecretKeySelector = in.UsernameSecretKeySelector
|
||||||
out.PasswordSecretKeySelector = in.PasswordSecretKeySelector
|
out.PasswordSecretKeySelector = in.PasswordSecretKeySelector
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SMTP.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SMTP.
|
||||||
|
|
@ -713,7 +647,6 @@ func (in *SMTP) DeepCopy() *SMTP {
|
||||||
func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
|
func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.LocalObjectReference = in.LocalObjectReference
|
out.LocalObjectReference = in.LocalObjectReference
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector.
|
||||||
|
|
@ -729,7 +662,6 @@ func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *SecretRef) DeepCopyInto(out *SecretRef) {
|
func (in *SecretRef) DeepCopyInto(out *SecretRef) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef.
|
||||||
|
|
@ -742,10 +674,25 @@ func (in *SecretRef) DeepCopy() *SecretRef {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *SecurityValidator) DeepCopyInto(out *SecurityValidator) {
|
||||||
|
*out = *in
|
||||||
|
in.PluginDataCache.DeepCopyInto(&out.PluginDataCache)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityValidator.
|
||||||
|
func (in *SecurityValidator) DeepCopy() *SecurityValidator {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SecurityValidator)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *SeedJob) DeepCopyInto(out *SeedJob) {
|
func (in *SeedJob) DeepCopyInto(out *SeedJob) {
|
||||||
*out = *in
|
*out = *in
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedJob.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedJob.
|
||||||
|
|
@ -780,7 +727,6 @@ func (in *Service) DeepCopyInto(out *Service) {
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service.
|
||||||
|
|
@ -803,7 +749,6 @@ func (in *ServiceAccount) DeepCopyInto(out *ServiceAccount) {
|
||||||
(*out)[key] = val
|
(*out)[key] = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccount.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccount.
|
||||||
|
|
@ -820,7 +765,6 @@ func (in *ServiceAccount) DeepCopy() *ServiceAccount {
|
||||||
func (in *Slack) DeepCopyInto(out *Slack) {
|
func (in *Slack) DeepCopyInto(out *Slack) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
|
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Slack.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Slack.
|
||||||
|
|
@ -832,3 +776,38 @@ func (in *Slack) DeepCopy() *Slack {
|
||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Version) DeepCopyInto(out *Version) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Version.
|
||||||
|
func (in *Version) DeepCopy() *Version {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Version)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Warning) DeepCopyInto(out *Warning) {
|
||||||
|
*out = *in
|
||||||
|
if in.Versions != nil {
|
||||||
|
in, out := &in.Versions, &out.Versions
|
||||||
|
*out = make([]Version, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Warning.
|
||||||
|
func (in *Warning) DeepCopy() *Warning {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Warning)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
|
|
@ -1,11 +1,22 @@
|
||||||
FROM debian:buster-slim
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
LABEL maintainer="Jenkins Kubernetes Operator Community" \
|
||||||
|
org.opencontainers.image.authors="Jenkins Kubernetes Operator Community" \
|
||||||
|
org.opencontainers.image.title="backup-pvc" \
|
||||||
|
org.opencontainers.image.description="Jenkins Operator Backup img via pvc volume" \
|
||||||
|
org.opencontainers.image.url="quay.io/jenkins-kubernetes-operator/backup-pvc" \
|
||||||
|
org.opencontainers.image.source="https://github.com/jenkinsci/kubernetes-operator/tree/master/backup/pvc" \
|
||||||
|
org.opencontainers.image.base.name="debian:bookworm-slim"
|
||||||
|
|
||||||
ARG UID
|
ARG UID
|
||||||
ARG GID
|
ARG GID
|
||||||
|
|
||||||
ENV USER=user
|
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 \
|
adduser \
|
||||||
--disabled-password \
|
--disabled-password \
|
||||||
--gecos "" \
|
--gecos "" \
|
||||||
|
|
@ -13,9 +24,9 @@ RUN addgroup --gid "$GID" "$USER" && \
|
||||||
--uid "$UID" \
|
--uid "$UID" \
|
||||||
"$USER"
|
"$USER"
|
||||||
|
|
||||||
|
COPY bin/*.sh /home/user/bin/
|
||||||
|
RUN chmod -R a+rx /home/user
|
||||||
WORKDIR /home/user/bin
|
WORKDIR /home/user/bin
|
||||||
COPY bin .
|
|
||||||
RUN chmod +x *.sh
|
|
||||||
USER user
|
USER user
|
||||||
|
|
||||||
CMD ./run.sh
|
CMD ./run.sh
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@ include $(config)
|
||||||
PREFIX?=$(shell pwd)
|
PREFIX?=$(shell pwd)
|
||||||
|
|
||||||
VERSION := $(shell cat VERSION.txt)
|
VERSION := $(shell cat VERSION.txt)
|
||||||
|
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
GITCOMMIT := $(shell git rev-parse --short HEAD)
|
GITCOMMIT := $(shell git rev-parse --short HEAD)
|
||||||
GITBRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
GITBRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||||
GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
|
GITUNTRACKEDCHANGES := $(shell git status --porcelain --untracked-files=no)
|
||||||
GITIGNOREDBUTTRACKEDCHANGES := $(shell git ls-files -i --exclude-standard)
|
GITIGNOREDBUTTRACKEDCHANGES := $(shell git ls-files -i -o --exclude-standard)
|
||||||
ifneq ($(GITUNTRACKEDCHANGES),)
|
ifneq ($(GITUNTRACKEDCHANGES),)
|
||||||
GITCOMMIT := $(GITCOMMIT)-dirty
|
GITCOMMIT := $(GITCOMMIT)-dirty
|
||||||
endif
|
endif
|
||||||
|
|
@ -57,7 +58,7 @@ spring-clean: ## Cleanup git ignored files (interactive)
|
||||||
git clean -Xdi
|
git clean -Xdi
|
||||||
|
|
||||||
.PHONY: checkmake
|
.PHONY: checkmake
|
||||||
HAS_CHECKMAKE := $(shell which checkmake)
|
HAS_CHECKMAKE := $(shell command -v checkmake)
|
||||||
checkmake: ## Check this Makefile
|
checkmake: ## Check this Makefile
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
ifndef HAS_CHECKMAKE
|
ifndef HAS_CHECKMAKE
|
||||||
|
|
@ -67,12 +68,12 @@ endif
|
||||||
|
|
||||||
define e2e
|
define e2e
|
||||||
echo "\nRunning $(1) e2e test";
|
echo "\nRunning $(1) e2e test";
|
||||||
@e2e/$(1)/test.sh $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT)
|
@e2e/$(1)/test.sh quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
.PHONY: docker-e2e
|
.PHONY: docker-e2e
|
||||||
E2E_TESTS := $(shell ls e2e)
|
E2E_TESTS := $(shell ls e2e)
|
||||||
docker-e2e: docker-build ## Make e2e tests for docker image
|
docker-e2e: docker-build-e2e ## Make e2e tests for docker image
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(foreach TEST_NAME,$(E2E_TESTS), $(call e2e,$(TEST_NAME)))
|
$(foreach TEST_NAME,$(E2E_TESTS), $(call e2e,$(TEST_NAME)))
|
||||||
|
|
||||||
|
|
@ -80,10 +81,15 @@ docker-e2e: docker-build ## Make e2e tests for docker image
|
||||||
docker-login: ## Log in into the Docker repository
|
docker-login: ## Log in into the Docker repository
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
|
|
||||||
|
.PHONY: docker-build-e2e
|
||||||
|
docker-build-e2e: UID=1001
|
||||||
|
docker-build-e2e: GID=1001
|
||||||
|
docker-build-e2e: docker-build
|
||||||
|
|
||||||
.PHONY: docker-build
|
.PHONY: docker-build
|
||||||
docker-build: check-env ## Build the container
|
docker-build: check-env ## Build the container
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
docker build . --build-arg UID=$(UID) --build-arg GID=$(GID) -t $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) --file Dockerfile
|
docker build . --build-arg UID=$(UID) --build-arg GID=$(GID) -t quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT) --file Dockerfile
|
||||||
|
|
||||||
.PHONY: docker-images
|
.PHONY: docker-images
|
||||||
docker-images: ## List all local containers
|
docker-images: ## List all local containers
|
||||||
|
|
@ -93,25 +99,31 @@ docker-images: ## List all local containers
|
||||||
.PHONY: docker-push
|
.PHONY: docker-push
|
||||||
docker-push: docker-build ## Push the container
|
docker-push: docker-build ## Push the container
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
docker tag $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(BUILD_TAG)
|
docker tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT) quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(BUILD_TAG)
|
||||||
docker push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(BUILD_TAG)
|
docker push quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(BUILD_TAG)
|
||||||
|
|
||||||
.PHONY: docker-release-version
|
.PHONY: docker-release-version
|
||||||
docker-release-version: docker-build ## Release image with version tag (in addition to build tag)
|
docker-release-version: docker-build ## Release image with version tag (in addition to build tag)
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
docker tag $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(VERSION_TAG)
|
docker tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT) quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(VERSION_TAG)
|
||||||
docker push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(VERSION_TAG)
|
docker push quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(VERSION_TAG)
|
||||||
|
|
||||||
.PHONY: docker-release-latest
|
.PHONY: docker-release-latest
|
||||||
docker-release-latest: docker-build ## Release image with latest tags (in addition to build tag)
|
docker-release-latest: docker-build ## Release image with latest tags (in addition to build tag)
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
docker tag $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(LATEST_TAG)
|
docker tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT) quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(LATEST_TAG)
|
||||||
docker push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(LATEST_TAG)
|
docker push quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(LATEST_TAG)
|
||||||
|
|
||||||
.PHONY: docker-release
|
.PHONY: docker-release
|
||||||
docker-release: docker-release-version docker-release-latest ## Release image with version and latest tags (in addition to build tag)
|
docker-release: docker-release-version docker-release-latest ## Release image with version and latest tags (in addition to build tag)
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
|
|
||||||
|
.PHONY: backup-kind-load
|
||||||
|
backup-kind-load: docker-build ## Build and load backup img in kind with e2e-test tag
|
||||||
|
@echo "+ $@"
|
||||||
|
docker tag quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT) quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):e2e-test
|
||||||
|
kind load docker-image quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):e2e-test --name $(KIND_CLUSTER_NAME)
|
||||||
|
|
||||||
# if this session isn't interactive, then we don't want to allocate a
|
# if this session isn't interactive, then we don't want to allocate a
|
||||||
# TTY, which would fail, but if it is interactive, we do want to attach
|
# TTY, which would fail, but if it is interactive, we do want to attach
|
||||||
# so that the user can send e.g. ^C through.
|
# so that the user can send e.g. ^C through.
|
||||||
|
|
@ -121,20 +133,30 @@ ifeq ($(INTERACTIVE), 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: docker-run
|
.PHONY: docker-run
|
||||||
docker-run: docker-build ## Run the container in docker, you can use EXTRA_ARGS
|
docker-run: docker-build
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
docker run --rm -i $(DOCKER_FLAGS) \
|
docker run --rm -i $(DOCKER_FLAGS) \
|
||||||
$(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(ARGS)
|
quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(GITCOMMIT) $(ARGS)
|
||||||
|
|
||||||
|
.PHONY: sembump
|
||||||
|
HAS_SEMBUMP := $(shell which $(PROJECT_DIR)/bin/sembump)
|
||||||
|
sembump: # Download sembump locally if necessary
|
||||||
|
@echo "+ $@"
|
||||||
|
ifndef HAS_SEMBUMP
|
||||||
|
mkdir -p $(PROJECT_DIR)/bin
|
||||||
|
wget -O $(PROJECT_DIR)/bin/sembump https://github.com/justintout/sembump/releases/download/v0.1.0/sembump-linux-amd64
|
||||||
|
chmod +x $(PROJECT_DIR)/bin/sembump
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: bump-version
|
.PHONY: bump-version
|
||||||
BUMP := patch
|
BUMP := patch
|
||||||
bump-version: ## Bump the version in the version file. Set BUMP to [ patch | major | minor ]
|
bump-version: sembump ## Bump the version in the version file. Set BUMP to [ patch | major | minor ]
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
$(eval NEW_VERSION=$(shell sembump --kind $(BUMP) $(VERSION)))
|
$(eval NEW_VERSION=$(shell $(PROJECT_DIR)/bin/sembump --kind $(BUMP) $(VERSION)))
|
||||||
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
|
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
|
||||||
echo $(NEW_VERSION) > VERSION.txt
|
echo $(NEW_VERSION) > VERSION.txt
|
||||||
git add VERSION.txt
|
git add VERSION.txt
|
||||||
git commit -vaem "Bump backup PVC version to $(NEW_VERSION)"
|
git commit -avm "Bump backup PVC version to $(NEW_VERSION)"
|
||||||
|
|
||||||
.PHONY: tag
|
.PHONY: tag
|
||||||
tag: ## Create a new git tag to prepare to build a release
|
tag: ## Create a new git tag to prepare to build a release
|
||||||
|
|
@ -158,7 +180,7 @@ ifneq ($(GITUNTRACKEDCHANGES),)
|
||||||
endif
|
endif
|
||||||
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
|
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
|
||||||
@echo "Ignored but tracked files:"
|
@echo "Ignored but tracked files:"
|
||||||
@git ls-files -i --exclude-standard
|
@git ls-files -i -c --exclude-standard
|
||||||
@echo
|
@echo
|
||||||
endif
|
endif
|
||||||
@echo "Dependencies:"
|
@echo "Dependencies:"
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
v0.1.0
|
v0.4.3
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,67 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
source "$(dirname "$0")/utils.sh"
|
||||||
|
|
||||||
[[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1;
|
[[ ! $# -eq 1 ]] && _log "ERROR" "Usage: $0 BACKUP_NUMBER" && exit 1
|
||||||
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
|
[[ -z "${BACKUP_DIR}" ]] && _log "ERROR" "Required 'BACKUP_DIR' env not set" && exit 1
|
||||||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
[[ -z "${JENKINS_HOME}" ]] && _log "ERROR" "Required 'JENKINS_HOME' env not set" && exit 1
|
||||||
BACKUP_TMP_DIR=$(mktemp -d)
|
BACKUP_RETRY_COUNT=${BACKUP_RETRY_COUNT:-3}
|
||||||
|
BACKUP_RETRY_INTERVAL=${BACKUP_RETRY_INTERVAL:-60}
|
||||||
|
BACKUP_NUMBER=$1
|
||||||
|
TRAP_FILE="/tmp/_backup_${BACKUP_NUMBER}_is_running"
|
||||||
|
|
||||||
backup_number=$1
|
# --> Check if another backup process is running (operator restart/crash)
|
||||||
echo "Running backup"
|
for ((i=0; i<BACKUP_RETRY_COUNT; i++)); do
|
||||||
|
[[ ! -f "${TRAP_FILE}" ]] && _log "INFO" "[backup] no other backup process are running" && break
|
||||||
|
_log "INFO" "[backup] backup is already running. Waiting for ${BACKUP_RETRY_INTERVAL} seconds..."
|
||||||
|
sleep "${BACKUP_RETRY_INTERVAL}"
|
||||||
|
done
|
||||||
|
[[ -f "${TRAP_FILE}" ]] && { _log "ERROR" "[backup] backup is still running after waiting ${BACKUP_RETRY_COUNT} time ${BACKUP_RETRY_INTERVAL}s. Exiting."; exit 1; }
|
||||||
|
# --< Done
|
||||||
|
|
||||||
# config.xml in a job directory is a config file that shouldnt be backed up
|
_log "INFO" "[backup] running backup ${BACKUP_NUMBER}"
|
||||||
# config.xml in child directores is state that should. For example-
|
touch "${TRAP_FILE}"
|
||||||
|
# create temp dir on the same filesystem with a BACKUP_DIR to be able use atomic mv enstead of copy
|
||||||
|
BACKUP_TMP_DIR=$(mktemp -d --tmpdir="${BACKUP_DIR}")
|
||||||
|
|
||||||
|
_clean(){
|
||||||
|
test -d "${BACKUP_TMP_DIR}" && rm -fr "${BACKUP_TMP_DIR}"
|
||||||
|
test -f "${TRAP_FILE}" && rm -f "${TRAP_FILE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_trap(){
|
||||||
|
_clean
|
||||||
|
_log "ERROR" "[backup] something wrong happened, check the logs"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap '_trap' SIGQUIT SIGINT SIGTERM
|
||||||
|
|
||||||
|
# config.xml in a job directory is a config file that shouldn't be backed up
|
||||||
|
# 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/branches/myrepo/branches/master/config.xml should be retained while
|
||||||
# branches/myorg/config.xml should not
|
# 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 && \
|
tar --zstd -C "${JENKINS_HOME}" -cf "${BACKUP_TMP_DIR}/${BACKUP_NUMBER}.tar.zstd" \
|
||||||
mv ${BACKUP_TMP_DIR}/${backup_number}.tar.gz ${BACKUP_DIR}/${backup_number}.tar.gz
|
--exclude jobs/*/workspace* \
|
||||||
|
--no-wildcards-match-slash --anchored \
|
||||||
|
--ignore-failed-read \
|
||||||
|
--exclude jobs/*/config.xml -c jobs || ret=$?
|
||||||
|
|
||||||
[[ ! -s ${BACKUP_DIR}/${backup_number}.tar.gz ]] && echo "backup file '${BACKUP_DIR}/${backup_number}.tar.gz' is empty" && exit 1;
|
if [[ "$ret" -eq 0 ]]; then
|
||||||
|
_log "INFO" "[backup] backup ${BACKUP_NUMBER} was completed without warnings"
|
||||||
|
elif [[ "$ret" -eq 1 ]]; then
|
||||||
|
_log "INFO" "[backup] backup ${BACKUP_NUMBER} was completed with some warnings"
|
||||||
|
else
|
||||||
|
_log "ERROR" "[backup] backup ${BACKUP_NUMBER} failed with error code: $ret"
|
||||||
|
_clean
|
||||||
|
exit "$ret"
|
||||||
|
fi
|
||||||
|
|
||||||
echo Done
|
mv "${BACKUP_TMP_DIR}/${BACKUP_NUMBER}.tar.zstd" "${BACKUP_DIR}/${BACKUP_NUMBER}.tar.zstd"
|
||||||
|
|
||||||
|
_log "INFO" "[backup] cleaning ${BACKUP_TMP_DIR} and trap file ${TRAP_FILE}"
|
||||||
|
_clean
|
||||||
|
[[ ! -s ${BACKUP_DIR}/${BACKUP_NUMBER}.tar.zstd ]] && _log "ERROR" "[backup] file '${BACKUP_DIR}/${BACKUP_NUMBER}.tar.zstd' is empty" && exit 1
|
||||||
|
|
||||||
|
_log "INFO" "[backup] ${BACKUP_NUMBER} done"
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,39 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
source "$(dirname "$0")/utils.sh"
|
||||||
|
|
||||||
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1
|
is_backup_not_exist() {
|
||||||
|
local backup_dir="$1"
|
||||||
|
# Save the current value of 'set -e'
|
||||||
|
local previous_e
|
||||||
|
previous_e=$(set +e; :; echo $?)
|
||||||
|
# Temporarily turn off 'set -e'
|
||||||
|
set +e
|
||||||
|
# Run ls command to check if any files matching the pattern exist
|
||||||
|
ls "${backup_dir}"/*.tar.* 1> /dev/null 2>&1
|
||||||
|
# Store the exit status of the ls command
|
||||||
|
local ls_exit_status=$?
|
||||||
|
# Restore the previous value of 'set -e'
|
||||||
|
[ "$previous_e" = "0" ] && set -e
|
||||||
|
# Return true if ls command succeeded (no files found), otherwise return false
|
||||||
|
[ $ls_exit_status -ne 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
latest=$(find ${BACKUP_DIR} -name '*.tar.gz' -exec basename {} \; | sort -g | tail -n 1)
|
[[ -z "${BACKUP_DIR}" ]] && { _log "ERROR" "Required 'BACKUP_DIR' env not set"; exit 1; }
|
||||||
|
|
||||||
|
# Check if we have any backup
|
||||||
|
if is_backup_not_exist "${BACKUP_DIR}"; then
|
||||||
|
_log "No backups exist in ${BACKUP_DIR}"
|
||||||
|
echo "-1"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Search for all the tar.* inside the backup dir to support the migration between gzip vs zstd
|
||||||
|
latest=$(find "${BACKUP_DIR}"/*.tar.* -maxdepth 0 -exec basename {} \; | sort -g | tail -n 1)
|
||||||
|
|
||||||
if [[ "${latest}" == "" ]]; then
|
if [[ "${latest}" == "" ]]; then
|
||||||
|
_log "Could not get the latest backup."
|
||||||
echo "-1"
|
echo "-1"
|
||||||
else
|
else
|
||||||
echo "${latest%%.*}"
|
echo "${latest%%.*}"
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,57 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
source "$(dirname "$0")/utils.sh"
|
||||||
|
|
||||||
[[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1
|
[[ ! $# -eq 1 ]] && _log "ERROR" "Usage: $0 <backup number>" && exit 1
|
||||||
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
|
[[ -z "${BACKUP_DIR}" ]] && _log "ERROR" "Required 'BACKUP_DIR' env not set" && exit 1
|
||||||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
[[ -z "${JENKINS_HOME}" ]] && _log "ERROR" "Required 'JENKINS_HOME' env not set" && exit 1
|
||||||
|
BACKUP_NUMBER=$1
|
||||||
|
RESTORE_RETRY_COUNT=${RESTORE_RETRY_COUNT:-10}
|
||||||
|
RESTORE_RETRY_INTERVAL=${RESTORE_RETRY_INTERVAL:-10}
|
||||||
|
|
||||||
backup_number=$1
|
# --> Check if another restore process is running (operator restart/crash)
|
||||||
echo "Running restore backup"
|
TRAP_FILE="/tmp/_restore_${BACKUP_NUMBER}_is_running"
|
||||||
|
trap "rm -f ${TRAP_FILE}" SIGINT SIGTERM
|
||||||
|
|
||||||
tar -C ${JENKINS_HOME} -zxf "${BACKUP_DIR}/${backup_number}.tar.gz"
|
for ((i=0; i<RESTORE_RETRY_COUNT; i++)); do
|
||||||
|
[[ ! -f "${TRAP_FILE}" ]] && _log "INFO" "[restore] no other process are running, restoring" && break
|
||||||
|
_log "INFO" "[restore] is already running. Waiting for ${RESTORE_RETRY_INTERVAL} seconds..."
|
||||||
|
sleep "${RESTORE_RETRY_INTERVAL}"
|
||||||
|
done
|
||||||
|
[[ -f "${TRAP_FILE}" ]] && { _log "ERROR" "[restore] is still running after waiting ${RESTORE_RETRY_COUNT} time ${RESTORE_RETRY_INTERVAL}s. Exiting."; exit 1; }
|
||||||
|
# --< Done
|
||||||
|
|
||||||
echo Done
|
_log "INFO" "[restore] restore backup with backup number #${BACKUP_NUMBER}"
|
||||||
exit 0
|
touch "${TRAP_FILE}"
|
||||||
|
BACKUP_FILE="${BACKUP_DIR}/${BACKUP_NUMBER}"
|
||||||
|
|
||||||
|
if [[ -f "$BACKUP_FILE.tar.gz" ]]; then
|
||||||
|
_log "INFO" "[restore] old format tar.gz found, restoring it"
|
||||||
|
OPTS=""
|
||||||
|
EXT="tar.gz"
|
||||||
|
elif [[ -f "$BACKUP_FILE.tar.zstd" ]]; then
|
||||||
|
_log "INFO" "[restore] Backup file found, proceeding"
|
||||||
|
OPTS="--zstd"
|
||||||
|
EXT="tar.zstd"
|
||||||
|
else
|
||||||
|
_log "ERROR" "[restore] backup file not found: $BACKUP_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tar $OPTS -C "${JENKINS_HOME}" -xf "${BACKUP_DIR}/${BACKUP_NUMBER}.${EXT}" || ret=$?
|
||||||
|
|
||||||
|
if [[ "$ret" -eq 0 ]]; then
|
||||||
|
_log "INFO" "[restore] restore ${BACKUP_NUMBER} was completed without warnings"
|
||||||
|
elif [[ "$ret" -eq 1 ]]; then
|
||||||
|
_log "INFO" "[restore] restore ${BACKUP_NUMBER} was completed with some warnings"
|
||||||
|
else
|
||||||
|
_log "ERROR" "[restore] restore ${BACKUP_NUMBER} failed with error code: $ret"
|
||||||
|
exit "$ret"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
_log "INFO" "[restore] deleting lock file ${TRAP_FILE}"
|
||||||
|
test -f "${TRAP_FILE}" && rm -f "${TRAP_FILE}"
|
||||||
|
_log "INFO" "[restore] restoring ${BACKUP_NUMBER} Done"
|
||||||
|
exit 0
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,72 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
source "$(dirname "$0")/utils.sh"
|
||||||
|
|
||||||
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
|
# Use 60 as default in case BACKUP_CLEANUP_INTERVAL did not set
|
||||||
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
|
BACKUP_CLEANUP_INTERVAL=${BACKUP_CLEANUP_INTERVAL:=60}
|
||||||
|
|
||||||
|
# Ensure required environment variables are set
|
||||||
|
check_env_var() {
|
||||||
|
if [[ -z "${!1}" ]]; then
|
||||||
|
_log "ERROR" "Required '$1' environment variable is not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_backup_not_exist() {
|
||||||
|
local backup_dir="$1"
|
||||||
|
# Save the current value of 'set -e'
|
||||||
|
local previous_e
|
||||||
|
previous_e=$(set +e; :; echo $?)
|
||||||
|
|
||||||
|
# Temporarily turn off 'set -e'
|
||||||
|
set +e
|
||||||
|
|
||||||
|
# Run ls command to check if any files matching the pattern exist
|
||||||
|
ls "${backup_dir}"/*.tar.* 1> /dev/null 2>&1
|
||||||
|
|
||||||
|
# Store the exit status of the ls command
|
||||||
|
local ls_exit_status=$?
|
||||||
|
|
||||||
|
# Restore the previous value of 'set -e'
|
||||||
|
[ "$previous_e" = "0" ] && set -e
|
||||||
|
|
||||||
|
# Return true if ls command succeeded (no files found), otherwise return false
|
||||||
|
[ $ls_exit_status -ne 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to find exceeding backups
|
||||||
|
find_exceeding_backups() {
|
||||||
|
local backup_dir="$1"
|
||||||
|
local backup_count="$2"
|
||||||
|
# Check if we have any backup
|
||||||
|
if is_backup_not_exist "${backup_dir}"; then
|
||||||
|
_log "ERROR" "[run] backups not found in ${backup_dir}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
find "${backup_dir}"/*.tar.zstd -maxdepth 0 -exec basename {} \; | sort -gr | tail -n +$((backup_count +1))
|
||||||
|
}
|
||||||
|
|
||||||
|
check_env_var "BACKUP_DIR"
|
||||||
|
check_env_var "JENKINS_HOME"
|
||||||
|
|
||||||
|
if [[ -z "${BACKUP_COUNT}" ]]; then
|
||||||
|
_log "WARNING" "[run] no BACKUP_COUNT set, it means you MUST delete old backups manually or by custom script"
|
||||||
|
else
|
||||||
|
_log "INFO" "[run] retaining only the ${BACKUP_COUNT} most recent backups, cleanup occurs every ${BACKUP_CLEANUP_INTERVAL} seconds"
|
||||||
|
fi
|
||||||
|
|
||||||
while true;
|
while true;
|
||||||
do
|
do
|
||||||
sleep 10
|
sleep "$BACKUP_CLEANUP_INTERVAL"
|
||||||
if [[ ! -z "${BACKUP_COUNT}" ]]; then
|
if [[ -n "${BACKUP_COUNT}" ]]; then
|
||||||
echo "Trimming to only ${BACKUP_COUNT} recent backups in preparation for new backup"
|
exceeding_backups=$(find_exceeding_backups "${BACKUP_DIR}" "${BACKUP_COUNT}")
|
||||||
find ${BACKUP_DIR} -name '*.tar.gz' -exec basename {} \; | sort -gr | tail -n +$((BACKUP_COUNT +1)) | xargs -I '{}' rm ${BACKUP_DIR}/'{}'
|
if [[ -n "$exceeding_backups" ]]; then
|
||||||
|
_log "INFO" "[run] removing backups: $(echo "$exceeding_backups" | tr '\n' ', ' | sed 's/,$//')"
|
||||||
|
echo "$exceeding_backups" | while read -r file; do
|
||||||
|
rm "${BACKUP_DIR}/${file}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Common utils
|
||||||
|
|
||||||
|
_log() {
|
||||||
|
local level="$1"
|
||||||
|
local message="$2"
|
||||||
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
if [[ "$level" =~ ^(ERROR|ERR|error|err)$ ]]; then
|
||||||
|
echo "${timestamp} - ${level} - ${message}" > /proc/1/fd/2
|
||||||
|
else
|
||||||
|
echo "${timestamp} - ${level} - ${message}" > /proc/1/fd/1
|
||||||
|
echo "${timestamp} - ${level} - ${message}" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
# Setup variables for the Makefile
|
# Setup variables for the Makefile
|
||||||
NAME=pvc
|
NAME=pvc
|
||||||
DOCKER_ORGANIZATION=virtuslab
|
QUAY_ORGANIZATION=jenkins-kubernetes-operator
|
||||||
DOCKER_REGISTRY=jenkins-operator-backup
|
QUAY_REGISTRY=backup
|
||||||
UID=1000
|
UID=1000
|
||||||
GID=1000
|
GID=1000
|
||||||
|
KIND_CLUSTER_NAME=jenkins
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${RESTORE_FOLDE
|
||||||
backup_number=1
|
backup_number=1
|
||||||
docker exec ${cid} /home/user/bin/backup.sh ${backup_number}
|
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;
|
[[ ! -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}"
|
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"
|
echo "Compare directories"
|
||||||
diff --brief --recursive "${RESTORE_FOLDER}" "${JENKINS_HOME_AFTER_RESTORE}"
|
diff --brief --recursive "${RESTORE_FOLDER}" "${JENKINS_HOME_AFTER_RESTORE}"
|
||||||
echo "Directories are the same"
|
echo "Directories are the same"
|
||||||
echo PASS
|
echo PASS
|
||||||
|
|
|
||||||
|
|
@ -19,17 +19,20 @@ mkdir -p ${BACKUP_DIR}
|
||||||
mkdir -p ${JENKINS_HOME}
|
mkdir -p ${JENKINS_HOME}
|
||||||
|
|
||||||
mkdir -p ${BACKUP_DIR}/lost+found
|
mkdir -p ${BACKUP_DIR}/lost+found
|
||||||
touch ${BACKUP_DIR}/1.tar.gz
|
touch ${BACKUP_DIR}/1.tar.zstd
|
||||||
touch ${BACKUP_DIR}/2.tar.gz
|
touch ${BACKUP_DIR}/2.tar.zstd
|
||||||
touch ${BACKUP_DIR}/3.tar.gz
|
touch ${BACKUP_DIR}/3.tar.zstd
|
||||||
touch ${BACKUP_DIR}/4.tar.gz
|
touch ${BACKUP_DIR}/4.tar.zstd
|
||||||
touch ${BACKUP_DIR}/5.tar.gz
|
touch ${BACKUP_DIR}/5.tar.zstd
|
||||||
touch ${BACKUP_DIR}/6.tar.gz
|
touch ${BACKUP_DIR}/6.tar.zstd
|
||||||
touch ${BACKUP_DIR}/7.tar.gz
|
touch ${BACKUP_DIR}/7.tar.zstd
|
||||||
touch ${BACKUP_DIR}/8.tar.gz
|
touch ${BACKUP_DIR}/8.tar.zstd
|
||||||
touch ${BACKUP_DIR}/9.tar.gz
|
touch ${BACKUP_DIR}/9.tar.zstd
|
||||||
touch ${BACKUP_DIR}/10.tar.gz
|
touch ${BACKUP_DIR}/10.tar.zstd
|
||||||
touch ${BACKUP_DIR}/11.tar.gz
|
touch ${BACKUP_DIR}/11.tar.zstd
|
||||||
|
# Emulate backup creation
|
||||||
|
BACKUP_TMP_DIR=$(mktemp -d --tmpdir="${BACKUP_DIR}")
|
||||||
|
touch ${BACKUP_TMP_DIR}/12.tar.zstd
|
||||||
|
|
||||||
# Create an instance of the container under testing
|
# 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})"
|
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})"
|
||||||
|
|
@ -38,10 +41,20 @@ echo "Docker container ID '${cid}'"
|
||||||
# Remove test directory and container afterwards
|
# Remove test directory and container afterwards
|
||||||
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
|
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
|
||||||
|
|
||||||
|
echo "Try to get latest against 11 backups and one in progress"
|
||||||
latest=$(docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/get-latest.sh")
|
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
|
||||||
|
echo "Try to get latest against one in progress"
|
||||||
empty_latest=$(docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/get-latest.sh")
|
empty_latest=$(docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/get-latest.sh")
|
||||||
|
|
||||||
|
rmdir ${BACKUP_DIR}/lost+found
|
||||||
|
rm ${BACKUP_TMP_DIR}/*.tar.zstd
|
||||||
|
rmdir ${BACKUP_TMP_DIR}
|
||||||
|
echo "Try to get latest against empty dir"
|
||||||
|
empty_dir_latest=$(docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/get-latest.sh")
|
||||||
|
|
||||||
|
|
||||||
if [[ "${DEBUG}" ]]; then
|
if [[ "${DEBUG}" ]]; then
|
||||||
docker logs ${cid}
|
docker logs ${cid}
|
||||||
ls -la ${BACKUP_DIR}
|
ls -la ${BACKUP_DIR}
|
||||||
|
|
@ -55,5 +68,9 @@ if [[ ! "${empty_latest}" == "-1" ]]; then
|
||||||
echo "Latest backup number should be '-1' but is '${empty_latest}'"
|
echo "Latest backup number should be '-1' but is '${empty_latest}'"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ ! "${empty_dir_latest}" == "-1" ]]; then
|
||||||
|
echo "Latest backup number should be '-1' but is '${empty_dir_latest}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo PASS
|
echo PASS
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
|
echo "Running limit_backup_count e2e test..."
|
||||||
|
|
||||||
[[ "${DEBUG}" ]] && set -x
|
[[ "${DEBUG}" ]] && set -x
|
||||||
|
|
||||||
# set current working directory to the directory of the script
|
# set current working directory to the directory of the script
|
||||||
|
|
@ -19,28 +21,31 @@ mkdir -p ${BACKUP_DIR}
|
||||||
mkdir -p ${JENKINS_HOME}
|
mkdir -p ${JENKINS_HOME}
|
||||||
|
|
||||||
mkdir -p ${BACKUP_DIR}/lost+found
|
mkdir -p ${BACKUP_DIR}/lost+found
|
||||||
touch ${BACKUP_DIR}/1.tar.gz
|
touch ${BACKUP_DIR}/1.tar.zstd
|
||||||
touch ${BACKUP_DIR}/2.tar.gz
|
touch ${BACKUP_DIR}/2.tar.zstd
|
||||||
touch ${BACKUP_DIR}/3.tar.gz
|
touch ${BACKUP_DIR}/3.tar.zstd
|
||||||
touch ${BACKUP_DIR}/4.tar.gz
|
touch ${BACKUP_DIR}/4.tar.zstd
|
||||||
touch ${BACKUP_DIR}/5.tar.gz
|
touch ${BACKUP_DIR}/5.tar.zstd
|
||||||
touch ${BACKUP_DIR}/6.tar.gz
|
touch ${BACKUP_DIR}/6.tar.zstd
|
||||||
touch ${BACKUP_DIR}/7.tar.gz
|
touch ${BACKUP_DIR}/7.tar.zstd
|
||||||
touch ${BACKUP_DIR}/8.tar.gz
|
touch ${BACKUP_DIR}/8.tar.zstd
|
||||||
touch ${BACKUP_DIR}/9.tar.gz
|
touch ${BACKUP_DIR}/9.tar.zstd
|
||||||
touch ${BACKUP_DIR}/10.tar.gz
|
touch ${BACKUP_DIR}/10.tar.zstd
|
||||||
touch ${BACKUP_DIR}/11.tar.gz
|
touch ${BACKUP_DIR}/11.tar.zstd
|
||||||
|
# Emulate backup creation
|
||||||
|
BACKUP_TMP_DIR=$(mktemp -d --tmpdir="${BACKUP_DIR}")
|
||||||
|
touch ${BACKUP_TMP_DIR}/12.tar.zstd
|
||||||
|
|
||||||
# Create an instance of the container under testing
|
# 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})"
|
cid="$(docker run -e BACKUP_CLEANUP_INTERVAL=1 -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})"
|
||||||
echo "Docker container ID '${cid}'"
|
echo "Docker container ID '${cid}'"
|
||||||
|
|
||||||
# Remove test directory and container afterwards
|
# Remove test directory and container afterwards
|
||||||
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
|
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
|
||||||
|
|
||||||
sleep 11
|
sleep 2
|
||||||
touch ${BACKUP_DIR}/12.tar.gz
|
mv ${BACKUP_TMP_DIR}/12.tar.zstd ${BACKUP_DIR}/
|
||||||
sleep 11
|
sleep 2
|
||||||
|
|
||||||
if [[ "${DEBUG}" ]]; then
|
if [[ "${DEBUG}" ]]; then
|
||||||
docker logs ${cid}
|
docker logs ${cid}
|
||||||
|
|
@ -48,7 +53,7 @@ if [[ "${DEBUG}" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# only two latest backup should exists
|
# only two latest backup should exists
|
||||||
[[ $(ls -1 ${BACKUP_DIR} | grep 'tar.gz' | wc -l) -eq 2 ]] || exit 1
|
[[ $(ls -1 ${BACKUP_DIR} | grep 'tar.zstd' | wc -l) -eq 2 ]] || exit 1
|
||||||
[[ -f ${BACKUP_DIR}/11.tar.gz ]] || exit 2
|
[[ -f ${BACKUP_DIR}/11.tar.zstd ]] || exit 2
|
||||||
[[ -f ${BACKUP_DIR}/12.tar.gz ]] || exit 3
|
[[ -f ${BACKUP_DIR}/12.tar.zstd ]] || exit 3
|
||||||
echo PASS
|
echo PASS
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
|
echo "Running limit_backup_count_no_backups e2e test..."
|
||||||
|
|
||||||
[[ "${DEBUG}" ]] && set -x
|
[[ "${DEBUG}" ]] && set -x
|
||||||
|
|
||||||
# set current working directory to the directory of the script
|
# set current working directory to the directory of the script
|
||||||
|
|
@ -19,7 +21,7 @@ mkdir -p ${BACKUP_DIR}
|
||||||
mkdir -p ${JENKINS_HOME}
|
mkdir -p ${JENKINS_HOME}
|
||||||
|
|
||||||
# Create an instance of the container under testing
|
# 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})"
|
cid="$(docker run -e BACKUP_CLEANUP_INTERVAL=1 -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})"
|
||||||
echo "Docker container ID '${cid}'"
|
echo "Docker container ID '${cid}'"
|
||||||
|
|
||||||
# Remove test directory and container afterwards
|
# Remove test directory and container afterwards
|
||||||
|
|
@ -27,8 +29,16 @@ trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}
|
||||||
|
|
||||||
# container should be running
|
# container should be running
|
||||||
echo 'Checking if container is running'
|
echo 'Checking if container is running'
|
||||||
sleep 11
|
sleep 3
|
||||||
|
set +e
|
||||||
docker exec ${cid} echo
|
docker exec ${cid} echo
|
||||||
|
exit_code=$?
|
||||||
|
set -e
|
||||||
|
if [ $exit_code -ne 0 ]; then
|
||||||
|
echo "container terminated with following logs:"
|
||||||
|
docker logs "${cid}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo 'Container is running'
|
echo 'Container is running'
|
||||||
|
|
||||||
echo PASS
|
echo PASS
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
build.xml
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
build logs
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
2
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
echo "Running tmp_dir_clean_after_backup_creation e2e test..."
|
||||||
|
|
||||||
|
[[ "${DEBUG}" ]] && set -x
|
||||||
|
|
||||||
|
# set current working directory to the directory of the script
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
docker_image=$1
|
||||||
|
|
||||||
|
if ! docker inspect ${docker_image} &> /dev/null; then
|
||||||
|
echo "Image '${docker_image}' does not exists"
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
JENKINS_HOME="$(pwd)/jenkins_home"
|
||||||
|
BACKUP_DIR="$(pwd)/backup"
|
||||||
|
mkdir -p ${BACKUP_DIR}
|
||||||
|
|
||||||
|
# Create an instance of the container under testing
|
||||||
|
cid="$(docker run -e BACKUP_CLEANUP_INTERVAL=1 -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})"
|
||||||
|
echo "Docker container ID '${cid}'"
|
||||||
|
|
||||||
|
# Remove test directory and container afterwards
|
||||||
|
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR}" EXIT
|
||||||
|
|
||||||
|
backup_number=1
|
||||||
|
docker exec ${cid} /home/user/bin/backup.sh ${backup_number}
|
||||||
|
|
||||||
|
[ "$(docker exec ${cid} ls /tmp | grep 'tmp')" ] && echo "tmp directory not empty" && exit 1;
|
||||||
|
# We should also check backup directory, since after #1000 we create temp directory at backup filesystem
|
||||||
|
[ "$(docker exec ${cid} ls ${BACKUP_DIR} | grep 'tmp')" ] && echo "backup dir consists temp directory" && exit 1;
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
ARG GO_VERSION
|
|
||||||
|
|
||||||
# build stage
|
|
||||||
FROM golang:$GO_VERSION-alpine3.11 AS build-stage
|
|
||||||
ARG OPERATOR_SDK_VERSION
|
|
||||||
ENV GO111MODULE=on
|
|
||||||
RUN apk --no-cache add git curl make \
|
|
||||||
&& curl -L https://github.com/operator-framework/operator-sdk/releases/download/v$OPERATOR_SDK_VERSION/operator-sdk-v$OPERATOR_SDK_VERSION-x86_64-linux-gnu -o /usr/local/bin/operator-sdk \
|
|
||||||
&& chmod +x /usr/local/bin/operator-sdk
|
|
||||||
ADD . /kubernetes-operator
|
|
||||||
|
|
||||||
RUN cd /kubernetes-operator && make build
|
|
||||||
|
|
||||||
# run stage
|
|
||||||
FROM alpine:3.10
|
|
||||||
|
|
||||||
USER nobody
|
|
||||||
|
|
||||||
COPY --from=build-stage /kubernetes-operator/build/_output/bin/jenkins-operator /usr/local/bin/jenkins-operator
|
|
||||||
|
|
||||||
CMD [ "/usr/local/bin/jenkins-operator" ]
|
|
||||||
210
chart/index.yaml
210
chart/index.yaml
|
|
@ -1,6 +1,214 @@
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
entries:
|
entries:
|
||||||
jenkins-operator:
|
jenkins-operator:
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.9.0-beta1
|
||||||
|
created: "2025-04-06T21:25:18.36969916Z"
|
||||||
|
dependencies:
|
||||||
|
- condition: cert-manager.enabled
|
||||||
|
name: cert-manager
|
||||||
|
repository: https://charts.jetstack.io
|
||||||
|
version: 1.14.2
|
||||||
|
- condition: cert-manager.enabled
|
||||||
|
name: cert-manager-crds
|
||||||
|
repository: ""
|
||||||
|
version: 1.14.2
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: 78b0756202efbf6a05d5016a4358053a07c89c0f4a3f3f1fb447eaf7323df078
|
||||||
|
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.9.0-beta1.tgz
|
||||||
|
version: 0.9.0-beta1
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.8.1
|
||||||
|
created: "2024-07-05T15:26:01.708923805Z"
|
||||||
|
dependencies:
|
||||||
|
- condition: cert-manager.enabled
|
||||||
|
name: cert-manager
|
||||||
|
repository: https://charts.jetstack.io
|
||||||
|
version: 1.14.2
|
||||||
|
- condition: cert-manager.enabled
|
||||||
|
name: cert-manager-crds
|
||||||
|
repository: ""
|
||||||
|
version: 1.14.2
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: 82c061ff42bbf2dbcf942939ffbd5b63508c9d8490fc06672a474af1cad14a5d
|
||||||
|
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.1.tgz
|
||||||
|
version: 0.8.1
|
||||||
|
- 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"
|
||||||
|
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: 4855dc0c673a1b3b4cd7ee502029c3d995f243a9a7051ad03d29def7c48a7c11
|
||||||
|
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-v0.8.0-beta.tgz
|
||||||
|
version: v0.8.0-beta
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.7.1
|
||||||
|
created: "2022-06-22T15:47:45.014723169Z"
|
||||||
|
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: e4f72051328b0feae90f5445c58a8776941ffb900a5849de14780ec0e2ce6081
|
||||||
|
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.6.2.tgz
|
||||||
|
version: 0.6.2
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.7.1
|
||||||
|
created: "2022-06-22T11:26:06.518430865Z"
|
||||||
|
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: a52262394e66a1274cc9508f5013c4da13182317f12bf949a7c28e8916be3fb8
|
||||||
|
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.6.1.tgz
|
||||||
|
version: 0.6.1
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.7.0
|
||||||
|
created: "2021-12-08T14:21:18.243261+01:00"
|
||||||
|
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: 6b36f47d6647231bd21581bea6b23c3660acb11073ebde2cb47f9a700101c462
|
||||||
|
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.6.0.tgz
|
||||||
|
version: 0.6.0
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.6.0
|
||||||
|
created: "2021-08-11T15:40:10.659538+02:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: e79615d988cc0c0bb64996394268ff87d232797b72ab9ad9a7891e9999daee9f
|
||||||
|
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.5.3.tgz
|
||||||
|
version: 0.5.3
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.6.0
|
||||||
|
created: "2021-06-11T13:50:32.677639006+02:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: 48fbf15c3ffff7003623edcde0bec39dc37d0a62303f08066960d5fac799af90
|
||||||
|
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.5.2.tgz
|
||||||
|
version: 0.5.2
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.6.0
|
||||||
|
created: "2021-06-11T13:50:32.677639006+02:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: 6f92759aaa7baafe5fe3a07f237b2c31b6921ca20cba145ee168c8fdb331d294
|
||||||
|
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.5.1.tgz
|
||||||
|
version: 0.5.1
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.6.0
|
||||||
|
created: "2021-06-11T13:50:32.697552742+02:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: aae33e13b8fcab6957b8ded2a2ae08025db38e1d86bbec8f8d9595b9eb904df1
|
||||||
|
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.5.0.tgz
|
||||||
|
version: 0.5.0
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.5.0
|
||||||
|
created: "2021-02-19T12:36:08.931516+01:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: 7a63ffab918dc012e0231cb362f16fa33d61b6db37a70b00b8c08ceb8cc90768
|
||||||
|
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.4.3.tgz
|
||||||
|
version: 0.4.3
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.5.0
|
||||||
|
created: "2021-02-04T08:33:21.964999+01:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: f045e699339da7345a1b848c5a068ec932ee3da7dfccf8c1f62c4df67aca488e
|
||||||
|
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.4.2.tgz
|
||||||
|
version: 0.4.2
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.5.0
|
||||||
|
created: "2021-02-04T08:33:21.989979+01:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: ac45a506be78fe1b68547e9ab6423491740b57a59a3ef631313c94bd67db164d
|
||||||
|
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.4.1.tgz
|
||||||
|
version: 0.4.1
|
||||||
|
- apiVersion: v2
|
||||||
|
appVersion: 0.5.0
|
||||||
|
created: "2021-01-23T14:09:57.322319864+01:00"
|
||||||
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
digest: 88149b9fd3a53e0850ddf0628ba07d7637e95e3a616e780497c2b3a3bed8b88a
|
||||||
|
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.4.0.tgz
|
||||||
|
version: 0.4.0
|
||||||
- apiVersion: v2
|
- apiVersion: v2
|
||||||
appVersion: 0.4.0
|
appVersion: 0.4.0
|
||||||
created: "2020-07-19T17:26:48.811339047+02:00"
|
created: "2020-07-19T17:26:48.811339047+02:00"
|
||||||
|
|
@ -208,4 +416,4 @@ entries:
|
||||||
urls:
|
urls:
|
||||||
- https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.0.1.tgz
|
- https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.0.1.tgz
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
generated: "2020-06-18T11:48:46.181495+02:00"
|
generated: "2025-04-06T21:25:18.363088324Z"
|
||||||
|
|
|
||||||
|
|
@ -20,3 +20,7 @@
|
||||||
.idea/
|
.idea/
|
||||||
*.tmproj
|
*.tmproj
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
# Ignore packaged charts
|
||||||
|
jenkins-operator-*.tgz
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
dependencies:
|
||||||
|
- name: cert-manager
|
||||||
|
repository: https://charts.jetstack.io
|
||||||
|
version: v1.14.2
|
||||||
|
digest: sha256:5f6f7c115d7b96e8c8e85515e087a9379473fd3d5262198a9e25c1a84d4ff9bd
|
||||||
|
generated: "2024-02-15T23:08:28.352007672+01:00"
|
||||||
|
|
@ -1,6 +1,14 @@
|
||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: "0.4.0"
|
appVersion: "0.9.0-beta1"
|
||||||
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
name: jenkins-operator
|
name: jenkins-operator
|
||||||
version: 0.3.4
|
version: 0.9.0-beta1
|
||||||
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
|
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
|
||||||
|
dependencies:
|
||||||
|
- name: cert-manager
|
||||||
|
version: "1.14.2"
|
||||||
|
condition: cert-manager.enabled
|
||||||
|
repository: https://charts.jetstack.io
|
||||||
|
- name: cert-manager-crds
|
||||||
|
version: "1.14.2"
|
||||||
|
condition: cert-manager.enabled
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
# jenkins-operator
|
||||||
|
|
||||||
|
 
|
||||||
|
|
||||||
|
Kubernetes native operator which fully manages Jenkins on Kubernetes
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
| Repository | Name | Version |
|
||||||
|
|------------|------|---------|
|
||||||
|
| | cert-manager-crds | 1.14.2 |
|
||||||
|
| https://charts.jetstack.io | cert-manager | 1.14.2 |
|
||||||
|
|
||||||
|
## Values
|
||||||
|
|
||||||
|
| Key | Type | Default | Description |
|
||||||
|
|-----|------|---------|-------------|
|
||||||
|
| cert-manager.enabled | bool | `false` | |
|
||||||
|
| cert-manager.startupapicheck.enabled | bool | `false` | |
|
||||||
|
| jenkins.annotations | object | `{}` | |
|
||||||
|
| jenkins.apiVersion | string | `"jenkins.io/v1alpha2"` | |
|
||||||
|
| jenkins.authorizationStrategy | string | `"createUser"` | |
|
||||||
|
| jenkins.backup.backupCommand[0] | string | `"/home/user/bin/backup.sh"` | |
|
||||||
|
| jenkins.backup.containerName | string | `"backup"` | |
|
||||||
|
| jenkins.backup.enabled | bool | `true` | |
|
||||||
|
| jenkins.backup.env[0].name | string | `"BACKUP_DIR"` | |
|
||||||
|
| jenkins.backup.env[0].value | string | `"/backup"` | |
|
||||||
|
| jenkins.backup.env[1].name | string | `"JENKINS_HOME"` | |
|
||||||
|
| jenkins.backup.env[1].value | string | `"/jenkins-home"` | |
|
||||||
|
| jenkins.backup.env[2].name | string | `"BACKUP_COUNT"` | |
|
||||||
|
| jenkins.backup.env[2].value | string | `"3"` | |
|
||||||
|
| jenkins.backup.getLatestAction[0] | string | `"/home/user/bin/get-latest.sh"` | |
|
||||||
|
| jenkins.backup.image | string | `"quay.io/jenkins-kubernetes-operator/backup-pvc:v0.4.3"` | |
|
||||||
|
| jenkins.backup.interval | int | `30` | |
|
||||||
|
| jenkins.backup.makeBackupBeforePodDeletion | bool | `true` | |
|
||||||
|
| jenkins.backup.pvc.className | string | `""` | |
|
||||||
|
| jenkins.backup.pvc.enabled | bool | `true` | |
|
||||||
|
| jenkins.backup.pvc.size | string | `"5Gi"` | |
|
||||||
|
| jenkins.backup.resources.limits.cpu | string | `"1000m"` | |
|
||||||
|
| jenkins.backup.resources.limits.memory | string | `"2Gi"` | |
|
||||||
|
| jenkins.backup.resources.requests.cpu | string | `"100m"` | |
|
||||||
|
| jenkins.backup.resources.requests.memory | string | `"500Mi"` | |
|
||||||
|
| jenkins.backup.restoreCommand[0] | string | `"/home/user/bin/restore.sh"` | |
|
||||||
|
| jenkins.backup.volumeMounts[0].mountPath | string | `"/jenkins-home"` | |
|
||||||
|
| jenkins.backup.volumeMounts[0].name | string | `"jenkins-home"` | |
|
||||||
|
| jenkins.backup.volumeMounts[1].mountPath | string | `"/backup"` | |
|
||||||
|
| jenkins.backup.volumeMounts[1].name | string | `"backup"` | |
|
||||||
|
| jenkins.basePlugins | list | `[]` | |
|
||||||
|
| jenkins.configuration.configurationAsCode | list | `[]` | |
|
||||||
|
| jenkins.configuration.groovyScripts | list | `[]` | |
|
||||||
|
| jenkins.configuration.secretData | object | `{}` | |
|
||||||
|
| jenkins.configuration.secretRefName | string | `""` | |
|
||||||
|
| jenkins.disableCSRFProtection | bool | `false` | |
|
||||||
|
| jenkins.enabled | bool | `true` | |
|
||||||
|
| jenkins.env | list | `[]` | |
|
||||||
|
| jenkins.hostAliases | object | `{}` | |
|
||||||
|
| jenkins.image | string | `"jenkins/jenkins:2.492.3-lts"` | |
|
||||||
|
| jenkins.imagePullPolicy | string | `"Always"` | |
|
||||||
|
| jenkins.imagePullSecrets | list | `[]` | |
|
||||||
|
| jenkins.labels | object | `{}` | |
|
||||||
|
| jenkins.latestPlugins | bool | `true` | |
|
||||||
|
| jenkins.lifecycle | object | `{}` | |
|
||||||
|
| jenkins.livenessProbe.failureThreshold | int | `20` | |
|
||||||
|
| jenkins.livenessProbe.httpGet.path | string | `"/login"` | |
|
||||||
|
| jenkins.livenessProbe.httpGet.port | string | `"http"` | |
|
||||||
|
| jenkins.livenessProbe.httpGet.scheme | string | `"HTTP"` | |
|
||||||
|
| jenkins.livenessProbe.initialDelaySeconds | int | `100` | |
|
||||||
|
| jenkins.livenessProbe.periodSeconds | int | `10` | |
|
||||||
|
| jenkins.livenessProbe.successThreshold | int | `1` | |
|
||||||
|
| jenkins.livenessProbe.timeoutSeconds | int | `8` | |
|
||||||
|
| jenkins.name | string | `"jenkins"` | |
|
||||||
|
| jenkins.namespace | string | `"default"` | |
|
||||||
|
| jenkins.nodeSelector | object | `{}` | |
|
||||||
|
| jenkins.notifications | list | `[]` | |
|
||||||
|
| jenkins.plugins | list | `[]` | |
|
||||||
|
| jenkins.priorityClassName | string | `""` | |
|
||||||
|
| jenkins.readinessProbe.failureThreshold | int | `60` | |
|
||||||
|
| jenkins.readinessProbe.httpGet.path | string | `"/login"` | |
|
||||||
|
| jenkins.readinessProbe.httpGet.port | string | `"http"` | |
|
||||||
|
| jenkins.readinessProbe.httpGet.scheme | string | `"HTTP"` | |
|
||||||
|
| jenkins.readinessProbe.initialDelaySeconds | int | `120` | |
|
||||||
|
| jenkins.readinessProbe.periodSeconds | int | `10` | |
|
||||||
|
| jenkins.readinessProbe.successThreshold | int | `1` | |
|
||||||
|
| jenkins.readinessProbe.timeoutSeconds | int | `8` | |
|
||||||
|
| jenkins.resources.limits.cpu | string | `"1000m"` | |
|
||||||
|
| jenkins.resources.limits.memory | string | `"3Gi"` | |
|
||||||
|
| jenkins.resources.requests.cpu | string | `"250m"` | |
|
||||||
|
| jenkins.resources.requests.memory | string | `"500Mi"` | |
|
||||||
|
| jenkins.securityContext.fsGroup | int | `1000` | |
|
||||||
|
| jenkins.securityContext.runAsUser | int | `1000` | |
|
||||||
|
| jenkins.seedJobAgentImage | string | `""` | |
|
||||||
|
| jenkins.seedJobs | list | `[]` | |
|
||||||
|
| jenkins.serviceAccount.annotations | object | `{}` | |
|
||||||
|
| jenkins.skipPlugins | bool | `false` | |
|
||||||
|
| jenkins.terminationGracePeriodSeconds | int | `30` | |
|
||||||
|
| 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.9.0-beta1"` | |
|
||||||
|
| operator.imagePullPolicy | string | `"IfNotPresent"` | |
|
||||||
|
| operator.imagePullSecrets | list | `[]` | |
|
||||||
|
| operator.nameOverride | string | `""` | |
|
||||||
|
| operator.nodeSelector | object | `{}` | |
|
||||||
|
| operator.replicaCount | int | `1` | |
|
||||||
|
| operator.resources | object | `{}` | |
|
||||||
|
| operator.tolerations | list | `[]` | |
|
||||||
|
| webhook.certificate.duration | string | `"2160h"` | |
|
||||||
|
| webhook.certificate.name | string | `"webhook-certificate"` | |
|
||||||
|
| webhook.certificate.renewbefore | string | `"360h"` | |
|
||||||
|
| webhook.enabled | bool | `false` | |
|
||||||
|
|
||||||
|
----------------------------------------------
|
||||||
|
Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
apiVersion: v2
|
||||||
|
name: cert-manager-crds
|
||||||
|
version: "1.14.2"
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,47 +1,88 @@
|
||||||
|
{{ define "jenkins-operator.role" }}
|
||||||
|
{{ $namespace := . }}
|
||||||
---
|
---
|
||||||
kind: Role
|
kind: {{ if eq $namespace "" }}ClusterRole{{ else }}Role{{ end }}
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: jenkins-operator
|
name: jenkins-operator
|
||||||
|
{{- if ne $namespace "" }}
|
||||||
|
namespace: {{ $namespace }}
|
||||||
|
{{- end }}
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
- configmaps
|
|
||||||
- secrets
|
|
||||||
- serviceaccounts
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- update
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- apps
|
- apps
|
||||||
resources:
|
resources:
|
||||||
- deployments
|
|
||||||
- daemonsets
|
- daemonsets
|
||||||
|
- deployments
|
||||||
- replicasets
|
- replicasets
|
||||||
- statefulsets
|
- statefulsets
|
||||||
verbs:
|
verbs:
|
||||||
- '*'
|
- '*'
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- rbac.authorization.k8s.io
|
- apps
|
||||||
|
- jenkins-operator
|
||||||
resources:
|
resources:
|
||||||
- roles
|
- deployments/finalizers
|
||||||
- rolebindings
|
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
|
||||||
- update
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- build.openshift.io
|
||||||
|
resources:
|
||||||
|
- buildconfigs
|
||||||
|
- builds
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
- list
|
- list
|
||||||
- watch
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- pods/portforward
|
- configmaps
|
||||||
|
- secrets
|
||||||
|
- services
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- 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:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
|
|
@ -53,26 +94,40 @@ rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- pods
|
- pods/portforward
|
||||||
- pods/exec
|
|
||||||
verbs:
|
verbs:
|
||||||
- "*"
|
- create
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
- events
|
- serviceaccounts
|
||||||
verbs:
|
verbs:
|
||||||
- watch
|
|
||||||
- list
|
|
||||||
- create
|
- create
|
||||||
- patch
|
- get
|
||||||
|
- list
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- apps
|
- image.openshift.io
|
||||||
resourceNames:
|
|
||||||
- jenkins-operator
|
|
||||||
resources:
|
resources:
|
||||||
- deployments/finalizers
|
- imagestreams
|
||||||
verbs:
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- jenkins.io
|
||||||
|
resources:
|
||||||
|
- jenkins/finalizers
|
||||||
|
verbs:
|
||||||
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- jenkins.io
|
||||||
|
resources:
|
||||||
|
- jenkins/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- patch
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- jenkins.io
|
- jenkins.io
|
||||||
|
|
@ -81,23 +136,26 @@ rules:
|
||||||
verbs:
|
verbs:
|
||||||
- '*'
|
- '*'
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- rbac.authorization.k8s.io
|
||||||
resources:
|
resources:
|
||||||
- persistentvolumeclaims
|
- rolebindings
|
||||||
|
- roles
|
||||||
verbs:
|
verbs:
|
||||||
|
- create
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
|
- update
|
||||||
- watch
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- "route.openshift.io"
|
- "route.openshift.io"
|
||||||
resources:
|
resources:
|
||||||
- routes
|
- routes
|
||||||
verbs:
|
verbs:
|
||||||
|
- create
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- update
|
- update
|
||||||
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- "image.openshift.io"
|
- "image.openshift.io"
|
||||||
resources:
|
resources:
|
||||||
|
|
@ -115,3 +173,4 @@ rules:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
- watch
|
- watch
|
||||||
|
{{ end }}
|
||||||
|
|
@ -9,31 +9,45 @@ metadata:
|
||||||
{{- end }}
|
{{- end }}
|
||||||
spec:
|
spec:
|
||||||
configurationAsCode:
|
configurationAsCode:
|
||||||
configurations:
|
|
||||||
{{- range .Values.jenkins.configuration.configurationAsCode }}
|
|
||||||
- name: {{ .configMapName }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.jenkins.configuration.configurationAsCode }}
|
{{- if .Values.jenkins.configuration.configurationAsCode }}
|
||||||
|
configurations:
|
||||||
|
{{ range .Values.jenkins.configuration.configurationAsCode }}
|
||||||
|
- name: {{ .configMapName }}
|
||||||
|
{{- end }}
|
||||||
secret:
|
secret:
|
||||||
{{- if .Values.jenkins.configuration.secretRefName }}
|
{{- if .Values.jenkins.configuration.secretRefName }}
|
||||||
name: {{ .Values.jenkins.configuration.secretRefName }}
|
name: {{ .Values.jenkins.configuration.secretRefName }}
|
||||||
{{- else if .Values.jenkins.configuration.secretData }}
|
{{- else if .Values.jenkins.configuration.secretData }}
|
||||||
name: jenkins-{{ .Values.jenkins.name }}
|
name: jenkins-{{ .Values.jenkins.name }}
|
||||||
|
{{- else }}
|
||||||
|
name: ""
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- else }}
|
||||||
|
configurations: []
|
||||||
|
secret:
|
||||||
|
name: ""
|
||||||
{{- end }}
|
{{- end }}
|
||||||
groovyScripts:
|
groovyScripts:
|
||||||
configurations:
|
|
||||||
{{- range .Values.jenkins.configuration.groovyScripts }}
|
|
||||||
- name: {{ .configMapName }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.jenkins.configuration.groovyScripts }}
|
{{- if .Values.jenkins.configuration.groovyScripts }}
|
||||||
|
configurations:
|
||||||
|
{{- range .Values.jenkins.configuration.groovyScripts }}
|
||||||
|
- name: {{ .configMapName }}
|
||||||
|
{{- end }}
|
||||||
secret:
|
secret:
|
||||||
{{- if .Values.jenkins.configuration.secretRefName }}
|
{{- if .Values.jenkins.configuration.secretRefName }}
|
||||||
name: {{ .Values.jenkins.configuration.secretRefName }}
|
name: {{ .Values.jenkins.configuration.secretRefName }}
|
||||||
{{- else if .Values.jenkins.configuration.secretData }}
|
{{- else if .Values.jenkins.configuration.secretData }}
|
||||||
name: jenkins-{{ .Values.jenkins.name }}
|
name: jenkins-{{ .Values.jenkins.name }}
|
||||||
|
{{- else }}
|
||||||
|
name: ""
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- else }}
|
||||||
|
configurations: []
|
||||||
|
secret:
|
||||||
|
name: ""
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
jenkinsAPISettings:
|
||||||
|
authorizationStrategy: {{ .Values.jenkins.authorizationStrategy }}
|
||||||
{{- if .Values.jenkins.backup.enabled }}
|
{{- if .Values.jenkins.backup.enabled }}
|
||||||
backup:
|
backup:
|
||||||
containerName: {{ .Values.jenkins.backup.containerName }}
|
containerName: {{ .Values.jenkins.backup.containerName }}
|
||||||
|
|
@ -51,6 +65,13 @@ spec:
|
||||||
{{- with .Values.jenkins.backup.restoreCommand }}
|
{{- with .Values.jenkins.backup.restoreCommand }}
|
||||||
command: {{ toYaml . | nindent 8 }}
|
command: {{ toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.jenkins.backup.getLatestAction }}
|
||||||
|
getLatestAction:
|
||||||
|
exec:
|
||||||
|
{{- with .Values.jenkins.backup.getLatestAction }}
|
||||||
|
command: {{ toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
{{- if .Values.jenkins.backup.recoveryOnce }}
|
{{- if .Values.jenkins.backup.recoveryOnce }}
|
||||||
recoveryOnce: {{ .Values.jenkins.backup.recoveryOnce }}
|
recoveryOnce: {{ .Values.jenkins.backup.recoveryOnce }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
@ -64,10 +85,19 @@ spec:
|
||||||
{{- with .Values.jenkins.notifications }}
|
{{- with .Values.jenkins.notifications }}
|
||||||
notifications: {{ toYaml . | nindent 4 }}
|
notifications: {{ toYaml . | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- with .Values.jenkins.serviceAccount }}
|
||||||
|
serviceAccount: {{ toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
master:
|
master:
|
||||||
{{- with .Values.jenkins.labels }}
|
{{- with .Values.jenkins.labels }}
|
||||||
labels: {{ toYaml . | nindent 6 }}
|
labels: {{ toYaml . | nindent 6 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- with .Values.jenkins.nodeSelector }}
|
||||||
|
nodeSelector: {{ toYaml . | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.jenkins.tolerations }}
|
||||||
|
tolerations: {{ toYaml . | nindent 6 }}
|
||||||
|
{{- end }}
|
||||||
{{- with .Values.jenkins.annotations }}
|
{{- with .Values.jenkins.annotations }}
|
||||||
annotations: {{ toYaml . | nindent 6 }}
|
annotations: {{ toYaml . | nindent 6 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
@ -77,48 +107,47 @@ spec:
|
||||||
{{- with .Values.jenkins.plugins }}
|
{{- with .Values.jenkins.plugins }}
|
||||||
plugins: {{ toYaml . | nindent 4 }}
|
plugins: {{ toYaml . | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
latestPlugins: {{ .Values.jenkins.latestPlugins }}
|
||||||
|
{{- if .Values.jenkins.priorityClassName }}
|
||||||
priorityClassName: {{ .Values.jenkins.priorityClassName }}
|
priorityClassName: {{ .Values.jenkins.priorityClassName }}
|
||||||
|
{{- end }}
|
||||||
disableCSRFProtection: {{ .Values.jenkins.disableCSRFProtection }}
|
disableCSRFProtection: {{ .Values.jenkins.disableCSRFProtection }}
|
||||||
|
{{- with .Values.jenkins.hostAliases }}
|
||||||
|
hostAliases: {{ toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
skipPlugins: {{ .Values.jenkins.skipPlugins }}
|
||||||
|
{{- if .Values.jenkins.terminationGracePeriodSeconds }}
|
||||||
|
terminationGracePeriodSeconds: {{ .Values.jenkins.terminationGracePeriodSeconds }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
- name: jenkins-master
|
- name: jenkins-master
|
||||||
image: {{ .Values.jenkins.image }}
|
image: {{ .Values.jenkins.image }}
|
||||||
imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }}
|
imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }}
|
||||||
{{- with .Values.jenkins.imagePullSecrets }}
|
{{- with .Values.jenkins.livenessProbe }}
|
||||||
imagePullSecrets: {{ toYaml . | nindent 10 }}
|
livenessProbe: {{ toYaml . | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.jenkins.readinessProbe }}
|
||||||
|
readinessProbe: {{ toYaml . | nindent 10 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
livenessProbe:
|
|
||||||
failureThreshold: 12
|
|
||||||
httpGet:
|
|
||||||
path: /login
|
|
||||||
port: http
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 80
|
|
||||||
periodSeconds: 10
|
|
||||||
successThreshold: 1
|
|
||||||
timeoutSeconds: 5
|
|
||||||
readinessProbe:
|
|
||||||
failureThreshold: 3
|
|
||||||
httpGet:
|
|
||||||
path: /login
|
|
||||||
port: http
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 30
|
|
||||||
periodSeconds: 10
|
|
||||||
successThreshold: 1
|
|
||||||
timeoutSeconds: 1
|
|
||||||
{{- with .Values.jenkins.resources }}
|
{{- with .Values.jenkins.resources }}
|
||||||
resources: {{ toYaml . | nindent 10 }}
|
resources: {{ toYaml . | nindent 10 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- with .Values.jenkins.env }}
|
{{- with .Values.jenkins.env }}
|
||||||
env: {{- toYaml . | nindent 8 }}
|
env: {{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- with .Values.jenkins.lifecycle}}
|
||||||
|
lifecycle: {{ toYaml . | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
{{- with .Values.jenkins.volumeMounts }}
|
{{- with .Values.jenkins.volumeMounts }}
|
||||||
volumeMounts: {{- toYaml . | nindent 8 }}
|
volumeMounts: {{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .Values.jenkins.backup.enabled }}
|
{{- if .Values.jenkins.backup.enabled }}
|
||||||
- name: {{ .Values.jenkins.backup.containerName }}
|
- name: {{ .Values.jenkins.backup.containerName }}
|
||||||
image: {{ .Values.jenkins.backup.image }}
|
image: {{ .Values.jenkins.backup.image }}
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }}
|
||||||
|
{{- with .Values.jenkins.backup.resources }}
|
||||||
|
resources: {{ toYaml . | nindent 10 }}
|
||||||
|
{{- end }}
|
||||||
{{- with .Values.jenkins.backup.env }}
|
{{- with .Values.jenkins.backup.env }}
|
||||||
env: {{- toYaml . | nindent 8 }}
|
env: {{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
@ -129,11 +158,18 @@ spec:
|
||||||
{{- with .Values.jenkins.volumes }}
|
{{- with .Values.jenkins.volumes }}
|
||||||
volumes: {{- toYaml . | nindent 4 }}
|
volumes: {{- toYaml . | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- with .Values.jenkins.imagePullSecrets }}
|
||||||
|
imagePullSecrets: {{ toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
{{- with .Values.jenkins.securityContext}}
|
{{- with .Values.jenkins.securityContext}}
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml . | nindent 6 }}
|
{{- toYaml . | nindent 6 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
validateSecurityWarnings: {{ .Values.jenkins.validateSecurityWarnings }}
|
||||||
{{- with .Values.jenkins.seedJobs }}
|
{{- with .Values.jenkins.seedJobs }}
|
||||||
seedJobs: {{- toYaml . | nindent 4 }}
|
seedJobs: {{- toYaml . | nindent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.jenkins.seedJobAgentImage }}
|
||||||
|
seedJobAgentImage: {{ .Values.jenkins.seedJobAgentImage }}
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
# 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
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -30,13 +30,40 @@ spec:
|
||||||
containerPort: 80
|
containerPort: 80
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
command:
|
command:
|
||||||
- jenkins-operator
|
- /manager
|
||||||
args: []
|
args:
|
||||||
|
{{- if .Values.webhook.enabled }}
|
||||||
|
- --validate-security-warnings
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.webhook.enabled }}
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp/k8s-webhook-server/serving-certs
|
||||||
|
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:
|
env:
|
||||||
- name: WATCH_NAMESPACE
|
- name: WATCH_NAMESPACE
|
||||||
|
{{- if .Values.jenkins.enabled }}
|
||||||
|
value: {{ .Values.jenkins.namespace }}
|
||||||
|
{{- else if .Values.operator.watchNamespace }}
|
||||||
|
value: {{ .Values.operator.watchNamespace }}
|
||||||
|
{{- else }}
|
||||||
valueFrom:
|
valueFrom:
|
||||||
fieldRef:
|
fieldRef:
|
||||||
fieldPath: metadata.namespace
|
fieldPath: metadata.namespace
|
||||||
|
{{- end }}
|
||||||
- name: POD_NAME
|
- name: POD_NAME
|
||||||
valueFrom:
|
valueFrom:
|
||||||
fieldRef:
|
fieldRef:
|
||||||
|
|
@ -57,3 +84,11 @@ spec:
|
||||||
tolerations:
|
tolerations:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.webhook.enabled }}
|
||||||
|
volumes:
|
||||||
|
- name: webhook-certs
|
||||||
|
secret:
|
||||||
|
defaultMode: 420
|
||||||
|
secretName: jenkins-{{ .Values.webhook.certificate.name }}
|
||||||
|
terminationGracePeriodSeconds: 10
|
||||||
|
{{- end }}
|
||||||
|
|
|
||||||
|
|
@ -1,127 +1,15 @@
|
||||||
---
|
{{ if eq .Values.jenkins.namespace "" }}
|
||||||
kind: Role
|
{{- /*
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
# This is a special case when .Values.jenkins.namespace is equal to empty
|
||||||
metadata:
|
# string which leads to WATCH_NAMESPACE env of jenkins-operator to be set to
|
||||||
name: jenkins-operator
|
# empty string and leads to operator actually watching all namespaces. In this
|
||||||
rules:
|
# case we need to create clusterrole and clusterrolebinding instead of role and
|
||||||
- apiGroups:
|
# rolebinding
|
||||||
- ""
|
*/ -}}
|
||||||
resources:
|
{{- template "jenkins-operator.role" .Values.jenkins.namespace }}
|
||||||
- services
|
{{ else }}
|
||||||
- configmaps
|
{{- template "jenkins-operator.role" .Release.Namespace }}
|
||||||
- secrets
|
{{- if ne .Release.Namespace .Values.jenkins.namespace -}}
|
||||||
verbs:
|
{{- template "jenkins-operator.role" .Values.jenkins.namespace }}
|
||||||
- get
|
{{- end }}
|
||||||
- create
|
{{ end }}
|
||||||
- update
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- deployments
|
|
||||||
- daemonsets
|
|
||||||
- replicasets
|
|
||||||
- statefulsets
|
|
||||||
verbs:
|
|
||||||
- '*'
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- serviceaccounts
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- update
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- roles
|
|
||||||
- rolebindings
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- update
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods/portforward
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods/log
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
- pods/exec
|
|
||||||
verbs:
|
|
||||||
- "*"
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- events
|
|
||||||
verbs:
|
|
||||||
- watch
|
|
||||||
- list
|
|
||||||
- create
|
|
||||||
- patch
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resourceNames:
|
|
||||||
- jenkins-operator
|
|
||||||
resources:
|
|
||||||
- deployments/finalizers
|
|
||||||
verbs:
|
|
||||||
- update
|
|
||||||
- apiGroups:
|
|
||||||
- jenkins.io
|
|
||||||
resources:
|
|
||||||
- '*'
|
|
||||||
verbs:
|
|
||||||
- '*'
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- persistentvolumeclaims
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- "route.openshift.io"
|
|
||||||
resources:
|
|
||||||
- routes
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- update
|
|
||||||
- apiGroups:
|
|
||||||
- "image.openshift.io"
|
|
||||||
resources:
|
|
||||||
- imagestreams
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- "build.openshift.io"
|
|
||||||
resources:
|
|
||||||
- builds
|
|
||||||
- buildconfigs
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
|
|
@ -1,12 +1,53 @@
|
||||||
|
{{ if eq .Values.jenkins.namespace "" }}
|
||||||
|
{{- /*
|
||||||
|
# This is a special case when .Values.jenkins.namespace is equal to empty
|
||||||
|
# string which leads to WATCH_NAMESPACE env of jenkins-operator to be set to
|
||||||
|
# empty string and leads to operator actually watching all namespaces. In this
|
||||||
|
# case we need to create clusterrole and clusterrolebinding instead of role and
|
||||||
|
# rolebinding
|
||||||
|
*/ -}}
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: jenkins-operator
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: jenkins-operator
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: jenkins-operator
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
{{ else }}
|
||||||
---
|
---
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: jenkins-operator
|
name: jenkins-operator
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: jenkins-operator
|
name: jenkins-operator
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: Role
|
kind: Role
|
||||||
name: jenkins-operator
|
name: jenkins-operator
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
{{ if ne .Release.Namespace .Values.jenkins.namespace }}
|
||||||
|
---
|
||||||
|
kind: RoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: jenkins-operator
|
||||||
|
namespace: {{ .Values.jenkins.namespace }}
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: jenkins-operator
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
roleRef:
|
||||||
|
kind: Role
|
||||||
|
name: jenkins-operator
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
{{- if .Values.webhook.enabled }}
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: jenkins-{{ .Values.webhook.certificate.name }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
spec:
|
||||||
|
duration: {{ .Values.webhook.certificate.duration }}
|
||||||
|
renewBefore: {{ .Values.webhook.certificate.renewbefore }}
|
||||||
|
secretName: jenkins-{{ .Values.webhook.certificate.name }}
|
||||||
|
dnsNames:
|
||||||
|
- jenkins-webhook-service.{{ .Release.Namespace }}.svc
|
||||||
|
- jenkins-webhook-service.{{ .Release.Namespace }}.svc.cluster.local
|
||||||
|
issuerRef:
|
||||||
|
kind: Issuer
|
||||||
|
name: selfsigned
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Issuer
|
||||||
|
metadata:
|
||||||
|
name: selfsigned
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
spec:
|
||||||
|
selfSigned: {}
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: jenkins-{{ .Values.webhook.certificate.name }}
|
||||||
|
type: opaque
|
||||||
|
|
||||||
|
{{- end }}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
{{- if .Values.webhook.enabled }}
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1
|
||||||
|
kind: ValidatingWebhookConfiguration
|
||||||
|
metadata:
|
||||||
|
name: {{ .Release.Name }}-webhook
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/jenkins-{{ .Values.webhook.certificate.name }}
|
||||||
|
webhooks:
|
||||||
|
- admissionReviewVersions:
|
||||||
|
- v1
|
||||||
|
- v1beta1
|
||||||
|
clientConfig:
|
||||||
|
service:
|
||||||
|
name: jenkins-webhook-service
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
path: /validate-jenkins-io-v1alpha2-jenkins
|
||||||
|
failurePolicy: Fail
|
||||||
|
name: vjenkins.kb.io
|
||||||
|
timeoutSeconds: 30
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- jenkins.io
|
||||||
|
apiVersions:
|
||||||
|
- v1alpha2
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resources:
|
||||||
|
- jenkins
|
||||||
|
scope: "Namespaced"
|
||||||
|
sideEffects: None
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: jenkins-webhook-service
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: 443
|
||||||
|
targetPort: 9443
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: {{ include "jenkins-operator.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
---
|
||||||
|
{{- end }}
|
||||||
|
|
@ -18,18 +18,25 @@ jenkins:
|
||||||
# namespace is the namespace where the resources will be deployed
|
# namespace is the namespace where the resources will be deployed
|
||||||
# It's not recommended to use default namespace
|
# It's not recommended to use default namespace
|
||||||
# Create new namespace for jenkins (called e.g. jenkins)
|
# Create new namespace for jenkins (called e.g. jenkins)
|
||||||
|
# Note: this affects roles and rolebindings for jenkins operator itself
|
||||||
namespace: default
|
namespace: default
|
||||||
|
|
||||||
# labels are injected into metadata labels field
|
# labels are injected into metadata labels field
|
||||||
labels: {}
|
labels: {}
|
||||||
|
|
||||||
|
# nodeSelector are injected into metadata nodeSelector field
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
# tolerations are injected into metadata tolerations field
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
# annotations are injected into metadata annotations field
|
# annotations are injected into metadata annotations field
|
||||||
annotations: {}
|
annotations: {}
|
||||||
|
|
||||||
# image is the name (and tag) of the Jenkins instance
|
# image is the name (and tag) of the Jenkins instance
|
||||||
# Default: jenkins/jenkins:lts
|
# Default: jenkins/jenkins:lts
|
||||||
# It's recommended to use LTS (tag: "lts") version
|
# It's recommended to use LTS (tag: "lts") version
|
||||||
image: jenkins/jenkins:2.263.2-lts-alpine
|
image: jenkins/jenkins:2.528.1-lts
|
||||||
|
|
||||||
# env contains jenkins container environment variables
|
# env contains jenkins container environment variables
|
||||||
env: []
|
env: []
|
||||||
|
|
@ -37,6 +44,9 @@ jenkins:
|
||||||
# imagePullPolicy defines policy for pulling images
|
# imagePullPolicy defines policy for pulling images
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
|
|
||||||
|
# lifecycle is used if you want to specify lifecycle hooks for the master container
|
||||||
|
lifecycle: {}
|
||||||
|
|
||||||
# priorityClassName indicates the importance of a Pod relative to other Pods
|
# priorityClassName indicates the importance of a Pod relative to other Pods
|
||||||
# See: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
|
# See: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
|
||||||
priorityClassName: ""
|
priorityClassName: ""
|
||||||
|
|
@ -46,14 +56,38 @@ jenkins:
|
||||||
# See https://github.com/jenkinsci/kubernetes-operator/pull/193 for more info
|
# See https://github.com/jenkinsci/kubernetes-operator/pull/193 for more info
|
||||||
disableCSRFProtection: false
|
disableCSRFProtection: false
|
||||||
|
|
||||||
|
# adding entries to a pod's /etc/hosts file provides pod-level override of hostname
|
||||||
|
# resolution when DNS and other options are not applicable.
|
||||||
|
hostAliases: {}
|
||||||
|
# - ip: "127.0.0.1"
|
||||||
|
# hostnames:
|
||||||
|
# - "foo.local"
|
||||||
|
# - "bar.local"
|
||||||
|
# - ip: "10.1.2.3"
|
||||||
|
# hostnames:
|
||||||
|
# - "foo.remote"
|
||||||
|
# - "bar.remote"
|
||||||
|
|
||||||
|
# Optional duration in seconds the pod needs to terminate gracefully.
|
||||||
|
# Default 30sec
|
||||||
|
terminationGracePeriodSeconds: 30
|
||||||
|
|
||||||
|
# validateSecurityWarnings enables or disables validating potential security warnings in Jenkins plugins via admission webhooks.
|
||||||
|
validateSecurityWarnings: false
|
||||||
|
|
||||||
# imagePullSecrets is used if you want to pull images from private repository
|
# imagePullSecrets is used if you want to pull images from private repository
|
||||||
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#pulling-docker-images-from-private-repositories for more info
|
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#pulling-docker-images-from-private-repositories for more info
|
||||||
imagePullSecrets: []
|
imagePullSecrets: []
|
||||||
|
|
||||||
# notifications is feature that notify user about Jenkins reconcilation status
|
# notifications is feature that notify user about Jenkins reconciliation status
|
||||||
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/notifications/ for more info
|
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/notifications/ for more info
|
||||||
notifications: []
|
notifications: []
|
||||||
|
|
||||||
|
# Enables customization of the Service Account attached to the master Jenkins instance via annotations
|
||||||
|
# https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/schema/#github.com/jenkinsci/kubernetes-operator/api/v1alpha2.ServiceAccount
|
||||||
|
serviceAccount:
|
||||||
|
annotations: {}
|
||||||
|
|
||||||
# basePlugins are plugins installed and required by the operator
|
# basePlugins are plugins installed and required by the operator
|
||||||
# Shouldn't contain plugins defined by user
|
# Shouldn't contain plugins defined by user
|
||||||
# You can change their versions here
|
# You can change their versions here
|
||||||
|
|
@ -63,34 +97,21 @@ jenkins:
|
||||||
#
|
#
|
||||||
# basePlugins:
|
# basePlugins:
|
||||||
# - name: kubernetes
|
# - name: kubernetes
|
||||||
# version: 1.28.6
|
# version: 4246.v5a_12b_1fe120e
|
||||||
# - name: workflow-job
|
# - name: workflow-job
|
||||||
# version: "2.40"
|
# version: 1400.v7fd111b_ec82f
|
||||||
# - name: workflow-aggregator
|
# - name: workflow-aggregator
|
||||||
# version: "2.6"
|
# version: 596.v8c21c963d92d
|
||||||
# - name: git
|
# - name: git
|
||||||
# version: 4.5.0
|
# version: 5.2.2
|
||||||
# - name: job-dsl
|
# - name: job-dsl
|
||||||
# version: "1.77"
|
# version: "1.87"
|
||||||
# - name: configuration-as-code
|
# - name: configuration-as-code
|
||||||
# version: "1.46"
|
# version: 1810.v9b_c30a_249a_4c
|
||||||
# - name: kubernetes-credentials-provider
|
# - name: kubernetes-credentials-provider
|
||||||
# version: 0.15
|
# version: 1.262.v2670ef7ea_0c5
|
||||||
basePlugins:
|
|
||||||
- name: kubernetes
|
basePlugins: []
|
||||||
version: "1.28.6"
|
|
||||||
- name: workflow-job
|
|
||||||
version: "2.40"
|
|
||||||
- name: workflow-aggregator
|
|
||||||
version: "2.6"
|
|
||||||
- name: git
|
|
||||||
version: "4.5.0"
|
|
||||||
- name: job-dsl
|
|
||||||
version: "1.77"
|
|
||||||
- name: configuration-as-code
|
|
||||||
version: "1.46"
|
|
||||||
- name: kubernetes-credentials-provider
|
|
||||||
version: "0.15"
|
|
||||||
|
|
||||||
# plugins are plugins required by the user
|
# plugins are plugins required by the user
|
||||||
# You can define plugins here
|
# You can define plugins here
|
||||||
|
|
@ -103,9 +124,14 @@ jenkins:
|
||||||
# version: "0.6"
|
# version: "0.6"
|
||||||
plugins: []
|
plugins: []
|
||||||
|
|
||||||
|
# latestPlugins: Allow to override jenkins-plugin-cli default behavior
|
||||||
|
# while downloading the plugin and dependencies
|
||||||
|
# see: https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options
|
||||||
|
# default to true
|
||||||
|
latestPlugins: true
|
||||||
|
|
||||||
# seedJobs is placeholder for jenkins seed jobs
|
# seedJobs is placeholder for jenkins seed jobs
|
||||||
# For seed job creation tutorial, check https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#prepare-job-definitions-and-pipelines
|
# For seed job creation tutorial, check https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/
|
||||||
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#configure-seed-jobs for additional info
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# seedJobs:
|
# seedJobs:
|
||||||
|
|
@ -116,14 +142,22 @@ jenkins:
|
||||||
# repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
# repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
|
||||||
seedJobs: []
|
seedJobs: []
|
||||||
|
|
||||||
|
# SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:3248.v65ecb_254c298-6 will be used.
|
||||||
|
seedJobAgentImage: ""
|
||||||
|
|
||||||
|
# skipPlugins allows to skip installation of both BasePlugins and Plugins.
|
||||||
|
# Requires using a custom image which includes the BasePlugins.
|
||||||
|
# Defaults to false.
|
||||||
|
skipPlugins: false
|
||||||
|
|
||||||
# Resource limit/request for Jenkins
|
# Resource limit/request for Jenkins
|
||||||
# See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ for details
|
# See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ for details
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 1500m
|
cpu: 1000m
|
||||||
memory: 3Gi
|
memory: 3Gi
|
||||||
requests:
|
requests:
|
||||||
cpu: 1
|
cpu: 250m
|
||||||
memory: 500Mi
|
memory: 500Mi
|
||||||
|
|
||||||
# volumes used by Jenkins
|
# volumes used by Jenkins
|
||||||
|
|
@ -134,8 +168,14 @@ jenkins:
|
||||||
claimName: jenkins-backup
|
claimName: jenkins-backup
|
||||||
|
|
||||||
# volumeMounts are mounts for Jenkins pod
|
# volumeMounts are mounts for Jenkins pod
|
||||||
|
# Note that attempting to overwrite default mount settings for restricted,
|
||||||
|
# non-configurable volumeMounts will result in Operator error
|
||||||
|
# See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts for details
|
||||||
volumeMounts: []
|
volumeMounts: []
|
||||||
|
|
||||||
|
# defines authorization strategy of the operator for the Jenkins API
|
||||||
|
authorizationStrategy: createUser
|
||||||
|
|
||||||
# securityContext for pod
|
# securityContext for pod
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsUser: 1000
|
runAsUser: 1000
|
||||||
|
|
@ -148,6 +188,29 @@ jenkins:
|
||||||
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/schema/#github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Service for details
|
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/schema/#github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2.Service for details
|
||||||
#slaveService:
|
#slaveService:
|
||||||
|
|
||||||
|
# LivenessProbe for Jenkins Master pod
|
||||||
|
livenessProbe:
|
||||||
|
failureThreshold: 20
|
||||||
|
httpGet:
|
||||||
|
path: /login
|
||||||
|
port: http
|
||||||
|
scheme: HTTP
|
||||||
|
initialDelaySeconds: 100
|
||||||
|
periodSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
timeoutSeconds: 8
|
||||||
|
# ReadinessProbe for Jenkins Master pod
|
||||||
|
readinessProbe:
|
||||||
|
failureThreshold: 60
|
||||||
|
httpGet:
|
||||||
|
path: /login
|
||||||
|
port: http
|
||||||
|
scheme: HTTP
|
||||||
|
initialDelaySeconds: 120
|
||||||
|
periodSeconds: 10
|
||||||
|
successThreshold: 1
|
||||||
|
timeoutSeconds: 8
|
||||||
|
|
||||||
# backup is section for configuring operator's backup feature
|
# backup is section for configuring operator's backup feature
|
||||||
# By default backup feature is enabled and pre-configured
|
# By default backup feature is enabled and pre-configured
|
||||||
# This section simplifies the configuration described here: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/
|
# This section simplifies the configuration described here: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/
|
||||||
|
|
@ -158,8 +221,8 @@ jenkins:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
# image used by backup feature
|
# image used by backup feature
|
||||||
# By default using prebuilt backup PVC image by VirtusLab
|
# By default using prebuilt backup PVC image
|
||||||
image: virtuslab/jenkins-operator-backup-pvc:v0.1.0
|
image: quay.io/jenkins-kubernetes-operator/backup-pvc:v0.4.3
|
||||||
|
|
||||||
# containerName is backup container name
|
# containerName is backup container name
|
||||||
containerName: backup
|
containerName: backup
|
||||||
|
|
@ -193,11 +256,25 @@ jenkins:
|
||||||
# See https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1 for more details
|
# See https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1 for more details
|
||||||
className: ""
|
className: ""
|
||||||
|
|
||||||
|
# resources used by backup container
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 2Gi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 500Mi
|
||||||
|
|
||||||
# env contains container environment variables
|
# env contains container environment variables
|
||||||
# PVC backup provider handles these variables:
|
# PVC backup provider handles these variables:
|
||||||
# BACKUP_DIR - path for storing backup files (default: "/backup")
|
# BACKUP_DIR - path for storing backup files (default: "/backup")
|
||||||
# JENKINS_HOME - path to jenkins home (default: "/jenkins-home")
|
# JENKINS_HOME - path to jenkins home (default: "/jenkins-home")
|
||||||
# BACKUP_COUNT - define how much recent backups will be kept
|
# BACKUP_COUNT - define how much recent backups will be kept
|
||||||
|
# Optional in case you want to modify the backup and restore retry logic
|
||||||
|
# BACKUP_RETRY_COUNT
|
||||||
|
# BACKUP_RETRY_INTERVAL
|
||||||
|
# RESTORE_RETRY_COUNT
|
||||||
|
# RESTORE_RETRY_INTERVAL
|
||||||
env:
|
env:
|
||||||
- name: BACKUP_DIR
|
- name: BACKUP_DIR
|
||||||
value: /backup
|
value: /backup
|
||||||
|
|
@ -205,6 +282,15 @@ jenkins:
|
||||||
value: /jenkins-home
|
value: /jenkins-home
|
||||||
- name: BACKUP_COUNT
|
- name: BACKUP_COUNT
|
||||||
value: "3" # keep only the 3 most recent backups
|
value: "3" # keep only the 3 most recent backups
|
||||||
|
#- name: BACKUP_RETRY_COUNT
|
||||||
|
# value: "3"
|
||||||
|
#- name: BACKUP_RETRY_INTERVAL
|
||||||
|
# value: "60"
|
||||||
|
#- name: RESTORE_RETRY_COUNT
|
||||||
|
# value: "10"
|
||||||
|
#- name: RESTORE_RETRY_INTERVAL
|
||||||
|
# value: "10"
|
||||||
|
|
||||||
|
|
||||||
# volumeMounts holds the mount points for volumes
|
# volumeMounts holds the mount points for volumes
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
|
@ -216,10 +302,10 @@ jenkins:
|
||||||
# configuration is section where we can configure Jenkins instance
|
# configuration is section where we can configure Jenkins instance
|
||||||
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/ for details
|
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/ for details
|
||||||
configuration:
|
configuration:
|
||||||
configurationAsCode: {}
|
configurationAsCode: []
|
||||||
# - configMapName: jenkins-casc
|
# - configMapName: jenkins-casc
|
||||||
# content: {}
|
# content: {}
|
||||||
groovyScripts: {}
|
groovyScripts: []
|
||||||
# - configMapName: jenkins-gs
|
# - configMapName: jenkins-gs
|
||||||
# content: {}
|
# content: {}
|
||||||
|
|
||||||
|
|
@ -234,7 +320,7 @@ operator:
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
|
|
||||||
# image is the name (and tag) of the Jenkins Operator image
|
# image is the name (and tag) of the Jenkins Operator image
|
||||||
image: virtuslab/jenkins-operator:v0.4.0
|
image: quay.io/jenkins-kubernetes-operator/operator:v0.9.0-beta1
|
||||||
|
|
||||||
# imagePullPolicy defines policy for pulling images
|
# imagePullPolicy defines policy for pulling images
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
|
|
@ -248,7 +334,33 @@ operator:
|
||||||
# fullnameOverride overrides the deployment name
|
# fullnameOverride overrides the deployment name
|
||||||
fullnameOverride: ""
|
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: {}
|
resources: {}
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
tolerations: []
|
tolerations: []
|
||||||
affinity: {}
|
affinity: {}
|
||||||
|
|
||||||
|
webhook:
|
||||||
|
# TLS certificates for webhook
|
||||||
|
certificate:
|
||||||
|
name: webhook-certificate
|
||||||
|
|
||||||
|
# validity of the certificate
|
||||||
|
duration: 2160h
|
||||||
|
|
||||||
|
# time after which the certificate will be automatically renewed
|
||||||
|
renewbefore: 360h
|
||||||
|
# enable or disable the validation webhook
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
cert-manager:
|
||||||
|
# cert-manager is required to generate certificates for webhook. If you don't have cert-manager installed in your cluster,
|
||||||
|
# you can install it as a subordinate chart
|
||||||
|
enabled: false
|
||||||
|
# This startupapicheck is a Helm post-install hook that waits for the webhook
|
||||||
|
# endpoints to become available.
|
||||||
|
startupapicheck:
|
||||||
|
enabled: false
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue