Move Jenkins container properties to spec.master.containers list

This commit is contained in:
Tomasz Sęk 2019-06-11 19:53:02 +02:00
parent e1aba3ed9f
commit 25469b1174
No known key found for this signature in database
GPG Key ID: DC356D23F6A644D0
11 changed files with 177 additions and 135 deletions

View File

@ -4,26 +4,37 @@ metadata:
name: example name: example
spec: spec:
master: master:
readinessProbe: containers:
- name: jenkins-master
image: jenkins/jenkins:lts
imagePullPolicy: Always
livenessProbe:
failureThreshold: 12
httpGet: httpGet:
path: /login path: /login
port: 8080 port: http
scheme: HTTP
initialDelaySeconds: 80
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
failureThreshold: 3
httpGet:
path: /login
port: http
scheme: HTTP scheme: HTTP
failureThreshold: 10
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
successThreshold: 1 successThreshold: 1
timeoutSeconds: 5 timeoutSeconds: 1
livenessProbe: resources:
httpGet: limits:
path: /login cpu: 1500m
port: 8080 memory: 3Gi
scheme: HTTP requests:
initialDelaySeconds: 35 cpu: "1"
failureThreshold: 10 memory: 600Mi
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
seedJobs: seedJobs:
- id: jenkins-operator - id: jenkins-operator
targets: "cicd/jobs/*.jenkins" targets: "cicd/jobs/*.jenkins"

View File

@ -47,8 +47,6 @@ type Plugin struct {
// JenkinsMaster defines the Jenkins master pod attributes and plugins, // JenkinsMaster defines the Jenkins master pod attributes and plugins,
// every single change requires Jenkins master pod restart // every single change requires Jenkins master pod restart
type JenkinsMaster struct { type JenkinsMaster struct {
Container //TODO move to containers
// pod properties // pod properties
Annotations map[string]string `json:"masterAnnotations,omitempty"` Annotations map[string]string `json:"masterAnnotations,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty"` NodeSelector map[string]string `json:"nodeSelector,omitempty"`

View File

@ -170,8 +170,8 @@ func (in *JenkinsList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) { func (in *JenkinsMaster) DeepCopyInto(out *JenkinsMaster) {
*out = *in *out = *in
if in.NodeSelector != nil { if in.Annotations != nil {
in, out := &in.NodeSelector, &out.NodeSelector in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in)) *out = make(map[string]string, len(*in))
for key, val := range *in { for key, val := range *in {
(*out)[key] = val (*out)[key] = val

View File

@ -438,8 +438,8 @@ func (r *ReconcileJenkinsBaseConfiguration) isRecreatePodNeeded(currentJenkinsMa
return true return true
} }
if (len(r.jenkins.Spec.Master.Containers) + 1) != len(currentJenkinsMasterPod.Spec.Containers) { if len(r.jenkins.Spec.Master.Containers) != len(currentJenkinsMasterPod.Spec.Containers) {
r.logger.Info(fmt.Sprintf("Jenkins amount of containers has changed to '%+v', recreating pod", len(r.jenkins.Spec.Master.Containers)+1)) r.logger.Info(fmt.Sprintf("Jenkins amount of containers has changed to '%+v', recreating pod", len(r.jenkins.Spec.Master.Containers)))
return true return true
} }

View File

@ -194,19 +194,20 @@ func GetJenkinsMasterContainerBaseVolumeMounts() []corev1.VolumeMount {
// NewJenkinsMasterContainer returns Jenkins master Kubernetes container // NewJenkinsMasterContainer returns Jenkins master Kubernetes container
func NewJenkinsMasterContainer(jenkins *v1alpha2.Jenkins) corev1.Container { func NewJenkinsMasterContainer(jenkins *v1alpha2.Jenkins) corev1.Container {
jenkinsContainer := jenkins.Spec.Master.Containers[0]
envs := GetJenkinsMasterPodBaseEnvs() envs := GetJenkinsMasterPodBaseEnvs()
envs = append(envs, jenkins.Spec.Master.Env...) envs = append(envs, jenkinsContainer.Env...)
return corev1.Container{ return corev1.Container{
Name: JenkinsMasterContainerName, Name: JenkinsMasterContainerName,
Image: jenkins.Spec.Master.Image, Image: jenkinsContainer.Image,
ImagePullPolicy: jenkins.Spec.Master.ImagePullPolicy, ImagePullPolicy: jenkinsContainer.ImagePullPolicy,
Command: []string{ Command: []string{
"bash", "bash",
fmt.Sprintf("%s/%s", jenkinsScriptsVolumePath, initScriptName), fmt.Sprintf("%s/%s", jenkinsScriptsVolumePath, initScriptName),
}, },
LivenessProbe: jenkins.Spec.Master.LivenessProbe, LivenessProbe: jenkinsContainer.LivenessProbe,
ReadinessProbe: jenkins.Spec.Master.ReadinessProbe, ReadinessProbe: jenkinsContainer.ReadinessProbe,
Ports: []corev1.ContainerPort{ Ports: []corev1.ContainerPort{
{ {
Name: httpPortName, Name: httpPortName,
@ -220,8 +221,8 @@ func NewJenkinsMasterContainer(jenkins *v1alpha2.Jenkins) corev1.Container {
}, },
}, },
Env: envs, Env: envs,
Resources: jenkins.Spec.Master.Resources, Resources: jenkinsContainer.Resources,
VolumeMounts: append(GetJenkinsMasterContainerBaseVolumeMounts(), jenkins.Spec.Master.VolumeMounts...), VolumeMounts: append(GetJenkinsMasterContainerBaseVolumeMounts(), jenkinsContainer.VolumeMounts...),
} }
} }
@ -249,7 +250,7 @@ func ConvertJenkinsContainerToKubernetesContainer(container v1alpha2.Container)
func newContainers(jenkins *v1alpha2.Jenkins) (containers []corev1.Container) { func newContainers(jenkins *v1alpha2.Jenkins) (containers []corev1.Container) {
containers = append(containers, NewJenkinsMasterContainer(jenkins)) containers = append(containers, NewJenkinsMasterContainer(jenkins))
for _, container := range jenkins.Spec.Master.Containers { for _, container := range jenkins.Spec.Master.Containers[1:] {
containers = append(containers, ConvertJenkinsContainerToKubernetesContainer(container)) containers = append(containers, ConvertJenkinsContainerToKubernetesContainer(container))
} }

View File

@ -32,10 +32,6 @@ func (r *ReconcileJenkinsBaseConfiguration) Validate(jenkins *v1alpha2.Jenkins)
return false, nil return false, nil
} }
if !r.validateContainer(jenkins.Spec.Master.Container) {
return false, nil
}
for _, container := range jenkins.Spec.Master.Containers { for _, container := range jenkins.Spec.Master.Containers {
if !r.validateContainer(container) { if !r.validateContainer(container) {
return false, nil return false, nil
@ -205,7 +201,7 @@ func (r *ReconcileJenkinsBaseConfiguration) validateJenkinsMasterPodEnvs() bool
} }
valid := true valid := true
for _, userEnv := range r.jenkins.Spec.Master.Env { for _, userEnv := range r.jenkins.Spec.Master.Containers[0].Env {
if _, overriding := baseEnvNames[userEnv.Name]; overriding { 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 pod env '%s' cannot be overridden", userEnv.Name))
valid = false valid = false

View File

@ -136,7 +136,8 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
jenkins := v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
Env: []v1.EnvVar{ Env: []v1.EnvVar{
{ {
Name: "SOME_VALUE", Name: "SOME_VALUE",
@ -146,6 +147,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
}, },
}, },
}, },
},
} }
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false) &jenkins, false, false)
@ -156,7 +158,8 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
jenkins := v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
Env: []v1.EnvVar{ Env: []v1.EnvVar{
{ {
Name: "JENKINS_HOME", Name: "JENKINS_HOME",
@ -166,6 +169,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) {
}, },
}, },
}, },
},
} }
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false) &jenkins, false, false)
@ -220,7 +224,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
} }
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false) &jenkins, false, false)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Container) got := baseReconcileLoop.validateContainerVolumeMounts(v1alpha2.Container{})
assert.Equal(t, true, got) assert.Equal(t, true, got)
}) })
t.Run("one extra volume", func(t *testing.T) { t.Run("one extra volume", func(t *testing.T) {
@ -232,7 +236,8 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
Name: "example", Name: "example",
}, },
}, },
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
VolumeMounts: []v1.VolumeMount{ VolumeMounts: []v1.VolumeMount{
{ {
Name: "example", Name: "example",
@ -242,10 +247,11 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}, },
}, },
}, },
},
} }
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false) &jenkins, false, false)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Container) got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0])
assert.Equal(t, true, got) assert.Equal(t, true, got)
}) })
t.Run("empty mountPath", func(t *testing.T) { t.Run("empty mountPath", func(t *testing.T) {
@ -257,7 +263,8 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
Name: "example", Name: "example",
}, },
}, },
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
VolumeMounts: []v1.VolumeMount{ VolumeMounts: []v1.VolumeMount{
{ {
Name: "example", Name: "example",
@ -267,17 +274,19 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}, },
}, },
}, },
},
} }
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false) &jenkins, false, false)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Container) got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0])
assert.Equal(t, false, got) assert.Equal(t, false, got)
}) })
t.Run("missing volume", func(t *testing.T) { t.Run("missing volume", func(t *testing.T) {
jenkins := v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
VolumeMounts: []v1.VolumeMount{ VolumeMounts: []v1.VolumeMount{
{ {
Name: "missing-volume", Name: "missing-volume",
@ -287,10 +296,11 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
}, },
}, },
}, },
},
} }
baseReconcileLoop := New(nil, nil, logf.ZapLogger(false), baseReconcileLoop := New(nil, nil, logf.ZapLogger(false),
&jenkins, false, false) &jenkins, false, false)
got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Container) got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0])
assert.Equal(t, false, got) assert.Equal(t, false, got)
}) })
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" "github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
"github.com/bndr/gojenkins" "github.com/bndr/gojenkins"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
@ -120,7 +121,9 @@ func jenkinsCustomResource() *v1alpha2.Jenkins {
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Annotations: map[string]string{"test": "label"}, Annotations: map[string]string{"test": "label"},
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
Name: resources.JenkinsMasterContainerName,
Image: "jenkins/jenkins", Image: "jenkins/jenkins",
Resources: corev1.ResourceRequirements{ Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{ Requests: corev1.ResourceList{
@ -134,6 +137,7 @@ func jenkinsCustomResource() *v1alpha2.Jenkins {
}, },
}, },
}, },
},
SeedJobs: []v1alpha2.SeedJob{ SeedJobs: []v1alpha2.SeedJob{
{ {
ID: "jenkins-operator-e2e", ID: "jenkins-operator-e2e",

View File

@ -7,6 +7,7 @@ import (
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" "github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/user" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/user"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/plugins"
@ -221,21 +222,33 @@ func (r *ReconcileJenkins) buildLogger(jenkinsName string) logr.Logger {
func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Logger) error { func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Logger) error {
changed := false changed := false
if len(jenkins.Spec.Master.Image) == 0 {
var jenkinsContainer v1alpha2.Container
if len(jenkins.Spec.Master.Containers) == 0 {
changed = true
jenkinsContainer = v1alpha2.Container{Name: resources.JenkinsMasterContainerName}
} else {
if jenkins.Spec.Master.Containers[0].Name != resources.JenkinsMasterContainerName {
return errors.Errorf("first container in spec.master.containers must be Jenkins container with name '%s', please correct CR", resources.JenkinsMasterContainerName)
}
jenkinsContainer = jenkins.Spec.Master.Containers[0]
}
if len(jenkinsContainer.Image) == 0 {
logger.Info("Setting default Jenkins master image: " + constants.DefaultJenkinsMasterImage) logger.Info("Setting default Jenkins master image: " + constants.DefaultJenkinsMasterImage)
changed = true changed = true
jenkins.Spec.Master.Image = constants.DefaultJenkinsMasterImage jenkinsContainer.Image = constants.DefaultJenkinsMasterImage
jenkins.Spec.Master.ImagePullPolicy = corev1.PullAlways jenkinsContainer.ImagePullPolicy = corev1.PullAlways
} }
if len(jenkins.Spec.Master.ImagePullPolicy) == 0 { if len(jenkinsContainer.ImagePullPolicy) == 0 {
logger.Info(fmt.Sprintf("Setting default Jenkins master image pull policy: %s", corev1.PullAlways)) logger.Info(fmt.Sprintf("Setting default Jenkins master image pull policy: %s", corev1.PullAlways))
changed = true changed = true
jenkins.Spec.Master.ImagePullPolicy = corev1.PullAlways jenkinsContainer.ImagePullPolicy = corev1.PullAlways
} }
if jenkins.Spec.Master.ReadinessProbe == nil { if jenkinsContainer.ReadinessProbe == nil {
logger.Info("Setting default Jenkins readinessProbe") logger.Info("Setting default Jenkins readinessProbe")
changed = true changed = true
jenkins.Spec.Master.ReadinessProbe = &corev1.Probe{ jenkinsContainer.ReadinessProbe = &corev1.Probe{
Handler: corev1.Handler{ Handler: corev1.Handler{
HTTPGet: &corev1.HTTPGetAction{ HTTPGet: &corev1.HTTPGetAction{
Path: "/login", Path: "/login",
@ -246,10 +259,10 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
InitialDelaySeconds: int32(30), InitialDelaySeconds: int32(30),
} }
} }
if jenkins.Spec.Master.LivenessProbe == nil { if jenkinsContainer.LivenessProbe == nil {
logger.Info("Setting default Jenkins livenessProbe") logger.Info("Setting default Jenkins livenessProbe")
changed = true changed = true
jenkins.Spec.Master.LivenessProbe = &corev1.Probe{ jenkinsContainer.LivenessProbe = &corev1.Probe{
Handler: corev1.Handler{ Handler: corev1.Handler{
HTTPGet: &corev1.HTTPGetAction{ HTTPGet: &corev1.HTTPGetAction{
Path: "/login", Path: "/login",
@ -281,10 +294,10 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
changed = true changed = true
jenkins.Spec.Master.Plugins = []v1alpha2.Plugin{{Name: "simple-theme-plugin", Version: "0.5.1"}} jenkins.Spec.Master.Plugins = []v1alpha2.Plugin{{Name: "simple-theme-plugin", Version: "0.5.1"}}
} }
if isResourceRequirementsNotSet(jenkins.Spec.Master.Resources) { if isResourceRequirementsNotSet(jenkinsContainer.Resources) {
logger.Info("Setting default Jenkins master container resource requirements") logger.Info("Setting default Jenkins master container resource requirements")
changed = true changed = true
jenkins.Spec.Master.Resources = corev1.ResourceRequirements{ jenkinsContainer.Resources = corev1.ResourceRequirements{
Requests: corev1.ResourceList{ Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1"), corev1.ResourceCPU: resource.MustParse("1"),
corev1.ResourceMemory: resource.MustParse("500Mi"), corev1.ResourceMemory: resource.MustParse("500Mi"),
@ -319,11 +332,15 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo
Port: constants.DefaultSlavePortInt32, Port: constants.DefaultSlavePortInt32,
} }
} }
for i, container := range jenkins.Spec.Master.Containers { if len(jenkins.Spec.Master.Containers) > 1 {
for i, container := range jenkins.Spec.Master.Containers[1:] {
if setDefaultsForContainer(jenkins, i, logger.WithValues("container", container.Name)) { if setDefaultsForContainer(jenkins, i, logger.WithValues("container", container.Name)) {
changed = true changed = true
} }
} }
}
jenkins.Spec.Master.Containers = []v1alpha2.Container{jenkinsContainer}
if changed { if changed {
return errors.WithStack(r.client.Update(context.TODO(), jenkins)) return errors.WithStack(r.client.Update(context.TODO(), jenkins))

View File

@ -9,6 +9,7 @@ import (
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" "github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
"github.com/bndr/gojenkins" "github.com/bndr/gojenkins"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
@ -388,7 +389,9 @@ func jenkinsCustomResource() *v1alpha2.Jenkins {
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Annotations: map[string]string{"test": "label"}, Annotations: map[string]string{"test": "label"},
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
Name: resources.JenkinsMasterContainerName,
Image: "jenkins/jenkins", Image: "jenkins/jenkins",
Resources: corev1.ResourceRequirements{ Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{ Requests: corev1.ResourceList{
@ -402,6 +405,7 @@ func jenkinsCustomResource() *v1alpha2.Jenkins {
}, },
}, },
}, },
},
SeedJobs: []v1alpha2.SeedJob{ SeedJobs: []v1alpha2.SeedJob{
{ {
ID: "jenkins-operator-e2e", ID: "jenkins-operator-e2e",

View File

@ -74,7 +74,9 @@ func createJenkinsCR(t *testing.T, name, namespace string, seedJob *[]v1alpha2.S
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Annotations: map[string]string{"test": "label"}, Annotations: map[string]string{"test": "label"},
Container: v1alpha2.Container{ Containers: []v1alpha2.Container{
{
Name: resources.JenkinsMasterContainerName,
Image: "jenkins/jenkins", Image: "jenkins/jenkins",
Env: []v1.EnvVar{ Env: []v1.EnvVar{
{ {
@ -107,7 +109,6 @@ func createJenkinsCR(t *testing.T, name, namespace string, seedJob *[]v1alpha2.S
FailureThreshold: int32(10), FailureThreshold: int32(10),
}, },
}, },
Containers: []v1alpha2.Container{
{ {
Name: "envoyproxy", Name: "envoyproxy",
Image: "envoyproxy/envoy-alpine", Image: "envoyproxy/envoy-alpine",