Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/common-go/kubernetes/kubernetes.go
2498 views
1
// Copyright (c) 2020 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 kubernetes
6
7
// Those two are the only cases where you would actually need this package. If you think you need this elsewhere,
8
// please make sure you're not better of using wsman's API to solve your problem. If this is actually what you need,
9
// please update this comment.
10
//
11
12
import (
13
"context"
14
"math"
15
16
"github.com/sirupsen/logrus"
17
corev1 "k8s.io/api/core/v1"
18
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19
20
"github.com/gitpod-io/gitpod/common-go/log"
21
)
22
23
const (
24
// WorkspaceIDLabel is the label which contains the workspaceID. We duplicate this information with the annotations to make selection easier
25
WorkspaceIDLabel = "workspaceID"
26
27
// OwnerLabel is the label of the workspace's owner
28
OwnerLabel = "owner"
29
30
// MetaIDLabel is the label of the workspace meta ID (just workspace ID outside of wsman)
31
MetaIDLabel = "metaID"
32
33
// ProjectLabel is the label for the workspace's project
34
ProjectLabel = "project"
35
36
// TeamLabel is the label for the workspace's team
37
TeamLabel = "team"
38
39
// TypeLabel marks the workspace type
40
TypeLabel = "workspaceType"
41
42
// ServiceTypeLabel help differentiate between port service and IDE service
43
ServiceTypeLabel = "serviceType"
44
45
// WorkspaceManaged indicates which component is responsible for managing the workspace
46
WorkspaceManagedByLabel = "gitpod.io/managed-by"
47
48
// CPULimitAnnotation enforces a strict CPU limit on a workspace by virtue of ws-daemon
49
CPULimitAnnotation = "gitpod.io/cpuLimit"
50
51
// WorkspaceURLAnnotation is the annotation on the WS pod which contains the public workspace URL.
52
WorkspaceURLAnnotation = "gitpod/url"
53
54
// OwnerTokenAnnotation contains the owner token of the workspace.
55
OwnerTokenAnnotation = "gitpod/ownerToken"
56
57
// WorkspaceAdmissionAnnotation determines the user admission to a workspace, i.e. if it can be accessed by everyone without token.
58
WorkspaceAdmissionAnnotation = "gitpod/admission"
59
60
// WorkspaceImageSpecAnnotation contains the protobuf serialized image spec in base64 encoding. We need to keep this around post-request
61
// to provide this information to the registry facade later in the workspace's lifecycle.
62
WorkspaceImageSpecAnnotation = "gitpod/imageSpec"
63
64
// WorkspaceExposedPorts contains the exposed ports in the workspace
65
WorkspaceExposedPorts = "gitpod/exposedPorts"
66
67
// WorkspaceSSHPublicKeys contains all authorized ssh public keys that can be connected to the workspace
68
WorkspaceSSHPublicKeys = "gitpod.io/sshPublicKeys"
69
70
// workspaceCpuMinLimitAnnotation denotes the minimum cpu limit of a workspace i.e. the minimum amount of resources it is guaranteed to get
71
WorkspaceCpuMinLimitAnnotation = "gitpod.io/cpuMinLimit"
72
73
// workspaceCpuBurstLimit denotes the cpu burst limit of a workspace
74
WorkspaceCpuBurstLimitAnnotation = "gitpod.io/cpuBurstLimit"
75
76
// workspaceNetConnLimit denotes the maximum number of connections a workspace can make per minute
77
WorkspaceNetConnLimitAnnotation = "gitpod.io/netConnLimitPerMinute"
78
79
// workspacePressureStallInfo indicates if pressure stall information should be retrieved for the workspace
80
WorkspacePressureStallInfoAnnotation = "gitpod.io/psi"
81
82
// ImageNameAnnotation indicates the original format of the main image of the pod
83
ImageNameAnnotation = "gitpod.io/image_name"
84
)
85
86
// GetOWIFromObject finds the owner, workspace and instance information on a Kubernetes object using labels
87
func GetOWIFromObject(pod *metav1.ObjectMeta) logrus.Fields {
88
owner := pod.Labels[OwnerLabel]
89
workspace := pod.Labels[MetaIDLabel]
90
instance := pod.Labels[WorkspaceIDLabel]
91
project := pod.Labels[ProjectLabel]
92
team := pod.Labels[TeamLabel]
93
return log.LogContext(owner, workspace, instance, project, team)
94
}
95
96
// UnlimitedRateLimiter implements an empty, unlimited flowcontrol.RateLimiter
97
type UnlimitedRateLimiter struct {
98
}
99
100
// TryAccept returns true if a token is taken immediately. Otherwise,
101
// it returns false.
102
func (u *UnlimitedRateLimiter) TryAccept() bool {
103
return true
104
}
105
106
// Accept returns once a token becomes available.
107
func (u *UnlimitedRateLimiter) Accept() {
108
}
109
110
// Stop stops the rate limiter, subsequent calls to CanAccept will return false
111
func (u *UnlimitedRateLimiter) Stop() {
112
}
113
114
// QPS returns QPS of this rate limiter
115
func (u *UnlimitedRateLimiter) QPS() float32 {
116
return math.MaxFloat32
117
}
118
119
// Wait returns nil if a token is taken before the Context is done.
120
func (u *UnlimitedRateLimiter) Wait(ctx context.Context) error {
121
return nil
122
}
123
124
func IsWorkspace(pod *corev1.Pod) bool {
125
val, ok := pod.ObjectMeta.Labels["component"]
126
return ok && val == "workspace"
127
}
128
129
func IsHeadlessWorkspace(pod *corev1.Pod) bool {
130
if !IsWorkspace(pod) {
131
return false
132
}
133
134
val, ok := pod.ObjectMeta.Labels["headless"]
135
return ok && val == "true"
136
}
137
138
func IsRegularWorkspace(pod *corev1.Pod) bool {
139
if !IsWorkspace(pod) {
140
return false
141
}
142
143
val, ok := pod.ObjectMeta.Labels[TypeLabel]
144
return ok && val == "regular"
145
}
146
147
func GetWorkspaceType(pod *corev1.Pod) string {
148
val, ok := pod.ObjectMeta.Labels[TypeLabel]
149
if !ok {
150
return ""
151
}
152
return val
153
}
154
155
// AddUniqueCondition adds a condition if it doesn't exist already
156
func AddUniqueCondition(conds []metav1.Condition, cond metav1.Condition) []metav1.Condition {
157
if cond.Reason == "" {
158
cond.Reason = "Unknown"
159
}
160
161
for i, c := range conds {
162
if c.Type == cond.Type {
163
conds[i] = cond
164
return conds
165
}
166
}
167
168
return append(conds, cond)
169
}
170
171
// GetCondition returns a condition from a list. If not present, it returns nil.
172
func GetCondition(conds []metav1.Condition, tpe string) *metav1.Condition {
173
for _, c := range conds {
174
if c.Type == tpe {
175
return &c
176
}
177
}
178
return nil
179
}
180
181
// ConditionPresentAndTrue returns whether a condition is present and its status set to True.
182
func ConditionPresentAndTrue(cond []metav1.Condition, tpe string) bool {
183
for _, c := range cond {
184
if c.Type == tpe {
185
return c.Status == metav1.ConditionTrue
186
}
187
}
188
return false
189
}
190
191
// ConditionWithStatusAndReason returns whether a condition is present, and with the given Reason.
192
func ConditionWithStatusAndReason(cond []metav1.Condition, tpe string, status bool, reason string) bool {
193
st := metav1.ConditionFalse
194
if status {
195
st = metav1.ConditionTrue
196
}
197
for _, c := range cond {
198
if c.Type == tpe {
199
return c.Type == tpe && c.Status == st && c.Reason == reason
200
}
201
}
202
return false
203
}
204
205