diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index dd97b894a..3b56feee3 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -37,7 +37,7 @@ type CheClusterSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,order=1 // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Development environments" - // +kubebuilder:default:={disableContainerBuildCapabilities: true, defaultComponents: {{name: universal-developer-image, container: {image: "quay.io/devfile/universal-developer-image:ubi8-38da5c2"}}}, defaultEditor: che-incubator/che-code/insiders, storage: {pvcStrategy: per-user}, defaultNamespace: {template: -che, autoProvision: true}, secondsOfInactivityBeforeIdling:1800, secondsOfRunBeforeIdling:-1} + // +kubebuilder:default:={disableContainerBuildCapabilities: true, defaultComponents: {{name: universal-developer-image, container: {image: "quay.io/devfile/universal-developer-image:ubi8-38da5c2"}}}, defaultEditor: che-incubator/che-code/insiders, storage: {pvcStrategy: per-user}, defaultNamespace: {template: -che, autoProvision: true}, secondsOfInactivityBeforeIdling:1800, secondsOfRunBeforeIdling:-1, startTimeoutSeconds:300} DevEnvironments CheClusterDevEnvironments `json:"devEnvironments"` // Che components configuration. // +optional @@ -123,6 +123,13 @@ type CheClusterDevEnvironments struct { // If not specified, the pod scheduler is set to the default scheduler on the cluster. // +optional PodSchedulerName string `json:"podSchedulerName,omitempty"` + // StartTimeoutSeconds determines the maximum duration (in seconds) that a workspace can take to start + // before it is automatically failed. + // If not specified, the default value of 300 seconds (5 minutes) is used. + // +optional + // +kubebuilder:validation:Minimum:=1 + // +kubebuilder:default:=300 + StartTimeoutSeconds *int32 `json:"startTimeoutSeconds,omitempty"` } // Che components configuration. diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 32dd1747f..684511c0c 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -187,6 +187,11 @@ func (in *CheClusterDevEnvironments) DeepCopyInto(out *CheClusterDevEnvironments *out = new(ContainerBuildConfiguration) **out = **in } + if in.StartTimeoutSeconds != nil { + in, out := &in.StartTimeoutSeconds, &out.StartTimeoutSeconds + *out = new(int32) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheClusterDevEnvironments. diff --git a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml index 5cb266f8b..ee2f29b22 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.59.0-742.next + name: eclipse-che.v7.59.0-744.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1233,7 +1233,7 @@ spec: minKubeVersion: 1.19.0 provider: name: Eclipse Foundation - version: 7.59.0-742.next + version: 7.59.0-744.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 1da854e54..77f5cc758 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -5410,6 +5410,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -7005,6 +7006,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it + is automatically failed. If not specified, the default value + of 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index cb199aa91..8a1b9c9db 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -5271,6 +5271,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -6815,6 +6816,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it is + automatically failed. If not specified, the default value of + 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index 576e5ba53..e6a1c531a 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -5290,6 +5290,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -6834,6 +6835,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it is + automatically failed. If not specified, the default value of + 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user 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 9e4495600..36ae158e7 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -5285,6 +5285,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -6829,6 +6830,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it is + automatically failed. If not specified, the default value of + 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 811ad0566..c6c8fed41 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -5290,6 +5290,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -6834,6 +6835,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it is + automatically failed. If not specified, the default value of + 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user 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 78ebef595..0cccc888d 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -5285,6 +5285,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -6829,6 +6830,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it is + automatically failed. If not specified, the default value of + 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 9e4495600..36ae158e7 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -5285,6 +5285,7 @@ spec: disableContainerBuildCapabilities: true secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 + startTimeoutSeconds: 300 storage: pvcStrategy: per-user description: Development environment default configuration options. @@ -6829,6 +6830,15 @@ spec: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + startTimeoutSeconds: + default: 300 + description: StartTimeoutSeconds determines the maximum duration + (in seconds) that a workspace can take to start before it is + automatically failed. If not specified, the default value of + 300 seconds (5 minutes) is used. + format: int32 + minimum: 1 + type: integer storage: default: pvcStrategy: per-user diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index 87e3d372c..92114b764 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -12,6 +12,11 @@ package constants +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/utils/pointer" +) + const ( // PostgresSQL DefaultPostgresUser = "pgche" @@ -139,4 +144,14 @@ var ( "app": "che", "component": "che-gateway-config", } + + DefaultWorkspaceContainerSecurityContext = corev1.SecurityContext{ + Capabilities: &corev1.Capabilities{ + Add: []corev1.Capability{ + "SETGID", + "SETUID", + }, + }, + AllowPrivilegeEscalation: pointer.BoolPtr(false), + } ) diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config.go b/pkg/deploy/dev-workspace-config/dev_workspace_config.go index a07077171..94d461b4f 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config.go @@ -12,6 +12,8 @@ package devworkspaceconfig import ( + "fmt" + controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/chetypes" @@ -56,7 +58,7 @@ func (d *DevWorkspaceConfigReconciler) Reconcile(ctx *chetypes.DeployContext) (r dwoc.Config = &controllerv1alpha1.OperatorConfiguration{} } - if err := updateWorkspaceConfig(&ctx.CheCluster.Spec.DevEnvironments, dwoc.Config); err != nil { + if err := updateWorkspaceConfig(ctx.CheCluster, dwoc.Config); err != nil { return reconcile.Result{}, false, err } @@ -71,7 +73,8 @@ func (d *DevWorkspaceConfigReconciler) Finalize(ctx *chetypes.DeployContext) boo return true } -func updateWorkspaceConfig(devEnvironments *chev2.CheClusterDevEnvironments, operatorConfig *controllerv1alpha1.OperatorConfiguration) error { +func updateWorkspaceConfig(cheCluster *chev2.CheCluster, operatorConfig *controllerv1alpha1.OperatorConfiguration) error { + devEnvironments := &cheCluster.Spec.DevEnvironments if operatorConfig.Workspace == nil { operatorConfig.Workspace = &controllerv1alpha1.WorkspaceConfig{} } @@ -88,9 +91,24 @@ func updateWorkspaceConfig(devEnvironments *chev2.CheClusterDevEnvironments, ope return err } + operatorConfig.Workspace.ContainerSecurityContext = nil + if cheCluster.IsContainerBuildCapabilitiesEnabled() { + operatorConfig.Workspace.ContainerSecurityContext = constants.DefaultWorkspaceContainerSecurityContext.DeepCopy() + } + + updateStartTimeout(operatorConfig, devEnvironments.StartTimeoutSeconds) return nil } +func updateStartTimeout(operatorConfig *controllerv1alpha1.OperatorConfiguration, startTimeoutSeconds *int32) { + if startTimeoutSeconds == nil { + // Allow the default start timeout of 5 minutes to be used if devEnvironments.StartTimeoutSeconds is unset + operatorConfig.Workspace.ProgressTimeout = "" + } else { + operatorConfig.Workspace.ProgressTimeout = fmt.Sprintf("%ds", *startTimeoutSeconds) + } +} + func updateWorkspaceStorageConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) error { pvcStrategy := utils.GetValue(devEnvironments.Storage.PvcStrategy, constants.DefaultPvcStorageStrategy) isPerWorkspacePVCStorageStrategy := pvcStrategy == constants.PerWorkspacePVCStorageStrategy 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 5129b89f6..fb8118cfc 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go @@ -17,6 +17,7 @@ import ( "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" @@ -325,7 +326,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { DefaultRoutingClass: "routing-class", }, Workspace: &controllerv1alpha1.WorkspaceConfig{ - ProgressTimeout: "10s", + ImagePullPolicy: "Always", }, }, }, @@ -335,7 +336,7 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { DefaultRoutingClass: "routing-class", }, Workspace: &controllerv1alpha1.WorkspaceConfig{ - ProgressTimeout: "10s", + ImagePullPolicy: "Always", StorageClassName: pointer.StringPtr("test-storage"), DefaultStorageSize: &controllerv1alpha1.StorageSizes{ Common: &quantity15Gi, @@ -343,6 +344,291 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) { }, }, }, + { + name: "Create DevWorkspaceOperatorConfig without Pod Security Context if container build disabled", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.BoolPtr(true), + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{}, + }, + }, + { + name: "Create DevWorkspaceOperatorConfig with Pod and Container Security Context if container build enabled", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.BoolPtr(false), + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + ContainerSecurityContext: &corev1.SecurityContext{ + Capabilities: &corev1.Capabilities{ + Add: []corev1.Capability{ + "SETGID", + "SETUID", + }, + }, + AllowPrivilegeEscalation: pointer.BoolPtr(false), + }, + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig by adding Pod and Container Security Context", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.BoolPtr(false), + }, + }, + }, + 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.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ContainerSecurityContext: &corev1.SecurityContext{ + Capabilities: &corev1.Capabilities{ + Add: []corev1.Capability{ + "SETGID", + "SETUID", + }, + }, + AllowPrivilegeEscalation: pointer.BoolPtr(false), + }, + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig by removing Pod and Container Security Context", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + DisableContainerBuildCapabilities: pointer.BoolPtr(true), + }, + }, + }, + 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.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ContainerSecurityContext: &corev1.SecurityContext{}, + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + }, + }, + }, + { + name: "Create DevWorkspaceOperatorConfig with progressTimeout", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + StartTimeoutSeconds: pointer.Int32Ptr(600), + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + ProgressTimeout: "600s", + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig by adding progressTimeout", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "eclipse-che", + Namespace: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + StartTimeoutSeconds: pointer.Int32Ptr(600), + }, + }, + }, + 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.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ProgressTimeout: "600s", + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig by overwriting progressTimeout", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + StartTimeoutSeconds: pointer.Int32Ptr(420), + }, + }, + }, + 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.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ProgressTimeout: "1h30m", + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ProgressTimeout: "420s", + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig by removing progressTimeout", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{}, + }, + }, + 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.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + ProgressTimeout: "1h30m", + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + StorageClassName: pointer.StringPtr("default-storage-class"), + DefaultStorageSize: &controllerv1alpha1.StorageSizes{ + Common: &quantity10Gi, + }, + }, + }, + }, } for _, testCase := range testCases {