diff --git a/Makefile b/Makefile index 193e0454..0ccd99d4 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ test: ## Runs the go tests .PHONY: e2e CURRENT_DIRECTORY := $(shell pwd) -e2e: ## Runs e2e tests +e2e: build docker-build ## Runs e2e tests @echo "+ $@" @echo "Docker image: $(REPO):$(GITCOMMIT)" cp deploy/service_account.yaml deploy/namespace-init.yaml diff --git a/docs/developer-guide.md b/docs/developer-guide.md index ca7d78a8..2b02ece9 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -50,8 +50,6 @@ Run e2e tests with minikube: ```bash make start-minikube eval $(minikube docker-env) -make build -make docker-build make e2e ``` diff --git a/pkg/controller/jenkins/configuration/base/reconcile.go b/pkg/controller/jenkins/configuration/base/reconcile.go index 8c5b47b6..925adbc2 100644 --- a/pkg/controller/jenkins/configuration/base/reconcile.go +++ b/pkg/controller/jenkins/configuration/base/reconcile.go @@ -315,7 +315,8 @@ func (r *ReconcileJenkinsBaseConfiguration) createJenkinsMasterPod(meta metav1.O if currentJenkinsMasterPod != nil && !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 } diff --git a/pkg/controller/jenkins/jenkins_controller.go b/pkg/controller/jenkins/jenkins_controller.go index 1189eda2..120f52ed 100644 --- a/pkg/controller/jenkins/jenkins_controller.go +++ b/pkg/controller/jenkins/jenkins_controller.go @@ -13,6 +13,7 @@ import ( "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "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 } - err = r.setDefaults(jenkins) + err = r.setDefaults(jenkins, logger) if err != nil { return reconcile.Result{}, err } @@ -180,9 +181,33 @@ func (r *ReconcileJenkins) buildLogger(jenkinsName string) logr.Logger { 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 { + logger.Info("Setting default base plugins in CR") + changed = true 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 nil diff --git a/test/e2e/base_configuration_test.go b/test/e2e/base_configuration_test.go index 4b629a70..60a30b2e 100644 --- a/test/e2e/base_configuration_test.go +++ b/test/e2e/base_configuration_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "reflect" "testing" @@ -8,6 +9,10 @@ import ( "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugin" "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) { @@ -17,6 +22,7 @@ func TestBaseConfiguration(t *testing.T) { defer ctx.Cleanup() jenkins := createJenkinsCR(t, namespace) + createDefaultLimitsForContainersInNamespace(t, namespace) waitForJenkinsBaseConfigurationToComplete(t, jenkins) verifyJenkinsMasterPodAttributes(t, jenkins) @@ -24,8 +30,38 @@ func TestBaseConfiguration(t *testing.T) { 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) { jenkinsPod := getJenkinsMasterPod(t, jenkins) + jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name) for key, value := range jenkins.Spec.Master.Annotations { if jenkinsPod.ObjectMeta.Annotations[key] != value { diff --git a/test/e2e/jenkins.go b/test/e2e/jenkins.go index 049fb531..4baf3c53 100644 --- a/test/e2e/jenkins.go +++ b/test/e2e/jenkins.go @@ -13,13 +13,21 @@ import ( "github.com/bndr/gojenkins" framework "github.com/operator-framework/operator-sdk/pkg/test" "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" "k8s.io/apimachinery/pkg/labels" "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 { lo := metav1.ListOptions{ LabelSelector: labels.SelectorFromSet(resources.BuildResourceLabels(jenkins)).String(), @@ -77,16 +85,6 @@ func createJenkinsCR(t *testing.T, namespace string) *virtuslabv1alpha1.Jenkins Master: virtuslabv1alpha1.JenkinsMaster{ Image: "jenkins/jenkins", 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{ Image: "jenkins/jenkins", 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 SeedJobs: []virtuslabv1alpha1.SeedJob{ diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 70e44754..7a194634 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -5,6 +5,7 @@ import ( "github.com/VirtusLab/jenkins-operator/pkg/apis" 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" framework "github.com/operator-framework/operator-sdk/pkg/test" @@ -13,7 +14,7 @@ import ( ) const ( - jenkinsOperatorDeploymentName = "jenkins-operator" + jenkinsOperatorDeploymentName = constants.OperatorName ) func TestMain(m *testing.M) { diff --git a/test/e2e/restart_pod_test.go b/test/e2e/restart_pod_test.go index 268be2a0..41c043c4 100644 --- a/test/e2e/restart_pod_test.go +++ b/test/e2e/restart_pod_test.go @@ -32,6 +32,6 @@ func checkBaseConfigurationCompleteTimeIsNotSet(t *testing.T, jenkins *virtuslab t.Fatal(err) } 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) } } diff --git a/test/e2e/user_configuration_test.go b/test/e2e/user_configuration_test.go index 6a954847..95207e91 100644 --- a/test/e2e/user_configuration_test.go +++ b/test/e2e/user_configuration_test.go @@ -44,7 +44,7 @@ func verifyJenkinsSeedJobs(t *testing.T, client *gojenkins.Jenkins, jenkins *vir seedJobName := "jenkins-operator-configure-seed-job" t.Logf("Attempting to verify if seed job has been created '%v'", seedJobName) seedJob, err := client.GetJob(seedJobName) - assert.NoError(t, err, ) + assert.NoError(t, err) assert.NotNil(t, seedJob) build, err = seedJob.GetLastSuccessfulBuild()