Skip to content

Commit 84e7cb5

Browse files
committed
[installer] Add support for workspace classes
1 parent d66bdc9 commit 84e7cb5

File tree

4 files changed

+85
-27
lines changed

4 files changed

+85
-27
lines changed

install/installer/pkg/components/ws-manager/configmap.go

+64-22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
storageconfig "github.com/gitpod-io/gitpod/content-service/api/config"
1818
"github.com/gitpod-io/gitpod/installer/pkg/common"
1919
configv1 "github.com/gitpod-io/gitpod/installer/pkg/config/v1"
20+
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"
2021
"github.com/gitpod-io/gitpod/ws-manager/api/config"
2122

2223
corev1 "k8s.io/api/core/v1"
@@ -25,7 +26,11 @@ import (
2526
)
2627

2728
func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
28-
templatesCfg, tpls, err := buildWorkspaceTemplates(ctx)
29+
cfgTpls := ctx.Config.Workspace.Templates
30+
if cfgTpls == nil {
31+
cfgTpls = &configv1.WorkspaceTemplates{}
32+
}
33+
templatesCfg, tpls, err := buildWorkspaceTemplates(ctx, cfgTpls, "")
2934
if err != nil {
3035
return nil, err
3136
}
@@ -48,6 +53,60 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
4853
customCASecret = ctx.Config.CustomCACert.Name
4954
}
5055

56+
classes := map[string]*config.WorkspaceClass{
57+
"": {
58+
Container: config.ContainerConfiguration{
59+
Requests: &config.ResourceConfiguration{
60+
CPU: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceCPU),
61+
Memory: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceMemory),
62+
EphemeralStorage: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceEphemeralStorage),
63+
},
64+
Limits: &config.ResourceConfiguration{
65+
CPU: quantityString(ctx.Config.Workspace.Resources.Limits, corev1.ResourceCPU),
66+
Memory: quantityString(ctx.Config.Workspace.Resources.Limits, corev1.ResourceMemory),
67+
EphemeralStorage: quantityString(ctx.Config.Workspace.Resources.Limits, corev1.ResourceEphemeralStorage),
68+
},
69+
},
70+
Templates: templatesCfg,
71+
},
72+
}
73+
err = ctx.WithExperimental(func(ucfg *experimental.Config) error {
74+
if ucfg.Workspace == nil {
75+
return nil
76+
}
77+
for k, c := range ucfg.Workspace.WorkspaceClasses {
78+
tplsCfg, ctpls, err := buildWorkspaceTemplates(ctx, &configv1.WorkspaceTemplates{
79+
Default: c.Templates.Default,
80+
Prebuild: c.Templates.Prebuild,
81+
ImageBuild: c.Templates.ImageBuild,
82+
Regular: c.Templates.Regular,
83+
}, k)
84+
if err != nil {
85+
return err
86+
}
87+
classes[k] = &config.WorkspaceClass{
88+
Container: config.ContainerConfiguration{
89+
Requests: &config.ResourceConfiguration{
90+
CPU: quantityString(c.Resources.Requests, corev1.ResourceCPU),
91+
Memory: quantityString(c.Resources.Requests, corev1.ResourceMemory),
92+
EphemeralStorage: quantityString(c.Resources.Requests, corev1.ResourceEphemeralStorage),
93+
},
94+
Limits: &config.ResourceConfiguration{
95+
CPU: quantityString(c.Resources.Limits, corev1.ResourceCPU),
96+
Memory: quantityString(c.Resources.Limits, corev1.ResourceMemory),
97+
EphemeralStorage: quantityString(c.Resources.Limits, corev1.ResourceEphemeralStorage),
98+
},
99+
},
100+
Templates: tplsCfg,
101+
}
102+
tpls = append(tpls, ctpls...)
103+
}
104+
return nil
105+
})
106+
if err != nil {
107+
return nil, err
108+
}
109+
51110
wsmcfg := config.ServiceConfiguration{
52111
Manager: config.Configuration{
53112
Namespace: ctx.Namespace,
@@ -65,21 +124,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
65124
PrivateKey: "/ws-daemon-tls-certs/tls.key",
66125
},
67126
},
68-
Container: config.AllContainerConfiguration{
69-
Workspace: config.ContainerConfiguration{
70-
Requests: config.ResourceConfiguration{
71-
CPU: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceCPU),
72-
Memory: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceMemory),
73-
EphemeralStorage: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceEphemeralStorage),
74-
},
75-
Limits: config.ResourceConfiguration{
76-
CPU: quantityString(ctx.Config.Workspace.Resources.Limits, corev1.ResourceCPU),
77-
Memory: quantityString(ctx.Config.Workspace.Resources.Limits, corev1.ResourceMemory),
78-
EphemeralStorage: quantityString(ctx.Config.Workspace.Resources.Requests, corev1.ResourceEphemeralStorage),
79-
},
80-
Image: "OVERWRITTEN-IN-REQUEST",
81-
},
82-
},
127+
WorkspaceClasses: classes,
83128
HeartbeatInterval: util.Duration(30 * time.Second),
84129
GitpodHostURL: "https://" + ctx.Config.Domain,
85130
WorkspaceClusterHost: fmt.Sprintf("ws.%s", ctx.Config.Domain),
@@ -89,7 +134,6 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
89134
WorkspaceURLTemplate: fmt.Sprintf("https://{{ .Prefix }}.ws.%s", ctx.Config.Domain),
90135
WorkspacePortURLTemplate: fmt.Sprintf("https://{{ .WorkspacePort }}-{{ .Prefix }}.ws.%s", ctx.Config.Domain),
91136
WorkspaceHostPath: wsdaemon.HostWorkingArea,
92-
WorkspacePodTemplate: templatesCfg,
93137
Timeouts: config.WorkspaceTimeoutConfiguration{
94138
AfterClose: timeoutAfterClose,
95139
HeadlessWorkspace: util.Duration(1 * time.Hour),
@@ -165,14 +209,13 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
165209
return res, nil
166210
}
167211

168-
func buildWorkspaceTemplates(ctx *common.RenderContext) (config.WorkspacePodTemplateConfiguration, []runtime.Object, error) {
212+
func buildWorkspaceTemplates(ctx *common.RenderContext, cfgTpls *configv1.WorkspaceTemplates, className string) (config.WorkspacePodTemplateConfiguration, []runtime.Object, error) {
169213
var (
170214
cfg config.WorkspacePodTemplateConfiguration
171215
tpls = make(map[string]string)
172216
)
173-
cfgTpls := ctx.Config.Workspace.Templates
174217
if cfgTpls == nil {
175-
cfgTpls = &configv1.WorkspaceTemplates{}
218+
cfgTpls = new(configv1.WorkspaceTemplates)
176219
}
177220

178221
ops := []struct {
@@ -184,7 +227,6 @@ func buildWorkspaceTemplates(ctx *common.RenderContext) (config.WorkspacePodTemp
184227
{Name: "imagebuild", Path: &cfg.ImagebuildPath, Tpl: cfgTpls.ImageBuild},
185228
{Name: "prebuild", Path: &cfg.PrebuildPath, Tpl: cfgTpls.Prebuild},
186229
{Name: "regular", Path: &cfg.RegularPath, Tpl: cfgTpls.Regular},
187-
{Name: "probe", Path: &cfg.ProbePath, Tpl: cfgTpls.Probe},
188230
}
189231
for _, op := range ops {
190232
if op.Tpl == nil {
@@ -194,7 +236,7 @@ func buildWorkspaceTemplates(ctx *common.RenderContext) (config.WorkspacePodTemp
194236
if err != nil {
195237
return cfg, nil, fmt.Errorf("unable to marshal %s workspace template: %w", op.Name, err)
196238
}
197-
fn := op.Name + ".yaml"
239+
fn := filepath.Join(className, op.Name+".yaml")
198240
*op.Path = filepath.Join(WorkspaceTemplatePath, fn)
199241
tpls[fn] = string(fc)
200242
}

install/installer/pkg/components/ws-manager/configmap_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ func TestBuildWorkspaceTemplates(t *testing.T) {
105105

106106
act.TplConfig, objs, err = buildWorkspaceTemplates(&common.RenderContext{Config: configv1.Config{
107107
ContainerRegistry: *test.ContainerRegistry,
108-
Workspace: configv1.Workspace{Templates: test.Config},
109-
}})
108+
}}, test.Config, "")
110109
if err != nil {
111110
t.Error(err)
112111
}

install/installer/pkg/config/v1/config.go

-2
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,8 @@ type WorkspaceRuntime struct {
227227
type WorkspaceTemplates struct {
228228
Default *corev1.Pod `json:"default"`
229229
Prebuild *corev1.Pod `json:"prebuild"`
230-
Ghost *corev1.Pod `json:"ghost"`
231230
ImageBuild *corev1.Pod `json:"imagebuild"`
232231
Regular *corev1.Pod `json:"regular"`
233-
Probe *corev1.Pod `json:"probe"`
234232
}
235233

236234
type Workspace struct {

install/installer/pkg/config/v1/experimental/experimental.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
// If you use any setting herein, you forfeit support from Gitpod.
1111
package experimental
1212

13-
import "k8s.io/apimachinery/pkg/api/resource"
13+
import (
14+
corev1 "k8s.io/api/core/v1"
15+
"k8s.io/apimachinery/pkg/api/resource"
16+
)
1417

1518
// Config contains all experimental configuration.
1619
type Config struct {
@@ -49,6 +52,22 @@ type WorkspaceConfig struct {
4952
PasswordSecret string `json:"passwordSecret"`
5053
} `json:"redisCache"`
5154
} `json:"registryFacade"`
55+
56+
WorkspaceClasses map[string]WorkspaceClass `json:"classes,omitempty"`
57+
}
58+
59+
type WorkspaceClass struct {
60+
Resources struct {
61+
Requests corev1.ResourceList `json:"requests" validate:"required"`
62+
Limits corev1.ResourceList `json:"limits,omitempty"`
63+
} `json:"resources" validate:"required"`
64+
Templates WorkspaceTemplates `json:"templates,omitempty"`
65+
}
66+
type WorkspaceTemplates struct {
67+
Default *corev1.Pod `json:"default"`
68+
Prebuild *corev1.Pod `json:"prebuild"`
69+
ImageBuild *corev1.Pod `json:"imagebuild"`
70+
Regular *corev1.Pod `json:"regular"`
5271
}
5372

5473
type WebAppConfig struct {

0 commit comments

Comments
 (0)