@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.
- package/data/gitpod-schema.json +4 -22
- package/lib/accounting-protocol.d.ts +3 -5
- package/lib/accounting-protocol.d.ts.map +1 -1
- package/lib/accounting-protocol.js +0 -5
- package/lib/accounting-protocol.js.map +1 -1
- package/lib/admin-protocol.d.ts +1 -2
- package/lib/admin-protocol.d.ts.map +1 -1
- package/lib/admin-protocol.js.map +1 -1
- package/lib/analytics.d.ts +33 -0
- package/lib/analytics.d.ts.map +1 -0
- package/lib/{util/without.js → analytics.js} +4 -2
- package/lib/analytics.js.map +1 -0
- package/lib/context-url.d.ts +18 -0
- package/lib/context-url.d.ts.map +1 -0
- package/lib/context-url.js +49 -0
- package/lib/context-url.js.map +1 -0
- package/lib/{util/context-url.spec.d.ts → context-url.spec.d.ts} +2 -0
- package/lib/context-url.spec.d.ts.map +1 -0
- package/lib/{util/context-url.spec.js → context-url.spec.js} +26 -2
- package/lib/context-url.spec.js.map +1 -0
- package/lib/email-protocol.d.ts +1 -2
- package/lib/email-protocol.d.ts.map +1 -1
- package/lib/email-protocol.js.map +1 -1
- package/lib/env.d.ts +1 -1
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +10 -9
- package/lib/env.js.map +1 -1
- package/lib/gitpod-service.d.ts +65 -5
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +7 -6
- package/lib/gitpod-service.js.map +1 -1
- package/lib/headless-workspace-log.d.ts +8 -11
- package/lib/headless-workspace-log.d.ts.map +1 -1
- package/lib/headless-workspace-log.js +4 -7
- package/lib/headless-workspace-log.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/messaging/client-call-metrics.d.ts +35 -0
- package/lib/messaging/client-call-metrics.d.ts.map +1 -0
- package/lib/messaging/client-call-metrics.js +84 -0
- package/lib/messaging/client-call-metrics.js.map +1 -0
- package/lib/messaging/error.d.ts +1 -0
- package/lib/messaging/error.d.ts.map +1 -1
- package/lib/messaging/error.js +2 -0
- package/lib/messaging/error.js.map +1 -1
- package/lib/messaging/node/connection.js +2 -2
- package/lib/messaging/node/connection.js.map +1 -1
- package/lib/messaging/proxy-factory.d.ts.map +1 -1
- package/lib/messaging/proxy-factory.js +3 -1
- package/lib/messaging/proxy-factory.js.map +1 -1
- package/lib/permission.d.ts +2 -1
- package/lib/permission.d.ts.map +1 -1
- package/lib/permission.js +1 -0
- package/lib/permission.js.map +1 -1
- package/lib/protocol.d.ts +41 -24
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +18 -1
- package/lib/protocol.js.map +1 -1
- package/lib/team-subscription-protocol.d.ts +3 -3
- package/lib/team-subscription-protocol.d.ts.map +1 -1
- package/lib/team-subscription-protocol.js +3 -0
- package/lib/team-subscription-protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +100 -0
- package/lib/teams-projects-protocol.d.ts.map +1 -0
- package/lib/teams-projects-protocol.js +34 -0
- package/lib/teams-projects-protocol.js.map +1 -0
- package/lib/util/analytics.d.ts +1 -26
- package/lib/util/analytics.d.ts.map +1 -1
- package/lib/util/analytics.js +1 -2
- package/lib/util/analytics.js.map +1 -1
- package/lib/util/generate-workspace-id.d.ts.map +1 -1
- package/lib/util/generate-workspace-id.js +1 -0
- package/lib/util/generate-workspace-id.js.map +1 -1
- package/lib/util/gitpod-host-url.js +1 -1
- package/lib/util/gitpod-host-url.js.map +1 -1
- package/lib/util/gitpod-host-url.spec.d.ts +5 -0
- package/lib/util/gitpod-host-url.spec.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.spec.js +70 -0
- package/lib/util/gitpod-host-url.spec.js.map +1 -1
- package/lib/util/grpc.d.ts +15 -0
- package/lib/util/grpc.d.ts.map +1 -0
- package/lib/util/grpc.js +18 -0
- package/lib/util/grpc.js.map +1 -0
- package/lib/util/logging.d.ts +17 -1
- package/lib/util/logging.d.ts.map +1 -1
- package/lib/util/logging.js +66 -28
- package/lib/util/logging.js.map +1 -1
- package/lib/workspace-cluster.d.ts +1 -2
- package/lib/workspace-cluster.d.ts.map +1 -1
- package/lib/workspace-cluster.js.map +1 -1
- package/lib/workspace-instance.d.ts +1 -0
- package/lib/workspace-instance.d.ts.map +1 -1
- package/lib/wsready.js +1 -1
- package/lib/wsready.js.map +1 -1
- package/package.json +9 -6
- package/pkg-yarn.lock +6 -4
- package/src/accounting-protocol.ts +3 -7
- package/src/admin-protocol.ts +1 -2
- package/src/analytics.ts +39 -0
- package/src/context-url.spec.ts +39 -0
- package/src/context-url.ts +51 -0
- package/src/email-protocol.ts +1 -2
- package/src/env.ts +10 -9
- package/src/gitpod-service.ts +80 -12
- package/src/headless-workspace-log.ts +7 -11
- package/src/index.ts +2 -0
- package/src/messaging/client-call-metrics.ts +97 -0
- package/src/messaging/error.ts +3 -0
- package/src/messaging/node/connection.ts +2 -2
- package/src/messaging/proxy-factory.ts +3 -1
- package/src/permission.ts +1 -0
- package/src/protocol.ts +58 -29
- package/src/team-subscription-protocol.ts +5 -3
- package/src/teams-projects-protocol.ts +129 -0
- package/src/util/analytics.ts +1 -30
- package/src/util/generate-workspace-id.ts +1 -0
- package/src/util/gitpod-host-url.spec.ts +20 -0
- package/src/util/gitpod-host-url.ts +1 -1
- package/src/util/grpc.ts +15 -0
- package/src/util/logging.ts +64 -13
- package/src/workspace-cluster.ts +1 -2
- package/src/workspace-instance.ts +13 -7
- package/src/wsready.ts +1 -1
- package/lib/util/context-url.d.ts +0 -13
- package/lib/util/context-url.d.ts.map +0 -1
- package/lib/util/context-url.js +0 -26
- package/lib/util/context-url.js.map +0 -1
- package/lib/util/context-url.spec.d.ts.map +0 -1
- package/lib/util/context-url.spec.js.map +0 -1
- package/lib/util/without.d.ts +0 -7
- package/lib/util/without.d.ts.map +0 -1
- package/lib/util/without.js.map +0 -1
- package/src/util/context-url.spec.ts +0 -25
- package/src/util/context-url.ts +0 -23
- 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.
|
|
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('
|
|
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]
|
|
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
|
-
|
|
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
|
-
*
|
|
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' | '
|
|
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
|
-
|
|
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]:
|
|
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:
|
|
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:
|
|
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
|
+
}
|
package/src/util/analytics.ts
CHANGED
|
@@ -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;
|
|
@@ -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;
|
package/src/util/grpc.ts
ADDED
|
@@ -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
|
+
};
|
package/src/util/logging.ts
CHANGED
|
@@ -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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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 {
|
package/src/workspace-cluster.ts
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|