diff --git a/components/ide-service-api/go/ide.pb.go b/components/ide-service-api/go/ide.pb.go index 8411c2a2c4373c..fd053d572e6003 100644 --- a/components/ide-service-api/go/ide.pb.go +++ b/components/ide-service-api/go/ide.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.28.1 // protoc v3.20.1 // source: ide.proto @@ -24,6 +24,52 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type WorkspaceType int32 + +const ( + WorkspaceType_REGULAR WorkspaceType = 0 + WorkspaceType_PREBUILD WorkspaceType = 1 +) + +// Enum value maps for WorkspaceType. +var ( + WorkspaceType_name = map[int32]string{ + 0: "REGULAR", + 1: "PREBUILD", + } + WorkspaceType_value = map[string]int32{ + "REGULAR": 0, + "PREBUILD": 1, + } +) + +func (x WorkspaceType) Enum() *WorkspaceType { + p := new(WorkspaceType) + *p = x + return p +} + +func (x WorkspaceType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WorkspaceType) Descriptor() protoreflect.EnumDescriptor { + return file_ide_proto_enumTypes[0].Descriptor() +} + +func (WorkspaceType) Type() protoreflect.EnumType { + return &file_ide_proto_enumTypes[0] +} + +func (x WorkspaceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use WorkspaceType.Descriptor instead. +func (WorkspaceType) EnumDescriptor() ([]byte, []int) { + return file_ide_proto_rawDescGZIP(), []int{0} +} + type GetConfigRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -109,6 +155,222 @@ func (x *GetConfigResponse) GetContent() string { return "" } +// TODO: import type from other packages +// EnvironmentVariable describes an env var as key/value pair +type EnvironmentVariable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *EnvironmentVariable) Reset() { + *x = EnvironmentVariable{} + if protoimpl.UnsafeEnabled { + mi := &file_ide_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnvironmentVariable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnvironmentVariable) ProtoMessage() {} + +func (x *EnvironmentVariable) ProtoReflect() protoreflect.Message { + mi := &file_ide_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnvironmentVariable.ProtoReflect.Descriptor instead. +func (*EnvironmentVariable) Descriptor() ([]byte, []int) { + return file_ide_proto_rawDescGZIP(), []int{2} +} + +func (x *EnvironmentVariable) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *EnvironmentVariable) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type ResolveWorkspaceConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type WorkspaceType `protobuf:"varint,1,opt,name=type,proto3,enum=ide_service_api.WorkspaceType" json:"type,omitempty"` + Context string `protobuf:"bytes,2,opt,name=context,proto3" json:"context,omitempty"` + IdeSettings string `protobuf:"bytes,3,opt,name=ide_settings,json=ideSettings,proto3" json:"ide_settings,omitempty"` + WorkspaceConfig string `protobuf:"bytes,4,opt,name=workspace_config,json=workspaceConfig,proto3" json:"workspace_config,omitempty"` +} + +func (x *ResolveWorkspaceConfigRequest) Reset() { + *x = ResolveWorkspaceConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ide_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveWorkspaceConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveWorkspaceConfigRequest) ProtoMessage() {} + +func (x *ResolveWorkspaceConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_ide_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResolveWorkspaceConfigRequest.ProtoReflect.Descriptor instead. +func (*ResolveWorkspaceConfigRequest) Descriptor() ([]byte, []int) { + return file_ide_proto_rawDescGZIP(), []int{3} +} + +func (x *ResolveWorkspaceConfigRequest) GetType() WorkspaceType { + if x != nil { + return x.Type + } + return WorkspaceType_REGULAR +} + +func (x *ResolveWorkspaceConfigRequest) GetContext() string { + if x != nil { + return x.Context + } + return "" +} + +func (x *ResolveWorkspaceConfigRequest) GetIdeSettings() string { + if x != nil { + return x.IdeSettings + } + return "" +} + +func (x *ResolveWorkspaceConfigRequest) GetWorkspaceConfig() string { + if x != nil { + return x.WorkspaceConfig + } + return "" +} + +type ResolveWorkspaceConfigResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Envvars []*EnvironmentVariable `protobuf:"bytes,1,rep,name=envvars,proto3" json:"envvars,omitempty"` + SupervisorImage string `protobuf:"bytes,2,opt,name=supervisor_image,json=supervisorImage,proto3" json:"supervisor_image,omitempty"` + WebImage string `protobuf:"bytes,3,opt,name=web_image,json=webImage,proto3" json:"web_image,omitempty"` + IdeImageLayers []string `protobuf:"bytes,4,rep,name=ide_image_layers,json=ideImageLayers,proto3" json:"ide_image_layers,omitempty"` + // control whether to configure default IDE for a user + RefererIde string `protobuf:"bytes,5,opt,name=referer_ide,json=refererIde,proto3" json:"referer_ide,omitempty"` + Tasks string `protobuf:"bytes,6,opt,name=tasks,proto3" json:"tasks,omitempty"` +} + +func (x *ResolveWorkspaceConfigResponse) Reset() { + *x = ResolveWorkspaceConfigResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ide_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResolveWorkspaceConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveWorkspaceConfigResponse) ProtoMessage() {} + +func (x *ResolveWorkspaceConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_ide_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResolveWorkspaceConfigResponse.ProtoReflect.Descriptor instead. +func (*ResolveWorkspaceConfigResponse) Descriptor() ([]byte, []int) { + return file_ide_proto_rawDescGZIP(), []int{4} +} + +func (x *ResolveWorkspaceConfigResponse) GetEnvvars() []*EnvironmentVariable { + if x != nil { + return x.Envvars + } + return nil +} + +func (x *ResolveWorkspaceConfigResponse) GetSupervisorImage() string { + if x != nil { + return x.SupervisorImage + } + return "" +} + +func (x *ResolveWorkspaceConfigResponse) GetWebImage() string { + if x != nil { + return x.WebImage + } + return "" +} + +func (x *ResolveWorkspaceConfigResponse) GetIdeImageLayers() []string { + if x != nil { + return x.IdeImageLayers + } + return nil +} + +func (x *ResolveWorkspaceConfigResponse) GetRefererIde() string { + if x != nil { + return x.RefererIde + } + return "" +} + +func (x *ResolveWorkspaceConfigResponse) GetTasks() string { + if x != nil { + return x.Tasks + } + return "" +} + var File_ide_proto protoreflect.FileDescriptor var file_ide_proto_rawDesc = []byte{ @@ -117,19 +379,62 @@ var file_ide_proto_rawDesc = []byte{ 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x32, - 0x62, 0x0a, 0x0a, 0x49, 0x44, 0x45, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x2e, 0x69, 0x64, 0x65, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, - 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, - 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0x47, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, - 0x2e, 0x69, 0x64, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x5a, - 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x70, - 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, 0x69, 0x64, 0x65, - 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, + 0x3f, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0xbb, 0x01, 0x0a, 0x1d, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1e, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x89, + 0x02, 0x0a, 0x1e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x76, 0x61, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x76, 0x61, 0x72, + 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x5f, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x70, + 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x77, 0x65, 0x62, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x77, 0x65, 0x62, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x64, 0x65, + 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x64, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x72, 0x49, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2a, 0x2a, 0x0a, 0x0d, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x52, + 0x45, 0x47, 0x55, 0x4c, 0x41, 0x52, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x45, 0x42, + 0x55, 0x49, 0x4c, 0x44, 0x10, 0x01, 0x32, 0xdf, 0x01, 0x0a, 0x0a, 0x49, 0x44, 0x45, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x21, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x16, 0x52, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x47, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x67, + 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2e, 0x69, 0x64, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, + 0x64, 0x2f, 0x69, 0x64, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x61, 0x70, + 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -144,19 +449,28 @@ func file_ide_proto_rawDescGZIP() []byte { return file_ide_proto_rawDescData } -var file_ide_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_ide_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_ide_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_ide_proto_goTypes = []interface{}{ - (*GetConfigRequest)(nil), // 0: ide_service_api.GetConfigRequest - (*GetConfigResponse)(nil), // 1: ide_service_api.GetConfigResponse + (WorkspaceType)(0), // 0: ide_service_api.WorkspaceType + (*GetConfigRequest)(nil), // 1: ide_service_api.GetConfigRequest + (*GetConfigResponse)(nil), // 2: ide_service_api.GetConfigResponse + (*EnvironmentVariable)(nil), // 3: ide_service_api.EnvironmentVariable + (*ResolveWorkspaceConfigRequest)(nil), // 4: ide_service_api.ResolveWorkspaceConfigRequest + (*ResolveWorkspaceConfigResponse)(nil), // 5: ide_service_api.ResolveWorkspaceConfigResponse } var file_ide_proto_depIdxs = []int32{ - 0, // 0: ide_service_api.IDEService.GetConfig:input_type -> ide_service_api.GetConfigRequest - 1, // 1: ide_service_api.IDEService.GetConfig:output_type -> ide_service_api.GetConfigResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 0, // 0: ide_service_api.ResolveWorkspaceConfigRequest.type:type_name -> ide_service_api.WorkspaceType + 3, // 1: ide_service_api.ResolveWorkspaceConfigResponse.envvars:type_name -> ide_service_api.EnvironmentVariable + 1, // 2: ide_service_api.IDEService.GetConfig:input_type -> ide_service_api.GetConfigRequest + 4, // 3: ide_service_api.IDEService.ResolveWorkspaceConfig:input_type -> ide_service_api.ResolveWorkspaceConfigRequest + 2, // 4: ide_service_api.IDEService.GetConfig:output_type -> ide_service_api.GetConfigResponse + 5, // 5: ide_service_api.IDEService.ResolveWorkspaceConfig:output_type -> ide_service_api.ResolveWorkspaceConfigResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_ide_proto_init() } @@ -189,19 +503,56 @@ func file_ide_proto_init() { return nil } } + file_ide_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnvironmentVariable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ide_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveWorkspaceConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ide_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResolveWorkspaceConfigResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ide_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, + NumEnums: 1, + NumMessages: 5, NumExtensions: 0, NumServices: 1, }, GoTypes: file_ide_proto_goTypes, DependencyIndexes: file_ide_proto_depIdxs, + EnumInfos: file_ide_proto_enumTypes, MessageInfos: file_ide_proto_msgTypes, }.Build() File_ide_proto = out.File diff --git a/components/ide-service-api/go/ide_grpc.pb.go b/components/ide-service-api/go/ide_grpc.pb.go index 3d25add4cc2940..00459ea003374c 100644 --- a/components/ide-service-api/go/ide_grpc.pb.go +++ b/components/ide-service-api/go/ide_grpc.pb.go @@ -27,6 +27,7 @@ const _ = grpc.SupportPackageIsVersion7 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type IDEServiceClient interface { GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error) + ResolveWorkspaceConfig(ctx context.Context, in *ResolveWorkspaceConfigRequest, opts ...grpc.CallOption) (*ResolveWorkspaceConfigResponse, error) } type iDEServiceClient struct { @@ -46,11 +47,21 @@ func (c *iDEServiceClient) GetConfig(ctx context.Context, in *GetConfigRequest, return out, nil } +func (c *iDEServiceClient) ResolveWorkspaceConfig(ctx context.Context, in *ResolveWorkspaceConfigRequest, opts ...grpc.CallOption) (*ResolveWorkspaceConfigResponse, error) { + out := new(ResolveWorkspaceConfigResponse) + err := c.cc.Invoke(ctx, "/ide_service_api.IDEService/ResolveWorkspaceConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // IDEServiceServer is the server API for IDEService service. // All implementations must embed UnimplementedIDEServiceServer // for forward compatibility type IDEServiceServer interface { GetConfig(context.Context, *GetConfigRequest) (*GetConfigResponse, error) + ResolveWorkspaceConfig(context.Context, *ResolveWorkspaceConfigRequest) (*ResolveWorkspaceConfigResponse, error) mustEmbedUnimplementedIDEServiceServer() } @@ -61,6 +72,9 @@ type UnimplementedIDEServiceServer struct { func (UnimplementedIDEServiceServer) GetConfig(context.Context, *GetConfigRequest) (*GetConfigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetConfig not implemented") } +func (UnimplementedIDEServiceServer) ResolveWorkspaceConfig(context.Context, *ResolveWorkspaceConfigRequest) (*ResolveWorkspaceConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveWorkspaceConfig not implemented") +} func (UnimplementedIDEServiceServer) mustEmbedUnimplementedIDEServiceServer() {} // UnsafeIDEServiceServer may be embedded to opt out of forward compatibility for this service. @@ -92,6 +106,24 @@ func _IDEService_GetConfig_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _IDEService_ResolveWorkspaceConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveWorkspaceConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IDEServiceServer).ResolveWorkspaceConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ide_service_api.IDEService/ResolveWorkspaceConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IDEServiceServer).ResolveWorkspaceConfig(ctx, req.(*ResolveWorkspaceConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + // IDEService_ServiceDesc is the grpc.ServiceDesc for IDEService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -103,6 +135,10 @@ var IDEService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetConfig", Handler: _IDEService_GetConfig_Handler, }, + { + MethodName: "ResolveWorkspaceConfig", + Handler: _IDEService_ResolveWorkspaceConfig_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ide.proto", diff --git a/components/ide-service-api/ide.proto b/components/ide-service-api/ide.proto index 5692facc6af93c..ad7b0607c41105 100644 --- a/components/ide-service-api/ide.proto +++ b/components/ide-service-api/ide.proto @@ -11,6 +11,7 @@ option java_package = "io.gitpod.ideservice.api"; service IDEService { rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {} + rpc ResolveWorkspaceConfig(ResolveWorkspaceConfigRequest) returns (ResolveWorkspaceConfigResponse) {} } message GetConfigRequest {} @@ -18,3 +19,33 @@ message GetConfigRequest {} message GetConfigResponse { string content = 1; } + +// TODO: import type from other packages +// EnvironmentVariable describes an env var as key/value pair +message EnvironmentVariable { + string name = 1; + string value = 2; +} + +enum WorkspaceType { + REGULAR = 0; + PREBUILD = 1; +} + + +message ResolveWorkspaceConfigRequest { + WorkspaceType type = 1; + string context = 2; + string ide_settings = 3; + string workspace_config = 4; +} + +message ResolveWorkspaceConfigResponse { + repeated EnvironmentVariable envvars = 1; + string supervisor_image = 2; + string web_image = 3; + repeated string ide_image_layers = 4; + // control whether to configure default IDE for a user + string referer_ide = 5; + string tasks = 6; +} diff --git a/components/ide-service-api/typescript/src/ide.pb.ts b/components/ide-service-api/typescript/src/ide.pb.ts index c1afa62132c5c5..85adb0466ac94b 100644 --- a/components/ide-service-api/typescript/src/ide.pb.ts +++ b/components/ide-service-api/typescript/src/ide.pb.ts @@ -10,6 +10,51 @@ import * as _m0 from "protobufjs/minimal"; export const protobufPackage = "ide_service_api"; +export enum WorkspaceType { + REGULAR = "REGULAR", + PREBUILD = "PREBUILD", + UNRECOGNIZED = "UNRECOGNIZED", +} + +export function workspaceTypeFromJSON(object: any): WorkspaceType { + switch (object) { + case 0: + case "REGULAR": + return WorkspaceType.REGULAR; + case 1: + case "PREBUILD": + return WorkspaceType.PREBUILD; + case -1: + case "UNRECOGNIZED": + default: + return WorkspaceType.UNRECOGNIZED; + } +} + +export function workspaceTypeToJSON(object: WorkspaceType): string { + switch (object) { + case WorkspaceType.REGULAR: + return "REGULAR"; + case WorkspaceType.PREBUILD: + return "PREBUILD"; + case WorkspaceType.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export function workspaceTypeToNumber(object: WorkspaceType): number { + switch (object) { + case WorkspaceType.REGULAR: + return 0; + case WorkspaceType.PREBUILD: + return 1; + case WorkspaceType.UNRECOGNIZED: + default: + return -1; + } +} + export interface GetConfigRequest { } @@ -17,6 +62,32 @@ export interface GetConfigResponse { content: string; } +/** + * TODO: import type from other packages + * EnvironmentVariable describes an env var as key/value pair + */ +export interface EnvironmentVariable { + name: string; + value: string; +} + +export interface ResolveWorkspaceConfigRequest { + type: WorkspaceType; + context: string; + ideSettings: string; + workspaceConfig: string; +} + +export interface ResolveWorkspaceConfigResponse { + envvars: EnvironmentVariable[]; + supervisorImage: string; + webImage: string; + ideImageLayers: string[]; + /** control whether to configure default IDE for a user */ + refererIde: string; + tasks: string; +} + function createBaseGetConfigRequest(): GetConfigRequest { return {}; } @@ -103,6 +174,242 @@ export const GetConfigResponse = { }, }; +function createBaseEnvironmentVariable(): EnvironmentVariable { + return { name: "", value: "" }; +} + +export const EnvironmentVariable = { + encode(message: EnvironmentVariable, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): EnvironmentVariable { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseEnvironmentVariable(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + case 2: + message.value = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): EnvironmentVariable { + return { + name: isSet(object.name) ? String(object.name) : "", + value: isSet(object.value) ? String(object.value) : "", + }; + }, + + toJSON(message: EnvironmentVariable): unknown { + const obj: any = {}; + message.name !== undefined && (obj.name = message.name); + message.value !== undefined && (obj.value = message.value); + return obj; + }, + + fromPartial(object: DeepPartial): EnvironmentVariable { + const message = createBaseEnvironmentVariable(); + message.name = object.name ?? ""; + message.value = object.value ?? ""; + return message; + }, +}; + +function createBaseResolveWorkspaceConfigRequest(): ResolveWorkspaceConfigRequest { + return { type: WorkspaceType.REGULAR, context: "", ideSettings: "", workspaceConfig: "" }; +} + +export const ResolveWorkspaceConfigRequest = { + encode(message: ResolveWorkspaceConfigRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== WorkspaceType.REGULAR) { + writer.uint32(8).int32(workspaceTypeToNumber(message.type)); + } + if (message.context !== "") { + writer.uint32(18).string(message.context); + } + if (message.ideSettings !== "") { + writer.uint32(26).string(message.ideSettings); + } + if (message.workspaceConfig !== "") { + writer.uint32(34).string(message.workspaceConfig); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ResolveWorkspaceConfigRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseResolveWorkspaceConfigRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.type = workspaceTypeFromJSON(reader.int32()); + break; + case 2: + message.context = reader.string(); + break; + case 3: + message.ideSettings = reader.string(); + break; + case 4: + message.workspaceConfig = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ResolveWorkspaceConfigRequest { + return { + type: isSet(object.type) ? workspaceTypeFromJSON(object.type) : WorkspaceType.REGULAR, + context: isSet(object.context) ? String(object.context) : "", + ideSettings: isSet(object.ideSettings) ? String(object.ideSettings) : "", + workspaceConfig: isSet(object.workspaceConfig) ? String(object.workspaceConfig) : "", + }; + }, + + toJSON(message: ResolveWorkspaceConfigRequest): unknown { + const obj: any = {}; + message.type !== undefined && (obj.type = workspaceTypeToJSON(message.type)); + message.context !== undefined && (obj.context = message.context); + message.ideSettings !== undefined && (obj.ideSettings = message.ideSettings); + message.workspaceConfig !== undefined && (obj.workspaceConfig = message.workspaceConfig); + return obj; + }, + + fromPartial(object: DeepPartial): ResolveWorkspaceConfigRequest { + const message = createBaseResolveWorkspaceConfigRequest(); + message.type = object.type ?? WorkspaceType.REGULAR; + message.context = object.context ?? ""; + message.ideSettings = object.ideSettings ?? ""; + message.workspaceConfig = object.workspaceConfig ?? ""; + return message; + }, +}; + +function createBaseResolveWorkspaceConfigResponse(): ResolveWorkspaceConfigResponse { + return { envvars: [], supervisorImage: "", webImage: "", ideImageLayers: [], refererIde: "", tasks: "" }; +} + +export const ResolveWorkspaceConfigResponse = { + encode(message: ResolveWorkspaceConfigResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.envvars) { + EnvironmentVariable.encode(v!, writer.uint32(10).fork()).ldelim(); + } + if (message.supervisorImage !== "") { + writer.uint32(18).string(message.supervisorImage); + } + if (message.webImage !== "") { + writer.uint32(26).string(message.webImage); + } + for (const v of message.ideImageLayers) { + writer.uint32(34).string(v!); + } + if (message.refererIde !== "") { + writer.uint32(42).string(message.refererIde); + } + if (message.tasks !== "") { + writer.uint32(50).string(message.tasks); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ResolveWorkspaceConfigResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseResolveWorkspaceConfigResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.envvars.push(EnvironmentVariable.decode(reader, reader.uint32())); + break; + case 2: + message.supervisorImage = reader.string(); + break; + case 3: + message.webImage = reader.string(); + break; + case 4: + message.ideImageLayers.push(reader.string()); + break; + case 5: + message.refererIde = reader.string(); + break; + case 6: + message.tasks = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ResolveWorkspaceConfigResponse { + return { + envvars: Array.isArray(object?.envvars) ? object.envvars.map((e: any) => EnvironmentVariable.fromJSON(e)) : [], + supervisorImage: isSet(object.supervisorImage) ? String(object.supervisorImage) : "", + webImage: isSet(object.webImage) ? String(object.webImage) : "", + ideImageLayers: Array.isArray(object?.ideImageLayers) ? object.ideImageLayers.map((e: any) => String(e)) : [], + refererIde: isSet(object.refererIde) ? String(object.refererIde) : "", + tasks: isSet(object.tasks) ? String(object.tasks) : "", + }; + }, + + toJSON(message: ResolveWorkspaceConfigResponse): unknown { + const obj: any = {}; + if (message.envvars) { + obj.envvars = message.envvars.map((e) => e ? EnvironmentVariable.toJSON(e) : undefined); + } else { + obj.envvars = []; + } + message.supervisorImage !== undefined && (obj.supervisorImage = message.supervisorImage); + message.webImage !== undefined && (obj.webImage = message.webImage); + if (message.ideImageLayers) { + obj.ideImageLayers = message.ideImageLayers.map((e) => e); + } else { + obj.ideImageLayers = []; + } + message.refererIde !== undefined && (obj.refererIde = message.refererIde); + message.tasks !== undefined && (obj.tasks = message.tasks); + return obj; + }, + + fromPartial(object: DeepPartial): ResolveWorkspaceConfigResponse { + const message = createBaseResolveWorkspaceConfigResponse(); + message.envvars = object.envvars?.map((e) => EnvironmentVariable.fromPartial(e)) || []; + message.supervisorImage = object.supervisorImage ?? ""; + message.webImage = object.webImage ?? ""; + message.ideImageLayers = object.ideImageLayers?.map((e) => e) || []; + message.refererIde = object.refererIde ?? ""; + message.tasks = object.tasks ?? ""; + return message; + }, +}; + export type IDEServiceDefinition = typeof IDEServiceDefinition; export const IDEServiceDefinition = { name: "IDEService", @@ -116,15 +423,31 @@ export const IDEServiceDefinition = { responseStream: false, options: {}, }, + resolveWorkspaceConfig: { + name: "ResolveWorkspaceConfig", + requestType: ResolveWorkspaceConfigRequest, + requestStream: false, + responseType: ResolveWorkspaceConfigResponse, + responseStream: false, + options: {}, + }, }, } as const; export interface IDEServiceServiceImplementation { getConfig(request: GetConfigRequest, context: CallContext & CallContextExt): Promise>; + resolveWorkspaceConfig( + request: ResolveWorkspaceConfigRequest, + context: CallContext & CallContextExt, + ): Promise>; } export interface IDEServiceClient { getConfig(request: DeepPartial, options?: CallOptions & CallOptionsExt): Promise; + resolveWorkspaceConfig( + request: DeepPartial, + options?: CallOptions & CallOptionsExt, + ): Promise; } export interface DataLoaderOptions { diff --git a/components/ide-service/BUILD.yaml b/components/ide-service/BUILD.yaml index 7767aa7e9726ca..26dafc997025ff 100644 --- a/components/ide-service/BUILD.yaml +++ b/components/ide-service/BUILD.yaml @@ -3,6 +3,7 @@ packages: type: go deps: - components/common-go:lib + - components/gitpod-protocol/go:lib - components/ide-service-api/go:lib srcs: - "**/*.go" @@ -10,6 +11,7 @@ packages: - "go.sum" - "pkg/server/schema.json" - "pkg/server/testdata/**" + - "example-ide-config.json" env: - CGO_ENABLED=0 - GOOS=linux diff --git a/components/ide-service/example-ide-config.json b/components/ide-service/example-ide-config.json index e9a58429783a4d..77dab087397616 100644 --- a/components/ide-service/example-ide-config.json +++ b/components/ide-service/example-ide-config.json @@ -9,7 +9,7 @@ "logo": "https://ide.gitpod.io/image/ide-logo/vscode.svg", "label": "Browser", "image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", - "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/code:nightly" + "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/code:nightly@sha256:8669f6ab8dceefde11138bf4bc0ee73b934b2cc47e6135426f05fb4343ec5ab1" }, "code-desktop": { "orderKey": "02", @@ -25,7 +25,9 @@ "type": "desktop", "logo": "https://ide.gitpod.io/image/ide-logo/golandLogo.svg", "image": "eu.gcr.io/gitpod-core-dev/build/ide/goland:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", - "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/goland:latest" + "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/goland:latest@sha256:e07524e52089829dc8d3b38f7d18fb51b24f07aed7d8e4e6e447899687978d43", + "pluginImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a", + "pluginLatestImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a-latest" }, "intellij": { "orderKey": "04", @@ -33,7 +35,9 @@ "type": "desktop", "logo": "https://ide.gitpod.io/image/ide-logo/intellijIdeaLogo.svg", "image": "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", - "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/intellij:latest" + "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/intellij:latest@sha256:e07524e52089829dc8d3b38f7d18fb51b24f07aed7d8e4e6e447899687978d43", + "pluginImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a", + "pluginLatestImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a-latest" }, "phpstorm": { "orderKey": "07", @@ -41,7 +45,9 @@ "type": "desktop", "logo": "https://ide.gitpod.io/image/ide-logo/phpstormLogo.svg", "image": "eu.gcr.io/gitpod-core-dev/build/ide/phpstorm:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", - "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/phpstorm:latest" + "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/phpstorm:latest@sha256:e07524e52089829dc8d3b38f7d18fb51b24f07aed7d8e4e6e447899687978d43", + "pluginImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a", + "pluginLatestImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a-latest" }, "pycharm": { "orderKey": "06", @@ -49,7 +55,9 @@ "type": "desktop", "logo": "https://ide.gitpod.io/image/ide-logo/pycharmLogo.svg", "image": "eu.gcr.io/gitpod-core-dev/build/ide/pycharm:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", - "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/pycharm:latest" + "latestImage": "eu.gcr.io/gitpod-core-dev/build/ide/pycharm:latest@sha256:e07524e52089829dc8d3b38f7d18fb51b24f07aed7d8e4e6e447899687978d43", + "pluginImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a", + "pluginLatestImage": "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a-latest" } }, "defaultIde": "code", diff --git a/components/ide-service/go.mod b/components/ide-service/go.mod index d13c6dcaf0f003..44ff69ac23670d 100644 --- a/components/ide-service/go.mod +++ b/components/ide-service/go.mod @@ -6,6 +6,7 @@ require ( github.com/containerd/containerd v1.5.7 github.com/docker/distribution v2.7.1+incompatible github.com/gitpod-io/gitpod/common-go v0.0.0-00010101000000-000000000000 + github.com/gitpod-io/gitpod/gitpod-protocol v0.0.0-00010101000000-000000000000 github.com/gitpod-io/gitpod/ide-service-api v0.0.0-00010101000000-000000000000 github.com/heptiolabs/healthcheck v0.0.0-20211123025425-613501dd5deb github.com/prometheus/client_golang v1.13.0 @@ -18,11 +19,14 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/go-test/deep v1.0.5 // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect @@ -39,6 +43,7 @@ require ( github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/slok/go-http-metrics v0.10.0 // indirect + github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.7.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect @@ -56,3 +61,5 @@ require ( replace github.com/gitpod-io/gitpod/common-go => ../common-go // leeway replace github.com/gitpod-io/gitpod/ide-service-api => ../ide-service-api/go // leeway + +replace github.com/gitpod-io/gitpod/gitpod-protocol => ../gitpod-protocol/go // leeway diff --git a/components/ide-service/go.sum b/components/ide-service/go.sum index 6af72a6ede9828..aef0209aeea78e 100644 --- a/components/ide-service/go.sum +++ b/components/ide-service/go.sum @@ -95,6 +95,8 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7 github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -315,6 +317,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -369,7 +373,10 @@ github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -587,6 +594,8 @@ github.com/slok/go-http-metrics v0.10.0/go.mod h1:lFqdaS4kWMfUKCSukjC47PdCeTk+hX github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 h1:marA1XQDC7N870zmSFIoHZpIUduK80USeY0Rkuflgp4= +github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra5qMlU4gTRwIo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -650,6 +659,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -711,6 +721,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -774,6 +785,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -918,6 +930,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/components/ide-service/pkg/server/server.go b/components/ide-service/pkg/server/server.go index 23c37a3bbed57a..8a17ac0b21e405 100644 --- a/components/ide-service/pkg/server/server.go +++ b/components/ide-service/pkg/server/server.go @@ -10,11 +10,14 @@ import ( "fmt" "os" "path/filepath" + "reflect" + "strings" "time" "github.com/gitpod-io/gitpod/common-go/baseserver" "github.com/gitpod-io/gitpod/common-go/log" "github.com/gitpod-io/gitpod/common-go/watch" + gitpodapi "github.com/gitpod-io/gitpod/gitpod-protocol" api "github.com/gitpod-io/gitpod/ide-service-api" "github.com/gitpod-io/gitpod/ide-service-api/config" "github.com/heptiolabs/healthcheck" @@ -173,3 +176,283 @@ func grpcProbe(cfg baseserver.ServerConfiguration) func() error { return fmt.Errorf("grpc service not ready") } } + +type IDESettings struct { + DefaultIde string `json:"defaultIde,omitempty"` + UseLatestVersion bool `json:"useLatestVersion,omitempty"` +} + +type WorkspaceContext struct { + Referrer string `json:"referrer,omitempty"` + ReferrerIde string `json:"referrerIde,omitempty"` +} + +var JetbrainsCode map[string]string + +func init() { + JetbrainsCode = make(map[string]string) + JetbrainsCode["intellij"] = "IIU" + JetbrainsCode["goland"] = "GO" + JetbrainsCode["pycharm"] = "PCP" + JetbrainsCode["phpstorm"] = "PS" + JetbrainsCode["rubymine"] = "RM" + JetbrainsCode["webstorm"] = "WS" + JetbrainsCode["rider"] = "RD" + JetbrainsCode["clion"] = "CL" +} + +func (s *IDEServiceServer) resolveReferrerIDE(ideConfig *config.IDEConfig, wsCtx *WorkspaceContext, chosenIDEName string) (ideName string, ideOption *config.IDEOption) { + if wsCtx == nil || wsCtx.Referrer == "" { + return + } + + client, ok := ideConfig.IdeOptions.Clients[wsCtx.Referrer] + if !ok { + return + } + + getValidIDEOption := func(ideName string) (*config.IDEOption, bool) { + optionToCheck, ok := ideConfig.IdeOptions.Options[ideName] + if !ok { + return nil, false + } + for _, ide := range client.DesktopIDEs { + if ide == ideName { + return &optionToCheck, true + } + } + return nil, false + } + + ideOption, ok = getValidIDEOption(wsCtx.ReferrerIde) + if ok { + ideName = wsCtx.ReferrerIde + return + } + ideOption, ok = getValidIDEOption(chosenIDEName) + if ok { + ideName = chosenIDEName + return + } + ideOption, ok = getValidIDEOption(client.DefaultDesktopIDE) + if ok { + ideName = client.DefaultDesktopIDE + return + } + return +} + +func (s *IDEServiceServer) ResolveWorkspaceConfig(ctx context.Context, req *api.ResolveWorkspaceConfigRequest) (resp *api.ResolveWorkspaceConfigResponse, err error) { + log.WithField("req", req).Debug("receive ResolveWorkspaceConfig request") + + // make a copy for ref ideConfig, it's safe because we replace ref in update config + ideConfig := s.ideConfig + + var defaultIde *config.IDEOption + + if ide, ok := ideConfig.IdeOptions.Options[ideConfig.IdeOptions.DefaultIde]; !ok { + // I think it never happen, we have a check to make sure all DefaultIDE should be in Options + log.WithError(err).WithField("defaultIDE", ideConfig.IdeOptions.DefaultIde).Error("IDE configuration corrupt, cannot found defaultIDE") + return nil, fmt.Errorf("IDE configuration corrupt") + } else { + defaultIde = &ide + } + + resp = &api.ResolveWorkspaceConfigResponse{ + SupervisorImage: ideConfig.SupervisorImage, + WebImage: defaultIde.Image, + } + + // TODO: reconsider this + // if req.Type != api.WorkspaceType_REGULAR { + // return resp, nil + // } + + var wsConfig *gitpodapi.GitpodConfig + var wsContext *WorkspaceContext + var ideSettings *IDESettings + + if req.IdeSettings != "" { + if err := json.Unmarshal([]byte(req.IdeSettings), &ideSettings); err != nil { + log.WithError(err).WithField("ideSetting", req.IdeSettings).Error("failed to parse ide settings") + } + } + if req.WorkspaceConfig != "" { + if err := json.Unmarshal([]byte(req.WorkspaceConfig), &wsConfig); err != nil { + log.WithError(err).WithField("workspaceConfig", req.WorkspaceConfig).Error("failed to parse workspace config") + } + } + if req.Context != "" { + if err := json.Unmarshal([]byte(req.Context), &wsContext); err != nil { + log.WithError(err).WithField("context", req.Context).Error("failed to parse context") + } + } + + userIdeName := "" + useLatest := false + + if ideSettings != nil { + userIdeName = ideSettings.DefaultIde + useLatest = ideSettings.UseLatestVersion + } + + chosenIDE := defaultIde + + getUserIDEImage := func(ideOption *config.IDEOption) string { + if useLatest && ideOption.LatestImage != "" { + return ideOption.LatestImage + } + + return ideOption.Image + } + + getUserPluginImage := func(ideOption *config.IDEOption) string { + if useLatest && ideOption.PluginLatestImage != "" { + return ideOption.PluginLatestImage + } + + return ideOption.PluginImage + } + + if userIdeName != "" { + if ide, ok := ideConfig.IdeOptions.Options[userIdeName]; ok { + chosenIDE = &ide + + // TODO: Currently this variable reflects the IDE selected in + // user's settings for backward compatibility but in the future + // we want to make it represent the actual IDE. + ideAlias := api.EnvironmentVariable{ + Name: "GITPOD_IDE_ALIAS", + Value: userIdeName, + } + resp.Envvars = append(resp.Envvars, &ideAlias) + } + } + + // we always need WebImage for when the user chooses a desktop ide + resp.WebImage = getUserIDEImage(defaultIde) + + var desktopImageLayer string + var desktopPluginImageLayer string + if chosenIDE.Type == config.IDETypeDesktop { + desktopImageLayer = getUserIDEImage(chosenIDE) + desktopPluginImageLayer = getUserPluginImage(chosenIDE) + } else { + resp.WebImage = getUserIDEImage(chosenIDE) + } + + ideName, referrer := s.resolveReferrerIDE(ideConfig, wsContext, userIdeName) + if ideName != "" { + resp.RefererIde = ideName + desktopImageLayer = getUserIDEImage(referrer) + desktopPluginImageLayer = getUserPluginImage(referrer) + } + + if desktopImageLayer != "" { + resp.IdeImageLayers = append(resp.IdeImageLayers, desktopImageLayer) + if desktopPluginImageLayer != "" { + resp.IdeImageLayers = append(resp.IdeImageLayers, desktopPluginImageLayer) + } + } + + jbGW, ok := ideConfig.IdeOptions.Clients["jetbrains-gateway"] + if ok { + warmUpTask := "" + for _, alias := range jbGW.DesktopIDEs { + prebuilds := getPrebuilds(wsConfig, alias) + if prebuilds != nil { + if prebuilds.Version != "latest" { + template := ` +echo 'warming up stable release of ${key}...' +echo 'downloading stable ${key} backend...' +mkdir /tmp/backend +curl -sSLo /tmp/backend/backend.tar.gz "https://download.jetbrains.com/product?type=release&distribution=linux&code=${productCode}" +tar -xf /tmp/backend/backend.tar.gz --strip-components=1 --directory /tmp/backend + +echo 'configuring JB system config and caches aligned with runtime...' +printf '\nshared.indexes.download.auto.consent=true' >> "/tmp/backend/bin/idea.properties" +unset JAVA_TOOL_OPTIONS +export IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains +export IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains + +echo 'running stable ${key} backend in warmup mode...' +/tmp/backend/bin/remote-dev-server.sh warmup "$GITPOD_REPO_ROOT" + +echo 'removing stable ${key} backend...' +rm -rf /tmp/backend +` + if code, ok := JetbrainsCode[alias]; ok { + template = strings.ReplaceAll(template, "${key}", alias) + template = strings.ReplaceAll(template, "${productCode}", code) + warmUpTask += template + } + } + + if prebuilds.Version != "stable" { + template := ` +echo 'warming up latest release of ${key}...' +echo 'downloading latest ${key} backend...' +mkdir /tmp/backend-latest +curl -sSLo /tmp/backend-latest/backend-latest.tar.gz "https://download.jetbrains.com/product?type=release,eap,rc&distribution=linux&code=${productCode}" +tar -xf /tmp/backend-latest/backend-latest.tar.gz --strip-components=1 --directory /tmp/backend-latest + +echo 'configuring JB system config and caches aligned with runtime...' +printf '\nshared.indexes.download.auto.consent=true' >> "/tmp/backend-latest/bin/idea.properties" +unset JAVA_TOOL_OPTIONS +export IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains-latest +export IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains-latest + +echo 'running ${key} backend in warmup mode...' +/tmp/backend-latest/bin/remote-dev-server.sh warmup "$GITPOD_REPO_ROOT" + +echo 'removing latest ${key} backend...' +rm -rf /tmp/backend-latest +` + if code, ok := JetbrainsCode[alias]; ok { + template = strings.ReplaceAll(template, "${key}", alias) + template = strings.ReplaceAll(template, "${productCode}", code) + warmUpTask += template + } + } + } + } + if warmUpTask != "" { + warmUpEncoded, err := json.Marshal([]gitpodapi.TaskConfig{{ + Init: strings.TrimSpace(warmUpTask), + }}) + if err != nil { + log.WithError(err).Error("cannot marshal warm up task") + } + + resp.Tasks = string(warmUpEncoded) + } + } + return +} + +func getPrebuilds(config *gitpodapi.GitpodConfig, alias string) *gitpodapi.Prebuilds { + if config == nil || config.Jetbrains == nil { + return nil + } + productConfig := getProductConfig(config, alias) + if productConfig == nil { + return nil + } + return productConfig.Prebuilds +} + +func getProductConfig(config *gitpodapi.GitpodConfig, alias string) *gitpodapi.JetbrainsProduct { + defer func() { + if err := recover(); err != nil { + log.WithField("error", err).WithField("alias", alias).Error("failed to extract JB product config") + } + }() + v := reflect.ValueOf(*config.Jetbrains).FieldByNameFunc(func(s string) bool { + return strings.ToLower(s) == alias + }).Interface() + productConfig, ok := v.(*gitpodapi.JetbrainsProduct) + if !ok { + return nil + } + return productConfig +} diff --git a/components/ide-service/pkg/server/server_test.go b/components/ide-service/pkg/server/server_test.go new file mode 100644 index 00000000000000..f2674686b67182 --- /dev/null +++ b/components/ide-service/pkg/server/server_test.go @@ -0,0 +1,54 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License-AGPL.txt in the project root for license information. + +package server + +import ( + "context" + "testing" + "time" + + "github.com/gitpod-io/gitpod/common-go/baseserver" + api "github.com/gitpod-io/gitpod/ide-service-api" + "github.com/gitpod-io/gitpod/ide-service-api/config" + + ctesting "github.com/gitpod-io/gitpod/common-go/testing" +) + +func TestResolveWorkspaceConfig(t *testing.T) { + type fixture struct { + api.ResolveWorkspaceConfigRequest + } + type gold struct { + Resp *api.ResolveWorkspaceConfigResponse + Err string + } + + cfg := &config.ServiceConfiguration{ + Server: &baseserver.Configuration{}, + IDEConfigPath: "../../example-ide-config.json", + } + server := New(cfg) + server.readIDEConfig(context.Background(), true) + + test := ctesting.FixtureTest{ + T: t, + Path: "testdata/resolve_ws_config_*.json", + Test: func(t *testing.T, input any) interface{} { + fixture := input.(*fixture) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + resp, err := server.ResolveWorkspaceConfig(ctx, &fixture.ResolveWorkspaceConfigRequest) + if err != nil { + return &gold{Err: err.Error()} + } + return &gold{Resp: resp, Err: ""} + }, + Fixture: func() interface{} { return &fixture{} }, + Gold: func() interface{} { return &gold{} }, + } + test.Run() +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_imagebuild.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_imagebuild.golden new file mode 100644 index 00000000000000..22e8d5a9e166fc --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_imagebuild.golden @@ -0,0 +1,13 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "code" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_imagebuild.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_imagebuild.json new file mode 100644 index 00000000000000..6504c0e5bfc45a --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_imagebuild.json @@ -0,0 +1,6 @@ +{ + "type": 1, + "context": "{\"ref\":\"jb-proxy-test\",\"refType\":\"branch\",\"isFile\":false,\"path\":\"\",\"title\":\"andreafalzetti/parcel-demo - jb-proxy-test\",\"revision\":\"3e5e8ce8e2133d9b82259f978cfd10e5b68cc9b4\",\"repository\":{\"cloneUrl\":\"https://github.com/andreafalzetti/parcel-demo.git\",\"host\":\"github.com\",\"name\":\"parcel-demo\",\"owner\":\"andreafalzetti\",\"private\":false,\"fork\":{\"parent\":{\"cloneUrl\":\"https://github.com/akosyakov/parcel-demo.git\",\"host\":\"github.com\",\"name\":\"parcel-demo\",\"owner\":\"akosyakov\",\"private\":false}}},\"normalizedContextURL\":\"https://github.com/andreafalzetti/parcel-demo/tree/jb-proxy-test\",\"checkoutLocation\":\"parcel-demo\",\"upstreamRemoteURI\":\"https://github.com/akosyakov/parcel-demo.git\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"code\",\"useLatestVersion\":false}", + "workspace_config": "{\"image\":\"gitpod/workspace-dotnet:latest\",\"tasks\":[{\"command\":\"sudo tinyproxy\\nsudo tail -f /var/log/tinyproxy/tinyproxy.log\\n\"}],\"jetbrains\":{\"intellij\":{\"vmoptions\":\"-Didea.log.debug.categories=#com.intellij.util\",\"plugins\":[\"com.haulmont.jpab\"]}},\"_origin\":\"repo\",\"vscode\":{\"extensions\":[]}}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild.golden new file mode 100644 index 00000000000000..22e8d5a9e166fc --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild.golden @@ -0,0 +1,13 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "code" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild.json new file mode 100644 index 00000000000000..6504c0e5bfc45a --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild.json @@ -0,0 +1,6 @@ +{ + "type": 1, + "context": "{\"ref\":\"jb-proxy-test\",\"refType\":\"branch\",\"isFile\":false,\"path\":\"\",\"title\":\"andreafalzetti/parcel-demo - jb-proxy-test\",\"revision\":\"3e5e8ce8e2133d9b82259f978cfd10e5b68cc9b4\",\"repository\":{\"cloneUrl\":\"https://github.com/andreafalzetti/parcel-demo.git\",\"host\":\"github.com\",\"name\":\"parcel-demo\",\"owner\":\"andreafalzetti\",\"private\":false,\"fork\":{\"parent\":{\"cloneUrl\":\"https://github.com/akosyakov/parcel-demo.git\",\"host\":\"github.com\",\"name\":\"parcel-demo\",\"owner\":\"akosyakov\",\"private\":false}}},\"normalizedContextURL\":\"https://github.com/andreafalzetti/parcel-demo/tree/jb-proxy-test\",\"checkoutLocation\":\"parcel-demo\",\"upstreamRemoteURI\":\"https://github.com/akosyakov/parcel-demo.git\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"code\",\"useLatestVersion\":false}", + "workspace_config": "{\"image\":\"gitpod/workspace-dotnet:latest\",\"tasks\":[{\"command\":\"sudo tinyproxy\\nsudo tail -f /var/log/tinyproxy/tinyproxy.log\\n\"}],\"jetbrains\":{\"intellij\":{\"vmoptions\":\"-Didea.log.debug.categories=#com.intellij.util\",\"plugins\":[\"com.haulmont.jpab\"]}},\"_origin\":\"repo\",\"vscode\":{\"extensions\":[]}}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_intellij.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_intellij.golden new file mode 100644 index 00000000000000..a7b2e673ff4482 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_intellij.golden @@ -0,0 +1,18 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "intellij" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "tasks": "[{\"init\":\"echo 'warming up stable release of intellij...'\\necho 'downloading stable intellij backend...'\\nmkdir /tmp/backend\\ncurl -sSLo /tmp/backend/backend.tar.gz \\\"https://download.jetbrains.com/product?type=release\\u0026distribution=linux\\u0026code=IIU\\\"\\ntar -xf /tmp/backend/backend.tar.gz --strip-components=1 --directory /tmp/backend\\n\\necho 'configuring JB system config and caches aligned with runtime...'\\nprintf '\\\\nshared.indexes.download.auto.consent=true' \\u003e\\u003e \\\"/tmp/backend/bin/idea.properties\\\"\\nunset JAVA_TOOL_OPTIONS\\nexport IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains\\nexport IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains\\n\\necho 'running stable intellij backend in warmup mode...'\\n/tmp/backend/bin/remote-dev-server.sh warmup \\\"$GITPOD_REPO_ROOT\\\"\\n\\necho 'removing stable intellij backend...'\\nrm -rf /tmp/backend\\n\\necho 'warming up latest release of intellij...'\\necho 'downloading latest intellij backend...'\\nmkdir /tmp/backend-latest\\ncurl -sSLo /tmp/backend-latest/backend-latest.tar.gz \\\"https://download.jetbrains.com/product?type=release,eap,rc\\u0026distribution=linux\\u0026code=IIU\\\"\\ntar -xf /tmp/backend-latest/backend-latest.tar.gz --strip-components=1 --directory /tmp/backend-latest\\n\\necho 'configuring JB system config and caches aligned with runtime...'\\nprintf '\\\\nshared.indexes.download.auto.consent=true' \\u003e\\u003e \\\"/tmp/backend-latest/bin/idea.properties\\\"\\nunset JAVA_TOOL_OPTIONS\\nexport IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains-latest\\nexport IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains-latest\\n\\necho 'running intellij backend in warmup mode...'\\n/tmp/backend-latest/bin/remote-dev-server.sh warmup \\\"$GITPOD_REPO_ROOT\\\"\\n\\necho 'removing latest intellij backend...'\\nrm -rf /tmp/backend-latest\"}]" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_intellij.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_intellij.json new file mode 100644 index 00000000000000..29006e4670f1ae --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_intellij.json @@ -0,0 +1,6 @@ +{ + "type": 1, + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"intellij\",\"useLatestVersion\":false}", + "workspace_config": "{\"tasks\":[{\"init\":\"echo 'init script'\",\"command\":\"echo 'start script'\"}],\"jetbrains\":{\"intellij\":{\"prebuilds\":{\"version\":\"both\"}}},\"_origin\":\"repo\",\"image\":\"docker.io/gitpod/workspace-full:latest\",\"vscode\":{\"extensions\":[]}}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_multiple_ide.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_multiple_ide.golden new file mode 100644 index 00000000000000..1b93fe9234ba98 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_multiple_ide.golden @@ -0,0 +1,18 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "intellij" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "tasks": "[{\"init\":\"echo 'warming up stable release of intellij...'\\necho 'downloading stable intellij backend...'\\nmkdir /tmp/backend\\ncurl -sSLo /tmp/backend/backend.tar.gz \\\"https://download.jetbrains.com/product?type=release\\u0026distribution=linux\\u0026code=IIU\\\"\\ntar -xf /tmp/backend/backend.tar.gz --strip-components=1 --directory /tmp/backend\\n\\necho 'configuring JB system config and caches aligned with runtime...'\\nprintf '\\\\nshared.indexes.download.auto.consent=true' \\u003e\\u003e \\\"/tmp/backend/bin/idea.properties\\\"\\nunset JAVA_TOOL_OPTIONS\\nexport IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains\\nexport IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains\\n\\necho 'running stable intellij backend in warmup mode...'\\n/tmp/backend/bin/remote-dev-server.sh warmup \\\"$GITPOD_REPO_ROOT\\\"\\n\\necho 'removing stable intellij backend...'\\nrm -rf /tmp/backend\\n\\necho 'warming up stable release of goland...'\\necho 'downloading stable goland backend...'\\nmkdir /tmp/backend\\ncurl -sSLo /tmp/backend/backend.tar.gz \\\"https://download.jetbrains.com/product?type=release\\u0026distribution=linux\\u0026code=GO\\\"\\ntar -xf /tmp/backend/backend.tar.gz --strip-components=1 --directory /tmp/backend\\n\\necho 'configuring JB system config and caches aligned with runtime...'\\nprintf '\\\\nshared.indexes.download.auto.consent=true' \\u003e\\u003e \\\"/tmp/backend/bin/idea.properties\\\"\\nunset JAVA_TOOL_OPTIONS\\nexport IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains\\nexport IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains\\n\\necho 'running stable goland backend in warmup mode...'\\n/tmp/backend/bin/remote-dev-server.sh warmup \\\"$GITPOD_REPO_ROOT\\\"\\n\\necho 'removing stable goland backend...'\\nrm -rf /tmp/backend\\n\\necho 'warming up latest release of goland...'\\necho 'downloading latest goland backend...'\\nmkdir /tmp/backend-latest\\ncurl -sSLo /tmp/backend-latest/backend-latest.tar.gz \\\"https://download.jetbrains.com/product?type=release,eap,rc\\u0026distribution=linux\\u0026code=GO\\\"\\ntar -xf /tmp/backend-latest/backend-latest.tar.gz --strip-components=1 --directory /tmp/backend-latest\\n\\necho 'configuring JB system config and caches aligned with runtime...'\\nprintf '\\\\nshared.indexes.download.auto.consent=true' \\u003e\\u003e \\\"/tmp/backend-latest/bin/idea.properties\\\"\\nunset JAVA_TOOL_OPTIONS\\nexport IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains-latest\\nexport IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains-latest\\n\\necho 'running goland backend in warmup mode...'\\n/tmp/backend-latest/bin/remote-dev-server.sh warmup \\\"$GITPOD_REPO_ROOT\\\"\\n\\necho 'removing latest goland backend...'\\nrm -rf /tmp/backend-latest\\n\\necho 'warming up latest release of phpstorm...'\\necho 'downloading latest phpstorm backend...'\\nmkdir /tmp/backend-latest\\ncurl -sSLo /tmp/backend-latest/backend-latest.tar.gz \\\"https://download.jetbrains.com/product?type=release,eap,rc\\u0026distribution=linux\\u0026code=PS\\\"\\ntar -xf /tmp/backend-latest/backend-latest.tar.gz --strip-components=1 --directory /tmp/backend-latest\\n\\necho 'configuring JB system config and caches aligned with runtime...'\\nprintf '\\\\nshared.indexes.download.auto.consent=true' \\u003e\\u003e \\\"/tmp/backend-latest/bin/idea.properties\\\"\\nunset JAVA_TOOL_OPTIONS\\nexport IJ_HOST_CONFIG_BASE_DIR=/workspace/.config/JetBrains-latest\\nexport IJ_HOST_SYSTEM_BASE_DIR=/workspace/.cache/JetBrains-latest\\n\\necho 'running phpstorm backend in warmup mode...'\\n/tmp/backend-latest/bin/remote-dev-server.sh warmup \\\"$GITPOD_REPO_ROOT\\\"\\n\\necho 'removing latest phpstorm backend...'\\nrm -rf /tmp/backend-latest\"}]" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_multiple_ide.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_multiple_ide.json new file mode 100644 index 00000000000000..10b31de2c34b5b --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_prebuild_multiple_ide.json @@ -0,0 +1,6 @@ +{ + "type": 1, + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"intellij\",\"useLatestVersion\":false}", + "workspace_config": "{\"tasks\":[{\"init\":\"echo 'init script'\",\"command\":\"echo 'start script'\"}],\"jetbrains\":{\"intellij\":{\"prebuilds\":{\"version\":\"stable\"}},\"phpstorm\":{\"prebuilds\":{\"version\":\"latest\"}},\"goland\":{\"prebuilds\":{\"version\":\"both\"}}},\"_origin\":\"repo\",\"image\":\"docker.io/gitpod/workspace-full:latest\",\"vscode\":{\"extensions\":[]}}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw.golden new file mode 100644 index 00000000000000..9b39fcb18f697c --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw.golden @@ -0,0 +1,12 @@ +{ + "Resp": { + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "referer_ide": "intellij" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw.json new file mode 100644 index 00000000000000..86e84564f08214 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw.json @@ -0,0 +1,4 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"jetbrains-gateway\"}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_goland.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_goland.golden new file mode 100644 index 00000000000000..7ab1d3f981fd06 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_goland.golden @@ -0,0 +1,12 @@ +{ + "Resp": { + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/goland:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "referer_ide": "goland" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_goland.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_goland.json new file mode 100644 index 00000000000000..450658f83a372a --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_goland.json @@ -0,0 +1,4 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"jetbrains-gateway\",\"referrerIde\":\"goland\"}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid.golden new file mode 100644 index 00000000000000..9b39fcb18f697c --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid.golden @@ -0,0 +1,12 @@ +{ + "Resp": { + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "referer_ide": "intellij" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid.json new file mode 100644 index 00000000000000..37ac618e136a26 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid.json @@ -0,0 +1,4 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"jetbrains-gateway\",\"referrerIde\":\"invalid\"}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code.golden new file mode 100644 index 00000000000000..940cc309d4649e --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code.golden @@ -0,0 +1,18 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "code" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "referer_ide": "intellij" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code.json new file mode 100644 index 00000000000000..a646b67a24be00 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"jetbrains-gateway\",\"referrerIde\":\"invalid\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"code\",\"useLatestVersion\":false}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code_desktop.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code_desktop.golden new file mode 100644 index 00000000000000..493a926657bfd9 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code_desktop.golden @@ -0,0 +1,18 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "code-desktop" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "referer_ide": "intellij" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code_desktop.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code_desktop.json new file mode 100644 index 00000000000000..0451e7393a30ad --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_code_desktop.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"jetbrains-gateway\",\"referrerIde\":\"invalid\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"code-desktop\",\"useLatestVersion\":false}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_goland.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_goland.golden new file mode 100644 index 00000000000000..b809688e334573 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_goland.golden @@ -0,0 +1,18 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "goland" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/goland:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ], + "referer_ide": "goland" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_goland.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_goland.json new file mode 100644 index 00000000000000..acf9e70d5ee6f7 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_gw_invalid_with_goland.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"jetbrains-gateway\",\"referrerIde\":\"invalid\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"goland\",\"useLatestVersion\":false}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid.golden new file mode 100644 index 00000000000000..ec088fcbca185b --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid.golden @@ -0,0 +1,7 @@ +{ + "Resp": { + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid.json new file mode 100644 index 00000000000000..51a5995062680f --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid.json @@ -0,0 +1,4 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"invalid\"}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid_with_intellij.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid_with_intellij.golden new file mode 100644 index 00000000000000..52a13f0eb73692 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid_with_intellij.golden @@ -0,0 +1,17 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "intellij" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ] + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid_with_intellij.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid_with_intellij.json new file mode 100644 index 00000000000000..41f85247bf9c17 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_referrer_invalid_with_intellij.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\",\"referrer\":\"invalid\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"intellij\",\"useLatestVersion\":false}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_code.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_code.golden new file mode 100644 index 00000000000000..22e8d5a9e166fc --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_code.golden @@ -0,0 +1,13 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "code" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9" + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_code.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_code.json new file mode 100644 index 00000000000000..78781488be13d1 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_code.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"code\",\"useLatestVersion\":false}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij.golden new file mode 100644 index 00000000000000..52a13f0eb73692 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij.golden @@ -0,0 +1,17 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "intellij" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-d6329814c2aa34c414574fd0d1301447d6fe82c9", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:commit-9a6c79a91b2b1f583d5bcb7f9f1ef54ee977e0df", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a" + ] + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij.json new file mode 100644 index 00000000000000..e63e087d268107 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"intellij\",\"useLatestVersion\":false}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +} diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij_latest.golden b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij_latest.golden new file mode 100644 index 00000000000000..67d56d4708b47e --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij_latest.golden @@ -0,0 +1,17 @@ +{ + "Resp": { + "envvars": [ + { + "name": "GITPOD_IDE_ALIAS", + "value": "intellij" + } + ], + "supervisor_image": "eu.gcr.io/gitpod-core-dev/build/supervisor:commit-ff38b98b7dde4929159bcaeec68d178898dc2139", + "web_image": "eu.gcr.io/gitpod-core-dev/build/ide/code:nightly@sha256:8669f6ab8dceefde11138bf4bc0ee73b934b2cc47e6135426f05fb4343ec5ab1", + "ide_image_layers": [ + "eu.gcr.io/gitpod-core-dev/build/ide/intellij:latest@sha256:e07524e52089829dc8d3b38f7d18fb51b24f07aed7d8e4e6e447899687978d43", + "eu.gcr.io/gitpod-core-dev/build/ide/jb-backend-plugin:commit-b38092639d1783a1957894ddd4f492b3cdc9794a-latest" + ] + }, + "Err": "" +} \ No newline at end of file diff --git a/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij_latest.json b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij_latest.json new file mode 100644 index 00000000000000..416c90234a39c7 --- /dev/null +++ b/components/ide-service/pkg/server/testdata/resolve_ws_config_regular_intellij_latest.json @@ -0,0 +1,5 @@ +{ + "context": "{\"isFile\":false,\"path\":\"\",\"title\":\"gitpod-io/empty \",\"revision\":\"\",\"repository\":{\"cloneUrl\":\"https://github.com/gitpod-io/empty.git\",\"host\":\"github.com\",\"name\":\"empty\",\"owner\":\"gitpod-io\",\"private\":false},\"normalizedContextURL\":\"https://github.com/gitpod-io/empty\",\"checkoutLocation\":\"empty\"}", + "ide_settings": "{\"settingVersion\":\"2.0\",\"defaultIde\":\"intellij\",\"useLatestVersion\":true}", + "workspace_config": "{\"ports\":[],\"tasks\":[],\"image\":\"docker.io/gitpod/workspace-full:latest\",\"_origin\":\"default\"}" +}