wip tests and chart values for ephemeral home

This commit is contained in:
Luigi Operoso 2023-05-06 16:43:26 +00:00
parent 4727c06c87
commit 4e9050d276
10 changed files with 152 additions and 55 deletions

View File

@ -346,7 +346,7 @@ type JenkinsMaster struct {
// Storage settings for the jenkins home directory
// Can be tempDir or ephemeral
// +optional
StorageSettings StorageSettings `json:"storage,omitempty"`
StorageSettings StorageSettings `json:"storageSettings,omitempty"`
// If specified, the pod's tolerations.
// +optional
@ -392,11 +392,16 @@ type JenkinsMaster struct {
HostAliases []corev1.HostAlias `json:"hostAliases,omitempty"`
}
// StorageSettings defines Jenkins master pod persistance attributes.
// StorageSettings defines Jenkins master pod persistence attributes.
// +optional
type StorageSettings struct {
UseTempDir bool `json:"useTempDir"`
// UseEmptyDir allows you to create an emptydir as jenkins-home, also this is the default
UseEmptyDir bool `json:"useEmptyDir"`
// UseEphemeralStorage allows you to create kubernetes ephemeral pvc, see "https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes"
UseEphemeralStorage bool `json:"useEphemeralStorage"`
// StorageClassName in case of ephemeral pvc, can be empty
StorageClassName string `json:"storageClassName"`
// StorageRequest allows you to specify the storage request, required in case of ephemeral pvc
StorageRequest string `json:"storageRequest"`
}

View File

@ -1,4 +1,3 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
@ -23,7 +22,7 @@ package v1alpha2
import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
)
@ -340,6 +339,7 @@ func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
out.StorageSettings = in.StorageSettings
if in.Tolerations != nil {
in, out := &in.Tolerations, &out.Tolerations
*out = make([]corev1.Toleration, len(*in))
@ -400,7 +400,7 @@ 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)
@ -763,6 +763,21 @@ func (in *Slack) DeepCopy() *Slack {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageSettings) DeepCopyInto(out *StorageSettings) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageSettings.
func (in *StorageSettings) DeepCopy() *StorageSettings {
if in == nil {
return nil
}
out := new(StorageSettings)
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

View File

@ -157,11 +157,11 @@ spec:
type: object
basePlugins:
description: 'BasePlugins contains plugins required by operator
Defaults to : - name: kubernetes version: "1.31.3" - name:
workflow-job version: "1145.v7f2433caa07f" - name: workflow-aggregator version:
"2.6" - name: git version: "4.11.3" - name: job-dsl version:
"1.78.1" - name: configuration-as-code version: "1346.ve8cfa_3473c94" - name:
kubernetes-credentials-provider version: "0.20"'
Defaults to : - name: configuration-as-code version: "1625.v27444588cc3d"
- name: git version: "5.0.0" - name: job-dsl version: "1.83"
- name: kubernetes version: "3909.v1f2c633e8590" - name: kubernetes-credentials-provider
version: "1.211.vc236a_f5a_2f3c" - name: workflow-aggregator
version: "596.v8c21c963d92d" - name: workflow-job version: "1289.vd1c337fd5354"'
items:
description: Plugin defines Jenkins plugin.
properties:
@ -1100,11 +1100,6 @@ spec:
- resources
type: object
type: array
latestPlugins:
description: 'Allow to override jenkins-plugin-cli default behavior
while downloading the plugin and dependencies, see:
https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options'
type: boolean
disableCSRFProtection:
description: DisableCSRFProtection allows you to toggle CSRF Protection
on Jenkins
@ -1150,6 +1145,10 @@ spec:
selectors of replication controllers and services. More info:
http://kubernetes.io/docs/user-guide/labels'
type: object
latestPlugins:
description: 'Allow to override jenkins-plugin-cli default behavior
while downloading the plugin and dependencies see: https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options'
type: boolean
nodeSelector:
additionalProperties:
type: string
@ -1331,6 +1330,32 @@ spec:
type: string
type: object
type: object
storageSettings:
description: Storage settings for the jenkins home directory Can
be tempDir or ephemeral
properties:
storageClassName:
description: StorageClassName in case of ephemeral pvc, can
be empty
type: string
storageRequest:
description: StorageRequest allows you to specify the storage
request, required in case of ephemeral pvc
type: string
useEmptyDir:
description: UseEmptyDir allows you to create an emptydir
as jenkins-home, also this is the default
type: boolean
useEphemeralStorage:
description: UseEphemeralStorage allows you to create kubernetes
ephemeral pvc, see "https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes"
type: boolean
required:
- storageClassName
- storageRequest
- useEmptyDir
- useEphemeralStorage
type: object
tolerations:
description: If specified, the pod's tolerations.
items:
@ -2864,6 +2889,7 @@ spec:
type: array
required:
- disableCSRFProtection
- latestPlugins
type: object
notifications:
description: Notifications defines list of a services which are used
@ -3124,8 +3150,10 @@ spec:
type: object
type: array
seedJobAgentImage:
description: SeedJobAgentImage defines the image that will be used
by the seed job agent. If not defined jenkins/inbound-agent:4.9-1
will be used.
type: string
description: 'SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:4.10-3 will be used.'
seedJobs:
description: 'SeedJobs defines list of Jenkins Seed Job configurations
More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines'

View File

@ -146,6 +146,9 @@ spec:
{{- end }}
{{- end }}
{{- with .Values.jenkins.volumes }}
storageSettings: {{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.jenkins.storageSettings }}
volumes: {{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.jenkins.imagePullSecrets }}

View File

@ -158,6 +158,18 @@ jenkins:
# See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts for details
volumeMounts: []
# Storage for Jenkins
# By default emptyDir
# See https://kubernetes.io/docs/concepts/storage/volumes/#emptydir for details
storageSettings:
useEmptyDir: true
# Alternative storage settings
# An ephemeral pvc can be used see https://kubernetes.io/docs/concepts/storage/volumes/#ephemeral-volume
# In case is true we also need to pass the storageRequest and optionally the storageClassName
ephemeralStorage: false
storageClassName: ""
storageRequest: ""
# defines authorization strategy of the operator for the Jenkins API
authorizationStrategy: createUser

View File

@ -157,11 +157,11 @@ spec:
type: object
basePlugins:
description: 'BasePlugins contains plugins required by operator
Defaults to : - name: kubernetes version: "1.31.3" - name:
workflow-job version: "1145.v7f2433caa07f" - name: workflow-aggregator version:
"2.6" - name: git version: "4.11.3" - name: job-dsl version:
"1.78.1" - name: configuration-as-code version: "1346.ve8cfa_3473c94" - name:
kubernetes-credentials-provider version: "0.20"'
Defaults to : - name: configuration-as-code version: "1625.v27444588cc3d"
- name: git version: "5.0.0" - name: job-dsl version: "1.83"
- name: kubernetes version: "3909.v1f2c633e8590" - name: kubernetes-credentials-provider
version: "1.211.vc236a_f5a_2f3c" - name: workflow-aggregator
version: "596.v8c21c963d92d" - name: workflow-job version: "1289.vd1c337fd5354"'
items:
description: Plugin defines Jenkins plugin.
properties:
@ -1100,11 +1100,6 @@ spec:
- resources
type: object
type: array
latestPlugins:
description: 'Allow to override jenkins-plugin-cli default behavior
while downloading the plugin and dependencies, see:
https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options'
type: boolean
disableCSRFProtection:
description: DisableCSRFProtection allows you to toggle CSRF Protection
on Jenkins
@ -1150,6 +1145,10 @@ spec:
selectors of replication controllers and services. More info:
http://kubernetes.io/docs/user-guide/labels'
type: object
latestPlugins:
description: 'Allow to override jenkins-plugin-cli default behavior
while downloading the plugin and dependencies see: https://github.com/jenkinsci/plugin-installation-manager-tool#cli-options'
type: boolean
nodeSelector:
additionalProperties:
type: string
@ -1331,6 +1330,32 @@ spec:
type: string
type: object
type: object
storageSettings:
description: Storage settings for the jenkins home directory Can
be tempDir or ephemeral
properties:
storageClassName:
description: StorageClassName in case of ephemeral pvc, can
be empty
type: string
storageRequest:
description: StorageRequest allows you to specify the storage
request, required in case of ephemeral pvc
type: string
useEmptyDir:
description: UseEmptyDir allows you to create an emptydir
as jenkins-home, also this is the default
type: boolean
useEphemeralStorage:
description: UseEphemeralStorage allows you to create kubernetes
ephemeral pvc, see "https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes"
type: boolean
required:
- storageClassName
- storageRequest
- useEmptyDir
- useEphemeralStorage
type: object
tolerations:
description: If specified, the pod's tolerations.
items:
@ -2864,6 +2889,7 @@ spec:
type: array
required:
- disableCSRFProtection
- latestPlugins
type: object
notifications:
description: Notifications defines list of a services which are used
@ -3124,8 +3150,10 @@ spec:
type: object
type: array
seedJobAgentImage:
description: SeedJobAgentImage defines the image that will be used
by the seed job agent. If not defined jenkins/inbound-agent:4.9-1
will be used.
type: string
description: 'SeedJobAgentImage defines the image that will be used by the seed job agent. If not defined jenkins/inbound-agent:4.10-3 will be used.'
seedJobs:
description: 'SeedJobs defines list of Jenkins Seed Job configurations
More info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration#configure-seed-jobs-and-pipelines'

View File

@ -94,16 +94,11 @@ func validateStorageSize(storageSize string) bool {
return false
}
_, err := resource.ParseQuantity(storageSize)
if err != nil {
return false
}
return true
return err == nil
}
// get Jenkins home storage settings from the CRD
func getJenkinsHomeStorageSettings(jenkins *v1alpha2.Jenkins) corev1.Volume {
JenkinsHomeVolume := corev1.Volume{}
emptyDirVol := corev1.Volume{
Name: JenkinsHomeVolumeName,
VolumeSource: corev1.VolumeSource{
@ -111,7 +106,7 @@ func getJenkinsHomeStorageSettings(jenkins *v1alpha2.Jenkins) corev1.Volume {
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
}
var JenkinsHomeVolume corev1.Volume
if jenkins.Spec.Master.StorageSettings.UseEphemeralStorage {
if !validateStorageSize(jenkins.Spec.Master.StorageSettings.StorageRequest) {
fmt.Println("Invalid storage size %s, falling back to empty dir" + jenkins.Spec.Master.StorageSettings.StorageRequest)

View File

@ -1,6 +1,7 @@
package resources
import (
"fmt"
"testing"
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
@ -143,22 +144,23 @@ func TestGetJenkinsMasterPodBaseVolumes(t *testing.T) {
assert.True(t, groovyExists)
assert.True(t, cascExists)
})
// TODO: fix me
t.Run("home volume is present and is Tempdir", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{
StorageSettings: v1alpha2.StorageSettings{
UseTempDir: true,
UseEmptyDir: true,
},
},
},
}
HomeExist, HomeTempdirExist, HomeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
homeExist, homeTempdirExist, homeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
assert.True(t, HomeExist)
assert.True(t, HomeTempdirExist)
assert.False(t, HomeEphemeralStorageExist)
assert.True(t, homeExist)
assert.True(t, homeTempdirExist)
assert.False(t, homeEphemeralStorageExist)
})
t.Run("home volume is present and it's ephemeral", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{
@ -166,18 +168,27 @@ func TestGetJenkinsMasterPodBaseVolumes(t *testing.T) {
Master: v1alpha2.JenkinsMaster{
StorageSettings: v1alpha2.StorageSettings{
UseEphemeralStorage: true,
StorageClassName: "",
StorageClassName: "default",
StorageRequest: "1Gi",
},
},
},
}
HomeExist, HomeTempdirExist, HomeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
homeExist, homeTempdirExist, homeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
assert.True(t, HomeExist)
assert.False(t, HomeTempdirExist)
assert.True(t, HomeEphemeralStorageExist)
assert.True(t, homeExist)
assert.False(t, homeTempdirExist)
assert.True(t, homeEphemeralStorageExist)
})
t.Run("home volume is default and should be an empty dir", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{}
homeExist, homeTempdirExist, homeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
assert.True(t, homeExist)
assert.True(t, homeTempdirExist)
assert.False(t, homeEphemeralStorageExist)
})
}
@ -192,23 +203,23 @@ func checkSecretVolumesPresence(jenkins *v1alpha2.Jenkins) (groovyExists bool, c
return groovyExists, cascExists
}
func checkHomeVolumesPresence(jenkins *v1alpha2.Jenkins) (HomeExist bool, HomeTempdirExist bool, HomeEphemeralStorageExist bool) {
func checkHomeVolumesPresence(jenkins *v1alpha2.Jenkins) (homeExist bool, homeTempdirExist bool, homeEphemeralStorageExist bool) {
for _, volume := range GetJenkinsMasterPodBaseVolumes(jenkins) {
if volume.Name == ("jenkins-home") {
HomeExist = true
homeExist = true
// check if the volume is an emptyDir
if volume.VolumeSource.EmptyDir != nil {
HomeTempdirExist = true
homeTempdirExist = true
} else if volume.VolumeSource.Ephemeral != nil {
HomeEphemeralStorageExist = true
homeEphemeralStorageExist = true
}
} else {
HomeExist = false
HomeTempdirExist = false
HomeEphemeralStorageExist = false
homeExist = false
homeTempdirExist = false
homeEphemeralStorageExist = false
}
}
return HomeExist, HomeTempdirExist, HomeEphemeralStorageExist
return homeExist, homeTempdirExist, homeEphemeralStorageExist
}
func Test_validateStorageSize(t *testing.T) {

View File

@ -2,7 +2,7 @@ package plugins
const (
configurationAsCodePlugin = "configuration-as-code:1625.v27444588cc3d"
gitPlugin = "git:5.0.0"
gitPlugin = "git:5.0.1"
jobDslPlugin = "job-dsl:1.83"
kubernetesPlugin = "kubernetes:3909.v1f2c633e8590"
kubernetesCredentialsProviderPlugin = "kubernetes-credentials-provider:1.211.vc236a_f5a_2f3c"

View File

@ -25,7 +25,7 @@ const e2e = "e2e"
var expectedBasePluginsList = []plugins.Plugin{
plugins.Must(plugins.New("configuration-as-code:1625.v27444588cc3d")),
plugins.Must(plugins.New("git:5.0.0")),
plugins.Must(plugins.New("git:5.0.1")),
plugins.Must(plugins.New("kubernetes:3909.v1f2c633e8590")),
plugins.Must(plugins.New("kubernetes-credentials-provider:1.211.vc236a_f5a_2f3c")),
plugins.Must(plugins.New("job-dsl:1.83")),