initial ephemeral home implementation
This commit is contained in:
parent
a690c7cc6c
commit
2e8fd0ea7a
|
|
@ -343,6 +343,11 @@ type JenkinsMaster struct {
|
|||
// +optional
|
||||
Volumes []corev1.Volume `json:"volumes,omitempty"`
|
||||
|
||||
// Storage settings for the jenkins home directory
|
||||
// Can be tempDir or ephemeral
|
||||
// +optional
|
||||
StorageSettings StorageSettings `json:"storage,omitempty"`
|
||||
|
||||
// If specified, the pod's tolerations.
|
||||
// +optional
|
||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
|
||||
|
|
@ -387,6 +392,14 @@ type JenkinsMaster struct {
|
|||
HostAliases []corev1.HostAlias `json:"hostAliases,omitempty"`
|
||||
}
|
||||
|
||||
// StorageSettings defines Jenkins master pod persistance attributes.
|
||||
type StorageSettings struct {
|
||||
UseTempDir bool `json:"useTempDir"`
|
||||
UseEphemeralStorage bool `json:"useEphemeralStorage"`
|
||||
StorageClassName string `json:"storageClassName"`
|
||||
StorageRequest string `json:"storageRequest"`
|
||||
}
|
||||
|
||||
// Service defines Kubernetes service attributes
|
||||
type Service struct {
|
||||
// Annotations is an unstructured key value map stored with a resource that may be
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/jenkinsci/kubernetes-operator/pkg/constants"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
|
@ -88,18 +89,67 @@ func getJenkinsHomePath(jenkins *v1alpha2.Jenkins) string {
|
|||
return defaultJenkinsHomePath
|
||||
}
|
||||
|
||||
func validateStorageSize(storageSize string) bool {
|
||||
if strings.TrimSpace(storageSize) == "" {
|
||||
return false
|
||||
}
|
||||
_, err := resource.ParseQuantity(storageSize)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 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{
|
||||
// Create empty dir for Jenkins home
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||
},
|
||||
}
|
||||
|
||||
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)
|
||||
JenkinsHomeVolume = emptyDirVol
|
||||
return JenkinsHomeVolume
|
||||
}
|
||||
JenkinsHomeVolume = corev1.Volume{
|
||||
Name: JenkinsHomeVolumeName,
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
// Create ephemeral storage for Jenkins home
|
||||
Ephemeral: &corev1.EphemeralVolumeSource{
|
||||
VolumeClaimTemplate: &corev1.PersistentVolumeClaimTemplate{
|
||||
Spec: corev1.PersistentVolumeClaimSpec{
|
||||
StorageClassName: &jenkins.Spec.Master.StorageSettings.StorageClassName,
|
||||
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce},
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
corev1.ResourceStorage: resource.MustParse(jenkins.Spec.Master.StorageSettings.StorageRequest),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
JenkinsHomeVolume = emptyDirVol
|
||||
}
|
||||
return JenkinsHomeVolume
|
||||
}
|
||||
|
||||
// GetJenkinsMasterPodBaseVolumes returns Jenkins master pod volumes required by operator
|
||||
func GetJenkinsMasterPodBaseVolumes(jenkins *v1alpha2.Jenkins) []corev1.Volume {
|
||||
configMapVolumeSourceDefaultMode := corev1.ConfigMapVolumeSourceDefaultMode
|
||||
secretVolumeSourceDefaultMode := corev1.SecretVolumeSourceDefaultMode
|
||||
var scriptsVolumeDefaultMode int32 = 0777
|
||||
volumes := []corev1.Volume{
|
||||
{
|
||||
Name: JenkinsHomeVolumeName,
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||
},
|
||||
},
|
||||
getJenkinsHomeStorageSettings(jenkins),
|
||||
{
|
||||
Name: jenkinsScriptsVolumeName,
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
@ -144,6 +143,42 @@ func TestGetJenkinsMasterPodBaseVolumes(t *testing.T) {
|
|||
assert.True(t, groovyExists)
|
||||
assert.True(t, cascExists)
|
||||
})
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
HomeExist, HomeTempdirExist, HomeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
|
||||
|
||||
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{
|
||||
Spec: v1alpha2.JenkinsSpec{
|
||||
Master: v1alpha2.JenkinsMaster{
|
||||
StorageSettings: v1alpha2.StorageSettings{
|
||||
UseEphemeralStorage: true,
|
||||
StorageClassName: "",
|
||||
StorageRequest: "1Gi",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
HomeExist, HomeTempdirExist, HomeEphemeralStorageExist := checkHomeVolumesPresence(jenkins)
|
||||
|
||||
assert.True(t, HomeExist)
|
||||
assert.False(t, HomeTempdirExist)
|
||||
assert.True(t, HomeEphemeralStorageExist)
|
||||
})
|
||||
}
|
||||
|
||||
func checkSecretVolumesPresence(jenkins *v1alpha2.Jenkins) (groovyExists bool, cascExists bool) {
|
||||
|
|
@ -156,3 +191,55 @@ func checkSecretVolumesPresence(jenkins *v1alpha2.Jenkins) (groovyExists bool, c
|
|||
}
|
||||
return groovyExists, cascExists
|
||||
}
|
||||
|
||||
func checkHomeVolumesPresence(jenkins *v1alpha2.Jenkins) (HomeExist bool, HomeTempdirExist bool, HomeEphemeralStorageExist bool) {
|
||||
for _, volume := range GetJenkinsMasterPodBaseVolumes(jenkins) {
|
||||
if volume.Name == ("jenkins-home") {
|
||||
HomeExist = true
|
||||
// check if the volume is an emptyDir
|
||||
if volume.VolumeSource.EmptyDir != nil {
|
||||
HomeTempdirExist = true
|
||||
} else if volume.VolumeSource.Ephemeral != nil {
|
||||
HomeEphemeralStorageExist = true
|
||||
}
|
||||
} else {
|
||||
HomeExist = false
|
||||
HomeTempdirExist = false
|
||||
HomeEphemeralStorageExist = false
|
||||
}
|
||||
}
|
||||
return HomeExist, HomeTempdirExist, HomeEphemeralStorageExist
|
||||
}
|
||||
|
||||
func Test_validateStorageSize(t *testing.T) {
|
||||
type args struct {
|
||||
storageSize string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "1Gi",
|
||||
args: args{
|
||||
storageSize: "1Gi",
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "1Gi1",
|
||||
args: args{
|
||||
storageSize: "1Gi1",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := validateStorageSize(tt.args.storageSize); got != tt.want {
|
||||
t.Errorf("validateStorageSize() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue