#76 Allow configure JAVA_OPTS variable in Jenkins container

This commit is contained in:
Tomasz Sęk 2019-08-23 13:43:18 +02:00
parent 89c46a1720
commit 3a1f9e1ccc
No known key found for this signature in database
GPG Key ID: DC356D23F6A644D0
5 changed files with 99 additions and 5 deletions

View File

@ -67,10 +67,6 @@ func GetJenkinsMasterContainerBaseEnvs(jenkins *v1alpha2.Jenkins) []corev1.EnvVa
Name: "JENKINS_HOME",
Value: jenkinsHomePath,
},
{
Name: "JAVA_OPTS",
Value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -Djenkins.install.runSetupWizard=false -Djava.awt.headless=true",
},
}
if len(jenkins.Spec.ConfigurationAsCode.Secret.Name) > 0 {

View File

@ -4,9 +4,11 @@ import (
"context"
"fmt"
"regexp"
"strings"
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins"
"github.com/jenkinsci/kubernetes-operator/pkg/log"
@ -254,14 +256,37 @@ func (r *ReconcileJenkinsBaseConfiguration) validateJenkinsMasterPodEnvs() bool
baseEnvNames[env.Name] = env.Value
}
javaOpts := corev1.EnvVar{}
valid := true
for _, userEnv := range r.jenkins.Spec.Master.Containers[0].Env {
if userEnv.Name == constants.JavaOpsVariableName {
javaOpts = userEnv
}
if _, overriding := baseEnvNames[userEnv.Name]; overriding {
r.logger.V(log.VWarn).Info(fmt.Sprintf("Jenkins Master pod env '%s' cannot be overridden", userEnv.Name))
r.logger.V(log.VWarn).Info(fmt.Sprintf("Jenkins Master container env '%s' cannot be overridden", userEnv.Name))
valid = false
}
}
requiredFlags := map[string]bool{
"-Djenkins.install.runSetupWizard=false": false,
"-Djava.awt.headless=true": false,
}
for _, setFlag := range strings.Split(javaOpts.Value, " ") {
for requiredFlag := range requiredFlags {
if setFlag == requiredFlag {
requiredFlags[requiredFlag] = true
break
}
}
}
for requiredFlag, set := range requiredFlags {
if !set {
valid = false
r.logger.V(log.VWarn).Info(fmt.Sprintf("Jenkins Master container env '%s' doesn't have required flag '%s'", constants.JavaOpsVariableName, requiredFlag))
}
}
return valid
}

View File

@ -6,6 +6,7 @@ import (
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins"
"github.com/jenkinsci/kubernetes-operator/pkg/log"
@ -322,6 +323,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T
}
func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
validJenkinsOps := "-Djenkins.install.runSetupWizard=false -Djava.awt.headless=true"
t.Run("happy", func(t *testing.T) {
jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{
@ -333,6 +335,10 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
Name: "SOME_VALUE",
Value: "",
},
{
Name: constants.JavaOpsVariableName,
Value: validJenkinsOps,
},
},
},
},
@ -355,6 +361,54 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
Name: "JENKINS_HOME",
Value: "",
},
{
Name: constants.JavaOpsVariableName,
Value: validJenkinsOps,
},
},
},
},
},
},
}
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false, nil, nil)
got := baseReconcileLoop.validateJenkinsMasterPodEnvs()
assert.Equal(t, false, got)
})
t.Run("missing -Djava.awt.headless=true in JAVA_OPTS env", func(t *testing.T) {
jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{
{
Env: []v1.EnvVar{
{
Name: constants.JavaOpsVariableName,
Value: "-Djenkins.install.runSetupWizard=false",
},
},
},
},
},
},
}
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false, nil, nil)
got := baseReconcileLoop.validateJenkinsMasterPodEnvs()
assert.Equal(t, false, got)
})
t.Run("missing -Djenkins.install.runSetupWizard=false in JAVA_OPTS env", func(t *testing.T) {
jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{
{
Env: []v1.EnvVar{
{
Name: constants.JavaOpsVariableName,
Value: "-Djava.awt.headless=true",
},
},
},
},

View File

@ -17,4 +17,6 @@ const (
DefaultHTTPPortInt32 = int32(8080)
// DefaultSlavePortInt32 is the default Jenkins port for slaves
DefaultSlavePortInt32 = int32(50000)
// JavaOpsVariableName is the name of environment variable which consists Jenkins Java options
JavaOpsVariableName = "JAVA_OPTS"
)

View File

@ -334,6 +334,14 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
changed = true
jenkinsContainer.Command = resources.GetJenkinsMasterContainerBaseCommand()
}
if isJavaOpsVariableNotSet(jenkinsContainer) {
logger.Info("Setting default Jenkins container JAVA_OPTS environment variable")
changed = true
jenkinsContainer.Env = append(jenkinsContainer.Env, corev1.EnvVar{
Name: constants.JavaOpsVariableName,
Value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -Djenkins.install.runSetupWizard=false -Djava.awt.headless=true",
})
}
if len(jenkins.Spec.Master.BasePlugins) == 0 {
logger.Info("Setting default operator plugins")
changed = true
@ -426,6 +434,15 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
return nil
}
func isJavaOpsVariableNotSet(container v1alpha2.Container) bool {
for _, env := range container.Env {
if env.Name == constants.JavaOpsVariableName {
return false
}
}
return true
}
func setDefaultsForContainer(jenkins *v1alpha2.Jenkins, containerIndex int, logger logr.Logger) bool {
changed := false