Path: blob/main/install/installer/pkg/components/openvsx-proxy/statefulset.go
2501 views
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package openvsx_proxy56import (7"fmt"89appsv1 "k8s.io/api/apps/v1"10v1 "k8s.io/api/core/v1"11"k8s.io/apimachinery/pkg/api/resource"12metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"13"k8s.io/apimachinery/pkg/runtime"14"k8s.io/apimachinery/pkg/util/intstr"15"k8s.io/utils/pointer"1617"github.com/gitpod-io/gitpod/common-go/baseserver"18"github.com/gitpod-io/gitpod/installer/pkg/cluster"19"github.com/gitpod-io/gitpod/installer/pkg/common"20"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"21)2223func statefulset(ctx *common.RenderContext) ([]runtime.Object, error) {24labels := common.CustomizeLabel(ctx, Component, common.TypeMetaStatefulSet)25// todo(sje): add redis2627configHash, err := common.ObjectHash(configmap(ctx))28if err != nil {29return nil, err30}3132volumeClaimTemplates := []v1.PersistentVolumeClaim{33{34ObjectMeta: metav1.ObjectMeta{35Name: "redis-data",36Labels: common.DefaultLabels(Component),37},38Spec: v1.PersistentVolumeClaimSpec{39AccessModes: []v1.PersistentVolumeAccessMode{40v1.ReadWriteOnce,41},42Resources: v1.VolumeResourceRequirements{43Requests: v1.ResourceList{44"storage": resource.MustParse("8Gi"),45},46},47},48},49}5051volumes := []v1.Volume{52{53Name: "config",54VolumeSource: v1.VolumeSource{55ConfigMap: &v1.ConfigMapVolumeSource{56LocalObjectReference: v1.LocalObjectReference{Name: fmt.Sprintf("%s-config", Component)},57},58},59},60}6162if ctx.Config.OpenVSX.Proxy != nil && ctx.Config.OpenVSX.Proxy.DisablePVC {63volumeClaimTemplates = nil64volumes = append(volumes, *common.NewEmptyDirVolume("redis-data"))65}6667const redisContainerName = "redis"6869var proxyEnvVars []v1.EnvVar7071_ = ctx.WithExperimental(func(cfg *experimental.Config) error {72proxyConfig := cfg.WebApp.ProxySettings73if proxyConfig != nil {74proxyEnvVars = []v1.EnvVar{75{76Name: "HTTP_PROXY",77Value: proxyConfig.HttpProxy,78},79{80Name: "HTTPS_PROXY",81Value: proxyConfig.HttpsProxy,82},83{84Name: "NO_PROXY",85Value: proxyConfig.NoProxy,86},87}88}89return nil90})9192return []runtime.Object{&appsv1.StatefulSet{93TypeMeta: common.TypeMetaStatefulSet,94ObjectMeta: metav1.ObjectMeta{95Name: Component,96Namespace: ctx.Namespace,97Labels: labels,98Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaConfigmap),99},100Spec: appsv1.StatefulSetSpec{101Selector: &metav1.LabelSelector{102MatchLabels: common.DefaultLabels(Component),103},104ServiceName: Component,105// todo(sje): receive config value106Replicas: common.Replicas(ctx, Component),107Template: v1.PodTemplateSpec{108ObjectMeta: metav1.ObjectMeta{109Name: Component,110Namespace: ctx.Namespace,111Labels: labels,112Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaConfigmap, func() map[string]string {113return map[string]string{114common.AnnotationConfigChecksum: configHash,115}116}),117},118Spec: v1.PodSpec{119Affinity: cluster.WithNodeAffinity(cluster.AffinityLabelIDE),120ServiceAccountName: Component,121EnableServiceLinks: pointer.Bool(false),122DNSPolicy: v1.DNSClusterFirst,123RestartPolicy: v1.RestartPolicyAlways,124TerminationGracePeriodSeconds: pointer.Int64(30),125Volumes: volumes,126Containers: []v1.Container{{127Name: Component,128Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.OpenVSXProxy.Version),129Args: []string{"/config/config.json"},130ReadinessProbe: &v1.Probe{131ProbeHandler: v1.ProbeHandler{132HTTPGet: &v1.HTTPGetAction{133Path: "/openvsx-proxy-status",134Port: intstr.IntOrString{IntVal: ContainerPort},135},136},137},138SecurityContext: &v1.SecurityContext{139AllowPrivilegeEscalation: pointer.Bool(false),140},141ImagePullPolicy: v1.PullIfNotPresent,142Resources: common.ResourceRequirements(ctx, Component, Component, v1.ResourceRequirements{143Requests: v1.ResourceList{144"cpu": resource.MustParse("1m"),145"memory": resource.MustParse("150Mi"),146},147}),148Ports: []v1.ContainerPort{{149Name: PortName,150ContainerPort: ContainerPort,151}, {152Name: baseserver.BuiltinMetricsPortName,153ContainerPort: baseserver.BuiltinMetricsPort,154}},155VolumeMounts: []v1.VolumeMount{{156Name: "config",157MountPath: "/config",158}},159Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv(160common.DefaultEnv(&ctx.Config),161common.ConfigcatEnv(ctx),162proxyEnvVars,163)),164}, {165Name: redisContainerName,166Image: ctx.ImageName(common.ThirdPartyContainerRepo(ctx.Config.Repository, common.DockerRegistryURL), "library/redis", "6.2"),167Command: []string{168"redis-server",169"/config/redis.conf",170},171Env: []v1.EnvVar{{172Name: "MASTER",173Value: "true",174}},175ImagePullPolicy: "IfNotPresent",176Ports: []v1.ContainerPort{{177ContainerPort: 6379,178}},179SecurityContext: &v1.SecurityContext{180AllowPrivilegeEscalation: pointer.Bool(false),181},182Resources: common.ResourceRequirements(ctx, Component, redisContainerName, v1.ResourceRequirements{183Requests: v1.ResourceList{184"cpu": resource.MustParse("1m"),185"memory": resource.MustParse("150Mi"),186},187}),188VolumeMounts: []v1.VolumeMount{{189Name: "config",190MountPath: "/config",191}, {192Name: "redis-data",193MountPath: "/data",194}},195}, *common.KubeRBACProxyContainer(ctx),196},197Tolerations: common.WithTolerationWorkspaceComponentNotReady(ctx),198},199},200VolumeClaimTemplates: volumeClaimTemplates,201}},202}, nil203}204205206