From ceb68c8e63bfb241db29ab1dfe8a5eb7c17f6438 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Sun, 11 Nov 2018 19:06:44 +0000 Subject: [PATCH 1/2] Enable resources to be defined at top level and overridden at component level Signed-off-by: Gary Brown --- pkg/apis/io/v1alpha1/types.go | 7 +++-- pkg/deployment/agent.go | 1 + pkg/deployment/agent_test.go | 37 ++++++++++++++++++++++ pkg/deployment/all-in-one.go | 1 + pkg/deployment/all-in-one_test.go | 35 +++++++++++++++++++++ pkg/deployment/collector.go | 1 + pkg/deployment/collector_test.go | 35 +++++++++++++++++++++ pkg/deployment/query.go | 1 + pkg/deployment/query_test.go | 35 +++++++++++++++++++++ pkg/util/util.go | 26 ++++++++++++++++ pkg/util/util_test.go | 51 +++++++++++++++++++++++++++++++ 11 files changed, 227 insertions(+), 3 deletions(-) diff --git a/pkg/apis/io/v1alpha1/types.go b/pkg/apis/io/v1alpha1/types.go index 9ae69f34f..bfb577f92 100644 --- a/pkg/apis/io/v1alpha1/types.go +++ b/pkg/apis/io/v1alpha1/types.go @@ -58,9 +58,10 @@ type JaegerSpec struct { // JaegerCommonSpec defines the common elements used in multiple other spec structs type JaegerCommonSpec struct { - Volumes []v1.Volume `json:"volumes"` - VolumeMounts []v1.VolumeMount `json:"volumeMounts"` - Annotations map[string]string `json:"annotations,omitempty"` + Volumes []v1.Volume `json:"volumes"` + VolumeMounts []v1.VolumeMount `json:"volumeMounts"` + Annotations map[string]string `json:"annotations,omitempty"` + Resources v1.ResourceRequirements `json:"resources,omitempty"` } // JaegerStatus defines what is to be returned from a status query diff --git a/pkg/deployment/agent.go b/pkg/deployment/agent.go index 43fb2a8e8..cab09d814 100644 --- a/pkg/deployment/agent.go +++ b/pkg/deployment/agent.go @@ -120,6 +120,7 @@ func (a *Agent) Get() *appsv1.DaemonSet { }, InitialDelaySeconds: 1, }, + Resources: commonSpec.Resources, }}, }, }, diff --git a/pkg/deployment/agent_test.go b/pkg/deployment/agent_test.go index 359df8994..b7f2b9eaf 100644 --- a/pkg/deployment/agent_test.go +++ b/pkg/deployment/agent_test.go @@ -5,6 +5,8 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/assert" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" "github.com/jaegertracing/jaeger-operator/pkg/apis/io/v1alpha1" ) @@ -81,3 +83,38 @@ func TestDaemonSetAgentAnnotations(t *testing.T) { assert.Equal(t, "world", dep.Spec.Template.Annotations["hello"]) assert.Equal(t, "false", dep.Spec.Template.Annotations["prometheus.io/scrape"]) } + +func TestDaemonSetAgentResources(t *testing.T) { + jaeger := v1alpha1.NewJaeger("TestDaemonSetAgentResources") + jaeger.Spec.Agent.Strategy = "daemonset" + jaeger.Spec.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceLimitsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceRequestsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + } + jaeger.Spec.Agent.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceLimitsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceRequestsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + } + + agent := NewAgent(jaeger) + dep := agent.Get() + + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsCPU]) + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsCPU]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsMemory]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsMemory]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsEphemeralStorage]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsEphemeralStorage]) +} diff --git a/pkg/deployment/all-in-one.go b/pkg/deployment/all-in-one.go index 04f260932..fe2ab5412 100644 --- a/pkg/deployment/all-in-one.go +++ b/pkg/deployment/all-in-one.go @@ -136,6 +136,7 @@ func (a *AllInOne) Get() *appsv1.Deployment { }, InitialDelaySeconds: 1, }, + Resources: commonSpec.Resources, }}, Volumes: commonSpec.Volumes, }, diff --git a/pkg/deployment/all-in-one_test.go b/pkg/deployment/all-in-one_test.go index b757bc6b3..abd70b22e 100644 --- a/pkg/deployment/all-in-one_test.go +++ b/pkg/deployment/all-in-one_test.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" "github.com/jaegertracing/jaeger-operator/pkg/apis/io/v1alpha1" ) @@ -201,3 +202,37 @@ func TestAllInOneVolumeWithSameName(t *testing.T) { // allInOne volume is mounted assert.Equal(t, podSpec.Volumes[0].VolumeSource.HostPath.Path, "/data2") } + +func TestAllInOneResources(t *testing.T) { + jaeger := v1alpha1.NewJaeger("TestAllInOneResources") + jaeger.Spec.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceLimitsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceRequestsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + } + jaeger.Spec.AllInOne.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceLimitsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceRequestsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + } + + allinone := NewAllInOne(jaeger) + dep := allinone.Get() + + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsCPU]) + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsCPU]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsMemory]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsMemory]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsEphemeralStorage]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsEphemeralStorage]) +} diff --git a/pkg/deployment/collector.go b/pkg/deployment/collector.go index fd87538de..3d83cd4a5 100644 --- a/pkg/deployment/collector.go +++ b/pkg/deployment/collector.go @@ -120,6 +120,7 @@ func (c *Collector) Get() *appsv1.Deployment { }, InitialDelaySeconds: 1, }, + Resources: commonSpec.Resources, }}, Volumes: commonSpec.Volumes, }, diff --git a/pkg/deployment/collector_test.go b/pkg/deployment/collector_test.go index 954e51008..809cdf638 100644 --- a/pkg/deployment/collector_test.go +++ b/pkg/deployment/collector_test.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" "github.com/jaegertracing/jaeger-operator/pkg/apis/io/v1alpha1" ) @@ -216,3 +217,37 @@ func TestCollectorVolumeWithSameName(t *testing.T) { // collector volume is mounted assert.Equal(t, podSpec.Volumes[0].VolumeSource.HostPath.Path, "/data2") } + +func TestCollectorResources(t *testing.T) { + jaeger := v1alpha1.NewJaeger("TestCollectorResources") + jaeger.Spec.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceLimitsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceRequestsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + } + jaeger.Spec.Collector.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceLimitsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceRequestsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + } + + collector := NewCollector(jaeger) + dep := collector.Get() + + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsCPU]) + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsCPU]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsMemory]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsMemory]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsEphemeralStorage]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsEphemeralStorage]) +} diff --git a/pkg/deployment/query.go b/pkg/deployment/query.go index fadad2d52..4d974b546 100644 --- a/pkg/deployment/query.go +++ b/pkg/deployment/query.go @@ -114,6 +114,7 @@ func (q *Query) Get() *appsv1.Deployment { }, InitialDelaySeconds: 1, }, + Resources: commonSpec.Resources, }}, Volumes: commonSpec.Volumes, }, diff --git a/pkg/deployment/query_test.go b/pkg/deployment/query_test.go index c4e7ef288..e3be73ce6 100644 --- a/pkg/deployment/query_test.go +++ b/pkg/deployment/query_test.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" "github.com/jaegertracing/jaeger-operator/pkg/apis/io/v1alpha1" ) @@ -208,3 +209,37 @@ func TestQueryVolumeWithSameName(t *testing.T) { // query volume is mounted assert.Equal(t, podSpec.Volumes[0].VolumeSource.HostPath.Path, "/data2") } + +func TestQueryResources(t *testing.T) { + jaeger := v1alpha1.NewJaeger("TestQueryResources") + jaeger.Spec.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceLimitsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceRequestsEphemeralStorage: *resource.NewQuantity(512, resource.DecimalSI), + }, + } + jaeger.Spec.Query.Resources = v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceLimitsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceRequestsMemory: *resource.NewQuantity(123, resource.DecimalSI), + }, + } + + query := NewQuery(jaeger) + dep := query.Get() + + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsCPU]) + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsCPU]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsMemory]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsMemory]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Limits[v1.ResourceLimitsEphemeralStorage]) + assert.Equal(t, *resource.NewQuantity(512, resource.DecimalSI), dep.Spec.Template.Spec.Containers[0].Resources.Requests[v1.ResourceRequestsEphemeralStorage]) +} diff --git a/pkg/util/util.go b/pkg/util/util.go index 52cd1cc45..7609290fe 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -42,6 +42,7 @@ func Merge(commonSpecs []v1alpha1.JaegerCommonSpec) *v1alpha1.JaegerCommonSpec { annotations := make(map[string]string) var volumeMounts []v1.VolumeMount var volumes []v1.Volume + resources := &v1.ResourceRequirements{} for _, commonSpec := range commonSpecs { // Merge annotations @@ -53,11 +54,36 @@ func Merge(commonSpecs []v1alpha1.JaegerCommonSpec) *v1alpha1.JaegerCommonSpec { } volumeMounts = append(volumeMounts, commonSpec.VolumeMounts...) volumes = append(volumes, commonSpec.Volumes...) + + // Merge resources + mergeResources(resources, commonSpec.Resources) } return &v1alpha1.JaegerCommonSpec{ Annotations: annotations, VolumeMounts: removeDuplicatedVolumeMounts(volumeMounts), Volumes: removeDuplicatedVolumes(volumes), + Resources: *resources, + } +} + +func mergeResources(resources *v1.ResourceRequirements, res v1.ResourceRequirements) { + + for k, v := range res.Limits { + if _, ok := resources.Limits[k]; !ok { + if resources.Limits == nil { + resources.Limits = make(v1.ResourceList) + } + resources.Limits[k] = v + } + } + + for k, v := range res.Requests { + if _, ok := resources.Requests[k]; !ok { + if resources.Requests == nil { + resources.Requests = make(v1.ResourceList) + } + resources.Requests[k] = v + } } } diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index aa661a38d..b7d9ae17a 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" "github.com/jaegertracing/jaeger-operator/pkg/apis/io/v1alpha1" ) @@ -131,3 +132,53 @@ func TestMergeVolumes(t *testing.T) { assert.Equal(t, "/data1", merged.Volumes[0].VolumeSource.HostPath.Path) assert.Equal(t, "volume2", merged.Volumes[1].Name) } + +func TestMergeResourceLimits(t *testing.T) { + generalSpec := v1alpha1.JaegerCommonSpec{ + Resources: v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceLimitsEphemeralStorage: *resource.NewQuantity(123, resource.DecimalSI), + }, + }, + } + specificSpec := v1alpha1.JaegerCommonSpec{ + Resources: v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceLimitsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceLimitsMemory: *resource.NewQuantity(1024, resource.BinarySI), + }, + }, + } + + merged := Merge([]v1alpha1.JaegerCommonSpec{specificSpec, generalSpec}) + + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), merged.Resources.Limits[v1.ResourceLimitsCPU]) + assert.Equal(t, *resource.NewQuantity(1024, resource.BinarySI), merged.Resources.Limits[v1.ResourceLimitsMemory]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), merged.Resources.Limits[v1.ResourceLimitsEphemeralStorage]) +} + +func TestMergeResourceRequests(t *testing.T) { + generalSpec := v1alpha1.JaegerCommonSpec{ + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(1024, resource.BinarySI), + v1.ResourceRequestsEphemeralStorage: *resource.NewQuantity(123, resource.DecimalSI), + }, + }, + } + specificSpec := v1alpha1.JaegerCommonSpec{ + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceRequestsCPU: *resource.NewQuantity(2048, resource.BinarySI), + v1.ResourceRequestsMemory: *resource.NewQuantity(1024, resource.BinarySI), + }, + }, + } + + merged := Merge([]v1alpha1.JaegerCommonSpec{specificSpec, generalSpec}) + + assert.Equal(t, *resource.NewQuantity(2048, resource.BinarySI), merged.Resources.Requests[v1.ResourceRequestsCPU]) + assert.Equal(t, *resource.NewQuantity(1024, resource.BinarySI), merged.Resources.Requests[v1.ResourceRequestsMemory]) + assert.Equal(t, *resource.NewQuantity(123, resource.DecimalSI), merged.Resources.Requests[v1.ResourceRequestsEphemeralStorage]) +} From b08363c022da9791558a4757fdde02c642c7edc4 Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Sun, 11 Nov 2018 19:36:35 +0000 Subject: [PATCH 2/2] Regenerate Signed-off-by: Gary Brown --- pkg/apis/io/v1alpha1/zz_generated.deepcopy.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/apis/io/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/io/v1alpha1/zz_generated.deepcopy.go index 901366089..eef0a9fe9 100644 --- a/pkg/apis/io/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/io/v1alpha1/zz_generated.deepcopy.go @@ -136,6 +136,7 @@ func (in *JaegerCommonSpec) DeepCopyInto(out *JaegerCommonSpec) { (*out)[key] = val } } + in.Resources.DeepCopyInto(&out.Resources) return }