Set default Jenkins master pod resources requirements, this closes #4
This commit is contained in:
parent
ae31901022
commit
8c4fa92ec5
2
Makefile
2
Makefile
|
|
@ -142,7 +142,7 @@ test: ## Runs the go tests
|
||||||
|
|
||||||
.PHONY: e2e
|
.PHONY: e2e
|
||||||
CURRENT_DIRECTORY := $(shell pwd)
|
CURRENT_DIRECTORY := $(shell pwd)
|
||||||
e2e: ## Runs e2e tests
|
e2e: build docker-build ## Runs e2e tests
|
||||||
@echo "+ $@"
|
@echo "+ $@"
|
||||||
@echo "Docker image: $(REPO):$(GITCOMMIT)"
|
@echo "Docker image: $(REPO):$(GITCOMMIT)"
|
||||||
cp deploy/service_account.yaml deploy/namespace-init.yaml
|
cp deploy/service_account.yaml deploy/namespace-init.yaml
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,6 @@ Run e2e tests with minikube:
|
||||||
```bash
|
```bash
|
||||||
make start-minikube
|
make start-minikube
|
||||||
eval $(minikube docker-env)
|
eval $(minikube docker-env)
|
||||||
make build
|
|
||||||
make docker-build
|
|
||||||
make e2e
|
make e2e
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,8 @@ func (r *ReconcileJenkinsBaseConfiguration) createJenkinsMasterPod(meta metav1.O
|
||||||
|
|
||||||
if currentJenkinsMasterPod != nil &&
|
if currentJenkinsMasterPod != nil &&
|
||||||
!reflect.DeepEqual(r.jenkins.Spec.Master.Resources, currentJenkinsMasterPod.Spec.Containers[0].Resources) {
|
!reflect.DeepEqual(r.jenkins.Spec.Master.Resources, currentJenkinsMasterPod.Spec.Containers[0].Resources) {
|
||||||
r.logger.Info(fmt.Sprintf("Jenkins pod resources have changed to '%+v', recreating pod", r.jenkins.Spec.Master.Resources))
|
r.logger.Info(fmt.Sprintf("Jenkins pod resources have changed, actual '%+v' required '%+v' - recreating pod",
|
||||||
|
currentJenkinsMasterPod.Spec.Containers[0].Resources, r.jenkins.Spec.Master.Resources))
|
||||||
recreatePod = true
|
recreatePod = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
@ -116,7 +117,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg
|
||||||
return reconcile.Result{}, err
|
return reconcile.Result{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.setDefaults(jenkins)
|
err = r.setDefaults(jenkins, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return reconcile.Result{}, err
|
return reconcile.Result{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -180,9 +181,33 @@ func (r *ReconcileJenkins) buildLogger(jenkinsName string) logr.Logger {
|
||||||
return log.Log.WithValues("cr", jenkinsName)
|
return log.Log.WithValues("cr", jenkinsName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkins) setDefaults(jenkins *virtuslabv1alpha1.Jenkins) error {
|
func (r *ReconcileJenkins) setDefaults(jenkins *virtuslabv1alpha1.Jenkins, logger logr.Logger) error {
|
||||||
|
changed := false
|
||||||
if len(jenkins.Spec.Master.Plugins) == 0 {
|
if len(jenkins.Spec.Master.Plugins) == 0 {
|
||||||
|
logger.Info("Setting default base plugins in CR")
|
||||||
|
changed = true
|
||||||
jenkins.Spec.Master.Plugins = plugin.BasePlugins()
|
jenkins.Spec.Master.Plugins = plugin.BasePlugins()
|
||||||
|
}
|
||||||
|
_, requestCPUSet := jenkins.Spec.Master.Resources.Requests[corev1.ResourceCPU]
|
||||||
|
_, requestMemporySet := jenkins.Spec.Master.Resources.Requests[corev1.ResourceMemory]
|
||||||
|
_, limitCPUSet := jenkins.Spec.Master.Resources.Limits[corev1.ResourceCPU]
|
||||||
|
_, limitMemporySet := jenkins.Spec.Master.Resources.Limits[corev1.ResourceMemory]
|
||||||
|
if !limitCPUSet || !limitMemporySet || !requestCPUSet || !requestMemporySet {
|
||||||
|
logger.Info("Setting default Jenkins master pod resource requirements in CR")
|
||||||
|
changed = true
|
||||||
|
jenkins.Spec.Master.Resources = corev1.ResourceRequirements{
|
||||||
|
Requests: corev1.ResourceList{
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1"),
|
||||||
|
corev1.ResourceMemory: resource.MustParse("500Mi"),
|
||||||
|
},
|
||||||
|
Limits: corev1.ResourceList{
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1500m"),
|
||||||
|
corev1.ResourceMemory: resource.MustParse("3Gi"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if changed {
|
||||||
return r.client.Update(context.TODO(), jenkins)
|
return r.client.Update(context.TODO(), jenkins)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package e2e
|
package e2e
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
|
@ -8,6 +9,10 @@ import (
|
||||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugin"
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugin"
|
||||||
|
|
||||||
"github.com/bndr/gojenkins"
|
"github.com/bndr/gojenkins"
|
||||||
|
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBaseConfiguration(t *testing.T) {
|
func TestBaseConfiguration(t *testing.T) {
|
||||||
|
|
@ -17,6 +22,7 @@ func TestBaseConfiguration(t *testing.T) {
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
jenkins := createJenkinsCR(t, namespace)
|
jenkins := createJenkinsCR(t, namespace)
|
||||||
|
createDefaultLimitsForContainersInNamespace(t, namespace)
|
||||||
waitForJenkinsBaseConfigurationToComplete(t, jenkins)
|
waitForJenkinsBaseConfigurationToComplete(t, jenkins)
|
||||||
|
|
||||||
verifyJenkinsMasterPodAttributes(t, jenkins)
|
verifyJenkinsMasterPodAttributes(t, jenkins)
|
||||||
|
|
@ -24,8 +30,38 @@ func TestBaseConfiguration(t *testing.T) {
|
||||||
verifyBasePlugins(t, jenkinsClient)
|
verifyBasePlugins(t, jenkinsClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createDefaultLimitsForContainersInNamespace(t *testing.T, namespace string) {
|
||||||
|
limitRange := &corev1.LimitRange{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "e2e",
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: corev1.LimitRangeSpec{
|
||||||
|
Limits: []corev1.LimitRangeItem{
|
||||||
|
{
|
||||||
|
Type: corev1.LimitTypeContainer,
|
||||||
|
DefaultRequest: map[corev1.ResourceName]resource.Quantity{
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1"),
|
||||||
|
corev1.ResourceMemory: resource.MustParse("1Gi"),
|
||||||
|
},
|
||||||
|
Default: map[corev1.ResourceName]resource.Quantity{
|
||||||
|
corev1.ResourceCPU: resource.MustParse("4"),
|
||||||
|
corev1.ResourceMemory: resource.MustParse("4Gi"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("LimitRange %+v", *limitRange)
|
||||||
|
if err := framework.Global.Client.Create(context.TODO(), limitRange, nil); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func verifyJenkinsMasterPodAttributes(t *testing.T, jenkins *virtuslabv1alpha1.Jenkins) {
|
func verifyJenkinsMasterPodAttributes(t *testing.T, jenkins *virtuslabv1alpha1.Jenkins) {
|
||||||
jenkinsPod := getJenkinsMasterPod(t, jenkins)
|
jenkinsPod := getJenkinsMasterPod(t, jenkins)
|
||||||
|
jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name)
|
||||||
|
|
||||||
for key, value := range jenkins.Spec.Master.Annotations {
|
for key, value := range jenkins.Spec.Master.Annotations {
|
||||||
if jenkinsPod.ObjectMeta.Annotations[key] != value {
|
if jenkinsPod.ObjectMeta.Annotations[key] != value {
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,21 @@ import (
|
||||||
"github.com/bndr/gojenkins"
|
"github.com/bndr/gojenkins"
|
||||||
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getJenkins(t *testing.T, namespace, name string) *virtuslabv1alpha1.Jenkins {
|
||||||
|
jenkins := &virtuslabv1alpha1.Jenkins{}
|
||||||
|
namespaceName := types.NamespacedName{Namespace: namespace, Name: name}
|
||||||
|
if err := framework.Global.Client.Get(context.TODO(), namespaceName, jenkins); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return jenkins
|
||||||
|
}
|
||||||
|
|
||||||
func getJenkinsMasterPod(t *testing.T, jenkins *virtuslabv1alpha1.Jenkins) *v1.Pod {
|
func getJenkinsMasterPod(t *testing.T, jenkins *virtuslabv1alpha1.Jenkins) *v1.Pod {
|
||||||
lo := metav1.ListOptions{
|
lo := metav1.ListOptions{
|
||||||
LabelSelector: labels.SelectorFromSet(resources.BuildResourceLabels(jenkins)).String(),
|
LabelSelector: labels.SelectorFromSet(resources.BuildResourceLabels(jenkins)).String(),
|
||||||
|
|
@ -77,16 +85,6 @@ func createJenkinsCR(t *testing.T, namespace string) *virtuslabv1alpha1.Jenkins
|
||||||
Master: virtuslabv1alpha1.JenkinsMaster{
|
Master: virtuslabv1alpha1.JenkinsMaster{
|
||||||
Image: "jenkins/jenkins",
|
Image: "jenkins/jenkins",
|
||||||
Annotations: map[string]string{"test": "label"},
|
Annotations: map[string]string{"test": "label"},
|
||||||
Resources: corev1.ResourceRequirements{
|
|
||||||
Requests: corev1.ResourceList{
|
|
||||||
corev1.ResourceCPU: resource.MustParse("300m"),
|
|
||||||
corev1.ResourceMemory: resource.MustParse("500Mi"),
|
|
||||||
},
|
|
||||||
Limits: corev1.ResourceList{
|
|
||||||
corev1.ResourceCPU: resource.MustParse("2"),
|
|
||||||
corev1.ResourceMemory: resource.MustParse("2Gi"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -109,16 +107,6 @@ func createJenkinsCRWithSeedJob(t *testing.T, namespace string) *virtuslabv1alph
|
||||||
Master: virtuslabv1alpha1.JenkinsMaster{
|
Master: virtuslabv1alpha1.JenkinsMaster{
|
||||||
Image: "jenkins/jenkins",
|
Image: "jenkins/jenkins",
|
||||||
Annotations: map[string]string{"test": "label"},
|
Annotations: map[string]string{"test": "label"},
|
||||||
Resources: corev1.ResourceRequirements{
|
|
||||||
Requests: corev1.ResourceList{
|
|
||||||
corev1.ResourceCPU: resource.MustParse("300m"),
|
|
||||||
corev1.ResourceMemory: resource.MustParse("500Mi"),
|
|
||||||
},
|
|
||||||
Limits: corev1.ResourceList{
|
|
||||||
corev1.ResourceCPU: resource.MustParse("2"),
|
|
||||||
corev1.ResourceMemory: resource.MustParse("2Gi"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
//TODO(bantoniak) add seed job with private key
|
//TODO(bantoniak) add seed job with private key
|
||||||
SeedJobs: []virtuslabv1alpha1.SeedJob{
|
SeedJobs: []virtuslabv1alpha1.SeedJob{
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/VirtusLab/jenkins-operator/pkg/apis"
|
"github.com/VirtusLab/jenkins-operator/pkg/apis"
|
||||||
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants"
|
||||||
|
|
||||||
f "github.com/operator-framework/operator-sdk/pkg/test"
|
f "github.com/operator-framework/operator-sdk/pkg/test"
|
||||||
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
||||||
|
|
@ -13,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
jenkinsOperatorDeploymentName = "jenkins-operator"
|
jenkinsOperatorDeploymentName = constants.OperatorName
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,6 @@ func checkBaseConfigurationCompleteTimeIsNotSet(t *testing.T, jenkins *virtuslab
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if jenkinsStatus.Status.BaseConfigurationCompletedTime != nil {
|
if jenkinsStatus.Status.BaseConfigurationCompletedTime != nil {
|
||||||
t.Fatalf("Status.BaseConfigurationCompletedTime is set after restart of pod, status %+v", jenkinsStatus.Status)
|
t.Fatalf("Status.BaseConfigurationCompletedTime is set after pod restart, status %+v", jenkinsStatus.Status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ func verifyJenkinsSeedJobs(t *testing.T, client *gojenkins.Jenkins, jenkins *vir
|
||||||
seedJobName := "jenkins-operator-configure-seed-job"
|
seedJobName := "jenkins-operator-configure-seed-job"
|
||||||
t.Logf("Attempting to verify if seed job has been created '%v'", seedJobName)
|
t.Logf("Attempting to verify if seed job has been created '%v'", seedJobName)
|
||||||
seedJob, err := client.GetJob(seedJobName)
|
seedJob, err := client.GetJob(seedJobName)
|
||||||
assert.NoError(t, err, )
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, seedJob)
|
assert.NotNil(t, seedJob)
|
||||||
|
|
||||||
build, err = seedJob.GetLastSuccessfulBuild()
|
build, err = seedJob.GetLastSuccessfulBuild()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue