@gitpod/gitpod-protocol 0.1.5-sefftinge-create-feature-flag-for-4354.0 → 0.1.5-server-vscode-oauth2.11
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 +6 -11
- package/lib/accounting-protocol.js.map +1 -1
- package/lib/admin-protocol.d.ts +9 -4
- 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 +44 -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/context-url.spec.js +73 -0
- 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 +3 -3
- 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 +1 -2
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +20 -21
- 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 +74 -5
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +149 -294
- 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/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 +34 -54
- 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 -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/handler.d.ts +10 -0
- package/lib/messaging/handler.d.ts.map +1 -1
- package/lib/messaging/node/connection.js +21 -21
- 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/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.js +38 -57
- package/lib/plans.js.map +1 -1
- package/lib/protocol.d.ts +52 -22
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +68 -115
- 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 +13 -10
- package/lib/team-subscription-protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +102 -0
- package/lib/teams-projects-protocol.d.ts.map +1 -0
- package/lib/teams-projects-protocol.js +23 -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 +36 -28
- 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.js +22 -46
- package/lib/util/garbage-collected-cache.js.map +1 -1
- package/lib/util/generate-workspace-id.d.ts.map +1 -1
- package/lib/util/generate-workspace-id.js +12 -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.js +93 -103
- 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 +92 -70
- 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 +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/repeater.js +35 -88
- package/lib/util/repeater.js.map +1 -1
- 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.js +43 -47
- package/lib/util/tracing.js.map +1 -1
- 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 +12 -3
- 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 +3 -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 +11 -6
- package/pkg-yarn.lock +7 -4
- package/src/accounting-protocol.ts +3 -7
- package/src/admin-protocol.ts +10 -5
- package/src/analytics.ts +52 -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 -10
- package/src/gitpod-service.ts +90 -12
- package/src/headless-workspace-log.ts +7 -11
- 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 +3 -0
- package/src/messaging/handler.ts +12 -0
- package/src/messaging/node/connection.ts +2 -2
- package/src/messaging/proxy-factory.ts +13 -5
- package/src/permission.ts +0 -1
- package/src/protocol.ts +73 -28
- package/src/team-subscription-protocol.ts +5 -3
- package/src/teams-projects-protocol.ts +131 -0
- package/src/util/analytics.ts +17 -30
- package/src/util/generate-workspace-id.ts +1 -0
- package/src/util/gitpod-cookie.ts +39 -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 +70 -6
- package/src/util/parse-workspace-id.spec.ts +21 -1
- package/src/util/parse-workspace-id.ts +32 -6
- package/src/workspace-cluster.ts +9 -3
- package/src/workspace-instance.ts +19 -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 +0 -52
- 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
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Logger, ConsoleLogger, toSocket, IWebSocket } from "vscode-ws-jsonrpc";
|
|
9
|
+
import { createMessageConnection } from "vscode-jsonrpc";
|
|
10
|
+
import { AbstractMessageWriter } from "vscode-jsonrpc/lib/messageWriter";
|
|
11
|
+
import { AbstractMessageReader } from "vscode-jsonrpc/lib/messageReader";
|
|
9
12
|
import { JsonRpcProxyFactory, JsonRpcProxy } from "../proxy-factory";
|
|
10
|
-
import { ConnectionHandler } from "../handler";
|
|
11
|
-
import ReconnectingWebSocket from 'reconnecting-websocket';
|
|
13
|
+
import { ConnectionEventHandler, ConnectionHandler } from "../handler";
|
|
14
|
+
import ReconnectingWebSocket, { Event } from 'reconnecting-websocket';
|
|
12
15
|
|
|
13
16
|
export interface WebSocketOptions {
|
|
14
17
|
onerror?: (event: Event) => void;
|
|
@@ -29,7 +32,10 @@ export class WebSocketConnectionProvider {
|
|
|
29
32
|
const startListening = (path: string) => {
|
|
30
33
|
const socket = this.listen({
|
|
31
34
|
path,
|
|
32
|
-
onConnection: c => factory.listen(c)
|
|
35
|
+
onConnection: c => factory.listen(c),
|
|
36
|
+
}, {
|
|
37
|
+
onTransportDidClose: () => factory.fireConnectionClosed(),
|
|
38
|
+
onTransportDidOpen: () => factory.fireConnectionOpened(),
|
|
33
39
|
},
|
|
34
40
|
options
|
|
35
41
|
);
|
|
@@ -49,7 +55,7 @@ export class WebSocketConnectionProvider {
|
|
|
49
55
|
/**
|
|
50
56
|
* Install a connection handler for the given path.
|
|
51
57
|
*/
|
|
52
|
-
listen(handler: ConnectionHandler, options?: WebSocketOptions): WebSocket {
|
|
58
|
+
listen(handler: ConnectionHandler, eventHandler: ConnectionEventHandler, options?: WebSocketOptions): WebSocket {
|
|
53
59
|
const url = handler.path;
|
|
54
60
|
const webSocket = this.createWebSocket(url);
|
|
55
61
|
|
|
@@ -64,11 +70,12 @@ export class WebSocketConnectionProvider {
|
|
|
64
70
|
logger.error(JSON.stringify(error));
|
|
65
71
|
});
|
|
66
72
|
}
|
|
67
|
-
doListen(
|
|
68
|
-
webSocket,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
doListen(
|
|
74
|
+
webSocket as any as ReconnectingWebSocket,
|
|
75
|
+
handler,
|
|
76
|
+
eventHandler,
|
|
77
|
+
logger,
|
|
78
|
+
);
|
|
72
79
|
return webSocket;
|
|
73
80
|
}
|
|
74
81
|
|
|
@@ -91,3 +98,162 @@ export class WebSocketConnectionProvider {
|
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
}
|
|
101
|
+
|
|
102
|
+
// The following was extracted from vscode-ws-jsonrpc to make these changes:
|
|
103
|
+
// - switch from WebSocket to ReconnectingWebSocket
|
|
104
|
+
// - webSocket.onopen: making sure it's only ever called once so we're re-using MessageConnection
|
|
105
|
+
// - WebSocketMessageWriter: buffer and re-try messages instead of throwing an error immidiately
|
|
106
|
+
// - WebSocketMessageReader: don't close MessageConnection on 'socket.onclose'
|
|
107
|
+
function doListen(resocket: ReconnectingWebSocket, handler: ConnectionHandler, eventHandler: ConnectionEventHandler, logger: Logger) {
|
|
108
|
+
resocket.addEventListener("close", () => eventHandler.onTransportDidClose());
|
|
109
|
+
|
|
110
|
+
let alreadyOpened = false;
|
|
111
|
+
resocket.onopen = () => {
|
|
112
|
+
// trigerr "open" every time we re-open the underlying websocket
|
|
113
|
+
eventHandler.onTransportDidOpen();
|
|
114
|
+
|
|
115
|
+
// make sure we're only ever creating one MessageConnection, irregardless of how many times we have to re-open the underlying (reconnecting) websocket
|
|
116
|
+
if (alreadyOpened) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
alreadyOpened = true;
|
|
120
|
+
|
|
121
|
+
const connection = createWebSocketConnection(resocket, logger);
|
|
122
|
+
handler.onConnection(connection);
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function createWebSocketConnection(resocket: ReconnectingWebSocket, logger: Logger) {
|
|
127
|
+
const socket = toSocket(resocket as any);
|
|
128
|
+
const messageReader = new NonClosingWebSocketMessageReader(socket);
|
|
129
|
+
const messageWriter = new BufferingWebSocketMessageWriter(resocket, logger);
|
|
130
|
+
const connection = createMessageConnection(messageReader, messageWriter, logger);
|
|
131
|
+
connection.onClose(() => connection.dispose());
|
|
132
|
+
return connection;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* This takes vscode-ws-jsonrpc/lib/socket/writer/WebSocketMessageWriter and adds a buffer
|
|
137
|
+
*/
|
|
138
|
+
class BufferingWebSocketMessageWriter extends AbstractMessageWriter {
|
|
139
|
+
protected readonly socket: ReconnectingWebSocket;
|
|
140
|
+
protected readonly logger: Logger;
|
|
141
|
+
protected errorCount: number = 0;
|
|
142
|
+
|
|
143
|
+
protected buffer: any[] = [];
|
|
144
|
+
|
|
145
|
+
constructor(socket: ReconnectingWebSocket, logger: Logger) {
|
|
146
|
+
super();
|
|
147
|
+
this.socket = socket;
|
|
148
|
+
this.logger = logger;
|
|
149
|
+
|
|
150
|
+
socket.addEventListener("open", (event: Event) => this.flushBuffer());
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
write(msg: any) {
|
|
154
|
+
if (this.socket.readyState !== ReconnectingWebSocket.OPEN) {
|
|
155
|
+
this.bufferMsg(msg);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
const content = JSON.stringify(msg);
|
|
161
|
+
this.socket.send(content);
|
|
162
|
+
} catch (e) {
|
|
163
|
+
this.errorCount++;
|
|
164
|
+
this.fireError(e, msg, this.errorCount);
|
|
165
|
+
|
|
166
|
+
this.bufferMsg(msg);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
protected flushBuffer() {
|
|
171
|
+
if (this.buffer.length === 0) {
|
|
172
|
+
return
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const buffer = [...this.buffer];
|
|
176
|
+
this.buffer = [];
|
|
177
|
+
for (const msg of buffer) {
|
|
178
|
+
this.write(msg);
|
|
179
|
+
}
|
|
180
|
+
//this.logger.info(`flushed buffer (${this.buffer.length})`)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
protected bufferMsg(msg: any) {
|
|
184
|
+
this.buffer.push(msg);
|
|
185
|
+
//this.logger.info(`buffered message (${this.buffer.length})`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* This takes vscode-ws-jsonrpc/lib/socket/reader/WebSocketMessageReader and removes the "onClose -> fireClose" connection
|
|
192
|
+
*/
|
|
193
|
+
class NonClosingWebSocketMessageReader extends AbstractMessageReader {
|
|
194
|
+
protected readonly socket: IWebSocket;
|
|
195
|
+
protected readonly events: any[] = [];
|
|
196
|
+
protected state: 'initial' | 'listening' | 'closed' = 'initial';
|
|
197
|
+
protected callback: (message: any) => void = () => {};
|
|
198
|
+
|
|
199
|
+
constructor(socket: IWebSocket) {
|
|
200
|
+
super();
|
|
201
|
+
this.socket = socket;
|
|
202
|
+
this.socket.onMessage(message => this.readMessage(message));
|
|
203
|
+
this.socket.onError(error => this.fireError(error));
|
|
204
|
+
this.socket.onClose((code, reason) => {
|
|
205
|
+
if (code !== 1000) {
|
|
206
|
+
const error = {
|
|
207
|
+
name: '' + code,
|
|
208
|
+
message: `Error during socket reconnect: code = ${code}, reason = ${reason}`
|
|
209
|
+
};
|
|
210
|
+
this.fireError(error);
|
|
211
|
+
}
|
|
212
|
+
// this.fireClose(); // <-- reason for this class to be copied over
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
listen(callback: (message: any) => void) {
|
|
216
|
+
if (this.state === 'initial') {
|
|
217
|
+
this.state = 'listening';
|
|
218
|
+
this.callback = callback;
|
|
219
|
+
while (this.events.length !== 0) {
|
|
220
|
+
const event = this.events.pop();
|
|
221
|
+
if (event.message) {
|
|
222
|
+
this.readMessage(event.message);
|
|
223
|
+
}
|
|
224
|
+
else if (event.error) {
|
|
225
|
+
this.fireError(event.error);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
this.fireClose();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
readMessage(message: any) {
|
|
234
|
+
if (this.state === 'initial') {
|
|
235
|
+
this.events.splice(0, 0, { message });
|
|
236
|
+
}
|
|
237
|
+
else if (this.state === 'listening') {
|
|
238
|
+
const data = JSON.parse(message);
|
|
239
|
+
this.callback(data);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
fireError(error: any) {
|
|
243
|
+
if (this.state === 'initial') {
|
|
244
|
+
this.events.splice(0, 0, { error });
|
|
245
|
+
}
|
|
246
|
+
else if (this.state === 'listening') {
|
|
247
|
+
super.fireError(error);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
fireClose() {
|
|
251
|
+
if (this.state === 'initial') {
|
|
252
|
+
this.events.splice(0, 0, {});
|
|
253
|
+
}
|
|
254
|
+
else if (this.state === 'listening') {
|
|
255
|
+
super.fireClose();
|
|
256
|
+
}
|
|
257
|
+
this.state = 'closed';
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -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
|
@@ -34,6 +34,9 @@ export namespace ErrorCodes {
|
|
|
34
34
|
// 460 Context Parse Error (custom status code)
|
|
35
35
|
export const CONTEXT_PARSE_ERROR = 460;
|
|
36
36
|
|
|
37
|
+
// 461 Invalid gitpod yml
|
|
38
|
+
export const INVALID_GITPOD_YML = 461;
|
|
39
|
+
|
|
37
40
|
// 450 Payment error
|
|
38
41
|
export const PAYMENT_ERROR = 450;
|
|
39
42
|
|
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
|
+
}
|
|
@@ -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
|
},
|
|
@@ -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
|
/**
|
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
|
@@ -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,11 +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
|
|
569
|
+
* additional-content - config comes from additional content, usually provided through the project's configuration
|
|
564
570
|
* default - our static catch-all default config
|
|
565
571
|
*/
|
|
566
|
-
_origin?: 'repo' | 'definitely-gp' | 'derived' | 'default';
|
|
572
|
+
_origin?: 'repo' | 'project-db' | 'definitely-gp' | 'derived' | 'additional-content' | 'default';
|
|
567
573
|
|
|
568
574
|
/**
|
|
569
575
|
* Set of automatically infered feature flags. That's not something the user can set, but
|
|
@@ -593,16 +599,13 @@ export namespace GithubAppPrebuildConfig {
|
|
|
593
599
|
|
|
594
600
|
export type WorkspaceImageSource = WorkspaceImageSourceDocker | WorkspaceImageSourceReference;
|
|
595
601
|
export interface WorkspaceImageSourceDocker {
|
|
596
|
-
// TODO: clean this up. We should have the commit and an ImageSource in here, not duplicate the whole thing again.
|
|
597
|
-
// We have a ton of those objects in the database, thus cleaning this up means lengthy DB migrations. Yuck.
|
|
598
|
-
dockerFileHash: string
|
|
599
|
-
dockerFileSource: Commit
|
|
600
602
|
dockerFilePath: string
|
|
603
|
+
dockerFileHash: string
|
|
604
|
+
dockerFileSource?: Commit
|
|
601
605
|
}
|
|
602
606
|
export namespace WorkspaceImageSourceDocker {
|
|
603
607
|
export function is(obj: object): obj is WorkspaceImageSourceDocker {
|
|
604
608
|
return 'dockerFileHash' in obj
|
|
605
|
-
&& 'dockerFileSource' in obj
|
|
606
609
|
&& 'dockerFilePath' in obj;
|
|
607
610
|
}
|
|
608
611
|
}
|
|
@@ -631,6 +634,8 @@ export type PrebuiltWorkspaceState
|
|
|
631
634
|
export interface PrebuiltWorkspace {
|
|
632
635
|
id: string;
|
|
633
636
|
cloneURL: string;
|
|
637
|
+
branch?: string;
|
|
638
|
+
projectId?: string;
|
|
634
639
|
commit: string;
|
|
635
640
|
buildWorkspaceId: string;
|
|
636
641
|
creationTime: string;
|
|
@@ -700,7 +705,7 @@ export interface TaskConfig {
|
|
|
700
705
|
init?: string;
|
|
701
706
|
prebuild?: string;
|
|
702
707
|
command?: string;
|
|
703
|
-
env?: { [env: string]:
|
|
708
|
+
env?: { [env: string]: any };
|
|
704
709
|
openIn?: 'bottom' | 'main' | 'left' | 'right';
|
|
705
710
|
openMode?: 'split-top' | 'split-left' | 'split-right' | 'split-bottom' | 'tab-before' | 'tab-after';
|
|
706
711
|
}
|
|
@@ -800,6 +805,29 @@ export namespace WithPrebuild {
|
|
|
800
805
|
}
|
|
801
806
|
}
|
|
802
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
|
+
|
|
803
831
|
export interface SnapshotContext extends WorkspaceContext, WithSnapshot {
|
|
804
832
|
snapshotId: string;
|
|
805
833
|
}
|
|
@@ -815,6 +843,8 @@ export namespace SnapshotContext {
|
|
|
815
843
|
export interface StartPrebuildContext extends WorkspaceContext {
|
|
816
844
|
actual: WorkspaceContext;
|
|
817
845
|
commitHistory?: string[];
|
|
846
|
+
project?: Project;
|
|
847
|
+
branch?: string;
|
|
818
848
|
}
|
|
819
849
|
|
|
820
850
|
export namespace StartPrebuildContext {
|
|
@@ -884,6 +914,25 @@ export interface Commit {
|
|
|
884
914
|
refType?: RefType
|
|
885
915
|
}
|
|
886
916
|
|
|
917
|
+
export interface AdditionalContentContext extends WorkspaceContext {
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* utf-8 encoded contents that will be copied on top of the workspace's filesystem
|
|
921
|
+
*/
|
|
922
|
+
additionalFiles: {[filePath: string]: string};
|
|
923
|
+
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
export namespace AdditionalContentContext {
|
|
927
|
+
export function is(ctx: any): ctx is AdditionalContentContext {
|
|
928
|
+
return 'additionalFiles' in ctx;
|
|
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
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
887
936
|
export interface CommitContext extends WorkspaceContext, Commit {
|
|
888
937
|
/** @deprecated Moved to .repository.cloneUrl, left here for backwards-compatibility for old workspace contextes in the DB */
|
|
889
938
|
cloneUrl?: string
|
|
@@ -959,6 +1008,19 @@ export interface Repository {
|
|
|
959
1008
|
parent: Repository
|
|
960
1009
|
}
|
|
961
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
|
+
}
|
|
962
1024
|
|
|
963
1025
|
export namespace Repository {
|
|
964
1026
|
export function fullRepoName(repo: Repository): string {
|
|
@@ -1001,6 +1063,7 @@ export interface WorkspaceCreationResult {
|
|
|
1001
1063
|
runningWorkspacePrebuild?: {
|
|
1002
1064
|
prebuildID: string
|
|
1003
1065
|
workspaceID: string
|
|
1066
|
+
instanceID: string
|
|
1004
1067
|
starting: RunningWorkspacePrebuildStarting
|
|
1005
1068
|
sameCluster: boolean
|
|
1006
1069
|
}
|
|
@@ -1177,21 +1240,3 @@ export interface Terms {
|
|
|
1177
1240
|
readonly content: string;
|
|
1178
1241
|
readonly formElements?: object;
|
|
1179
1242
|
}
|
|
1180
|
-
|
|
1181
|
-
export interface Project {
|
|
1182
|
-
id: string;
|
|
1183
|
-
cloneUrl: string;
|
|
1184
|
-
teamId: string;
|
|
1185
|
-
appInstallationId: string;
|
|
1186
|
-
creationTime: string;
|
|
1187
|
-
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
1188
|
-
deleted?: boolean;
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
export interface Team {
|
|
1192
|
-
id: string;
|
|
1193
|
-
name: string;
|
|
1194
|
-
creationTime: string;
|
|
1195
|
-
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
1196
|
-
deleted?: boolean;
|
|
1197
|
-
}
|
|
@@ -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
|
/**
|