@gitpod/gitpod-protocol 0.1.5-sje-installer-namespace-docs.0 → 0.1.5-sje-installer-migration-cmd.0
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 +17 -2
- package/lib/gitpod-service.d.ts +4 -3
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +4 -2
- package/lib/gitpod-service.js.map +1 -1
- package/lib/messaging/node/connection.d.ts +1 -7
- package/lib/messaging/node/connection.d.ts.map +1 -1
- package/lib/messaging/node/connection.js +20 -18
- package/lib/messaging/node/connection.js.map +1 -1
- package/lib/protocol.d.ts +4 -33
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js.map +1 -1
- package/lib/util/generate-workspace-id.d.ts +1 -1
- package/lib/util/generate-workspace-id.d.ts.map +1 -1
- package/lib/util/generate-workspace-id.js +19 -2
- package/lib/util/generate-workspace-id.js.map +1 -1
- package/lib/util/generate-workspace-id.spec.js +24 -0
- package/lib/util/generate-workspace-id.spec.js.map +1 -1
- package/lib/util/gitpod-host-url.d.ts +0 -1
- package/lib/util/gitpod-host-url.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.js +3 -6
- package/lib/util/gitpod-host-url.js.map +1 -1
- package/lib/util/parse-workspace-id.js +1 -1
- package/lib/util/parse-workspace-id.js.map +1 -1
- package/lib/util/tracing.d.ts +3 -2
- package/lib/util/tracing.d.ts.map +1 -1
- package/lib/util/tracing.js +36 -8
- package/lib/util/tracing.js.map +1 -1
- package/package.json +3 -2
- package/pkg-yarn.lock +1 -1
- package/provenance-bundle.jsonl +2 -0
- package/src/gitpod-service.ts +7 -6
- package/src/messaging/node/connection.ts +20 -23
- package/src/protocol.ts +6 -34
- package/src/util/generate-workspace-id.spec.ts +17 -0
- package/src/util/generate-workspace-id.ts +20 -2
- package/src/util/gitpod-host-url.ts +3 -7
- package/src/util/parse-workspace-id.ts +1 -1
- package/src/util/tracing.ts +38 -9
package/src/protocol.ts
CHANGED
|
@@ -104,6 +104,9 @@ export interface AdditionalUserData {
|
|
|
104
104
|
oauthClientsApproved?: { [key: string]: string }
|
|
105
105
|
// to remember GH Orgs the user installed/updated the GH App for
|
|
106
106
|
knownGitHubOrgs?: string[];
|
|
107
|
+
|
|
108
|
+
// Git clone URL pointing to the user's dotfile repo
|
|
109
|
+
dotfileRepo?: string;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
export interface EmailNotificationSettings {
|
|
@@ -588,7 +591,7 @@ export interface GithubAppPrebuildConfig {
|
|
|
588
591
|
branches?: boolean
|
|
589
592
|
pullRequests?: boolean
|
|
590
593
|
pullRequestsFromForks?: boolean
|
|
591
|
-
addCheck?: boolean
|
|
594
|
+
addCheck?: boolean | 'prevent-merge-on-error'
|
|
592
595
|
addBadge?: boolean
|
|
593
596
|
addLabel?: boolean | string
|
|
594
597
|
addComment?: boolean
|
|
@@ -684,6 +687,8 @@ export interface PortConfig {
|
|
|
684
687
|
port: number;
|
|
685
688
|
onOpen?: PortOnOpen;
|
|
686
689
|
visibility?: PortVisibility;
|
|
690
|
+
description?: string;
|
|
691
|
+
name?: string;
|
|
687
692
|
}
|
|
688
693
|
export namespace PortConfig {
|
|
689
694
|
export function is(config: any): config is PortConfig {
|
|
@@ -1170,39 +1175,6 @@ export namespace AuthProviderEntry {
|
|
|
1170
1175
|
}
|
|
1171
1176
|
}
|
|
1172
1177
|
|
|
1173
|
-
export interface Branding {
|
|
1174
|
-
readonly name: string;
|
|
1175
|
-
readonly favicon?: string;
|
|
1176
|
-
/** Either including domain OR absolute path (interpreted relative to host URL) */
|
|
1177
|
-
readonly logo: string;
|
|
1178
|
-
readonly startupLogo: string;
|
|
1179
|
-
readonly showProductivityTips: boolean;
|
|
1180
|
-
readonly redirectUrlIfNotAuthenticated?: string;
|
|
1181
|
-
readonly redirectUrlAfterLogout?: string;
|
|
1182
|
-
readonly homepage: string;
|
|
1183
|
-
readonly ide?: {
|
|
1184
|
-
readonly logo: string;
|
|
1185
|
-
readonly showReleaseNotes: boolean;
|
|
1186
|
-
readonly helpMenu: Branding.Link[];
|
|
1187
|
-
}
|
|
1188
|
-
readonly links: {
|
|
1189
|
-
readonly header: Branding.Link[];
|
|
1190
|
-
readonly footer: Branding.Link[];
|
|
1191
|
-
readonly social: Branding.SocialLink[];
|
|
1192
|
-
readonly legal: Branding.Link[];
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
export namespace Branding {
|
|
1196
|
-
export interface Link {
|
|
1197
|
-
readonly name: string;
|
|
1198
|
-
readonly url: string;
|
|
1199
|
-
}
|
|
1200
|
-
export interface SocialLink {
|
|
1201
|
-
readonly type: string;
|
|
1202
|
-
readonly url: string;
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
1178
|
export interface Configuration {
|
|
1207
1179
|
readonly daysBeforeGarbageCollection: number;
|
|
1208
1180
|
readonly garbageCollectionStartDate: number;
|
|
@@ -27,5 +27,22 @@ const expect = chai.expect
|
|
|
27
27
|
expect(longestName.length <= 36, `"${longestName}" is longer than 36 chars (${longestName.length})`).to.be.true;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
@test public async testCustomName() {
|
|
31
|
+
const data = [
|
|
32
|
+
['foo','bar','foo-bar-'],
|
|
33
|
+
['f','bar','.{2,16}-bar-'],
|
|
34
|
+
['gitpod-io','gitpod','gitpodio-gitpod-'],
|
|
35
|
+
['this is rather long and has some "§$"% special chars','also here pretty long and needs abbreviation','thisisratherlon-alsohere-'],
|
|
36
|
+
['breatheco-de', 'python-flask-api-tutorial', 'breathecode-pythonflaska-'],
|
|
37
|
+
['UPPER', "CaSe", "upper-case-"]
|
|
38
|
+
]
|
|
39
|
+
for (const d of data) {
|
|
40
|
+
const id = await generateWorkspaceID(d[0], d[1]);
|
|
41
|
+
expect(id).match(new RegExp("^"+d[2]));
|
|
42
|
+
expect(new GitpodHostUrl().withWorkspacePrefix(id, "eu").workspaceId).to.equal(id);
|
|
43
|
+
expect(id.length <= 36, `"${id}" is longer than 36 chars (${id.length})`).to.be.true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
}
|
|
31
48
|
module.exports = new TestGenerateWorkspaceId()
|
|
@@ -5,8 +5,26 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import randomNumber = require("random-number-csprng");
|
|
7
7
|
|
|
8
|
-
export async function generateWorkspaceID(): Promise<string> {
|
|
9
|
-
|
|
8
|
+
export async function generateWorkspaceID(firstSegment?: string, secondSegment?: string): Promise<string> {
|
|
9
|
+
const firstSeg = clean(firstSegment) || await random(colors);
|
|
10
|
+
const secSeg = clean(secondSegment, Math.min(15, 23 - firstSeg.length)) || await random(animals);
|
|
11
|
+
return firstSeg+'-'+secSeg+'-'+(await random(characters, 11));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function clean(segment: string | undefined, maxChars: number = 15) {
|
|
15
|
+
if (!segment) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
segment = segment.toLowerCase();
|
|
19
|
+
let result = '';
|
|
20
|
+
for (let i =0; i < segment.length; i++) {
|
|
21
|
+
if (characters.indexOf(segment[i]) !== -1) {
|
|
22
|
+
result += segment[i];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (result.length >= 2) {
|
|
26
|
+
return result.substring(0, maxChars);
|
|
27
|
+
}
|
|
10
28
|
}
|
|
11
29
|
|
|
12
30
|
async function random(array: string[], length: number = 1): Promise<string> {
|
|
@@ -12,13 +12,13 @@ export interface UrlChange {
|
|
|
12
12
|
}
|
|
13
13
|
export type UrlUpdate = UrlChange | Partial<URL>;
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const baseWorkspaceIDRegex = "(([a-f][0-9a-f]{7}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})|([0-9a-z]{2,16}-[0-9a-z]{2,16}-[0-9a-z]{8,11}))";
|
|
16
16
|
|
|
17
17
|
// this pattern matches v4 UUIDs as well as the new generated workspace ids (e.g. pink-panda-ns35kd21)
|
|
18
|
-
const workspaceIDRegex = RegExp(`^${
|
|
18
|
+
const workspaceIDRegex = RegExp(`^${baseWorkspaceIDRegex}$`);
|
|
19
19
|
|
|
20
20
|
// this pattern matches URL prefixes of workspaces
|
|
21
|
-
const workspaceUrlPrefixRegex = RegExp(`^([0-9]{4,6}-)?${
|
|
21
|
+
const workspaceUrlPrefixRegex = RegExp(`^([0-9]{4,6}-)?${baseWorkspaceIDRegex}\\.`);
|
|
22
22
|
|
|
23
23
|
export class GitpodHostUrl {
|
|
24
24
|
readonly url: URL;
|
|
@@ -108,10 +108,6 @@ export class GitpodHostUrl {
|
|
|
108
108
|
return this.with(url => ({ pathname: '/preferences' }));
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
asGraphQLApi(): GitpodHostUrl {
|
|
112
|
-
return this.with(url => ({ pathname: '/graphql/' }));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
111
|
asStart(workspaceId = this.workspaceId): GitpodHostUrl {
|
|
116
112
|
return this.withoutWorkspacePrefix().with({
|
|
117
113
|
pathname: '/start/',
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const REGEX_WORKSPACE_ID = /[0-9a-z]{2,16}-[0-9a-z]{2,16}-[0-9a-z]{8}/;
|
|
7
|
+
const REGEX_WORKSPACE_ID = /[0-9a-z]{2,16}-[0-9a-z]{2,16}-[0-9a-z]{8,11}/;
|
|
8
8
|
const REGEX_WORKSPACE_ID_EXACT = new RegExp(`^${REGEX_WORKSPACE_ID.source}$`);
|
|
9
9
|
// We need to parse the workspace id precisely here to get the case '<some-str>-<port>-<wsid>.ws.' right
|
|
10
10
|
const REGEX_WORKSPACE_ID_FROM_HOSTNAME = new RegExp(`(${REGEX_WORKSPACE_ID.source})\.ws`);
|
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 { initGlobalTracer } from 'opentracing';
|
|
11
|
+
import { followsFrom, initGlobalTracer } from 'opentracing';
|
|
12
12
|
import { injectable } from 'inversify';
|
|
13
13
|
import { ResponseError } from 'vscode-jsonrpc';
|
|
14
14
|
import { log, LogContext } from './logging';
|
|
@@ -22,13 +22,19 @@ export type TraceContextWithSpan = TraceContext & {
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
export namespace TraceContext {
|
|
25
|
-
export function startSpan(operation: string, parentCtx?: TraceContext): opentracing.Span {
|
|
26
|
-
|
|
27
|
-
if (parentCtx) {
|
|
28
|
-
options =
|
|
29
|
-
childOf: parentCtx.span
|
|
30
|
-
};
|
|
25
|
+
export function startSpan(operation: string, parentCtx?: TraceContext, ...referencedSpans: (opentracing.Span | undefined)[]): opentracing.Span {
|
|
26
|
+
const options: opentracing.SpanOptions = {};
|
|
27
|
+
if (parentCtx && parentCtx.span && !!parentCtx.span.context().toSpanId()) {
|
|
28
|
+
options.childOf = parentCtx.span;
|
|
31
29
|
}
|
|
30
|
+
if (referencedSpans) {
|
|
31
|
+
// note: allthough followsForm's type says it takes 'opentracing.Span | opentracing.SpanContext', it only works with SpanContext (typing mismatch)
|
|
32
|
+
// note2: we need to filter out debug spans (spanId === "")
|
|
33
|
+
options.references = referencedSpans.filter(s => s !== undefined)
|
|
34
|
+
.filter(s => !!s!.context().toSpanId())
|
|
35
|
+
.map(s => followsFrom(s!.context()));
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
return opentracing.globalTracer().startSpan(operation, options);
|
|
33
39
|
}
|
|
34
40
|
|
|
@@ -37,6 +43,24 @@ export namespace TraceContext {
|
|
|
37
43
|
return { span };
|
|
38
44
|
}
|
|
39
45
|
|
|
46
|
+
export function withSpan(operation: string, callback: () => void, ctx?: TraceContext, ...referencedSpans: (opentracing.Span | undefined)[]): void {
|
|
47
|
+
// if we don't have a parent span, don't create a trace here as those <trace-without-root-spans> are not useful.
|
|
48
|
+
if (!ctx || !ctx.span || !ctx.span.context()) {
|
|
49
|
+
callback();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const span = TraceContext.startSpan(operation, ctx, ...referencedSpans);
|
|
54
|
+
try {
|
|
55
|
+
callback();
|
|
56
|
+
} catch (e) {
|
|
57
|
+
TraceContext.setError({span}, e);
|
|
58
|
+
throw e;
|
|
59
|
+
} finally {
|
|
60
|
+
span.finish();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
40
64
|
export function setError(ctx: TraceContext, err: Error) {
|
|
41
65
|
if (!ctx.span) {
|
|
42
66
|
return;
|
|
@@ -68,13 +92,13 @@ export namespace TraceContext {
|
|
|
68
92
|
addNestedTags(ctx, tags);
|
|
69
93
|
}
|
|
70
94
|
|
|
71
|
-
export function setJsonRPCError(ctx: TraceContext, method: string, err: ResponseError<any
|
|
95
|
+
export function setJsonRPCError(ctx: TraceContext, method: string, err: ResponseError<any>, withStatusCode: boolean = false) {
|
|
72
96
|
if (!ctx.span) {
|
|
73
97
|
return;
|
|
74
98
|
}
|
|
75
99
|
// not use setError bc this is (most likely) a working operation
|
|
76
100
|
|
|
77
|
-
setJsonRPCMetadata(ctx);
|
|
101
|
+
setJsonRPCMetadata(ctx, method);
|
|
78
102
|
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/rpc.md#json-rpc
|
|
79
103
|
addNestedTags(ctx, {
|
|
80
104
|
rpc: {
|
|
@@ -84,6 +108,11 @@ export namespace TraceContext {
|
|
|
84
108
|
},
|
|
85
109
|
},
|
|
86
110
|
});
|
|
111
|
+
|
|
112
|
+
// the field "status_code" is used by honeycomb to derive insights like success rate, etc. Defaults to "0".
|
|
113
|
+
if (withStatusCode) {
|
|
114
|
+
ctx.span.setTag("status_code", err.code);
|
|
115
|
+
}
|
|
87
116
|
}
|
|
88
117
|
|
|
89
118
|
export function addJsonRPCParameters(ctx: TraceContext, params: { [key: string]: any }) {
|