Skip to content

Commit

Permalink
Run dashboard in a dedicated deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
sleshchenko committed Apr 6, 2021
1 parent d7c9ec1 commit 7b5a4ed
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 0 deletions.
11 changes: 11 additions & 0 deletions pkg/controller/che/che_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/eclipse-che/che-operator/pkg/deploy/dashboard"
devworkspace "github.com/eclipse-che/che-operator/pkg/deploy/dev-workspace"
devfile_registry "github.com/eclipse-che/che-operator/pkg/deploy/devfile-registry"
"github.com/eclipse-che/che-operator/pkg/deploy/gateway"
Expand Down Expand Up @@ -940,6 +941,16 @@ func (r *ReconcileChe) Reconcile(request reconcile.Request) (reconcile.Result, e
}
}

provisioned, err = dashboard.SyncDashboardToCluster(deployContext)
if !tests {
if !provisioned {
if err != nil {
logrus.Errorf("Error provisioning '%s' to cluster: %v", dashboard.DashboardComponent, err)
}
return reconcile.Result{Requeue: true}, err
}
}

// create Che ConfigMap which is synced with CR and is not supposed to be manually edited
// controller will reconcile this CM with CR spec
done, err = server.SyncCheConfigMapToCluster(deployContext)
Expand Down
63 changes: 63 additions & 0 deletions pkg/deploy/dashboard/dashboard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// Copyright (c) 2012-2019 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package dashboard

import (
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/eclipse-che/che-operator/pkg/deploy/expose"
"github.com/eclipse-che/che-operator/pkg/util"
"github.com/sirupsen/logrus"
)

const (
// DashboardComponent which is supposed to be used for the naming related objects
DashboardComponent = "dashboard"
)

/**
* Create dashboard resources.
*/
func SyncDashboardToCluster(deployContext *deploy.DeployContext) (done bool, err error) {
// Deploy dashboard
success, err := SyncDashboardDeploymentToCluster(deployContext)
if !util.IsTestMode() {
if !success {
logrus.Info("Waiting on deployment '" + DashboardComponent + "' to be ready")
if err != nil {
logrus.Error(err)
}

return false, err
}
}

// Create a new dashboard service
serviceStatus := deploy.SyncServiceToCluster(deployContext, DashboardComponent, []string{"http"}, []int32{8080}, DashboardComponent)
if !util.IsTestMode() {
if !serviceStatus.Continue {
logrus.Info("Waiting on service '" + DashboardComponent + "' to be ready")
if serviceStatus.Err != nil {
logrus.Error(serviceStatus.Err)
}

return false, serviceStatus.Err
}
}

_, done, err = expose.ExposeWithHostPath(deployContext, DashboardComponent, deployContext.CheCluster.Spec.Server.CheHost,
"/dashboard",
deployContext.CheCluster.Spec.Server.CheServerRoute,
deployContext.CheCluster.Spec.Server.CheServerIngress,
)

return done, err
}
185 changes: 185 additions & 0 deletions pkg/deploy/dashboard/deployment_dashboard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
//
// Copyright (c) 2012-2019 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package dashboard

import (
"github.com/eclipse-che/che-operator/pkg/deploy"
"strconv"
"strings"

orgv1 "github.com/eclipse-che/che-operator/pkg/apis/org/v1"
"github.com/eclipse-che/che-operator/pkg/util"
appsv1 "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"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func SyncDashboardDeploymentToCluster(deployContext *deploy.DeployContext) (bool, error) {
specDeployment, err := getSpecDashboardDeployment(deployContext)
if err != nil {
return false, err
}

return deploy.SyncDeploymentSpecToCluster(deployContext, specDeployment, deploy.DefaultDeploymentDiffOpts)
}

func getSpecDashboardDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployment, error) {
isOpenShift, _, err := util.DetectOpenShift()
if err != nil {
return nil, err
}

terminationGracePeriodSeconds := int64(30)
cheFlavor := deploy.DefaultCheFlavor(deployContext.CheCluster)
labels := deploy.GetLabels(deployContext.CheCluster, DashboardComponent)
memRequest := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryRequest, deploy.DefaultServerMemoryRequest)

memLimit := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryLimit, deploy.DefaultServerMemoryLimit)
dashboardImageAndTag := "quay.io/eclipse/che-dashboard:next"
pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.CheImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(dashboardImageAndTag)))

deployment := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: DashboardComponent,
Namespace: deployContext.CheCluster.Namespace,
Labels: labels,
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{MatchLabels: labels},
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: cheFlavor,
ImagePullPolicy: pullPolicy,
Image: dashboardImageAndTag,
Ports: []corev1.ContainerPort{
{
Name: "http",
ContainerPort: 8080,
Protocol: "TCP",
},
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceMemory: resource.MustParse(memRequest),
},
Limits: corev1.ResourceList{
corev1.ResourceMemory: resource.MustParse(memLimit),
},
},
},
},
RestartPolicy: "Always",
TerminationGracePeriodSeconds: &terminationGracePeriodSeconds,
},
},
},
}

// configure probes if debug isn't set
//deployment.Spec.Template.Spec.Containers[0].ReadinessProbe = &corev1.Probe{
// Handler: corev1.Handler{
// HTTPGet: &corev1.HTTPGetAction{
// Path: "/api/system/state",
// Port: intstr.IntOrString{
// Type: intstr.Int,
// IntVal: int32(8080),
// },
// Scheme: corev1.URISchemeHTTP,
// },
// },
// // After POD start, the POD will be seen as ready after a minimum of 15 seconds and we expect it to be seen as ready until a maximum of 200 seconds
// // 200 s = InitialDelaySeconds + PeriodSeconds * (FailureThreshold - 1) + TimeoutSeconds
// InitialDelaySeconds: 25,
// FailureThreshold: 18,
// TimeoutSeconds: 5,
// PeriodSeconds: 10,
// SuccessThreshold: 1,
//}
//deployment.Spec.Template.Spec.Containers[0].LivenessProbe = &corev1.Probe{
// Handler: corev1.Handler{
// HTTPGet: &corev1.HTTPGetAction{
// Path: "/api/system/state",
// Port: intstr.IntOrString{
// Type: intstr.Int,
// IntVal: int32(8080),
// },
// Scheme: corev1.URISchemeHTTP,
// },
// },
// // After POD start, don't initiate liveness probe while the POD is still expected to be declared as ready by the readiness probe
// InitialDelaySeconds: 200,
// FailureThreshold: 3,
// TimeoutSeconds: 3,
// PeriodSeconds: 10,
// SuccessThreshold: 1,
//}

if !isOpenShift {
runAsUser, err := strconv.ParseInt(util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextRunAsUser, deploy.DefaultSecurityContextRunAsUser), 10, 64)
if err != nil {
return nil, err
}
fsGroup, err := strconv.ParseInt(util.GetValue(deployContext.CheCluster.Spec.K8s.SecurityContextFsGroup, deploy.DefaultSecurityContextFsGroup), 10, 64)
if err != nil {
return nil, err
}
deployment.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{
RunAsUser: &runAsUser,
FSGroup: &fsGroup,
}
}

if !util.IsTestMode() {
err = controllerutil.SetControllerReference(deployContext.CheCluster, deployment, deployContext.ClusterAPI.Scheme)
if err != nil {
return nil, err
}
}

return deployment, nil
}

// GetFullCheServerImageLink evaluate full cheImage link(with repo and tag)
// based on Checluster information and image defaults from env variables
func GetFullDashboardServerImageLink(checluster *orgv1.CheCluster) string {
if len(checluster.Spec.Server.CheImage) > 0 {
cheServerImageTag := util.GetValue(checluster.Spec.Server.CheImageTag, deploy.DefaultCheVersion())
return checluster.Spec.Server.CheImage + ":" + cheServerImageTag
}

defaultCheServerImage := deploy.DefaultCheServerImage(checluster)
if len(checluster.Spec.Server.CheImageTag) == 0 {
return defaultCheServerImage
}

// For back compatibility with version < 7.9.0:
// if cr.Spec.Server.CheImage is empty, but cr.Spec.Server.CheImageTag is not empty,
// parse from default Che image(value comes from env variable) "Che image repository"
// and return "Che image", like concatenation: "cheImageRepo:cheImageTag"
separator := map[bool]string{true: "@", false: ":"}[strings.Contains(defaultCheServerImage, "@")]
imageParts := strings.Split(defaultCheServerImage, separator)
return imageParts[0] + ":" + checluster.Spec.Server.CheImageTag
}

0 comments on commit 7b5a4ed

Please sign in to comment.