#76 Allow configure JAVA_OPTS variable in Jenkins container
This commit is contained in:
		
							parent
							
								
									89c46a1720
								
							
						
					
					
						commit
						3a1f9e1ccc
					
				|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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", | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  |  | |||
|  | @ -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" | ||||
| ) | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue