@gitpod/gitpod-protocol 0.1.5-se-external-config.13 → 0.1.5-se-workspace-for-teams.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/data/gitpod-schema.json +4 -22
  2. package/lib/accounting-protocol.d.ts +3 -5
  3. package/lib/accounting-protocol.d.ts.map +1 -1
  4. package/lib/accounting-protocol.js +0 -5
  5. package/lib/accounting-protocol.js.map +1 -1
  6. package/lib/admin-protocol.d.ts +1 -2
  7. package/lib/admin-protocol.d.ts.map +1 -1
  8. package/lib/admin-protocol.js.map +1 -1
  9. package/lib/analytics.d.ts +33 -0
  10. package/lib/analytics.d.ts.map +1 -0
  11. package/lib/{util/without.js → analytics.js} +4 -2
  12. package/lib/analytics.js.map +1 -0
  13. package/lib/context-url.d.ts +18 -0
  14. package/lib/context-url.d.ts.map +1 -0
  15. package/lib/context-url.js +49 -0
  16. package/lib/context-url.js.map +1 -0
  17. package/lib/{util/context-url.spec.d.ts → context-url.spec.d.ts} +2 -0
  18. package/lib/context-url.spec.d.ts.map +1 -0
  19. package/lib/{util/context-url.spec.js → context-url.spec.js} +26 -2
  20. package/lib/context-url.spec.js.map +1 -0
  21. package/lib/email-protocol.d.ts +1 -2
  22. package/lib/email-protocol.d.ts.map +1 -1
  23. package/lib/email-protocol.js.map +1 -1
  24. package/lib/env.d.ts +1 -1
  25. package/lib/env.d.ts.map +1 -1
  26. package/lib/env.js +10 -9
  27. package/lib/env.js.map +1 -1
  28. package/lib/gitpod-service.d.ts +65 -5
  29. package/lib/gitpod-service.d.ts.map +1 -1
  30. package/lib/gitpod-service.js +7 -6
  31. package/lib/gitpod-service.js.map +1 -1
  32. package/lib/headless-workspace-log.d.ts +8 -11
  33. package/lib/headless-workspace-log.d.ts.map +1 -1
  34. package/lib/headless-workspace-log.js +4 -7
  35. package/lib/headless-workspace-log.js.map +1 -1
  36. package/lib/index.d.ts +2 -0
  37. package/lib/index.d.ts.map +1 -1
  38. package/lib/index.js +2 -0
  39. package/lib/index.js.map +1 -1
  40. package/lib/messaging/client-call-metrics.d.ts +35 -0
  41. package/lib/messaging/client-call-metrics.d.ts.map +1 -0
  42. package/lib/messaging/client-call-metrics.js +84 -0
  43. package/lib/messaging/client-call-metrics.js.map +1 -0
  44. package/lib/messaging/error.d.ts +1 -0
  45. package/lib/messaging/error.d.ts.map +1 -1
  46. package/lib/messaging/error.js +2 -0
  47. package/lib/messaging/error.js.map +1 -1
  48. package/lib/messaging/node/connection.js +2 -2
  49. package/lib/messaging/node/connection.js.map +1 -1
  50. package/lib/messaging/proxy-factory.d.ts.map +1 -1
  51. package/lib/messaging/proxy-factory.js +3 -1
  52. package/lib/messaging/proxy-factory.js.map +1 -1
  53. package/lib/permission.d.ts +2 -1
  54. package/lib/permission.d.ts.map +1 -1
  55. package/lib/permission.js +1 -0
  56. package/lib/permission.js.map +1 -1
  57. package/lib/protocol.d.ts +41 -24
  58. package/lib/protocol.d.ts.map +1 -1
  59. package/lib/protocol.js +18 -1
  60. package/lib/protocol.js.map +1 -1
  61. package/lib/team-subscription-protocol.d.ts +3 -3
  62. package/lib/team-subscription-protocol.d.ts.map +1 -1
  63. package/lib/team-subscription-protocol.js +3 -0
  64. package/lib/team-subscription-protocol.js.map +1 -1
  65. package/lib/teams-projects-protocol.d.ts +100 -0
  66. package/lib/teams-projects-protocol.d.ts.map +1 -0
  67. package/lib/teams-projects-protocol.js +34 -0
  68. package/lib/teams-projects-protocol.js.map +1 -0
  69. package/lib/util/analytics.d.ts +1 -26
  70. package/lib/util/analytics.d.ts.map +1 -1
  71. package/lib/util/analytics.js +1 -2
  72. package/lib/util/analytics.js.map +1 -1
  73. package/lib/util/generate-workspace-id.d.ts.map +1 -1
  74. package/lib/util/generate-workspace-id.js +1 -0
  75. package/lib/util/generate-workspace-id.js.map +1 -1
  76. package/lib/util/gitpod-host-url.js +1 -1
  77. package/lib/util/gitpod-host-url.js.map +1 -1
  78. package/lib/util/gitpod-host-url.spec.d.ts +5 -0
  79. package/lib/util/gitpod-host-url.spec.d.ts.map +1 -1
  80. package/lib/util/gitpod-host-url.spec.js +70 -0
  81. package/lib/util/gitpod-host-url.spec.js.map +1 -1
  82. package/lib/util/grpc.d.ts +15 -0
  83. package/lib/util/grpc.d.ts.map +1 -0
  84. package/lib/util/grpc.js +18 -0
  85. package/lib/util/grpc.js.map +1 -0
  86. package/lib/util/logging.d.ts +17 -1
  87. package/lib/util/logging.d.ts.map +1 -1
  88. package/lib/util/logging.js +66 -28
  89. package/lib/util/logging.js.map +1 -1
  90. package/lib/workspace-cluster.d.ts +1 -2
  91. package/lib/workspace-cluster.d.ts.map +1 -1
  92. package/lib/workspace-cluster.js.map +1 -1
  93. package/lib/workspace-instance.d.ts +1 -0
  94. package/lib/workspace-instance.d.ts.map +1 -1
  95. package/lib/wsready.js +1 -1
  96. package/lib/wsready.js.map +1 -1
  97. package/package.json +9 -6
  98. package/pkg-yarn.lock +6 -4
  99. package/src/accounting-protocol.ts +3 -7
  100. package/src/admin-protocol.ts +1 -2
  101. package/src/analytics.ts +39 -0
  102. package/src/context-url.spec.ts +39 -0
  103. package/src/context-url.ts +51 -0
  104. package/src/email-protocol.ts +1 -2
  105. package/src/env.ts +10 -9
  106. package/src/gitpod-service.ts +80 -12
  107. package/src/headless-workspace-log.ts +7 -11
  108. package/src/index.ts +2 -0
  109. package/src/messaging/client-call-metrics.ts +97 -0
  110. package/src/messaging/error.ts +3 -0
  111. package/src/messaging/node/connection.ts +2 -2
  112. package/src/messaging/proxy-factory.ts +3 -1
  113. package/src/permission.ts +1 -0
  114. package/src/protocol.ts +58 -29
  115. package/src/team-subscription-protocol.ts +5 -3
  116. package/src/teams-projects-protocol.ts +129 -0
  117. package/src/util/analytics.ts +1 -30
  118. package/src/util/generate-workspace-id.ts +1 -0
  119. package/src/util/gitpod-host-url.spec.ts +20 -0
  120. package/src/util/gitpod-host-url.ts +1 -1
  121. package/src/util/grpc.ts +15 -0
  122. package/src/util/logging.ts +64 -13
  123. package/src/workspace-cluster.ts +1 -2
  124. package/src/workspace-instance.ts +13 -7
  125. package/src/wsready.ts +1 -1
  126. package/lib/util/context-url.d.ts +0 -13
  127. package/lib/util/context-url.d.ts.map +0 -1
  128. package/lib/util/context-url.js +0 -26
  129. package/lib/util/context-url.js.map +0 -1
  130. package/lib/util/context-url.spec.d.ts.map +0 -1
  131. package/lib/util/context-url.spec.js.map +0 -1
  132. package/lib/util/without.d.ts +0 -7
  133. package/lib/util/without.d.ts.map +0 -1
  134. package/lib/util/without.js.map +0 -1
  135. package/src/util/context-url.spec.ts +0 -25
  136. package/src/util/context-url.ts +0 -23
  137. package/src/util/without.ts +0 -8
@@ -65,13 +65,13 @@ export function toIWebSocket(webSocket: ws) {
65
65
  send: content => {
66
66
  if (webSocket.readyState !== ws.OPEN) {
67
67
  if (sendsAfterOpen++ > 3) {
68
- log.error(`Repeated try to send on closed web socket (readyState was ${webSocket.readyState})`, { ws });
68
+ //log.debug(`Repeated try to send on closed web socket (readyState was ${webSocket.readyState})`, { ws });
69
69
  }
70
70
  return;
71
71
  }
72
72
  webSocket.send(content, err => {
73
73
  if (err) {
74
- log.error('Error in ws.send()', err, { ws });
74
+ log.error('error in ws.send()', err, { ws });
75
75
  }
76
76
  })
77
77
  },
@@ -158,7 +158,9 @@ export class JsonRpcProxyFactory<T extends object> implements ProxyHandler<T> {
158
158
  * methods calls.
159
159
  */
160
160
  protected onNotification(method: string, ...args: any[]): void {
161
- this.target[method](...args);
161
+ if (this.target[method]) {
162
+ this.target[method](...args);
163
+ }
162
164
  }
163
165
 
164
166
  /**
package/src/permission.ts CHANGED
@@ -16,6 +16,7 @@ export const Permissions = {
16
16
  "admin-api": undefined,
17
17
  "ide-settings": undefined,
18
18
  "new-workspace-cluster": undefined,
19
+ "teams-and-projects": undefined,
19
20
  };
20
21
  export type PermissionName = keyof (typeof Permissions);
21
22
  export const Roles = {"devops": undefined, "viewer": undefined, "admin": undefined };
package/src/protocol.ts CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { WorkspaceInstance, PortVisibility } from "./workspace-instance";
8
8
  import { RoleOrPermission } from "./permission";
9
+ import { Project } from "./teams-projects-protocol";
9
10
 
10
11
  export interface UserInfo {
11
12
  name?: string
@@ -27,8 +28,6 @@ export interface User {
27
28
 
28
29
  identities: Identity[]
29
30
 
30
- allowsMarketingCommunication: boolean;
31
-
32
31
  /**
33
32
  * Whether the user has been blocked to use our service, because of TOS violation for example.
34
33
  * Optional for backwards compatibility.
@@ -103,10 +102,14 @@ export interface AdditionalUserData {
103
102
  // key is the name of the OAuth client i.e. local app, string the iso date when it was approved
104
103
  // TODO(rl): provide a management UX to allow rescinding of approval
105
104
  oauthClientsApproved?: { [key: string]: string }
105
+ // to remember GH Orgs the user installed/updated the GH App for
106
+ knownGitHubOrgs?: string[];
106
107
  }
107
108
 
108
109
  export interface EmailNotificationSettings {
109
- disallowTransactionalEmails?: boolean;
110
+ allowsChangelogMail?: boolean;
111
+ allowsDevXMail?: boolean;
112
+ allowsOnboardingMail?: boolean;
110
113
  }
111
114
 
112
115
  export type IDESettings = {
@@ -392,6 +395,7 @@ export interface Workspace {
392
395
  contextURL: string;
393
396
  description: string;
394
397
  ownerId: string;
398
+ projectId?: string;
395
399
  context: WorkspaceContext;
396
400
  config: WorkspaceConfig;
397
401
 
@@ -559,12 +563,13 @@ export interface WorkspaceConfig {
559
563
  * Where the config object originates from.
560
564
  *
561
565
  * repo - from the repository
566
+ * project-db - from the "Project" stored in the database
562
567
  * definitly-gp - from github.com/gitpod-io/definitely-gp
563
568
  * derived - computed based on analyzing the repository
564
- * context - explicitly passed as part of the context
569
+ * additional-content - config comes from additional content, usually provided through the project's configuration
565
570
  * default - our static catch-all default config
566
571
  */
567
- _origin?: 'repo' | 'definitely-gp' | 'derived' | 'default' | 'context';
572
+ _origin?: 'repo' | 'project-db' | 'definitely-gp' | 'derived' | 'additional-content' | 'default';
568
573
 
569
574
  /**
570
575
  * Set of automatically infered feature flags. That's not something the user can set, but
@@ -594,11 +599,8 @@ export namespace GithubAppPrebuildConfig {
594
599
 
595
600
  export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
596
601
  export interface WorkspaceImageSourceDocker {
597
- dockerFileContentSHA?: string
598
602
  dockerFilePath: string
599
- // deprecated we use dockerFileContentSHA to compute the baseRef
600
- dockerFileHash?: string
601
- // deprecated we use dockerFileContentSHA to compute the baseRef
603
+ dockerFileHash: string
602
604
  dockerFileSource?: Commit
603
605
  }
604
606
  export namespace WorkspaceImageSourceDocker {
@@ -632,6 +634,8 @@ export type PrebuiltWorkspaceState
632
634
  export interface PrebuiltWorkspace {
633
635
  id: string;
634
636
  cloneURL: string;
637
+ branch?: string;
638
+ projectId?: string;
635
639
  commit: string;
636
640
  buildWorkspaceId: string;
637
641
  creationTime: string;
@@ -701,7 +705,7 @@ export interface TaskConfig {
701
705
  init?: string;
702
706
  prebuild?: string;
703
707
  command?: string;
704
- env?: { [env: string]: string };
708
+ env?: { [env: string]: any };
705
709
  openIn?: 'bottom' | 'main' | 'left' | 'right';
706
710
  openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
707
711
  }
@@ -801,6 +805,29 @@ export namespace WithPrebuild {
801
805
  }
802
806
  }
803
807
 
808
+ /**
809
+ * WithDefaultConfig contexts disable the download of the gitpod.yml from the repository
810
+ * and fall back to the built-in configuration.
811
+ */
812
+ export interface WithDefaultConfig {
813
+ withDefaultConfig: true;
814
+ }
815
+
816
+ export namespace WithDefaultConfig {
817
+ export function is(context: any): context is WithDefaultConfig {
818
+ return context
819
+ && 'withDefaultConfig' in context
820
+ && context.withDefaultConfig;
821
+ }
822
+
823
+ export function mark(ctx: WorkspaceContext): WorkspaceContext & WithDefaultConfig {
824
+ return {
825
+ ...ctx,
826
+ withDefaultConfig: true
827
+ }
828
+ }
829
+ }
830
+
804
831
  export interface SnapshotContext extends WorkspaceContext, WithSnapshot {
805
832
  snapshotId: string;
806
833
  }
@@ -816,6 +843,8 @@ export namespace SnapshotContext {
816
843
  export interface StartPrebuildContext extends WorkspaceContext {
817
844
  actual: WorkspaceContext;
818
845
  commitHistory?: string[];
846
+ project?: Project;
847
+ branch?: string;
819
848
  }
820
849
 
821
850
  export namespace StartPrebuildContext {
@@ -885,7 +914,7 @@ export interface Commit {
885
914
  refType?: RefType
886
915
  }
887
916
 
888
- export interface AdditionalContentContext {
917
+ export interface AdditionalContentContext extends WorkspaceContext {
889
918
 
890
919
  /**
891
920
  * utf-8 encoded contents that will be copied on top of the workspace's filesystem
@@ -898,6 +927,10 @@ export namespace AdditionalContentContext {
898
927
  export function is(ctx: any): ctx is AdditionalContentContext {
899
928
  return 'additionalFiles' in ctx;
900
929
  }
930
+
931
+ export function hasDockerConfig(ctx: any, config: WorkspaceConfig): boolean {
932
+ return is(ctx) && ImageConfigFile.is(config.image) && !!ctx.additionalFiles[config.image.file];
933
+ }
901
934
  }
902
935
 
903
936
  export interface CommitContext extends WorkspaceContext, Commit {
@@ -975,6 +1008,19 @@ export interface Repository {
975
1008
  parent: Repository
976
1009
  }
977
1010
  }
1011
+ export interface Branch {
1012
+ name: string;
1013
+ commit: CommitInfo;
1014
+ htmlUrl: string;
1015
+ }
1016
+
1017
+ export interface CommitInfo {
1018
+ author: string;
1019
+ sha: string;
1020
+ commitMessage: string;
1021
+ authorAvatarUrl?: string;
1022
+ authorDate?: string;
1023
+ }
978
1024
 
979
1025
  export namespace Repository {
980
1026
  export function fullRepoName(repo: Repository): string {
@@ -1017,6 +1063,7 @@ export interface WorkspaceCreationResult {
1017
1063
  runningWorkspacePrebuild?: {
1018
1064
  prebuildID: string
1019
1065
  workspaceID: string
1066
+ instanceID: string
1020
1067
  starting: RunningWorkspacePrebuildStarting
1021
1068
  sameCluster: boolean
1022
1069
  }
@@ -1193,21 +1240,3 @@ export interface Terms {
1193
1240
  readonly content: string;
1194
1241
  readonly formElements?: object;
1195
1242
  }
1196
-
1197
- export interface Project {
1198
- id: string;
1199
- cloneUrl: string;
1200
- teamId: string;
1201
- appInstallationId: string;
1202
- creationTime: string;
1203
- /** This is a flag that triggers the HARD DELETION of this entity */
1204
- deleted?: boolean;
1205
- }
1206
-
1207
- export interface Team {
1208
- id: string;
1209
- name: string;
1210
- creationTime: string;
1211
- /** This is a flag that triggers the HARD DELETION of this entity */
1212
- deleted?: boolean;
1213
- }
@@ -4,7 +4,6 @@
4
4
  * See License-AGPL.txt in the project root for license information.
5
5
  */
6
6
 
7
- import { Without } from "./util/without";
8
7
  import uuidv4 = require("uuid/v4");
9
8
  import { Subscription } from "./accounting-protocol";
10
9
 
@@ -22,7 +21,7 @@ export interface TeamSubscription {
22
21
  }
23
22
 
24
23
  export namespace TeamSubscription {
25
- export const create = (ts: Without<TeamSubscription, 'id'>): TeamSubscription => {
24
+ export const create = (ts: Omit<TeamSubscription, 'id'>): TeamSubscription => {
26
25
  const withId = ts as TeamSubscription;
27
26
  withId.id = uuidv4();
28
27
  return withId;
@@ -49,7 +48,7 @@ export type TeamSubscriptionSlotAssigned = TeamSubscriptionSlot & TeamSubscripti
49
48
  export type TeamSubscriptionSlotState = 'unassigned' | 'assigned' | 'deactivated' | 'cancelled';
50
49
 
51
50
  export namespace TeamSubscriptionSlot {
52
- export const create = (ts: Without<TeamSubscriptionSlot, 'id'>): TeamSubscriptionSlot => {
51
+ export const create = (ts: Omit<TeamSubscriptionSlot, 'id'>): TeamSubscriptionSlot => {
53
52
  const withId = ts as TeamSubscriptionSlot;
54
53
  withId.id = uuidv4();
55
54
  return withId;
@@ -83,6 +82,9 @@ export namespace TeamSubscriptionSlot {
83
82
  }
84
83
 
85
84
  }
85
+ export const isActive = (slot: TeamSubscriptionSlot): boolean => {
86
+ return !slot.cancellationDate;
87
+ }
86
88
  }
87
89
 
88
90
  /**
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Copyright (c) 2021 Gitpod GmbH. All rights reserved.
3
+ * Licensed under the GNU Affero General Public License (AGPL).
4
+ * See License-AGPL.txt in the project root for license information.
5
+ */
6
+
7
+ import { PrebuiltWorkspaceState } from "./protocol";
8
+ import uuidv4 = require("uuid/v4");
9
+
10
+ export interface ProjectConfig {
11
+ '.gitpod.yml': string;
12
+ }
13
+
14
+ export interface Project {
15
+ id: string;
16
+ name: string;
17
+ cloneUrl: string;
18
+ teamId?: string;
19
+ userId?: string;
20
+ appInstallationId: string;
21
+ config?: ProjectConfig;
22
+ creationTime: string;
23
+ /** This is a flag that triggers the HARD DELETION of this entity */
24
+ deleted?: boolean;
25
+ markedDeleted?: boolean;
26
+ }
27
+
28
+ export namespace Project {
29
+ export const create = (project: Omit<Project, 'id' | 'creationTime'>): Project => {
30
+ return {
31
+ ...project,
32
+ id: uuidv4(),
33
+ creationTime: new Date().toISOString()
34
+ };
35
+ }
36
+
37
+ export interface Overview {
38
+ branches: BranchDetails[]
39
+ }
40
+
41
+ export interface BranchDetails {
42
+ name: string;
43
+ url: string;
44
+ isDefault: boolean;
45
+
46
+ // Latest commit
47
+ changeTitle: string;
48
+ changeDate?: string;
49
+ changeAuthor?: string;
50
+ changeAuthorAvatar?: string;
51
+ changePR?: string;
52
+ changeUrl?: string;
53
+ changeHash: string;
54
+ }
55
+ }
56
+
57
+ export interface PrebuildWithStatus {
58
+ info: PrebuildInfo;
59
+ status: PrebuiltWorkspaceState;
60
+ }
61
+
62
+ export interface PrebuildInfo {
63
+ id: string;
64
+ buildWorkspaceId: string;
65
+
66
+ teamId?: string;
67
+ userId?: string;
68
+
69
+ projectId: string;
70
+ projectName: string;
71
+
72
+ cloneUrl: string;
73
+ branch: string;
74
+
75
+ startedAt: string;
76
+ startedBy: string;
77
+ startedByAvatar?: string;
78
+
79
+ changeTitle: string;
80
+ changeDate: string;
81
+ changeAuthor: string;
82
+ changeAuthorAvatar?: string;
83
+ changePR?: string;
84
+ changeUrl?: string;
85
+ changeHash: string;
86
+ }
87
+ export namespace PrebuildInfo {
88
+ export function is(data?: any): data is PrebuildInfo {
89
+ return typeof data === "object" && ["id", "buildWorkspaceId", "projectId", "branch"].every(p => p in data);
90
+ }
91
+ }
92
+
93
+ export interface StartPrebuildResult {
94
+ wsid: string;
95
+ done: boolean;
96
+ didFinish?: boolean;
97
+ }
98
+
99
+ export interface Team {
100
+ id: string;
101
+ name: string;
102
+ slug: string;
103
+ creationTime: string;
104
+ /** This is a flag that triggers the HARD DELETION of this entity */
105
+ deleted?: boolean;
106
+ }
107
+
108
+ export type TeamMemberRole = "owner" | "member";
109
+
110
+ export interface TeamMemberInfo {
111
+ userId: string;
112
+ fullName?: string;
113
+ primaryEmail?: string;
114
+ avatarUrl?: string;
115
+ role: TeamMemberRole;
116
+ memberSince: string;
117
+ }
118
+
119
+ export interface TeamMembershipInvite {
120
+ id: string;
121
+ teamId: string;
122
+ role: TeamMemberRole;
123
+ creationTime: string;
124
+ invalidationTime: string;
125
+ invitedEmail?: string;
126
+
127
+ /** This is a flag that triggers the HARD DELETION of this entity */
128
+ deleted?: boolean;
129
+ }
@@ -5,30 +5,9 @@
5
5
  */
6
6
 
7
7
  import Analytics = require("analytics-node");
8
+ import { IAnalyticsWriter, IdentifyMessage, TrackMessage } from "../analytics";
8
9
  import { log } from './logging';
9
10
 
10
- export const IAnalyticsWriter = Symbol("IAnalyticsWriter");
11
-
12
- type Identity =
13
- | { userId: string | number }
14
- | { userId?: string | number; anonymousId: string | number };
15
-
16
- interface Message {
17
- messageId?: string;
18
- }
19
-
20
- export type IdentifyMessage = Message & Identity & {
21
- traits?: any;
22
- timestamp?: Date;
23
- context?: any;
24
- };
25
-
26
- export type TrackMessage = Message & Identity & {
27
- event: string;
28
- properties?: any;
29
- timestamp?: Date;
30
- context?: any;
31
- };
32
11
 
33
12
  export function newAnalyticsWriterFromEnv(): IAnalyticsWriter {
34
13
  switch (process.env.GITPOD_ANALYTICS_WRITER) {
@@ -41,14 +20,6 @@ export function newAnalyticsWriterFromEnv(): IAnalyticsWriter {
41
20
  }
42
21
  }
43
22
 
44
- export interface IAnalyticsWriter {
45
-
46
- identify(msg: IdentifyMessage): void;
47
-
48
- track(msg: TrackMessage): void;
49
-
50
- }
51
-
52
23
  class SegmentAnalyticsWriter implements IAnalyticsWriter {
53
24
 
54
25
  protected readonly analytics: Analytics;
@@ -173,6 +173,7 @@ export const colors = [
173
173
  'deer',
174
174
  'dingo',
175
175
  'dinosaur',
176
+ 'dodo',
176
177
  'dog',
177
178
  'dolphin',
178
179
  'donkey',
@@ -25,5 +25,25 @@ export class GitpodHostUrlTest {
25
25
  @test public async testWithoutWorkspacePrefix() {
26
26
  expect(GitpodHostUrl.fromWorkspaceUrl("https://3000-moccasin-ferret-155799b3.ws-eu02.gitpod-staging.com/").withoutWorkspacePrefix().toString()).to.equal("https://gitpod-staging.com/");
27
27
  }
28
+
29
+ @test public async testWithoutWorkspacePrefix2() {
30
+ expect(GitpodHostUrl.fromWorkspaceUrl("https://gitpod-staging.com/").withoutWorkspacePrefix().toString()).to.equal("https://gitpod-staging.com/");
31
+ }
32
+
33
+ @test public async testWithoutWorkspacePrefix3() {
34
+ expect(GitpodHostUrl.fromWorkspaceUrl("https://gray-rook-5523v5d8.ws-dev.my-branch-1234.staging.gitpod-dev.com/").withoutWorkspacePrefix().toString()).to.equal("https://my-branch-1234.staging.gitpod-dev.com/");
35
+ }
36
+
37
+ @test public async testWithoutWorkspacePrefix4() {
38
+ expect(GitpodHostUrl.fromWorkspaceUrl("https://my-branch-1234.staging.gitpod-dev.com/").withoutWorkspacePrefix().toString()).to.equal("https://my-branch-1234.staging.gitpod-dev.com/");
39
+ }
40
+
41
+ @test public async testWithoutWorkspacePrefix5() {
42
+ expect(GitpodHostUrl.fromWorkspaceUrl("https://abc-nice-brunch-4224.staging.gitpod-dev.com/").withoutWorkspacePrefix().toString()).to.equal("https://abc-nice-brunch-4224.staging.gitpod-dev.com/");
43
+ }
44
+
45
+ @test public async testWithoutWorkspacePrefix6() {
46
+ expect(GitpodHostUrl.fromWorkspaceUrl("https://gray-rook-5523v5d8.ws-dev.abc-nice-brunch-4224.staging.gitpod-dev.com/").withoutWorkspacePrefix().toString()).to.equal("https://abc-nice-brunch-4224.staging.gitpod-dev.com/");
47
+ }
28
48
  }
29
49
  module.exports = new GitpodHostUrlTest()
@@ -18,7 +18,7 @@ const basewoWkspaceIDRegex = "(([a-f][0-9a-f]{7}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f
18
18
  const workspaceIDRegex = RegExp(`^${basewoWkspaceIDRegex}$`);
19
19
 
20
20
  // this pattern matches URL prefixes of workspaces
21
- const workspaceUrlPrefixRegex = RegExp(`^([0-9]{4,6}-)?${basewoWkspaceIDRegex}\.`);
21
+ const workspaceUrlPrefixRegex = RegExp(`^([0-9]{4,6}-)?${basewoWkspaceIDRegex}\\.`);
22
22
 
23
23
  export class GitpodHostUrl {
24
24
  readonly url: URL;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2021 Gitpod GmbH. All rights reserved.
3
+ * Licensed under the GNU Affero General Public License (AGPL).
4
+ * See License-AGPL.txt in the project root for license information.
5
+ */
6
+
7
+ export const defaultGRPCOptions = {
8
+ "grpc.keepalive_timeout_ms": 1000,
9
+ "grpc.keepalive_time_ms": 5000,
10
+ "grpc.http2.min_time_between_pings_ms": 1000,
11
+ "grpc.keepalive_permit_without_calls": 1,
12
+ "grpc-node.max_session_memory": 50,
13
+ "grpc.max_reconnect_backoff_ms": 5000,
14
+ "grpc.max_receive_message_length": 1024 * 1024 * 16,
15
+ };
@@ -97,24 +97,32 @@ export namespace log {
97
97
  /**
98
98
  * Do not use in frontend.
99
99
  */
100
- export function enableJSONLogging(componentArg: string, versionArg: string | undefined): void {
100
+ export function enableJSONLogging(componentArg: string, versionArg: string | undefined, logLevel?: LogrusLogLevel): void {
101
101
  component = componentArg;
102
102
  version = versionArg;
103
103
 
104
+ setLogLevel(logLevel);
105
+ }
106
+
107
+ export function setLogLevel(logLevel: LogrusLogLevel | undefined) {
104
108
  jsonLogging = true;
105
109
 
106
- console.error = function (...args: any[]): void {
107
- errorLog(true, args);
108
- }
109
- console.warn = function (...args: any[]): void {
110
- warnLog(true, args);
111
- }
112
- console.info = function (...args: any[]): void {
113
- infoLog(true, args);
114
- }
115
- console.debug = function (...args: any[]): void {
116
- debugLog(true, args);
117
- }
110
+ const noop = () => {};
111
+ const setLog = (logFunc: (calleViaConsole: boolean, args: any[]) => void, funcLvl: LogrusLogLevel): (() => void) => {
112
+ if (LogrusLogLevel.isGreatherOrEqual(funcLvl, logLevel)) {
113
+ return function (...args: any[]): void {
114
+ logFunc(true, args);
115
+ };
116
+ } else {
117
+ return noop;
118
+ }
119
+ };
120
+
121
+ console.error = setLog(errorLog, "error");
122
+ console.warn = setLog(warnLog, "warning");
123
+ console.info = setLog(infoLog, "info");
124
+ console.debug = setLog(debugLog, "debug");
125
+
118
126
  console.log = console.info;
119
127
  // FIXME wrap also other console methods (e.g. trace())
120
128
  }
@@ -128,6 +136,10 @@ export namespace log {
128
136
  console.info = infoConsoleLog;
129
137
  console.debug = debugConsoleLog;
130
138
  }
139
+
140
+ export function setVersion(versionArg: string) {
141
+ version = versionArg;
142
+ }
131
143
  }
132
144
 
133
145
  function errorLog(calledViaConsole: boolean, args: any[]): void {
@@ -146,6 +158,45 @@ function debugLog(calledViaConsole: boolean, args: any[]): void {
146
158
  doLog(calledViaConsole, debugConsoleLog, 'DEBUG', args);
147
159
  }
148
160
 
161
+ // Ref: https://github.com/sirupsen/logrus#level-logging
162
+ export type LogrusLogLevel = keyof (typeof LogrusLogLevels);
163
+ export const LogrusLogLevels = {
164
+ trace: true,
165
+ debug: true,
166
+ info: true,
167
+ warning: true,
168
+ error: true,
169
+ fatal: true,
170
+ panic: true,
171
+ }
172
+ export namespace LogrusLogLevel {
173
+ export function isGreatherOrEqual(lvl: LogrusLogLevel | undefined, ref: LogrusLogLevel | undefined): boolean {
174
+ if (lvl === undefined) {
175
+ return false;
176
+ }
177
+ if (ref === undefined) {
178
+ return true;
179
+ }
180
+ return getLevelArity(lvl) >= getLevelArity(ref);
181
+ }
182
+ function getLevelArity(lvl: LogrusLogLevel): number {
183
+ return Object.keys(LogrusLogLevels)
184
+ .findIndex((l) => l === lvl);
185
+ }
186
+ export function getFromEnv(): LogrusLogLevel | undefined {
187
+ const lvlStr = process.env.LOG_LEVEL;
188
+ if (!lvlStr) {
189
+ return undefined;
190
+ }
191
+ const lvl = lvlStr as LogrusLogLevel;
192
+ const exists = LogrusLogLevels[lvl]
193
+ if (!exists) {
194
+ return undefined;
195
+ }
196
+ return lvl;
197
+ }
198
+ }
199
+
149
200
  // Source: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
150
201
  type GoogleLogSeverity = 'EMERGENCY' | 'ALERT' | 'CRITICAL' | 'ERROR' | 'WARNING' | 'INFO' | 'DEBUG';
151
202
  namespace GoogleLogSeverity {
@@ -7,7 +7,6 @@
7
7
  import * as fs from 'fs';
8
8
  import { filePathTelepresenceAware } from './env';
9
9
  import { DeepPartial } from "./util/deep-partial";
10
- import { Without } from './util/without';
11
10
  import { PermissionName } from './permission';
12
11
 
13
12
  export interface WorkspaceCluster {
@@ -50,7 +49,7 @@ export interface TLSConfig {
50
49
  export namespace TLSConfig {
51
50
  export const loadFromBase64File = (path: string): string => fs.readFileSync(filePathTelepresenceAware(path)).toString("base64");
52
51
  }
53
- export type WorkspaceClusterWoTLS = Without<WorkspaceCluster, "tls">;
52
+ export type WorkspaceClusterWoTLS = Omit<WorkspaceCluster, "tls">;
54
53
  export type WorkspaceManagerConnectionInfo = Pick<WorkspaceCluster, "name" | "url" | "tls">;
55
54
 
56
55
  export type AdmissionConstraint = AdmissionConstraintFeaturePreview | AdmissionConstraintHasRole;
@@ -23,16 +23,22 @@ export interface WorkspaceInstance {
23
23
  // The time an instance has switched phase to 'Running'
24
24
  startedTime?: string;
25
25
 
26
+ // The time an instance has switched phase to 'Stopping' */
27
+ stoppingTime?: string;
28
+
26
29
  // The time an instance has switched phase to 'Stopped' */
27
30
  stoppedTime?: string;
28
31
 
29
32
  // ideUrl is the URL at which the workspace is available on the internet
33
+ // Note: this is nitially empty, filled during starting process!
30
34
  ideUrl: string;
31
35
 
32
36
  // region is the name of the workspace cluster this instance runs in
37
+ // Note: this is nitially empty, filled during starting process!
33
38
  region: string;
34
39
 
35
40
  // workspaceImage is the name of the Docker image this instance runs
41
+ // Note: this is nitially empty, filled during starting process!
36
42
  workspaceImage: string;
37
43
 
38
44
  // status is the latest status of the instance that we're aware of
@@ -83,7 +89,7 @@ export interface WorkspaceInstanceStatus {
83
89
  // WorkspaceInstancePhase describes a high-level state of a workspace instance
84
90
  export type WorkspaceInstancePhase =
85
91
  // unknown indicates an issue within the system in that it cannot determine the actual phase of
86
- // a workspace. This phase is usually accompanied by an error.
92
+ // a workspace. This phase is usually accompanied by an error.
87
93
  "unknown" |
88
94
 
89
95
  // Preparing means that we haven't actually started the workspace instance just yet, but rather
@@ -91,21 +97,21 @@ export type WorkspaceInstancePhase =
91
97
  "preparing" |
92
98
 
93
99
  // Pending means the workspace does not yet consume resources in the cluster, but rather is looking for
94
- // some space within the cluster. If for example the cluster needs to scale up to accomodate the
95
- // workspace, the workspace will be in Pending state until that happened.
100
+ // some space within the cluster. If for example the cluster needs to scale up to accomodate the
101
+ // workspace, the workspace will be in Pending state until that happened.
96
102
  "pending" |
97
103
 
98
104
  // Creating means the workspace is currently being created. Thati includes downloading the images required
99
- // to run the workspace over the network. The time spent in this phase varies widely and depends on the current
100
- // network speed, image size and cache states.
105
+ // to run the workspace over the network. The time spent in this phase varies widely and depends on the current
106
+ // network speed, image size and cache states.
101
107
  "creating" |
102
108
 
103
109
  // Initializing is the phase in which the workspace is executing the appropriate workspace initializer (e.g. Git
104
- // clone or backup download). After this phase one can expect the workspace to either be Running or Failed.
110
+ // clone or backup download). After this phase one can expect the workspace to either be Running or Failed.
105
111
  "initializing" |
106
112
 
107
113
  // Running means the workspace is able to actively perform work, either by serving a user through Theia,
108
- // or as a headless workspace.
114
+ // or as a headless workspace.
109
115
  "running" |
110
116
 
111
117
  // Interrupted is an exceptional state where the container should be running but is temporarily unavailable.