Skip to content

Commit

Permalink
feat: implement secondsOfInactivityBeforeIdling and secondsOfRunBefor…
Browse files Browse the repository at this point in the history
…eIdling CR config

Signed-off-by: David Kwon <dakwon@redhat.com>
  • Loading branch information
dkwon17 committed Jul 12, 2022
1 parent c4b3481 commit 020efca
Show file tree
Hide file tree
Showing 18 changed files with 288 additions and 6 deletions.
4 changes: 4 additions & 0 deletions api/checluster_conversion_from_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,8 @@ func TestConvertFrom(t *testing.T) {
Value: "Value",
Effect: "Effect",
}},
SecondsOfInactivityBeforeIdling: pointer.Int32Ptr(900),
SecondsOfRunBeforeIdling: pointer.Int32Ptr(-1),
},
ContainerRegistry: chev2.CheClusterContainerRegistry{
Hostname: "AirGapContainerRegistryHostname",
Expand Down Expand Up @@ -405,6 +407,8 @@ func TestConvertFrom(t *testing.T) {

assert.Equal(t, checlusterv1.Spec.DevWorkspace.ControllerImage, "DevWorkspaceImage")
assert.Equal(t, checlusterv1.Spec.DevWorkspace.RunningLimit, "RunningLimit")
assert.Equal(t, checlusterv1.Spec.DevWorkspace.SecondsOfInactivityBeforeIdling, pointer.Int32Ptr(900))
assert.Equal(t, checlusterv1.Spec.DevWorkspace.SecondsOfRunBeforeIdling, pointer.Int32Ptr(-1))
assert.True(t, checlusterv1.Spec.DevWorkspace.Enable)

assert.Equal(t, checlusterv1.Spec.Dashboard.Warning, "DashboardWarning")
Expand Down
11 changes: 8 additions & 3 deletions api/checluster_conversion_to_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"testing"

"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/utils/pointer"

devfile "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/devworkspace-operator/pkg/infrastructure"
Expand Down Expand Up @@ -274,9 +275,11 @@ func TestConvertTo(t *testing.T) {
Enable: true,
},
DevWorkspace: chev1.CheClusterSpecDevWorkspace{
Enable: true,
ControllerImage: "ControllerImage",
RunningLimit: "RunningLimit",
Enable: true,
ControllerImage: "ControllerImage",
RunningLimit: "RunningLimit",
SecondsOfInactivityBeforeIdling: pointer.Int32Ptr(900),
SecondsOfRunBeforeIdling: pointer.Int32Ptr(-1),
},
Dashboard: chev1.CheClusterSpecDashboard{
Warning: "DashboardWarning",
Expand Down Expand Up @@ -413,6 +416,8 @@ func TestConvertTo(t *testing.T) {
assert.Equal(t, checlusterv2.Spec.DevEnvironments.Storage.Pvc.ClaimSize, "WorkspacePvcClaimSize")
assert.Equal(t, checlusterv2.Spec.DevEnvironments.Storage.Pvc.StorageClass, "WorkspacePVCStorageClassName")
assert.Equal(t, checlusterv2.Spec.DevEnvironments.Storage.PvcStrategy, "PvcStrategy")
assert.Equal(t, checlusterv2.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling, pointer.Int32Ptr(900))
assert.Equal(t, checlusterv2.Spec.DevEnvironments.SecondsOfRunBeforeIdling, pointer.Int32Ptr(-1))

assert.Equal(t, checlusterv2.Status.CheURL, "CheURL")
assert.Equal(t, checlusterv2.Status.CheVersion, "CheVersion")
Expand Down
2 changes: 2 additions & 0 deletions api/v1/checluster_conversion_from.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ func (dst *CheCluster) convertFrom_DevWorkspace(src *chev2.CheCluster) error {
}

dst.Spec.DevWorkspace.RunningLimit = src.Spec.Components.DevWorkspace.RunningLimit
dst.Spec.DevWorkspace.SecondsOfInactivityBeforeIdling = src.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling
dst.Spec.DevWorkspace.SecondsOfRunBeforeIdling = src.Spec.DevEnvironments.SecondsOfRunBeforeIdling
dst.Spec.DevWorkspace.Enable = true
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions api/v1/checluster_conversion_to.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ func (src *CheCluster) convertTo_DevEnvironments(dst *chev2.CheCluster) error {

dst.Spec.DevEnvironments.DefaultEditor = src.Spec.Server.WorkspaceDefaultEditor
dst.Spec.DevEnvironments.DefaultComponents = src.Spec.Server.WorkspaceDefaultComponents
dst.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling = src.Spec.DevWorkspace.SecondsOfInactivityBeforeIdling
dst.Spec.DevEnvironments.SecondsOfRunBeforeIdling = src.Spec.DevWorkspace.SecondsOfRunBeforeIdling

if err := src.convertTo_Workspaces_Storage(dst); err != nil {
return err
Expand Down
10 changes: 10 additions & 0 deletions api/v1/checluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,16 @@ type CheClusterSpecDevWorkspace struct {
// Maximum number of the running workspaces per user.
// +optional
RunningLimit string `json:"runningLimit,omitempty"`
// Idle timeout for workspaces in seconds.
// This timeout is the duration after which a workspace will be idled if there is no activity.
// To disable workspace idling due to inactivity, set this value to -1.
// +kubebuilder:default:=900
SecondsOfInactivityBeforeIdling *int32 `json:"secondsOfInactivityBeforeIdling,omitempty"`
// Run timeout for workspaces in seconds.
// This timeout is the maximum duration a workspace runs.
// To disable workspace run timeout, set this value to -1.
// +kubebuilder:default:=-1
SecondsOfRunBeforeIdling *int32 `json:"secondsOfRunBeforeIdling,omitempty"`
}

// +k8s:openapi-gen=true
Expand Down
13 changes: 12 additions & 1 deletion api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions api/v2/checluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ type CheClusterDevEnvironments struct {
// These default components are meant to be used when a Devfile, that does not contain any components.
// +optional
DefaultComponents []devfile.Component `json:"defaultComponents,omitempty"`
// Idle timeout for workspaces in seconds.
// This timeout is the duration after which a workspace will be idled if there is no activity.
// To disable workspace idling due to inactivity, set this value to -1.
// +kubebuilder:default:=900
SecondsOfInactivityBeforeIdling *int32 `json:"secondsOfInactivityBeforeIdling,omitempty"`
// Run timeout for workspaces in seconds.
// This timeout is the maximum duration a workspace runs.
// To disable workspace run timeout, set this value to -1.
// +kubebuilder:default:=-1
SecondsOfRunBeforeIdling *int32 `json:"secondsOfRunBeforeIdling,omitempty"`
}

// Che components configuration.
Expand Down
11 changes: 11 additions & 0 deletions api/v2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,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-preview-openshift.v7.50.0-621.next
name: eclipse-che-preview-openshift.v7.51.0-622.next
namespace: placeholder
spec:
apiservicedefinitions: {}
Expand Down Expand Up @@ -1390,7 +1390,7 @@ spec:
maturity: stable
provider:
name: Eclipse Foundation
version: 7.50.0-621.next
version: 7.51.0-622.next
webhookdefinitions:
- admissionReviewVersions:
- v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,21 @@ spec:
runningLimit:
description: Maximum number of the running workspaces per user.
type: string
secondsOfInactivityBeforeIdling:
default: 900
description: Idle timeout for workspaces in seconds. This timeout
is the duration after which a workspace will be idled if there
is no activity. To disable workspace idling due to inactivity,
set this value to -1.
format: int32
type: integer
secondsOfRunBeforeIdling:
default: -1
description: Run timeout for workspaces in seconds. This timeout
is the maximum duration a workspace runs. To disable workspace
run timeout, set this value to -1.
format: int32
type: integer
required:
- enable
type: object
Expand Down Expand Up @@ -5174,6 +5189,21 @@ spec:
description: The node selector limits the nodes that can run
the workspace pods.
type: object
secondsOfInactivityBeforeIdling:
default: 900
description: Idle timeout for workspaces in seconds. This timeout
is the duration after which a workspace will be idled if there
is no activity. To disable workspace idling due to inactivity,
set this value to -1.
format: int32
type: integer
secondsOfRunBeforeIdling:
default: -1
description: Run timeout for workspaces in seconds. This timeout
is the maximum duration a workspace runs. To disable workspace
run timeout, set this value to -1.
format: int32
type: integer
storage:
default:
pvcStrategy: common
Expand Down
30 changes: 30 additions & 0 deletions config/crd/bases/org.eclipse.che_checlusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,21 @@ spec:
runningLimit:
description: Maximum number of the running workspaces per user.
type: string
secondsOfInactivityBeforeIdling:
default: 900
description: Idle timeout for workspaces in seconds. This timeout
is the duration after which a workspace will be idled if there
is no activity. To disable workspace idling due to inactivity,
set this value to -1.
format: int32
type: integer
secondsOfRunBeforeIdling:
default: -1
description: Run timeout for workspaces in seconds. This timeout
is the maximum duration a workspace runs. To disable workspace
run timeout, set this value to -1.
format: int32
type: integer
required:
- enable
type: object
Expand Down Expand Up @@ -5022,6 +5037,21 @@ spec:
description: The node selector limits the nodes that can run the
workspace pods.
type: object
secondsOfInactivityBeforeIdling:
default: 900
description: Idle timeout for workspaces in seconds. This timeout
is the duration after which a workspace will be idled if there
is no activity. To disable workspace idling due to inactivity,
set this value to -1.
format: int32
type: integer
secondsOfRunBeforeIdling:
default: -1
description: Run timeout for workspaces in seconds. This timeout
is the maximum duration a workspace runs. To disable workspace
run timeout, set this value to -1.
format: int32
type: integer
storage:
default:
pvcStrategy: common
Expand Down
51 changes: 51 additions & 0 deletions controllers/usernamespace/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package usernamespace
import (
"context"
"encoding/json"
"strconv"

"github.com/eclipse-che/che-operator/pkg/common/chetypes"
"github.com/eclipse-che/che-operator/pkg/common/constants"
Expand All @@ -34,6 +35,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/pointer"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/handler"
Expand Down Expand Up @@ -238,6 +240,11 @@ func (r *CheUserNamespaceReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, err
}

if err = r.reconcileIdleSettings(ctx, req.Name, checluster, deployContext); err != nil {
logrus.Errorf("Failed to reconcile idle settings into namespace '%s': %v", req.Name, err)
return ctrl.Result{}, err
}

if err = r.reconcileNodeSelectorAndTolerations(ctx, req.Name, checluster, deployContext); err != nil {
logrus.Errorf("Failed to reconcile the workspace pod node selector and tolerations in namespace '%s': %v", req.Name, err)
return ctrl.Result{}, err
Expand Down Expand Up @@ -448,6 +455,50 @@ func (r *CheUserNamespaceReconciler) reconcileProxySettings(ctx context.Context,
return err
}

func (r *CheUserNamespaceReconciler) reconcileIdleSettings(ctx context.Context, targetNs string, checluster *chev2.CheCluster, deployContext *chetypes.DeployContext) error {

noIdle := pointer.Int32Ptr(-1)
if checluster.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling == noIdle && checluster.Spec.DevEnvironments.SecondsOfRunBeforeIdling == noIdle {
return nil
}
configMapName := prefixedName("idle-settings")
cfg := &corev1.ConfigMap{}

requiredLabels := defaults.AddStandardLabelsForComponent(checluster, userSettingsComponentLabelValue, map[string]string{
dwconstants.DevWorkspaceMountLabel: "true",
dwconstants.DevWorkspaceWatchConfigMapLabel: "true",
})
requiredAnnos := map[string]string{
dwconstants.DevWorkspaceMountAsAnnotation: "env",
}

data := map[string]string{}

if checluster.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling != noIdle {
data["SECONDS_OF_DW_INACTIVITY_BEFORE_IDLING"] = strconv.Itoa(int(*checluster.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling))
}

if checluster.Spec.DevEnvironments.SecondsOfRunBeforeIdling != noIdle {
data["SECONDS_OF_DW_RUN_BEFORE_IDLING"] = strconv.Itoa(int(*checluster.Spec.DevEnvironments.SecondsOfRunBeforeIdling))
}

cfg = &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: configMapName,
Namespace: targetNs,
Labels: requiredLabels,
Annotations: requiredAnnos,
},
Data: data,
}
_, err := deploy.DoSync(deployContext, cfg, deploy.ConfigMapDiffOpts)
return err
}

func (r *CheUserNamespaceReconciler) reconcileGitTlsCertificate(ctx context.Context, targetNs string, checluster *chev2.CheCluster, deployContext *chetypes.DeployContext) error {
if err := deleteLegacyObject("git-tls-creds", &corev1.ConfigMap{}, targetNs, checluster, deployContext); err != nil {
return err
Expand Down
16 changes: 16 additions & 0 deletions controllers/usernamespace/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ func setupCheCluster(t *testing.T, ctx context.Context, cl client.Client, scheme
TrustedCerts: &chev2.TrustedCerts{
GitTrustedCertsConfigMapName: "che-git-self-signed-cert",
},
SecondsOfInactivityBeforeIdling: pointer.Int32Ptr(900),
SecondsOfRunBeforeIdling: pointer.Int32Ptr(1800),
},
Networking: chev2.CheClusterSpecNetworking{
Domain: "root-domain",
Expand Down Expand Up @@ -325,6 +327,20 @@ func TestCreatesDataInNamespace(t *testing.T) {

assert.Equal(t, ".svc", proxySettings.Data["NO_PROXY"], "Unexpected proxy settings")

idleSettings := corev1.ConfigMap{}
assert.NoError(t, cl.Get(ctx, client.ObjectKey{Name: "che-idle-settings", Namespace: namespace.GetName()}, &idleSettings))

assert.Equal(t, "env", idleSettings.GetAnnotations()[dwconstants.DevWorkspaceMountAsAnnotation],
"idle settings should be annotated as mount as 'env'")

assert.Equal(t, "true", idleSettings.GetLabels()[dwconstants.DevWorkspaceMountLabel],
"idle settings should be labeled as mounted")

assert.Equal(t, 2, len(idleSettings.Data), "Expecting 2 elements in the idle settings")

assert.Equal(t, "900", idleSettings.Data["SECONDS_OF_DW_INACTIVITY_BEFORE_IDLING"], "Unexpected idle settings")
assert.Equal(t, "1800", idleSettings.Data["SECONDS_OF_DW_RUN_BEFORE_IDLING"], "Unexpected idle settings")

cert := corev1.Secret{}
assert.NoError(t, cl.Get(ctx, client.ObjectKey{Name: "che-server-cert", Namespace: namespace.GetName()}, &cert))

Expand Down
Loading

0 comments on commit 020efca

Please sign in to comment.