diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 8cf13d04a..21cf7feab 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -448,7 +448,7 @@ | [golang.org/x/mobile@d3739f865fa66d07c1f506505c18aac71a8ead6e](https://cs.opensource.google/go) | BSD-3-Clause | N/A | | [github.com/devfile/api/v2@0d163445376d4d28898f3fbac4f2ff62863b944b](https://github.com/devfile/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/api/0d163445376d4d28898f3fbac4f2ff62863b944b) | | [github.com/che-incubator/kubernetes-image-puller-operator@0128446f5af78587c0427a35d693bbb8d24036bc](https://github.com/che-incubator/kubernetes-image-puller-operator.git) | EPL-2.0 | todo | -| [github.com/devfile/devworkspace-operator@v0.20.0](https://github.com/devfile/devworkspace-operator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/devworkspace-operator/ef761d812e029d094d2e9936d11ce4a3f6b8efd3) | +| [github.com/devfile/devworkspace-operator@v0.21.0](https://github.com/devfile/devworkspace-operator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/devworkspace-operator/21edf4373322c228ed54a5d4747b0451435a8f08) | | [github.com/gophercloud/gophercloud@v0.1.0](https://github.com/gophercloud/gophercloud) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgophercloud/gophercloud/v0.1.0) | | [gopkg.in/imdario/mergo.v0@v0.3.7](https://github.com/imdario/mergo/) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fimdario/mergo/v0.3.7) | | [github.com/mikefarah/yq/v2@v2.4.1](https://github.com/mikefarah/yq) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mikefarah/yq/b8b2c9de6189471c0cdbd459b5b0b49a57844bd4) | diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index 1b2ed3481..c0d0b327d 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -78,6 +78,9 @@ type CheClusterDevEnvironments struct { // GatewayContainer configuration. // +optional GatewayContainer *Container `json:"gatewayContainer,omitempty"` + // Project clone container configuration. + // +optional + ProjectCloneContainer *Container `json:"projectCloneContainer,omitempty"` // Workspaces persistent storage. // +optional // +kubebuilder:default:={pvcStrategy: per-user} @@ -779,7 +782,7 @@ type CheCluster struct { Status CheClusterStatus `json:"status,omitempty"` } -//+kubebuilder:object:root=true +// +kubebuilder:object:root=true // The CheClusterList contains a list of CheClusters. type CheClusterList struct { metav1.TypeMeta `json:",inline"` diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 7185cd812..0fae43f27 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -152,6 +152,11 @@ func (in *CheClusterDevEnvironments) DeepCopyInto(out *CheClusterDevEnvironments *out = new(Container) (*in).DeepCopyInto(*out) } + if in.ProjectCloneContainer != nil { + in, out := &in.ProjectCloneContainer, &out.ProjectCloneContainer + *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 79e71b130..e65d98e48 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.68.0-794.next + name: eclipse-che.v7.68.0-795.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1235,7 +1235,7 @@ spec: minKubeVersion: 1.19.0 provider: name: Eclipse Foundation - version: 7.68.0-794.next + version: 7.68.0-795.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 0835e385b..c55638846 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -7001,6 +7001,198 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index f45841865..01e995cde 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -6804,6 +6804,194 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index 0cf453c08..3e451e8fb 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -6823,6 +6823,194 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout 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 99d628bc4..749fdb29d 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -6818,6 +6818,194 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 5cad47d1c..81906b499 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -6823,6 +6823,194 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout 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 2586c6a3e..16831144c 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -6818,6 +6818,194 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout diff --git a/go.mod b/go.mod index b0e4cce76..3162c1d3a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20210929175054-0128446f5af7 github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd - github.com/devfile/devworkspace-operator v0.20.0 + github.com/devfile/devworkspace-operator v0.21.0 github.com/go-logr/logr v1.2.3 github.com/golang/mock v1.5.0 github.com/google/go-cmp v0.5.9 diff --git a/go.sum b/go.sum index 60569ebbf..aeebedc47 100644 --- a/go.sum +++ b/go.sum @@ -102,8 +102,8 @@ github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd h1:HpGR728CfB6BB9ZuFtQb0UeTIYNFgpuGsuoMOJNMUTM= github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM= -github.com/devfile/devworkspace-operator v0.20.0 h1:xm8+vCzVGf1D7AV05d4liRijIzWxnNwuV1Z976uzIOU= -github.com/devfile/devworkspace-operator v0.20.0/go.mod h1:LTraBqSugk9bR/ZKj3HAry+pnAdYOfwEYCl/FkuIjfI= +github.com/devfile/devworkspace-operator v0.21.0 h1:AiN2HEBpBkYoOcKClFZsOut46zKhsMIlHwmjI+OB2Oc= +github.com/devfile/devworkspace-operator v0.21.0/go.mod h1:42cQKSbE+Zdqez8X5IqlEfdeeA0a/LkOTe2kkekJX6c= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dhui/dktest v0.3.2/go.mod h1:l1/ib23a/CmxAe7yixtrYPc8Iy90Zy2udyaHINM5p58= github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw= diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 99d628bc4..749fdb29d 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -6818,6 +6818,194 @@ spec: description: Pod scheduler for the workspace pods. If not specified, the pod scheduler is set to the default scheduler on the cluster. type: string + projectCloneContainer: + description: Project clone container 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 secondsOfInactivityBeforeIdling: default: 1800 description: Idle timeout for workspaces in seconds. This timeout diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config.go b/pkg/deploy/dev-workspace-config/dev_workspace_config.go index 5c81fa112..b4190c2aa 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config.go @@ -9,6 +9,7 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // + package devworkspaceconfig import ( @@ -21,6 +22,7 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/utils" "github.com/eclipse-che/che-operator/pkg/deploy" v1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" @@ -84,14 +86,14 @@ func updateWorkspaceConfig(cheCluster *chev2.CheCluster, operatorConfig *control return err } - if err := updateWorkspaceServiceAccountConfig(devEnvironments, operatorConfig.Workspace); err != nil { - return err - } + updateWorkspaceServiceAccountConfig(devEnvironments, operatorConfig.Workspace) if err := updateWorkspacePodSchedulerNameConfig(devEnvironments, operatorConfig.Workspace); err != nil { return err } + updateProjectCloneConfig(devEnvironments, operatorConfig.Workspace) + operatorConfig.Workspace.ContainerSecurityContext = nil if cheCluster.IsContainerBuildCapabilitiesEnabled() { operatorConfig.Workspace.ContainerSecurityContext = constants.DefaultWorkspaceContainerSecurityContext.DeepCopy() @@ -146,19 +148,63 @@ func updateWorkspaceStorageConfig(devEnvironments *chev2.CheClusterDevEnvironmen return nil } -func updateWorkspaceServiceAccountConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) error { - isNamespaceAutoProvisioned := pointer.BoolPtrDerefOr(devEnvironments.DefaultNamespace.AutoProvision, constants.DefaultAutoProvision) +func updateWorkspaceServiceAccountConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) { + isNamespaceAutoProvisioned := pointer.BoolDeref(devEnvironments.DefaultNamespace.AutoProvision, constants.DefaultAutoProvision) workspaceConfig.ServiceAccount = &controllerv1alpha1.ServiceAccountConfig{ ServiceAccountName: devEnvironments.ServiceAccount, ServiceAccountTokens: devEnvironments.ServiceAccountTokens, // If user's Namespace is not auto provisioned (is pre-created by admin), then ServiceAccount must be pre-created as well - DisableCreation: pointer.BoolPtr(!isNamespaceAutoProvisioned && devEnvironments.ServiceAccount != ""), + DisableCreation: pointer.Bool(!isNamespaceAutoProvisioned && devEnvironments.ServiceAccount != ""), } - return nil } func updateWorkspacePodSchedulerNameConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) error { workspaceConfig.SchedulerName = devEnvironments.PodSchedulerName return nil } + +func updateProjectCloneConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) { + if devEnvironments.ProjectCloneContainer == nil { + return + } + if workspaceConfig.ProjectCloneConfig == nil { + workspaceConfig.ProjectCloneConfig = &controllerv1alpha1.ProjectCloneConfig{} + } + container := devEnvironments.ProjectCloneContainer + + workspaceConfig.ProjectCloneConfig.Image = container.Image + workspaceConfig.ProjectCloneConfig.ImagePullPolicy = container.ImagePullPolicy + workspaceConfig.ProjectCloneConfig.Env = container.Env + workspaceConfig.ProjectCloneConfig.Resources = cheResourcesToCoreV1Resources(container.Resources) +} + +// cheResourcesToCoreV1Resources converts a Che resources struct to the usual Kubernetes object by directly copying fields. +// It does not set any default values or include logic for removing requests/limits that are set to "0" as it is intended +// to prepare resources for the DevWorkspace Operator, which has its own defaults and handling of "0" values. +func cheResourcesToCoreV1Resources(resources *chev2.ResourceRequirements) *corev1.ResourceRequirements { + if resources == nil { + return nil + } + + result := &corev1.ResourceRequirements{} + if resources.Limits != nil { + result.Limits = corev1.ResourceList{} + if resources.Limits.Memory != nil { + result.Limits[corev1.ResourceMemory] = *resources.Limits.Memory + } + if resources.Limits.Cpu != nil { + result.Limits[corev1.ResourceCPU] = *resources.Limits.Cpu + } + } + if resources.Requests != nil { + result.Requests = corev1.ResourceList{} + if resources.Requests.Memory != nil { + result.Requests[corev1.ResourceMemory] = *resources.Requests.Memory + } + if resources.Requests.Cpu != nil { + result.Requests[corev1.ResourceCPU] = *resources.Requests.Cpu + } + } + return result +} diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go index d897952ac..cf195ea76 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go @@ -9,30 +9,28 @@ // Contributors: // Red Hat, Inc. - initial API and implementation // + package devworkspaceconfig import ( + "context" "regexp" "testing" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - corev1 "k8s.io/api/core/v1" - - "github.com/eclipse-che/che-operator/pkg/common/constants" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/utils/pointer" - - "context" - controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" + "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/common/test" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/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" + "k8s.io/utils/pointer" ) func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { @@ -52,6 +50,8 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { var quantity15Gi = resource.MustParse("15Gi") var quantity10Gi = resource.MustParse("10Gi") + var quantity1CPU = resource.MustParse("1000m") + var quantity500mCPU = resource.MustParse("500m") var expectedErrorTestCases = []errorTestCase{ { @@ -87,7 +87,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), }, }, }, @@ -102,7 +102,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.EphemeralPVCStorageStrategy, PerUserStrategyPvcConfig: &chev2.PVC{ @@ -128,7 +128,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.PerUserPVCStorageStrategy, PerUserStrategyPvcConfig: &chev2.PVC{ @@ -140,7 +140,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("test-storage"), + StorageClassName: pointer.String("test-storage"), DeploymentStrategy: "Recreate", }, }, @@ -154,7 +154,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.PerUserPVCStorageStrategy, PerUserStrategyPvcConfig: &chev2.PVC{ @@ -167,7 +167,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("test-storage"), + StorageClassName: pointer.String("test-storage"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity15Gi, }, @@ -184,7 +184,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.PerWorkspacePVCStorageStrategy, PerWorkspaceStrategyPvcConfig: &chev2.PVC{ @@ -197,7 +197,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("test-storage"), + StorageClassName: pointer.String("test-storage"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ PerWorkspace: &quantity15Gi, }, @@ -214,7 +214,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.PerWorkspacePVCStorageStrategy, PerWorkspaceStrategyPvcConfig: &chev2.PVC{ @@ -237,7 +237,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ PerWorkspace: &quantity10Gi, }, @@ -247,7 +247,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("test-storage"), + StorageClassName: pointer.String("test-storage"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ PerWorkspace: &quantity15Gi, }, @@ -264,7 +264,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.PerUserPVCStorageStrategy, PerUserStrategyPvcConfig: &chev2.PVC{ @@ -287,7 +287,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -297,7 +297,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("test-storage"), + StorageClassName: pointer.String("test-storage"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity15Gi, }, @@ -314,7 +314,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), Storage: chev2.WorkspaceStorage{ PvcStrategy: constants.PerUserPVCStorageStrategy, PerUserStrategyPvcConfig: &chev2.PVC{ @@ -351,7 +351,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Workspace: &controllerv1alpha1.WorkspaceConfig{ ImagePullPolicy: "Always", - StorageClassName: pointer.StringPtr("test-storage"), + StorageClassName: pointer.String("test-storage"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity15Gi, }, @@ -368,7 +368,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), }, }, }, @@ -387,7 +387,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(false), + DisableContainerBuildCapabilities: pointer.Bool(false), }, }, }, @@ -400,7 +400,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { "SETUID", }, }, - AllowPrivilegeEscalation: pointer.BoolPtr(true), + AllowPrivilegeEscalation: pointer.Bool(true), }, DeploymentStrategy: "Recreate", }, @@ -415,7 +415,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(false), + DisableContainerBuildCapabilities: pointer.Bool(false), }, }, }, @@ -431,7 +431,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -441,7 +441,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -452,7 +452,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { "SETUID", }, }, - AllowPrivilegeEscalation: pointer.BoolPtr(true), + AllowPrivilegeEscalation: pointer.Bool(true), }, DeploymentStrategy: "Recreate", }, @@ -467,7 +467,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), }, }, }, @@ -483,7 +483,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -495,7 +495,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -512,8 +512,8 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), - StartTimeoutSeconds: pointer.Int32Ptr(600), + DisableContainerBuildCapabilities: pointer.Bool(true), + StartTimeoutSeconds: pointer.Int32(600), }, }, }, @@ -533,8 +533,8 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), - StartTimeoutSeconds: pointer.Int32Ptr(600), + DisableContainerBuildCapabilities: pointer.Bool(true), + StartTimeoutSeconds: pointer.Int32(600), }, }, }, @@ -550,7 +550,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -560,7 +560,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -578,8 +578,8 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), - StartTimeoutSeconds: pointer.Int32Ptr(420), + DisableContainerBuildCapabilities: pointer.Bool(true), + StartTimeoutSeconds: pointer.Int32(420), }, }, }, @@ -595,7 +595,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -606,7 +606,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -624,7 +624,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - DisableContainerBuildCapabilities: pointer.BoolPtr(true), + DisableContainerBuildCapabilities: pointer.Bool(true), }, }, }, @@ -640,7 +640,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -651,7 +651,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - StorageClassName: pointer.StringPtr("default-storage-class"), + StorageClassName: pointer.String("default-storage-class"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity10Gi, }, @@ -659,6 +659,87 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, }, }, + { + name: "Configures ProjectCloneConfig in DevWorkspaceOperatorConfig", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.Bool(true), + ProjectCloneContainer: &chev2.Container{ + Name: "project-clone", + Image: "test-image", + ImagePullPolicy: "IfNotPresent", + Env: []corev1.EnvVar{ + {Name: "test-env-1", Value: "test-val-1"}, + {Name: "test-env-2", Value: "test-val-2"}, + }, + Resources: &chev2.ResourceRequirements{ + Requests: &chev2.ResourceList{ + Memory: &quantity10Gi, + Cpu: &quantity500mCPU, + }, + Limits: &chev2.ResourceList{ + Memory: &quantity15Gi, + Cpu: &quantity1CPU, + }, + }, + }, + }, + }, + }, + existedObjects: []runtime.Object{ + &controllerv1alpha1.DevWorkspaceOperatorConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: devWorkspaceConfigName, + Namespace: "eclipse-che", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "DevWorkspaceOperatorConfig", + APIVersion: controllerv1alpha1.GroupVersion.String(), + }, + Config: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.String("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ProgressTimeout: "1h30m", + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.String("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + DeploymentStrategy: "Recreate", + ProjectCloneConfig: &controllerv1alpha1.ProjectCloneConfig{ + Image: "test-image", + ImagePullPolicy: "IfNotPresent", + Env: []corev1.EnvVar{ + {Name: "test-env-1", Value: "test-val-1"}, + {Name: "test-env-2", Value: "test-val-2"}, + }, + Resources: &corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceMemory: quantity10Gi, + corev1.ResourceCPU: quantity500mCPU, + }, + Limits: corev1.ResourceList{ + corev1.ResourceMemory: quantity15Gi, + corev1.ResourceCPU: quantity1CPU, + }, + }, + }, + }, + }, + }, } for _, testCase := range testCases { @@ -717,7 +798,7 @@ func TestReconcileServiceAccountConfig(t *testing.T) { Workspace: &controllerv1alpha1.WorkspaceConfig{ ServiceAccount: &controllerv1alpha1.ServiceAccountConfig{ ServiceAccountName: "service-account", - DisableCreation: pointer.BoolPtr(false), + DisableCreation: pointer.Bool(false), }, DeploymentStrategy: "Recreate", }, @@ -733,7 +814,7 @@ func TestReconcileServiceAccountConfig(t *testing.T) { Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ DefaultNamespace: chev2.DefaultNamespace{ - AutoProvision: pointer.BoolPtr(false), + AutoProvision: pointer.Bool(false), }, ServiceAccount: "service-account", }, @@ -743,7 +824,7 @@ func TestReconcileServiceAccountConfig(t *testing.T) { Workspace: &controllerv1alpha1.WorkspaceConfig{ ServiceAccount: &controllerv1alpha1.ServiceAccountConfig{ ServiceAccountName: "service-account", - DisableCreation: pointer.BoolPtr(true), + DisableCreation: pointer.Bool(true), }, DeploymentStrategy: "Recreate", }, @@ -763,7 +844,7 @@ func TestReconcileServiceAccountConfig(t *testing.T) { expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ ServiceAccount: &controllerv1alpha1.ServiceAccountConfig{ - DisableCreation: pointer.BoolPtr(false), + DisableCreation: pointer.Bool(false), }, DeploymentStrategy: "Recreate", }, @@ -779,7 +860,7 @@ func TestReconcileServiceAccountConfig(t *testing.T) { Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ DefaultNamespace: chev2.DefaultNamespace{ - AutoProvision: pointer.BoolPtr(false), + AutoProvision: pointer.Bool(false), }, }, }, @@ -787,7 +868,7 @@ func TestReconcileServiceAccountConfig(t *testing.T) { expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ ServiceAccount: &controllerv1alpha1.ServiceAccountConfig{ - DisableCreation: pointer.BoolPtr(false), + DisableCreation: pointer.Bool(false), }, DeploymentStrategy: "Recreate", }, @@ -1328,3 +1409,194 @@ func TestReconcileDevWorkspaceConfigDeploymentStrategy(t *testing.T) { }) } } + +func TestReconcileDevWorkspaceProjectCloneCOnfig(t *testing.T) { + const testNamespace = "eclipse-che" + testMemLimit := resource.MustParse("2Gi") + testCpuLimit := resource.MustParse("1000m") + testMemRequest := resource.MustParse("1Gi") + testCpuRequest := resource.MustParse("500m") + + type testCase struct { + name string + cheProjectCloneConfig *chev2.Container + expectedDevWorkspaceConfig *controllerv1alpha1.ProjectCloneConfig + existingDevWorkspaceConfig *controllerv1alpha1.ProjectCloneConfig + } + + tests := []testCase{ + { + name: "Syncs Che project clone config to DevWorkspaceOperatorConfig", + cheProjectCloneConfig: &chev2.Container{ + Name: "project-clone", + Image: "test-image", + ImagePullPolicy: "IfNotPresent", + Env: []corev1.EnvVar{ + {Name: "test-env-1", Value: "test-val-1"}, + {Name: "test-env-2", Value: "test-val-2"}, + }, + Resources: &chev2.ResourceRequirements{ + Limits: &chev2.ResourceList{ + Memory: &testMemLimit, + Cpu: &testCpuLimit, + }, + Requests: &chev2.ResourceList{ + Memory: &testMemRequest, + Cpu: &testCpuRequest, + }, + }, + }, + expectedDevWorkspaceConfig: &controllerv1alpha1.ProjectCloneConfig{ + Image: "test-image", + ImagePullPolicy: "IfNotPresent", + Env: []corev1.EnvVar{ + {Name: "test-env-1", Value: "test-val-1"}, + {Name: "test-env-2", Value: "test-val-2"}, + }, + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: testMemLimit, + corev1.ResourceCPU: testCpuLimit, + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: testMemRequest, + corev1.ResourceCPU: testCpuRequest, + }, + }, + }, + }, + { + name: "Updates existing DevWorkspaceOperatorConfig with new Che project clone config", + cheProjectCloneConfig: &chev2.Container{ + Name: "project-clone", + Image: "test-image", + ImagePullPolicy: "IfNotPresent", + Env: []corev1.EnvVar{ + {Name: "test-env-1", Value: "test-val-1"}, + {Name: "test-env-2", Value: "test-val-2"}, + }, + Resources: &chev2.ResourceRequirements{ + Limits: &chev2.ResourceList{ + Memory: &testMemLimit, + Cpu: &testCpuLimit, + }, + Requests: &chev2.ResourceList{ + Memory: &testMemRequest, + Cpu: &testCpuRequest, + }, + }, + }, + expectedDevWorkspaceConfig: &controllerv1alpha1.ProjectCloneConfig{ + Image: "test-image", + ImagePullPolicy: "IfNotPresent", + Env: []corev1.EnvVar{ + {Name: "test-env-1", Value: "test-val-1"}, + {Name: "test-env-2", Value: "test-val-2"}, + }, + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: testMemLimit, + corev1.ResourceCPU: testCpuLimit, + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: testMemRequest, + corev1.ResourceCPU: testCpuRequest, + }, + }, + }, + existingDevWorkspaceConfig: &controllerv1alpha1.ProjectCloneConfig{ + Image: "other image", + ImagePullPolicy: "Always", + Env: []corev1.EnvVar{ + {Name: "other-env", Value: "other-val"}, + }, + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1234Mi"), + corev1.ResourceCPU: resource.MustParse("1234m"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1111Mi"), + corev1.ResourceCPU: resource.MustParse("1111m"), + }, + }, + }, + }, + { + name: "Removes fields from existing config when removed from CheCluster", + cheProjectCloneConfig: &chev2.Container{ + Name: "", + Image: "", + ImagePullPolicy: "", + Env: nil, + Resources: nil, + }, + expectedDevWorkspaceConfig: &controllerv1alpha1.ProjectCloneConfig{ + Image: "", + ImagePullPolicy: "", + Env: nil, + Resources: nil, + }, + existingDevWorkspaceConfig: &controllerv1alpha1.ProjectCloneConfig{ + Image: "other image", + ImagePullPolicy: "Always", + Env: []corev1.EnvVar{ + {Name: "other-env", Value: "other-val"}, + }, + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1234Mi"), + corev1.ResourceCPU: resource.MustParse("1234m"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1111Mi"), + corev1.ResourceCPU: resource.MustParse("1111m"), + }, + }, + }, + }, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + cheCluster := &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + ProjectCloneContainer: testCase.cheProjectCloneConfig, + }, + }, + } + existingDWOC := &controllerv1alpha1.DevWorkspaceOperatorConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: devWorkspaceConfigName, + Namespace: testNamespace, + }, + Config: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + ProjectCloneConfig: testCase.existingDevWorkspaceConfig, + }, + }, + } + runtimeDWOC := runtime.Object(existingDWOC) + + deployContext := test.GetDeployContext(cheCluster, []runtime.Object{runtimeDWOC}) + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + + devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() + _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) + assert.NoError(t, err) + + dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} + err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testNamespace}, dwoc) + assert.NoError(t, err) + + diff := cmp.Diff(testCase.expectedDevWorkspaceConfig, dwoc.Config.Workspace.ProjectCloneConfig) + assert.Empty(t, diff) + }) + } + +} diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go index 692687bb4..31bc96e47 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go @@ -62,76 +62,10 @@ type RoutingConfig struct { ProxyConfig *Proxy `json:"proxyConfig,omitempty"` } -type Proxy struct { - // HttpProxy is the URL of the proxy for HTTP requests, in the format http://USERNAME:PASSWORD@SERVER:PORT/ - HttpProxy string `json:"httpProxy,omitempty"` - // HttpsProxy is the URL of the proxy for HTTPS requests, in the format http://USERNAME:PASSWORD@SERVER:PORT/ - HttpsProxy string `json:"httpsProxy,omitempty"` - // NoProxy is a comma-separated list of hostnames and/or CIDRs for which the proxy should not be used. Ignored - // when HttpProxy and HttpsProxy are unset - NoProxy string `json:"noProxy,omitempty"` -} - -type StorageSizes struct { - // The default Persistent Volume Claim size for the "common" storage class. - // Note that the "async" storage class also uses the PVC size set for the "common" storage class. - // If not specified, the "common" and "async" Persistent Volume Claim sizes are set to 10Gi - Common *resource.Quantity `json:"common,omitempty"` - // The default Persistent Volume Claim size for the "per-workspace" storage class. - // If not specified, the "per-workspace" Persistent Volume Claim size is set to 5Gi - PerWorkspace *resource.Quantity `json:"perWorkspace,omitempty"` -} - -type ServiceAccountConfig struct { - // ServiceAccountName defines a fixed name to be used for all DevWorkspaces. If set, the DevWorkspace - // Operator will not generate a separate ServiceAccount for each DevWorkspace, and will instead create - // a ServiceAccount with the specified name in each namespace where DevWorkspaces are created. If specified, - // the created ServiceAccount will not be removed when DevWorkspaces are deleted and must be cleaned up manually. - // +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - // +kubebuilder:validation:MaxLength=63 - ServiceAccountName string `json:"serviceAccountName,omitempty"` - // Disable creation of DevWorkspace ServiceAccounts by the DevWorkspace Operator. If set to true, the serviceAccountName - // field must also be set. If ServiceAccount creation is disabled, it is assumed that the specified ServiceAccount already - // exists in any namespace where a workspace is created. If a suitable ServiceAccount does not exist, starting DevWorkspaces - // will fail. - DisableCreation *bool `json:"disableCreation,omitempty"` - // List of ServiceAccount tokens that will be mounted into workspace pods as projected volumes. - ServiceAccountTokens []ServiceAccountToken `json:"serviceAccountTokens,omitempty"` -} - -type ServiceAccountToken struct { - // Identifiable name of the ServiceAccount token. - // If multiple ServiceAccount tokens use the same mount path, a generic name will be used - // for the projected volume instead. - // +kubebuilder:validation:Required - Name string `json:"name"` - // Path within the workspace container at which the token should be mounted. Must - // not contain ':'. - // +kubebuilder:validation:Required - MountPath string `json:"mountPath"` - // Path is the path relative to the mount point of the file to project the - // token into. - // +kubebuilder:validation:Required - Path string `json:"path"` - // Audience is the intended audience of the token. A recipient of a token - // must identify itself with an identifier specified in the audience of the - // token, and otherwise should reject the token. The audience defaults to the - // identifier of the apiserver. - // +kubebuilder:validation:Optional - Audience string `json:"audience,omitempty"` - // ExpirationSeconds is the requested duration of validity of the service - // account token. As the token approaches expiration, the kubelet volume - // plugin will proactively rotate the service account token. The kubelet will - // start trying to rotate the token if the token is older than 80 percent of - // its time to live or if the token is older than 24 hours. Defaults to 1 hour - // and must be at least 10 minutes. - // +kubebuilder:validation:Minimum=600 - // +kubebuilder:default:=3600 - // +kubebuilder:validation:Optional - ExpirationSeconds int64 `json:"expirationSeconds,omitempty"` -} - type WorkspaceConfig struct { + // ProjectCloneConfig defines configuration related to the project clone init container + // that is used to clone git projects into the DevWorkspace. + ProjectCloneConfig *ProjectCloneConfig `json:"projectClone,omitempty"` // ImagePullPolicy defines the imagePullPolicy used for containers in a DevWorkspace // For additional information, see Kubernetes documentation for imagePullPolicy. If // not specified, the default value of "Always" is used. @@ -203,6 +137,89 @@ type WorkspaceConfig struct { SchedulerName string `json:"schedulerName,omitempty"` } +type Proxy struct { + // HttpProxy is the URL of the proxy for HTTP requests, in the format http://USERNAME:PASSWORD@SERVER:PORT/ + HttpProxy string `json:"httpProxy,omitempty"` + // HttpsProxy is the URL of the proxy for HTTPS requests, in the format http://USERNAME:PASSWORD@SERVER:PORT/ + HttpsProxy string `json:"httpsProxy,omitempty"` + // NoProxy is a comma-separated list of hostnames and/or CIDRs for which the proxy should not be used. Ignored + // when HttpProxy and HttpsProxy are unset + NoProxy string `json:"noProxy,omitempty"` +} + +type StorageSizes struct { + // The default Persistent Volume Claim size for the "common" storage class. + // Note that the "async" storage class also uses the PVC size set for the "common" storage class. + // If not specified, the "common" and "async" Persistent Volume Claim sizes are set to 10Gi + Common *resource.Quantity `json:"common,omitempty"` + // The default Persistent Volume Claim size for the "per-workspace" storage class. + // If not specified, the "per-workspace" Persistent Volume Claim size is set to 5Gi + PerWorkspace *resource.Quantity `json:"perWorkspace,omitempty"` +} + +type ServiceAccountConfig struct { + // ServiceAccountName defines a fixed name to be used for all DevWorkspaces. If set, the DevWorkspace + // Operator will not generate a separate ServiceAccount for each DevWorkspace, and will instead create + // a ServiceAccount with the specified name in each namespace where DevWorkspaces are created. If specified, + // the created ServiceAccount will not be removed when DevWorkspaces are deleted and must be cleaned up manually. + // +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + // +kubebuilder:validation:MaxLength=63 + ServiceAccountName string `json:"serviceAccountName,omitempty"` + // Disable creation of DevWorkspace ServiceAccounts by the DevWorkspace Operator. If set to true, the serviceAccountName + // field must also be set. If ServiceAccount creation is disabled, it is assumed that the specified ServiceAccount already + // exists in any namespace where a workspace is created. If a suitable ServiceAccount does not exist, starting DevWorkspaces + // will fail. + DisableCreation *bool `json:"disableCreation,omitempty"` + // List of ServiceAccount tokens that will be mounted into workspace pods as projected volumes. + ServiceAccountTokens []ServiceAccountToken `json:"serviceAccountTokens,omitempty"` +} + +type ServiceAccountToken struct { + // Identifiable name of the ServiceAccount token. + // If multiple ServiceAccount tokens use the same mount path, a generic name will be used + // for the projected volume instead. + // +kubebuilder:validation:Required + Name string `json:"name"` + // Path within the workspace container at which the token should be mounted. Must + // not contain ':'. + // +kubebuilder:validation:Required + MountPath string `json:"mountPath"` + // Path is the path relative to the mount point of the file to project the + // token into. + // +kubebuilder:validation:Required + Path string `json:"path"` + // Audience is the intended audience of the token. A recipient of a token + // must identify itself with an identifier specified in the audience of the + // token, and otherwise should reject the token. The audience defaults to the + // identifier of the apiserver. + // +kubebuilder:validation:Optional + Audience string `json:"audience,omitempty"` + // ExpirationSeconds is the requested duration of validity of the service + // account token. As the token approaches expiration, the kubelet volume + // plugin will proactively rotate the service account token. The kubelet will + // start trying to rotate the token if the token is older than 80 percent of + // its time to live or if the token is older than 24 hours. Defaults to 1 hour + // and must be at least 10 minutes. + // +kubebuilder:validation:Minimum=600 + // +kubebuilder:default:=3600 + // +kubebuilder:validation:Optional + ExpirationSeconds int64 `json:"expirationSeconds,omitempty"` +} + +type ProjectCloneConfig struct { + // Image is the container image to use for cloning projects + Image string `json:"image,omitempty"` + // ImagePullPolicy configures the imagePullPolicy for the project clone container. + // If undefined, the general setting .config.workspace.imagePullPolicy is used instead. + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + // Resources defines the resource (cpu, memory) limits and requests for the project + // clone container. To explicitly not specify a limit or request, define the resource + // quantity as zero ('0') + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + // Env allows defining additional environment variables for the project clone container. + Env []corev1.EnvVar `json:"env,omitempty"` +} + // DevWorkspaceOperatorConfig is the Schema for the devworkspaceoperatorconfigs API // +kubebuilder:object:root=true // +kubebuilder:resource:path=devworkspaceoperatorconfigs,scope=Namespaced,shortName=dwoc diff --git a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go index 8cf65ffff..24a97d005 100644 --- a/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/devfile/devworkspace-operator/apis/controller/v1alpha1/zz_generated.deepcopy.go @@ -444,6 +444,33 @@ func (in *PodAdditions) DeepCopy() *PodAdditions { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectCloneConfig) DeepCopyInto(out *ProjectCloneConfig) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectCloneConfig. +func (in *ProjectCloneConfig) DeepCopy() *ProjectCloneConfig { + if in == nil { + return nil + } + out := new(ProjectCloneConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Proxy) DeepCopyInto(out *Proxy) { *out = *in @@ -547,6 +574,11 @@ func (in *StorageSizes) DeepCopy() *StorageSizes { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WorkspaceConfig) DeepCopyInto(out *WorkspaceConfig) { *out = *in + if in.ProjectCloneConfig != nil { + in, out := &in.ProjectCloneConfig, &out.ProjectCloneConfig + *out = new(ProjectCloneConfig) + (*in).DeepCopyInto(*out) + } if in.ServiceAccount != nil { in, out := &in.ServiceAccount, &out.ServiceAccount *out = new(ServiceAccountConfig) diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go index 05d13e92d..c145dea3b 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/defaults.go @@ -49,6 +49,18 @@ var defaultConfig = &v1alpha1.OperatorConfiguration{ PodSecurityContext: nil, ContainerSecurityContext: &corev1.SecurityContext{}, DefaultTemplate: nil, + ProjectCloneConfig: &v1alpha1.ProjectCloneConfig{ + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + corev1.ResourceCPU: resource.MustParse("1000m"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("128Mi"), + corev1.ResourceCPU: resource.MustParse("100m"), + }, + }, + }, }, } diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go b/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go index 7b66ef60d..51ff528ec 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/config/sync.go @@ -334,6 +334,29 @@ func mergeConfig(from, to *controller.OperatorConfiguration) { if from.Workspace.SchedulerName != "" { to.Workspace.SchedulerName = from.Workspace.SchedulerName } + if from.Workspace.ProjectCloneConfig != nil { + if to.Workspace.ProjectCloneConfig == nil { + to.Workspace.ProjectCloneConfig = &controller.ProjectCloneConfig{} + } + if from.Workspace.ProjectCloneConfig.Image != "" { + to.Workspace.ProjectCloneConfig.Image = from.Workspace.ProjectCloneConfig.Image + } + if from.Workspace.ProjectCloneConfig.ImagePullPolicy != "" { + to.Workspace.ProjectCloneConfig.ImagePullPolicy = from.Workspace.ProjectCloneConfig.ImagePullPolicy + } + if from.Workspace.ProjectCloneConfig.Resources != nil { + if to.Workspace.ProjectCloneConfig.Resources == nil { + to.Workspace.ProjectCloneConfig.Resources = &corev1.ResourceRequirements{} + } + to.Workspace.ProjectCloneConfig.Resources = mergeResources(from.Workspace.ProjectCloneConfig.Resources, to.Workspace.ProjectCloneConfig.Resources) + } + + // Overwrite env instead of trying to merge, don't want to bother merging lists when + // the default is empty + if from.Workspace.ProjectCloneConfig.Env != nil { + to.Workspace.ProjectCloneConfig.Env = from.Workspace.ProjectCloneConfig.Env + } + } } } @@ -385,6 +408,33 @@ func mergeContainerSecurityContext(base, patch *corev1.SecurityContext) *corev1. return patched } +func mergeResources(from, to *corev1.ResourceRequirements) *corev1.ResourceRequirements { + result := to.DeepCopy() + if from.Limits != nil { + if result.Limits == nil { + result.Limits = corev1.ResourceList{} + } + if cpu, ok := from.Limits[corev1.ResourceCPU]; ok { + result.Limits[corev1.ResourceCPU] = cpu + } + if memory, ok := from.Limits[corev1.ResourceMemory]; ok { + result.Limits[corev1.ResourceMemory] = memory + } + } + if from.Requests != nil { + if result.Requests == nil { + result.Requests = corev1.ResourceList{} + } + if cpu, ok := from.Requests[corev1.ResourceCPU]; ok { + result.Requests[corev1.ResourceCPU] = cpu + } + if memory, ok := from.Requests[corev1.ResourceMemory]; ok { + result.Requests[corev1.ResourceMemory] = memory + } + } + return result +} + func GetCurrentConfigString(currConfig *controller.OperatorConfiguration) string { if currConfig == nil { return "" @@ -462,6 +512,20 @@ func GetCurrentConfigString(currConfig *controller.OperatorConfiguration) string if workspace.SchedulerName != "" { config = append(config, fmt.Sprintf("workspace.schedulerName=%s", workspace.SchedulerName)) } + if workspace.ProjectCloneConfig != nil { + if workspace.ProjectCloneConfig.Image != defaultConfig.Workspace.ProjectCloneConfig.Image { + config = append(config, fmt.Sprintf("workspace.projectClone.image=%s", workspace.ProjectCloneConfig.Image)) + } + if workspace.ProjectCloneConfig.ImagePullPolicy != defaultConfig.Workspace.ProjectCloneConfig.ImagePullPolicy { + config = append(config, fmt.Sprintf("workspace.projectClone.imagePullPolicy=%s", workspace.ProjectCloneConfig.ImagePullPolicy)) + } + if workspace.ProjectCloneConfig.Env != nil { + config = append(config, "workspace.projectClone.env is set") + } + if !reflect.DeepEqual(workspace.ProjectCloneConfig.Resources, defaultConfig.Workspace.ProjectCloneConfig.Resources) { + config = append(config, "workspace.projectClone.resources is set") + } + } } if currConfig.EnableExperimentalFeatures != nil && *currConfig.EnableExperimentalFeatures { config = append(config, "enableExperimentalFeatures=true") diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go index 9660bc5ae..71659976c 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go @@ -65,12 +65,6 @@ const ( // PVCCleanupPodCPURequest is the cpu request used for PVC clean up pods PVCCleanupPodCPURequest = "5m" - // Resource limits/requests for project cloner init container - ProjectCloneMemoryLimit = "1Gi" - ProjectCloneMemoryRequest = "128Mi" - ProjectCloneCPULimit = "1000m" - ProjectCloneCPURequest = "100m" - // Constants describing storage classes supported by the controller // CommonStorageClassType defines the 'common' storage policy, which is an alias of the 'per-user' storage policy, and operates in the same fashion as the 'per-user' storage policy. diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go index 62ad02d5b..e0ff5a7c4 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/provision/sync/sync.go @@ -200,17 +200,19 @@ func printDiff(specObj, clusterObj crclient.Object, log logr.Logger) { diffOpts = podDiffOpts case *corev1.ConfigMap: diffOpts = configmapDiffOpts - case *corev1.Secret: - diffOpts = secretDiffOpts case *v1alpha1.DevWorkspaceRouting: diffOpts = routingDiffOpts case *networkingv1.Ingress: diffOpts = ingressDiffOpts case *routev1.Route: diffOpts = routeDiffOpts + case *corev1.Secret: + log.Info(fmt.Sprintf("Diff: secret %s data upated", specObj.GetName())) + return default: diffOpts = nil } + log.Info(fmt.Sprintf("Diff: %s", cmp.Diff(specObj, clusterObj, diffOpts))) } } diff --git a/vendor/modules.txt b/vendor/modules.txt index b3d99ae00..cad42123e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -32,7 +32,7 @@ github.com/davecgh/go-spew/spew github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2 github.com/devfile/api/v2/pkg/attributes github.com/devfile/api/v2/pkg/devfile -# github.com/devfile/devworkspace-operator v0.20.0 +# github.com/devfile/devworkspace-operator v0.21.0 ## explicit; go 1.18 github.com/devfile/devworkspace-operator/apis/controller/v1alpha1 github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting