From 7cb307d2547af7a6e87ca45bb300642fa7aa0270 Mon Sep 17 00:00:00 2001 From: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Date: Sat, 10 Jun 2023 22:42:03 +0300 Subject: [PATCH] NAS-122335 / 23.10 / Add `jenkins` to `community` train (#1245) * Add `Jenkins` to `community` train * add another combo test * update wording * change custom flag * remove space * disable http when https is enabled * unique ports --- library/ix-dev/community/jenkins/Chart.lock | 6 + library/ix-dev/community/jenkins/Chart.yaml | 26 ++ library/ix-dev/community/jenkins/README.md | 9 + .../ix-dev/community/jenkins/app-readme.md | 9 + .../community/jenkins/charts/common-1.0.8.tgz | Bin 0 -> 55444 bytes .../jenkins/ci/additional-values.yaml | 27 ++ .../community/jenkins/ci/basic-values.yaml | 4 + .../jenkins/ci/http-agent-values.yaml | 8 + .../jenkins/ci/https-agent-values.yaml | 96 ++++++ .../community/jenkins/ci/https-values.yaml | 94 ++++++ library/ix-dev/community/jenkins/item.yaml | 9 + .../ix-dev/community/jenkins/metadata.yaml | 8 + .../ix-dev/community/jenkins/questions.yaml | 275 ++++++++++++++++++ .../community/jenkins/templates/NOTES.txt | 1 + .../jenkins/templates/_certContainer.tpl | 48 +++ .../jenkins/templates/_configuration.tpl | 23 ++ .../community/jenkins/templates/_jenkins.tpl | 148 ++++++++++ .../community/jenkins/templates/_portal.tpl | 16 + .../jenkins/templates/_validation.tpl | 38 +++ .../community/jenkins/templates/common.yaml | 19 ++ .../community/jenkins/upgrade_info.json | 1 + .../ix-dev/community/jenkins/upgrade_strategy | 31 ++ library/ix-dev/community/jenkins/values.yaml | 42 +++ 23 files changed, 938 insertions(+) create mode 100644 library/ix-dev/community/jenkins/Chart.lock create mode 100644 library/ix-dev/community/jenkins/Chart.yaml create mode 100644 library/ix-dev/community/jenkins/README.md create mode 100644 library/ix-dev/community/jenkins/app-readme.md create mode 100644 library/ix-dev/community/jenkins/charts/common-1.0.8.tgz create mode 100644 library/ix-dev/community/jenkins/ci/additional-values.yaml create mode 100644 library/ix-dev/community/jenkins/ci/basic-values.yaml create mode 100644 library/ix-dev/community/jenkins/ci/http-agent-values.yaml create mode 100644 library/ix-dev/community/jenkins/ci/https-agent-values.yaml create mode 100644 library/ix-dev/community/jenkins/ci/https-values.yaml create mode 100644 library/ix-dev/community/jenkins/item.yaml create mode 100644 library/ix-dev/community/jenkins/metadata.yaml create mode 100644 library/ix-dev/community/jenkins/questions.yaml create mode 100644 library/ix-dev/community/jenkins/templates/NOTES.txt create mode 100644 library/ix-dev/community/jenkins/templates/_certContainer.tpl create mode 100644 library/ix-dev/community/jenkins/templates/_configuration.tpl create mode 100644 library/ix-dev/community/jenkins/templates/_jenkins.tpl create mode 100644 library/ix-dev/community/jenkins/templates/_portal.tpl create mode 100644 library/ix-dev/community/jenkins/templates/_validation.tpl create mode 100644 library/ix-dev/community/jenkins/templates/common.yaml create mode 100644 library/ix-dev/community/jenkins/upgrade_info.json create mode 100755 library/ix-dev/community/jenkins/upgrade_strategy create mode 100644 library/ix-dev/community/jenkins/values.yaml diff --git a/library/ix-dev/community/jenkins/Chart.lock b/library/ix-dev/community/jenkins/Chart.lock new file mode 100644 index 0000000000..0c15893a68 --- /dev/null +++ b/library/ix-dev/community/jenkins/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../../../common + version: 1.0.8 +digest: sha256:254efaa1285f634b7a80b7baadeadbd20a680f7fee49d1d9d3c4618aa0d657ad +generated: "2023-06-06T16:49:32.884968988+03:00" diff --git a/library/ix-dev/community/jenkins/Chart.yaml b/library/ix-dev/community/jenkins/Chart.yaml new file mode 100644 index 0000000000..7da2818af5 --- /dev/null +++ b/library/ix-dev/community/jenkins/Chart.yaml @@ -0,0 +1,26 @@ +name: jenkins +description: Jenkins is a leading open source automation server, +annotations: + title: Jenkins +type: application +version: 1.0.0 +apiVersion: v2 +appVersion: '2.401.1' +kubeVersion: '>=1.16.0-0' +maintainers: + - name: truenas + url: https://www.truenas.com/ + email: dev@ixsystems.com +dependencies: + - name: common + repository: file://../../../common + version: 1.0.8 +home: https://www.jenkins.io/ +icon: https://camo.githubusercontent.com/1babb15d046739f64d24c9a3424dd912a88683894f6f2307a969501ad84739f8/68747470733a2f2f7777772e6a656e6b696e732e696f2f696d616765732f6a656e6b696e732d6c6f676f2d7469746c652d6461726b2e737667 +sources: + - https://hub.docker.com/r/jenkins/jenkins + - https://github.com/jenkinsci/jenkins + - https://www.jenkins.io/ +keywords: + - automation + - ci/cd diff --git a/library/ix-dev/community/jenkins/README.md b/library/ix-dev/community/jenkins/README.md new file mode 100644 index 0000000000..2a7080f913 --- /dev/null +++ b/library/ix-dev/community/jenkins/README.md @@ -0,0 +1,9 @@ +# Jenkins + +[Jenkins](https://www.jenkins.io/). The leading open source automation server, Jenkins provides hundreds of +plugins to support building, deploying and automating any project. + +> When application is installed and on each startup, a container will be launched with **root** privileges. +> This is required in order to apply the correct permissions to the `Jenkins` directories. +> Afterward, the `Jenkins` container will run as a **non**-root user (`1000`). +> All mounted storage(s) will be `chown`ed only if the parent directory does not match the user and group (`1000`). diff --git a/library/ix-dev/community/jenkins/app-readme.md b/library/ix-dev/community/jenkins/app-readme.md new file mode 100644 index 0000000000..2a7080f913 --- /dev/null +++ b/library/ix-dev/community/jenkins/app-readme.md @@ -0,0 +1,9 @@ +# Jenkins + +[Jenkins](https://www.jenkins.io/). The leading open source automation server, Jenkins provides hundreds of +plugins to support building, deploying and automating any project. + +> When application is installed and on each startup, a container will be launched with **root** privileges. +> This is required in order to apply the correct permissions to the `Jenkins` directories. +> Afterward, the `Jenkins` container will run as a **non**-root user (`1000`). +> All mounted storage(s) will be `chown`ed only if the parent directory does not match the user and group (`1000`). diff --git a/library/ix-dev/community/jenkins/charts/common-1.0.8.tgz b/library/ix-dev/community/jenkins/charts/common-1.0.8.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5a6f455592d42261d8caac704bf4cf7da384ec51 GIT binary patch literal 55444 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%0DY^B5!^vSUgL01`zw~oCu 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%0D@9>C$4 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 bvl{NouI$RLc$Pl{00960H2(g$03HVbX;Tqy literal 0 HcmV?d00001 diff --git a/library/ix-dev/community/jenkins/ci/additional-values.yaml b/library/ix-dev/community/jenkins/ci/additional-values.yaml new file mode 100644 index 0000000000..47c918bfa7 --- /dev/null +++ b/library/ix-dev/community/jenkins/ci/additional-values.yaml @@ -0,0 +1,27 @@ +jenkinsStorage: + home: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/home + additionalStorages: + - type: hostPath + hostPath: /mnt/{{ .Release.Name }}/jenkinsWorkspace1 + mountPath: /workspace1 + - type: hostPath + hostPath: /mnt/{{ .Release.Name }}/jenkinsWorkspace2 + mountPath: /workspace2 + +jenkinsConfig: + jenkinsOpts: + - useJmx + - sessionTimeout=100 + jenkinsJavaOpts: + - property: hudson.footerURL + value: https://jenkins.example.com + - property: jenkins.CLI.disabled + value: "true" + + additionalEnvs: + - name: PLUGINS_FORCE_UPGRADE + value: "true" + - name: TRY_UPGRADE_IF_NO_MARKER + value: "true" diff --git a/library/ix-dev/community/jenkins/ci/basic-values.yaml b/library/ix-dev/community/jenkins/ci/basic-values.yaml new file mode 100644 index 0000000000..f6b0632022 --- /dev/null +++ b/library/ix-dev/community/jenkins/ci/basic-values.yaml @@ -0,0 +1,4 @@ +jenkinsStorage: + home: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/home diff --git a/library/ix-dev/community/jenkins/ci/http-agent-values.yaml b/library/ix-dev/community/jenkins/ci/http-agent-values.yaml new file mode 100644 index 0000000000..0108052adb --- /dev/null +++ b/library/ix-dev/community/jenkins/ci/http-agent-values.yaml @@ -0,0 +1,8 @@ +jenkinsStorage: + home: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/home + +jenkinsNetwork: + agent: true + agentPort: 31000 diff --git a/library/ix-dev/community/jenkins/ci/https-agent-values.yaml b/library/ix-dev/community/jenkins/ci/https-agent-values.yaml new file mode 100644 index 0000000000..4ad09d902e --- /dev/null +++ b/library/ix-dev/community/jenkins/ci/https-agent-values.yaml @@ -0,0 +1,96 @@ +jenkinsStorage: + home: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/home + +jenkinsNetwork: + agent: true + agentPort: 31000 + certificateID: 1 + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/library/ix-dev/community/jenkins/ci/https-values.yaml b/library/ix-dev/community/jenkins/ci/https-values.yaml new file mode 100644 index 0000000000..600fde7ba0 --- /dev/null +++ b/library/ix-dev/community/jenkins/ci/https-values.yaml @@ -0,0 +1,94 @@ +jenkinsStorage: + home: + type: hostPath + hostPath: /mnt/{{ .Release.Name }}/home + +jenkinsNetwork: + certificateID: 1 + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/library/ix-dev/community/jenkins/item.yaml b/library/ix-dev/community/jenkins/item.yaml new file mode 100644 index 0000000000..3d70f4b360 --- /dev/null +++ b/library/ix-dev/community/jenkins/item.yaml @@ -0,0 +1,9 @@ +icon_url: https://camo.githubusercontent.com/1babb15d046739f64d24c9a3424dd912a88683894f6f2307a969501ad84739f8/68747470733a2f2f7777772e6a656e6b696e732e696f2f696d616765732f6a656e6b696e732d6c6f676f2d7469746c652d6461726b2e737667 +categories: + - productivity +screenshots: + - https://assets.digitalocean.com/articles/jcasc_docker/step4a.png + - https://assets.digitalocean.com/articles/jcasc_docker/step7a.png +tags: + - automation + - ci/cd diff --git a/library/ix-dev/community/jenkins/metadata.yaml b/library/ix-dev/community/jenkins/metadata.yaml new file mode 100644 index 0000000000..828d5006e4 --- /dev/null +++ b/library/ix-dev/community/jenkins/metadata.yaml @@ -0,0 +1,8 @@ +runAsContext: + - userName: jenkins + groupName: jenkins + gid: 1000 + uid: 1000 + description: Jenkins runs as a non-root user. +capabilities: [] +hostMounts: [] diff --git a/library/ix-dev/community/jenkins/questions.yaml b/library/ix-dev/community/jenkins/questions.yaml new file mode 100644 index 0000000000..9ea7121330 --- /dev/null +++ b/library/ix-dev/community/jenkins/questions.yaml @@ -0,0 +1,275 @@ +groups: + - name: Jenkins Configuration + description: Configure Jenkins + - name: User and Group Configuration + description: Configure User and Group for Jenkins + - name: Network Configuration + description: Configure Network for Jenkins + - name: Storage Configuration + description: Configure Storage for Jenkins + - name: Resources Configuration + description: Configure Resources for Jenkins + +portals: + web_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "$kubernetes-resource_configmap_portal_path" + +questions: + - variable: TZ + group: Jenkins Configuration + label: Timezone + schema: + type: string + default: Etc/UTC + required: true + $ref: + - definitions/timezone + + - variable: jenkinsConfig + label: "" + group: Jenkins Configuration + schema: + type: dict + attrs: + - variable: jenkinsJavaOpts + label: Additional Jenkins Java Options + description: | + Configure additional jenkins java options for Jenkins.
+ See https://www.jenkins.io/doc/book/managing/system-properties + schema: + type: list + default: [] + items: + - variable: jenkinsJavaOpt + label: Jenkins Java Option + schema: + type: dict + attrs: + - variable: property + label: Property + description: | + The property to set, see https://www.jenkins.io/doc/book/managing/system-properties
+ The prefix [-D] is automatically added. + schema: + type: string + required: true + - variable: value + description: | + The value to set for the property.
+ label: Value + schema: + type: string + required: true + - variable: jenkinsOpts + label: Additional Jenkins Options + description: | + Configure additional jenkins options for Jenkins.
+ see https://www.jenkins.io/doc/book/installing/initial-settings + schema: + type: list + default: [] + items: + - variable: jenkinsOption + label: Jenkins Option + description: | + The option to set, see https://www.jenkins.io/doc/book/installing/initial-settings
+ The prefix [--] is automatically added. + schema: + type: string + required: true + - variable: additionalEnvs + label: Additional Environment Variables + description: Configure additional environment variables for Jenkins. + schema: + type: list + default: [] + items: + - variable: env + label: Environment Variable + schema: + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: value + label: Value + schema: + type: string + required: true + + - variable: jenkinsNetwork + label: "" + group: Network Configuration + schema: + type: dict + attrs: + - variable: webPort + label: Web Port + description: The port for the Jenkins Web UI. + schema: + type: int + default: 30036 + min: 9000 + max: 65535 + required: true + - variable: certificateID + label: Certificate + description: The certificate to use for HTTPS. + schema: + type: int + $ref: + - "definitions/certificate" + - variable: agent + label: Enable Agent + description: Enable Agent Port for Jenkins. + schema: + type: boolean + default: false + - variable: agentPort + label: Agent Port + description: The port for the Jenkins Agent. + schema: + type: int + show_if: [["agent", "=", true]] + default: 50000 + min: 9000 + max: 65535 + required: true + - variable: hostNetwork + label: Host Network + description: | + Bind to the host network. It's recommended to keep this disabled.
+ schema: + type: boolean + default: false + + - variable: jenkinsStorage + label: "" + group: Storage Configuration + schema: + type: dict + attrs: + - variable: home + label: Jenkins Home Storage + description: The path to store Jenkins Home Directory. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + default: "ixVolume" + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - variable: datasetName + label: Dataset Name + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + hidden: true + immutable: true + default: "home" + $ref: + - "normalize/ixVolume" + - variable: hostPath + label: Host Path + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + immutable: true + required: true + + - variable: additionalStorages + label: Additional Storage + description: Additional storage for Jenkins. + schema: + type: list + default: [] + items: + - variable: storageEntry + label: Storage Entry + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + default: "ixVolume" + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - variable: mountPath + label: Mount Path + description: The path inside the container to mount the storage. + schema: + type: path + required: true + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["type", "=", "hostPath"]] + required: true + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + show_if: [["type", "=", "ixVolume"]] + required: true + immutable: true + default: "storage_entry" + $ref: + - "normalize/ixVolume" + + - variable: resources + group: Resources Configuration + label: "" + schema: + type: dict + attrs: + - variable: limits + label: Limits + schema: + type: dict + attrs: + - variable: cpu + label: CPU + description: CPU limit for Jenkins. + schema: + type: string + default: "4000m" + required: true + - variable: memory + label: Memory + description: Memory limit for Jenkins. + schema: + type: string + default: "8Gi" + required: true diff --git a/library/ix-dev/community/jenkins/templates/NOTES.txt b/library/ix-dev/community/jenkins/templates/NOTES.txt new file mode 100644 index 0000000000..ba4e01146c --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/NOTES.txt @@ -0,0 +1 @@ +{{ include "ix.v1.common.lib.chart.notes" $ }} diff --git a/library/ix-dev/community/jenkins/templates/_certContainer.tpl b/library/ix-dev/community/jenkins/templates/_certContainer.tpl new file mode 100644 index 0000000000..9615f947ab --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/_certContainer.tpl @@ -0,0 +1,48 @@ +{{- define "jenkins.certContainer" -}} +enabled: true +type: init +imageSelector: image +securityContext: + runAsUser: 1000 + runAsGroup: 1000 +command: + - /bin/sh + - -c +args: + - | + {{- $key := printf "%v/%v" .Values.jenkinsConstants.certsPath .Values.jenkinsConstants.keyName -}} + {{- $cert := printf "%v/%v" .Values.jenkinsConstants.certsPath .Values.jenkinsConstants.crtName -}} + {{- $keystore := printf "%v/%v" .Values.jenkinsConstants.keystorePath .Values.jenkinsConstants.keystoreName }} + # Create the directories for the certificates and keystore + mkdir -p "{{ .Values.jenkinsConstants.certsPath }}" + mkdir -p "{{ .Values.jenkinsConstants.keystorePath }}" + + if [ -f "/tmp/ix.p12" ]; then + echo "Cleaning up old certificate" + rm "/tmp/ix.p12" + fi + + echo "Generating new certificate from key and cert" + + if [ -f "{{ $key }}" ] && [ -f "{{ $cert }}" ]; then + echo "Found key and cert, creating p12 certificate" + + openssl pkcs12 -inkey "{{ $key }}" -in "{{ $cert }}" \ + -export -out "/tmp/ix.p12" \ + -password pass:{{ .Values.jenkinsCertRandomPass }} || exit 1 + echo "P12 Certificate created" + + if [ -f "{{ $keystore }}" ]; then + echo "Keystore already exists, removing and creating a new one" + rm "{{ $keystore }}" + fi + + echo "Importing certificate into a new java keystore" + keytool -importkeystore -srckeystore "/tmp/ix.p12" -srcstoretype pkcs12 \ + -destkeystore "{{ $keystore }}" -deststoretype JKS \ + -srcstorepass {{ .Values.jenkinsCertRandomPass }} \ + -deststorepass {{ .Values.jenkinsCertRandomPass }} || exit 1 + + echo "Certificate imported" + fi +{{- end -}} diff --git a/library/ix-dev/community/jenkins/templates/_configuration.tpl b/library/ix-dev/community/jenkins/templates/_configuration.tpl new file mode 100644 index 0000000000..5b23be5d9f --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/_configuration.tpl @@ -0,0 +1,23 @@ +{{- define "jenkins.configuration" -}} +opts: + jenkinsOpts: + {{- if not .Values.jenkinsNetwork.certificateID }} + - --httpPort={{ .Values.jenkinsNetwork.webPort }} + {{- end -}} + {{- if .Values.jenkinsNetwork.certificateID }} + - --httpPort=-1 + - --httpsPort={{ .Values.jenkinsNetwork.webPort }} + - --httpsKeyStore={{ .Values.jenkinsConstants.keystorePath }}/{{ .Values.jenkinsConstants.keystoreName }} + - --httpsKeyStorePassword={{ .Values.jenkinsCertRandomPass }} + {{- end -}} + {{- range $opt := .Values.jenkinsConfig.jenkinsOpts }} + - --{{ $opt }} + {{- end }} + + jenkinsJavaOpts: + - -Djenkins.model.Jenkins.slaveAgentPortEnforce=true + - -Djenkins.model.Jenkins.slaveAgentPort={{ ternary .Values.jenkinsNetwork.agentPort "-1" .Values.jenkinsNetwork.agent }} + {{- range $opt := .Values.jenkinsConfig.jenkinsJavaOpts }} + - -D{{ $opt.property }}={{ $opt.value }} + {{- end }} +{{- end -}} diff --git a/library/ix-dev/community/jenkins/templates/_jenkins.tpl b/library/ix-dev/community/jenkins/templates/_jenkins.tpl new file mode 100644 index 0000000000..06e1355833 --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/_jenkins.tpl @@ -0,0 +1,148 @@ +{{- define "jenkins.workload" -}} +workload: + jenkins: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: {{ .Values.jenkinsNetwork.hostNetwork }} + securityContext: + fsGroup: 1000 + containers: + jenkins: + enabled: true + primary: true + imageSelector: image + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + {{ $config := (include "jenkins.configuration" $ | fromYaml).opts }} + env: + JENKINS_SLAVE_AGENT_PORT: {{ .Values.jenkinsNetwork.agentPort }} + JENKINS_JAVA_OPTS: {{ join " " $config.jenkinsJavaOpts }} + JENKINS_OPTS: {{ join " " $config.jenkinsOpts }} + {{ with .Values.jenkinsConfig.additionalEnvs }} + envList: + {{ range $env := . }} + - name: {{ $env.name }} + values: {{ $env.value }} + {{ end }} + {{ end }} + {{ $scheme := "http" }} + {{ if .Values.jenkinsNetwork.certificateID }} + {{ $scheme = "https" }} + {{ end }} + probes: + liveness: + enabled: true + type: {{ $scheme }} + port: {{ .Values.jenkinsNetwork.webPort }} + path: /login + readiness: + enabled: true + type: {{ $scheme }} + port: {{ .Values.jenkinsNetwork.webPort }} + path: /login + startup: + enabled: true + type: {{ $scheme }} + port: {{ .Values.jenkinsNetwork.webPort }} + path: /login + initContainers: + {{- include "ix.v1.common.app.permissions" (dict "containerName" "01-permissions" + "UID" 1000 + "GID" 1000 + "mode" "check" + "type" "init") | nindent 8 }} + {{- if .Values.jenkinsNetwork.certificateID }} + 02-cert-container: + {{- include "jenkins.certContainer" $ | nindent 10 }} + {{- end }} + +{{/* Service */}} +service: + jenkins: + enabled: true + primary: true + type: NodePort + targetSelector: jenkins + ports: + web: + enabled: true + primary: true + port: {{ .Values.jenkinsNetwork.webPort }} + nodePort: {{ .Values.jenkinsNetwork.webPort }} + targetSelector: jenkins + agent: + enabled: {{ .Values.jenkinsNetwork.agent }} + primary: false + type: NodePort + targetSelector: jenkins + ports: + agent: + enabled: {{ .Values.jenkinsNetwork.agent }} + primary: true + port: {{ .Values.jenkinsNetwork.agentPort }} + nodePort: {{ .Values.jenkinsNetwork.agentPort }} + targetSelector: jenkins + +{{/* Persistence */}} +persistence: + home: + enabled: true + type: {{ .Values.jenkinsStorage.home.type }} + datasetName: {{ .Values.jenkinsStorage.home.datasetName | default "" }} + hostPath: {{ .Values.jenkinsStorage.home.hostPath | default "" }} + targetSelector: + jenkins: + jenkins: + mountPath: /var/jenkins_home + 01-permissions: + mountPath: /mnt/directories/home + 02-cert-container: + mountPath: /var/jenkins_home + tmp: + enabled: true + type: emptyDir + targetSelector: + jenkins: + jenkins: + mountPath: /tmp + 02-cert-container: + mountPath: /tmp + {{- range $idx, $storage := .Values.jenkinsStorage.additionalStorages }} + {{ printf "jenkins-%v" (int $idx) }}: + enabled: true + type: {{ $storage.type }} + datasetName: {{ $storage.datasetName | default "" }} + hostPath: {{ $storage.hostPath | default "" }} + targetSelector: + jenkins: + jenkins: + mountPath: {{ $storage.mountPath }} + 01-permissions: + mountPath: /mnt/directories{{ $storage.mountPath }} + {{- end }} + {{- if .Values.jenkinsNetwork.certificateID }} + cert: + enabled: true + type: secret + objectName: jenkins-cert + defaultMode: "0600" + items: + - key: tls.key + path: {{ .Values.jenkinsConstants.keyName }} + - key: tls.crt + path: {{ .Values.jenkinsConstants.crtName }} + targetSelector: + jenkins: + 02-cert-container: + mountPath: {{ .Values.jenkinsConstants.certsPath }} + readOnly: true + +scaleCertificate: + jenkins-cert: + enabled: true + id: {{ .Values.jenkinsNetwork.certificateID }} + {{- end -}} +{{- end -}} diff --git a/library/ix-dev/community/jenkins/templates/_portal.tpl b/library/ix-dev/community/jenkins/templates/_portal.tpl new file mode 100644 index 0000000000..2e8c496f90 --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/_portal.tpl @@ -0,0 +1,16 @@ +{{- define "jenkins.portal" -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: portal +data: + {{- $protocol := "http" -}} + {{- if .Values.jenkinsNetwork.certificateID -}} + {{- $protocol = "https" -}} + {{- end }} + path: "/login" + host: $node_ip + protocol: {{ $protocol }} + port: {{ .Values.jenkinsNetwork.webPort | quote }} +{{- end -}} diff --git a/library/ix-dev/community/jenkins/templates/_validation.tpl b/library/ix-dev/community/jenkins/templates/_validation.tpl new file mode 100644 index 0000000000..fad804d740 --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/_validation.tpl @@ -0,0 +1,38 @@ +{{- define "jenkins.validation" -}} + + {{- if not (deepEqual (uniq .Values.jenkinsConfig.jenkinsJavaOpts) .Values.jenkinsConfig.jenkinsJavaOpts) -}} + {{- fail "Jenkins - Jenkins Java Options must be unique" -}} + {{- end -}} + + {{- if not (deepEqual (uniq .Values.jenkinsConfig.jenkinsOpts) .Values.jenkinsConfig.jenkinsOpts) -}} + {{- fail "Jenkins - Jenkins Options must be unique" -}} + {{- end -}} + + {{- $reservedJenkinsJavaOpts := (list + "jenkins.model.Jenkins.slaveAgentPortEnforce" + "jenkins.model.Jenkins.slaveAgentPort") -}} + {{- $reservedJenkinsOpts := (list "httpPort") -}} + + {{- if .Values.jenkinsNetwork.certificateID -}} + {{- $reservedJenkinsOpts = mustAppend $reservedJenkinsOpts "httpsPort" -}} + {{- $reservedJenkinsOpts = mustAppend $reservedJenkinsOpts "httpsKeyStore" -}} + {{- end -}} + + {{- range $opt := .Values.jenkinsConfig.jenkinsOpts -}} + {{- if (hasPrefix "--" $opt) -}} + {{- fail "Jenkins - Please remove [--] prefix from Jenkins Option [%v], as it is added automatically." -}} + {{- end -}} + {{- if (mustHas $opt $reservedJenkinsOpts) -}} + {{- fail "Jenkins - Setting Jenkins Option [%v] is not allowed." -}} + {{- end -}} + {{- end -}} + + {{- range $opt := .Values.jenkinsConfig.jenkinsJavaOpts -}} + {{- if (hasPrefix "-D" $opt.property) -}} + {{- fail "Jenkins - Please remove [-D] prefix from Jenkins Java Option [%v], as it is added automatically." -}} + {{- end -}} + {{- if (mustHas $opt.property $reservedJenkinsJavaOpts) -}} + {{- fail "Jenkins - Setting Jenkins Java Option [%v] is not allowed." -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/library/ix-dev/community/jenkins/templates/common.yaml b/library/ix-dev/community/jenkins/templates/common.yaml new file mode 100644 index 0000000000..259bb1e190 --- /dev/null +++ b/library/ix-dev/community/jenkins/templates/common.yaml @@ -0,0 +1,19 @@ +{{- include "ix.v1.common.loader.init" . -}} + +{{/* Run the validation */}} +{{- include "jenkins.validation" $ -}} + +{{/* Generate a new random pass on each start to password protect certificate */}} +{{- if .Values.jenkinsNetwork.certificateID -}} + {{- $_ := set .Values "jenkinsCertRandomPass" (randAlphaNum 32) -}} +{{- else if .Values.jenkinsCertRandomPass -}} {{/* Cleanup if no cert is defined */}} + {{- $_ := unset .Values "jenkinsCertRandomPass" -}} +{{- end -}} + +{{/* Merge the templates with Values */}} +{{- $_ := mustMergeOverwrite .Values (include "jenkins.workload" $ | fromYaml) -}} + +{{/* Create the configmap for portal manually*/}} +{{- include "jenkins.portal" $ -}} + +{{- include "ix.v1.common.loader.apply" . -}} diff --git a/library/ix-dev/community/jenkins/upgrade_info.json b/library/ix-dev/community/jenkins/upgrade_info.json new file mode 100644 index 0000000000..767388094a --- /dev/null +++ b/library/ix-dev/community/jenkins/upgrade_info.json @@ -0,0 +1 @@ +{"filename": "values.yaml", "keys": ["image"]} diff --git a/library/ix-dev/community/jenkins/upgrade_strategy b/library/ix-dev/community/jenkins/upgrade_strategy new file mode 100755 index 0000000000..52d32d78f8 --- /dev/null +++ b/library/ix-dev/community/jenkins/upgrade_strategy @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import json +import re +import sys + +from catalog_update.upgrade_strategy import semantic_versioning + + +RE_STABLE_VERSION = re.compile(r'[0-9]+\.[0-9]+\.[0-9]+-jdk17') + + +def newer_mapping(image_tags): + key = list(image_tags.keys())[0] + tags = {t.strip('-jdk17'): t for t in image_tags[key] if RE_STABLE_VERSION.fullmatch(t)} + version = semantic_versioning(list(tags)) + if not version: + return {} + + return { + 'tags': {key: tags[version]}, + 'app_version': version, + } + + +if __name__ == '__main__': + try: + versions_json = json.loads(sys.stdin.read()) + except ValueError: + raise ValueError('Invalid json specified') + + print(json.dumps(newer_mapping(versions_json))) diff --git a/library/ix-dev/community/jenkins/values.yaml b/library/ix-dev/community/jenkins/values.yaml new file mode 100644 index 0000000000..ceb22ff439 --- /dev/null +++ b/library/ix-dev/community/jenkins/values.yaml @@ -0,0 +1,42 @@ +image: + repository: jenkins/jenkins + pullPolicy: IfNotPresent + tag: '2.401.1-jdk17' + +resources: + limits: + cpu: 4000m + memory: 8Gi + +jenkinsConfig: + jenkinsOpts: [] + jenkinsJavaOpts: [] + additionalEnvs: [] +jenkinsNetwork: + webPort: 30036 + https: false + certificateID: 0 + agent: false + agentPort: 50000 + hostNetwork: false +jenkinsStorage: + home: + type: ixVolume + datasetName: home + additionalStorages: [] + +# Not user configurable +jenkinsConstants: + certsPath: /tmp/ix-certs + keystorePath: /var/jenkins_home/ix-keystore + crtName: ix.crt + keyName: ix.key + keystoreName: ix.jks + +notes: + custom: | + The initial Admin password is generated on the + first run of Jenkins. You can retrieve it by + looking at the logs of Jenkins. + + The default username is admin.