diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index c161aee17..9f69ccd1c 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -74,6 +74,10 @@ type CheClusterSpec struct { // Development environment configuration. // +k8s:openapi-gen=true type CheClusterDevEnvironments struct { + // + // GatewayContainer configuration. + // +optional + GatewayContainer *Container `json:"gatewayContainer,omitempty"` // Workspaces persistent storage. // +optional // +kubebuilder:default:={pvcStrategy: per-user} diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 7682a8678..88de86f24 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -148,6 +148,11 @@ func (in *CheClusterContainerRegistry) DeepCopy() *CheClusterContainerRegistry { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheClusterDevEnvironments) DeepCopyInto(out *CheClusterDevEnvironments) { *out = *in + if in.GatewayContainer != nil { + in, out := &in.GatewayContainer, &out.GatewayContainer + *out = new(Container) + (*in).DeepCopyInto(*out) + } in.Storage.DeepCopyInto(&out.Storage) if in.DefaultPlugins != nil { in, out := &in.DefaultPlugins, &out.DefaultPlugins diff --git a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml index 165e47bd1..d1fbf3968 100644 --- a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml @@ -77,7 +77,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che.v7.66.0-790.next + name: eclipse-che.v7.66.0-791.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1243,7 +1243,7 @@ spec: minKubeVersion: 1.19.0 provider: name: Eclipse Foundation - version: 7.66.0-790.next + version: 7.66.0-791.next webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml index 620a81bdf..ad72b6972 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -7061,6 +7061,198 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the + container. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty + to use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute + resources allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If + the value is not specified, then the default value + is set depending on the component. If value is + `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = + 500 * 1024 * 1024 * 1024) If the value is not + specified, then the default value is set depending + on the component. If value is `0`, then no value + is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute + resources required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If + the value is not specified, then the default value + is set depending on the component. If value is + `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = + 500 * 1024 * 1024 * 1024) If the value is not + specified, then the default value is set depending + on the component. If value is `0`, then no value + is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index b6d210d55..6d2d7c204 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -6866,6 +6866,194 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the container. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty to + use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute resources + allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute resources + required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of workspaces. diff --git a/controllers/devworkspace/solver/che_routing.go b/controllers/devworkspace/solver/che_routing.go index 3ec1b53e1..f1a2a49dc 100644 --- a/controllers/devworkspace/solver/che_routing.go +++ b/controllers/devworkspace/solver/che_routing.go @@ -24,6 +24,7 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/constants" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/utils" + "github.com/eclipse-che/che-operator/pkg/deploy" "github.com/eclipse-che/che-operator/pkg/deploy/gateway" "k8s.io/apimachinery/pkg/api/resource" @@ -176,7 +177,7 @@ func (c *CheRoutingSolver) provisionPodAdditions(objs *solvers.RoutingObjects, c } } - objs.PodAdditions.Containers = append(objs.PodAdditions.Containers, corev1.Container{ + gatewayContainer := &corev1.Container{ Name: wsGatewayName, Image: image, ImagePullPolicy: corev1.PullPolicy(utils.GetPullPolicyFromDockerImage(image)), @@ -188,15 +189,23 @@ func (c *CheRoutingSolver) provisionPodAdditions(objs *solvers.RoutingObjects, c }, Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("256Mi"), - corev1.ResourceCPU: resource.MustParse("0.5"), + corev1.ResourceMemory: resource.MustParse(constants.DefaultGatewayMemoryLimit), + corev1.ResourceCPU: resource.MustParse(constants.DefaultGatewayCpuLimit), }, Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("64Mi"), - corev1.ResourceCPU: resource.MustParse("0.05"), + corev1.ResourceMemory: resource.MustParse(constants.DefaultGatewayMemoryRequest), + corev1.ResourceCPU: resource.MustParse(constants.DefaultGatewayCpuRequest), }, }, - }) + } + + if cheCluster.Spec.DevEnvironments.GatewayContainer != nil { + if err := deploy.CustomizeContainer(gatewayContainer, cheCluster.Spec.DevEnvironments.GatewayContainer); err != nil { + return err + } + } + + objs.PodAdditions.Containers = append(objs.PodAdditions.Containers, *gatewayContainer) // Even though DefaultMode is optional in Kubernetes, DevWorkspace Controller needs it to be explicitly defined. // 420 = 0644 = '-rw-r--r--' diff --git a/controllers/devworkspace/solver/che_routing_test.go b/controllers/devworkspace/solver/che_routing_test.go index 6f16b4843..4aa9ab983 100644 --- a/controllers/devworkspace/solver/che_routing_test.go +++ b/controllers/devworkspace/solver/che_routing_test.go @@ -20,14 +20,19 @@ import ( "github.com/stretchr/testify/assert" + // "k8s.io/apimachinery/pkg/api/resource" + dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" dwo "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" "github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers" - "github.com/devfile/devworkspace-operator/pkg/constants" + "github.com/eclipse-che/che-operator/pkg/common/test" + + dwConstants "github.com/devfile/devworkspace-operator/pkg/constants" "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" controller "github.com/eclipse-che/che-operator/controllers/devworkspace" "github.com/eclipse-che/che-operator/controllers/devworkspace/defaults" + constants "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/deploy/gateway" routev1 "github.com/openshift/api/route/v1" appsv1 "k8s.io/api/apps/v1" @@ -35,6 +40,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" rbac "k8s.io/api/rbac/v1" apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -248,7 +254,7 @@ func TestCreateRelocatedObjectsK8S(t *testing.T) { t.Errorf("The namespace of the associated che manager should have been recorded in the service annotation") } - if svc.Labels[constants.DevWorkspaceIDLabel] != "wsid" { + if svc.Labels[dwConstants.DevWorkspaceIDLabel] != "wsid" { t.Errorf("The workspace ID should be recorded in the service labels") } }) @@ -561,7 +567,7 @@ func TestCreateSubDomainObjects(t *testing.T) { t.Errorf("The namespace of the associated che manager should have been recorded in the service annotation") } - if svc.Labels[constants.DevWorkspaceIDLabel] != "wsid" { + if svc.Labels[dwConstants.DevWorkspaceIDLabel] != "wsid" { t.Errorf("The workspace ID should be recorded in the service labels") } }) @@ -1038,3 +1044,213 @@ func TestUsesCustomCertificateForWorkspaceEndpointRoutes(t *testing.T) { t.Errorf("Unexpected TLS on the route: %s", route.Spec.TLS) } } + +func TestOverrideGatewayContainerProvisioning(t *testing.T) { + overrideMemoryRequest := resource.MustParse("128Mi") + overrideCpuRequest := resource.MustParse("1") + overrideMemoryLimit := resource.MustParse("228Mi") + overrideCpuLimit := resource.MustParse("2") + + cheCluster := &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Hostname: "test.hostname", + Domain: "test.domain", + }, + DevEnvironments: chev2.CheClusterDevEnvironments{ + GatewayContainer: &chev2.Container{ + Resources: &chev2.ResourceRequirements{ + Requests: &chev2.ResourceList{ + Memory: &overrideMemoryRequest, + Cpu: &overrideCpuRequest, + }, + Limits: &chev2.ResourceList{ + Memory: &overrideMemoryLimit, + Cpu: &overrideCpuLimit, + }, + }, + }, + }, + }, + } + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + + cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + objs := &solvers.RoutingObjects{} + + routing := &dwo.DevWorkspaceRouting{ + ObjectMeta: metav1.ObjectMeta{ + Name: "routing", + Namespace: "ws", + }, + Spec: dwo.DevWorkspaceRoutingSpec{ + DevWorkspaceId: "wsid", + }, + } + + cheSolver.provisionPodAdditions(objs, cheCluster, routing) + + assert.Equal(t, overrideCpuRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Cpu().String()) + assert.Equal(t, overrideMemoryRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Memory().String()) + assert.Equal(t, overrideCpuLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Cpu().String()) + assert.Equal(t, overrideMemoryLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Memory().String()) +} + +func TestOverridePartialLimitsGatewayContainerProvisioning(t *testing.T) { + overrideMemoryRequest := resource.MustParse("0") + overrideCpuRequest := resource.MustParse("0") + defaultMemoryLimit := resource.MustParse(constants.DefaultGatewayMemoryLimit) + defaultCpuLimit := resource.MustParse(constants.DefaultGatewayCpuLimit) + + cheCluster := &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Hostname: "test.hostname", + Domain: "test.domain", + }, + DevEnvironments: chev2.CheClusterDevEnvironments{ + GatewayContainer: &chev2.Container{ + Resources: &chev2.ResourceRequirements{ + Requests: &chev2.ResourceList{ + Memory: &overrideMemoryRequest, + Cpu: &overrideCpuRequest, + }, + }, + }, + }, + }, + } + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + + cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + objs := &solvers.RoutingObjects{} + + routing := &dwo.DevWorkspaceRouting{ + ObjectMeta: metav1.ObjectMeta{ + Name: "routing", + Namespace: "ws", + }, + Spec: dwo.DevWorkspaceRoutingSpec{ + DevWorkspaceId: "wsid", + }, + } + + cheSolver.provisionPodAdditions(objs, cheCluster, routing) + + assert.Equal(t, overrideCpuRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Cpu().String()) + assert.Equal(t, overrideMemoryRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Memory().String()) + assert.Equal(t, defaultCpuLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Cpu().String()) + assert.Equal(t, defaultMemoryLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Memory().String()) +} + +func TestOverrideGatewayEmptyContainerProvisioning(t *testing.T) { + overrideMemoryRequest := resource.MustParse("0") + overrideCpuRequest := resource.MustParse("0") + overrideMemoryLimit := resource.MustParse("0") + overrideCpuLimit := resource.MustParse("0") + + cheCluster := &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Hostname: "test.hostname", + Domain: "test.domain", + }, + DevEnvironments: chev2.CheClusterDevEnvironments{ + GatewayContainer: &chev2.Container{ + Resources: &chev2.ResourceRequirements{ + Requests: &chev2.ResourceList{ + Memory: &overrideMemoryRequest, + Cpu: &overrideCpuRequest, + }, + Limits: &chev2.ResourceList{ + Memory: &overrideMemoryLimit, + Cpu: &overrideCpuLimit, + }, + }, + }, + }, + }, + } + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + + cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + objs := &solvers.RoutingObjects{} + + routing := &dwo.DevWorkspaceRouting{ + ObjectMeta: metav1.ObjectMeta{ + Name: "routing", + Namespace: "ws", + }, + Spec: dwo.DevWorkspaceRoutingSpec{ + DevWorkspaceId: "wsid", + }, + } + + cheSolver.provisionPodAdditions(objs, cheCluster, routing) + + assert.Equal(t, overrideCpuRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Cpu().String()) + assert.Equal(t, overrideMemoryRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Memory().String()) + assert.Equal(t, overrideCpuLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Cpu().String()) + assert.Equal(t, overrideMemoryLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Memory().String()) +} + +func TestDefaultGatewayContainerProvisioning(t *testing.T) { + defaultMemoryRequest := resource.MustParse(constants.DefaultGatewayMemoryRequest) + defaultCpuRequest := resource.MustParse(constants.DefaultGatewayCpuRequest) + defaultMemoryLimit := resource.MustParse(constants.DefaultGatewayMemoryLimit) + defaultCpuLimit := resource.MustParse(constants.DefaultGatewayCpuLimit) + + cheCluster := &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Hostname: "test.hostname", + Domain: "test.domain", + }, + }, + } + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + + cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + objs := &solvers.RoutingObjects{} + + routing := &dwo.DevWorkspaceRouting{ + ObjectMeta: metav1.ObjectMeta{ + Name: "routing", + Namespace: "ws", + }, + Spec: dwo.DevWorkspaceRoutingSpec{ + DevWorkspaceId: "wsid", + }, + } + + cheSolver.provisionPodAdditions(objs, cheCluster, routing) + + assert.Equal(t, defaultCpuRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Cpu().String()) + assert.Equal(t, defaultMemoryRequest.String(), objs.PodAdditions.Containers[0].Resources.Requests.Memory().String()) + assert.Equal(t, defaultCpuLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Cpu().String()) + assert.Equal(t, defaultMemoryLimit.String(), objs.PodAdditions.Containers[0].Resources.Limits.Memory().String()) +} diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index f1015e886..aee563e24 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -6885,6 +6885,194 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the container. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty to + use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute resources + allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute resources + required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of workspaces. diff --git a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 944ca1c92..1034c299d 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -6880,6 +6880,194 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the container. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty to + use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute resources + allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute resources + required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of workspaces. diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 5912e314a..9295fe33e 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -6885,6 +6885,194 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the container. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty to + use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute resources + allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute resources + required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of workspaces. diff --git a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 606766b24..de1032354 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -6880,6 +6880,194 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the container. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty to + use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute resources + allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute resources + required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of workspaces. diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 944ca1c92..1034c299d 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -6880,6 +6880,194 @@ spec: disableContainerBuildCapabilities: description: Disables the container build capabilities. type: boolean + gatewayContainer: + description: GatewayContainer configuration. + properties: + env: + description: List of environment variables to set in the container. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Container image. Omit it or leave it empty to + use the default container image provided by the Operator. + type: string + imagePullPolicy: + description: Image pull policy. Default value is `Always` + for `nightly`, `next` or `latest` images, and `IfNotPresent` + in other cases. + enum: + - Always + - IfNotPresent + - Never + type: string + name: + description: Container name. + type: string + resources: + description: Compute resources required by this container. + properties: + limits: + description: Describes the maximum amount of compute resources + allowed. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + request: + description: Describes the minimum amount of compute resources + required. + properties: + cpu: + anyOf: + - type: integer + - type: string + description: CPU, in cores. (500m = .5 cores) If the + value is not specified, then the default value is + set depending on the component. If value is `0`, + then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + memory: + anyOf: + - type: integer + - type: string + description: Memory, in bytes. (500Gi = 500GiB = 500 + * 1024 * 1024 * 1024) If the value is not specified, + then the default value is set depending on the component. + If value is `0`, then no value is set for the component. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object maxNumberOfRunningWorkspacesPerUser: description: The maximum number of running workspaces per user. The value, -1, allows users to run an unlimited number of workspaces. diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index 85825dec0..8fac8ae7b 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -24,6 +24,12 @@ const ( DefaultDashboardCpuLimit = "500m" DefaultDashboardCpuRequest = "100m" + // Gateway + DefaultGatewayMemoryLimit = "256Mi" + DefaultGatewayMemoryRequest = "64Mi" + DefaultGatewayCpuLimit = "25m" + DefaultGatewayCpuRequest = "5m" + // PluginRegistry DefaultPluginRegistryMemoryLimit = "256Mi" DefaultPluginRegistryMemoryLimitEmbeddedOpenVSXRegistry = "4Gi"