@gitpod/gitpod-protocol 0.1.5-se-workspace-for-teams.0 → 0.1.5-se-init.1
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 +9 -2
- package/lib/accounting-protocol.d.ts +0 -1
- package/lib/accounting-protocol.d.ts.map +1 -1
- package/lib/accounting-protocol.js +10 -11
- package/lib/accounting-protocol.js.map +1 -1
- package/lib/admin-protocol.d.ts +8 -2
- package/lib/admin-protocol.d.ts.map +1 -1
- package/lib/admin-protocol.js +2 -13
- package/lib/admin-protocol.js.map +1 -1
- package/lib/analytics.d.ts +13 -1
- package/lib/analytics.d.ts.map +1 -1
- package/lib/context-url.js +4 -4
- package/lib/context-url.js.map +1 -1
- package/lib/context-url.spec.js +45 -48
- package/lib/context-url.spec.js.map +1 -1
- package/lib/email-protocol.js +4 -4
- package/lib/email-protocol.js.map +1 -1
- package/lib/encryption/container-module.js +4 -4
- package/lib/encryption/container-module.js.map +1 -1
- package/lib/encryption/encryption-engine.js +19 -20
- package/lib/encryption/encryption-engine.js.map +1 -1
- package/lib/encryption/encryption-engine.spec.js +29 -36
- package/lib/encryption/encryption-engine.spec.js.map +1 -1
- package/lib/encryption/encryption-service.js +29 -43
- package/lib/encryption/encryption-service.js.map +1 -1
- package/lib/encryption/key-provider.js +25 -30
- package/lib/encryption/key-provider.js.map +1 -1
- package/lib/env.d.ts +0 -1
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +12 -14
- package/lib/env.js.map +1 -1
- package/lib/gitpod-file-parser.js +25 -41
- package/lib/gitpod-file-parser.js.map +1 -1
- package/lib/gitpod-file-parser.spec.js +116 -116
- package/lib/gitpod-file-parser.spec.js.map +1 -1
- package/lib/gitpod-service.d.ts +31 -9
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +149 -295
- package/lib/gitpod-service.js.map +1 -1
- package/lib/ide-protocol.d.ts +81 -0
- package/lib/ide-protocol.d.ts.map +1 -0
- package/lib/ide-protocol.js +8 -0
- package/lib/ide-protocol.js.map +1 -0
- 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/browser/connection.d.ts +3 -3
- package/lib/messaging/browser/connection.d.ts.map +1 -1
- package/lib/messaging/browser/connection.js +172 -35
- package/lib/messaging/browser/connection.js.map +1 -1
- package/lib/messaging/browser/window-connection.js +35 -55
- package/lib/messaging/browser/window-connection.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 +83 -0
- package/lib/messaging/client-call-metrics.js.map +1 -0
- package/lib/messaging/connection-error-handler.js +11 -23
- package/lib/messaging/connection-error-handler.js.map +1 -1
- package/lib/messaging/error.d.ts +1 -1
- package/lib/messaging/error.d.ts.map +1 -1
- package/lib/messaging/error.js +2 -2
- package/lib/messaging/error.js.map +1 -1
- package/lib/messaging/handler.d.ts +10 -0
- package/lib/messaging/handler.d.ts.map +1 -1
- package/lib/messaging/node/connection.d.ts +0 -10
- package/lib/messaging/node/connection.d.ts.map +1 -1
- package/lib/messaging/node/connection.js +12 -50
- package/lib/messaging/node/connection.js.map +1 -1
- package/lib/messaging/proxy-factory.d.ts +2 -0
- package/lib/messaging/proxy-factory.d.ts.map +1 -1
- package/lib/messaging/proxy-factory.js +74 -159
- package/lib/messaging/proxy-factory.js.map +1 -1
- package/lib/oss-allowlist.d.ts +14 -0
- package/lib/oss-allowlist.d.ts.map +1 -0
- package/lib/oss-allowlist.js +8 -0
- package/lib/oss-allowlist.js.map +1 -0
- package/lib/permission.d.ts +1 -2
- package/lib/permission.d.ts.map +1 -1
- package/lib/permission.js +12 -13
- package/lib/permission.js.map +1 -1
- package/lib/plans.d.ts +1 -1
- package/lib/plans.d.ts.map +1 -1
- package/lib/plans.js +38 -57
- package/lib/plans.js.map +1 -1
- package/lib/protocol.d.ts +12 -8
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +44 -114
- package/lib/protocol.js.map +1 -1
- package/lib/snapshot-url.d.ts +14 -0
- package/lib/snapshot-url.d.ts.map +1 -0
- package/lib/snapshot-url.js +26 -0
- package/lib/snapshot-url.js.map +1 -0
- package/lib/snapshot-url.spec.d.ts +7 -0
- package/lib/snapshot-url.spec.d.ts.map +1 -0
- package/lib/snapshot-url.spec.js +41 -0
- package/lib/snapshot-url.spec.js.map +1 -0
- package/lib/team-subscription-protocol.js +13 -13
- package/lib/team-subscription-protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +15 -0
- package/lib/teams-projects-protocol.d.ts.map +1 -1
- package/lib/teams-projects-protocol.js +4 -15
- package/lib/teams-projects-protocol.js.map +1 -1
- package/lib/util/analytics.d.ts.map +1 -1
- package/lib/util/analytics.js +35 -26
- package/lib/util/analytics.js.map +1 -1
- package/lib/util/async-iterator.js +55 -133
- package/lib/util/async-iterator.js.map +1 -1
- package/lib/util/cancelable.js +17 -59
- package/lib/util/cancelable.js.map +1 -1
- package/lib/util/date-time.js +8 -8
- package/lib/util/date-time.js.map +1 -1
- package/lib/util/deferred.js +10 -12
- package/lib/util/deferred.js.map +1 -1
- package/lib/util/disposable.js +26 -39
- package/lib/util/disposable.js.map +1 -1
- package/lib/util/event.js +58 -74
- package/lib/util/event.js.map +1 -1
- package/lib/util/garbage-collected-cache.d.ts +1 -0
- package/lib/util/garbage-collected-cache.d.ts.map +1 -1
- package/lib/util/garbage-collected-cache.js +26 -46
- package/lib/util/garbage-collected-cache.js.map +1 -1
- package/lib/util/generate-workspace-id.js +11 -67
- package/lib/util/generate-workspace-id.js.map +1 -1
- package/lib/util/generate-workspace-id.spec.js +34 -79
- package/lib/util/generate-workspace-id.spec.js.map +1 -1
- package/lib/util/gitpod-cookie.d.ts +20 -0
- package/lib/util/gitpod-cookie.d.ts.map +1 -0
- package/lib/util/gitpod-cookie.js +44 -0
- package/lib/util/gitpod-cookie.js.map +1 -0
- package/lib/util/gitpod-host-url.d.ts +1 -0
- package/lib/util/gitpod-host-url.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.js +96 -103
- package/lib/util/gitpod-host-url.js.map +1 -1
- package/lib/util/gitpod-host-url.spec.js +87 -135
- package/lib/util/gitpod-host-url.spec.js.map +1 -1
- package/lib/util/grpc.js +3 -3
- package/lib/util/grpc.js.map +1 -1
- package/lib/util/jaeger-client-types.d.ts +68 -0
- package/lib/util/jaeger-client-types.d.ts.map +1 -0
- package/lib/util/jaeger-client-types.js +8 -0
- package/lib/util/jaeger-client-types.js.map +1 -0
- package/lib/util/logging.d.ts +49 -33
- package/lib/util/logging.d.ts.map +1 -1
- package/lib/util/logging.js +107 -110
- package/lib/util/logging.js.map +1 -1
- package/lib/util/make-link.js +2 -2
- package/lib/util/make-link.js.map +1 -1
- package/lib/util/parse-workspace-id.d.ts +10 -0
- package/lib/util/parse-workspace-id.d.ts.map +1 -1
- package/lib/util/parse-workspace-id.js +31 -7
- package/lib/util/parse-workspace-id.js.map +1 -1
- package/lib/util/parse-workspace-id.spec.d.ts +4 -0
- package/lib/util/parse-workspace-id.spec.d.ts.map +1 -1
- package/lib/util/parse-workspace-id.spec.js +123 -84
- package/lib/util/parse-workspace-id.spec.js.map +1 -1
- package/lib/util/queue.js +16 -55
- package/lib/util/queue.js.map +1 -1
- package/lib/util/queue.spec.js +144 -288
- package/lib/util/queue.spec.js.map +1 -1
- package/lib/util/repeat.d.ts +15 -0
- package/lib/util/repeat.d.ts.map +1 -0
- package/lib/util/repeat.js +55 -0
- package/lib/util/repeat.js.map +1 -0
- package/lib/util/safe-promise.js +9 -12
- package/lib/util/safe-promise.js.map +1 -1
- package/lib/util/semaphore.js +15 -46
- package/lib/util/semaphore.js.map +1 -1
- package/lib/util/skip-if.js +6 -6
- package/lib/util/skip-if.js.map +1 -1
- package/lib/util/timeutil.js +16 -16
- package/lib/util/timeutil.js.map +1 -1
- package/lib/util/timeutil.spec.js +21 -24
- package/lib/util/timeutil.spec.js.map +1 -1
- package/lib/util/tracing.d.ts +50 -5
- package/lib/util/tracing.d.ts.map +1 -1
- package/lib/util/tracing.js +171 -63
- package/lib/util/tracing.js.map +1 -1
- package/lib/util/tracing.spec.d.ts +7 -0
- package/lib/util/tracing.spec.d.ts.map +1 -0
- package/lib/util/tracing.spec.js +121 -0
- package/lib/util/tracing.spec.js.map +1 -0
- package/lib/util/workspace-port-authentication.js +2 -2
- package/lib/util/workspace-port-authentication.js.map +1 -1
- package/lib/workspace-cluster.d.ts +11 -1
- package/lib/workspace-cluster.d.ts.map +1 -1
- package/lib/workspace-cluster.js +3 -3
- package/lib/workspace-cluster.js.map +1 -1
- package/lib/workspace-instance.d.ts +4 -2
- package/lib/workspace-instance.d.ts.map +1 -1
- package/lib/wsready.js +1 -1
- package/package.json +22 -12
- package/pkg-yarn.lock +14 -7
- package/src/accounting-protocol.ts +1 -3
- package/src/admin-protocol.ts +9 -3
- package/src/analytics.ts +16 -1
- package/src/email-protocol.ts +1 -1
- package/src/env.ts +0 -1
- package/src/gitpod-service.ts +31 -10
- package/src/ide-protocol.ts +92 -0
- package/src/index.ts +2 -0
- package/src/messaging/browser/connection.ts +176 -10
- package/src/messaging/client-call-metrics.ts +97 -0
- package/src/messaging/error.ts +2 -2
- package/src/messaging/handler.ts +12 -0
- package/src/messaging/node/connection.ts +3 -47
- package/src/messaging/proxy-factory.ts +13 -5
- package/src/oss-allowlist.ts +15 -0
- package/src/permission.ts +0 -1
- package/src/protocol.ts +14 -9
- package/src/snapshot-url.spec.ts +25 -0
- package/src/snapshot-url.ts +27 -0
- package/src/team-subscription-protocol.ts +1 -1
- package/src/teams-projects-protocol.ts +19 -1
- package/src/util/analytics.ts +17 -1
- package/src/util/garbage-collected-cache.ts +7 -1
- package/src/util/gitpod-cookie.ts +39 -0
- package/src/util/gitpod-host-url.ts +9 -5
- package/src/util/grpc.ts +3 -3
- package/src/util/jaeger-client-types.ts +102 -0
- package/src/util/logging.ts +102 -38
- package/src/util/parse-workspace-id.spec.ts +21 -1
- package/src/util/parse-workspace-id.ts +32 -6
- package/src/util/repeat.ts +45 -0
- package/src/util/tracing.spec.ts +83 -0
- package/src/util/tracing.ts +157 -18
- package/src/workspace-cluster.ts +8 -1
- package/src/workspace-instance.ts +12 -6
- package/src/wsready.ts +1 -1
- package/lib/util/repeater.d.ts +0 -22
- package/lib/util/repeater.d.ts.map +0 -1
- package/lib/util/repeater.js +0 -118
- package/lib/util/repeater.js.map +0 -1
- package/src/util/jaeger-client.d.ts +0 -105
- package/src/util/repeater.ts +0 -49
|
@@ -0,0 +1,97 @@
|
|
|
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 { injectable } from 'inversify';
|
|
8
|
+
import * as prometheusClient from 'prom-client';
|
|
9
|
+
|
|
10
|
+
type GrpcMethodType = 'unary' | 'client_stream' | 'server_stream' | 'bidi_stream';
|
|
11
|
+
export interface IGrpcCallMetricsLabels {
|
|
12
|
+
service: string,
|
|
13
|
+
method: string,
|
|
14
|
+
type: GrpcMethodType,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IGrpcCallMetricsLabelsWithCode extends IGrpcCallMetricsLabels {
|
|
18
|
+
code: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const IClientCallMetrics = Symbol("IClientCallMetrics");
|
|
22
|
+
|
|
23
|
+
export interface IClientCallMetrics {
|
|
24
|
+
started(labels: IGrpcCallMetricsLabels) : void;
|
|
25
|
+
sent(labels: IGrpcCallMetricsLabels) : void;
|
|
26
|
+
received(labels: IGrpcCallMetricsLabels) : void;
|
|
27
|
+
handled(labels: IGrpcCallMetricsLabelsWithCode) : void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@injectable()
|
|
31
|
+
export class PrometheusClientCallMetrics implements IClientCallMetrics {
|
|
32
|
+
|
|
33
|
+
readonly startedCounter: prometheusClient.Counter<string>;
|
|
34
|
+
readonly sentCounter: prometheusClient.Counter<string>;
|
|
35
|
+
readonly receivedCounter: prometheusClient.Counter<string>;
|
|
36
|
+
readonly handledCounter: prometheusClient.Counter<string>;
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
this.startedCounter = new prometheusClient.Counter({
|
|
40
|
+
name: 'grpc_client_started_total',
|
|
41
|
+
help: 'Total number of RPCs started on the client.',
|
|
42
|
+
labelNames: ['grpc_service', 'grpc_method', 'grpc_type'],
|
|
43
|
+
registers: [prometheusClient.register]
|
|
44
|
+
});
|
|
45
|
+
this.sentCounter = new prometheusClient.Counter({
|
|
46
|
+
name: 'grpc_client_msg_sent_total',
|
|
47
|
+
help: ' Total number of gRPC stream messages sent by the client.',
|
|
48
|
+
labelNames: ['grpc_service', 'grpc_method', 'grpc_type'],
|
|
49
|
+
registers: [prometheusClient.register]
|
|
50
|
+
});
|
|
51
|
+
this.receivedCounter = new prometheusClient.Counter({
|
|
52
|
+
name: 'grpc_client_msg_received_total',
|
|
53
|
+
help: 'Total number of RPC stream messages received by the client.',
|
|
54
|
+
labelNames: ['grpc_service', 'grpc_method', 'grpc_type'],
|
|
55
|
+
registers: [prometheusClient.register]
|
|
56
|
+
});
|
|
57
|
+
this.handledCounter = new prometheusClient.Counter({
|
|
58
|
+
name: 'grpc_client_handled_total',
|
|
59
|
+
help: 'Total number of RPCs completed by the client, regardless of success or failure.',
|
|
60
|
+
labelNames: ['grpc_service', 'grpc_method', 'grpc_type', 'grpc_code'],
|
|
61
|
+
registers: [prometheusClient.register]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
started(labels: IGrpcCallMetricsLabels): void {
|
|
66
|
+
this.startedCounter.inc({
|
|
67
|
+
grpc_service: labels.service,
|
|
68
|
+
grpc_method: labels.method,
|
|
69
|
+
grpc_type: labels.type
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
sent(labels: IGrpcCallMetricsLabels): void {
|
|
74
|
+
this.sentCounter.inc({
|
|
75
|
+
grpc_service: labels.service,
|
|
76
|
+
grpc_method: labels.method,
|
|
77
|
+
grpc_type: labels.type
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
received(labels: IGrpcCallMetricsLabels): void {
|
|
82
|
+
this.receivedCounter.inc({
|
|
83
|
+
grpc_service: labels.service,
|
|
84
|
+
grpc_method: labels.method,
|
|
85
|
+
grpc_type: labels.type
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
handled(labels: IGrpcCallMetricsLabelsWithCode): void {
|
|
90
|
+
this.handledCounter.inc({
|
|
91
|
+
grpc_service: labels.service,
|
|
92
|
+
grpc_method: labels.method,
|
|
93
|
+
grpc_type: labels.type,
|
|
94
|
+
grpc_code: labels.code
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
package/src/messaging/error.ts
CHANGED
|
@@ -76,6 +76,6 @@ export namespace ErrorCodes {
|
|
|
76
76
|
// 620 Team Subscription Assignment Failed
|
|
77
77
|
export const TEAM_SUBSCRIPTION_ASSIGNMENT_FAILED = 620;
|
|
78
78
|
|
|
79
|
-
//
|
|
80
|
-
export const
|
|
79
|
+
// 630 Snapshot Error
|
|
80
|
+
export const SNAPSHOT_ERROR = 630;
|
|
81
81
|
}
|
package/src/messaging/handler.ts
CHANGED
|
@@ -13,3 +13,15 @@ export interface ConnectionHandler {
|
|
|
13
13
|
readonly path: string;
|
|
14
14
|
onConnection(connection: MessageConnection, session?: object): void;
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
export interface ConnectionEventHandler {
|
|
18
|
+
/**
|
|
19
|
+
* Called when the transport underpinning the connection got closed
|
|
20
|
+
*/
|
|
21
|
+
onTransportDidClose(): void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Called when the transport underpinning the connection is (re-)opened
|
|
25
|
+
*/
|
|
26
|
+
onTransportDidOpen(): void;
|
|
27
|
+
}
|
|
@@ -7,71 +7,27 @@
|
|
|
7
7
|
|
|
8
8
|
import * as ws from "ws";
|
|
9
9
|
import * as http from "http";
|
|
10
|
-
import * as https from "https";
|
|
11
|
-
import * as url from "url";
|
|
12
10
|
import * as net from "net";
|
|
13
|
-
import {
|
|
14
|
-
import { createWebSocketConnection, IWebSocket } from "vscode-ws-jsonrpc";
|
|
11
|
+
import { IWebSocket } from "vscode-ws-jsonrpc";
|
|
15
12
|
import { log } from '../../util/logging';
|
|
16
13
|
|
|
17
|
-
export interface IServerOptions {
|
|
18
|
-
readonly server: http.Server | https.Server;
|
|
19
|
-
readonly path?: string;
|
|
20
|
-
matches?(request: http.IncomingMessage): boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function createServerWebSocketConnection(options: IServerOptions, onConnect: (connection: MessageConnection) => void): void {
|
|
24
|
-
openJsonRpcSocket(options, socket => {
|
|
25
|
-
onConnect(createWebSocketConnection(socket, console));
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function openJsonRpcSocket(options: IServerOptions, onOpen: (socket: IWebSocket) => void): void {
|
|
30
|
-
openSocket(options, socket => {
|
|
31
|
-
const webSocket = toIWebSocket(socket);
|
|
32
|
-
onOpen(webSocket);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
14
|
export interface OnOpen {
|
|
37
15
|
(webSocket: ws, request: http.IncomingMessage, socket: net.Socket, head: Buffer): void;
|
|
38
16
|
}
|
|
39
17
|
|
|
40
|
-
export function openSocket(options: IServerOptions, onOpen: OnOpen): void {
|
|
41
|
-
const wss = new ws.Server({
|
|
42
|
-
noServer: true,
|
|
43
|
-
perMessageDeflate: {
|
|
44
|
-
// don't compress if a message is less than 256kb
|
|
45
|
-
threshold: 256 * 1024
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
options.server.on('upgrade', (request: http.IncomingMessage, socket: net.Socket, head: Buffer) => {
|
|
49
|
-
const pathname = request.url ? url.parse(request.url).pathname : undefined;
|
|
50
|
-
if (options.path && pathname === options.path || options.matches && options.matches(request)) {
|
|
51
|
-
wss.handleUpgrade(request, socket, head, webSocket => {
|
|
52
|
-
if (webSocket.readyState === webSocket.OPEN) {
|
|
53
|
-
onOpen(webSocket, request, socket, head);
|
|
54
|
-
} else {
|
|
55
|
-
webSocket.on('open', () => onOpen(webSocket, request, socket, head));
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
18
|
export function toIWebSocket(webSocket: ws) {
|
|
63
19
|
let sendsAfterOpen = 0;
|
|
64
20
|
return <IWebSocket>{
|
|
65
21
|
send: content => {
|
|
66
22
|
if (webSocket.readyState !== ws.OPEN) {
|
|
67
23
|
if (sendsAfterOpen++ > 3) {
|
|
68
|
-
log.
|
|
24
|
+
//log.debug(`Repeated try to send on closed web socket (readyState was ${webSocket.readyState})`, { ws });
|
|
69
25
|
}
|
|
70
26
|
return;
|
|
71
27
|
}
|
|
72
28
|
webSocket.send(content, err => {
|
|
73
29
|
if (err) {
|
|
74
|
-
log.error('
|
|
30
|
+
log.error('error in ws.send()', err, { ws });
|
|
75
31
|
}
|
|
76
32
|
})
|
|
77
33
|
},
|
|
@@ -105,13 +105,19 @@ export class JsonRpcProxyFactory<T extends object> implements ProxyHandler<T> {
|
|
|
105
105
|
this.connectionPromiseResolve = resolve
|
|
106
106
|
);
|
|
107
107
|
this.connectionPromise.then(connection => {
|
|
108
|
-
connection.onClose(() =>
|
|
109
|
-
|
|
110
|
-
);
|
|
111
|
-
this.onDidOpenConnectionEmitter.fire(undefined);
|
|
108
|
+
connection.onClose(() => this.fireConnectionClosed());
|
|
109
|
+
this.fireConnectionOpened();
|
|
112
110
|
});
|
|
113
111
|
}
|
|
114
112
|
|
|
113
|
+
fireConnectionClosed() {
|
|
114
|
+
this.onDidCloseConnectionEmitter.fire(undefined)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fireConnectionOpened() {
|
|
118
|
+
this.onDidOpenConnectionEmitter.fire(undefined);
|
|
119
|
+
}
|
|
120
|
+
|
|
115
121
|
/**
|
|
116
122
|
* Connect a MessageConnection to the factory.
|
|
117
123
|
*
|
|
@@ -158,7 +164,9 @@ export class JsonRpcProxyFactory<T extends object> implements ProxyHandler<T> {
|
|
|
158
164
|
* methods calls.
|
|
159
165
|
*/
|
|
160
166
|
protected onNotification(method: string, ...args: any[]): void {
|
|
161
|
-
this.target[method]
|
|
167
|
+
if (this.target[method]) {
|
|
168
|
+
this.target[method](...args);
|
|
169
|
+
}
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
/**
|
|
@@ -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 interface OssAllowList {
|
|
8
|
+
/**
|
|
9
|
+
* A string that identifies a GitHub/GitLab/Bitbucket identity of the form "<host>/<profilename>"
|
|
10
|
+
* E.g., "github.com/geropl"
|
|
11
|
+
*/
|
|
12
|
+
identity: string,
|
|
13
|
+
|
|
14
|
+
deleted?: boolean,
|
|
15
|
+
}
|
package/src/permission.ts
CHANGED
|
@@ -16,7 +16,6 @@ export const Permissions = {
|
|
|
16
16
|
"admin-api": undefined,
|
|
17
17
|
"ide-settings": undefined,
|
|
18
18
|
"new-workspace-cluster": undefined,
|
|
19
|
-
"teams-and-projects": undefined,
|
|
20
19
|
};
|
|
21
20
|
export type PermissionName = keyof (typeof Permissions);
|
|
22
21
|
export const Roles = {"devops": undefined, "viewer": undefined, "admin": undefined };
|
package/src/protocol.ts
CHANGED
|
@@ -114,6 +114,8 @@ export interface EmailNotificationSettings {
|
|
|
114
114
|
|
|
115
115
|
export type IDESettings = {
|
|
116
116
|
defaultIde?: string
|
|
117
|
+
useDesktopIde?: boolean
|
|
118
|
+
defaultDesktopIde?: string
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
export interface UserPlatform {
|
|
@@ -135,14 +137,6 @@ export interface UserPlatform {
|
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
export interface UserFeatureSettings {
|
|
138
|
-
/**
|
|
139
|
-
* This field is used as marker to grant users a free trial for using private repositories,
|
|
140
|
-
* independent of any subscription or Chargebee.
|
|
141
|
-
* - it is set when the user uses their first private repo
|
|
142
|
-
* - whether the trial is expired or not is juged by the UserService
|
|
143
|
-
*/
|
|
144
|
-
privateRepoTrialStartDate?: string;
|
|
145
|
-
|
|
146
140
|
/**
|
|
147
141
|
* Permanent feature flags are added to each and every workspace instance
|
|
148
142
|
* this user starts.
|
|
@@ -378,11 +372,16 @@ export interface PendingGithubEvent {
|
|
|
378
372
|
export interface Snapshot {
|
|
379
373
|
id: string;
|
|
380
374
|
creationTime: string;
|
|
375
|
+
availableTime?: string;
|
|
381
376
|
originalWorkspaceId: string;
|
|
382
377
|
bucketId: string;
|
|
383
378
|
layoutData?: string;
|
|
379
|
+
state: SnapshotState;
|
|
380
|
+
message?: string;
|
|
384
381
|
}
|
|
385
382
|
|
|
383
|
+
export type SnapshotState = 'pending' | 'available' | 'error';
|
|
384
|
+
|
|
386
385
|
export interface LayoutData {
|
|
387
386
|
workspaceId: string;
|
|
388
387
|
lastUpdatedTime: string;
|
|
@@ -559,6 +558,9 @@ export interface WorkspaceConfig {
|
|
|
559
558
|
github?: GithubAppConfig;
|
|
560
559
|
vscode?: VSCodeConfig;
|
|
561
560
|
|
|
561
|
+
/** deprecated. Enabled by default **/
|
|
562
|
+
experimentalNetwork?: boolean;
|
|
563
|
+
|
|
562
564
|
/**
|
|
563
565
|
* Where the config object originates from.
|
|
564
566
|
*
|
|
@@ -682,6 +684,8 @@ export interface PortConfig {
|
|
|
682
684
|
port: number;
|
|
683
685
|
onOpen?: PortOnOpen;
|
|
684
686
|
visibility?: PortVisibility;
|
|
687
|
+
description?: string;
|
|
688
|
+
name?: string;
|
|
685
689
|
}
|
|
686
690
|
export namespace PortConfig {
|
|
687
691
|
export function is(config: any): config is PortConfig {
|
|
@@ -705,7 +709,7 @@ export interface TaskConfig {
|
|
|
705
709
|
init?: string;
|
|
706
710
|
prebuild?: string;
|
|
707
711
|
command?: string;
|
|
708
|
-
env?: { [env: string]:
|
|
712
|
+
env?: { [env: string]: any };
|
|
709
713
|
openIn?: 'bottom' | 'main' | 'left' | 'right';
|
|
710
714
|
openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
|
|
711
715
|
}
|
|
@@ -769,6 +773,7 @@ export namespace ExternalImageConfigFile {
|
|
|
769
773
|
|
|
770
774
|
export interface WorkspaceContext {
|
|
771
775
|
title: string;
|
|
776
|
+
/** This contains the URL portion of the contextURL (which might contain other modifiers as well). It's optional because it's not set for older workspaces. */
|
|
772
777
|
normalizedContextURL?: string;
|
|
773
778
|
forceCreateNewWorkspace?: boolean;
|
|
774
779
|
forceImageBuild?: boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
|
|
7
|
+
import { suite, test } from "mocha-typescript"
|
|
8
|
+
import * as chai from "chai"
|
|
9
|
+
import { SnapshotUrl } from ".";
|
|
10
|
+
|
|
11
|
+
const expect = chai.expect
|
|
12
|
+
|
|
13
|
+
@suite class TestSnapshotUrlParser {
|
|
14
|
+
|
|
15
|
+
@test public testPositive() {
|
|
16
|
+
const actual = SnapshotUrl.parse("workspaces/c362d434-6faa-4ce0-9ad4-91b4a87c4abe/3f0556f7-4afa-11e9-98d5-52f8983b9279.tar@gitpod-prodcopy-user-e1e28f18-0354-4a5d-b6b4-8879a2ff73fd");
|
|
17
|
+
|
|
18
|
+
expect(actual).to.deep.equal(<SnapshotUrl>{
|
|
19
|
+
bucketId: "gitpod-prodcopy-user-e1e28f18-0354-4a5d-b6b4-8879a2ff73fd",
|
|
20
|
+
filename: "3f0556f7-4afa-11e9-98d5-52f8983b9279.tar",
|
|
21
|
+
fullPath: "workspaces/c362d434-6faa-4ce0-9ad4-91b4a87c4abe/3f0556f7-4afa-11e9-98d5-52f8983b9279.tar",
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
module.exports = new TestSnapshotUrlParser() // Only to circumvent no usage warning :-/
|
|
@@ -0,0 +1,27 @@
|
|
|
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 interface SnapshotUrl {
|
|
8
|
+
bucketId: string;
|
|
9
|
+
fullPath: string;
|
|
10
|
+
filename: string;
|
|
11
|
+
}
|
|
12
|
+
export namespace SnapshotUrl {
|
|
13
|
+
export function parse(url: string): SnapshotUrl {
|
|
14
|
+
const parts = url.split("@");
|
|
15
|
+
if (parts.length !== 2) {
|
|
16
|
+
throw new Error(`cannot parse snapshot URL: ${url}`);
|
|
17
|
+
}
|
|
18
|
+
const [fullPath, bucketId] = parts;
|
|
19
|
+
|
|
20
|
+
const pathParts = fullPath.split("/");
|
|
21
|
+
if (pathParts.length < 1) {
|
|
22
|
+
throw new Error(`cannot parse snapshot URL: ${url}`);
|
|
23
|
+
}
|
|
24
|
+
const filename = pathParts[pathParts.length - 1];
|
|
25
|
+
return { bucketId, fullPath, filename };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -5,20 +5,27 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { PrebuiltWorkspaceState } from "./protocol";
|
|
8
|
-
import uuidv4
|
|
8
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
import { DeepPartial } from "./util/deep-partial";
|
|
9
10
|
|
|
10
11
|
export interface ProjectConfig {
|
|
11
12
|
'.gitpod.yml': string;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
export interface ProjectSettings {
|
|
16
|
+
useIncrementalPrebuilds?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
export interface Project {
|
|
15
20
|
id: string;
|
|
16
21
|
name: string;
|
|
22
|
+
slug?: string;
|
|
17
23
|
cloneUrl: string;
|
|
18
24
|
teamId?: string;
|
|
19
25
|
userId?: string;
|
|
20
26
|
appInstallationId: string;
|
|
21
27
|
config?: ProjectConfig;
|
|
28
|
+
settings?: ProjectSettings;
|
|
22
29
|
creationTime: string;
|
|
23
30
|
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
24
31
|
deleted?: boolean;
|
|
@@ -54,14 +61,18 @@ export namespace Project {
|
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
64
|
+
export type PartialProject = DeepPartial<Project> & Pick<Project, 'id'>;
|
|
65
|
+
|
|
57
66
|
export interface PrebuildWithStatus {
|
|
58
67
|
info: PrebuildInfo;
|
|
59
68
|
status: PrebuiltWorkspaceState;
|
|
69
|
+
error?: string;
|
|
60
70
|
}
|
|
61
71
|
|
|
62
72
|
export interface PrebuildInfo {
|
|
63
73
|
id: string;
|
|
64
74
|
buildWorkspaceId: string;
|
|
75
|
+
basedOnPrebuildId?: string;
|
|
65
76
|
|
|
66
77
|
teamId?: string;
|
|
67
78
|
userId?: string;
|
|
@@ -90,11 +101,18 @@ export namespace PrebuildInfo {
|
|
|
90
101
|
}
|
|
91
102
|
}
|
|
92
103
|
|
|
104
|
+
export interface StartPrebuildResult {
|
|
105
|
+
prebuildId: string;
|
|
106
|
+
wsid: string;
|
|
107
|
+
done: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
93
110
|
export interface Team {
|
|
94
111
|
id: string;
|
|
95
112
|
name: string;
|
|
96
113
|
slug: string;
|
|
97
114
|
creationTime: string;
|
|
115
|
+
markedDeleted?: boolean;
|
|
98
116
|
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
99
117
|
deleted?: boolean;
|
|
100
118
|
}
|
package/src/util/analytics.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import Analytics = require("analytics-node");
|
|
8
|
-
import { IAnalyticsWriter, IdentifyMessage, TrackMessage } from "../analytics";
|
|
8
|
+
import { IAnalyticsWriter, IdentifyMessage, TrackMessage, PageMessage } from "../analytics";
|
|
9
9
|
import { log } from './logging';
|
|
10
10
|
|
|
11
11
|
|
|
@@ -52,6 +52,18 @@ class SegmentAnalyticsWriter implements IAnalyticsWriter {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
page(msg: PageMessage) {
|
|
56
|
+
try{
|
|
57
|
+
this.analytics.page(msg, (err: Error) => {
|
|
58
|
+
if (err) {
|
|
59
|
+
log.warn("analytics.page failed", err);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
} catch (err) {
|
|
63
|
+
log.warn("analytics.page failed", err);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
class LogAnalyticsWriter implements IAnalyticsWriter {
|
|
@@ -62,10 +74,14 @@ class LogAnalyticsWriter implements IAnalyticsWriter {
|
|
|
62
74
|
track(msg: TrackMessage): void {
|
|
63
75
|
log.debug("analytics track", msg);
|
|
64
76
|
}
|
|
77
|
+
page(msg: PageMessage): void {
|
|
78
|
+
log.debug("analytics page", msg);
|
|
79
|
+
}
|
|
65
80
|
|
|
66
81
|
}
|
|
67
82
|
|
|
68
83
|
class NoAnalyticsWriter implements IAnalyticsWriter {
|
|
69
84
|
identify(msg: IdentifyMessage): void {}
|
|
70
85
|
track(msg: TrackMessage): void {}
|
|
86
|
+
page(msg: PageMessage): void {}
|
|
71
87
|
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { repeat } from "./repeat";
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
interface CacheEntry<T> {
|
|
9
11
|
key: string;
|
|
@@ -41,8 +43,12 @@ export class GarbageCollectedCache<T> {
|
|
|
41
43
|
return entry.value;
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
public delete(key: string) {
|
|
47
|
+
this.store.delete(key);
|
|
48
|
+
}
|
|
49
|
+
|
|
44
50
|
protected regularlyCollectGarbage() {
|
|
45
|
-
|
|
51
|
+
repeat(() => this.collectGarbage(), this.gcIntervalSeconds * 1000);
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
protected collectGarbage() {
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
import * as cookie from 'cookie';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* This cookie indicates whether the connected client is a Gitpod user (= "has logged in within the last year") or not.
|
|
11
|
+
* This is used by "gitpod.io" and "www.gitpod.io" to display different content/buttons.
|
|
12
|
+
*/
|
|
13
|
+
export const NAME = "gitpod-user";
|
|
14
|
+
export const VALUE = "true";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param domain The domain the Gitpod installation is installed onto
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export function options(domain: string): cookie.CookieSerializeOptions {
|
|
21
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
|
|
22
|
+
return {
|
|
23
|
+
path: "/", // make sure we send the cookie to all sub-pages
|
|
24
|
+
httpOnly: false,
|
|
25
|
+
secure: false,
|
|
26
|
+
maxAge: 60 * 60 * 24 * 365, // 1 year
|
|
27
|
+
sameSite: "lax", // default: true. "Lax" needed to ensure we see cookies from users that neavigate to gitpod.io from external sites
|
|
28
|
+
domain: `.${domain}`, // explicilty include subdomains to not only cover "gitpod.io", but also "www.gitpod.io" or workspaces
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function generateCookie(domain: string): string {
|
|
33
|
+
return cookie.serialize(NAME, VALUE, options(domain));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export function isPresent(cookies: string): boolean {
|
|
37
|
+
// needs to match the old (gitpod-user=loggedIn) and new (gitpod-user=true) values to ensure a smooth transition during rollout.
|
|
38
|
+
return !!cookies.match(`${NAME}=`);
|
|
39
|
+
};
|
|
@@ -85,23 +85,27 @@ export class GitpodHostUrl {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
asDashboard(): GitpodHostUrl {
|
|
88
|
-
return this.with(url => ({ pathname: '/
|
|
88
|
+
return this.with(url => ({ pathname: '/' }));
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
asLogin(): GitpodHostUrl {
|
|
92
|
-
return this.with(url => ({ pathname: '/login
|
|
92
|
+
return this.with(url => ({ pathname: '/login' }));
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
asUpgradeSubscription(): GitpodHostUrl {
|
|
96
|
-
return this.with(url => ({ pathname: '/plans
|
|
96
|
+
return this.with(url => ({ pathname: '/plans' }));
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
asAccessControl(): GitpodHostUrl {
|
|
100
|
-
return this.with(url => ({ pathname: '/
|
|
100
|
+
return this.with(url => ({ pathname: '/integrations' }));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
asSettings(): GitpodHostUrl {
|
|
104
|
-
return this.with(url => ({ pathname: '/settings
|
|
104
|
+
return this.with(url => ({ pathname: '/settings' }));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
asPreferences(): GitpodHostUrl {
|
|
108
|
+
return this.with(url => ({ pathname: '/preferences' }));
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
asGraphQLApi(): GitpodHostUrl {
|
package/src/util/grpc.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export const defaultGRPCOptions = {
|
|
8
|
-
"grpc.keepalive_timeout_ms":
|
|
9
|
-
"grpc.keepalive_time_ms":
|
|
10
|
-
"grpc.http2.min_time_between_pings_ms":
|
|
8
|
+
"grpc.keepalive_timeout_ms": 10000,
|
|
9
|
+
"grpc.keepalive_time_ms": 60000,
|
|
10
|
+
"grpc.http2.min_time_between_pings_ms": 10000,
|
|
11
11
|
"grpc.keepalive_permit_without_calls": 1,
|
|
12
12
|
"grpc-node.max_session_memory": 50,
|
|
13
13
|
"grpc.max_reconnect_backoff_ms": 5000,
|