Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/install/installer/pkg/components/ws-manager-bridge/deployment.go
2501 views
1
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package wsmanagerbridge
6
7
import (
8
"fmt"
9
10
"github.com/gitpod-io/gitpod/common-go/baseserver"
11
"github.com/gitpod-io/gitpod/installer/pkg/cluster"
12
"github.com/gitpod-io/gitpod/installer/pkg/common"
13
wsmanagermk2 "github.com/gitpod-io/gitpod/installer/pkg/components/ws-manager-mk2"
14
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"
15
16
appsv1 "k8s.io/api/apps/v1"
17
corev1 "k8s.io/api/core/v1"
18
"k8s.io/apimachinery/pkg/api/resource"
19
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20
"k8s.io/apimachinery/pkg/runtime"
21
"k8s.io/apimachinery/pkg/util/intstr"
22
"k8s.io/utils/pointer"
23
)
24
25
func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {
26
labels := common.CustomizeLabel(ctx, Component, common.TypeMetaDeployment)
27
28
var hashObj []runtime.Object
29
if objs, err := configmap(ctx); err != nil {
30
return nil, err
31
} else {
32
hashObj = append(hashObj, objs...)
33
}
34
35
var volumes []corev1.Volume
36
var volumeMounts []corev1.VolumeMount
37
38
addWsManagerTls := common.WithLocalWsManager(ctx)
39
if addWsManagerTls {
40
volumes = append(volumes, corev1.Volume{
41
Name: "ws-manager-client-tls-certs",
42
VolumeSource: corev1.VolumeSource{
43
Secret: &corev1.SecretVolumeSource{
44
SecretName: wsmanagermk2.TLSSecretNameClient,
45
},
46
},
47
})
48
volumeMounts = append(volumeMounts, corev1.VolumeMount{
49
Name: "ws-manager-client-tls-certs",
50
MountPath: "/ws-manager-client-tls-certs",
51
ReadOnly: true,
52
})
53
}
54
55
hashObj = append(hashObj, &corev1.Pod{
56
Spec: corev1.PodSpec{
57
Containers: []corev1.Container{
58
{
59
Env: []corev1.EnvVar{
60
{
61
// If the database type changes, this pod may stay up if no other changes are made.
62
Name: "DATABASE_TYPE",
63
Value: func() string {
64
if pointer.BoolDeref(ctx.Config.Database.InCluster, false) {
65
return "in-cluster"
66
}
67
if ctx.Config.Database.CloudSQL != nil {
68
return "cloudsql"
69
}
70
return "external"
71
}(),
72
},
73
},
74
},
75
},
76
},
77
})
78
79
configHash, err := common.ObjectHash(hashObj, nil)
80
if err != nil {
81
return nil, err
82
}
83
84
env := common.CustomizeEnvvar(ctx, Component, common.MergeEnv(
85
common.DefaultEnv(&ctx.Config),
86
common.WorkspaceTracingEnv(ctx, Component),
87
common.AnalyticsEnv(&ctx.Config),
88
common.DatabaseEnv(&ctx.Config),
89
common.ConfigcatEnv(ctx),
90
[]corev1.EnvVar{
91
{
92
Name: "WSMAN_BRIDGE_CONFIGPATH",
93
Value: "/config/ws-manager-bridge.json",
94
},
95
// Required for node.js to pick up custom CAs
96
{
97
Name: "NODE_EXTRA_CA_CERTS",
98
Value: common.CUSTOM_CA_MOUNT_PATH,
99
},
100
},
101
))
102
103
_ = ctx.WithExperimental(func(cfg *experimental.Config) error {
104
if cfg.WebApp != nil && cfg.WebApp.Redis != nil {
105
env = append(env, corev1.EnvVar{
106
Name: "REDIS_USERNAME",
107
Value: cfg.WebApp.Redis.Username,
108
})
109
110
env = append(env, corev1.EnvVar{
111
Name: "REDIS_PASSWORD",
112
ValueFrom: &corev1.EnvVarSource{
113
SecretKeyRef: &corev1.SecretKeySelector{
114
LocalObjectReference: corev1.LocalObjectReference{
115
Name: cfg.WebApp.Redis.SecretRef,
116
},
117
Key: "password",
118
},
119
},
120
})
121
}
122
return nil
123
})
124
125
return []runtime.Object{
126
&appsv1.Deployment{
127
TypeMeta: common.TypeMetaDeployment,
128
ObjectMeta: metav1.ObjectMeta{
129
Name: Component,
130
Namespace: ctx.Namespace,
131
Labels: labels,
132
Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDeployment),
133
},
134
Spec: appsv1.DeploymentSpec{
135
Selector: &metav1.LabelSelector{MatchLabels: common.DefaultLabels(Component)},
136
Replicas: common.Replicas(ctx, Component),
137
Strategy: common.DeploymentStrategy,
138
Template: corev1.PodTemplateSpec{
139
ObjectMeta: metav1.ObjectMeta{
140
Name: Component,
141
Namespace: ctx.Namespace,
142
Labels: labels,
143
Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDeployment, func() map[string]string {
144
return map[string]string{
145
common.AnnotationConfigChecksum: configHash,
146
}
147
}),
148
},
149
Spec: corev1.PodSpec{
150
Affinity: cluster.WithNodeAffinityHostnameAntiAffinity(Component, cluster.AffinityLabelMeta),
151
TopologySpreadConstraints: cluster.WithHostnameTopologySpread(Component),
152
ServiceAccountName: Component,
153
PriorityClassName: common.SystemNodeCritical,
154
EnableServiceLinks: pointer.Bool(false),
155
DNSPolicy: corev1.DNSClusterFirst,
156
RestartPolicy: corev1.RestartPolicyAlways,
157
TerminationGracePeriodSeconds: pointer.Int64(30),
158
Volumes: append(
159
[]corev1.Volume{
160
{
161
Name: "config",
162
VolumeSource: corev1.VolumeSource{
163
ConfigMap: &corev1.ConfigMapVolumeSource{
164
LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("%s-config", Component)},
165
},
166
},
167
},
168
common.CAVolume(),
169
},
170
volumes...,
171
),
172
InitContainers: []corev1.Container{
173
*common.DatabaseMigrationWaiterContainer(ctx),
174
*common.RedisWaiterContainer(ctx),
175
},
176
Containers: []corev1.Container{{
177
Name: Component,
178
Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.WSManagerBridge.Version),
179
ImagePullPolicy: corev1.PullIfNotPresent,
180
Resources: common.ResourceRequirements(ctx, Component, Component, corev1.ResourceRequirements{
181
Requests: corev1.ResourceList{
182
"cpu": resource.MustParse("100m"),
183
"memory": resource.MustParse("64Mi"),
184
},
185
}),
186
SecurityContext: &corev1.SecurityContext{
187
Privileged: pointer.Bool(false),
188
AllowPrivilegeEscalation: pointer.Bool(false),
189
},
190
Env: env,
191
Ports: []corev1.ContainerPort{
192
{
193
ContainerPort: baseserver.BuiltinMetricsPort,
194
Name: baseserver.BuiltinMetricsPortName,
195
},
196
},
197
VolumeMounts: append(
198
[]corev1.VolumeMount{
199
{
200
Name: "config",
201
MountPath: "/config",
202
ReadOnly: true,
203
},
204
common.CAVolumeMount(),
205
},
206
volumeMounts...,
207
),
208
LivenessProbe: &corev1.Probe{
209
ProbeHandler: corev1.ProbeHandler{
210
HTTPGet: &corev1.HTTPGetAction{
211
Path: "/healthz",
212
Port: intstr.FromInt(9090),
213
},
214
},
215
InitialDelaySeconds: 15,
216
PeriodSeconds: 20,
217
},
218
}, *common.KubeRBACProxyContainer(ctx)},
219
Tolerations: common.WithTolerationWorkspaceComponentNotReady(ctx),
220
},
221
},
222
},
223
},
224
}, nil
225
}
226
227