Compare commits

...

314 Commits

Author SHA1 Message Date
github-actions[bot] 08f0a74771
chore: update Jenkins lts version to 2.528.1 (#1137)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2025-10-26 21:57:13 +01:00
fuero bf040e1188
Removes disabling insecure protocols (#1129)
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
2025-10-06 13:13:12 +02:00
Ilya Pyatizbyantsev b8a756909f
docs: remove duplicated 'image' key (#1133)
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
2025-10-05 19:03:01 +02:00
github-actions[bot] 697dc1b370
chore: update Jenkins lts version to 2.516.3 (#1135)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2025-10-05 18:58:55 +02:00
Luigi Operoso ac3db2fbc6
feat: automatic update of jenkins lts version and base plugins (#1134) 2025-10-05 18:36:57 +02:00
Benjamin Herbert ae9cb0c7f5
fix(backup): Add error handling and logging backup and restore scripts (#1120)
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
2025-07-16 23:43:08 +02:00
Benjamin Herbert 3300775a1d
docs: improve (#1121) 2025-07-10 23:32:35 +02:00
github-actions[bot] 8a66d658eb
Auto-updated Kubernetes Manifests (#1112)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2025-04-21 11:45:35 +02:00
Tobia De Koninck 69bdd916d5
Add option to skip install of plugins (#1065)
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
2025-04-21 11:38:28 +02:00
github-actions[bot] 132fcb22dc
Auto-updated Kubernetes Manifests (#1108)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2025-04-06 23:28:12 +02:00
github-actions[bot] ee191bfc4e
Release 0.9.0-beta1 Helm Chart (#1107)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2025-04-06 23:26:33 +02:00
github-actions[bot] 191caefbbe
Auto-updated Kubernetes Manifests (#1106)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2025-04-06 23:22:19 +02:00
Luigi Operoso 627d3d2af2
chore: prepare release v0.9.0-beta1 (#1105) 2025-04-06 23:21:12 +02:00
Luigi Operoso 17d3c0bf4b
chore: bump jenkins and golang.org/x/crypto (#1104) 2025-04-06 10:12:51 +02:00
Luigi Operoso faf812a0ce
feat: add matrix tests for bats and replace the old devoptics plugin in tests (#1102) 2025-04-05 18:27:17 +02:00
Luigi Operoso 832debbd45
chore: bump version to 2.492.2-lts and update helm chart readme (#1101) 2025-03-30 23:20:31 +02:00
dependabot[bot] 4b3600ff0e
build(deps-dev): bump the npm group across 1 directory with 3 updates (#1100)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: brokenpip3 <brokenpip3@gmail.com>
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
2025-03-30 19:20:42 +02:00
dependabot[bot] 3b61208f2e
build(deps): bump the actions group across 1 directory with 5 updates (#1098)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: brokenpip3 <brokenpip3@gmail.com>
2025-03-30 18:58:10 +02:00
Luigi Operoso bec1c61e27
fix(backup): exec of backup binaries can be executed by random id (for ocp compatibility) (#1099) 2025-03-30 18:32:17 +02:00
Luigi Operoso 2864a85364
chore: pin github actions, update and freeze pre-commit hooks, update nix flake (#1097) 2025-03-30 18:11:32 +02:00
Manish Bhasin 9c09db8031
update to go 1.22 and operator-sdk 1.35 (#1094)
Co-authored-by: brokenpip3 <brokenpip3@gmail.com>
Co-authored-by: Ansh Garhewal <me@anshdevs.in>
Co-authored-by: xmbhasin <xmbhasin@users.noreply.github.com>
2025-03-30 16:37:15 +02:00
Manish Bhasin 1ec83b9de9
fix(bats-tests): lifecycle hook injection test failing (#1095)
Co-authored-by: xmbhasin <xmbhasin@users.noreply.github.com>
2025-03-27 00:19:52 +01:00
Daniel Beck f0da3494ae
Delete workflow using backdoored action
https://news.ycombinator.com/item?id=43368870
0e58ed8671
2025-03-15 11:09:10 +01:00
DionJones615 d919a2a11c
fix(master): pass lifecycle configuration to master container (#1062) 2024-11-22 01:03:01 +01:00
Luigi Operoso a4fa09b2ed
chore: plugins and lts version october update (#1070) 2024-10-21 00:00:49 +02:00
Benjamin Herbert bb33b8ffa0
Fix broken links on Jenkins API type docs (#1067) 2024-10-17 12:03:21 +02:00
dependabot[bot] 7cdffbe716
build(deps): bump the actions group across 1 directory with 2 updates (#1038)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-25 15:48:27 +02:00
Luigi Operoso 24eac18564
fix(test): helm/bats + chore(blog): add 0.8.1 release note (#1033) 2024-07-08 08:56:23 +02:00
Luigi Operoso 3a5b7f6b4f
fix(ci): release go env version (#1032) 2024-07-05 19:07:37 +02:00
github-actions[bot] 6abbd56e77
Auto-updated Kubernetes Manifests (#1031)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2024-07-05 17:27:50 +02:00
github-actions[bot] b63b31a398
Release 0.8.1 Helm Chart (#1030)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2024-07-05 17:27:10 +02:00
github-actions[bot] 7c6616b2bf
Auto-updated Kubernetes Manifests (#1029)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2024-07-05 15:04:29 +02:00
Luigi Operoso 57a1b6bfb9
chore: prepare 0.8.1 bug fix release (#1028) 2024-07-04 23:38:48 +02:00
Luigi Operoso 5e962b26ae
fix(operator): deprecated jnlpUrl (#1026) 2024-07-02 22:39:50 +02:00
dependabot[bot] 0911dfe64a
build(deps): bump the actions group across 1 directory with 2 updates (#1019)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-25 23:30:29 +02:00
Luigi Operoso b722ef11ae
feat(backup): logs everything to stdout/err, implement lock file for both backup/restore (#1023) 2024-06-25 23:29:35 +02:00
DionJones615 5ef6c730de
fix(backup): Duplicated backups & restores (#1021) 2024-06-25 18:44:55 +02:00
Luigi Operoso e0f52b5bdf
chore(operator): update jenkins latest img and plugins, use latest backup in bats tests (#1022) 2024-06-22 16:27:38 +02:00
Evgenii f98b0bc5ee
fix(backup): find race and disable search in subdir, always test latest backup image in e2e, bump backup to 0.3.x (#1011)
Co-authored-by: brokenpip3 <brokenpip3@gmail.com>
2024-06-22 09:47:24 +02:00
github-actions[bot] e40032497b
Auto-updated Kubernetes Manifests (#1020)
Co-authored-by: brokenpip3 <40476330+brokenpip3@users.noreply.github.com>
2024-06-11 23:59:07 +02:00
DionJones615 18197e66b7
feat: expose jenkins master terminationGracePeriodSeconds (#1012)
Co-authored-by: brokenpip3 <brokenpip3@gmail.com>
2024-06-11 23:57:48 +02:00
Luigi Operoso 061995a65c
fix: seed job warnings, updated latest lts and plugins (#1018) 2024-06-02 23:33:56 +02:00
Evgenii 25b329aa13
fix(backup): use atomic mv to create backup (#1000) 2024-05-05 16:54:04 +02:00
dependabot[bot] 3f036bdea7
build(deps): bump the actions group with 5 updates (#1005)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-24 09:26:16 +02:00
Rafał Krzewski cf49a4a28f
Control cert-manager installation with a separate config value (#972)
Co-authored-by: Rafał Krzewski <rafal.krzewski@caltha.eu>
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
Co-authored-by: brokenpip3 <brokenpip3@gmail.com>
2024-03-16 16:28:15 +00:00
dependabot[bot] 6dd45eebf0
build(deps): bump the actions group with 5 updates (#985)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
2024-03-16 15:39:13 +00:00
Luigi Operoso 1a7dc9107a
fix(test): bats test fix webhook upgrade (#987) 2024-03-16 16:24:22 +01:00
Luigi Operoso 036b20c01b
feat(test): better bats tests, install from latest tag and then update from master (#986) 2024-03-15 20:57:30 +01:00
Luigi Operoso 48aa102342
fix(website): base url in website build (#984) 2024-03-10 17:52:47 +01:00
Luigi Operoso 4f03cefda0
Fix website build and 0.8.x pages, move deploy to workflow and nixify the website part (#982) 2024-03-10 17:30:01 +01:00
dependabot[bot] cee202004d
build(deps-dev): bump the npm group in /website with 1 update (#981)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-04 11:18:46 +01:00
Luigi Operoso be737522f0
feat: make ginkgo tests as matrix (#979)
- make ginkgo tests as matrix for easily re-run failing tests or checking logs
- fix pod restart check
2024-02-26 00:00:37 +01:00
Luigi Operoso ec20bbe630
fix: mkdir bin before link helm (#978) 2024-02-24 17:21:23 +01:00
Luigi Operoso 81251d3ddc
chore: update jenkins and plugins to latest lts, update gh actions, add flake, remove minikube and use kind (#974)
- update to latest jenkins lts
- update github actions
- add nix flake (experimental, build artifacts still wip)
- remove minikube and use kind for a better experience
2024-02-24 17:08:10 +01:00
dependabot[bot] 95f0215c37
build(deps-dev): bump the npm group in /website with 2 updates (#958)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-13 23:43:50 +01:00
João Valença bfda3c8cf9
Provides an Override to the WATCH_NAMESPACE env variable. (#923)
Co-authored-by: João Valença <joao.valenca@feedzai.com>
2024-02-04 18:34:36 +01:00
Aniket Shitole 332eabe8d7
Modified ldap.md for issue #937 (#951) 2024-02-04 11:24:47 +01:00
Pavel Mashchenskiy 2ba5334c10
Fix: change default value for configurationAsCode and groovyScripts (#947)
Co-authored-by: Pavel Mashchenskiy <pavel.mashchenskiy@ims.co.at>
2024-01-07 12:20:38 +01:00
Yuedong Wu 50c7217daa
Fix: use consistent imagePullPolicy when enable Jenkins backup (#939) 2023-11-28 09:48:07 +01:00
Luigi Operoso 8d61604b03
fix(tests) (#936) 2023-11-19 14:04:23 +01:00
dependabot[bot] 63e8a76b95
build(deps-dev): bump the npm group in /website with 2 updates (#929)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-13 00:27:48 +01:00
Luigi Operoso 138e569841
fix(ci): update devcontainers, github actions config, bats action (#928) 2023-11-13 00:26:13 +01:00
Ilya Pyatizbyantsev 3682468b5f
Combine dark and regular logo in README.md (#915) 2023-10-15 16:31:07 +02:00
github-actions[bot] d70f70f0f4
Auto-updated Kubernetes Manifests (#901)
Co-authored-by: brokenpip3 <brokenpip3@users.noreply.github.com>
2023-10-12 10:02:59 +02:00
brokenpip3 a6e32fde98
bump to 0.8.0 2023-09-13 10:15:42 +02:00
github-actions[bot] 8268c1e4c5
Release 0.8.0 Helm Chart (#908)
Co-authored-by: brokenpip3 <brokenpip3@users.noreply.github.com>
2023-09-13 08:56:20 +02:00
Luigi Operoso 2c88fe13a8
chore(jenkins): update latest lts and plugins version (#900) 2023-09-05 15:21:44 +02:00
Luigi Operoso 1b6e944ae6
fix(chart): #873 operator watch namespace (#899) 2023-09-05 11:56:56 +02:00
Rob Ratcliffe 01a3990d66
Fix #873 (#875) 2023-07-05 21:28:57 +02:00
dependabot[bot] b95ccec075
build(deps-dev): bump postcss-cli from 5.0.1 to 7.1.2 in /website (#872)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-01 00:21:39 +02:00
github-actions[bot] 0fe4456abc
Auto-updated Kubernetes Manifests (#864)
Co-authored-by: brokenpip3 <brokenpip3@users.noreply.github.com>
2023-07-01 00:21:09 +02:00
Luigi Operoso 181bcc3316
fix(ci): auto generate manifests cleanup (#871) 2023-07-01 00:19:15 +02:00
Luigi Operoso 6065f012ee
chore(ci): remove some garbage from auto-generate manifests (#869) 2023-06-30 23:54:50 +02:00
github-actions[bot] 7233d82237
Release 0.8.0-beta.2 Helm Chart (#868)
Co-authored-by: brokenpip3 <brokenpip3@users.noreply.github.com>
2023-06-30 23:24:08 +02:00
Luigi Operoso e79b06024a
chore: preparing v0.8.0-beta2 version bump (#866) 2023-06-29 09:05:29 +02:00
Luigi Operoso 5ddcf1075d
fix: latestplugin always true, add more complex bats tests, update devcontainers and make manifests (#857) 2023-06-27 09:37:31 +02:00
Luigi Operoso 0abc758dc3
chore: several minor updates, bump helm, base-plugins and backup base img (#865) 2023-06-26 12:43:24 +02:00
Luigi Operoso 97892a4cbd
wip feat(ci): Auto update k8s manifests, chart: add operator live/readiness probe (#860) 2023-06-25 21:34:27 +02:00
Luigi Operoso c2c249aa48
fix(ci): remove sembump (#859) 2023-06-25 15:59:05 +02:00
Luigi Operoso 6cceedba77
fix(backup): get-latest.sh, search for both .gz and .zstd (#858) 2023-06-25 15:48:36 +02:00
Luigi Operoso 3fe842fff4
chore: prearing version bumpt to v0.8.0-beta2 (#849) 2023-06-06 00:10:36 +02:00
Luigi Operoso 813cbc812e
fix: hugo and backup ci again (#848) 2023-06-05 23:54:37 +02:00
Luigi Operoso 93d3e9eb9f
fix hugo and backup version, fix backup ci (#847) 2023-06-05 23:20:03 +02:00
dependabot[bot] e6bd8c3f14
Bump peter-evans/create-pull-request from 3 to 5 (#817)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-05 23:06:57 +02:00
dependabot[bot] 936dbc4713
Bump actions/checkout from 2 to 3 (#815)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-05 23:06:17 +02:00
dependabot[bot] dab511fed3
Bump docker/login-action from 1 to 2 (#819)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-05 23:05:43 +02:00
Luigi Operoso 1e4ffd4718
fix: backup trimming, only selecting zstd file (#846) 2023-06-05 23:05:16 +02:00
Luigi Operoso 4e5f9d562f
chore: add v0.8.0 doc (#845) 2023-06-05 22:54:54 +02:00
Luigi Operoso d9ea2ee83b
feat: attempt to move restore before seed job creation (#844) 2023-06-04 13:35:14 +02:00
Luigi Operoso 00bb04745b
Fix: add tollerations again (#842)
Signed-off-by: tombokombo <tombo@sysart.tech>
Co-authored-by: Tomas Hulata <tombo@sysart.tech>
2023-05-30 09:36:55 +02:00
Luigi Operoso 3275be357a
feat: use zstd instead of gz by default, fix the backup script (#841) 2023-05-26 16:10:24 +02:00
Luigi Operoso 44a7d2460a
feat(repo): add stale bot (#836) 2023-05-09 00:26:02 +02:00
Luigi Operoso 7bccdc21b1
chore: update to latest lts, update plugins, remove devbots, add devcontainer (#835)
Update to the latest lts
Update plugins
Remove devbots
Initial devcontainer config
2023-05-09 00:12:54 +02:00
Alexander Robson 5058fc2a6e
chore: Update git ls-files cmd with missing arg (#832) 2023-05-05 16:05:39 +02:00
Alexander Robson a690c7cc6c
chore(doc): Update links in README (#829) 2023-04-27 19:46:44 +02:00
github-actions[bot] f97badca9c
Release v0.8.0-beta Helm Chart (#825)
Co-authored-by: brokenpip3 <brokenpip3@users.noreply.github.com>
2023-04-18 00:12:09 +02:00
Luigi Operoso 38eaa0fc55
chore: bump version to v0.8.0-beta (#814)
- add dependabot
- add codespell
- update operator version in helm chart
2023-04-18 00:01:07 +02:00
Luigi Operoso 00fc29e772
chore: update to 2.387.2-lts and base plugins (#811) 2023-04-13 23:22:22 +02:00
github-actions[bot] 605669de0d
Auto-generated docs update (#793)
Co-authored-by: brokenpip3 <brokenpip3@users.noreply.github.com>
2023-03-23 22:24:54 +01:00
Luigi Operoso 901100a759
chore(doc): Add the new chat references (#809) 2023-03-23 22:21:11 +01:00
Luigi Operoso 9fd053b784
feat(operator): several updates (#806)
- prepare to switch from `master` to `main`
- avoid to run workflow in case is not needed
- add a way to bump the lts via make
- use latest jenkins lts 2.387.1
- add the docker labels
- update base plugins
- fix #797 
- Add more tests with bats
- Update base plugin to latest version
- Temporary revert #807 
- Better nightly job
2023-03-23 00:04:57 +01:00
Tomas Hulata e36441a4a2
Add tolerations for jenkis pod (#807)
Signed-off-by: tombokombo <tombo@sysart.tech>
2023-03-17 18:56:29 +01:00
Piotr Ryba 6932b61ff9
chore: Prepare the project for handover (#800) 2023-03-13 16:07:09 +01:00
Luigi Operoso 2f90db9dc9
fix(quay.io): start using quay.io and fix backup push (#805) 2023-03-12 18:29:39 +01:00
Luigi Operoso d91a729ccf
feat(backup): add backup img ci for e2e tests, docker build and push (#795)
also fix the current CI
2023-03-07 00:34:07 +01:00
Luigi Operoso e9fbe575a6
chore(update): use latest jenkins lts: 2.375.3 (#796) 2023-03-07 00:09:23 +01:00
Luigi Operoso cd2efd6722
feat(registry): change the default registry from dockerhub to quay.io (#799) 2023-03-07 00:08:33 +01:00
Alexander Brandes 1adaf00ca7
fix(docs) delete SECURITY.md (#785) 2023-03-02 23:47:29 +01:00
github-actions[bot] c39eaa95b7
Auto-updated docs (#790)
Co-authored-by: prryb <prryb@users.noreply.github.com>
2023-01-19 14:22:39 +01:00
Luigi Operoso fc3fe04581
chore(operator): update operator version in master (#791) 2023-01-19 13:50:56 +01:00
github-actions[bot] 7a72939de8
Auto-updated docs (#789)
Co-authored-by: prryb <prryb@users.noreply.github.com>
2023-01-16 07:32:41 +01:00
Luigi Operoso 60b8ee56de
fix(operator): Attempt to fix all the major issues present atm against the newest jenkins lts version (#784)
* fix(seed): fix #742, workaround #698
Original fix proposal: https://github.com/jenkinsci/kubernetes-operator/issues/742#issuecomment-1304398590

* fix(install-plugin.sh): fix #758, #739
* the fix was original attempted here:
  https://github.com/jenkinsci/kubernetes-operator/pull/764 but was not
  working correctly due to 2-3 additional changes which needed to be
  done
* removed the openshift check because the env is not mention anywhere
  and also the new jenkins-plugin-cli does not a specific command for
  openshift. Finally this does not make any sense in general, the only
  problem in ocp will be the user id that will be mapped to a random uid
  but that's another story. The command to install the plugins should
  remain the same across different k8s flavours.

* fix(doc/test): fix /usr/bin/tini in any doc and validation

* fix(jenkins): remove AdminWhitelistRule to avoid jvm stack trace, see: https://www.jenkins.io/doc/book/security/controller-isolation/jep-235/#api-compatibility

* fix(seed): fix seed img built on a previous jvm, fix #761

* fix(plugin): update the base plugin to work with the newest version of
jenkins:lts

* fix(run): fix #778

* fix(backup): add a trap to remove the tmp dir if the tar fail, also fix: #770

* test(chart): update chart values for testing, will revert before merge

* fix(configmap): leftover

* fix(tests): fix seed job test

* fix(e2e)

* fix(e2e): helm

* fix(operator): update the temporary img to reflect latests changes

* Fix Helm e2e tests

* add trap in case of unwanted exit and make shellcheck happy

* chore(plugin): update git ver to 5.0.0

* fix(backup): always force delete the backup directory

* chore(operator): update the temporary img to reflect latest changes

* chore(jenkins): upgrade jenkins latest lts
2023-01-12 17:29:30 +01:00
github-actions[bot] 6e03948b09
Auto-updated docs (#788)
Co-authored-by: prryb <prryb@users.noreply.github.com>
2023-01-09 22:07:47 +01:00
Peter Becich fbe70f11ca
update image tag for `virtuslab/jenkins-operator-backup-pvc` (#781)
https://hub.docker.com/r/virtuslab/jenkins-operator-backup-pvc/tags
2023-01-08 19:45:01 +01:00
Jelmer Vernooij 3ce8a49d26
Increase memory, to prevent OOM killing (#774) 2023-01-08 19:42:18 +01:00
github-actions[bot] 410c403452
Auto-updated docs (#787)
Co-authored-by: prryb <prryb@users.noreply.github.com>
2023-01-08 19:41:34 +01:00
twildber a8065cc038
adding seedjobagentimage to jenkins chart (#771)
Co-authored-by: Thorsten Wildberger <thorsten.wildberger@capgemini.com>
2023-01-08 19:34:56 +01:00
Eli Ezeugoh addb94f83e
Fix broken link for configuring seed jobs (#780)
Link from Schema docs to seed job is broken
2023-01-08 19:32:49 +01:00
Bastien HUBERT 94b1473c63
Add seedJobAgentImage into CRD (#754)
* Add seedJobAgentImage into CRD

* Fix lint by ignoring auto-generated files
2022-06-29 17:23:23 +02:00
Bartosz Surma bef796af8a
Update and use install-plugins.sh (#756)
* Download install-plugins.sh manually from remote

* Reformat

* Goimports

* Use install-plugins.sh bundled with the operator

* Fix compile error

* Update install-plugins.sh

* Remove redundant param to new install-plugins.sh

Co-authored-by: Piotr Ryba <pryba@virtuslab.com>
2022-06-28 19:14:31 +02:00
github-actions[bot] 4c2671c1a3
Release Helm chart 0.6.2 (#753)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2022-06-22 17:55:00 +02:00
Szymon Fugas e1b1e9cb3c
Bump to 0.7.1 (#752) 2022-06-22 17:46:49 +02:00
github-actions[bot] 4079d4e93e
Release Helm chart 0.6.1 (#751)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2022-06-22 13:31:26 +02:00
Szymon Fugas 63e96c9715
chore: add release workflow (#750)
* Regenerate deepcopy

* Add the workflow

* Stop signing the tag
2022-06-21 15:36:22 +02:00
Piotr Ryba 8fee7f2806 Bump version to v0.7.1 2022-06-20 21:53:45 +02:00
ywang-psee b734b6d74f
Customize jenkins-operator helmchart with adding 'nodeSelector' (#723)
* Customize jenkins-operator helmchart with adding 'nodeSelector'

* Fix nindent in chart template

* Fix nodeSelector position in helm jenkins template
2022-06-20 21:25:37 +02:00
Tomas Hulata 3362aae2a3
helmchart: hostAliases support (#720)
Signed-off-by: tombokombo <tombo@sysart.tech>
2022-06-20 21:22:17 +02:00
Piotr Ryba a97f283fb9
Remove cron validation (#748)
* Remove cron validation

* Bump git plugin
2022-06-20 20:13:35 +02:00
Bastien HUBERT 56b65aed16
Allow to specify seed agent image (#718)
* Allow to specify seed agent image

* Fix formatting issue

* Add optional for documentation

* Add entry for helm chart

* Add default value for helm chart

Co-authored-by: bhubert <bhubert@expediagroup.com>
2022-06-14 11:39:24 +02:00
Andras Szerdahelyi 46f64fea6a
Seed job SCM may now be configured with github-branch-source/GitHubAppCredentials (#719)
* Now allowing seed jobs to be configured with GithubAppCredential

* fmt

* Validation for GithubAppCredentials type seed job SCM secret

* GithubAppCredentials validation error messages were not referring to actual GithubAppCredentials fields

* cleanup
2022-05-31 16:04:03 +02:00
thecooldrop 13f871b1e4
Remove the validation of plugin version against a regex (#729) 2022-04-04 11:52:13 +02:00
Mateusz Korus 4fde1df8d8
Fix nil reference panic when using non-http readiness probe (#735) 2022-04-04 11:51:34 +02:00
github-actions[bot] 49bdf518de
Auto-updated docs (#724)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2022-02-28 16:22:06 +01:00
github-actions[bot] d3b1fd8172
Auto-updated docs (#717)
Co-authored-by: MKajzik <MKajzik@users.noreply.github.com>
2022-02-28 16:17:05 +01:00
Mateusz Kajzik 47eb115219
Docs: Fix yaml with configuration 2022-02-18 11:26:54 +01:00
Mateusz Kajzik 4c60936da2 Fix yaml in configuration 2022-02-17 14:34:45 +01:00
Mateusz Kajzik 202d7a87b7
Merge pull request #1 from jenkinsci/master
Merge master
2022-02-17 14:02:29 +01:00
Bastien HUBERT 29c5b1e705
Fix nightly release pipeline (#714)
* Add buildx create command to makefile to specify driver for the builder

* Use docker-container as driver for docker buildx

Co-authored-by: bhubert <bhubert@expediagroup.com>
2022-02-16 12:33:17 +01:00
Guillaume Le Biller 17a5bfec3e
Build multi-arch images (#693)
* Build multi-arch images

* Reduce CPU requirements for jenkins instances in e2e tests

* Bump Jenkins LTS & plugins versions
2022-02-15 14:51:29 +01:00
Szymon Fugas e8414c09a8
chore: enable manual run of nightly builds with possibility of skipping tests (#712)
* Add manual dispatch trigger for nightly build workflow, with an input parameter for optionally skipping the e2e and helm tests part of the workflow

* Bump how much memory to start minikube cluster with on e2e test workflows

* Log events from default namespace on tests failure, bump the limit of kubernetes events logged to 30

* Bump workflow-job plugin version used by default from 2.42 to 1145.v7f2433caa07f
2022-02-10 18:03:08 +01:00
João Valença 424ec3fbc2
Receive plugins' versions with underscores. (#699)
* Receive plugins versions with underscores.

New jenkins plugin versions have underscores in them (example: https://plugins.jenkins.io/credentials/). The operator refuses configuration for such plug-ins as they do not match the existing regex.

* Add tests to underscores in plugin versions

Adds a new test to check that versions with underscores are valid.

* Synchronise regexps character order to avoid range

Make two related regexps more evidently similar to each other and re-order the symbols so that the - is not interpreted.
2022-01-27 10:58:27 +01:00
thecooldrop 0f507409cc
Fixes #687 (#688)
This is necessary in order to be able to provide the annotations attached to the
service account associated with the Jenkins master instance.

Co-authored-by: Vanio Begic <vanio.begic@capgemini.com>
2021-12-23 13:37:08 +01:00
Andre 2724ec2f70
#685 Do not strip leading whitespace from priorityClassName in helm template (#686) 2021-12-22 08:16:11 +01:00
Andre 7fb4add0b2
#689 ignore packaged helm charts (#690) 2021-12-21 09:20:00 +01:00
Szymon Fugas 64de9aad91
chore: fix Helm chart release workflow (#683)
Modified sed usage in Helm chart release workflow to account for dependencies section present in Chart.yaml 

Unify usage of sed across Helm chart release workflow
2021-12-15 14:40:03 +01:00
Sylwia Brant dd6e48c8d5 Release 0.6.0 Helm Chart 2021-12-08 14:22:11 +01:00
Sylwia Brant 2b158d5bda Update Operator image in Helm Chart 2021-12-08 14:03:52 +01:00
github-actions[bot] 445d48ab54
Auto-updated docs (#681)
Co-authored-by: SylwiaBrant <SylwiaBrant@users.noreply.github.com>
2021-12-08 13:35:21 +01:00
Sylwia Brant 8d953ae457 Update website - 0.7.0 release 2021-12-08 13:18:09 +01:00
Sylwia Brant 76078d5ff2 Bump version to v0.7.0 2021-12-08 10:26:46 +01:00
maslakov e2f19454b1
#674 move imagePullSecrets in template (#675)
* Update jenkins.yaml

fix https://github.com/jenkinsci/kubernetes-operator/issues/674

* Fix nindent to be 4
2021-12-07 11:59:54 +01:00
SylwiaBrant 7e94bc623f
Prepare for Security Validator release (#680)
* Tidy up k8s events logging
* Increase memory and decrease CPU in resources
* Standarize API fields
* Refactor tests
* Change image and resources for e2e tests
* Increase readability
2021-12-07 08:23:58 +01:00
SylwiaBrant 89fa53ae08
Merge pull request #678 from comjf/patch-1
Update broken documentation links
2021-12-06 11:30:34 +01:00
James Flowers 907be3a214
Update broken documentation links
Update seed-job-creation-tutorial link referenced in values.yaml
2021-11-10 16:35:46 -05:00
github-actions[bot] 93072ae7b3
Auto-updated docs (#676)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-11-08 17:13:17 +01:00
Hervé Le Meur b3e06ad85a
docs: update Jenkins plugins versions in doc (#672)
Follow-up of https://github.com/jenkinsci/kubernetes-operator/pull/670
2021-11-08 17:05:42 +01:00
SylwiaBrant e27992ba9e
Merge pull request #670 from manut/bugfix_669
Update jenkins base plugins to latest version (#669)
2021-10-20 16:33:45 +02:00
Manuel Traut e03ca0674a Upgrade Jenkins Master default docker image to latest LTS
Current plugin versions require at least Jenkins 2.289

Signed-off-by: Manuel Traut <manuel.traut@mt.com>
2021-10-20 14:31:06 +02:00
github-actions[bot] 75826d5367
Auto-updated docs (#671)
Co-authored-by: KorusMateusz <KorusMateusz@users.noreply.github.com>
2021-10-20 14:09:17 +02:00
Kalmalyzer 7092beabdc
Added config + instructions for testing on Docker Desktop (#668) 2021-10-20 14:03:26 +02:00
Manuel Traut d6f1dcbb54 Update jenkins plugins in tests to latest version (#669)
Since the base plugins are updated compatible plugins need to be
used in the tests.

Signed-off-by: Manuel Traut <manuel.traut@mt.com>
2021-10-20 09:51:50 +02:00
Manuel Traut 90d26f0548 Update jenkins base plugins to latest version (#669)
Signed-off-by: Manuel Traut <manuel.traut@mt.com>
2021-10-18 15:32:05 +02:00
Szymon Fugas b1a388b6d6
Chore: #611 delete old manifests (#666)
* Delete jenkinsimages CRDs, old Jenkins CRD and CR and OpenShift Jenkins CR

* Delete old, olm-related manifests

* Delete Operator manifests that are covered by all-in-one
2021-10-08 17:12:46 +02:00
github-actions[bot] b3a4a6ca80
Auto-updated docs (#665)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-10-08 09:04:22 +02:00
github-actions[bot] 2663555170
Auto-updated docs (#664)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-10-08 08:40:13 +02:00
kalle (jag) b4345b2905
Added documentation for LDAP (#658)
* Added documentation for LDAP

Related to #133
Inspired by https://github.com/jenkinsci/kubernetes-operator/issues/133#issuecomment-555976832
2021-10-06 16:35:57 +02:00
github-actions[bot] 14b0018a7f
Auto-updated docs (#663)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-10-06 16:06:10 +02:00
Szymon Fugas 273eab0a69
Docs: General fixes and improvements (#662)
* Restore security docs (non-versioned), fix troubleshooting section

* Fix links in security page, add prerequisites to deploying jenkins

* Minor fixes in troubleshooting section

* Fix order of main sections

* Remove tools guide from developer guide

* Fix order of Getting Started guide parts
2021-10-06 16:02:29 +02:00
github-actions[bot] 266c2aa50d
Auto-updated docs (#660)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-10-01 13:53:57 +02:00
github-actions[bot] 768d1ac617
Auto-updated docs (#655)
Co-authored-by: SylwiaBrant <SylwiaBrant@users.noreply.github.com>
2021-10-01 10:44:14 +02:00
Mateusz Korus 764a144c5a
Regenerate crds (#659) 2021-09-30 11:42:35 +02:00
Mateusz Korus 31c8368c55
Add HostAliases to schema (#656)
Add HostAliases to schema and propagate them to pods so the user can add entries to /etc/hosts
2021-09-24 15:00:14 +02:00
SylwiaBrant dfae860ca8
Security validator - Pulkit Sharma's GSoC project 2021-09-02 10:28:40 +02:00
SylwiaBrant b4aed5c154
Merge pull request #654 from sharmapulkit04/security-validator
Updated docs
2021-09-01 15:46:28 +02:00
sharmapulkit04 c8d640cc8c Updated docs 2021-09-01 18:17:43 +05:30
Sylwia Brant 225448b965 Revert accidental rebase 2021-09-01 14:26:27 +02:00
SylwiaBrant 2e8fed4e59
Merge pull request #651 from sharmapulkit04/security-validator-manifests
Added kubectl manifests to deploy webhook
2021-09-01 11:43:38 +02:00
sharmapulkit04 78d33977a7 Fixed docs and Makefile 2021-08-31 18:55:46 +05:30
sharmapulkit04 7ae767ac84 Merge branch 'security-validator' into security-validator-manifests 2021-08-30 18:25:05 +05:30
sharmapulkit04 51f7ec8248 Implemented validation logic for the webhook (#593)
* Fix workflow for autogenerating docs (#592)

* Use grep -c flag in check for changes step to fix case when more than 1 website file was modified

* Implemented validation logic for the webhook
- Created a single Validate() function to validate both updating and creating Jenkins CR.
- Implemented the Validate function to fetch warnings from the API and do security check if
  being enabled.
- Updated the helm charts and helm-e2e target to run the helm tests.

* Configure bot for labelling new issues as needing triage (#597)

* Configure bot for managing stale issues (#598)

* Docs: explanation what is backed up and why (#599)

* Explanation what's backed up and why

* Auto-updated docs (#600)

Co-authored-by: prryb <prryb@users.noreply.github.com>

* Docs: clarification of description of get latest command in backup (#601)

* Auto-updated docs (#602)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Bump seedjobs agent image version to 4.9-1 (#604)

* Add GitLFS pull after checkout behaviour to SeedJob GroovyScript Template (#483)

Add GitLFS pull after checkout behaviour to support also repositories which are relying on Git LFS

Close #482

* Docs: minor fixes (#608)

* Link to project's DockerHub in README's section on nightly builds, add paragraph about nightly builds in installation docs

* Fix repositoryURL in sample seedJob configuration with SSH auth

* Slightly expand on #348

* Fix formatting in docs on Jenkins' customization, update plugin versions

* Add notes on Jenkins home Volume in Helm chart values.yaml and docs (#589)

* Auto-updated docs (#610)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Reimplemented the validation logic with caching the security warnings
- Reimplemented the validator interface
- Updated manifests to allocate more resources

* Add an issue template for documentation (#613)

* Docs: add info on restricted volumeMounts other than jenkins-home(#612)

* Update note in installation docs

* Update Helm chart default values.yaml

* Update schema

* Auto-updated docs (#616)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Auto-updated docs (#617)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Updated Validation logic
- Defined a security manager struct to cache all the plugin data
- Added flag to make validating security warnings optional while deploying the operator

* Helm Chart: Remove empty priorityClassName from Jenkins template (#618)

Also bump Helm Chart version to v0.5.2

* Added unit test cases for webhook

* Updated Helm Charts
- Optimized the charts
- Made the webhook optional
- Added cert manager as dependency to be installed while running webhook

* Updated unit tests, helm charts and validation logic

* Completed helm e2e tests and updated helm charts
- Completed helm tests for various scenarios
- Disabled startupapi check for cert manager webhook, defined a secret and updated templates
- Made the webhook completely optional

* Code optimization and cleanup

* Modified helm tests

* code cleanup and optimization
2021-08-30 08:21:52 +02:00
Mateusz Korus 4aa34157c3 Merge master (#620)
* Fix workflow for autogenerating docs (#592)

* Use grep -c flag in check for changes step to fix case when more than 1 website file was modified

* Configure bot for labelling new issues as needing triage (#597)

* Configure bot for managing stale issues (#598)

* Docs: explanation what is backed up and why (#599)

* Explanation what's backed up and why

* Auto-updated docs (#600)

Co-authored-by: prryb <prryb@users.noreply.github.com>

* Docs: clarification of description of get latest command in backup (#601)

* Auto-updated docs (#602)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Bump seedjobs agent image version to 4.9-1 (#604)

* Add GitLFS pull after checkout behaviour to SeedJob GroovyScript Template (#483)

Add GitLFS pull after checkout behaviour to support also repositories which are relying on Git LFS

Close #482

* Docs: minor fixes (#608)

* Link to project's DockerHub in README's section on nightly builds, add paragraph about nightly builds in installation docs

* Fix repositoryURL in sample seedJob configuration with SSH auth

* Slightly expand on #348

* Fix formatting in docs on Jenkins' customization, update plugin versions

* Add notes on Jenkins home Volume in Helm chart values.yaml and docs (#589)

* Auto-updated docs (#610)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Add an issue template for documentation (#613)

* Docs: add info on restricted volumeMounts other than jenkins-home(#612)

* Update note in installation docs

* Update Helm chart default values.yaml

* Update schema

* Auto-updated docs (#616)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Auto-updated docs (#617)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Helm Chart: Remove empty priorityClassName from Jenkins template (#618)

Also bump Helm Chart version to v0.5.2

* Fix bad identation in chart/index.yaml (#619)

Co-authored-by: Szymon Fugas <sz.fugas@gmail.com>
Co-authored-by: Piotr Ryba <55996264+prryb@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: prryb <prryb@users.noreply.github.com>
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
Co-authored-by: Cosnita Radu Viorel <radu.cosnita@gmail.com>
Co-authored-by: Morten Birkelund <mbi@salecto.com>
Co-authored-by: Ernestas <ernetas@gmail.com>
2021-08-30 08:21:52 +02:00
sharmapulkit04 626246ac4d Added validation webhook,cert-manager,and updated Makefile.
- Scaffolded a new validation webhook using operator-sdk
- Added manifests for webhook.
- Added manifests for self signed issuer and certificates
- Added a new spec named ValidateSecurityWarnings to the Jenkins custom resource definition to enable/disable security check.
- Updated Makefile to deploy the operator locally.
- Updated helm template and default values.yaml
2021-08-27 14:29:50 +02:00
sharmapulkit04 b8f5157906 Added kubectl manifests to deploy webhook
- Updatedd Makefile
- Added yaml manifests in deploy/
- Removed webhook/
2021-08-27 03:44:02 +05:30
sharmapulkit04 55c3e88037 Merge branch 'master' of github.com:jenkinsci/kubernetes-operator into security-validator-docs 2021-08-27 02:58:20 +05:30
sharmapulkit04 d4917b46dd Completed Documentation 2021-08-27 02:57:32 +05:30
Sig00rd 126b02aaab
Fix broken links in README (#648) 2021-08-23 16:38:42 +02:00
sharmapulkit04 5423173340 Merge branch 'security-validator' of github.com:jenkinsci/kubernetes-operator into security-validator-docs 2021-08-23 19:14:30 +05:30
sharmapulkit04 586515b212 Updated Documentation 2021-08-23 18:57:26 +05:30
sharmapulkit04 34c9ee3cd5
Implemented validation logic for the webhook (#593)
* Fix workflow for autogenerating docs (#592)

* Use grep -c flag in check for changes step to fix case when more than 1 website file was modified

* Implemented validation logic for the webhook
- Created a single Validate() function to validate both updating and creating Jenkins CR.
- Implemented the Validate function to fetch warnings from the API and do security check if
  being enabled.
- Updated the helm charts and helm-e2e target to run the helm tests.

* Configure bot for labelling new issues as needing triage (#597)

* Configure bot for managing stale issues (#598)

* Docs: explanation what is backed up and why (#599)

* Explanation what's backed up and why

* Auto-updated docs (#600)

Co-authored-by: prryb <prryb@users.noreply.github.com>

* Docs: clarification of description of get latest command in backup (#601)

* Auto-updated docs (#602)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Bump seedjobs agent image version to 4.9-1 (#604)

* Add GitLFS pull after checkout behaviour to SeedJob GroovyScript Template (#483)

Add GitLFS pull after checkout behaviour to support also repositories which are relying on Git LFS

Close #482

* Docs: minor fixes (#608)

* Link to project's DockerHub in README's section on nightly builds, add paragraph about nightly builds in installation docs

* Fix repositoryURL in sample seedJob configuration with SSH auth

* Slightly expand on #348

* Fix formatting in docs on Jenkins' customization, update plugin versions

* Add notes on Jenkins home Volume in Helm chart values.yaml and docs (#589)

* Auto-updated docs (#610)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Reimplemented the validation logic with caching the security warnings
- Reimplemented the validator interface
- Updated manifests to allocate more resources

* Add an issue template for documentation (#613)

* Docs: add info on restricted volumeMounts other than jenkins-home(#612)

* Update note in installation docs

* Update Helm chart default values.yaml

* Update schema

* Auto-updated docs (#616)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Auto-updated docs (#617)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Updated Validation logic
- Defined a security manager struct to cache all the plugin data
- Added flag to make validating security warnings optional while deploying the operator

* Helm Chart: Remove empty priorityClassName from Jenkins template (#618)

Also bump Helm Chart version to v0.5.2

* Added unit test cases for webhook

* Updated Helm Charts
- Optimized the charts
- Made the webhook optional
- Added cert manager as dependency to be installed while running webhook

* Updated unit tests, helm charts and validation logic

* Completed helm e2e tests and updated helm charts
- Completed helm tests for various scenarios
- Disabled startupapi check for cert manager webhook, defined a secret and updated templates
- Made the webhook completely optional

* Code optimization and cleanup

* Modified helm tests

* code cleanup and optimization
2021-08-23 15:18:31 +02:00
sharmapulkit04 ba66ba4c4d code cleanup and optimization 2021-08-23 17:24:13 +05:30
sharmapulkit04 95c29d4994 Modified helm tests 2021-08-22 05:16:14 +05:30
sharmapulkit04 9594c8e7cd Code optimization and cleanup 2021-08-22 03:51:50 +05:30
github-actions[bot] de02559c68
Auto-updated docs (#641)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-20 16:24:01 +02:00
Sig00rd 9761d6a576
Fix broken links in 0.6 docs (#640) 2021-08-20 16:08:16 +02:00
sharmapulkit04 f527a8c5cb Completed helm e2e tests and updated helm charts
- Completed helm tests for various scenarios
- Disabled startupapi check for cert manager webhook, defined a secret and updated templates
- Made the webhook completely optional
2021-08-20 12:37:55 +05:30
github-actions[bot] 2c240538e0
Auto-updated docs (#639)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-19 18:15:16 +02:00
Sig00rd a1d98a73e7
Regenerate docs (#638)
* Update last modified dates

* Regenerate docs
2021-08-19 18:09:37 +02:00
Sig00rd b84617b1ba
Fix docs autogen workflow case where markdown files were deleted (#637) 2021-08-19 17:46:12 +02:00
Sig00rd 03cfa758f5
Docs: information architecture and security guide update (#634)
* Add FAQ section

* Add Troubleshooting section

* Use Jenkins Operator as project name instead of jenkins-operator

* Move installation and security pages to section on version they are for

* Fix order of versions in getting started in section menu

* Configure side bar menu to be compact

* Rename getting started subpages

* Update Security docs for 0.6 (#611)

* Fix ordering of main sections in docs section menu

* Add more descriptive names for customization and configuration sections

* Update Getting Started index to link to latest version installation
2021-08-19 17:14:34 +02:00
github-actions[bot] f8621fcb81
Auto-updated docs (#635)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-18 18:47:23 +02:00
github-actions[bot] 4657ed6d65
Auto-updated docs (#633)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-18 18:36:30 +02:00
Sig00rd e88d63fdf7
Docs: minor fixes (#632)
* Fix descriptions of major releases

* Update meta links 'create documentation issue' link to use new docs issue template

* Update meta links 'create project issue' link to open issue template list instead of blank issue from meta links

* Fix typo in markdown in docs issue template

* Add Jenkins Discourse section in index, revisit index and about pages

* Fix favicon not showing by generating more favicon sizes with icongen
2021-08-18 17:53:19 +02:00
sharmapulkit04 e2ec2ea329 Updated unit tests, helm charts and validation logic 2021-08-18 05:57:28 +05:30
Sig00rd 38e46a13dd
Fix Helm package URL in Makefile & Index entry for 0.5.3 (#631)
* Fix url pointing to 0.5.3 Helm chart package in index

* Fix url used for indexing latest chart version in Makefile target releasing chart
2021-08-16 15:01:24 +02:00
github-actions[bot] 39ec91da29
Auto-updated docs (#630)
Co-authored-by: prryb <prryb@users.noreply.github.com>
2021-08-16 10:56:48 +02:00
Sig00rd 4e046280a3
Workflow: Release Helm chart (#626)
* Add Makefile target to release latest version of Helm chart

* Add workflow that packages Helm chart release and creates PR with it

* Remove old Helm targets
2021-08-16 10:54:12 +02:00
Piotr Ryba 16b4723b79
Fix links on Installation page (#629) 2021-08-16 10:51:11 +02:00
sharmapulkit04 5ca4e0a90c Updated Helm Charts
- Optimized the charts
- Made the webhook optional
- Added cert manager as dependency to be installed while running webhook
2021-08-16 04:24:24 +05:30
Sig00rd ff6e03539c
Add step to update 'last modified' date in docs autogen workflow (#627) 2021-08-13 16:55:58 +02:00
sharmapulkit04 b11ca32d1a Added unit test cases for webhook 2021-08-13 02:33:23 +05:30
Sig00rd 058ea61d70
Update project and repo documents (#621)
* Removed Contributor Covenant version from Code of Conduct doc

* Added a note on PRs with changes to Helm Chart to CONTRIBUTING doc

* Mentioned Discourse as current main channel of communication in README

* Updated ROADMAP
2021-08-12 10:58:54 +02:00
sharmapulkit04 90b685db9b Merge branch 'security-validator' of github.com:jenkinsci/kubernetes-operator into security-validator 2021-08-12 13:13:39 +05:30
Sig00rd 851fb0d3e9
Release 0.5.3 Helm Chart 2021-08-11 16:57:24 +02:00
Sig00rd 65bc574cb8
Helm chart: Fix role and rb templates for case with jenkins ns being empty string (#624) 2021-08-11 14:49:53 +02:00
Sig00rd ba78896ea6
Stale bot: configure time to close to 30 days after stale (#622) 2021-08-10 12:15:46 +02:00
sharmapulkit04 9106582a9e Merge branch 'master' of github.com:jenkinsci/kubernetes-operator into security-validator
- Refactored code in webhook and main
- Merged changes from master
2021-08-10 15:27:37 +05:30
Oleksandr Kovalchuk aedc2aff59
Add handling of empty WATCH_NAMESPACE value of jenkins.namespace (#609)
* Add note that jenkins.namespace also affects jenkins-operator resources

* Add handling of empty WATCH_NAMESPACE value of jenkins.namespace

If jenkins.namespace is set to "", it leads to WATCH_NAMESPACE
environment value of Jenkins Operator itself to be set to "", which
leads that operator watches all namespaces (see
https://github.com/jenkinsci/kubernetes-operator/issues/77#issuecomment-523727092).
This case requires custom handling: instead of creating role and
role_binding we need to create clusterrole and clusterrolebinding with
the required permissions.

* Bump chart version

* Fix grammar as suggested by @Sig00rd

Co-authored-by: Sig00rd <sz.fugas@gmail.com>
2021-08-10 11:36:53 +02:00
Mateusz Korus 3e5d80269d
Merge master (#620)
* Fix workflow for autogenerating docs (#592)

* Use grep -c flag in check for changes step to fix case when more than 1 website file was modified

* Configure bot for labelling new issues as needing triage (#597)

* Configure bot for managing stale issues (#598)

* Docs: explanation what is backed up and why (#599)

* Explanation what's backed up and why

* Auto-updated docs (#600)

Co-authored-by: prryb <prryb@users.noreply.github.com>

* Docs: clarification of description of get latest command in backup (#601)

* Auto-updated docs (#602)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Bump seedjobs agent image version to 4.9-1 (#604)

* Add GitLFS pull after checkout behaviour to SeedJob GroovyScript Template (#483)

Add GitLFS pull after checkout behaviour to support also repositories which are relying on Git LFS

Close #482

* Docs: minor fixes (#608)

* Link to project's DockerHub in README's section on nightly builds, add paragraph about nightly builds in installation docs

* Fix repositoryURL in sample seedJob configuration with SSH auth

* Slightly expand on #348

* Fix formatting in docs on Jenkins' customization, update plugin versions

* Add notes on Jenkins home Volume in Helm chart values.yaml and docs (#589)

* Auto-updated docs (#610)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Add an issue template for documentation (#613)

* Docs: add info on restricted volumeMounts other than jenkins-home(#612)

* Update note in installation docs

* Update Helm chart default values.yaml

* Update schema

* Auto-updated docs (#616)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Auto-updated docs (#617)

Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>

* Helm Chart: Remove empty priorityClassName from Jenkins template (#618)

Also bump Helm Chart version to v0.5.2

* Fix bad identation in chart/index.yaml (#619)

Co-authored-by: Szymon Fugas <sz.fugas@gmail.com>
Co-authored-by: Piotr Ryba <55996264+prryb@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: prryb <prryb@users.noreply.github.com>
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
Co-authored-by: Cosnita Radu Viorel <radu.cosnita@gmail.com>
Co-authored-by: Morten Birkelund <mbi@salecto.com>
Co-authored-by: Ernestas <ernetas@gmail.com>
2021-08-10 09:58:24 +02:00
Ernestas 2d1a67afb9
Fix bad identation in chart/index.yaml (#619) 2021-08-09 18:40:59 +02:00
Morten Birkelund 853f485746
Helm Chart: Remove empty priorityClassName from Jenkins template (#618)
Also bump Helm Chart version to v0.5.2
2021-08-09 14:57:00 +02:00
sharmapulkit04 1d2651d43f Updated Validation logic
- Defined a security manager struct to cache all the plugin data
- Added flag to make validating security warnings optional while deploying the operator
2021-08-06 19:12:09 +05:30
github-actions[bot] b400a420e5
Auto-updated docs (#617)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-06 13:06:12 +02:00
github-actions[bot] b82fc7c764
Auto-updated docs (#616)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-06 10:03:57 +02:00
Szymon Fugas 858f0f4c72
Docs: add info on restricted volumeMounts other than jenkins-home(#612)
* Update note in installation docs

* Update Helm chart default values.yaml

* Update schema
2021-08-05 17:28:01 +02:00
Szymon Fugas 8453b3e9fe
Add an issue template for documentation (#613) 2021-08-05 17:27:19 +02:00
sharmapulkit04 37d0eac4e3 Reimplemented the validation logic with caching the security warnings
- Reimplemented the validator interface
- Updated manifests to allocate more resources
2021-08-05 04:39:27 +05:30
github-actions[bot] 17dba087b8
Auto-updated docs (#610)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-08-02 16:22:29 +02:00
Szymon Fugas dfd25e822c
Docs: minor fixes (#608)
* Link to project's DockerHub in README's section on nightly builds, add paragraph about nightly builds in installation docs

* Fix repositoryURL in sample seedJob configuration with SSH auth

* Slightly expand on #348

* Fix formatting in docs on Jenkins' customization, update plugin versions

* Add notes on Jenkins home Volume in Helm chart values.yaml and docs (#589)
2021-08-02 15:52:10 +02:00
Cosnita Radu Viorel 935b60b6d8
Add GitLFS pull after checkout behaviour to SeedJob GroovyScript Template (#483)
Add GitLFS pull after checkout behaviour to support also repositories which are relying on Git LFS

Close #482
2021-07-29 11:44:51 +02:00
Szymon Fugas 9d5c525ace
Bump seedjobs agent image version to 4.9-1 (#604) 2021-07-23 10:29:04 +02:00
github-actions[bot] bd32624fe1
Auto-updated docs (#602)
Co-authored-by: Sig00rd <Sig00rd@users.noreply.github.com>
2021-07-21 09:54:59 +02:00
Szymon Fugas 463cad3b07
Docs: clarification of description of get latest command in backup (#601) 2021-07-20 14:58:04 +02:00
github-actions[bot] 7ce9d1f077
Auto-updated docs (#600)
Co-authored-by: prryb <prryb@users.noreply.github.com>
2021-07-20 14:56:36 +02:00
Piotr Ryba 35dfd47ec7
Docs: explanation what is backed up and why (#599)
* Explanation what's backed up and why
2021-07-20 12:06:25 +02:00
Szymon Fugas 800c1a7d5d
Configure bot for managing stale issues (#598) 2021-07-19 16:04:45 +02:00
Szymon Fugas db0978c4d4
Configure bot for labelling new issues as needing triage (#597) 2021-07-16 11:45:43 +02:00
sharmapulkit04 52fe5fe95e Implemented validation logic for the webhook
- Created a single Validate() function to validate both updating and creating Jenkins CR.
- Implemented the Validate function to fetch warnings from the API and do security check if
  being enabled.
- Updated the helm charts and helm-e2e target to run the helm tests.
2021-07-15 02:53:49 +05:30
Szymon Fugas b407e51bba
Fix workflow for autogenerating docs (#592)
* Use grep -c flag in check for changes step to fix case when more than 1 website file was modified
2021-07-07 13:18:18 +02:00
SylwiaBrant 16a1ad8314
Merge pull request #585 from sharmapulkit04/security-validator
Added validation webhook,cert-manager,and updated Makefile.
2021-07-01 09:48:50 +02:00
sharmapulkit04 e87c7cac5f Added validation webhook,cert-manager,and updated Makefile.
- Scaffolded a new validation webhook using operator-sdk
- Added manifests for webhook.
- Added manifests for self signed issuer and certificates
- Added a new spec named ValidateSecurityWarnings to the Jenkins custom resource definition to enable/disable security check.
- Updated Makefile to deploy the operator locally.
- Updated helm template and default values.yaml
2021-06-30 20:34:51 +05:30
github-actions[bot] 63370a55cc
Auto-updated docs (#583) 2021-06-16 14:20:45 +02:00
Szymon Fugas eb256fec76
Update Minikube and Kubernetes versions in Minikube env config (#582)
* Update minikube and kubernetes version in minikube env config

* Update minikube version in docs' developer's guide
2021-06-16 14:01:25 +02:00
Michael Schmid 222af51cb9
Update Kubernetes to 1.30.0 (#579) 2021-06-16 11:23:04 +02:00
Szymon Fugas 6cc53704e8
Makefile goal to run docs locally (#578)
* Add makefile goal to run docs locally
2021-06-15 16:32:43 +02:00
Szymon Fugas ec6e288673
Regerate docs (#577)
Co-authored-by: Sig00rd <sfugas@virtuslab.com>
2021-06-11 15:44:14 +02:00
Szymon Fugas 040fbbfea5
Separate instructions on YAML vs Helm installation in docs (#576)
* Fix link to Installation on Getting started index

* Separate instructions on installing via YAML and Helm more clearly

* Link deploy jenkins section in instructions on installing via YAML

Co-authored-by: Sig00rd <sfugas@virtuslab.com>
2021-06-11 15:34:02 +02:00
Tomasz Sęk b9059bc26b
Release 0.5.1 Helm Chart 2021-06-11 13:53:13 +02:00
Mateusz Korus 27213fdc48 Regenerate docs 2021-06-10 16:26:11 +02:00
Mateusz Korus 985517b04f
Copy sample cr to docs with new required values && fix urls (#575) 2021-06-10 16:21:49 +02:00
Mateusz Korus 485abaad8d Release 0.5.0 Helm Chart 2021-06-10 11:29:09 +02:00
Mateusz Korus 46ee392a7c Generate website - 0.5.0 history 2021-06-10 10:53:40 +02:00
Mateusz Korus 20b1bb7169 Generate website - 0.6.0 release 2021-06-10 10:49:11 +02:00
Mateusz Korus cd3dbeb0a5 Update website - 0.6.0 release 2021-06-10 10:39:12 +02:00
Mateusz Korus fbea1ed790 Bump version to v0.6.0 2021-06-10 08:10:50 +02:00
SylwiaBrant e762957cc1
Add security-validator branch to tests triggers 2021-06-08 09:38:47 +02:00
SylwiaBrant 38fcdf5d37
#555 Add nightly release of a snapshot (#566)
* #555 Add nightly release of a snapshot

* Update README

* Bump image and plugins

* Bump image and plugins in Helm Chart
2021-05-24 12:13:27 +02:00
MKajzik 59d522c5d2
#554 Remove Deprecated JVM opts (#569)
* Upgrade base plugins
* Upgrade Jenkins image
* Remove deprecated JVM opts
2021-05-20 17:22:00 +02:00
Mateusz Korus 30723cf6f8 Remove preview of installation from generated docs 2021-05-17 13:21:22 +02:00
MKajzik 8a42cdc1ee
#560 Fixed envFrom not propagating to master pod (#564)
* Fixed envFrom not propagate to master pod
2021-05-11 15:58:56 +02:00
Mateusz Korus 81374d0857 Bump backup PVC version to v0.1.1 2021-05-06 11:17:51 +02:00
Piotr Ryba a7fb199f98
Regenerate docs (#558) 2021-05-05 12:08:01 +02:00
Piotr Ryba 41dac85ea1
#552 Seed Jobs: Don't Validate "external" Credential Type (#556)
* Don't validate external credential type

The operator shouldn't try to fetch credentials that have their types
defined as `external` - that means that credentials are supplied
externally, without using k8s secrets.

* Docs: Add example of `external` credential type
2021-05-05 09:27:43 +02:00
Tomasz Sęk 332c08ccf2
Update README.md 2021-05-01 17:44:09 +02:00
SylwiaBrant c74606a2ee
Migrate Helm Chart to OSDK v1.3.0 (#551)
Migrate Helm Chart to OSDK v1.3.0
2021-04-29 13:50:06 +02:00
Piotr Ryba 223119b62d
Skip kube-api-access Volume Comparison (#550)
* Skip kube-api-access volume comparison

This hotfixes the incompatibility between the Operator and Kubernetes
1.21.

Kubernetes 1.21 started adding a new volume named
"kube-api-access-<random-suffix>" and that broke the comparison
function and resulted in an infinite loop.
2021-04-28 14:23:00 +02:00
Piotr Ryba 0d118bf046
Fix WATCH_NAMESPACE in helm chart (#547)
* Fix WATCH_NAMESPACE in helm chart

When applying the chart, the operator will now watch the correct
namespace. This required changes in roles and role bindings so that
the operator has access to both namespaces.

* Use Role instead of ClusterRole

Mitigates the risk of restrictions in creating ClusterRole in
multitenant k8s clusters.

* Update configuration-as-code version to 1.47
2021-04-27 15:36:09 +02:00
Piotr Ryba 07d2e5e129
Use ssh.ParseRawPrivateKey to validate ssh private key (#546)
This allows the user to use keys other than PEM encoded RSA. ed25519
is often recommended to be used if it's supported. Using this
algorithm implies the use of OpenSSH key format in ssh-keygen.
2021-04-27 07:21:58 +02:00
SylwiaBrant 6595462398
Merge pull request #549 from jenkinsci/fix/#545-tmp-dir-clearing
#548 Fix clearing /tmp dir in backup script
2021-04-26 20:31:06 +02:00
Sylwia Brant 84b5499755 #548 Fix clearing /tmp dir in backup script 2021-04-26 15:57:13 +02:00
Mateusz Korus 57bb20bd41
Docs hotfix (#545)
* Fixed docs' styles and makefile goalFixed docs' styles and makefile goal

* Fix makefile
2021-04-16 14:57:58 +02:00
Piotr Ryba 53802eb60b
Add extra logs for Jenkins CR create/delete events (#536) 2021-04-16 12:10:41 +02:00
SylwiaBrant 212bbe2896
Merge pull request #544 from jenkinsci/update-docs
Update docs
2021-04-14 15:13:12 +02:00
Sylwia Brant d8e05db017 Update docs 2021-04-14 15:09:11 +02:00
Tomasz Sęk 9197c29a30
Update README.md 2021-04-06 14:56:31 +02:00
SylwiaBrant 4bf5c63e2e
Merge pull request #519 from pniederlag/patch-1
Update configure-backup-and-restore.md
2021-02-19 13:02:25 +01:00
Sylwia Brant 892b2c8dd9 Release 0.4.3 Helm Chart 2021-02-19 12:44:08 +01:00
Peter Niederlag b720176afa
Update configure-backup-and-restore.md
getLatestAction must be set on restore, not on backup
2021-02-19 12:03:28 +01:00
SylwiaBrant bf4bf4ecdd
Merge pull request #506 from emilkostadinov/feature/helm-backuprestore-last-action
Pass getLatestAction Helm value to the Jenkins instance
2021-02-19 11:28:11 +01:00
SylwiaBrant 652580c0a5
#507 Allow listing events (#514)
Added missing permissions for listing events by Jenkins
2021-02-12 15:38:23 +01:00
Tomasz Sęk 3dab502234
Merge pull request #510 from jenkinsci/operator-sdk-1.3.0
#494 Upgrade to Operator sdk 1.3.0
2021-02-12 12:19:45 +01:00
Sylwia Brant f1ea9d8ce9 Fix images in CRs 2021-02-11 16:10:37 +01:00
Sylwia Brant ce081bfd28 Add preview docs and Github Actions e2e test workflow 2021-02-10 16:59:26 +01:00
Fabiano Pimentel a78b9ea77b
Fix README.md latest schema link (#511) 2021-02-10 11:04:50 +01:00
Sylwia Brant d225cc113e Minikube downloaded to bin, test fixes 2021-02-08 13:37:00 +01:00
Sylwia Brant 77a79e8f97 Removed image CRD, updated plugins 2021-02-05 13:28:30 +01:00
SylwiaBrant 021ebb4745
Added TestPlugins, TestRestart and TestRestoreBackup (#504)
Co-authored-by: Tomasz Sęk
2021-02-05 13:17:06 +01:00
github-actions[bot] b69d1d4a23
Auto-updated docs (#509)
Co-authored-by: tomaszsek <tomaszsek@users.noreply.github.com>
2021-02-04 10:38:18 +01:00
Sylwia Brant 5bbd1585af Release 0.4.2 Helm Chart 2021-02-04 08:37:33 +01:00
SylwiaBrant 5f1b28f539
#503 Added JenkinsImage crd to Helm Chart (#508) 2021-02-04 08:28:38 +01:00
SylwiaBrant 4410ad6b88
Updated guide to 0.5.0 (#501)
- updated versions of plugins and images in the guide
- added 'get-latest' to backup docs
2021-02-02 12:26:26 +01:00
Emil Kostadinov 545c7b99b3 Pass getLatestAction helm value to the Jenkins instance 2021-02-01 06:00:48 +02:00
Tomasz Sęk 294be87c64
Makefile cleanup 2021-01-28 17:21:18 +01:00
Tomasz Sęk 814f5d77c1
Fix scheme-doc-gen Makefile goal 2021-01-27 16:32:16 +01:00
Tomasz Sęk ea861d8bd5
Download all dependent binaries into repo/bin 2021-01-27 16:12:47 +01:00
Tomasz Sęk e03b3f25a5
Fix container-runtime-build Makefile goal 2021-01-27 14:29:05 +01:00
Tomasz Sęk 53961d7bde
Fix logging 2021-01-27 12:32:08 +01:00
Tomasz Sęk 34ffdde054
Resolve some FIXME 2021-01-27 11:29:38 +01:00
Tomasz Sęk 363b9e0fc0
Resolve some FIXME 2021-01-27 10:33:38 +01:00
Tomasz Sęk 524d0b861f
Refactor e2e tests to new ginkgo framework 2021-01-26 22:00:23 +01:00
Tomasz Sęk 5f45777554
Release 0.4.1 Helm Chart 2021-01-23 14:12:06 +01:00
github-actions[bot] 3157b29373
Auto-updated docs (#500) 2021-01-23 14:08:43 +01:00
Mitsufumi KIkyotani 73db2e0fc9
Make livenessProbe and readinessProbe configurable in Helm chart (#499) 2021-01-23 14:00:27 +01:00
Bartek Antoniak 9713375a37
Merge pull request #492 from jenkinsci/contribiute-guide
Update docs and minor improvements
2021-01-22 16:16:28 +01:00
antoniaklja e6e00af4d9 Update docs and minor improvements
- add issue templates
- improve typos in README.md
- add ROADMAP.md
2021-01-22 13:39:10 +01:00
antoniaklja 57ecbee244 Update docs and minor improvements
- add issue templates
- improve typos in README.md
- add ROADMAP.md
2021-01-21 14:19:32 +01:00
antoniaklja e4e2d91a35 Update docs and minor improvements
- add issue templates
- improve typos in README.md
- add ROADMAP.md
2021-01-21 14:14:18 +01:00
antoniaklja 134c88fde7 Update docs and minor improvements
- add issue templates
- improve typos in README.md
- add ROADMAP.md
2021-01-21 14:13:50 +01:00
Sylwia Brant b6bf47b949 Added base for envtests 2021-01-20 15:46:39 +01:00
Tomasz Sęk cb26623f5f
Upgrade operator-sdk to 1.3.0 without e2e tests 2021-01-19 15:47:05 +01:00
Tomasz Sęk aa45c79c56
Release 0.4.0 Helm Chart 2021-01-18 16:18:04 +01:00
Tomasz Sęk ae0fe371ba
Update Helm Chart - 0.5.0 release 2021-01-18 16:13:27 +01:00
Tomasz Sęk 0c253e7753
Generate website - 0.5.0 release 2021-01-18 16:09:45 +01:00
SylwiaBrant 8f7af2a149
Add github actions for docs generation (#491) 2021-01-18 15:56:04 +01:00
Tomasz Sęk 9f261169f0
Update website - 0.5.0 release 2021-01-18 15:41:30 +01:00
500 changed files with 40073 additions and 97933 deletions

View File

@ -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"
}

5
.dockerignore Normal file
View File

@ -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

1
.envrc Normal file
View File

@ -0,0 +1 @@
has nix && use flake

22
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -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).

14
.github/ISSUE_TEMPLATE/documentation.md vendored Normal file
View File

@ -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

View File

@ -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.

28
.github/dependabot.yml vendored Normal file
View File

@ -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:
- "*"

View File

@ -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 -->

View File

@ -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)
_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
```

99
.github/workflows/auto-gen-docs.yaml vendored Normal file
View File

@ -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

View File

@ -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 }}

22
.github/workflows/auto-stale-issue.yaml vendored Normal file
View File

@ -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"

67
.github/workflows/auto-tests-bats.yaml vendored Normal file
View File

@ -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

115
.github/workflows/auto-tests-e2e.yaml vendored Normal file
View File

@ -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}

117
.github/workflows/auto-tests-helm.yaml vendored Normal file
View File

@ -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}

View File

@ -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.*$'

View File

@ -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

60
.github/workflows/release-backup.yaml vendored Normal file
View File

@ -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

View File

@ -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

89
.github/workflows/release-nightly.yaml vendored Normal file
View File

@ -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

57
.github/workflows/release.yaml vendored Normal file
View File

@ -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

126
.github/workflows/update-plugins.sh vendored Executable file
View File

@ -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 "$@"

14
.gitignore vendored
View File

@ -88,3 +88,17 @@ tags
### IntelliJ IDEA ###
*.iml
/bin
testbin/*
### Bats
chart/jenkins-operator/deploy.tmp
### Nix
result
### website
website/node_modules
website/public
website/.hugo_build.lock

View File

@ -1,29 +1,41 @@
run:
deadline: 10m
linters-settings:
errcheck:
check-blank: false
ignore: fmt:.*,io/ioutil:^Read.*,Write
deadline: 5m
allow-parallel-runners: true
skip-files:
- api/v1alpha2/zz_generated.deepcopy.go
issues:
exclude-use-default: false
exclude-rules:
- path: "internal/*"
linters:
- dupl
- path: (.+)_test.go
linters:
- dupl
linters:
enable-all: true
disable:
- funlen
- gocognit
- godox
- gomnd
- gochecknoglobals
- gochecknoinits
- lll
- prealloc
- wsl
- gocyclo
- scopelint
disable-all: true
enable:
- dupl
- gosec
- maligned
- testpackage
- goerr113
- errcheck
- exportloopref
- goconst
- gocyclo
- gofmt
- goimports
- gosimple
- govet
- ineffassign
- loggercheck
- misspell
- nakedret
- nestif
- godot
- staticcheck
- typecheck
- unconvert
- unparam
- unused
output:
sort-results: true
sort-order:
- file
- severity
- linter

26
.pre-commit-config.yaml Normal file
View File

@ -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

1
CODEOWNERS Normal file
View File

@ -0,0 +1 @@
* @brokenpip3

View File

@ -2,5 +2,4 @@
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.
[version]: http://contributor-covenant.org/version/1/4/
It applies to the entire `jenkinsci` GitHub organization, among other community spaces.

View File

@ -1,46 +1,50 @@
# Contributing
# Contribution Model
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
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)
Thanks for taking the time to contribute!
## 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
[these best practices](https://chris.beams.io/posts/git-commit/), specifically:
## We Use GitHub Flow, So All Code Changes Happen Through Pull Requests
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
- Contain a body that explains _why_ you're making the change you're making
- Reference an issue number one exists, closing it if applicable (with text such
as
["Fixes #245" or "Closes #111"](https://help.github.com/articles/closing-issues-using-keywords/))
- Create feature requests and discuss the scope.
- Fork the repo and create your branch from master.
- If youve added code that should be tested, add tests.
- If youve changed APIs or design, update the documentation.
- 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?
- 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?
### General Contribution
## 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.

42
Dockerfile Normal file
View File

@ -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
View File

@ -1,74 +1,4 @@
# Set POSIX sh for maximum interoperability
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
include variables.mk
.PHONY: all
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)
$(NAME): $(wildcard *.go) $(wildcard */*.go) VERSION.txt
@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
static: ## Builds a static executable
@ -136,22 +66,26 @@ fmt: ## Verifies all files have been `gofmt`ed
@go fmt $(PACKAGES)
.PHONY: lint
HAS_GOLINT := $(shell which golangci-lint)
HAS_GOLINT := $(shell which $(PROJECT_DIR)/bin/golangci-lint)
lint: ## Verifies `golint` passes
@echo "+ $@"
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
@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
HAS_GOIMPORTS := $(shell which goimports)
HAS_GOIMPORTS := $(shell which $(PROJECT_DIR)/bin/goimports)
goimports: ## Verifies `goimports` passes
@echo "+ $@"
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
@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
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)
.PHONY: e2e
CURRENT_DIRECTORY := $(shell pwd)
e2e: container-runtime-build ## Runs e2e tests, you can use EXTRA_ARGS
e2e: deepcopy-gen manifests backup-kind-load jenkins-kind-load ## Runs e2e tests, you can use EXTRA_ARGS
@echo "+ $@"
@echo "Docker image: $(DOCKER_REGISTRY):$(GITCOMMIT)"
ifeq ($(KUBERNETES_PROVIDER),minikube)
kubectl config use-context $(KUBECTL_CONTEXT)
endif
ifeq ($(KUBERNETES_PROVIDER),crc)
oc project $(CRC_OC_PROJECT)
endif
cp deploy/service_account.yaml deploy/namespace-init.yaml
cat deploy/role.yaml >> deploy/namespace-init.yaml
cat deploy/role_binding.yaml >> deploy/namespace-init.yaml
cat deploy/operator.yaml >> deploy/namespace-init.yaml
ifeq ($(OSFLAG), LINUX)
ifeq ($(IMAGE_PULL_MODE), remote)
sed -i 's|\(image:\).*|\1 $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT)|g' deploy/namespace-init.yaml
sed -i 's|\(imagePullPolicy\): IfNotPresent|\1: Always|g' deploy/namespace-init.yaml
RUNNING_TESTS=1 go test -parallel=1 "./test/e2e/" -ginkgo.v -tags "$(BUILDTAGS) cgo" -v -timeout 60m -run "$(E2E_TEST_SELECTOR)" \
-jenkins-api-hostname=$(JENKINS_API_HOSTNAME) -jenkins-api-port=$(JENKINS_API_PORT) -jenkins-api-use-nodeport=$(JENKINS_API_USE_NODEPORT) $(E2E_TEST_ARGS)
.PHONY: jenkins-kind-load
jenkins-kind-load: ## Load the jenkins lts version in kind to speed up tests
@echo "+ $@"
docker pull jenkins/jenkins:$(LATEST_LTS_VERSION)
kind load docker-image jenkins/jenkins:$(LATEST_LTS_VERSION) --name $(KIND_CLUSTER_NAME)
## Backup Section
.PHONY: backup-kind-load
backup-kind-load: ## Load latest backup image in the cluster
@echo "+ $@"
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
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
mkdir -p $(PROJECT_DIR)/bin
test -L $(PROJECT_DIR)/bin/helm || ln -sf $(shell command -v helm) $(PROJECT_DIR)/bin/helm
endif
ifeq ($(OSFLAG), OSX)
ifeq ($(IMAGE_PULL_MODE), remote)
sed -i '' 's|\(image:\).*|\1 $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT)|g' deploy/namespace-init.yaml
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
.PHONY: helm-lint
helm-lint: helm
bin/helm lint chart/jenkins-operator
RUNNING_TESTS=1 go test -parallel=1 "./test/e2e/" -tags "$(BUILDTAGS) cgo" -v -timeout 60m -run "$(E2E_TEST_SELECTOR)" \
-root=$(CURRENT_DIRECTORY) -kubeconfig=$(HOME)/.kube/config -globalMan deploy/crds/jenkins_$(API_VERSION)_jenkins_crd.yaml \
-namespacedMan deploy/namespace-init.yaml $(TEST_ARGS)
.PHONY: helm-release-latest
helm-release-latest: helm
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
vet: ## Verifies `go vet` passes
@ -207,23 +157,25 @@ vet: ## Verifies `go vet` passes
@go vet $(PACKAGES)
.PHONY: staticcheck
HAS_STATICCHECK := $(shell which staticcheck)
PLATFORM = $(shell echo $(UNAME_S) | tr A-Z a-z)
HAS_STATICCHECK := $(shell which $(PROJECT_DIR)/bin/staticcheck)
staticcheck: ## Verifies `staticcheck` passes
@echo "+ $@"
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
tar zxvf staticcheck_$(PLATFORM)_amd64.tar.gz
mkdir -p $(GOPATH)/bin
mv staticcheck/staticcheck $(GOPATH)/bin
$(eval TMP_DIR := $(shell mktemp -d))
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
tar zxvf $(TMP_DIR)/staticcheck_$(PLATFORM)_amd64.tar.gz -C $(TMP_DIR)
mkdir -p $(PROJECT_DIR)/bin
mv $(TMP_DIR)/staticcheck/staticcheck $(PROJECT_DIR)/bin
rm -rf $(TMP_DIR)
endif
@staticcheck $(PACKAGES)
@$(PROJECT_DIR)/bin/staticcheck $(PACKAGES)
.PHONY: cover
cover: ## Runs go test with coverage
@echo "" > coverage.txt
@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 \
cat profile.out >> coverage.txt; \
rm profile.out; \
@ -239,21 +191,62 @@ install: ## Installs the executable
@echo "+ $@"
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
run: export WATCH_NAMESPACE = $(NAMESPACE)
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 "+ $@"
ifeq ($(KUBERNETES_PROVIDER),minikube)
ifeq ($(KUBERNETES_PROVIDER),kind)
kubectl config use-context $(KUBECTL_CONTEXT)
endif
ifeq ($(KUBERNETES_PROVIDER),crc)
oc project $(CRC_OC_PROJECT)
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"
build/_output/bin/jenkins-operator $(OPERATOR_ARGS)
bin/manager $(OPERATOR_ARGS)
.PHONY: clean
clean: ## Cleanup any build binaries or packages
@ -308,46 +301,66 @@ endif
container-runtime-login: ## Log in into the Docker repository
@echo "+ $@"
.PHONY: container-runtime-build
container-runtime-build: check-env ## Build the container
.PHONY: container-runtime-build-%
container-runtime-build-%: ## Build the container
@echo "+ $@"
$(CONTAINER_RUNTIME_COMMAND) build \
--build-arg GO_VERSION=$(GO_VERSION) \
--build-arg OPERATOR_SDK_VERSION=$(OPERATOR_SDK_VERSION) \
-t $(DOCKER_REGISTRY):$(GITCOMMIT) . \
--file build/Dockerfile $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(CONTAINER_RUNTIME_COMMAND) buildx build \
--output=type=docker --platform linux/$* \
--build-arg GO_VERSION=$(GO_VERSION) \
--build-arg CTIMEVAR="$(CTIMEVAR)" \
--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
container-runtime-images: ## List all local containers
@echo "+ $@"
$(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
container-runtime-push: ## Push the container
container-runtime-push: check-env deepcopy-gen ## Push the container
@echo "+ $@"
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(BUILD_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(BUILD_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(call buildx-create-command)
$(call container-runtime-push-command,$(BUILD_TAG))
.PHONY: container-runtime-snapshot-push
container-runtime-snapshot-push:
container-runtime-snapshot-push: check-env deepcopy-gen
@echo "+ $@"
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(GITCOMMIT) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(call buildx-create-command)
$(call container-runtime-push-command,$(GITCOMMIT))
.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 "+ $@"
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(VERSION_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(VERSION_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(call buildx-create-command)
$(call container-runtime-push-command,$(VERSION_TAG))
.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 "+ $@"
$(CONTAINER_RUNTIME_COMMAND) tag $(DOCKER_REGISTRY):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(LATEST_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(CONTAINER_RUNTIME_COMMAND) push $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY):$(LATEST_TAG) $(CONTAINER_RUNTIME_EXTRA_ARGS)
$(call buildx-create-command)
$(call container-runtime-push-command,$(LATEST_TAG))
.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 "+ $@"
# 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.
INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
ifeq ($(INTERACTIVE), 1)
DOCKER_FLAGS += -t
DOCKER_FLAGS += -t
endif
.PHONY: container-runtime-run
@ -363,52 +376,29 @@ container-runtime-run: ## Run the container in docker, you can use EXTRA_ARGS
@echo "+ $@"
$(CONTAINER_RUNTIME_COMMAND) run $(CONTAINER_RUNTIME_EXTRA_ARGS) --rm -i $(DOCKER_FLAGS) \
--volume $(HOME)/.kube/config:/home/jenkins-operator/.kube/config \
$(DOCKER_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)
quay.io/${QUAY_ORGANIZATION}/$(QUAY_REGISTRY):$(GITCOMMIT) /usr/bin/jenkins-operator $(OPERATOR_ARGS)
.PHONY: crc-run
crc-run: export WATCH_NAMESPACE = $(NAMESPACE)
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 "+ $@"
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
deepcopy-gen: ## Generate deepcopy golang code
deepcopy-gen: generate ## Generate deepcopy golang code
@echo "+ $@"
operator-sdk generate k8s
.PHONY: scheme-doc-gen
HAS_GEN_CRD_API_REFERENCE_DOCS := $(shell ls gen-crd-api-reference-docs 2> /dev/null)
scheme-doc-gen: ## Generate Jenkins CRD scheme doc
@echo "+ $@"
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)
@tar -C $(GEN_CRD_API) -zxf $(GEN_CRD_API)_linux_amd64.tar.gz
@rm $(GEN_CRD_API)_linux_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')
@tar -C $(GEN_CRD_API) -zxf $(GEN_CRD_API)_$(PLATFORM)_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 $(PKG)/api/$(API_VERSION) -template-dir $(GEN_CRD_API)/template -out-file documentation/$(VERSION)/jenkins-$(API_VERSION)-scheme.md
.PHONY: check-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')
endif
.PHONY: minikube-start
minikube-start: check-minikube ## Start minikube
.PHONY: kind-setup
kind-setup: ## Setup kind cluster
@echo "+ $@"
@minikube status && exit 0 || \
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
kind create cluster --config kind-cluster.yaml --name $(KIND_CLUSTER_NAME)
.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
crc-start: check-crc ## Start CodeReady Containers Kubernetes cluster
@echo "+ $@"
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
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 "+ $@"
#@go get -u github.com/jessfraz/junk/sembump # update sembump tool FIXME
$(eval NEW_VERSION=$(shell sembump --kind $(BUMP) $(VERSION)))
$(eval NEW_VERSION=$(shell bin/sembump --kind $(BUMP) $(VERSION)))
@echo "Bumping VERSION.txt from $(VERSION) to $(NEW_VERSION)"
echo $(NEW_VERSION) > VERSION.txt
@echo "Updating version from $(VERSION) to $(NEW_VERSION) in README.md"
sed -i s/$(VERSION)/$(NEW_VERSION)/g README.md
sed -i s/$(VERSION)/$(NEW_VERSION)/g deploy/operator.yaml
sed -i 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
cat deploy/role.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
cat deploy/role_binding.yaml >> deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
cat deploy/operator.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
sed -i.bak 's/$(VERSION)/$(NEW_VERSION)/g' README.md
sed -i.bak 's/$(VERSION)/$(NEW_VERSION)/g' config/manager/manager.yaml
sed -i.bak 's/$(VERSION)/$(NEW_VERSION)/g' deploy/$(ALL_IN_ONE_DEPLOY_FILE_PREFIX)-$(API_VERSION).yaml
rm */*/**.bak
rm */**.bak
rm *.bak
cp config/service_account.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)"
@echo "Run make tag to create and push the tag for new version $(NEW_VERSION)"
.PHONY: tag
tag: ## Create a new git tag to prepare to build a release
@echo "+ $@"
git tag -s -a $(VERSION) -m "$(VERSION)"
git tag -a $(VERSION) -m "$(VERSION)"
git push origin $(VERSION)
.PHONY: help
@ -471,30 +497,187 @@ ifneq ($(GITUNTRACKEDCHANGES),)
endif
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
@echo "Ignored but tracked files:"
@git ls-files -i --exclude-standard
@git ls-files -i -o --exclude-standard
@echo
endif
@echo "Dependencies:"
go mod vendor -v
@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
helm-deploy: helm-package
@echo "+ $@"
helm repo index chart/ --url https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/
cd chart/ && mv jenkins-operator-*.tgz jenkins-operator
# Download and build hugo extended locally if necessary
HUGO_PATH = $(shell pwd)/bin/hugo
HUGO_VERSION = v0.99.1
HAS_HUGO := $(shell $(HUGO_PATH)/hugo version 2>&- | grep $(HUGO_VERSION))
.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
generate-docs: ## Re-generate docs directory from the website directory
generate-docs: hugo ## Re-generate docs directory from the website directory
@echo "+ $@"
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

21
PROJECT Normal file
View File

@ -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: {}

View File

@ -1,11 +1,16 @@
# Jenkins Operator
[![Version](https://img.shields.io/badge/version-v0.5.0-brightgreen.svg)](https://github.com/jenkinsci/kubernetes-operator/releases/tag/v0.5.0)
[![Build Status](https://travis-ci.org/jenkinsci/kubernetes-operator.svg?branch=master)](https://travis-ci.org/jenkinsci/kubernetes-operator)
[![Version](https://img.shields.io/badge/version-v0.8.0-brightgreen.svg)](https://github.com/jenkinsci/kubernetes-operator/releases/tag/v0.8.0)
[![Build status](https://github.com/jenkinsci/kubernetes-operator/actions/workflows/auto-tests-e2e.yaml/badge.svg)](https://github.com/jenkinsci/kubernetes-operator/actions/workflows/auto-tests-e2e.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/jenkinsci/kubernetes-operator "Go Report Card")](https://goreportcard.com/report/github.com/jenkinsci/kubernetes-operator)
[![Docker Pulls](https://img.shields.io/docker/pulls/virtuslab/jenkins-operator.svg)](https://hub.docker.com/r/virtuslab/jenkins-operator/tags)
[![Gitter chat](https://badges.gitter.im/jenkinsci/kubernetes-operator.png)](https://gitter.im/jenkinsci/kubernetes-operator)
![logo](/assets/jenkins_gopher_wide.png)
<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?
@ -15,9 +20,9 @@ It has been built with Immutability and declarative Configuration as Code in min
## Preliminaries
Considering that this Operator is created for managing instances for Jenkins,
it is important to understand what
- [Jenkins Pipelines](https://jenkins.io/doc/book/pipeline/) and
Considering that this Operator is created for managing instances for Jenkins,
it is important to understand what
- [Jenkins Pipelines](https://jenkins.io/doc/book/pipeline/) and
- 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.
@ -33,14 +38,13 @@ Jenkins uses [plugins](https://plugins.jenkins.io/) like CasC to extend it's sol
## 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.
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:
- [installing plugins with incompatible versions or security vulnerabilities](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/#install-plugins)
- [better configuration as code](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/)
- [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/customizing-jenkins/)
- [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/)
- [backup and restore for jobs history](https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/)
- [make errors more visible for end users](https://jenkinsci.github.io/kubernetes-operator/docs/troubleshooting/)
- orphaned jobs with no JNLP connection
- handle graceful shutdown properly
- 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.
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/)
3. [How it works](https://jenkinsci.github.io/kubernetes-operator/docs/how-it-works/)
4. [Security](https://jenkinsci.github.io/kubernetes-operator/docs/security/)
3. [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. [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
- Multibranch Pipelines and Backup Issues: https://github.com/jenkinsci/kubernetes-operator/issues/104#issuecomment-554289768
## 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)
Fill out ([Invite form](https://forms.gle/X3X8qA1XMirdBuEH7)) and come say hi !
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.
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
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.
@ -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 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

31
ROADMAP.md Normal file
View File

@ -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.

View File

@ -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/).

View File

@ -1 +1 @@
v0.5.0
v0.9.0-beta1

View File

@ -1,4 +1,5 @@
// Package v1alpha2 contains API Schema definitions for the jenkins.io v1alpha2 API group
// +k8s:deepcopy-gen=package,register
// +kubebuilder:object:generate=true
// +groupName=jenkins.io
package v1alpha2

View File

@ -6,7 +6,7 @@ import (
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
type JenkinsSpec struct {
// Master represents Jenkins master pod properties and Jenkins plugins.
@ -14,10 +14,18 @@ type JenkinsSpec struct {
Master JenkinsMaster `json:"master"`
// 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
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
// Can be used to integrate chat services like Slack, Microsoft Teams or Mailgun
// +optional
@ -38,12 +46,12 @@ type JenkinsSpec struct {
SlaveService Service `json:"slaveService,omitempty"`
// 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
Backup Backup `json:"backup,omitempty"`
// 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
Restore Restore `json:"restore,omitempty"`
@ -264,14 +272,6 @@ type JenkinsMaster struct {
// +optional
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
// (scope and select) objects. May match selectors of replication controllers
// and services.
@ -311,6 +311,7 @@ type JenkinsMaster struct {
// periodSeconds: 10
// successThreshold: 1
// timeoutSeconds: 5
// lifecycle: {}
// name: jenkins-master
// readinessProbe:
// failureThreshold: 3
@ -350,32 +351,55 @@ type JenkinsMaster struct {
// BasePlugins contains plugins required by operator
// +optional
// 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
// 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
// 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"`
// Plugins contains plugins required by user
// +optional
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 bool `json:"disableCSRFProtection"`
// PriorityClassName for Jenkins master pod
// +optional
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
@ -489,12 +513,13 @@ type JenkinsStatus struct {
AppliedGroovyScripts []AppliedGroovyScript `json:"appliedGroovyScripts,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Jenkins is the Schema for the jenkins API
// +k8s:openapi-gen=true
// +kubebuilder:subresource:status
type Jenkins struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@ -506,9 +531,10 @@ type Jenkins struct {
Status JenkinsStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// +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 {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
@ -525,6 +551,7 @@ const (
BasicSSHCredentialType JenkinsCredentialType = "basicSSHUserPrivateKey"
// UsernamePasswordCredentialType define username & password Jenkins credential type
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
GithubAppCredentialType JenkinsCredentialType = "githubApp"
// ExternalCredentialType defines other credential type
ExternalCredentialType JenkinsCredentialType = "external"
)
@ -534,6 +561,7 @@ var AllowedJenkinsCredentialMap = map[string]string{
string(NoJenkinsCredentialCredentialType): "",
string(BasicSSHCredentialType): "",
string(UsernamePasswordCredentialType): "",
string(GithubAppCredentialType): "",
string(ExternalCredentialType): "",
}

View File

@ -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")
}
}

View File

@ -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}}
}

View File

@ -15,11 +15,17 @@ const (
)
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 = schema.GroupVersion{Group: "jenkins.io", Version: "v1alpha2"}
// 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
@ -47,5 +53,4 @@ func JenkinsTypeMeta() metav1.TypeMeta {
func init() {
SchemeBuilder.Register(&Jenkins{}, &JenkinsList{})
SchemeBuilder.Register(&JenkinsImage{}, &JenkinsImageList{})
}

View File

@ -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
import (
v1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
corev1 "k8s.io/api/core/v1"
"k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AppliedGroovyScript) DeepCopyInto(out *AppliedGroovyScript) {
*out = *in
return
}
// 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) {
*out = *in
in.Action.DeepCopyInto(&out.Action)
return
}
// 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.
func (in *ConfigMapRef) DeepCopyInto(out *ConfigMapRef) {
*out = *in
return
}
// 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) {
*out = *in
in.Customization.DeepCopyInto(&out.Customization)
return
}
// 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 {
in, out := &in.Ports, &out.Ports
*out = make([]v1.ContainerPort, len(*in))
*out = make([]corev1.ContainerPort, len(*in))
copy(*out, *in)
}
if in.EnvFrom != nil {
in, out := &in.EnvFrom, &out.EnvFrom
*out = make([]v1.EnvFromSource, len(*in))
*out = make([]corev1.EnvFromSource, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make([]v1.EnvVar, len(*in))
*out = make([]corev1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts
*out = make([]v1.VolumeMount, len(*in))
*out = make([]corev1.VolumeMount, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
*out = new(v1.Probe)
*out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.ReadinessProbe != nil {
in, out := &in.ReadinessProbe, &out.ReadinessProbe
*out = new(v1.Probe)
*out = new(corev1.Probe)
(*in).DeepCopyInto(*out)
}
if in.Lifecycle != nil {
in, out := &in.Lifecycle, &out.Lifecycle
*out = new(v1.Lifecycle)
*out = new(corev1.Lifecycle)
(*in).DeepCopyInto(*out)
}
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
*out = new(v1.SecurityContext)
*out = new(corev1.SecurityContext)
(*in).DeepCopyInto(*out)
}
return
}
// 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))
copy(*out, *in)
}
return
}
// 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) {
*out = *in
in.Customization.DeepCopyInto(&out.Customization)
return
}
// 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
if in.Exec != nil {
in, out := &in.Exec, &out.Exec
*out = new(v1.ExecAction)
*out = new(corev1.ExecAction)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Handler.
@ -209,22 +217,6 @@ func (in *Handler) DeepCopy() *Handler {
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.
func (in *Jenkins) DeepCopyInto(out *Jenkins) {
*out = *in
@ -232,7 +224,6 @@ func (in *Jenkins) DeepCopyInto(out *Jenkins) {
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 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.
func (in *JenkinsAPISettings) DeepCopyInto(out *JenkinsAPISettings) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JenkinsAPISettings.
@ -269,110 +259,6 @@ func (in *JenkinsAPISettings) DeepCopy() *JenkinsAPISettings {
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.
func (in *JenkinsList) DeepCopyInto(out *JenkinsList) {
*out = *in
@ -385,7 +271,6 @@ func (in *JenkinsList) DeepCopyInto(out *JenkinsList) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// 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
}
}
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 {
in, out := &in.Labels, &out.Labels
*out = make(map[string]string, len(*in))
@ -439,7 +317,7 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
}
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
*out = new(v1.PodSecurityContext)
*out = new(corev1.PodSecurityContext)
(*in).DeepCopyInto(*out)
}
if in.Containers != nil {
@ -451,19 +329,19 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
}
if in.ImagePullSecrets != nil {
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
*out = make([]v1.LocalObjectReference, len(*in))
*out = make([]corev1.LocalObjectReference, len(*in))
copy(*out, *in)
}
if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes
*out = make([]v1.Volume, len(*in))
*out = make([]corev1.Volume, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Tolerations != nil {
in, out := &in.Tolerations, &out.Tolerations
*out = make([]v1.Toleration, len(*in))
*out = make([]corev1.Toleration, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@ -478,7 +356,28 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
*out = make([]Plugin, len(*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.
@ -491,22 +390,6 @@ func (in *JenkinsMaster) DeepCopy() *JenkinsMaster {
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.
func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
*out = *in
@ -531,12 +414,11 @@ func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
in.ConfigurationAsCode.DeepCopyInto(&out.ConfigurationAsCode)
if in.Roles != nil {
in, out := &in.Roles, &out.Roles
*out = make([]rbacv1.RoleRef, len(*in))
*out = make([]v1.RoleRef, len(*in))
copy(*out, *in)
}
in.ServiceAccount.DeepCopyInto(&out.ServiceAccount)
out.JenkinsAPISettings = in.JenkinsAPISettings
return
}
// 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))
copy(*out, *in)
}
return
}
// 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) {
*out = *in
out.APIKeySecretKeySelector = in.APIKeySecretKeySelector
return
}
// 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) {
*out = *in
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
return
}
// 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 = **in
}
return
}
// 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.
func (in *Plugin) DeepCopyInto(out *Plugin) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin.
@ -673,12 +550,70 @@ func (in *Plugin) DeepCopy() *Plugin {
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.
func (in *Restore) DeepCopyInto(out *Restore) {
*out = *in
in.Action.DeepCopyInto(&out.Action)
in.GetLatestAction.DeepCopyInto(&out.GetLatestAction)
return
}
// 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.UsernameSecretKeySelector = in.UsernameSecretKeySelector
out.PasswordSecretKeySelector = in.PasswordSecretKeySelector
return
}
// 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) {
*out = *in
out.LocalObjectReference = in.LocalObjectReference
return
}
// 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.
func (in *SecretRef) DeepCopyInto(out *SecretRef) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef.
@ -742,10 +674,25 @@ func (in *SecretRef) DeepCopy() *SecretRef {
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.
func (in *SeedJob) DeepCopyInto(out *SeedJob) {
*out = *in
return
}
// 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))
copy(*out, *in)
}
return
}
// 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
}
}
return
}
// 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) {
*out = *in
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
return
}
// 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)
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

View File

@ -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 GID
ENV USER=user
RUN addgroup --gid "$GID" "$USER" && \
RUN apt update \
&& apt install -y procps zstd \
&& rm -rf /var/lib/apt/lists/* \
&& addgroup --gid "$GID" "$USER" && \
adduser \
--disabled-password \
--gecos "" \
@ -13,9 +24,9 @@ RUN addgroup --gid "$GID" "$USER" && \
--uid "$UID" \
"$USER"
COPY bin/*.sh /home/user/bin/
RUN chmod -R a+rx /home/user
WORKDIR /home/user/bin
COPY bin .
RUN chmod +x *.sh
USER user
CMD ./run.sh

View File

@ -11,10 +11,11 @@ include $(config)
PREFIX?=$(shell pwd)
VERSION := $(shell cat VERSION.txt)
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
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)
GITIGNOREDBUTTRACKEDCHANGES := $(shell git ls-files -i -o --exclude-standard)
ifneq ($(GITUNTRACKEDCHANGES),)
GITCOMMIT := $(GITCOMMIT)-dirty
endif
@ -57,7 +58,7 @@ spring-clean: ## Cleanup git ignored files (interactive)
git clean -Xdi
.PHONY: checkmake
HAS_CHECKMAKE := $(shell which checkmake)
HAS_CHECKMAKE := $(shell command -v checkmake)
checkmake: ## Check this Makefile
@echo "+ $@"
ifndef HAS_CHECKMAKE
@ -67,12 +68,12 @@ endif
define e2e
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
.PHONY: docker-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 "+ $@"
$(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
@echo "+ $@"
.PHONY: docker-build-e2e
docker-build-e2e: UID=1001
docker-build-e2e: GID=1001
docker-build-e2e: docker-build
.PHONY: docker-build
docker-build: check-env ## Build the container
@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
docker-images: ## List all local containers
@ -93,25 +99,31 @@ docker-images: ## List all local containers
.PHONY: docker-push
docker-push: docker-build ## Push the container
@echo "+ $@"
docker tag $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(BUILD_TAG)
docker push $(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 quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(BUILD_TAG)
.PHONY: docker-release-version
docker-release-version: docker-build ## Release image with version tag (in addition to build tag)
@echo "+ $@"
docker tag $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(VERSION_TAG)
docker push $(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 quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(VERSION_TAG)
.PHONY: docker-release-latest
docker-release-latest: docker-build ## Release image with latest tags (in addition to build tag)
@echo "+ $@"
docker tag $(DOCKER_REGISTRY)-$(NAME):$(GITCOMMIT) $(DOCKER_ORGANIZATION)/$(DOCKER_REGISTRY)-$(NAME):$(LATEST_TAG)
docker push $(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 quay.io/$(QUAY_ORGANIZATION)/$(QUAY_REGISTRY)-$(NAME):$(LATEST_TAG)
.PHONY: docker-release
docker-release: docker-release-version docker-release-latest ## Release image with version and latest tags (in addition to build tag)
@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
# TTY, which would fail, but if it is interactive, we do want to attach
# so that the user can send e.g. ^C through.
@ -121,20 +133,30 @@ ifeq ($(INTERACTIVE), 1)
endif
.PHONY: docker-run
docker-run: docker-build ## Run the container in docker, you can use EXTRA_ARGS
docker-run: docker-build
@echo "+ $@"
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
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 "+ $@"
$(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 $(NEW_VERSION) > 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
tag: ## Create a new git tag to prepare to build a release
@ -158,7 +180,7 @@ ifneq ($(GITUNTRACKEDCHANGES),)
endif
ifneq ($(GITIGNOREDBUTTRACKEDCHANGES),)
@echo "Ignored but tracked files:"
@git ls-files -i --exclude-standard
@git ls-files -i -c --exclude-standard
@echo
endif
@echo "Dependencies:"

View File

@ -1 +1 @@
v0.1.0
v0.4.3

68
backup/pvc/bin/backup.sh Normal file → Executable file
View File

@ -1,23 +1,67 @@
#!/usr/bin/env bash
set -eo pipefail
source "$(dirname "$0")/utils.sh"
[[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1;
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
BACKUP_TMP_DIR=$(mktemp -d)
[[ ! $# -eq 1 ]] && _log "ERROR" "Usage: $0 BACKUP_NUMBER" && exit 1
[[ -z "${BACKUP_DIR}" ]] && _log "ERROR" "Required 'BACKUP_DIR' env not set" && exit 1
[[ -z "${JENKINS_HOME}" ]] && _log "ERROR" "Required 'JENKINS_HOME' env not set" && exit 1
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
echo "Running backup"
# --> Check if another backup process is running (operator restart/crash)
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
# config.xml in child directores is state that should. For example-
_log "INFO" "[backup] running backup ${BACKUP_NUMBER}"
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/config.xml should not
tar -C ${JENKINS_HOME} -czf "${BACKUP_TMP_DIR}/${backup_number}.tar.gz" --exclude jobs/*/workspace* --no-wildcards-match-slash --anchored --exclude jobs/*/config.xml -c jobs && \
mv ${BACKUP_TMP_DIR}/${backup_number}.tar.gz ${BACKUP_DIR}/${backup_number}.tar.gz
tar --zstd -C "${JENKINS_HOME}" -cf "${BACKUP_TMP_DIR}/${BACKUP_NUMBER}.tar.zstd" \
--exclude jobs/*/workspace* \
--no-wildcards-match-slash --anchored \
--ignore-failed-read \
--exclude jobs/*/config.xml -c jobs || ret=$?
[[ ! -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

31
backup/pvc/bin/get-latest.sh Normal file → Executable file
View File

@ -1,12 +1,39 @@
#!/usr/bin/env bash
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
_log "Could not get the latest backup."
echo "-1"
else
echo "${latest%%.*}"

58
backup/pvc/bin/restore.sh Normal file → Executable file
View File

@ -1,15 +1,57 @@
#!/usr/bin/env bash
set -eo pipefail
source "$(dirname "$0")/utils.sh"
[[ ! $# -eq 1 ]] && echo "Usage: $0 backup_number" && exit 1
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
[[ ! $# -eq 1 ]] && _log "ERROR" "Usage: $0 <backup number>" && exit 1
[[ -z "${BACKUP_DIR}" ]] && _log "ERROR" "Required 'BACKUP_DIR' 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
echo "Running restore backup"
# --> Check if another restore process is running (operator restart/crash)
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
exit 0
_log "INFO" "[restore] restore backup with backup number #${BACKUP_NUMBER}"
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

69
backup/pvc/bin/run.sh Normal file → Executable file
View File

@ -1,15 +1,72 @@
#!/usr/bin/env bash
set -eo pipefail
source "$(dirname "$0")/utils.sh"
[[ -z "${BACKUP_DIR}" ]] && echo "Required 'BACKUP_DIR' env not set" && exit 1;
[[ -z "${JENKINS_HOME}" ]] && echo "Required 'JENKINS_HOME' env not set" && exit 1;
# Use 60 as default in case BACKUP_CLEANUP_INTERVAL did not set
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;
do
sleep 10
if [[ ! -z "${BACKUP_COUNT}" ]]; then
echo "Trimming to only ${BACKUP_COUNT} recent backups in preparation for new backup"
find ${BACKUP_DIR} -name '*.tar.gz' -exec basename {} \; | sort -gr | tail -n +$((BACKUP_COUNT +1)) | xargs -I '{}' rm ${BACKUP_DIR}/'{}'
sleep "$BACKUP_CLEANUP_INTERVAL"
if [[ -n "${BACKUP_COUNT}" ]]; then
exceeding_backups=$(find_exceeding_backups "${BACKUP_DIR}" "${BACKUP_COUNT}")
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
done

14
backup/pvc/bin/utils.sh Executable file
View File

@ -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
}

View File

@ -1,6 +1,7 @@
# Setup variables for the Makefile
NAME=pvc
DOCKER_ORGANIZATION=virtuslab
DOCKER_REGISTRY=jenkins-operator-backup
QUAY_ORGANIZATION=jenkins-kubernetes-operator
QUAY_REGISTRY=backup
UID=1000
GID=1000
GID=1000
KIND_CLUSTER_NAME=jenkins

View File

@ -30,7 +30,7 @@ trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${RESTORE_FOLDE
backup_number=1
docker exec ${cid} /home/user/bin/backup.sh ${backup_number}
backup_file="${BACKUP_DIR}/${backup_number}.tar.gz"
backup_file="${BACKUP_DIR}/${backup_number}.tar.zstd"
[[ ! -f ${backup_file} ]] && echo "Backup file ${backup_file} not found" && exit 1;
docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/restore.sh ${backup_number}"
@ -38,4 +38,4 @@ docker exec ${cid} /bin/bash -c "JENKINS_HOME=${RESTORE_FOLDER};/home/user/bin/r
echo "Compare directories"
diff --brief --recursive "${RESTORE_FOLDER}" "${JENKINS_HOME_AFTER_RESTORE}"
echo "Directories are the same"
echo PASS
echo PASS

View File

@ -19,17 +19,20 @@ mkdir -p ${BACKUP_DIR}
mkdir -p ${JENKINS_HOME}
mkdir -p ${BACKUP_DIR}/lost+found
touch ${BACKUP_DIR}/1.tar.gz
touch ${BACKUP_DIR}/2.tar.gz
touch ${BACKUP_DIR}/3.tar.gz
touch ${BACKUP_DIR}/4.tar.gz
touch ${BACKUP_DIR}/5.tar.gz
touch ${BACKUP_DIR}/6.tar.gz
touch ${BACKUP_DIR}/7.tar.gz
touch ${BACKUP_DIR}/8.tar.gz
touch ${BACKUP_DIR}/9.tar.gz
touch ${BACKUP_DIR}/10.tar.gz
touch ${BACKUP_DIR}/11.tar.gz
touch ${BACKUP_DIR}/1.tar.zstd
touch ${BACKUP_DIR}/2.tar.zstd
touch ${BACKUP_DIR}/3.tar.zstd
touch ${BACKUP_DIR}/4.tar.zstd
touch ${BACKUP_DIR}/5.tar.zstd
touch ${BACKUP_DIR}/6.tar.zstd
touch ${BACKUP_DIR}/7.tar.zstd
touch ${BACKUP_DIR}/8.tar.zstd
touch ${BACKUP_DIR}/9.tar.zstd
touch ${BACKUP_DIR}/10.tar.zstd
touch ${BACKUP_DIR}/11.tar.zstd
# 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
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
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")
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")
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
docker logs ${cid}
ls -la ${BACKUP_DIR}
@ -55,5 +68,9 @@ if [[ ! "${empty_latest}" == "-1" ]]; then
echo "Latest backup number should be '-1' but is '${empty_latest}'"
exit 1
fi
if [[ ! "${empty_dir_latest}" == "-1" ]]; then
echo "Latest backup number should be '-1' but is '${empty_dir_latest}'"
exit 1
fi
echo PASS

View File

@ -1,6 +1,8 @@
#!/bin/bash
set -eo pipefail
echo "Running limit_backup_count e2e test..."
[[ "${DEBUG}" ]] && set -x
# set current working directory to the directory of the script
@ -19,28 +21,31 @@ mkdir -p ${BACKUP_DIR}
mkdir -p ${JENKINS_HOME}
mkdir -p ${BACKUP_DIR}/lost+found
touch ${BACKUP_DIR}/1.tar.gz
touch ${BACKUP_DIR}/2.tar.gz
touch ${BACKUP_DIR}/3.tar.gz
touch ${BACKUP_DIR}/4.tar.gz
touch ${BACKUP_DIR}/5.tar.gz
touch ${BACKUP_DIR}/6.tar.gz
touch ${BACKUP_DIR}/7.tar.gz
touch ${BACKUP_DIR}/8.tar.gz
touch ${BACKUP_DIR}/9.tar.gz
touch ${BACKUP_DIR}/10.tar.gz
touch ${BACKUP_DIR}/11.tar.gz
touch ${BACKUP_DIR}/1.tar.zstd
touch ${BACKUP_DIR}/2.tar.zstd
touch ${BACKUP_DIR}/3.tar.zstd
touch ${BACKUP_DIR}/4.tar.zstd
touch ${BACKUP_DIR}/5.tar.zstd
touch ${BACKUP_DIR}/6.tar.zstd
touch ${BACKUP_DIR}/7.tar.zstd
touch ${BACKUP_DIR}/8.tar.zstd
touch ${BACKUP_DIR}/9.tar.zstd
touch ${BACKUP_DIR}/10.tar.zstd
touch ${BACKUP_DIR}/11.tar.zstd
# 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
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}'"
# Remove test directory and container afterwards
trap "docker rm -vf $cid > /dev/null;rm -rf ${BACKUP_DIR};rm -rf ${JENKINS_HOME}" EXIT
sleep 11
touch ${BACKUP_DIR}/12.tar.gz
sleep 11
sleep 2
mv ${BACKUP_TMP_DIR}/12.tar.zstd ${BACKUP_DIR}/
sleep 2
if [[ "${DEBUG}" ]]; then
docker logs ${cid}
@ -48,7 +53,7 @@ if [[ "${DEBUG}" ]]; then
fi
# only two latest backup should exists
[[ $(ls -1 ${BACKUP_DIR} | grep 'tar.gz' | wc -l) -eq 2 ]] || exit 1
[[ -f ${BACKUP_DIR}/11.tar.gz ]] || exit 2
[[ -f ${BACKUP_DIR}/12.tar.gz ]] || exit 3
[[ $(ls -1 ${BACKUP_DIR} | grep 'tar.zstd' | wc -l) -eq 2 ]] || exit 1
[[ -f ${BACKUP_DIR}/11.tar.zstd ]] || exit 2
[[ -f ${BACKUP_DIR}/12.tar.zstd ]] || exit 3
echo PASS

View File

@ -1,6 +1,8 @@
#!/bin/bash
set -eo pipefail
echo "Running limit_backup_count_no_backups e2e test..."
[[ "${DEBUG}" ]] && set -x
# set current working directory to the directory of the script
@ -19,7 +21,7 @@ mkdir -p ${BACKUP_DIR}
mkdir -p ${JENKINS_HOME}
# 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}'"
# 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
echo 'Checking if container is running'
sleep 11
sleep 3
set +e
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 PASS

View File

@ -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

View File

@ -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" ]

View File

@ -1,6 +1,214 @@
apiVersion: v1
entries:
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
appVersion: 0.4.0
created: "2020-07-19T17:26:48.811339047+02:00"
@ -208,4 +416,4 @@ entries:
urls:
- https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.0.1.tgz
version: 0.0.1
generated: "2020-06-18T11:48:46.181495+02:00"
generated: "2025-04-06T21:25:18.363088324Z"

View File

@ -20,3 +20,7 @@
.idea/
*.tmproj
.vscode/
# Ignore packaged charts
jenkins-operator-*.tgz

View File

@ -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"

View File

@ -1,6 +1,14 @@
apiVersion: v2
appVersion: "0.4.0"
appVersion: "0.9.0-beta1"
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
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
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

View File

@ -0,0 +1,117 @@
# jenkins-operator
![Version: 0.8.1](https://img.shields.io/badge/Version-0.8.1-informational?style=flat-square) ![AppVersion: 0.8.1](https://img.shields.io/badge/AppVersion-0.8.1-informational?style=flat-square)
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)

View File

@ -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.

View File

@ -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
metadata:
name: jenkins-operator
{{- if ne $namespace "" }}
namespace: {{ $namespace }}
{{- end }}
rules:
- apiGroups:
- ""
resources:
- services
- configmaps
- secrets
- serviceaccounts
verbs:
- get
- create
- update
- list
- watch
- apiGroups:
- apps
resources:
- deployments
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- '*'
- apiGroups:
- rbac.authorization.k8s.io
- apps
- jenkins-operator
resources:
- roles
- rolebindings
- deployments/finalizers
verbs:
- create
- update
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
- builds
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods/portforward
- configmaps
- secrets
- services
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- '*'
- apiGroups:
- ""
resources:
@ -53,26 +94,40 @@ rules:
- apiGroups:
- ""
resources:
- pods
- pods/exec
- pods/portforward
verbs:
- "*"
- create
- apiGroups:
- ""
resources:
- events
- serviceaccounts
verbs:
- watch
- list
- create
- patch
- get
- list
- update
- watch
- apiGroups:
- apps
resourceNames:
- jenkins-operator
- image.openshift.io
resources:
- deployments/finalizers
- imagestreams
verbs:
- get
- list
- watch
- apiGroups:
- jenkins.io
resources:
- jenkins/finalizers
verbs:
- update
- apiGroups:
- jenkins.io
resources:
- jenkins/status
verbs:
- get
- patch
- update
- apiGroups:
- jenkins.io
@ -81,23 +136,26 @@ rules:
verbs:
- '*'
- apiGroups:
- ""
- rbac.authorization.k8s.io
resources:
- persistentvolumeclaims
- rolebindings
- roles
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- "route.openshift.io"
resources:
- routes
verbs:
- create
- get
- list
- watch
- create
- update
- watch
- apiGroups:
- "image.openshift.io"
resources:
@ -115,3 +173,4 @@ rules:
- get
- list
- watch
{{ end }}

View File

@ -9,31 +9,45 @@ metadata:
{{- end }}
spec:
configurationAsCode:
configurations:
{{- range .Values.jenkins.configuration.configurationAsCode }}
- name: {{ .configMapName }}
{{- end }}
{{- if .Values.jenkins.configuration.configurationAsCode }}
configurations:
{{ range .Values.jenkins.configuration.configurationAsCode }}
- name: {{ .configMapName }}
{{- end }}
secret:
{{- if .Values.jenkins.configuration.secretRefName }}
name: {{ .Values.jenkins.configuration.secretRefName }}
{{- else if .Values.jenkins.configuration.secretData }}
name: jenkins-{{ .Values.jenkins.name }}
{{- else }}
name: ""
{{- end }}
{{- else }}
configurations: []
secret:
name: ""
{{- end }}
groovyScripts:
configurations:
{{- range .Values.jenkins.configuration.groovyScripts }}
- name: {{ .configMapName }}
{{- end }}
{{- if .Values.jenkins.configuration.groovyScripts }}
configurations:
{{- range .Values.jenkins.configuration.groovyScripts }}
- name: {{ .configMapName }}
{{- end }}
secret:
{{- if .Values.jenkins.configuration.secretRefName }}
name: {{ .Values.jenkins.configuration.secretRefName }}
{{- else if .Values.jenkins.configuration.secretData }}
name: jenkins-{{ .Values.jenkins.name }}
{{- else }}
name: ""
{{- end }}
{{- else }}
configurations: []
secret:
name: ""
{{- end }}
jenkinsAPISettings:
authorizationStrategy: {{ .Values.jenkins.authorizationStrategy }}
{{- if .Values.jenkins.backup.enabled }}
backup:
containerName: {{ .Values.jenkins.backup.containerName }}
@ -51,6 +65,13 @@ spec:
{{- with .Values.jenkins.backup.restoreCommand }}
command: {{ toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.jenkins.backup.getLatestAction }}
getLatestAction:
exec:
{{- with .Values.jenkins.backup.getLatestAction }}
command: {{ toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- if .Values.jenkins.backup.recoveryOnce }}
recoveryOnce: {{ .Values.jenkins.backup.recoveryOnce }}
{{- end }}
@ -64,10 +85,19 @@ spec:
{{- with .Values.jenkins.notifications }}
notifications: {{ toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.jenkins.serviceAccount }}
serviceAccount: {{ toYaml . | nindent 4 }}
{{- end }}
master:
{{- with .Values.jenkins.labels }}
labels: {{ toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.jenkins.nodeSelector }}
nodeSelector: {{ toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.jenkins.tolerations }}
tolerations: {{ toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.jenkins.annotations }}
annotations: {{ toYaml . | nindent 6 }}
{{- end }}
@ -77,48 +107,47 @@ spec:
{{- with .Values.jenkins.plugins }}
plugins: {{ toYaml . | nindent 4 }}
{{- end }}
latestPlugins: {{ .Values.jenkins.latestPlugins }}
{{- if .Values.jenkins.priorityClassName }}
priorityClassName: {{ .Values.jenkins.priorityClassName }}
{{- end }}
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:
- name: jenkins-master
image: {{ .Values.jenkins.image }}
imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }}
{{- with .Values.jenkins.imagePullSecrets }}
imagePullSecrets: {{ toYaml . | nindent 10 }}
{{- with .Values.jenkins.livenessProbe }}
livenessProbe: {{ toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.jenkins.readinessProbe }}
readinessProbe: {{ toYaml . | nindent 10 }}
{{- 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 }}
resources: {{ toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.jenkins.env }}
env: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.jenkins.lifecycle}}
lifecycle: {{ toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.jenkins.volumeMounts }}
volumeMounts: {{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.jenkins.backup.enabled }}
- name: {{ .Values.jenkins.backup.containerName }}
image: {{ .Values.jenkins.backup.image }}
imagePullPolicy: IfNotPresent
imagePullPolicy: {{ .Values.jenkins.imagePullPolicy }}
{{- with .Values.jenkins.backup.resources }}
resources: {{ toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.jenkins.backup.env }}
env: {{- toYaml . | nindent 8 }}
{{- end }}
@ -129,11 +158,18 @@ spec:
{{- with .Values.jenkins.volumes }}
volumes: {{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.jenkins.imagePullSecrets }}
imagePullSecrets: {{ toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.jenkins.securityContext}}
securityContext:
{{- toYaml . | nindent 6 }}
{{- end }}
validateSecurityWarnings: {{ .Values.jenkins.validateSecurityWarnings }}
{{- with .Values.jenkins.seedJobs }}
seedJobs: {{- toYaml . | nindent 4 }}
{{- end }}
{{- if .Values.jenkins.seedJobAgentImage }}
seedJobAgentImage: {{ .Values.jenkins.seedJobAgentImage }}
{{- end }}
{{- end }}

View File

@ -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

View File

@ -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

View File

@ -30,13 +30,40 @@ spec:
containerPort: 80
protocol: TCP
command:
- jenkins-operator
args: []
- /manager
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:
- name: WATCH_NAMESPACE
{{- if .Values.jenkins.enabled }}
value: {{ .Values.jenkins.namespace }}
{{- else if .Values.operator.watchNamespace }}
value: {{ .Values.operator.watchNamespace }}
{{- else }}
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- end }}
- name: POD_NAME
valueFrom:
fieldRef:
@ -57,3 +84,11 @@ spec:
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.webhook.enabled }}
volumes:
- name: webhook-certs
secret:
defaultMode: 420
secretName: jenkins-{{ .Values.webhook.certificate.name }}
terminationGracePeriodSeconds: 10
{{- end }}

View File

@ -1,127 +1,15 @@
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins-operator
rules:
- apiGroups:
- ""
resources:
- services
- configmaps
- secrets
verbs:
- get
- create
- 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
{{ 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
*/ -}}
{{- template "jenkins-operator.role" .Values.jenkins.namespace }}
{{ else }}
{{- template "jenkins-operator.role" .Release.Namespace }}
{{- if ne .Release.Namespace .Values.jenkins.namespace -}}
{{- template "jenkins-operator.role" .Values.jenkins.namespace }}
{{- end }}
{{ end }}

View File

@ -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
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins-operator
namespace: {{ .Release.Namespace }}
subjects:
- kind: ServiceAccount
name: jenkins-operator
- kind: ServiceAccount
name: jenkins-operator
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: jenkins-operator
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 }}

View File

@ -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 }}

View File

@ -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 }}

View File

@ -18,18 +18,25 @@ jenkins:
# namespace is the namespace where the resources will be deployed
# It's not recommended to use default namespace
# Create new namespace for jenkins (called e.g. jenkins)
# Note: this affects roles and rolebindings for jenkins operator itself
namespace: default
# labels are injected into metadata labels field
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: {}
# image is the name (and tag) of the Jenkins instance
# Default: jenkins/jenkins:lts
# It's recommended to use LTS (tag: "lts") version
image: jenkins/jenkins:2.263.2-lts-alpine
image: jenkins/jenkins:2.528.1-lts
# env contains jenkins container environment variables
env: []
@ -37,6 +44,9 @@ jenkins:
# imagePullPolicy defines policy for pulling images
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
# See: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/
priorityClassName: ""
@ -46,14 +56,38 @@ jenkins:
# See https://github.com/jenkinsci/kubernetes-operator/pull/193 for more info
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
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#pulling-docker-images-from-private-repositories for more info
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
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
# Shouldn't contain plugins defined by user
# You can change their versions here
@ -63,34 +97,21 @@ jenkins:
#
# basePlugins:
# - name: kubernetes
# version: 1.28.6
# version: 4246.v5a_12b_1fe120e
# - name: workflow-job
# version: "2.40"
# version: 1400.v7fd111b_ec82f
# - name: workflow-aggregator
# version: "2.6"
# version: 596.v8c21c963d92d
# - name: git
# version: 4.5.0
# version: 5.2.2
# - name: job-dsl
# version: "1.77"
# version: "1.87"
# - name: configuration-as-code
# version: "1.46"
# version: 1810.v9b_c30a_249a_4c
# - name: kubernetes-credentials-provider
# version: 0.15
basePlugins:
- 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
version: "1.46"
- name: kubernetes-credentials-provider
version: "0.15"
# version: 1.262.v2670ef7ea_0c5
basePlugins: []
# plugins are plugins required by the user
# You can define plugins here
@ -103,9 +124,14 @@ jenkins:
# version: "0.6"
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
# For seed job creation tutorial, check https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#prepare-job-definitions-and-pipelines
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#configure-seed-jobs for additional info
# For seed job creation tutorial, check https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuring-seed-jobs-and-pipelines/
# Example:
#
# seedJobs:
@ -116,14 +142,22 @@ jenkins:
# repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
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
# See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ for details
resources:
limits:
cpu: 1500m
cpu: 1000m
memory: 3Gi
requests:
cpu: 1
cpu: 250m
memory: 500Mi
# volumes used by Jenkins
@ -134,8 +168,14 @@ jenkins:
claimName: jenkins-backup
# 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: []
# defines authorization strategy of the operator for the Jenkins API
authorizationStrategy: createUser
# securityContext for pod
securityContext:
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
#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
# 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/
@ -158,8 +221,8 @@ jenkins:
enabled: true
# image used by backup feature
# By default using prebuilt backup PVC image by VirtusLab
image: virtuslab/jenkins-operator-backup-pvc:v0.1.0
# By default using prebuilt backup PVC image
image: quay.io/jenkins-kubernetes-operator/backup-pvc:v0.4.3
# containerName is backup container name
containerName: backup
@ -193,11 +256,25 @@ jenkins:
# See https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1 for more details
className: ""
# resources used by backup container
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 100m
memory: 500Mi
# env contains container environment variables
# PVC backup provider handles these variables:
# BACKUP_DIR - path for storing backup files (default: "/backup")
# JENKINS_HOME - path to jenkins home (default: "/jenkins-home")
# 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:
- name: BACKUP_DIR
value: /backup
@ -205,6 +282,15 @@ jenkins:
value: /jenkins-home
- name: BACKUP_COUNT
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:
@ -216,10 +302,10 @@ jenkins:
# configuration is section where we can configure Jenkins instance
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/customization/ for details
configuration:
configurationAsCode: {}
configurationAsCode: []
# - configMapName: jenkins-casc
# content: {}
groovyScripts: {}
groovyScripts: []
# - configMapName: jenkins-gs
# content: {}
@ -234,7 +320,7 @@ operator:
replicaCount: 1
# 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: IfNotPresent
@ -248,7 +334,33 @@ operator:
# fullnameOverride overrides the deployment name
fullnameOverride: ""
# Select a different namespace to look for the Jenkins CR and deploy Jenkins in. Defaults to the same namespace as
# the operator.
# watchNamespace: "jenkins-namespace"
resources: {}
nodeSelector: {}
tolerations: []
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