Skip to content

Commit 1e65aaa

Browse files
committed
[ws-manager] Introduce workspace classes
1 parent 74e5863 commit 1e65aaa

15 files changed

+895
-365
lines changed

components/ws-manager-api/core.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ message WorkspaceSpec {
307307

308308
// ide_image is the name of the Docker image used as IDE
309309
IDEImage ide_image = 8;
310+
311+
// class names the class of this workspace
312+
string class = 9;
310313
}
311314

312315
// PortSpec describes a networking port exposed on a workspace
@@ -493,6 +496,9 @@ message StartWorkspaceSpec {
493496

494497
// ide_image is the Docker image name of the IDE image
495498
IDEImage ide_image = 12;
499+
500+
// Class denotes the class of the workspace we ought to start
501+
string class = 13;
496502
}
497503

498504
// WorkspaceFeatureFlag enable non-standard behaviour in workspaces

components/ws-manager-api/go/config/config.go

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,11 @@ type Configuration struct {
6969
SchedulerName string `json:"schedulerName"`
7070
// SeccompProfile names the seccomp profile workspaces will use
7171
SeccompProfile string `json:"seccompProfile"`
72-
// Container configures all three workspace containers
73-
Container AllContainerConfiguration `json:"container"`
7472
// Timeouts configures how long workspaces can be without activity before they're shut down.
7573
// All values in here must be valid time.Duration
7674
Timeouts WorkspaceTimeoutConfiguration `json:"timeouts"`
7775
// InitProbe configures the ready-probe of workspaces which signal when the initialization is finished
7876
InitProbe InitProbeConfiguration `json:"initProbe"`
79-
// WorkspacePodTemplate is a path to a workspace pod template YAML file
80-
WorkspacePodTemplate WorkspacePodTemplateConfiguration `json:"podTemplate,omitempty"`
8177
// WorkspaceCACertSecret optionally names a secret which is mounted in `/etc/ssl/certs/gp-custom.crt`
8278
// in all workspace pods.
8379
WorkspaceCACertSecret string `json:"caCertSecret,omitempty"`
@@ -113,6 +109,13 @@ type Configuration struct {
113109
RegistryFacadeHost string `json:"registryFacadeHost"`
114110
// Cluster host under which workspaces are served, e.g. ws-eu11.gitpod.io
115111
WorkspaceClusterHost string `json:"workspaceClusterHost"`
112+
// WorkspaceClasses provide different resource classes for workspaces
113+
WorkspaceClasses map[string]*WorkspaceClass `json:"workspaceClass"`
114+
}
115+
116+
type WorkspaceClass struct {
117+
Container ContainerConfiguration `json:"container"`
118+
Templates WorkspacePodTemplateConfiguration `json:"templates"`
116119
}
117120

118121
// AllContainerConfiguration contains the configuration for all container in a workspace pod
@@ -185,10 +188,6 @@ type WorkspaceDaemonConfiguration struct {
185188

186189
// Validate validates the configuration to catch issues during startup and not at runtime
187190
func (c *Configuration) Validate() error {
188-
if err := c.Container.Workspace.Validate(); err != nil {
189-
return xerrors.Errorf("container.workspace: %w", err)
190-
}
191-
192191
err := validation.ValidateStruct(&c.Timeouts,
193192
validation.Field(&c.Timeouts.AfterClose, validation.Required),
194193
validation.Field(&c.Timeouts.HeadlessWorkspace, validation.Required),
@@ -206,23 +205,33 @@ func (c *Configuration) Validate() error {
206205
return xerrors.Errorf("stopping timeout must be greater than content finalization timeout")
207206
}
208207

209-
err = validation.ValidateStruct(&c.WorkspacePodTemplate,
210-
validation.Field(&c.WorkspacePodTemplate.DefaultPath, validPodTemplate),
211-
validation.Field(&c.WorkspacePodTemplate.PrebuildPath, validPodTemplate),
212-
validation.Field(&c.WorkspacePodTemplate.ProbePath, validPodTemplate),
213-
validation.Field(&c.WorkspacePodTemplate.RegularPath, validPodTemplate),
214-
)
215-
if err != nil {
216-
return xerrors.Errorf("workspacePodTemplate: %w", err)
217-
}
218-
219208
err = validation.ValidateStruct(c,
220209
validation.Field(&c.WorkspaceURLTemplate, validation.Required, validWorkspaceURLTemplate),
221210
validation.Field(&c.WorkspaceHostPath, validation.Required),
222211
validation.Field(&c.HeartbeatInterval, validation.Required),
223212
validation.Field(&c.GitpodHostURL, validation.Required, is.URL),
224213
validation.Field(&c.ReconnectionInterval, validation.Required),
225214
)
215+
if err != nil {
216+
return err
217+
}
218+
219+
for name, class := range c.WorkspaceClasses {
220+
if err := class.Container.Validate(); err != nil {
221+
return xerrors.Errorf("workspace class %s: %w", name, err)
222+
}
223+
224+
err = validation.ValidateStruct(&class.Templates,
225+
validation.Field(&class.Templates.DefaultPath, validPodTemplate),
226+
validation.Field(&class.Templates.PrebuildPath, validPodTemplate),
227+
validation.Field(&class.Templates.ProbePath, validPodTemplate),
228+
validation.Field(&class.Templates.RegularPath, validPodTemplate),
229+
)
230+
if err != nil {
231+
return xerrors.Errorf("workspace class %s: %w", name, err)
232+
}
233+
}
234+
226235
return err
227236
}
228237

@@ -256,15 +265,13 @@ var validWorkspaceURLTemplate = validation.By(func(o interface{}) error {
256265

257266
// ContainerConfiguration configures properties of workspace pod container
258267
type ContainerConfiguration struct {
259-
Image string `json:"image"`
260-
Requests ResourceConfiguration `json:"requests"`
261-
Limits ResourceConfiguration `json:"limits"`
268+
Requests *ResourceConfiguration `json:"requests,omitempty"`
269+
Limits *ResourceConfiguration `json:"limits,omitempty"`
262270
}
263271

264272
// Validate validates a container configuration
265273
func (c *ContainerConfiguration) Validate() error {
266274
return validation.ValidateStruct(c,
267-
validation.Field(&c.Image, validation.Required),
268275
validation.Field(&c.Requests, validResourceConfig),
269276
validation.Field(&c.Limits, validResourceConfig),
270277
)
@@ -298,6 +305,9 @@ var validResourceConfig = validation.By(func(o interface{}) error {
298305

299306
// ResourceList parses the quantities in the resource config
300307
func (r *ResourceConfiguration) ResourceList() (corev1.ResourceList, error) {
308+
if r == nil {
309+
return corev1.ResourceList{}, nil
310+
}
301311
res := map[corev1.ResourceName]string{
302312
corev1.ResourceCPU: r.CPU,
303313
corev1.ResourceMemory: r.Memory,

0 commit comments

Comments
 (0)