@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.
Files changed (80) hide show
  1. package/lib/admin-protocol.d.ts +12 -0
  2. package/lib/admin-protocol.d.ts.map +1 -1
  3. package/lib/admin-protocol.js.map +1 -1
  4. package/lib/analytics.d.ts +4 -5
  5. package/lib/analytics.d.ts.map +1 -1
  6. package/lib/context-url.d.ts +18 -5
  7. package/lib/context-url.d.ts.map +1 -1
  8. package/lib/context-url.js +58 -5
  9. package/lib/context-url.js.map +1 -1
  10. package/lib/context-url.spec.d.ts +2 -0
  11. package/lib/context-url.spec.d.ts.map +1 -1
  12. package/lib/context-url.spec.js +25 -4
  13. package/lib/context-url.spec.js.map +1 -1
  14. package/lib/gitpod-service.d.ts +19 -0
  15. package/lib/gitpod-service.d.ts.map +1 -1
  16. package/lib/gitpod-service.js.map +1 -1
  17. package/lib/ide-protocol.d.ts +24 -0
  18. package/lib/ide-protocol.d.ts.map +1 -1
  19. package/lib/index.d.ts +1 -0
  20. package/lib/index.d.ts.map +1 -1
  21. package/lib/index.js +1 -0
  22. package/lib/index.js.map +1 -1
  23. package/lib/installation-admin-protocol.d.ts +27 -0
  24. package/lib/installation-admin-protocol.d.ts.map +1 -0
  25. package/lib/installation-admin-protocol.js +30 -0
  26. package/lib/installation-admin-protocol.js.map +1 -0
  27. package/lib/messaging/error.d.ts +1 -0
  28. package/lib/messaging/error.d.ts.map +1 -1
  29. package/lib/messaging/error.js +2 -0
  30. package/lib/messaging/error.js.map +1 -1
  31. package/lib/permission.d.ts +7 -1
  32. package/lib/permission.d.ts.map +1 -1
  33. package/lib/permission.js +24 -4
  34. package/lib/permission.js.map +1 -1
  35. package/lib/protocol.d.ts +11 -2
  36. package/lib/protocol.d.ts.map +1 -1
  37. package/lib/protocol.js +12 -4
  38. package/lib/protocol.js.map +1 -1
  39. package/lib/teams-projects-protocol.d.ts +3 -0
  40. package/lib/teams-projects-protocol.d.ts.map +1 -1
  41. package/lib/teams-projects-protocol.js +7 -0
  42. package/lib/teams-projects-protocol.js.map +1 -1
  43. package/lib/util/tracing.d.ts +2 -2
  44. package/lib/util/tracing.d.ts.map +1 -1
  45. package/lib/util/tracing.js +13 -12
  46. package/lib/util/tracing.js.map +1 -1
  47. package/lib/workspace-cluster.d.ts +9 -7
  48. package/lib/workspace-cluster.d.ts.map +1 -1
  49. package/lib/workspace-cluster.js +18 -1
  50. package/lib/workspace-cluster.js.map +1 -1
  51. package/lib/workspace-instance.d.ts +19 -0
  52. package/lib/workspace-instance.d.ts.map +1 -1
  53. package/package.json +2 -2
  54. package/pkg-yarn.lock +2 -2
  55. package/provenance-bundle.jsonl +1 -1
  56. package/src/admin-protocol.ts +19 -4
  57. package/src/analytics.ts +4 -6
  58. package/src/context-url.spec.ts +18 -4
  59. package/src/context-url.ts +62 -6
  60. package/src/gitpod-service.ts +23 -0
  61. package/src/ide-protocol.ts +27 -0
  62. package/src/index.ts +1 -0
  63. package/src/installation-admin-protocol.ts +42 -0
  64. package/src/messaging/error.ts +3 -0
  65. package/src/permission.ts +22 -3
  66. package/src/protocol.ts +19 -5
  67. package/src/teams-projects-protocol.ts +7 -1
  68. package/src/util/tracing.ts +14 -13
  69. package/src/workspace-cluster.ts +17 -9
  70. package/src/workspace-instance.ts +20 -0
  71. package/lib/messaging/connection-error-handler.d.ts +0 -27
  72. package/lib/messaging/connection-error-handler.d.ts.map +0 -1
  73. package/lib/messaging/connection-error-handler.js +0 -34
  74. package/lib/messaging/connection-error-handler.js.map +0 -1
  75. package/lib/util/safe-promise.d.ts +0 -11
  76. package/lib/util/safe-promise.d.ts.map +0 -1
  77. package/lib/util/safe-promise.js +0 -31
  78. package/lib/util/safe-promise.js.map +0 -1
  79. package/src/messaging/connection-error-handler.ts +0 -62
  80. package/src/util/safe-promise.ts +0 -26
@@ -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
- export function parseToURL(contextUrl: string | undefined): URL | undefined {
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 new URL(segments[0]); // this might be something, we just try
77
+ return segments[0]; // this might be something, we just try
26
78
  }
27
79
 
28
- const segmentsToURL = (offset: number): URL => {
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 new URL(rest);
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
 
@@ -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;
@@ -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
@@ -19,3 +19,4 @@ export * from './context-url';
19
19
  export * from './teams-projects-protocol';
20
20
  export * from './snapshot-url';
21
21
  export * from './oss-allowlist';
22
+ export * from './installation-admin-protocol';
@@ -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
+ }
@@ -78,4 +78,7 @@ export namespace ErrorCodes {
78
78
 
79
79
  // 630 Snapshot Error
80
80
  export const SNAPSHOT_ERROR = 630;
81
+
82
+ // 640 Headless logs are not available (yet)
83
+ export const HEADLESS_LOG_NOT_YET_AVAILABLE = 640;
81
84
  }
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(Permission)
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.pop() || "";
262
- const ownerPattern = patterns.join('/');
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
- && 'snapshotBucketId' in context
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 {
@@ -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 { followsFrom, initGlobalTracer } from 'opentracing';
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, ...referencedSpans: (opentracing.Span | undefined)[]): opentracing.Span {
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
- 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
- }
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, ...referencedSpans: (opentracing.Span | undefined)[]): void {
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, ...referencedSpans);
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;
@@ -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 | AdmissionConstraintHasRole | AdmissionConstraintHasUserLevel;
55
+ export type AdmissionConstraint = AdmissionConstraintFeaturePreview | AdmissionConstraintHasPermission | AdmissionConstraintHasUserLevel | AdmissionConstraintHasMoreResources;
59
56
  export type AdmissionConstraintFeaturePreview = { type: "has-feature-preview" };
60
- export type AdmissionConstraintHasRole = { type: "has-permission", permission: PermissionName };
57
+ export type AdmissionConstraintHasPermission = { type: "has-permission", permission: PermissionName };
61
58
  export type AdmissionConstraintHasUserLevel = { type: "has-user-level", level: string };
62
-
63
- export type AdmissionPreference = AdmissionPreferenceUserLevel;
64
- export type AdmissionPreferenceUserLevel = { type: 'user-level', level: string };
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"}
@@ -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"}