Add option to skip install of plugins (#1065)

Co-authored-by: Luigi Operoso <40476330+brokenpip3@users.noreply.github.com>
This commit is contained in:
Tobia De Koninck 2025-04-21 11:38:28 +02:00 committed by GitHub
parent 132fcb22dc
commit 69bdd916d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 56 additions and 0 deletions

View File

@ -377,6 +377,12 @@ type JenkinsMaster struct {
// +optional // +optional
LatestPlugins *bool `json:"latestPlugins,omitempty"` LatestPlugins *bool `json:"latestPlugins,omitempty"`
// Allow to skip installation of both BasePlugins and Plugins.
// Requires using a custom image which includes the BasePlugins.
// Defaults to false.
// +optional
SkipPlugins *bool `json:"skipPlugins,omitempty"`
// DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins // DisableCSRFProtection allows you to toggle CSRF Protection on Jenkins
DisableCSRFProtection bool `json:"disableCSRFProtection"` DisableCSRFProtection bool `json:"disableCSRFProtection"`

View File

@ -361,6 +361,11 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
if in.SkipPlugins != nil {
in, out := &in.SkipPlugins, &out.SkipPlugins
*out = new(bool)
**out = **in
}
if in.HostAliases != nil { if in.HostAliases != nil {
in, out := &in.HostAliases, &out.HostAliases in, out := &in.HostAliases, &out.HostAliases
*out = make([]corev1.HostAlias, len(*in)) *out = make([]corev1.HostAlias, len(*in))

View File

@ -91,6 +91,7 @@ Kubernetes native operator which fully manages Jenkins on Kubernetes
| jenkins.seedJobAgentImage | string | `""` | | | jenkins.seedJobAgentImage | string | `""` | |
| jenkins.seedJobs | list | `[]` | | | jenkins.seedJobs | list | `[]` | |
| jenkins.serviceAccount.annotations | object | `{}` | | | jenkins.serviceAccount.annotations | object | `{}` | |
| jenkins.skipPlugins | bool | `false` | |
| jenkins.terminationGracePeriodSeconds | int | `30` | | | jenkins.terminationGracePeriodSeconds | int | `30` | |
| jenkins.tolerations | list | `[]` | | | jenkins.tolerations | list | `[]` | |
| jenkins.validateSecurityWarnings | bool | `false` | | | jenkins.validateSecurityWarnings | bool | `false` | |

View File

@ -1330,6 +1330,11 @@ spec:
type: string type: string
type: object type: object
type: object type: object
skipPlugins:
description: 'Allow to skip installation of both BasePlugins and
Plugins. Requires using a custom image which includes the
BasePlugins. Defaults to false.'
type: boolean
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
description: 'Optional duration in seconds the pod needs to terminate gracefully.' description: 'Optional duration in seconds the pod needs to terminate gracefully.'
type: integer type: integer

View File

@ -115,6 +115,7 @@ spec:
{{- with .Values.jenkins.hostAliases }} {{- with .Values.jenkins.hostAliases }}
hostAliases: {{ toYaml . | nindent 4 }} hostAliases: {{ toYaml . | nindent 4 }}
{{- end }} {{- end }}
skipPlugins: {{ .Values.jenkins.skipPlugins }}
{{- if .Values.jenkins.terminationGracePeriodSeconds }} {{- if .Values.jenkins.terminationGracePeriodSeconds }}
terminationGracePeriodSeconds: {{ .Values.jenkins.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.jenkins.terminationGracePeriodSeconds }}
{{- end }} {{- end }}

View File

@ -145,6 +145,11 @@ jenkins:
# 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 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: "" seedJobAgentImage: ""
# skipPlugins allows to skip installation of both BasePlugins and Plugins.
# Requires using a custom image which includes the BasePlugins.
# Defaults to false.
skipPlugins: false
# Resource limit/request for Jenkins # Resource limit/request for Jenkins
# See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ for details # See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ for details
resources: resources:

View File

@ -1674,6 +1674,10 @@ spec:
type: string type: string
type: object type: object
type: object type: object
skipPlugins:
description: Allow to skip installation of both BasePlugins and Plugins. Requires using a custom
image which includes the BasePlugins. Defaults to false.
type: boolean
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
description: |- description: |-
The grace period is the duration in seconds after the processes running in the pod are sent The grace period is the duration in seconds after the processes running in the pod are sent

View File

@ -13,6 +13,9 @@ import (
) )
func (r *JenkinsBaseConfigurationReconciler) verifyPlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) { func (r *JenkinsBaseConfigurationReconciler) verifyPlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) {
if r.Configuration.Jenkins.Spec.Master.SkipPlugins != nil && *r.Configuration.Jenkins.Spec.Master.SkipPlugins {
return true, nil
}
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins) allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
if err != nil { if err != nil {
return false, stackerr.WithStack(err) return false, stackerr.WithStack(err)

View File

@ -2,6 +2,7 @@ package resources
import ( import (
"fmt" "fmt"
"strings"
"text/template" "text/template"
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2" "github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
@ -14,6 +15,8 @@ import (
const installPluginsCommand = "jenkins-plugin-cli" const installPluginsCommand = "jenkins-plugin-cli"
var requiredBasePlugins = []string{"configuration-as-code", "git", "job-dsl", "kubernetes", "kubernetes-credentials-provider", "workflow-aggregator"}
var initBashTemplate = template.Must(template.New(InitScriptName).Parse(`#!/usr/bin/env bash var initBashTemplate = template.Must(template.New(InitScriptName).Parse(`#!/usr/bin/env bash
set -e set -e
set -x set -x
@ -36,6 +39,7 @@ mkdir -p {{ .JenkinsHomePath }}/scripts
cp {{ .JenkinsScriptsVolumePath }}/*.sh {{ .JenkinsHomePath }}/scripts cp {{ .JenkinsScriptsVolumePath }}/*.sh {{ .JenkinsHomePath }}/scripts
chmod +x {{ .JenkinsHomePath }}/scripts/*.sh chmod +x {{ .JenkinsHomePath }}/scripts/*.sh
{{if not .SkipPlugins }}
{{- $jenkinsHomePath := .JenkinsHomePath }} {{- $jenkinsHomePath := .JenkinsHomePath }}
{{- $installPluginsCommand := .InstallPluginsCommand }} {{- $installPluginsCommand := .InstallPluginsCommand }}
@ -58,6 +62,19 @@ EOF
{{ $installPluginsCommand }} --verbose --latest {{ .LatestPlugins }} -f {{ .JenkinsHomePath }}/user-plugins.txt {{ $installPluginsCommand }} --verbose --latest {{ .LatestPlugins }} -f {{ .JenkinsHomePath }}/user-plugins.txt
echo "Installing plugins required by user - end" echo "Installing plugins required by user - end"
{{else}}
echo "Skipping installation if plugins"
echo "Checking if required base plugins are installed"
installedPlugins=$(jenkins-plugin-cli --list 2> /dev/null)
for plugin in {{ .RequiredBasePlugins }}; do
if ! echo "$installedPlugins" | grep -q "^$plugin "; then
echo "Required base plugin $plugin not installed, exiting"
exit 1
else
echo "Found $plugin"
fi
done
{{end}}
`)) `))
func buildConfigMapTypeMeta() metav1.TypeMeta { func buildConfigMapTypeMeta() metav1.TypeMeta {
@ -73,22 +90,31 @@ func buildInitBashScript(jenkins *v1alpha2.Jenkins) (*string, error) {
latestP = new(bool) latestP = new(bool)
*latestP = true *latestP = true
} }
skipPlugins := jenkins.Spec.Master.SkipPlugins
if skipPlugins == nil {
skipPlugins = new(bool)
*skipPlugins = false
}
data := struct { data := struct {
JenkinsHomePath string JenkinsHomePath string
InitConfigurationPath string InitConfigurationPath string
InstallPluginsCommand string InstallPluginsCommand string
RequiredBasePlugins string
JenkinsScriptsVolumePath string JenkinsScriptsVolumePath string
BasePlugins []v1alpha2.Plugin BasePlugins []v1alpha2.Plugin
UserPlugins []v1alpha2.Plugin UserPlugins []v1alpha2.Plugin
LatestPlugins bool LatestPlugins bool
SkipPlugins bool
}{ }{
JenkinsHomePath: getJenkinsHomePath(jenkins), JenkinsHomePath: getJenkinsHomePath(jenkins),
InitConfigurationPath: jenkinsInitConfigurationVolumePath, InitConfigurationPath: jenkinsInitConfigurationVolumePath,
BasePlugins: jenkins.Spec.Master.BasePlugins, BasePlugins: jenkins.Spec.Master.BasePlugins,
UserPlugins: jenkins.Spec.Master.Plugins, UserPlugins: jenkins.Spec.Master.Plugins,
InstallPluginsCommand: installPluginsCommand, InstallPluginsCommand: installPluginsCommand,
RequiredBasePlugins: strings.Join(requiredBasePlugins, " "),
JenkinsScriptsVolumePath: JenkinsScriptsVolumePath, JenkinsScriptsVolumePath: JenkinsScriptsVolumePath,
LatestPlugins: *latestP, LatestPlugins: *latestP,
SkipPlugins: *skipPlugins,
} }
output, err := render.Render(initBashTemplate, data) output, err := render.Render(initBashTemplate, data)