4
4
* See License.AGPL.txt in the project root for license information.
5
5
*/
6
6
7
+ import * as crypto from "crypto" ;
7
8
import { inject , injectable } from "inversify" ;
8
- import fetch from "node-fetch" ;
9
9
import * as path from "path" ;
10
- import * as crypto from "crypto" ;
11
10
12
- import { log , LogContext } from "@gitpod/gitpod-protocol/lib/util/logging" ;
13
11
import {
14
- User ,
15
- WorkspaceConfig ,
12
+ AdditionalContentContext ,
16
13
CommitContext ,
17
- Repository ,
18
14
ImageConfigString ,
19
- ExternalImageConfigFile ,
20
- ImageConfigFile ,
21
- Commit ,
22
15
NamedWorkspaceFeatureFlag ,
23
- AdditionalContentContext ,
24
- WithDefaultConfig ,
25
16
ProjectConfig ,
17
+ User ,
18
+ WithDefaultConfig ,
19
+ WorkspaceConfig ,
26
20
} from "@gitpod/gitpod-protocol" ;
27
21
import { GitpodFileParser } from "@gitpod/gitpod-protocol/lib/gitpod-file-parser" ;
22
+ import { log , LogContext } from "@gitpod/gitpod-protocol/lib/util/logging" ;
28
23
29
- import { MaybeContent } from "../repohost/file-provider" ;
30
- import { ConfigurationService } from "../config/configuration-service" ;
31
- import { HostContextProvider } from "../auth/host-context-provider" ;
32
- import { AuthorizationService } from "../user/authorization-service" ;
33
24
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing" ;
25
+ import { HostContextProvider } from "../auth/host-context-provider" ;
34
26
import { Config } from "../config" ;
35
- import { EntitlementService } from "../billing/entitlement-service" ;
36
- import { TeamDB } from "@gitpod/gitpod-db/lib" ;
27
+ import { ConfigurationService } from "../config/configuration-service" ;
37
28
38
29
const POD_PATH_WORKSPACE_BASE = "/workspace" ;
39
30
40
31
@injectable ( )
41
32
export class ConfigProvider {
42
- static readonly DEFINITELY_GP_REPO : Repository = {
43
- host : "github.com" ,
44
- owner : "gitpod-io" ,
45
- name : "definitely-gp" ,
46
- cloneUrl : "https://github.com/gitpod-io/definitely-gp" ,
47
- } ;
48
-
49
- @inject ( GitpodFileParser ) protected readonly gitpodParser : GitpodFileParser ;
50
- @inject ( HostContextProvider ) protected readonly hostContextProvider : HostContextProvider ;
51
- @inject ( AuthorizationService ) protected readonly authService : AuthorizationService ;
52
- @inject ( Config ) protected readonly config : Config ;
53
- @inject ( ConfigurationService ) protected readonly configurationService : ConfigurationService ;
54
- @inject ( EntitlementService ) protected readonly entitlementService : EntitlementService ;
55
- @inject ( TeamDB ) protected readonly teamDB : TeamDB ;
33
+ constructor (
34
+ @inject ( GitpodFileParser ) private readonly gitpodParser : GitpodFileParser ,
35
+ @inject ( HostContextProvider ) private readonly hostContextProvider : HostContextProvider ,
36
+ @inject ( Config ) private readonly config : Config ,
37
+ @inject ( ConfigurationService ) private readonly configurationService : ConfigurationService ,
38
+ ) { }
56
39
57
40
public async fetchConfig (
58
41
ctx : TraceContext ,
@@ -64,7 +47,6 @@ export class ConfigProvider {
64
47
commit,
65
48
} ) ;
66
49
const logContext : LogContext = { userId : user . id } ;
67
- let configBasePath = "" ;
68
50
try {
69
51
let customConfig : WorkspaceConfig | undefined ;
70
52
let literalConfig : ProjectConfig | undefined ;
@@ -73,7 +55,6 @@ export class ConfigProvider {
73
55
const cc = await this . fetchCustomConfig ( ctx , user , commit ) ;
74
56
if ( ! ! cc ) {
75
57
customConfig = cc . customConfig ;
76
- configBasePath = cc . configBasePath ;
77
58
literalConfig = cc . literalConfig ;
78
59
}
79
60
}
@@ -94,29 +75,6 @@ export class ConfigProvider {
94
75
const config = customConfig ;
95
76
if ( ! config . image ) {
96
77
config . image = this . config . workspaceDefaults . workspaceImage ;
97
- } else if ( ImageConfigFile . is ( config . image ) ) {
98
- const dockerfilePath = [ configBasePath , config . image . file ] . filter ( ( s ) => ! ! s ) . join ( "/" ) ;
99
- let repo = commit . repository ;
100
- let rev = commit . revision ;
101
- const image = config . image ! ;
102
-
103
- if ( config . _origin === "definitely-gp" ) {
104
- repo = ConfigProvider . DEFINITELY_GP_REPO ;
105
- rev = "master" ;
106
- image . file = dockerfilePath ;
107
- }
108
- if ( ! ( AdditionalContentContext . is ( commit ) && commit . additionalFiles [ dockerfilePath ] ) ) {
109
- config . image = < ExternalImageConfigFile > {
110
- ...image ,
111
- externalSource : await this . fetchWorkspaceImageSourceDocker (
112
- { span } ,
113
- repo ,
114
- rev ,
115
- user ,
116
- dockerfilePath ,
117
- ) ,
118
- } ;
119
- }
120
78
}
121
79
122
80
config . vscode = {
@@ -143,7 +101,7 @@ export class ConfigProvider {
143
101
}
144
102
}
145
103
146
- protected async fetchCustomConfig (
104
+ private async fetchCustomConfig (
147
105
ctx : TraceContext ,
148
106
user : User ,
149
107
commit : CommitContext ,
@@ -154,7 +112,7 @@ export class ConfigProvider {
154
112
155
113
try {
156
114
let customConfig : WorkspaceConfig | undefined ;
157
- let configBasePath = "" ;
115
+ const configBasePath = "" ;
158
116
if ( AdditionalContentContext . is ( commit ) && commit . additionalFiles [ ".gitpod.yml" ] ) {
159
117
customConfigString = commit . additionalFiles [ ".gitpod.yml" ] ;
160
118
const parseResult = this . gitpodParser . parse ( customConfigString ) ;
@@ -183,21 +141,6 @@ export class ConfigProvider {
183
141
customConfigString = await contextRepoConfig ;
184
142
let origin : WorkspaceConfig [ "_origin" ] = "repo" ;
185
143
186
- if ( ! customConfigString ) {
187
- /* We haven't found a Gitpod configuration file in the context repo - check definitely-gp.
188
- *
189
- * In case we had found a config file here, we'd still be checking the definitely GP repo, just to save some time.
190
- * While all those checks will be in vain, they should not leak memory either as they'll simply
191
- * be resolved and garbage collected.
192
- */
193
- const definitelyGpConfig = this . fetchExternalGitpodFileContent ( { span } , commit . repository ) ;
194
- const { content, basePath } = await definitelyGpConfig ;
195
- customConfigString = content ;
196
- // We do not only care about the config itself but also where we got it from
197
- configBasePath = basePath ;
198
- origin = "definitely-gp" ;
199
- }
200
-
201
144
if ( ! customConfigString ) {
202
145
const inferredConfig = this . configurationService . guessRepositoryConfiguration (
203
146
{ span } ,
@@ -248,140 +191,7 @@ export class ConfigProvider {
248
191
} ;
249
192
}
250
193
251
- protected async fetchWorkspaceImageSourceDocker (
252
- ctx : TraceContext ,
253
- repository : Repository ,
254
- revisionOrTagOrBranch : string ,
255
- user : User ,
256
- dockerFilePath : string ,
257
- ) : Promise < Commit > {
258
- const span = TraceContext . startSpan ( "fetchWorkspaceImageSourceDocker" , ctx ) ;
259
- span . addTags ( {
260
- repository,
261
- revisionOrTagOrBranch,
262
- dockerFilePath,
263
- } ) ;
264
-
265
- try {
266
- const host = repository . host ;
267
- const hostContext = this . hostContextProvider . get ( host ) ;
268
- if ( ! hostContext || ! hostContext . services ) {
269
- throw new Error ( `Cannot fetch workspace image source for host: ${ host } ` ) ;
270
- }
271
- const repoHost = hostContext . services ;
272
- const lastDockerFileSha = await repoHost . fileProvider . getLastChangeRevision (
273
- repository ,
274
- revisionOrTagOrBranch ,
275
- user ,
276
- dockerFilePath ,
277
- ) ;
278
- return {
279
- repository,
280
- revision : lastDockerFileSha ,
281
- } ;
282
- } catch ( e ) {
283
- TraceContext . setError ( { span } , e ) ;
284
- throw e ;
285
- } finally {
286
- span . finish ( ) ;
287
- }
288
- }
289
-
290
- protected async fillInDefaultLocations (
291
- cfg : WorkspaceConfig | undefined ,
292
- inferredConfig : Promise < WorkspaceConfig | undefined > ,
293
- ) : Promise < void > {
294
- if ( ! cfg ) {
295
- // there is no config - return
296
- return ;
297
- }
298
-
299
- if ( ! cfg . checkoutLocation ) {
300
- const inferredCfg = await inferredConfig ;
301
- if ( inferredCfg ) {
302
- cfg . checkoutLocation = inferredCfg . checkoutLocation ;
303
- }
304
- }
305
- if ( ! cfg . workspaceLocation ) {
306
- const inferredCfg = await inferredConfig ;
307
- if ( inferredCfg ) {
308
- cfg . workspaceLocation = inferredCfg . workspaceLocation ;
309
- }
310
- }
311
- }
312
-
313
- protected async fetchExternalGitpodFileContent (
314
- ctx : TraceContext ,
315
- repository : Repository ,
316
- ) : Promise < { content : MaybeContent ; basePath : string } > {
317
- const span = TraceContext . startSpan ( "fetchExternalGitpodFileContent" , ctx ) ;
318
- span . setTag ( "repo" , `${ repository . owner } /${ repository . name } ` ) ;
319
-
320
- if ( this . config . definitelyGpDisabled ) {
321
- span . finish ( ) ;
322
- return {
323
- content : undefined ,
324
- basePath : `${ repository . name } ` ,
325
- } ;
326
- }
327
-
328
- try {
329
- const ownerConfigBasePath = `${ repository . name } /${ repository . owner } ` ;
330
- const baseConfigBasePath = `${ repository . name } ` ;
331
-
332
- const possibleConfigs = [
333
- [ this . fetchDefinitelyGpContent ( { span } , `${ ownerConfigBasePath } /.gitpod.yml` ) , ownerConfigBasePath ] ,
334
- [ this . fetchDefinitelyGpContent ( { span } , `${ ownerConfigBasePath } /.gitpod` ) , ownerConfigBasePath ] ,
335
- [ this . fetchDefinitelyGpContent ( { span } , `${ baseConfigBasePath } /.gitpod.yml` ) , baseConfigBasePath ] ,
336
- [ this . fetchDefinitelyGpContent ( { span } , `${ baseConfigBasePath } /.gitpod` ) , baseConfigBasePath ] ,
337
- ] ;
338
- for ( const [ configPromise , basePath ] of possibleConfigs ) {
339
- const ownerConfig = await configPromise ;
340
- if ( ownerConfig !== undefined ) {
341
- return {
342
- content : ownerConfig ,
343
- basePath : basePath as string ,
344
- } ;
345
- }
346
- }
347
- return {
348
- content : undefined ,
349
- basePath : baseConfigBasePath ,
350
- } ;
351
- } catch ( e ) {
352
- TraceContext . setError ( { span } , e ) ;
353
- throw e ;
354
- } finally {
355
- span . finish ( ) ;
356
- }
357
- }
358
-
359
- protected async fetchDefinitelyGpContent ( ctx : TraceContext , filePath : string ) {
360
- const span = TraceContext . startSpan ( "fetchDefinitelyGpContent" , ctx ) ;
361
- span . setTag ( "filePath" , filePath ) ;
362
-
363
- try {
364
- const url = `https://raw.githubusercontent.com/gitpod-io/definitely-gp/master/${ filePath } ` ;
365
- const response = await fetch ( url , {
366
- timeout : 10000 ,
367
- method : "GET" ,
368
- } ) ;
369
- let content ;
370
- if ( response . ok ) {
371
- try {
372
- content = await response . text ( ) ;
373
- } catch { }
374
- }
375
- return content ;
376
- } catch ( e ) {
377
- TraceContext . setError ( { span } , e ) ;
378
- throw e ;
379
- } finally {
380
- span . finish ( ) ;
381
- }
382
- }
383
-
384
- protected async validateConfig ( config : WorkspaceConfig , user : User ) : Promise < void > {
194
+ private async validateConfig ( config : WorkspaceConfig , user : User ) : Promise < void > {
385
195
// Make sure the projectRoot does not leave POD_PATH_WORKSPACE_BASE as that's a common
386
196
// assumption throughout the code (e.g. ws-daemon)
387
197
const checkoutLocation = config . checkoutLocation ;
@@ -407,7 +217,7 @@ export class ConfigProvider {
407
217
}
408
218
}
409
219
410
- protected leavesWorkspaceBase ( normalizedPath : string ) {
220
+ private leavesWorkspaceBase ( normalizedPath : string ) {
411
221
const pathSegments = normalizedPath . split ( path . sep ) ;
412
222
return normalizedPath . includes ( ".." ) || pathSegments . slice ( 0 , 2 ) . join ( "/" ) != POD_PATH_WORKSPACE_BASE ;
413
223
}
0 commit comments