diff --git a/api/v1alpha1/devfileregistry_types.go b/api/v1alpha1/devfileregistry_types.go index 0471df1..7cae449 100644 --- a/api/v1alpha1/devfileregistry_types.go +++ b/api/v1alpha1/devfileregistry_types.go @@ -82,6 +82,10 @@ type DevfileRegistrySpecContainer struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // +optional ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + // Sets the memory limit for the container + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +optional + MemoryLimit string `json:"memoryLimit,omitempty"` } // DevfileRegistrySpecStorage defines the desired state of the storage for the DevfileRegistry diff --git a/config/crd/bases/registry.devfile.io_devfileregistries.yaml b/config/crd/bases/registry.devfile.io_devfileregistries.yaml index c23924a..c201448 100644 --- a/config/crd/bases/registry.devfile.io_devfileregistries.yaml +++ b/config/crd/bases/registry.devfile.io_devfileregistries.yaml @@ -56,6 +56,9 @@ spec: imagePullPolicy: description: Sets the image pull policy for the container type: string + memoryLimit: + description: Sets the memory limit for the container + type: string type: object devfileIndexImage: description: Sets the container image containing devfile stacks to @@ -84,6 +87,9 @@ spec: imagePullPolicy: description: Sets the image pull policy for the container type: string + memoryLimit: + description: Sets the memory limit for the container + type: string type: object ociRegistryImage: description: Overrides the container image used for the OCI registry. @@ -100,6 +106,9 @@ spec: imagePullPolicy: description: Sets the image pull policy for the container type: string + memoryLimit: + description: Sets the memory limit for the container + type: string type: object registryViewerImage: description: Overrides the container image used for the registry viewer. diff --git a/pkg/registry/defaults.go b/pkg/registry/defaults.go index 37993d4..5c3e10b 100644 --- a/pkg/registry/defaults.go +++ b/pkg/registry/defaults.go @@ -19,6 +19,7 @@ package registry import ( registryv1alpha1 "github.com/devfile/registry-operator/api/v1alpha1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" ) const ( @@ -32,6 +33,11 @@ const ( DefaultRegistryViewerImagePullPolicy = corev1.PullAlways DefaultOCIRegistryImagePullPolicy = corev1.PullAlways + // Default memory limits + DefaultDevfileIndexMemoryLimit = "256Mi" + DefaultRegistryViewerMemoryLimit = "256Mi" + DefaultOCIRegistryMemoryLimit = "256Mi" + // Defaults/constants for devfile registry storages DefaultDevfileRegistryVolumeSize = "1Gi" DevfileRegistryVolumeEnabled = false @@ -73,6 +79,13 @@ func GetRegistryViewerImagePullPolicy(cr *registryv1alpha1.DevfileRegistry) core return DefaultRegistryViewerImagePullPolicy } +// GetRegistryViewerMemoryLimit returns the memory limit for the registry viewer container. +// In case of invalid quantity given, it returns the default value. +// Default: resource.Quantity{s: "256Mi"} +func GetRegistryViewerMemoryLimit(cr *registryv1alpha1.DevfileRegistry) resource.Quantity { + return getDevfileRegistrySpecContainer(cr.Spec.RegistryViewer.MemoryLimit, DefaultRegistryViewerMemoryLimit) +} + // GetOCIRegistryImage returns the container image for the OCI registry to be deployed on the Devfile Registry. // Default: "quay.io/devfile/oci-registry:next" func GetOCIRegistryImage(cr *registryv1alpha1.DevfileRegistry) string { @@ -93,6 +106,13 @@ func GetOCIRegistryImagePullPolicy(cr *registryv1alpha1.DevfileRegistry) corev1. return DefaultOCIRegistryImagePullPolicy } +// GetOCIRegistryMemoryLimit returns the memory limit for the OCI registry container. +// In case of invalid quantity given, it returns the default value. +// Default: resource.Quantity{s: "256Mi"} +func GetOCIRegistryMemoryLimit(cr *registryv1alpha1.DevfileRegistry) resource.Quantity { + return getDevfileRegistrySpecContainer(cr.Spec.OciRegistry.MemoryLimit, DefaultOCIRegistryMemoryLimit) +} + // GetDevfileIndexImage returns the container image for the devfile index server to be deployed on the Devfile Registry. // Default: "quay.io/devfile/devfile-index:next" func GetDevfileIndexImage(cr *registryv1alpha1.DevfileRegistry) string { @@ -113,6 +133,13 @@ func GetDevfileIndexImagePullPolicy(cr *registryv1alpha1.DevfileRegistry) corev1 return DefaultDevfileIndexImagePullPolicy } +// GetDevfileIndexMemoryLimit returns the memory limit for the devfile index container. +// In case of invalid quantity given, it returns the default value. +// Default: resource.Quantity{s: "256Mi"} +func GetDevfileIndexMemoryLimit(cr *registryv1alpha1.DevfileRegistry) resource.Quantity { + return getDevfileRegistrySpecContainer(cr.Spec.DevfileIndex.MemoryLimit, DefaultDevfileIndexMemoryLimit) +} + func getDevfileRegistryVolumeSize(cr *registryv1alpha1.DevfileRegistry) string { if cr.Spec.Storage.RegistryVolumeSize != "" { return cr.Spec.Storage.RegistryVolumeSize @@ -167,3 +194,13 @@ func IsHeadlessEnabled(cr *registryv1alpha1.DevfileRegistry) bool { } return DefaultDevfileRegistryHeadlessEnabled } + +func getDevfileRegistrySpecContainer(quantity string, defaultValue string) resource.Quantity { + if quantity != "" { + resourceQuantity, err := resource.ParseQuantity(quantity) + if err == nil { + return resourceQuantity + } + } + return resource.MustParse(defaultValue) +} diff --git a/pkg/registry/defaults_test.go b/pkg/registry/defaults_test.go index 893d34e..20b73f3 100644 --- a/pkg/registry/defaults_test.go +++ b/pkg/registry/defaults_test.go @@ -22,6 +22,7 @@ import ( registryv1alpha1 "github.com/devfile/registry-operator/api/v1alpha1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -189,6 +190,120 @@ func TestGetDevfileRegistryVolumeSource(t *testing.T) { } +func TestGetDevfileIndexMemoryLimit(t *testing.T) { + tests := []struct { + name string + cr registryv1alpha1.DevfileRegistry + want resource.Quantity + }{ + { + name: "Case 1: Memory Limit size set in DevfileRegistry CR", + cr: registryv1alpha1.DevfileRegistry{ + Spec: registryv1alpha1.DevfileRegistrySpec{ + DevfileIndex: registryv1alpha1.DevfileRegistrySpecContainer{ + MemoryLimit: "5Gi", + }, + }, + }, + want: resource.MustParse("5Gi"), + }, + { + name: "Case 2: Memory Limit size not set in DevfileRegistry CR", + cr: registryv1alpha1.DevfileRegistry{ + Spec: registryv1alpha1.DevfileRegistrySpec{ + DevfileIndex: registryv1alpha1.DevfileRegistrySpecContainer{}, + }, + }, + want: resource.MustParse(DefaultDevfileIndexMemoryLimit), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + volSize := GetDevfileIndexMemoryLimit(&tt.cr) + if volSize != tt.want { + t.Errorf("TestGetDevfileIndexMemoryLimit error: storage size mismatch, expected: %v got: %v", tt.want, volSize) + } + }) + } + +} + +func TestGetOCIRegistryMemoryLimit(t *testing.T) { + tests := []struct { + name string + cr registryv1alpha1.DevfileRegistry + want resource.Quantity + }{ + { + name: "Case 1: Memory Limit size set in DevfileRegistry CR", + cr: registryv1alpha1.DevfileRegistry{ + Spec: registryv1alpha1.DevfileRegistrySpec{ + OciRegistry: registryv1alpha1.DevfileRegistrySpecContainer{ + MemoryLimit: "5Gi", + }, + }, + }, + want: resource.MustParse("5Gi"), + }, + { + name: "Case 2: Memory Limit size not set in DevfileRegistry CR", + cr: registryv1alpha1.DevfileRegistry{ + Spec: registryv1alpha1.DevfileRegistrySpec{ + OciRegistry: registryv1alpha1.DevfileRegistrySpecContainer{}, + }, + }, + want: resource.MustParse(DefaultOCIRegistryMemoryLimit), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + volSize := GetOCIRegistryMemoryLimit(&tt.cr) + if volSize != tt.want { + t.Errorf("TestGetOCIRegistryMemoryLimit error: storage size mismatch, expected: %v got: %v", tt.want, volSize) + } + }) + } + +} + +func TestGetRegistryViewerMemoryLimit(t *testing.T) { + tests := []struct { + name string + cr registryv1alpha1.DevfileRegistry + want resource.Quantity + }{ + { + name: "Case 1: Memory Limit size set in DevfileRegistry CR", + cr: registryv1alpha1.DevfileRegistry{ + Spec: registryv1alpha1.DevfileRegistrySpec{ + RegistryViewer: registryv1alpha1.DevfileRegistrySpecContainer{ + MemoryLimit: "5Gi", + }, + }, + }, + want: resource.MustParse("5Gi"), + }, + { + name: "Case 2: Memory Limit size not set in DevfileRegistry CR", + cr: registryv1alpha1.DevfileRegistry{ + Spec: registryv1alpha1.DevfileRegistrySpec{ + RegistryViewer: registryv1alpha1.DevfileRegistrySpecContainer{}, + }, + }, + want: resource.MustParse(DefaultRegistryViewerMemoryLimit), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + volSize := GetRegistryViewerMemoryLimit(&tt.cr) + if volSize != tt.want { + t.Errorf("TestGetRegistryViewerMemoryLimit error: storage size mismatch, expected: %v got: %v", tt.want, volSize) + } + }) + } + +} + func TestGetDevfileRegistryVolumeSize(t *testing.T) { tests := []struct { name string @@ -284,3 +399,33 @@ func TestIsTelemetryEnabled(t *testing.T) { } } + +func Test_getDevfileRegistrySpecContainer(t *testing.T) { + tests := []struct { + name string + quantity string + defaultValue string + want resource.Quantity + }{ + { + name: "Case 1: DevfileRegistrySpecContainer given correct quantity", + quantity: "256Mi", + defaultValue: "512Mi", + want: resource.MustParse("256Mi"), + }, + { + name: "Case 2: DevfileRegistrySpecContainer given correct quantity", + quantity: "test", + defaultValue: "512Mi", + want: resource.MustParse("512Mi"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := getDevfileRegistrySpecContainer(tt.quantity, tt.defaultValue) + if result != tt.want { + t.Errorf("func TestgetDevfileRegistrySpecContainer(t *testing.T) {\n error: enablement value mismatch, expected: %v got: %v", tt.want, result) + } + }) + } +}