@@ -157,7 +157,7 @@ import { Deferred } from "@gitpod/gitpod-protocol/lib/util/deferred";
157
157
import { ListUsageRequest , ListUsageResponse } from "@gitpod/gitpod-protocol/lib/usage" ;
158
158
import { VerificationService } from "../auth/verification-service" ;
159
159
import { BillingMode } from "@gitpod/gitpod-protocol/lib/billing-mode" ;
160
- import { EntitlementService , MayStartWorkspaceResult } from "../billing/entitlement-service" ;
160
+ import { EntitlementService } from "../billing/entitlement-service" ;
161
161
import { formatPhoneNumber } from "../user/phone-numbers" ;
162
162
import { IDEService } from "../ide-service" ;
163
163
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution" ;
@@ -169,8 +169,6 @@ import {
169
169
getExperimentsClientForBackend ,
170
170
} from "@gitpod/gitpod-protocol/lib/experiments/configcat-server" ;
171
171
import { increaseDashboardErrorBoundaryCounter , reportCentralizedPermsValidation } from "../prometheus-metrics" ;
172
- import { RegionService } from "./region-service" ;
173
- import { isWorkspaceRegion , WorkspaceRegion } from "@gitpod/gitpod-protocol/lib/workspace-cluster" ;
174
172
import { EnvVarService } from "./env-var-service" ;
175
173
import { LinkedInService } from "../linkedin-service" ;
176
174
import { SnapshotService , WaitForSnapshotOptions } from "./snapshot-service" ;
@@ -920,15 +918,11 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
920
918
921
919
const user = await this . checkAndBlockUser ( "startWorkspace" , undefined , { workspaceId } ) ;
922
920
921
+ // (gpl) We keep this check here for backwards compatibility, it should be superfluous in the future
923
922
const workspace = await this . workspaceService . getWorkspace ( user . id , workspaceId ) ;
924
- const mayStartPromise = this . mayStartWorkspace (
925
- ctx ,
926
- user ,
927
- workspace . organizationId ,
928
- this . workspaceDb . trace ( ctx ) . findRegularRunningInstances ( user . id ) ,
929
- ) ;
930
923
await this . guardAccess ( { kind : "workspace" , subject : workspace } , "get" ) ;
931
924
925
+ // (gpl) We keep this check here for backwards compatibility, it should be superfluous in the future
932
926
const runningInstance = await this . workspaceDb . trace ( ctx ) . findRunningInstance ( workspace . id ) ;
933
927
if ( runningInstance ) {
934
928
traceWI ( ctx , { instanceId : runningInstance . id } ) ;
@@ -944,38 +938,15 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
944
938
} ;
945
939
}
946
940
947
- if ( ! ! workspace . softDeleted ) {
948
- throw new ApplicationError ( ErrorCodes . NOT_FOUND , "Workspace not found!" ) ;
949
- }
950
-
941
+ // (gpl) We keep this check here for backwards compatibility, it should be superfluous in the future
951
942
// no matter if the workspace is shared or not, you cannot create a new instance
952
943
await this . guardAccess ( { kind : "workspaceInstance" , subject : undefined , workspace } , "create" ) ;
953
944
954
- if ( workspace . type !== "regular" ) {
955
- throw new ApplicationError ( ErrorCodes . PERMISSION_DENIED , "Cannot (re-)start irregular workspace." ) ;
956
- }
957
-
958
- if ( workspace . deleted ) {
959
- throw new ApplicationError ( ErrorCodes . PERMISSION_DENIED , "Cannot (re-)start a deleted workspace." ) ;
960
- }
961
- const envVarsPromise = this . envVarService . resolve ( workspace ) ;
962
- const projectPromise = workspace . projectId
963
- ? ApplicationError . notFoundToUndefined ( this . projectsService . getProject ( user . id , workspace . projectId ) )
964
- : Promise . resolve ( undefined ) ;
965
-
966
- await mayStartPromise ;
967
-
968
- options . region = await this . determineWorkspaceRegion ( workspace , options . region || "" ) ;
969
-
970
- // at this point we're about to actually start a new workspace
971
- const result = await this . workspaceStarter . startWorkspace (
972
- ctx ,
973
- workspace ,
974
- user ,
975
- await projectPromise ,
976
- await envVarsPromise ,
977
- options ,
978
- ) ;
945
+ const opts = {
946
+ ...options ,
947
+ clientCountryCode : this . clientHeaderFields . clientRegion ,
948
+ } ;
949
+ const result = await this . workspaceService . startWorkspace ( user , workspaceId , opts ) ;
979
950
traceWI ( ctx , { instanceId : result . instanceID } ) ;
980
951
return result ;
981
952
}
@@ -1405,7 +1376,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
1405
1376
? ( await this . projectsService . findProjectsByCloneUrl ( user . id , context . repository . cloneUrl ) ) [ 0 ]
1406
1377
: undefined ;
1407
1378
1408
- const mayStartWorkspacePromise = this . mayStartWorkspace (
1379
+ const mayStartWorkspacePromise = this . workspaceService . mayStartWorkspace (
1409
1380
ctx ,
1410
1381
user ,
1411
1382
options . organizationId ,
@@ -1448,19 +1419,14 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
1448
1419
throw err ;
1449
1420
}
1450
1421
1451
- const envVarsPromise = this . envVarService . resolve ( workspace ) ;
1452
- options . region = await this . determineWorkspaceRegion ( workspace , options . region || "" ) ;
1453
-
1454
1422
logContext . workspaceId = workspace . id ;
1455
1423
traceWI ( ctx , { workspaceId : workspace . id } ) ;
1456
- const startWorkspaceResult = await this . workspaceStarter . startWorkspace (
1457
- ctx ,
1458
- workspace ,
1459
- user ,
1460
- project ,
1461
- await envVarsPromise ,
1462
- options ,
1463
- ) ;
1424
+
1425
+ const opts = {
1426
+ ...options ,
1427
+ clientCountryCode : this . clientHeaderFields . clientRegion ,
1428
+ } ;
1429
+ const startWorkspaceResult = await this . workspaceService . startWorkspace ( user , workspace . id , opts ) ;
1464
1430
ctx . span ?. log ( { event : "startWorkspaceComplete" , ...startWorkspaceResult } ) ;
1465
1431
1466
1432
return {
@@ -1664,41 +1630,6 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
1664
1630
return result ;
1665
1631
}
1666
1632
1667
- private async mayStartWorkspace (
1668
- ctx : TraceContext ,
1669
- user : User ,
1670
- organizationId : string ,
1671
- runningInstances : Promise < WorkspaceInstance [ ] > ,
1672
- ) : Promise < void > {
1673
- let result : MayStartWorkspaceResult = { } ;
1674
- try {
1675
- result = await this . entitlementService . mayStartWorkspace ( user , organizationId , runningInstances ) ;
1676
- TraceContext . addNestedTags ( ctx , { mayStartWorkspace : { result } } ) ;
1677
- } catch ( err ) {
1678
- log . error ( { userId : user . id } , "EntitlementSerivce.mayStartWorkspace error" , err ) ;
1679
- TraceContext . setError ( ctx , err ) ;
1680
- return ; // we don't want to block workspace starts because of internal errors
1681
- }
1682
- if ( ! ! result . needsVerification ) {
1683
- throw new ApplicationError ( ErrorCodes . NEEDS_VERIFICATION , `Please verify your account.` ) ;
1684
- }
1685
- if ( ! ! result . usageLimitReachedOnCostCenter ) {
1686
- throw new ApplicationError (
1687
- ErrorCodes . PAYMENT_SPENDING_LIMIT_REACHED ,
1688
- "Increase usage limit and try again." ,
1689
- {
1690
- attributionId : result . usageLimitReachedOnCostCenter ,
1691
- } ,
1692
- ) ;
1693
- }
1694
- if ( ! ! result . hitParallelWorkspaceLimit ) {
1695
- throw new ApplicationError (
1696
- ErrorCodes . TOO_MANY_RUNNING_WORKSPACES ,
1697
- `You cannot run more than ${ result . hitParallelWorkspaceLimit . max } workspaces at the same time. Please stop a workspace before starting another one.` ,
1698
- ) ;
1699
- }
1700
- }
1701
-
1702
1633
public async getFeaturedRepositories ( ctx : TraceContext ) : Promise < WhitelistedRepository [ ] > {
1703
1634
const user = await this . checkAndBlockUser ( "getFeaturedRepositories" ) ;
1704
1635
const repositories = await this . workspaceDb . trace ( ctx ) . getFeaturedRepositories ( ) ;
@@ -3782,50 +3713,6 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
3782
3713
}
3783
3714
}
3784
3715
3785
- private async determineWorkspaceRegion ( ws : Workspace , preference : WorkspaceRegion ) : Promise < WorkspaceRegion > {
3786
- const guessWorkspaceRegionEnabled = await getExperimentsClientForBackend ( ) . getValueAsync (
3787
- "guessWorkspaceRegion" ,
3788
- false ,
3789
- {
3790
- user : { id : this . userID || "" } ,
3791
- } ,
3792
- ) ;
3793
-
3794
- const regionLogContext = {
3795
- requested_region : preference ,
3796
- client_region_from_header : this . clientHeaderFields . clientRegion ,
3797
- experiment_enabled : false ,
3798
- guessed_region : "" ,
3799
- } ;
3800
-
3801
- let targetRegion = preference ;
3802
- if ( ! isWorkspaceRegion ( preference ) ) {
3803
- targetRegion = "" ;
3804
- } else {
3805
- targetRegion = preference ;
3806
- }
3807
-
3808
- if ( guessWorkspaceRegionEnabled ) {
3809
- regionLogContext . experiment_enabled = true ;
3810
-
3811
- if ( ! preference ) {
3812
- // Attempt to identify the region based on LoadBalancer headers, if there was no explicit choice on the request.
3813
- // The Client region contains the two letter country code.
3814
- if ( this . clientHeaderFields . clientRegion ) {
3815
- const countryCode = this . clientHeaderFields . clientRegion ;
3816
-
3817
- targetRegion = RegionService . countryCodeToNearestWorkspaceRegion ( countryCode ) ;
3818
- regionLogContext . guessed_region = targetRegion ;
3819
- }
3820
- }
3821
- }
3822
-
3823
- const logCtx = { userId : this . userID , workspaceId : ws . id } ;
3824
- log . info ( logCtx , "[guessWorkspaceRegion] Workspace with region selection" , regionLogContext ) ;
3825
-
3826
- return targetRegion ;
3827
- }
3828
-
3829
3716
async getIDToken ( ) : Promise < void > { }
3830
3717
3831
3718
public async controlAdmission ( ctx : TraceContext , workspaceId : string , level : "owner" | "everyone" ) : Promise < void > {
0 commit comments