From 4bacfff7295b55c7c3ed64ddd6df5a88c380a9ed Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 13 Sep 2024 17:48:22 -0400 Subject: [PATCH] feat: implement devEnvironments.runtimeClassName field Signed-off-by: admin --- api/v2/checluster_types.go | 3 + api/v2/zz_generated.deepcopy.go | 5 + .../org.eclipse.che_checlusters.yaml | 4 + .../bases/org.eclipse.che_checlusters.yaml | 4 + deploy/deployment/kubernetes/combined.yaml | 4 + ....eclipse.che.CustomResourceDefinition.yaml | 4 + deploy/deployment/openshift/combined.yaml | 4 + ....eclipse.che.CustomResourceDefinition.yaml | 4 + ....eclipse.che.CustomResourceDefinition.yaml | 4 + .../dev_workspace_config.go | 6 + .../dev_workspace_config_test.go | 148 ++++++++++++++++++ 11 files changed, 190 insertions(+) diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index 97d7f69cf..027700166 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -155,6 +155,9 @@ type CheClusterDevEnvironments struct { // If not specified, the pod scheduler is set to the default scheduler on the cluster. // +optional PodSchedulerName string `json:"podSchedulerName,omitempty"` + // RuntimeClassName specifies the spec.runtimeClassName for workspace pods. + // +optional + RuntimeClassName *string `json:"runtimeClassName,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. diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 81521752e..1eb3efc63 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -302,6 +302,11 @@ func (in *CheClusterDevEnvironments) DeepCopyInto(out *CheClusterDevEnvironments *out = make([]v1alpha1.ServiceAccountToken, len(*in)) copy(*out, *in) } + if in.RuntimeClassName != nil { + in, out := &in.RuntimeClassName, &out.RuntimeClassName + *out = new(string) + **out = **in + } if in.StartTimeoutSeconds != nil { in, out := &in.StartTimeoutSeconds, &out.StartTimeoutSeconds *out = new(int32) 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 b6ade78bd..3aa7805e8 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -7289,6 +7289,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index bf85fc942..8fac423ca 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -7241,6 +7241,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index 6f8a640c7..ca83b58f0 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -7262,6 +7262,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- 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 7c8d50e88..a6ef8ccf8 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -7257,6 +7257,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 51c8988df..5d092117e 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -7262,6 +7262,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- 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 8a2873855..9fe2d88d2 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -7257,6 +7257,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 7c8d50e88..a6ef8ccf8 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -7257,6 +7257,10 @@ spec: type: object type: object type: object + runtimeClassName: + description: RuntimeClassName specifies the spec.runtimeClassName + for workspace pods. + type: string secondsOfInactivityBeforeIdling: default: 1800 description: |- diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config.go b/pkg/deploy/dev-workspace-config/dev_workspace_config.go index c314ade7b..c2ae4dd04 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config.go @@ -93,6 +93,8 @@ func updateWorkspaceConfig(ctx *chetypes.DeployContext, operatorConfig *controll updateWorkspacePodSchedulerNameConfig(devEnvironments, operatorConfig.Workspace) + updateWorkspaceRuntimeClassNameConfig(devEnvironments, operatorConfig.Workspace) + updateProjectCloneConfig(devEnvironments, operatorConfig.Workspace) if err := updateSecurityContext(operatorConfig, cheCluster); err != nil { @@ -222,6 +224,10 @@ func updateWorkspacePodSchedulerNameConfig(devEnvironments *chev2.CheClusterDevE workspaceConfig.SchedulerName = devEnvironments.PodSchedulerName } +func updateWorkspaceRuntimeClassNameConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) { + workspaceConfig.RuntimeClassName = devEnvironments.RuntimeClassName +} + func updateProjectCloneConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) { if devEnvironments.ProjectCloneContainer == nil { workspaceConfig.ProjectCloneConfig = nil 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 1fbb28172..9ba81f832 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go @@ -978,6 +978,154 @@ func TestReconcileDevWorkspaceConfigPodSchedulerName(t *testing.T) { } } +func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { + type testCase struct { + name string + cheCluster *chev2.CheCluster + existedObjects []runtime.Object + expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration + } + + var testCases = []testCase{ + { + name: "Create DevWorkspaceOperatorConfig with RuntimeClassName", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + RuntimeClassName: pointer.StringPtr("test-runtime-class"), + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + RuntimeClassName: pointer.StringPtr("test-runtime-class"), + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig when RuntimeClassName is added", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + RuntimeClassName: pointer.StringPtr("test-runtime-class"), + }, + }, + }, + existedObjects: []runtime.Object{ + &controllerv1alpha1.DevWorkspaceOperatorConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: devWorkspaceConfigName, + Namespace: "eclipse-che", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "DevWorkspaceOperatorConfig", + APIVersion: controllerv1alpha1.GroupVersion.String(), + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + RuntimeClassName: pointer.StringPtr("test-runtime-class"), + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig when RuntimeClassName is changed", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + RuntimeClassName: pointer.StringPtr("test-runtime-class"), + }, + }, + }, + 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{ + RuntimeClassName: pointer.StringPtr("previous-runtime-class"), + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{ + RuntimeClassName: pointer.StringPtr("test-runtime-class"), + }, + }, + }, + { + name: "Update existing DevWorkspaceOperatorConfig when RuntimeClassName is removed", + cheCluster: &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + DevEnvironments: chev2.CheClusterDevEnvironments{ + RuntimeClassName: nil, + }, + }, + }, + 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{ + RuntimeClassName: pointer.StringPtr("previous-runtime-class"), + }, + }, + }, + }, + expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ + Workspace: &controllerv1alpha1.WorkspaceConfig{}, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + 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: testCase.cheCluster.Namespace}, dwoc) + assert.NoError(t, err) + assert.Equal(t, testCase.expectedOperatorConfig.Workspace.SchedulerName, dwoc.Config.Workspace.SchedulerName) + }) + } +} + func TestReconcileDevWorkspaceConfigServiceAccountTokens(t *testing.T) { type testCase struct { name string