@gitpod/gitpod-protocol 0.1.5-to-code-reading.1 → 0.1.5-to-new-image.2
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/lib/admin-protocol.d.ts +12 -0
- package/lib/admin-protocol.d.ts.map +1 -1
- package/lib/admin-protocol.js.map +1 -1
- package/lib/analytics.d.ts +4 -5
- package/lib/analytics.d.ts.map +1 -1
- package/lib/context-url.d.ts +18 -5
- package/lib/context-url.d.ts.map +1 -1
- package/lib/context-url.js +58 -5
- package/lib/context-url.js.map +1 -1
- package/lib/context-url.spec.d.ts +2 -0
- package/lib/context-url.spec.d.ts.map +1 -1
- package/lib/context-url.spec.js +25 -4
- package/lib/context-url.spec.js.map +1 -1
- package/lib/gitpod-service.d.ts +19 -0
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js.map +1 -1
- package/lib/ide-protocol.d.ts +24 -0
- package/lib/ide-protocol.d.ts.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/installation-admin-protocol.d.ts +27 -0
- package/lib/installation-admin-protocol.d.ts.map +1 -0
- package/lib/installation-admin-protocol.js +30 -0
- package/lib/installation-admin-protocol.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/permission.d.ts +7 -1
- package/lib/permission.d.ts.map +1 -1
- package/lib/permission.js +24 -4
- package/lib/permission.js.map +1 -1
- package/lib/protocol.d.ts +11 -2
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +12 -4
- package/lib/protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +3 -0
- package/lib/teams-projects-protocol.d.ts.map +1 -1
- package/lib/teams-projects-protocol.js +7 -0
- package/lib/teams-projects-protocol.js.map +1 -1
- package/lib/util/tracing.d.ts +2 -2
- package/lib/util/tracing.d.ts.map +1 -1
- package/lib/util/tracing.js +13 -12
- package/lib/util/tracing.js.map +1 -1
- package/lib/workspace-cluster.d.ts +9 -7
- package/lib/workspace-cluster.d.ts.map +1 -1
- package/lib/workspace-cluster.js +18 -1
- package/lib/workspace-cluster.js.map +1 -1
- package/lib/workspace-instance.d.ts +19 -0
- package/lib/workspace-instance.d.ts.map +1 -1
- package/package.json +2 -2
- package/pkg-yarn.lock +2 -2
- package/provenance-bundle.jsonl +1 -1
- package/src/admin-protocol.ts +19 -4
- package/src/analytics.ts +4 -6
- package/src/context-url.spec.ts +18 -4
- package/src/context-url.ts +62 -6
- package/src/gitpod-service.ts +23 -0
- package/src/ide-protocol.ts +27 -0
- package/src/index.ts +1 -0
- package/src/installation-admin-protocol.ts +42 -0
- package/src/messaging/error.ts +3 -0
- package/src/permission.ts +22 -3
- package/src/protocol.ts +19 -5
- package/src/teams-projects-protocol.ts +7 -1
- package/src/util/tracing.ts +14 -13
- package/src/workspace-cluster.ts +17 -9
- package/src/workspace-instance.ts +20 -0
- package/lib/messaging/connection-error-handler.d.ts +0 -27
- package/lib/messaging/connection-error-handler.d.ts.map +0 -1
- package/lib/messaging/connection-error-handler.js +0 -34
- package/lib/messaging/connection-error-handler.js.map +0 -1
- package/lib/util/safe-promise.d.ts +0 -11
- package/lib/util/safe-promise.d.ts.map +0 -1
- package/lib/util/safe-promise.js +0 -31
- package/lib/util/safe-promise.js.map +0 -1
- package/src/messaging/connection-error-handler.ts +0 -62
- package/src/util/safe-promise.ts +0 -26
package/src/context-url.ts
CHANGED
|
@@ -4,10 +4,62 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { Workspace } from ".";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The whole point of these methods is to overcome inconsistencies in our data model.
|
|
11
|
+
* Ideally we remove it at some point once we fixed our model, as it:
|
|
12
|
+
* - duplicates logic
|
|
13
|
+
* - but additional burden on clients (using this, copying this to other languages!)
|
|
14
|
+
*
|
|
15
|
+
* TODO(gpl) See if we can get this into `server` code to remove the burden from clients
|
|
16
|
+
*/
|
|
7
17
|
export namespace ContextURL {
|
|
8
18
|
export const INCREMENTAL_PREBUILD_PREFIX = "incremental-prebuild";
|
|
9
19
|
export const PREBUILD_PREFIX = "prebuild";
|
|
10
20
|
export const IMAGEBUILD_PREFIX = "imagebuild";
|
|
21
|
+
export const SNAPSHOT_PREFIX = "snapshot";
|
|
22
|
+
export const REFERRER_PREFIX = 'referrer:';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This function will (try to) return the HTTP(S) URL of the context the user originally created this workspace on.
|
|
26
|
+
* Especially it will not contain any modifiers or be of different scheme than HTTP(S).
|
|
27
|
+
*
|
|
28
|
+
* Use this function if you need to provided a _working_ URL to the original context.
|
|
29
|
+
* @param ws
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
export function getNormalizedURL(ws: Pick<Workspace, "context" | "contextURL"> | undefined): URL | undefined {
|
|
33
|
+
const normalized = normalize(ws);
|
|
34
|
+
if (!normalized) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
return new URL(normalized);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.error(`unable to parse URL from normalized contextURL: '${normalized}'`, err);
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function normalize(ws: Pick<Workspace, "context" | "contextURL"> | undefined): string | undefined {
|
|
47
|
+
if (!ws) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (ws.context.normalizedContextURL) {
|
|
51
|
+
return ws.context.normalizedContextURL;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// fallback: we do not yet set normalizedContextURL on all workspaces, yet, let alone older existing workspaces
|
|
55
|
+
let fallback: string | undefined = undefined;
|
|
56
|
+
try {
|
|
57
|
+
fallback = removePrefixes(ws.contextURL);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error(`unable to remove prefixes from contextURL: '${ws.contextURL}'`, err);
|
|
60
|
+
}
|
|
61
|
+
return fallback;
|
|
62
|
+
}
|
|
11
63
|
|
|
12
64
|
/**
|
|
13
65
|
* The field "contextUrl" might contain prefixes like:
|
|
@@ -15,29 +67,33 @@ export namespace ContextURL {
|
|
|
15
67
|
* - prebuild/...
|
|
16
68
|
* This is the analogon to the (Prefix)ContextParser structure in "server".
|
|
17
69
|
*/
|
|
18
|
-
|
|
70
|
+
function removePrefixes(contextUrl: string | undefined): string | undefined {
|
|
19
71
|
if (contextUrl === undefined) {
|
|
20
72
|
return undefined;
|
|
21
73
|
}
|
|
22
74
|
|
|
23
75
|
const segments = contextUrl.split("/");
|
|
24
76
|
if (segments.length === 1) {
|
|
25
|
-
return
|
|
77
|
+
return segments[0]; // this might be something, we just try
|
|
26
78
|
}
|
|
27
79
|
|
|
28
|
-
const segmentsToURL = (offset: number):
|
|
80
|
+
const segmentsToURL = (offset: number): string => {
|
|
29
81
|
let rest = segments.slice(offset).join("/");
|
|
82
|
+
if (/^git@[^:\/]+:/.test(rest)) {
|
|
83
|
+
rest = rest.replace(/^git@([^:\/]+):/, 'https://$1/');
|
|
84
|
+
}
|
|
30
85
|
if (!rest.startsWith("http")) {
|
|
31
86
|
rest = 'https://' + rest;
|
|
32
87
|
}
|
|
33
|
-
return
|
|
88
|
+
return rest;
|
|
34
89
|
};
|
|
35
90
|
|
|
36
|
-
|
|
37
91
|
const firstSegment = segments[0];
|
|
38
92
|
if (firstSegment === PREBUILD_PREFIX ||
|
|
39
93
|
firstSegment === INCREMENTAL_PREBUILD_PREFIX ||
|
|
40
|
-
firstSegment === IMAGEBUILD_PREFIX
|
|
94
|
+
firstSegment === IMAGEBUILD_PREFIX ||
|
|
95
|
+
firstSegment === SNAPSHOT_PREFIX ||
|
|
96
|
+
firstSegment.startsWith(REFERRER_PREFIX)) {
|
|
41
97
|
return segmentsToURL(1);
|
|
42
98
|
}
|
|
43
99
|
|
package/src/gitpod-service.ts
CHANGED
|
@@ -30,6 +30,7 @@ import { GithubUpgradeURL, PlanCoupon } from './payment-protocol';
|
|
|
30
30
|
import { TeamSubscription, TeamSubscriptionSlot, TeamSubscriptionSlotResolved } from './team-subscription-protocol';
|
|
31
31
|
import { RemotePageMessage, RemoteTrackMessage, RemoteIdentifyMessage } from './analytics';
|
|
32
32
|
import { IDEServer } from './ide-protocol';
|
|
33
|
+
import { InstallationAdminSettings, TelemetryData } from './installation-admin-protocol';
|
|
33
34
|
|
|
34
35
|
export interface GitpodClient {
|
|
35
36
|
onInstanceUpdate(instance: WorkspaceInstance): void;
|
|
@@ -71,8 +72,15 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
|
|
|
71
72
|
getWorkspaceOwner(workspaceId: string): Promise<UserInfo | undefined>;
|
|
72
73
|
getWorkspaceUsers(workspaceId: string): Promise<WorkspaceInstanceUser[]>;
|
|
73
74
|
getFeaturedRepositories(): Promise<WhitelistedRepository[]>;
|
|
75
|
+
getSuggestedContextURLs(): Promise<string[]>;
|
|
76
|
+
/**
|
|
77
|
+
* **Security:**
|
|
78
|
+
* Sensitive information like an owner token is erased, since it allows access for all team members.
|
|
79
|
+
* If you need to access an owner token use `getOwnerToken` instead.
|
|
80
|
+
*/
|
|
74
81
|
getWorkspace(id: string): Promise<WorkspaceInfo>;
|
|
75
82
|
isWorkspaceOwner(workspaceId: string): Promise<boolean>;
|
|
83
|
+
getOwnerToken(workspaceId: string): Promise<string>;
|
|
76
84
|
|
|
77
85
|
/**
|
|
78
86
|
* Creates and starts a workspace for the given context URL.
|
|
@@ -125,6 +133,11 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
|
|
|
125
133
|
resetGenericInvite(inviteId: string): Promise<TeamMembershipInvite>;
|
|
126
134
|
deleteTeam(teamId: string, userId: string): Promise<void>;
|
|
127
135
|
|
|
136
|
+
// Admin Settings
|
|
137
|
+
adminGetSettings(): Promise<InstallationAdminSettings>;
|
|
138
|
+
adminUpdateSettings(settings: InstallationAdminSettings): Promise<void>;
|
|
139
|
+
adminGetTelemetryData(): Promise<TelemetryData>;
|
|
140
|
+
|
|
128
141
|
// Projects
|
|
129
142
|
getProviderRepositoriesForUser(params: GetProviderRepositoriesParams): Promise<ProviderRepository[]>;
|
|
130
143
|
createProject(params: CreateProjectParams): Promise<Project>;
|
|
@@ -241,6 +254,16 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
|
|
|
241
254
|
identifyUser(event: RemoteIdentifyMessage): Promise<void>;
|
|
242
255
|
}
|
|
243
256
|
|
|
257
|
+
export interface RateLimiterError {
|
|
258
|
+
method?: string,
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Retry after this many seconds, earliest.
|
|
262
|
+
* cmp.: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
|
263
|
+
*/
|
|
264
|
+
retryAfter: number,
|
|
265
|
+
}
|
|
266
|
+
|
|
244
267
|
export interface CreateProjectParams {
|
|
245
268
|
name: string;
|
|
246
269
|
slug?: string;
|
package/src/ide-protocol.ts
CHANGED
|
@@ -29,6 +29,28 @@ export interface IDEOptions {
|
|
|
29
29
|
* The default desktop IDE when the user has not specified one.
|
|
30
30
|
*/
|
|
31
31
|
defaultDesktopIde: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Client specific IDE options.
|
|
35
|
+
*/
|
|
36
|
+
clients?: { [id: string]: IDEClient };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface IDEClient {
|
|
40
|
+
/**
|
|
41
|
+
* The default desktop IDE when the user has not specified one.
|
|
42
|
+
*/
|
|
43
|
+
defaultDesktopIDE?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Desktop IDEs supported by the client.
|
|
47
|
+
*/
|
|
48
|
+
desktopIDEs?: string[]
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Steps to install the client on user machine.
|
|
52
|
+
*/
|
|
53
|
+
installationSteps?: string[]
|
|
32
54
|
}
|
|
33
55
|
|
|
34
56
|
export interface IDEOption {
|
|
@@ -80,6 +102,11 @@ export interface IDEOption {
|
|
|
80
102
|
*/
|
|
81
103
|
image: string;
|
|
82
104
|
|
|
105
|
+
/**
|
|
106
|
+
* The latest image ref to the IDE image, this image ref always resolve to digest.
|
|
107
|
+
*/
|
|
108
|
+
latestImage?: string;
|
|
109
|
+
|
|
83
110
|
/**
|
|
84
111
|
* When this is `true`, the tag of this image is resolved to the latest
|
|
85
112
|
* image digest regularly.
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022 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 { v4 as uuidv4 } from 'uuid';
|
|
8
|
+
|
|
9
|
+
const InstallationAdminSettingsPrototype = {
|
|
10
|
+
sendTelemetry: true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type InstallationAdminSettings = typeof InstallationAdminSettingsPrototype;
|
|
14
|
+
|
|
15
|
+
export namespace InstallationAdminSettings {
|
|
16
|
+
export function fields(): (keyof InstallationAdminSettings)[] {
|
|
17
|
+
return Object.keys(InstallationAdminSettingsPrototype) as (keyof InstallationAdminSettings)[];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface InstallationAdmin {
|
|
22
|
+
id: string;
|
|
23
|
+
settings: InstallationAdminSettings;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TelemetryData {
|
|
27
|
+
installationAdmin: InstallationAdmin
|
|
28
|
+
totalUsers: number
|
|
29
|
+
totalWorkspaces: number
|
|
30
|
+
totalInstances: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export namespace InstallationAdmin {
|
|
34
|
+
export function createDefault(): InstallationAdmin {
|
|
35
|
+
return {
|
|
36
|
+
id: uuidv4(),
|
|
37
|
+
settings: {
|
|
38
|
+
...InstallationAdminSettingsPrototype,
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/messaging/error.ts
CHANGED
package/src/permission.ts
CHANGED
|
@@ -13,6 +13,7 @@ export const Permissions = {
|
|
|
13
13
|
"registry-access": undefined,
|
|
14
14
|
"admin-users": undefined,
|
|
15
15
|
"admin-workspaces": undefined,
|
|
16
|
+
"admin-projects": undefined,
|
|
16
17
|
"admin-api": undefined,
|
|
17
18
|
"ide-settings": undefined,
|
|
18
19
|
"new-workspace-cluster": undefined,
|
|
@@ -34,6 +35,22 @@ export interface Role {
|
|
|
34
35
|
permissions: PermissionName[],
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
export namespace RolesOrPermissions {
|
|
39
|
+
export function toPermissionSet(rolesOrPermissions: RoleOrPermission[] | undefined): Set<PermissionName> {
|
|
40
|
+
rolesOrPermissions = rolesOrPermissions || [];
|
|
41
|
+
|
|
42
|
+
const permissions = new Set<PermissionName>();
|
|
43
|
+
for (const rop of rolesOrPermissions) {
|
|
44
|
+
if (Permission.is(rop)) {
|
|
45
|
+
permissions.add(rop);
|
|
46
|
+
} else if (RoleName.is(rop)) {
|
|
47
|
+
Role.getByName(rop).permissions.forEach(p => permissions.add(p));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return permissions;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
37
54
|
export namespace Permission {
|
|
38
55
|
/** The permission to monitor the (live) state of a Gitpod installation */
|
|
39
56
|
export const MONITOR: PermissionName = "monitor";
|
|
@@ -50,6 +67,9 @@ export namespace Permission {
|
|
|
50
67
|
/** The permission for accessing all workspace data */
|
|
51
68
|
export const ADMIN_WORKSPACES: PermissionName = "admin-workspaces";
|
|
52
69
|
|
|
70
|
+
/** The permission for accessing all projects data */
|
|
71
|
+
export const ADMIN_PROJECTS: PermissionName = "admin-projects";
|
|
72
|
+
|
|
53
73
|
/** The permission to access the admin API */
|
|
54
74
|
export const ADMIN_API: PermissionName = "admin-api";
|
|
55
75
|
|
|
@@ -62,9 +82,7 @@ export namespace Permission {
|
|
|
62
82
|
}
|
|
63
83
|
|
|
64
84
|
export const all = (): PermissionName[] => {
|
|
65
|
-
return Object.keys(
|
|
66
|
-
.map(k => (Permission as any)[k])
|
|
67
|
-
.filter(k => typeof(k) === 'string');
|
|
85
|
+
return Object.keys(Permissions) as PermissionName[];
|
|
68
86
|
};
|
|
69
87
|
}
|
|
70
88
|
|
|
@@ -94,6 +112,7 @@ export namespace Role {
|
|
|
94
112
|
permissions: [
|
|
95
113
|
Permission.ADMIN_USERS,
|
|
96
114
|
Permission.ADMIN_WORKSPACES,
|
|
115
|
+
Permission.ADMIN_PROJECTS,
|
|
97
116
|
Permission.ADMIN_API,
|
|
98
117
|
Permission.ENFORCEMENT,
|
|
99
118
|
]
|
package/src/protocol.ts
CHANGED
|
@@ -119,6 +119,7 @@ export type IDESettings = {
|
|
|
119
119
|
defaultIde?: string
|
|
120
120
|
useDesktopIde?: boolean
|
|
121
121
|
defaultDesktopIde?: string
|
|
122
|
+
useLatestVersion?: boolean
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
export interface UserPlatform {
|
|
@@ -258,8 +259,8 @@ export namespace UserEnvVar {
|
|
|
258
259
|
// DEPRECATED: Use ProjectEnvVar instead of repositoryPattern - https://github.com/gitpod-com/gitpod/issues/5322
|
|
259
260
|
export function splitRepositoryPattern(repositoryPattern: string): string[] {
|
|
260
261
|
const patterns = repositoryPattern.split('/');
|
|
261
|
-
const repoPattern = patterns.
|
|
262
|
-
const ownerPattern = patterns
|
|
262
|
+
const repoPattern = patterns.slice(1).join('/')
|
|
263
|
+
const ownerPattern = patterns[0];
|
|
263
264
|
return [ownerPattern, repoPattern];
|
|
264
265
|
}
|
|
265
266
|
}
|
|
@@ -814,15 +815,14 @@ export namespace WithSnapshot {
|
|
|
814
815
|
}
|
|
815
816
|
}
|
|
816
817
|
|
|
817
|
-
export interface WithPrebuild {
|
|
818
|
-
snapshotBucketId: string;
|
|
818
|
+
export interface WithPrebuild extends WithSnapshot {
|
|
819
819
|
prebuildWorkspaceId: string;
|
|
820
820
|
wasPrebuilt: true;
|
|
821
821
|
}
|
|
822
822
|
export namespace WithPrebuild {
|
|
823
823
|
export function is(context: any): context is WithPrebuild {
|
|
824
824
|
return context
|
|
825
|
-
&&
|
|
825
|
+
&& WithSnapshot.is(context)
|
|
826
826
|
&& 'prebuildWorkspaceId' in context
|
|
827
827
|
&& 'wasPrebuilt' in context;
|
|
828
828
|
}
|
|
@@ -891,6 +891,18 @@ export namespace PrebuiltWorkspaceContext {
|
|
|
891
891
|
}
|
|
892
892
|
}
|
|
893
893
|
|
|
894
|
+
export interface WithReferrerContext extends WorkspaceContext {
|
|
895
|
+
referrer: string
|
|
896
|
+
referrerIde?: string
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
export namespace WithReferrerContext {
|
|
900
|
+
export function is(context: any): context is WithReferrerContext {
|
|
901
|
+
return context
|
|
902
|
+
&& 'referrer' in context;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
894
906
|
export interface WithEnvvarsContext extends WorkspaceContext {
|
|
895
907
|
envvars: EnvVarWithValue[];
|
|
896
908
|
}
|
|
@@ -1158,6 +1170,8 @@ export interface AuthProviderEntry {
|
|
|
1158
1170
|
readonly status: AuthProviderEntry.Status;
|
|
1159
1171
|
|
|
1160
1172
|
readonly oauth: OAuth2Config;
|
|
1173
|
+
/** A random string that is to change whenever oauth changes (enforced on DB level) */
|
|
1174
|
+
readonly oauthRevision?: string;
|
|
1161
1175
|
}
|
|
1162
1176
|
|
|
1163
1177
|
export interface OAuth2Config {
|
|
@@ -42,7 +42,13 @@ export namespace Project {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export interface Overview {
|
|
45
|
-
branches: BranchDetails[]
|
|
45
|
+
branches: BranchDetails[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export namespace Overview {
|
|
49
|
+
export function is(data?: any): data is Project.Overview {
|
|
50
|
+
return Array.isArray(data?.branches);
|
|
51
|
+
}
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
export interface BranchDetails {
|
package/src/util/tracing.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import * as opentracing from 'opentracing';
|
|
9
9
|
import { TracingConfig, initTracerFromEnv } from 'jaeger-client';
|
|
10
10
|
import { Sampler, SamplingDecision } from './jaeger-client-types';
|
|
11
|
-
import {
|
|
11
|
+
import { initGlobalTracer } from 'opentracing';
|
|
12
12
|
import { injectable } from 'inversify';
|
|
13
13
|
import { ResponseError } from 'vscode-jsonrpc';
|
|
14
14
|
import { log, LogContext } from './logging';
|
|
@@ -22,18 +22,19 @@ export type TraceContextWithSpan = TraceContext & {
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
export namespace TraceContext {
|
|
25
|
-
export function startSpan(operation: string, parentCtx?: TraceContext
|
|
25
|
+
export function startSpan(operation: string, parentCtx?: TraceContext): opentracing.Span {
|
|
26
26
|
const options: opentracing.SpanOptions = {};
|
|
27
27
|
if (parentCtx && parentCtx.span && !!parentCtx.span.context().toSpanId()) {
|
|
28
28
|
options.childOf = parentCtx.span;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
// TODO(gpl) references lead to a huge amount of errors in prod logs. Avoid those until we have time to figure out how to fix it.
|
|
31
|
+
// if (referencedSpans) {
|
|
32
|
+
// // note: allthough followsForm's type says it takes 'opentracing.Span | opentracing.SpanContext', it only works with SpanContext (typing mismatch)
|
|
33
|
+
// // note2: we need to filter out debug spans (spanId === "")
|
|
34
|
+
// options.references = referencedSpans.filter(s => s !== undefined)
|
|
35
|
+
// .filter(s => !!s!.context().toSpanId())
|
|
36
|
+
// .map(s => followsFrom(s!.context()));
|
|
37
|
+
// }
|
|
37
38
|
|
|
38
39
|
return opentracing.globalTracer().startSpan(operation, options);
|
|
39
40
|
}
|
|
@@ -43,16 +44,16 @@ export namespace TraceContext {
|
|
|
43
44
|
return { span };
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
export function withSpan(operation: string, callback: () => void, ctx?: TraceContext
|
|
47
|
+
export function withSpan(operation: string, callback: (ctx: TraceContext) => void, ctx?: TraceContext): void {
|
|
47
48
|
// if we don't have a parent span, don't create a trace here as those <trace-without-root-spans> are not useful.
|
|
48
49
|
if (!ctx || !ctx.span || !ctx.span.context()) {
|
|
49
|
-
callback();
|
|
50
|
+
callback({});
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
const span = TraceContext.startSpan(operation, ctx
|
|
54
|
+
const span = TraceContext.startSpan(operation, ctx);
|
|
54
55
|
try {
|
|
55
|
-
callback();
|
|
56
|
+
callback({span});
|
|
56
57
|
} catch (e) {
|
|
57
58
|
TraceContext.setError({span}, e);
|
|
58
59
|
throw e;
|
package/src/workspace-cluster.ts
CHANGED
|
@@ -35,9 +35,6 @@ export interface WorkspaceCluster {
|
|
|
35
35
|
|
|
36
36
|
// An optional set of constraints that limit who can start workspaces on the cluster
|
|
37
37
|
admissionConstraints?: AdmissionConstraint[];
|
|
38
|
-
|
|
39
|
-
// An optional set of admission preferences that guide cluster selection
|
|
40
|
-
admissionPreferences?: AdmissionPreference[];
|
|
41
38
|
}
|
|
42
39
|
|
|
43
40
|
export type WorkspaceClusterState = "available" | "cordoned" | "draining";
|
|
@@ -55,14 +52,25 @@ export namespace TLSConfig {
|
|
|
55
52
|
export type WorkspaceClusterWoTLS = Omit<WorkspaceCluster, "tls">;
|
|
56
53
|
export type WorkspaceManagerConnectionInfo = Pick<WorkspaceCluster, "name" | "url" | "tls">;
|
|
57
54
|
|
|
58
|
-
export type AdmissionConstraint = AdmissionConstraintFeaturePreview |
|
|
55
|
+
export type AdmissionConstraint = AdmissionConstraintFeaturePreview | AdmissionConstraintHasPermission | AdmissionConstraintHasUserLevel | AdmissionConstraintHasMoreResources;
|
|
59
56
|
export type AdmissionConstraintFeaturePreview = { type: "has-feature-preview" };
|
|
60
|
-
export type
|
|
57
|
+
export type AdmissionConstraintHasPermission = { type: "has-permission", permission: PermissionName };
|
|
61
58
|
export type AdmissionConstraintHasUserLevel = { type: "has-user-level", level: string };
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
export
|
|
65
|
-
|
|
59
|
+
export type AdmissionConstraintHasMoreResources = { type: "has-more-resources" };
|
|
60
|
+
|
|
61
|
+
export namespace AdmissionConstraint {
|
|
62
|
+
export function is(o: any): o is AdmissionConstraint {
|
|
63
|
+
return !!o
|
|
64
|
+
&& 'type' in o;
|
|
65
|
+
}
|
|
66
|
+
export function isHasPermissionConstraint(o: any): o is AdmissionConstraintHasPermission {
|
|
67
|
+
return is(o)
|
|
68
|
+
&& o.type === "has-permission";
|
|
69
|
+
}
|
|
70
|
+
export function hasPermission(ac: AdmissionConstraint, permission: PermissionName): boolean {
|
|
71
|
+
return isHasPermissionConstraint(ac) && ac.permission === permission;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
66
74
|
|
|
67
75
|
export const WorkspaceClusterDB = Symbol("WorkspaceClusterDB");
|
|
68
76
|
export interface WorkspaceClusterDB {
|
|
@@ -51,6 +51,11 @@ export interface WorkspaceInstance {
|
|
|
51
51
|
|
|
52
52
|
// instance is hard-deleted on the database and about to be collected by db-sync
|
|
53
53
|
readonly deleted?: boolean;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Contains information about the image build, if there was any
|
|
57
|
+
*/
|
|
58
|
+
imageBuildInfo?: ImageBuildInfo;
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
// WorkspaceInstanceStatus describes the current state of a workspace instance
|
|
@@ -213,3 +218,18 @@ export interface WorkspaceInstanceConfiguration {
|
|
|
213
218
|
// supervisorImage is the ref of the supervisor image this instance uses.
|
|
214
219
|
supervisorImage?: string;
|
|
215
220
|
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Holds information about the image build (if there was one) for this WorkspaceInstance
|
|
224
|
+
*/
|
|
225
|
+
export interface ImageBuildInfo {
|
|
226
|
+
log?: ImageBuildLogInfo,
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Holds information about how to access logs for this an image build
|
|
231
|
+
*/
|
|
232
|
+
export interface ImageBuildLogInfo {
|
|
233
|
+
url: string,
|
|
234
|
+
headers: { [key: string]: string },
|
|
235
|
+
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Message } from "vscode-jsonrpc";
|
|
2
|
-
export interface ResolvedConnectionErrorHandlerOptions {
|
|
3
|
-
readonly serverName: string;
|
|
4
|
-
/**
|
|
5
|
-
* The maximum amount of errors allowed before stopping the server.
|
|
6
|
-
*/
|
|
7
|
-
readonly maxErrors: number;
|
|
8
|
-
/**
|
|
9
|
-
* The maimum amount of restarts allowed in the restart interval.
|
|
10
|
-
*/
|
|
11
|
-
readonly maxRestarts: number;
|
|
12
|
-
/**
|
|
13
|
-
* In minutes.
|
|
14
|
-
*/
|
|
15
|
-
readonly restartInterval: number;
|
|
16
|
-
}
|
|
17
|
-
export declare type ConnectionErrorHandlerOptions = Partial<ResolvedConnectionErrorHandlerOptions> & {
|
|
18
|
-
readonly serverName: string;
|
|
19
|
-
};
|
|
20
|
-
export declare class ConnectionErrorHandler {
|
|
21
|
-
protected readonly options: ResolvedConnectionErrorHandlerOptions;
|
|
22
|
-
constructor(options: ConnectionErrorHandlerOptions);
|
|
23
|
-
shouldStop(error: Error, message?: Message, count?: number): boolean;
|
|
24
|
-
protected readonly restarts: number[];
|
|
25
|
-
shouldRestart(): boolean;
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=connection-error-handler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connection-error-handler.d.ts","sourceRoot":"","sources":["../../src/messaging/connection-error-handler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGzC,MAAM,WAAW,qCAAqC;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CACnC;AAED,oBAAY,6BAA6B,GAAG,OAAO,CAAC,qCAAqC,CAAC,GAAG;IACzF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC9B,CAAC;AAEF,qBAAa,sBAAsB;IAE/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,qCAAqC,CAAC;gBACtD,OAAO,EAAE,6BAA6B;IASlD,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAIpE,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAM;IAC3C,aAAa,IAAI,OAAO;CAc3B"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (C) 2017 TypeFox and others.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.ConnectionErrorHandler = void 0;
|
|
10
|
-
const logging_1 = require("../util/logging");
|
|
11
|
-
class ConnectionErrorHandler {
|
|
12
|
-
constructor(options) {
|
|
13
|
-
this.restarts = [];
|
|
14
|
-
this.options = Object.assign({ maxErrors: 3, maxRestarts: 5, restartInterval: 3 }, options);
|
|
15
|
-
}
|
|
16
|
-
shouldStop(error, message, count) {
|
|
17
|
-
return !count || count > this.options.maxErrors;
|
|
18
|
-
}
|
|
19
|
-
shouldRestart() {
|
|
20
|
-
this.restarts.push(Date.now());
|
|
21
|
-
if (this.restarts.length <= this.options.maxRestarts) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
const diff = this.restarts[this.restarts.length - 1] - this.restarts[0];
|
|
25
|
-
if (diff <= this.options.restartInterval * 60 * 1000) {
|
|
26
|
-
logging_1.log.error(`Server ${this.options.serverName} crashed ${this.options.maxRestarts} times in the last ${this.options.restartInterval} minutes. Will not restart`);
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
this.restarts.shift();
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.ConnectionErrorHandler = ConnectionErrorHandler;
|
|
34
|
-
//# sourceMappingURL=connection-error-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connection-error-handler.js","sourceRoot":"","sources":["../../src/messaging/connection-error-handler.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAGH,6CAAsC;AAsBtC,MAAa,sBAAsB;IAG/B,YAAY,OAAsC;QAa/B,aAAQ,GAAa,EAAE,CAAC;QAZvC,IAAI,CAAC,OAAO,mBACR,SAAS,EAAE,CAAC,EACZ,WAAW,EAAE,CAAC,EACd,eAAe,EAAE,CAAC,IACf,OAAO,CACb,CAAC;IACN,CAAC;IAED,UAAU,CAAC,KAAY,EAAE,OAAiB,EAAE,KAAc;QACtD,OAAO,CAAC,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IACpD,CAAC;IAGD,aAAa;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YAClD,OAAO,IAAI,CAAC;SACf;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,EAAE,GAAG,IAAI,EAAE;YAClD,aAAG,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,UAAU,YAAY,IAAI,CAAC,OAAO,CAAC,WAAW,sBAAsB,IAAI,CAAC,OAAO,CAAC,eAAe,4BAA4B,CAAC,CAAC;YAC/J,OAAO,KAAK,CAAC;SAChB;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IAChB,CAAC;CAEJ;AA/BD,wDA+BC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2020 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
|
-
import { LogContext } from './logging';
|
|
7
|
-
export declare class SafePromise {
|
|
8
|
-
static catchAndLog<T>(p: Promise<T>, logCtx?: LogContext): Promise<T>;
|
|
9
|
-
static catch<T>(p: Promise<T>, handler: (err: any) => void): Promise<T>;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=safe-promise.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"safe-promise.d.ts","sourceRoot":"","sources":["../../src/util/safe-promise.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAO,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,qBAAa,WAAW;WACN,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,UAAU;WASjD,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;CAMjF"}
|
package/lib/util/safe-promise.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
|
|
4
|
-
* Licensed under the GNU Affero General Public License (AGPL).
|
|
5
|
-
* See License-AGPL.txt in the project root for license information.
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.SafePromise = void 0;
|
|
9
|
-
const logging_1 = require("./logging");
|
|
10
|
-
class SafePromise {
|
|
11
|
-
static catchAndLog(p, logCtx) {
|
|
12
|
-
return SafePromise.catch(p, (err) => {
|
|
13
|
-
if (logCtx) {
|
|
14
|
-
logging_1.log.error(logCtx, err);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
logging_1.log.error(err);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
;
|
|
22
|
-
static catch(p, handler) {
|
|
23
|
-
return p.catch((err) => {
|
|
24
|
-
handler(err);
|
|
25
|
-
return {}; // Nobody will ever see this value as the Promise already failed. It's just there to please the compiler
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
;
|
|
29
|
-
}
|
|
30
|
-
exports.SafePromise = SafePromise;
|
|
31
|
-
//# sourceMappingURL=safe-promise.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"safe-promise.js","sourceRoot":"","sources":["../../src/util/safe-promise.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAGH,uCAA4C;AAE5C,MAAa,WAAW;IACb,MAAM,CAAC,WAAW,CAAI,CAAa,EAAE,MAAmB;QAC3D,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;YAChC,IAAI,MAAM,EAAE;gBACR,aAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;aAC1B;iBAAM;gBACH,aAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;aAClB;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAAA,CAAC;IACK,MAAM,CAAC,KAAK,CAAI,CAAa,EAAE,OAA2B;QAC7D,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,OAAO,CAAC,GAAG,CAAC,CAAC;YACb,OAAO,EAAO,CAAC,CAAC,wGAAwG;QAC5H,CAAC,CAAC,CAAC;IACP,CAAC;IAAA,CAAC;CACL;AAhBD,kCAgBC"}
|