diff --git a/chart/templates/server-ide-configmap.yaml b/chart/templates/server-ide-configmap.yaml
index 9583bc787db303..3ec8a51dc431ee 100644
--- a/chart/templates/server-ide-configmap.yaml
+++ b/chart/templates/server-ide-configmap.yaml
@@ -104,6 +104,26 @@ options:
defaultIde: "code"
defaultDesktopIde: "code-desktop"
+
+clients:
+ vscode:
+ defaultDesktopIDE: "code-desktop"
+ desktopIDEs: ["code-desktop"]
+ installationSteps: [
+ "If you don't see an open dialog by the browser, make sure you have VS Code installed on your machine, and then click ${OPEN_LINK_LABEL} below.",
+ ]
+ vscode-insiders:
+ defaultDesktopIDE: "code-desktop-insiders"
+ desktopIDEs: ["code-desktop-insiders"]
+ installationSteps: [
+ "If you don't see an open dialog by the browser, make sure you have VS Code Insiders installed on your machine, and then click ${OPEN_LINK_LABEL} below.",
+ ]
+ jetbrains-gateway:
+ defaultDesktopIDE: "intellij"
+ desktopIDEs: ["intellij", "goland", "pycharm", "phpstorm"]
+ installationSteps: [
+ "If you don't see an open dialog by the browser, make sure you have JetBrains Gateway with Gitpod Plugin installed on your machine, and then click ${OPEN_LINK_LABEL} below.",
+ ]
{{ end }}
{{- if $comp.serverIdeConfigDeploy.enabled }}
diff --git a/components/dashboard/src/start/StartPage.tsx b/components/dashboard/src/start/StartPage.tsx
index 77e67ebe07f304..9f86c156cd6afb 100644
--- a/components/dashboard/src/start/StartPage.tsx
+++ b/components/dashboard/src/start/StartPage.tsx
@@ -34,7 +34,7 @@ function getPhaseTitle(phase?: StartPhase, error?: StartWorkspaceError) {
case StartPhase.Running:
return "Starting";
case StartPhase.IdeReady:
- return "Your Workspace is Ready!";
+ return "Running";
case StartPhase.Stopping:
return "Stopping";
case StartPhase.Stopped:
diff --git a/components/dashboard/src/start/StartWorkspace.tsx b/components/dashboard/src/start/StartWorkspace.tsx
index da9a94a0ba938b..f517d431b5b29d 100644
--- a/components/dashboard/src/start/StartWorkspace.tsx
+++ b/components/dashboard/src/start/StartWorkspace.tsx
@@ -5,6 +5,7 @@
*/
import { ContextURL, DisposableCollection, WithPrebuild, Workspace, WorkspaceImageBuild, WorkspaceInstance } from "@gitpod/gitpod-protocol";
+import { IDEOptions } from "@gitpod/gitpod-protocol/lib/ide-protocol";
import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
import EventEmitter from "events";
import React, { Suspense, useEffect } from "react";
@@ -32,7 +33,9 @@ export interface StartWorkspaceState {
desktopIde?: {
link: string
label: string
+ clientID?: string
}
+ ideOptions?: IDEOptions
}
export default class StartWorkspace extends React.Component {
@@ -54,7 +57,8 @@ export default class StartWorkspace extends React.Component this.setState({ ideOptions }))
}
componentWillUnmount() {
@@ -238,6 +243,7 @@ export default class StartWorkspace extends React.ComponentPreparing workspace …
;
+ const contextURL = this.state.workspace?.context.normalizedContextURL || ContextURL.parseToURL(this.state.workspace?.contextURL)?.toString();
switch (this.state?.workspaceInstance?.status.phase) {
// unknown indicates an issue within the system in that it cannot determine the actual phase of
@@ -281,17 +287,26 @@ export default class StartWorkspace extends React.ComponentOpening IDE …;
+ statusMessage = Opening Workspace …
;
} else {
phase = StartPhase.IdeReady;
+ const openLink = this.state.desktopIde.link;
+ const openLinkLabel = this.state.desktopIde.label;
+ const clientID = this.state.desktopIde.clientID
+ const client = clientID ? this.state.ideOptions?.clients?.[clientID] : undefined;
+ const installationSteps = client?.installationSteps?.length &&
+ {client.installationSteps.map(step =>
)}
+
statusMessage =
+
Opening Workspace …
+ {installationSteps}
More Actions...
-
{this.state.desktopIde.label}
+
{
+ let redirect = false;
+ try {
+ const desktopLink = new URL(openLink);
+ redirect = desktopLink.protocol != 'http:' && desktopLink.protocol != 'https:';
+ } catch {}
+ if (redirect) {
+ window.location.href = openLink;
+ } else {
+ window.open(openLink, '_blank', 'noopener');
+ }
+ }}>{openLinkLabel}
;
@@ -336,7 +362,7 @@ export default class StartWorkspace extends React.Component
@@ -363,7 +389,7 @@ export default class StartWorkspace extends React.Component
diff --git a/components/gitpod-protocol/src/context-url.ts b/components/gitpod-protocol/src/context-url.ts
index dd83762e5d3513..fc5a9aa43545e8 100644
--- a/components/gitpod-protocol/src/context-url.ts
+++ b/components/gitpod-protocol/src/context-url.ts
@@ -8,6 +8,7 @@ export namespace ContextURL {
export const INCREMENTAL_PREBUILD_PREFIX = "incremental-prebuild";
export const PREBUILD_PREFIX = "prebuild";
export const IMAGEBUILD_PREFIX = "imagebuild";
+ export const REFERRER_PREFIX = 'referrer:';
/**
* The field "contextUrl" might contain prefixes like:
@@ -37,7 +38,8 @@ export namespace ContextURL {
const firstSegment = segments[0];
if (firstSegment === PREBUILD_PREFIX ||
firstSegment === INCREMENTAL_PREBUILD_PREFIX ||
- firstSegment === IMAGEBUILD_PREFIX) {
+ firstSegment === IMAGEBUILD_PREFIX ||
+ firstSegment.startsWith(REFERRER_PREFIX)) {
return segmentsToURL(1);
}
diff --git a/components/gitpod-protocol/src/gitpod-service.ts b/components/gitpod-protocol/src/gitpod-service.ts
index f659fe54ce29c5..b1a51a895681f3 100644
--- a/components/gitpod-protocol/src/gitpod-service.ts
+++ b/components/gitpod-protocol/src/gitpod-service.ts
@@ -71,8 +71,14 @@ export interface GitpodServer extends JsonRpcServer, AdminServer,
getWorkspaceOwner(workspaceId: string): Promise;
getWorkspaceUsers(workspaceId: string): Promise;
getFeaturedRepositories(): Promise;
+ /**
+ * **Security:**
+ * Sensitive information like an owner token is erased, since it allows access for all team members.
+ * If you need to access an owner token use `getOwnerToken` instead.
+ */
getWorkspace(id: string): Promise;
isWorkspaceOwner(workspaceId: string): Promise;
+ getOwnerToken(workspaceId: string): Promise;
/**
* Creates and starts a workspace for the given context URL.
diff --git a/components/gitpod-protocol/src/ide-protocol.ts b/components/gitpod-protocol/src/ide-protocol.ts
index 760b10bc90b8ea..6e3c9980932670 100644
--- a/components/gitpod-protocol/src/ide-protocol.ts
+++ b/components/gitpod-protocol/src/ide-protocol.ts
@@ -29,6 +29,28 @@ export interface IDEOptions {
* The default desktop IDE when the user has not specified one.
*/
defaultDesktopIde: string;
+
+ /**
+ * Client specific IDE options.
+ */
+ clients?: { [id: string]: IDEClient };
+}
+
+export interface IDEClient {
+ /**
+ * The default desktop IDE when the user has not specified one.
+ */
+ defaultDesktopIDE?: string;
+
+ /**
+ * Desktop IDEs supported by the client.
+ */
+ desktopIDEs?: string[]
+
+ /**
+ * Steps to install the client on user machine.
+ */
+ installationSteps?: string[]
}
export interface IDEOption {
diff --git a/components/gitpod-protocol/src/protocol.ts b/components/gitpod-protocol/src/protocol.ts
index 514fcbbad91f71..3b0415ebc6155e 100644
--- a/components/gitpod-protocol/src/protocol.ts
+++ b/components/gitpod-protocol/src/protocol.ts
@@ -891,6 +891,18 @@ export namespace PrebuiltWorkspaceContext {
}
}
+export interface WithReferrerContext extends WorkspaceContext {
+ referrer: string
+ referrerIde?: string
+}
+
+export namespace WithReferrerContext {
+ export function is(context: any): context is WithReferrerContext {
+ return context
+ && 'referrer' in context;
+ }
+}
+
export interface WithEnvvarsContext extends WorkspaceContext {
envvars: EnvVarWithValue[];
}
diff --git a/components/ide/code-desktop/status/main.go b/components/ide/code-desktop/status/main.go
index 34ab1dedc11ca6..11f89631daeb0e 100644
--- a/components/ide/code-desktop/status/main.go
+++ b/components/ide/code-desktop/status/main.go
@@ -72,6 +72,7 @@ func main() {
response := make(map[string]string)
response["link"] = link.String()
response["label"] = label
+ response["clientID"] = schema
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
})
diff --git a/components/server/ee/src/workspace/workspace-starter.ts b/components/server/ee/src/workspace/workspace-starter.ts
index 2472e599719703..66360d5125b93d 100644
--- a/components/server/ee/src/workspace/workspace-starter.ts
+++ b/components/server/ee/src/workspace/workspace-starter.ts
@@ -5,6 +5,7 @@
*/
import { Workspace, User, WorkspaceInstance, WorkspaceInstanceConfiguration, NamedWorkspaceFeatureFlag } from "@gitpod/gitpod-protocol";
+import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
import { inject, injectable } from "inversify";
import { IDEConfig } from "../../../src/ide-config";
import { WorkspaceStarter } from "../../../src/workspace/workspace-starter";
@@ -19,8 +20,8 @@ export class WorkspaceStarterEE extends WorkspaceStarter {
*
* @param workspace the workspace to create an instance for
*/
- protected async newInstance(workspace: Workspace, user: User, excludeFeatureFlags: NamedWorkspaceFeatureFlag[], ideConfig: IDEConfig): Promise {
- const instance = await super.newInstance(workspace, user, excludeFeatureFlags, ideConfig);
+ protected async newInstance(ctx: TraceContext, workspace: Workspace, user: User, excludeFeatureFlags: NamedWorkspaceFeatureFlag[], ideConfig: IDEConfig): Promise {
+ const instance = await super.newInstance(ctx, workspace, user, excludeFeatureFlags, ideConfig);
if (await this.eligibilityService.hasFixedWorkspaceResources(user)) {
const config: WorkspaceInstanceConfiguration = instance.configuration!;
const ff = (config.featureFlags || []);
diff --git a/components/server/src/auth/rate-limiter.ts b/components/server/src/auth/rate-limiter.ts
index f946e65136a5bb..3440fc220ab3cd 100644
--- a/components/server/src/auth/rate-limiter.ts
+++ b/components/server/src/auth/rate-limiter.ts
@@ -57,6 +57,7 @@ function getConfig(config: RateLimiterConfig): RateLimiterConfig {
"getFeaturedRepositories": { group: "default", points: 1 },
"getWorkspace": { group: "default", points: 1 },
"isWorkspaceOwner": { group: "default", points: 1 },
+ "getOwnerToken": { group: "default", points: 1 },
"createWorkspace": { group: "default", points: 1 },
"startWorkspace": { group: "default", points: 1 },
"stopWorkspace": { group: "default", points: 1 },
diff --git a/components/server/src/container-module.ts b/components/server/src/container-module.ts
index 5ff576d6ae7b54..66f463449599f5 100644
--- a/components/server/src/container-module.ts
+++ b/components/server/src/container-module.ts
@@ -79,6 +79,7 @@ import { IClientCallMetrics } from '@gitpod/content-service/lib/client-call-metr
import { DebugApp } from './debug-app';
import { LocalMessageBroker, LocalRabbitMQBackedMessageBroker } from './messaging/local-message-broker';
import { contentServiceBinder } from '@gitpod/content-service/lib/sugar';
+import { ReferrerPrefixParser } from './workspace/referrer-prefix-context-parser';
export const productionContainerModule = new ContainerModule((bind, unbind, isBound, rebind) => {
bind(Config).toConstantValue(ConfigFile.fromFile());
@@ -147,6 +148,7 @@ export const productionContainerModule = new ContainerModule((bind, unbind, isBo
bind(ContextParser).toSelf().inSingletonScope();
bind(SnapshotContextParser).toSelf().inSingletonScope();
bind(IContextParser).to(SnapshotContextParser).inSingletonScope();
+ bind(IPrefixContextParser).to(ReferrerPrefixParser).inSingletonScope();
bind(IPrefixContextParser).to(EnvvarPrefixParser).inSingletonScope();
bind(IPrefixContextParser).to(ImageBuildPrefixContextParser).inSingletonScope();
bind(IPrefixContextParser).to(AdditionalContentPrefixContextParser).inSingletonScope();
diff --git a/components/server/src/ide-config.ts b/components/server/src/ide-config.ts
index 47c628d647aec8..aa1911209f1a0d 100644
--- a/components/server/src/ide-config.ts
+++ b/components/server/src/ide-config.ts
@@ -6,7 +6,7 @@
import { Disposable, DisposableCollection, Emitter } from '@gitpod/gitpod-protocol';
import { filePathTelepresenceAware } from '@gitpod/gitpod-protocol/lib/env';
-import { IDEOptions } from '@gitpod/gitpod-protocol/lib/ide-protocol';
+import { IDEClient, IDEOptions } from '@gitpod/gitpod-protocol/lib/ide-protocol';
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';
import { repeat } from '@gitpod/gitpod-protocol/lib/util/repeat';
import * as Ajv from 'ajv';
@@ -19,6 +19,7 @@ import debounce = require('lodash.debounce')
export interface IDEConfig {
supervisorImage: string;
ideOptions: IDEOptions;
+ clients?: { [id: string]: IDEClient };
}
const scheme = {
@@ -56,13 +57,23 @@ const scheme = {
},
"defaultIde": { "type": "string" },
"defaultDesktopIde": { "type": "string" },
+ "clients": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "defaultDesktopIDE": { "type": "string" },
+ "desktopIDEs": { "type": "array", "items": { "type": "string" } },
+ }
+ }
+ }
},
"required": [
"options",
"defaultIde",
"defaultDesktopIde",
],
- },
+ }
},
"required": [
"supervisorImage",
@@ -143,6 +154,21 @@ export class IDEConfigService {
throw new Error(`invalid: Editor (desktop), '${newValue.ideOptions.defaultDesktopIde}' needs to be of type 'desktop' but is '${newValue.ideOptions.options[newValue.ideOptions.defaultIde].type}'.`);
}
+ if (newValue.ideOptions.clients) {
+ for (const [clientId, client] of Object.entries(newValue.ideOptions.clients)) {
+ if (client.defaultDesktopIDE && !(client.defaultDesktopIDE in newValue.ideOptions.options)) {
+ throw new Error(`${clientId} client: there is no option entry for editor '${client.defaultDesktopIDE}'.`);
+ }
+ if (client.desktopIDEs) {
+ for (const ide of client.desktopIDEs) {
+ if (!(ide in newValue.ideOptions.options)) {
+ throw new Error(`${clientId} client: there is no option entry for editor '${ide}'.`);
+ }
+ }
+ }
+ }
+ }
+
value = newValue;
}
diff --git a/components/server/src/oauth-server/db.ts b/components/server/src/oauth-server/db.ts
index 4eed0cc74f97f4..fddc8bd8278966 100644
--- a/components/server/src/oauth-server/db.ts
+++ b/components/server/src/oauth-server/db.ts
@@ -16,15 +16,6 @@ export interface InMemory {
scopes: { [id: string]: OAuthScope };
}
-// Scopes
-const scopes: OAuthScope[] = [
- { name: "function:getGitpodTokenScopes" },
- { name: "function:getWorkspace" },
- { name: "function:getWorkspaces" },
- { name: "function:listenForWorkspaceInstanceUpdates" },
- { name: "resource:default" }
-];
-
// Clients
const localAppClientID = 'gplctl-1.0';
const localClient: OAuthClient = {
@@ -35,16 +26,46 @@ const localClient: OAuthClient = {
// NOTE: these need to be kept in sync with the port range in the local app
redirectUris: Array.from({ length: 10 }, (_, i) => 'http://127.0.0.1:' + (63110 + i)),
allowedGrants: ['authorization_code'],
- scopes,
+ scopes: [
+ { name: "function:getGitpodTokenScopes" },
+ { name: "function:getWorkspace" },
+ { name: "function:getWorkspaces" },
+ { name: "function:listenForWorkspaceInstanceUpdates" },
+ { name: "resource:default" }
+ ],
+}
+
+const jetBrainsGateway: OAuthClient = {
+ id: 'jetbrains-gateway-gitpod-plugin',
+ name: 'JetBrains Gateway Gitpod Plugin',
+ // Set of valid redirect URIs
+ // NOTE: these need to be kept in sync with the port range in
+ // https://github.com/JetBrains/intellij-community/blob/8f07b83138bcb8a98a031e4508080c849a735644/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInServerOptions.java#L34
+ redirectUris: Array.from({ length: 20 }, (_, i) => `http://127.0.0.1:${63342 + i}/api/gitpod/oauth/authorization_code`),
+ allowedGrants: ['authorization_code'],
+ scopes: [
+ { name: "function:getGitpodTokenScopes" },
+ { name: "function:getIDEOptions" },
+ { name: "function:getOwnerToken" },
+ { name: "function:getWorkspace" },
+ { name: "function:getWorkspaces" },
+ { name: "function:listenForWorkspaceInstanceUpdates" },
+ { name: "resource:default" }
+ ],
}
+
export const inMemoryDatabase: InMemory = {
clients: {
[localClient.id]: localClient,
+ [jetBrainsGateway.id]: jetBrainsGateway
},
tokens: {},
scopes: {},
};
-for (const scope of scopes) {
- inMemoryDatabase.scopes[scope.name] = scope;
+for (const clientId in inMemoryDatabase.clients) {
+ const client = inMemoryDatabase.clients[clientId];
+ for (const scope of client.scopes) {
+ inMemoryDatabase.scopes[scope.name] = scope;
+ }
}
diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts
index 3afaf2b1995ef4..5023a29215cbd5 100644
--- a/components/server/src/workspace/gitpod-server-impl.ts
+++ b/components/server/src/workspace/gitpod-server-impl.ts
@@ -443,6 +443,28 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
};
}
+ public async getOwnerToken(ctx: TraceContext, workspaceId: string): Promise {
+ traceAPIParams(ctx, { workspaceId });
+ traceWI(ctx, { workspaceId });
+
+ this.checkUser('getOwnerToken');
+
+ const workspace = await this.workspaceDb.trace(ctx).findById(workspaceId);
+ if (!workspace) {
+ throw new Error('owner token not found');
+ }
+ await this.guardAccess({ kind: "workspace", subject: workspace }, "get");
+
+ const latestInstance = await this.workspaceDb.trace(ctx).findCurrentInstance(workspaceId);
+ this.guardAccess({ kind: "workspaceInstance", subject: latestInstance, workspace}, "get");
+
+ const ownerToken = latestInstance?.status.ownerToken;
+ if (!ownerToken) {
+ throw new Error('owner token not found');
+ }
+ return ownerToken;
+ }
+
public async startWorkspace(ctx: TraceContext, workspaceId: string, options: GitpodServer.StartWorkspaceOptions): Promise {
traceAPIParams(ctx, { workspaceId, options });
traceWI(ctx, { workspaceId });
diff --git a/components/server/src/workspace/referrer-prefix-context-parser.ts b/components/server/src/workspace/referrer-prefix-context-parser.ts
new file mode 100644
index 00000000000000..03b16d93343d27
--- /dev/null
+++ b/components/server/src/workspace/referrer-prefix-context-parser.ts
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
+ * Licensed under the GNU Affero General Public License (AGPL).
+ * See License-AGPL.txt in the project root for license information.
+ */
+
+ import { IPrefixContextParser } from "./context-parser";
+ import { User, WorkspaceContext, WithReferrerContext } from "@gitpod/gitpod-protocol";
+ import { injectable } from "inversify";
+
+
+@injectable()
+export class ReferrerPrefixParser implements IPrefixContextParser {
+
+ private readonly prefix = /^\/?referrer:([^\/:]*)(?::([^\/]*))?\//
+
+ findPrefix(_: User, context: string): string | undefined {
+ return this.prefix.exec(context)?.[0] || undefined;
+ }
+
+ async handle(_: User, prefix: string, context: WorkspaceContext): Promise {
+ const matches = this.prefix.exec(prefix);
+ const referrer = matches?.[1];
+ const referrerIde = matches?.[2];
+ return referrer ? {...context, referrer, referrerIde} : context;
+ }
+
+}
\ No newline at end of file
diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts
index d1624cc9f9780c..24b7c5bcf20154 100644
--- a/components/server/src/workspace/workspace-starter.ts
+++ b/components/server/src/workspace/workspace-starter.ts
@@ -32,6 +32,8 @@ import * as path from 'path';
import * as grpc from "@grpc/grpc-js";
import { IDEConfig, IDEConfigService } from "../ide-config";
import { EnvVarWithValue } from "@gitpod/gitpod-protocol/src/protocol";
+import { WithReferrerContext } from "@gitpod/gitpod-protocol/lib/protocol";
+import { IDEOption } from "@gitpod/gitpod-protocol/lib/ide-protocol";
export interface StartWorkspaceOptions {
rethrow?: boolean;
@@ -88,9 +90,9 @@ export class WorkspaceStarter {
req.setAuth(auth);
const client = this.imagebuilderClientProvider.getDefault();
- const res = await client.resolveBaseImage({span}, req);
+ const res = await client.resolveBaseImage({ span }, req);
workspace.imageSource = {
- baseImageResolved: res.getRef()
+ baseImageResolved: res.getRef()
}
}
@@ -101,7 +103,7 @@ export class WorkspaceStarter {
const ideConfig = await this.ideConfigService.config;
// create and store instance
- let instance = await this.workspaceDb.trace({ span }).storeInstance(await this.newInstance(workspace, user, options.excludeFeatureFlags || [], ideConfig));
+ let instance = await this.workspaceDb.trace({ span }).storeInstance(await this.newInstance(ctx, workspace, user, options.excludeFeatureFlags || [], ideConfig));
span.log({ "newInstance": instance.id });
const forceRebuild = !!workspace.context.forceImageBuild;
@@ -194,12 +196,12 @@ export class WorkspaceStarter {
}
// start that thing
- log.info({instanceId: instance.id}, 'starting instance');
+ log.info({ instanceId: instance.id }, 'starting instance');
resp = (await manager.startWorkspace({ span }, startRequest)).toObject();
break;
} catch (err: any) {
if ('code' in err && err.code !== grpc.status.OK && lastInstallation !== "") {
- log.error({instanceId: instance.id}, "cannot start workspace on cluster, might retry", err, {cluster: lastInstallation});
+ log.error({ instanceId: instance.id }, "cannot start workspace on cluster, might retry", err, { cluster: lastInstallation });
exceptInstallation.push(lastInstallation);
} else {
throw err;
@@ -240,7 +242,7 @@ export class WorkspaceStarter {
if (rethrow) {
throw err;
} else {
- log.error("error starting instance", err, { instanceId: instance.id});
+ log.error("error starting instance", err, { instanceId: instance.id });
}
return { instanceID: instance.id };
@@ -251,9 +253,9 @@ export class WorkspaceStarter {
protected async notifyOnPrebuildQueued(ctx: TraceContext, workspaceId: string) {
const span = TraceContext.startSpan("notifyOnPrebuildQueued", ctx);
- const prebuild = await this.workspaceDb.trace({span}).findPrebuildByWorkspaceID(workspaceId);
+ const prebuild = await this.workspaceDb.trace({ span }).findPrebuildByWorkspaceID(workspaceId);
if (prebuild) {
- const info = (await this.workspaceDb.trace({span}).findPrebuildInfos([prebuild.id]))[0];
+ const info = (await this.workspaceDb.trace({ span }).findPrebuildInfos([prebuild.id]))[0];
if (info) {
this.messageBus.notifyOnPrebuildUpdate({ info, status: "queued" });
}
@@ -281,21 +283,21 @@ export class WorkspaceStarter {
// If we just attempted to start a workspace for a prebuild - and that failed, we have to fail the prebuild itself.
if (workspace.type === 'prebuild') {
- const prebuild = await this.workspaceDb.trace({span}).findPrebuildByWorkspaceID(workspace.id);
+ const prebuild = await this.workspaceDb.trace({ span }).findPrebuildByWorkspaceID(workspace.id);
if (prebuild && prebuild.state !== 'aborted') {
prebuild.state = "aborted";
prebuild.error = err.toString();
await this.workspaceDb.trace({ span }).storePrebuiltWorkspace(prebuild)
- await this.messageBus.notifyHeadlessUpdate({span}, workspace.ownerId, workspace.id, {
+ await this.messageBus.notifyHeadlessUpdate({ span }, workspace.ownerId, workspace.id, {
type: HeadlessWorkspaceEventType.Aborted,
// TODO: `workspaceID: workspace.id` not needed here? (found in ee/src/prebuilds/prebuild-queue-maintainer.ts and ee/src/bridge.ts)
});
}
}
} catch (err) {
- TraceContext.setError({span}, err);
- log.error({workspaceId: workspace.id, instanceId: instance.id, userId: workspace.ownerId}, "cannot properly fail workspace instance during start", err);
+ TraceContext.setError({ span }, err);
+ log.error({ workspaceId: workspace.id, instanceId: instance.id, userId: workspace.ownerId }, "cannot properly fail workspace instance during start", err);
}
}
@@ -304,7 +306,7 @@ export class WorkspaceStarter {
*
* @param workspace the workspace to create an instance for
*/
- protected async newInstance(workspace: Workspace, user: User, excludeFeatureFlags: NamedWorkspaceFeatureFlag[], ideConfig: IDEConfig): Promise {
+ protected async newInstance(ctx: TraceContext, workspace: Workspace, user: User, excludeFeatureFlags: NamedWorkspaceFeatureFlag[], ideConfig: IDEConfig): Promise {
// TODO(cw): once we allow changing the IDE in the workspace config (i.e. .gitpod.yml), we must
// give that value precedence over the default choice.
const configuration: WorkspaceInstanceConfiguration = {
@@ -324,17 +326,34 @@ export class WorkspaceStarter {
}
}
- const useDesktopIdeChoice = user.additionalData?.ideSettings?.useDesktopIde || false;
- if (useDesktopIdeChoice) {
- const desktopIdeChoice = user.additionalData?.ideSettings?.defaultDesktopIde;
- if (!!desktopIdeChoice) {
- const mappedImage = ideConfig.ideOptions.options[desktopIdeChoice];
- if (!!mappedImage && mappedImage.image) {
- configuration.desktopIdeImage = mappedImage.image;
- } else if (this.authService.hasPermission(user, "ide-settings")) {
- // if the IDE choice isn't one of the preconfiured choices, we assume its the image name.
- // For now, this feature requires special permissions.
- configuration.desktopIdeImage = desktopIdeChoice;
+ const referrerIde = this.resolveReferrerIDE(workspace, user, ideConfig);
+ if (referrerIde) {
+ configuration.desktopIdeImage = referrerIde.option.image;
+ if (!user.additionalData?.ideSettings) {
+ // A user does not have IDE settings configured yet configure it with a referrer ide as default.
+ const additionalData = user?.additionalData || {};
+ const settings = additionalData.ideSettings || {};
+ settings.useDesktopIde = true;
+ settings.defaultDesktopIde = referrerIde.id;
+ additionalData.ideSettings = settings;
+ user.additionalData = additionalData;
+ this.userDB.trace(ctx).updateUserPartial(user).catch(e => {
+ log.error({ userId: user.id }, "cannot configure default desktop ide", e);
+ });
+ }
+ } else {
+ const useDesktopIdeChoice = user.additionalData?.ideSettings?.useDesktopIde || false;
+ if (useDesktopIdeChoice) {
+ const desktopIdeChoice = user.additionalData?.ideSettings?.defaultDesktopIde;
+ if (!!desktopIdeChoice) {
+ const mappedImage = ideConfig.ideOptions.options[desktopIdeChoice];
+ if (!!mappedImage && mappedImage.image) {
+ configuration.desktopIdeImage = mappedImage.image;
+ } else if (this.authService.hasPermission(user, "ide-settings")) {
+ // if the IDE choice isn't one of the preconfiured choices, we assume its the image name.
+ // For now, this feature requires special permissions.
+ configuration.desktopIdeImage = desktopIdeChoice;
+ }
}
}
}
@@ -373,10 +392,48 @@ export class WorkspaceStarter {
},
configuration
}
+ if (WithReferrerContext.is(workspace.context)) {
+ this.analytics.track({ userId: user.id, event: "ide_referrer", properties: {
+ workspaceId: workspace.id,
+ instanceId: instance.id,
+ referrer: workspace.context.referrer,
+ referrerIde: workspace.context.referrerIde
+ }});
+ }
return instance;
}
- protected async prepareBuildRequest(ctx: TraceContext, workspace: Workspace, imgsrc: WorkspaceImageSource, user: User, ignoreBaseImageresolvedAndRebuildBase: boolean = false): Promise<{src: BuildSource, auth: BuildRegistryAuth, disposable?: Disposable}> {
+ protected resolveReferrerIDE(workspace: Workspace, user: User, ideConfig: IDEConfig): { id: string, option: IDEOption } | undefined {
+ if (!WithReferrerContext.is(workspace.context)) {
+ return undefined;
+ }
+ const referrer = ideConfig.ideOptions.clients?.[workspace.context.referrer];
+ if (!referrer) {
+ return undefined;
+ }
+
+ const providedIde = workspace.context.referrerIde;
+ const providedOption = providedIde && ideConfig.ideOptions.options[providedIde];
+ if (providedOption && referrer.desktopIDEs?.some(ide => ide === providedIde)) {
+ return { id: providedIde, option: providedOption };
+ }
+
+ const defaultDesktopIde = user.additionalData?.ideSettings?.defaultDesktopIde;
+ const userOption = defaultDesktopIde && ideConfig.ideOptions.options[defaultDesktopIde];
+ if (userOption && referrer.desktopIDEs?.some(ide => ide === defaultDesktopIde)) {
+ return { id: defaultDesktopIde, option: userOption };
+ }
+
+ const defaultIde = referrer.defaultDesktopIDE;
+ const defaultOption = defaultIde && ideConfig.ideOptions.options[defaultIde];
+ if (defaultOption) {
+ return { id: defaultIde, option: defaultOption }
+ }
+
+ return undefined;
+ }
+
+ protected async prepareBuildRequest(ctx: TraceContext, workspace: Workspace, imgsrc: WorkspaceImageSource, user: User, ignoreBaseImageresolvedAndRebuildBase: boolean = false): Promise<{ src: BuildSource, auth: BuildRegistryAuth, disposable?: Disposable }> {
const span = TraceContext.startSpan("prepareBuildRequest", ctx);
try {
@@ -384,7 +441,7 @@ export class WorkspaceStarter {
// and dismiss the original image source.
if (workspace.baseImageNameResolved && !ignoreBaseImageresolvedAndRebuildBase) {
span.setTag("hasBaseImageNameResolved", true);
- span.log({"baseImageNameResolved": workspace.baseImageNameResolved});
+ span.log({ "baseImageNameResolved": workspace.baseImageNameResolved });
const ref = new BuildSourceReference();
ref.setRef(workspace.baseImageNameResolved);
@@ -403,7 +460,7 @@ export class WorkspaceStarter {
const auth = new BuildRegistryAuth();
auth.setSelective(nauth);
- return {src, auth};
+ return { src, auth };
}
const auth = new BuildRegistryAuth();
@@ -424,7 +481,7 @@ export class WorkspaceStarter {
if (!AdditionalContentContext.hasDockerConfig(workspace.context, workspace.config) && imgsrc.dockerFileSource) {
// TODO(se): we cannot change this initializer structure now because it is part of how baserefs are computed in image-builder.
// Image builds should however just use the initialization if the workspace they are running for (i.e. the one from above).
- const { git, disposable } = await this.createGitInitializer({span}, workspace, {
+ const { git, disposable } = await this.createGitInitializer({ span }, workspace, {
...imgsrc.dockerFileSource,
title: "irrelevant",
ref: undefined,
@@ -437,7 +494,7 @@ export class WorkspaceStarter {
source = new WorkspaceInitializer();
source.setGit(git);
} else {
- const {initializer, disposable} = await this.createInitializer({span}, workspace, workspace.context, user, false);
+ const { initializer, disposable } = await this.createInitializer({ span }, workspace, workspace.context, user, false);
source = initializer;
disp.push(disposable);
}
@@ -454,7 +511,7 @@ export class WorkspaceStarter {
const src = new BuildSource();
src.setFile(file);
- return {src, auth, disposable: disp};
+ return { src, auth, disposable: disp };
}
if (WorkspaceImageSourceReference.is(imgsrc)) {
const ref = new BuildSourceReference();
@@ -462,7 +519,7 @@ export class WorkspaceStarter {
const src = new BuildSource();
src.setRef(ref);
- return {src, auth};
+ return { src, auth };
}
throw new Error("unknown workspace image source");
@@ -478,7 +535,7 @@ export class WorkspaceStarter {
const span = TraceContext.startSpan("needsImageBuild", ctx);
try {
const client = this.imagebuilderClientProvider.getDefault();
- const {src, auth, disposable} = await this.prepareBuildRequest({ span }, workspace, workspace.imageSource!, user);
+ const { src, auth, disposable } = await this.prepareBuildRequest({ span }, workspace, workspace.imageSource!, user);
const req = new ResolveWorkspaceImageRequest();
req.setSource(src);
@@ -504,7 +561,7 @@ export class WorkspaceStarter {
try {
// Start build...
const client = this.imagebuilderClientProvider.getDefault();
- const {src, auth, disposable} = await this.prepareBuildRequest({ span }, workspace, workspace.imageSource!, user, ignoreBaseImageresolvedAndRebuildBase || forceRebuild);
+ const { src, auth, disposable } = await this.prepareBuildRequest({ span }, workspace, workspace.imageSource!, user, ignoreBaseImageresolvedAndRebuildBase || forceRebuild);
const req = new BuildRequest();
req.setSource(src);
@@ -515,7 +572,7 @@ export class WorkspaceStarter {
// Update the workspace now that we know what the name of the workspace image will be (which doubles as buildID)
workspace.imageNameResolved = result.ref;
- span.log({"ref": workspace.imageNameResolved});
+ span.log({ "ref": workspace.imageNameResolved });
await this.workspaceDb.trace({ span }).store(workspace);
// Update workspace instance to tell the world we're building an image
@@ -550,7 +607,7 @@ export class WorkspaceStarter {
// Note: it's intentional that we overwrite existing baseImageNameResolved values here so that one by one the refs here become absolute (i.e. digested form).
// This prevents the "rebuilds" for old workspaces.
if (!!buildResult.getBaseRef() && buildResult.getBaseRef() != workspace.baseImageNameResolved) {
- span.log({"oldBaseRef": workspace.baseImageNameResolved, "newBaseRef": buildResult.getBaseRef()});
+ span.log({ "oldBaseRef": workspace.baseImageNameResolved, "newBaseRef": buildResult.getBaseRef() });
workspace.baseImageNameResolved = buildResult.getBaseRef();
await this.workspaceDb.trace({ span }).store(workspace);
@@ -572,11 +629,11 @@ export class WorkspaceStarter {
return msg.startsWith("build failed:");
};
if (looksLikeUserError(message)) {
- log.debug({instanceId: instance.id, userId: user.id, workspaceId: workspace.id}, `workspace image build failed: ${message}`);
+ log.debug({ instanceId: instance.id, userId: user.id, workspaceId: workspace.id }, `workspace image build failed: ${message}`);
} else {
- log.warn({instanceId: instance.id, userId: user.id, workspaceId: workspace.id}, `workspace image build failed: ${message}`);
+ log.warn({ instanceId: instance.id, userId: user.id, workspaceId: workspace.id }, `workspace image build failed: ${message}`);
}
- this.analytics.track({ userId: user.id, event: "imagebuild-failed", properties: { workspaceId: workspace.id, instanceId: instance.id, contextURL: workspace.contextURL, }});
+ this.analytics.track({ userId: user.id, event: "imagebuild-failed", properties: { workspaceId: workspace.id, instanceId: instance.id, contextURL: workspace.contextURL, } });
throw err;
} finally {
@@ -703,7 +760,7 @@ export class WorkspaceStarter {
const portIndex = new Set();
const ports = (workspace.config.ports || []).map(p => {
if (portIndex.has(p.port)) {
- log.debug({instanceId: instance.id, workspaceId: workspace.id, userId: user.id}, `duplicate port in user config: ${p.port}`);
+ log.debug({ instanceId: instance.id, workspaceId: workspace.id, userId: user.id }, `duplicate port in user config: ${p.port}`);
return undefined;
}
portIndex.add(p.port);
@@ -797,18 +854,18 @@ export class WorkspaceStarter {
"function:deleteEnvVar",
"function:trackEvent",
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "workspace", subjectID: workspace.id, operations: ["get", "update"]}),
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "workspaceInstance", subjectID: instance.id, operations: ["get", "update", "delete"]}),
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "snapshot", subjectID: ScopedResourceGuard.SNAPSHOT_WORKSPACE_SUBJECT_ID_PREFIX + workspace.id, operations: ["create"]}),
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "gitpodToken", subjectID: "*", operations: ["create"]}),
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "userStorage", subjectID: "*", operations: ["create", "get", "update"]}),
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "token", subjectID: "*", operations: ["get"]}),
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "contentBlob", subjectID: "*", operations: ["create", "get"]}),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "workspace", subjectID: workspace.id, operations: ["get", "update"] }),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "workspaceInstance", subjectID: instance.id, operations: ["get", "update", "delete"] }),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "snapshot", subjectID: ScopedResourceGuard.SNAPSHOT_WORKSPACE_SUBJECT_ID_PREFIX + workspace.id, operations: ["create"] }),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "gitpodToken", subjectID: "*", operations: ["create"] }),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "userStorage", subjectID: "*", operations: ["create", "get", "update"] }),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "token", subjectID: "*", operations: ["get"] }),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "contentBlob", subjectID: "*", operations: ["create", "get"] }),
];
if (CommitContext.is(workspace.context)) {
const subjectID = workspace.context.repository.owner + '/' + workspace.context.repository.name;
scopes.push(
- "resource:"+ScopedResourceGuard.marshalResourceScope({kind: "envVar", subjectID, operations: ["create", "get", "update", "delete"]}),
+ "resource:" + ScopedResourceGuard.marshalResourceScope({ kind: "envVar", subjectID, operations: ["create", "get", "update", "delete"] }),
);
}
return scopes;
@@ -838,7 +895,7 @@ export class WorkspaceStarter {
return gitSpec;
}
- protected async createInitializer(traceCtx: TraceContext, workspace: Workspace, context: WorkspaceContext, user: User, mustHaveBackup: boolean): Promise<{initializer: WorkspaceInitializer, disposable: Disposable}> {
+ protected async createInitializer(traceCtx: TraceContext, workspace: Workspace, context: WorkspaceContext, user: User, mustHaveBackup: boolean): Promise<{ initializer: WorkspaceInitializer, disposable: Disposable }> {
let result = new WorkspaceInitializer();
const disp = new DisposableCollection();
@@ -870,10 +927,10 @@ export class WorkspaceStarter {
throw new Error("cannot create initializer for unkown context type");
}
if (AdditionalContentContext.is(context)) {
- const additionalInit = new FileDownloadInitializer();
+ const additionalInit = new FileDownloadInitializer();
const getDigest = (contents: string) => {
- return 'sha256:'+crypto.createHash('sha256').update(contents).digest('hex');
+ return 'sha256:' + crypto.createHash('sha256').update(contents).digest('hex');
}
const tokenExpirationTime = new Date();
@@ -900,10 +957,10 @@ export class WorkspaceStarter {
composite.addInitializer(wsInitializerForDownload);
result = newRoot;
}
- return {initializer: result, disposable: disp};
+ return { initializer: result, disposable: disp };
}
- protected async createGitInitializer(traceCtx: TraceContext, workspace: Workspace, context: CommitContext, user: User): Promise<{git: GitInitializer, disposable: Disposable}> {
+ protected async createGitInitializer(traceCtx: TraceContext, workspace: Workspace, context: CommitContext, user: User): Promise<{ git: GitInitializer, disposable: Disposable }> {
if (!CommitContext.is(context)) {
throw new Error("Unknown workspace context");
}
@@ -929,7 +986,7 @@ export class WorkspaceStarter {
tokenOTS = res.token;
disposable = res.disposable;
} catch (error) { // no token
- log.error({workspaceId: workspace.id, userId: workspace.ownerId}, "cannot authenticate user for Git initializer", error);
+ log.error({ workspaceId: workspace.id, userId: workspace.ownerId }, "cannot authenticate user for Git initializer", error);
throw new Error("User is unauthorized!");
}
const cloneUrl = context.repository.cloneUrl || context.cloneUrl!;
diff --git a/components/supervisor-api/go/info.pb.gw.go b/components/supervisor-api/go/info.pb.gw.go
index 7d05fe385d9835..bbb171b6c2ce31 100644
--- a/components/supervisor-api/go/info.pb.gw.go
+++ b/components/supervisor-api/go/info.pb.gw.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/info_grpc.pb.go b/components/supervisor-api/go/info_grpc.pb.go
index c1d602c8cc09fc..a6ba0486b1d054 100644
--- a/components/supervisor-api/go/info_grpc.pb.go
+++ b/components/supervisor-api/go/info_grpc.pb.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/notification.pb.gw.go b/components/supervisor-api/go/notification.pb.gw.go
index 473fc0e8d96cf0..1f02ee798a0ce8 100644
--- a/components/supervisor-api/go/notification.pb.gw.go
+++ b/components/supervisor-api/go/notification.pb.gw.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/notification_grpc.pb.go b/components/supervisor-api/go/notification_grpc.pb.go
index 13b467b3b1a505..781237778f80f9 100644
--- a/components/supervisor-api/go/notification_grpc.pb.go
+++ b/components/supervisor-api/go/notification_grpc.pb.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/port.pb.gw.go b/components/supervisor-api/go/port.pb.gw.go
index 8fcf868a2ac9ae..b34ddc80540c7f 100644
--- a/components/supervisor-api/go/port.pb.gw.go
+++ b/components/supervisor-api/go/port.pb.gw.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/port_grpc.pb.go b/components/supervisor-api/go/port_grpc.pb.go
index a3f3a35f500a96..71c1ccae8af106 100644
--- a/components/supervisor-api/go/port_grpc.pb.go
+++ b/components/supervisor-api/go/port_grpc.pb.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/status.pb.go b/components/supervisor-api/go/status.pb.go
index e596f7335610d7..823637c74e98f2 100644
--- a/components/supervisor-api/go/status.pb.go
+++ b/components/supervisor-api/go/status.pb.go
@@ -1225,8 +1225,9 @@ type IDEStatusResponse_DesktopStatus struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Link string `protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"`
- Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"`
+ Link string `protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"`
+ Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"`
+ ClientID string `protobuf:"bytes,3,opt,name=clientID,proto3" json:"clientID,omitempty"`
}
func (x *IDEStatusResponse_DesktopStatus) Reset() {
@@ -1275,6 +1276,13 @@ func (x *IDEStatusResponse_DesktopStatus) GetLabel() string {
return ""
}
+func (x *IDEStatusResponse_DesktopStatus) GetClientID() string {
+ if x != nil {
+ return x.ClientID
+ }
+ return ""
+}
+
var File_status_proto protoreflect.FileDescriptor
var file_status_proto_rawDesc = []byte{
@@ -1289,186 +1297,188 @@ var file_status_proto_rawDesc = []byte{
0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0x26, 0x0a, 0x10, 0x49,
0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77,
- 0x61, 0x69, 0x74, 0x22, 0xa5, 0x01, 0x0a, 0x11, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x61, 0x69, 0x74, 0x22, 0xc1, 0x01, 0x0a, 0x11, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18,
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x45, 0x0a, 0x07, 0x64, 0x65, 0x73,
0x6b, 0x74, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x75, 0x70,
0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f,
0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70,
- 0x1a, 0x39, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x1a, 0x55, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x2a, 0x0a, 0x14, 0x43,
- 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x68, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x65,
- 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x31,
- 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19,
- 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
- 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x22, 0x15, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x41, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b,
- 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x12, 0x29, 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c,
- 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x61,
- 0x72, 0x79, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x2e, 0x0a, 0x12, 0x50,
- 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22, 0x44, 0x0a, 0x13, 0x50,
- 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
- 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50,
- 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74,
- 0x73, 0x22, 0x9f, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72,
- 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3a, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c,
- 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x75, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62,
- 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74,
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x75, 0x72, 0x6c, 0x12, 0x3e, 0x0a, 0x0a, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65,
- 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76,
- 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x4f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73,
- 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f,
- 0x73, 0x65, 0x64, 0x22, 0xf1, 0x01, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64,
- 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67,
- 0x65, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74,
- 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73,
- 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e,
- 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65,
- 0x6c, 0x56, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69,
- 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
- 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76,
- 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72,
- 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x52, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x43,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
- 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
- 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb4, 0x02, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74,
- 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
- 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x63,
- 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x35,
- 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x1b, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x70,
- 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x65, 0x78,
- 0x70, 0x6f, 0x73, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x65, 0x78,
- 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x73,
- 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x75,
- 0x74, 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x6f,
- 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x74, 0x75, 0x6e, 0x6e,
- 0x65, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70,
- 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64,
- 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
- 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x2e,
- 0x0a, 0x12, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22, 0x43,
- 0x0a, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x01,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f,
- 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x74, 0x61,
- 0x73, 0x6b, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
- 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54,
- 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12,
- 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x40, 0x0a, 0x0c, 0x70,
- 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54,
- 0x61, 0x73, 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
- 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5c, 0x0a,
- 0x10, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x69, 0x6e,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x49, 0x6e, 0x12, 0x1b,
- 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x2a, 0x43, 0x0a, 0x0d, 0x43,
- 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x0a,
- 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b,
- 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x10, 0x01, 0x12, 0x11, 0x0a,
- 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x10, 0x02,
- 0x2a, 0x29, 0x0a, 0x0e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69,
- 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, 0x00, 0x12,
- 0x0a, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x01, 0x2a, 0x65, 0x0a, 0x13, 0x4f,
- 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x10, 0x00, 0x12, 0x10,
- 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x10, 0x01,
- 0x12, 0x10, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77,
- 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x10, 0x03, 0x12, 0x12,
- 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
- 0x10, 0x04, 0x2a, 0x39, 0x0a, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x45, 0x78,
- 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67,
- 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x10,
- 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x31, 0x0a,
- 0x09, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x6f, 0x70,
- 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x6e, 0x69,
- 0x6e, 0x67, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x10, 0x02,
- 0x32, 0xcb, 0x06, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69,
- 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x10, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72,
- 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69,
- 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53, 0x74,
- 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x75,
- 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69,
- 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x73,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72,
- 0x12, 0x83, 0x01, 0x0a, 0x09, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c,
- 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73,
- 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4,
- 0x93, 0x02, 0x33, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f,
- 0x69, 0x64, 0x65, 0x5a, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x2f, 0x69, 0x64, 0x65, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x2f, 0x7b, 0x77, 0x61, 0x69, 0x74,
- 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x12, 0x97, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65,
- 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72,
- 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x75, 0x70,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x22, 0x2a, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+ 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+ 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77,
+ 0x61, 0x69, 0x74, 0x22, 0x68, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74,
+ 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09,
+ 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x75, 0x70,
0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x82,
- 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5a, 0x25, 0x12, 0x23, 0x2f, 0x76, 0x31,
- 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2f,
- 0x77, 0x61, 0x69, 0x74, 0x2f, 0x7b, 0x77, 0x61, 0x69, 0x74, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d,
- 0x12, 0x6c, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
- 0x12, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x42, 0x61,
- 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x42,
- 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
- 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31,
- 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x95,
- 0x01, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e,
- 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74,
- 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f,
- 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74,
- 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
- 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5a, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31,
- 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x6f, 0x62,
- 0x73, 0x65, 0x72, 0x76, 0x65, 0x2f, 0x7b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x3d, 0x74,
- 0x72, 0x75, 0x65, 0x7d, 0x30, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x73,
- 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69,
- 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69,
- 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12,
- 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b,
- 0x73, 0x5a, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f,
- 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2f, 0x7b, 0x6f,
- 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x30, 0x01, 0x42, 0x46,
- 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2e, 0x73, 0x75, 0x70, 0x65,
- 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68,
- 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f,
- 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73,
- 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x15, 0x0a,
+ 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x22, 0x41, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74,
+ 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10,
+ 0x63, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x41, 0x76,
+ 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x2e, 0x0a, 0x12, 0x50, 0x6f, 0x72, 0x74, 0x73,
+ 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+ 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
+ 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22, 0x44, 0x0a, 0x13, 0x50, 0x6f, 0x72, 0x74, 0x73,
+ 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d,
+ 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e,
+ 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73,
+ 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x9f, 0x01,
+ 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66,
+ 0x6f, 0x12, 0x3a, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73,
+ 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74,
+ 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12,
+ 0x3e, 0x0a, 0x0a, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72,
+ 0x2e, 0x4f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x22,
+ 0xf1, 0x01, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74,
+ 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70,
+ 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c,
+ 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x75, 0x70, 0x65,
+ 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x69, 0x73,
+ 0x69, 0x62, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69,
+ 0x74, 0x79, 0x12, 0x43, 0x0a, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72,
+ 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66,
+ 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
+ 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
+ 0x02, 0x38, 0x01, 0x22, 0xb4, 0x02, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x72,
+ 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f,
+ 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x07, 0x65, 0x78,
+ 0x70, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x75,
+ 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64,
+ 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65,
+ 0x64, 0x12, 0x41, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x75,
+ 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72,
+ 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x45, 0x78,
+ 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x45, 0x78, 0x70, 0x6f,
+ 0x73, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64,
+ 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69,
+ 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x20,
+ 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x2e, 0x0a, 0x12, 0x54, 0x61,
+ 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x54, 0x61,
+ 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x16, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61,
+ 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x22,
+ 0xa7, 0x01, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e,
+ 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b,
+ 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e,
+ 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53,
+ 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74,
+ 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74,
+ 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x40, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65,
+ 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+ 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x50,
+ 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x70, 0x72, 0x65,
+ 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5c, 0x0a, 0x10, 0x54, 0x61, 0x73,
+ 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x49, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70,
+ 0x65, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f,
+ 0x70, 0x65, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x2a, 0x43, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+ 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x66, 0x72, 0x6f, 0x6d,
+ 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d,
+ 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x66, 0x72, 0x6f,
+ 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x10, 0x02, 0x2a, 0x29, 0x0a, 0x0e,
+ 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x0b,
+ 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x70,
+ 0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x01, 0x2a, 0x65, 0x0a, 0x13, 0x4f, 0x6e, 0x50, 0x6f, 0x72,
+ 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a,
+ 0x0a, 0x06, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x6f, 0x70,
+ 0x65, 0x6e, 0x5f, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
+ 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x10, 0x02, 0x12, 0x0a,
+ 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x6e, 0x6f,
+ 0x74, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, 0x04, 0x2a, 0x39,
+ 0x0a, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75,
+ 0x72, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0d,
+ 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a,
+ 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x31, 0x0a, 0x09, 0x54, 0x61, 0x73,
+ 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6e,
+ 0x67, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x01,
+ 0x12, 0x0a, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x10, 0x02, 0x32, 0xcb, 0x06, 0x0a,
+ 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7c,
+ 0x0a, 0x10, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e,
+ 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76,
+ 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82,
+ 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x12, 0x83, 0x01, 0x0a,
+ 0x09, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x75, 0x70,
+ 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72,
+ 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x12,
+ 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x69, 0x64, 0x65, 0x5a,
+ 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x69, 0x64,
+ 0x65, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x2f, 0x7b, 0x77, 0x61, 0x69, 0x74, 0x3d, 0x74, 0x72, 0x75,
+ 0x65, 0x7d, 0x12, 0x97, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74,
+ 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f,
+ 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69,
+ 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+ 0x3b, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f,
+ 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5a, 0x25, 0x12, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2f, 0x77, 0x61, 0x69, 0x74,
+ 0x2f, 0x7b, 0x77, 0x61, 0x69, 0x74, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x12, 0x6c, 0x0a, 0x0c,
+ 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x73,
+ 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
+ 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e,
+ 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75,
+ 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+ 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x50,
+ 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x75, 0x70,
+ 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x75, 0x70,
+ 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4,
+ 0x93, 0x02, 0x3d, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f,
+ 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5a, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x2f, 0x7b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d,
+ 0x30, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e,
+ 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e,
+ 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12, 0x10, 0x2f, 0x76, 0x31,
+ 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x5a, 0x29, 0x12,
+ 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b,
+ 0x73, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2f, 0x7b, 0x6f, 0x62, 0x73, 0x65, 0x72,
+ 0x76, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x30, 0x01, 0x42, 0x46, 0x0a, 0x18, 0x69, 0x6f,
+ 0x2e, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73,
+ 0x6f, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74,
+ 0x70, 0x6f, 0x64, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2f, 0x61,
+ 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/components/supervisor-api/go/status.pb.gw.go b/components/supervisor-api/go/status.pb.gw.go
index cef3d2004593c3..310fb074c88116 100644
--- a/components/supervisor-api/go/status.pb.gw.go
+++ b/components/supervisor-api/go/status.pb.gw.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/status_grpc.pb.go b/components/supervisor-api/go/status_grpc.pb.go
index b9cf45b9104284..f67278ca34c6f7 100644
--- a/components/supervisor-api/go/status_grpc.pb.go
+++ b/components/supervisor-api/go/status_grpc.pb.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/terminal.pb.gw.go b/components/supervisor-api/go/terminal.pb.gw.go
index 9d93c8d91543f2..e9521171e23bd5 100644
--- a/components/supervisor-api/go/terminal.pb.gw.go
+++ b/components/supervisor-api/go/terminal.pb.gw.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/terminal_grpc.pb.go b/components/supervisor-api/go/terminal_grpc.pb.go
index 1a662e505e3409..fa2c37e903cef9 100644
--- a/components/supervisor-api/go/terminal_grpc.pb.go
+++ b/components/supervisor-api/go/terminal_grpc.pb.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/token.pb.gw.go b/components/supervisor-api/go/token.pb.gw.go
index 6198985ec6c41e..f3e9f17ac7b7ce 100644
--- a/components/supervisor-api/go/token.pb.gw.go
+++ b/components/supervisor-api/go/token.pb.gw.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/go/token_grpc.pb.go b/components/supervisor-api/go/token_grpc.pb.go
index 41c96edc9b639a..6d87c9eea6b0e5 100644
--- a/components/supervisor-api/go/token_grpc.pb.go
+++ b/components/supervisor-api/go/token_grpc.pb.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Info.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Info.java
index fda4e22aec5c5a..86cbe8ce0f0dc6 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Info.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Info.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/InfoServiceGrpc.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/InfoServiceGrpc.java
index eead5000e9ef4d..3a0745aefe4637 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/InfoServiceGrpc.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/InfoServiceGrpc.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Notification.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Notification.java
index a31d858e3444d8..816ca822921c07 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Notification.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Notification.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/NotificationServiceGrpc.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/NotificationServiceGrpc.java
index 092a0decc2f05d..5b547cc8a28e60 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/NotificationServiceGrpc.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/NotificationServiceGrpc.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Port.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Port.java
index 0cde0049cb8f48..ec8d07f14981b8 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Port.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Port.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/PortServiceGrpc.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/PortServiceGrpc.java
index d9a91d1bf8875e..08235cfa9b0d02 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/PortServiceGrpc.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/PortServiceGrpc.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java
index de63efc212c39f..d2e5f9d086710d 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
@@ -2180,6 +2180,18 @@ public interface DesktopStatusOrBuilder extends
*/
com.google.protobuf.ByteString
getLabelBytes();
+
+ /**
+ * string clientID = 3;
+ * @return The clientID.
+ */
+ java.lang.String getClientID();
+ /**
+ * string clientID = 3;
+ * @return The bytes for clientID.
+ */
+ com.google.protobuf.ByteString
+ getClientIDBytes();
}
/**
* Protobuf type {@code supervisor.IDEStatusResponse.DesktopStatus}
@@ -2196,6 +2208,7 @@ private DesktopStatus(com.google.protobuf.GeneratedMessageV3.Builder> builder)
private DesktopStatus() {
link_ = "";
label_ = "";
+ clientID_ = "";
}
@java.lang.Override
@@ -2240,6 +2253,12 @@ private DesktopStatus(
label_ = s;
break;
}
+ case 26: {
+ java.lang.String s = input.readStringRequireUtf8();
+
+ clientID_ = s;
+ break;
+ }
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
@@ -2348,6 +2367,44 @@ public java.lang.String getLabel() {
}
}
+ public static final int CLIENTID_FIELD_NUMBER = 3;
+ private volatile java.lang.Object clientID_;
+ /**
+ * string clientID = 3;
+ * @return The clientID.
+ */
+ @java.lang.Override
+ public java.lang.String getClientID() {
+ java.lang.Object ref = clientID_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ clientID_ = s;
+ return s;
+ }
+ }
+ /**
+ * string clientID = 3;
+ * @return The bytes for clientID.
+ */
+ @java.lang.Override
+ public com.google.protobuf.ByteString
+ getClientIDBytes() {
+ java.lang.Object ref = clientID_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ clientID_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
@@ -2368,6 +2425,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output)
if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(label_)) {
com.google.protobuf.GeneratedMessageV3.writeString(output, 2, label_);
}
+ if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(clientID_)) {
+ com.google.protobuf.GeneratedMessageV3.writeString(output, 3, clientID_);
+ }
unknownFields.writeTo(output);
}
@@ -2383,6 +2443,9 @@ public int getSerializedSize() {
if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(label_)) {
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, label_);
}
+ if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(clientID_)) {
+ size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, clientID_);
+ }
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
@@ -2402,6 +2465,8 @@ public boolean equals(final java.lang.Object obj) {
.equals(other.getLink())) return false;
if (!getLabel()
.equals(other.getLabel())) return false;
+ if (!getClientID()
+ .equals(other.getClientID())) return false;
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@@ -2417,6 +2482,8 @@ public int hashCode() {
hash = (53 * hash) + getLink().hashCode();
hash = (37 * hash) + LABEL_FIELD_NUMBER;
hash = (53 * hash) + getLabel().hashCode();
+ hash = (37 * hash) + CLIENTID_FIELD_NUMBER;
+ hash = (53 * hash) + getClientID().hashCode();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
@@ -2554,6 +2621,8 @@ public Builder clear() {
label_ = "";
+ clientID_ = "";
+
return this;
}
@@ -2582,6 +2651,7 @@ public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus buildPart
io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus result = new io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus(this);
result.link_ = link_;
result.label_ = label_;
+ result.clientID_ = clientID_;
onBuilt();
return result;
}
@@ -2638,6 +2708,10 @@ public Builder mergeFrom(io.gitpod.supervisor.api.Status.IDEStatusResponse.Deskt
label_ = other.label_;
onChanged();
}
+ if (!other.getClientID().isEmpty()) {
+ clientID_ = other.clientID_;
+ onChanged();
+ }
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
@@ -2818,6 +2892,82 @@ public Builder setLabelBytes(
onChanged();
return this;
}
+
+ private java.lang.Object clientID_ = "";
+ /**
+ * string clientID = 3;
+ * @return The clientID.
+ */
+ public java.lang.String getClientID() {
+ java.lang.Object ref = clientID_;
+ if (!(ref instanceof java.lang.String)) {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ clientID_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * string clientID = 3;
+ * @return The bytes for clientID.
+ */
+ public com.google.protobuf.ByteString
+ getClientIDBytes() {
+ java.lang.Object ref = clientID_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ clientID_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * string clientID = 3;
+ * @param value The clientID to set.
+ * @return This builder for chaining.
+ */
+ public Builder setClientID(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ clientID_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * string clientID = 3;
+ * @return This builder for chaining.
+ */
+ public Builder clearClientID() {
+
+ clientID_ = getDefaultInstance().getClientID();
+ onChanged();
+ return this;
+ }
+ /**
+ * string clientID = 3;
+ * @param value The bytes for clientID to set.
+ * @return This builder for chaining.
+ */
+ public Builder setClientIDBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ checkByteStringIsUtf8(value);
+
+ clientID_ = value;
+ onChanged();
+ return this;
+ }
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
@@ -13758,72 +13908,72 @@ public io.gitpod.supervisor.api.Status.TaskPresentation getDefaultInstanceForTyp
"nnotations.proto\032\nport.proto\"\031\n\027Supervis" +
"orStatusRequest\"&\n\030SupervisorStatusRespo" +
"nse\022\n\n\002ok\030\001 \001(\010\" \n\020IDEStatusRequest\022\014\n\004w" +
- "ait\030\001 \001(\010\"\213\001\n\021IDEStatusResponse\022\n\n\002ok\030\001 " +
+ "ait\030\001 \001(\010\"\235\001\n\021IDEStatusResponse\022\n\n\002ok\030\001 " +
"\001(\010\022<\n\007desktop\030\002 \001(\0132+.supervisor.IDESta" +
- "tusResponse.DesktopStatus\032,\n\rDesktopStat" +
- "us\022\014\n\004link\030\001 \001(\t\022\r\n\005label\030\002 \001(\t\"$\n\024Conte" +
- "ntStatusRequest\022\014\n\004wait\030\001 \001(\010\"U\n\025Content" +
- "StatusResponse\022\021\n\tavailable\030\001 \001(\010\022)\n\006sou" +
- "rce\030\002 \001(\0162\031.supervisor.ContentSource\"\025\n\023" +
- "BackupStatusRequest\"0\n\024BackupStatusRespo" +
- "nse\022\030\n\020canary_available\030\001 \001(\010\"%\n\022PortsSt" +
- "atusRequest\022\017\n\007observe\030\001 \001(\010\"=\n\023PortsSta" +
- "tusResponse\022&\n\005ports\030\001 \003(\0132\027.supervisor." +
- "PortsStatus\"\203\001\n\017ExposedPortInfo\022.\n\nvisib" +
- "ility\030\001 \001(\0162\032.supervisor.PortVisibility\022" +
- "\013\n\003url\030\002 \001(\t\0223\n\non_exposed\030\003 \001(\0162\037.super" +
- "visor.OnPortExposedAction\"\304\001\n\020TunneledPo" +
- "rtInfo\022\023\n\013target_port\030\001 \001(\r\022/\n\nvisibilit" +
- "y\030\002 \001(\0162\033.supervisor.TunnelVisiblity\022:\n\007" +
- "clients\030\003 \003(\0132).supervisor.TunneledPortI" +
- "nfo.ClientsEntry\032.\n\014ClientsEntry\022\013\n\003key\030" +
- "\001 \001(\t\022\r\n\005value\030\002 \001(\r:\0028\001\"\355\001\n\013PortsStatus" +
- "\022\022\n\nlocal_port\030\001 \001(\r\022\016\n\006served\030\004 \001(\010\022,\n\007" +
- "exposed\030\005 \001(\0132\033.supervisor.ExposedPortIn" +
- "fo\0223\n\rauto_exposure\030\007 \001(\0162\034.supervisor.P" +
- "ortAutoExposure\022.\n\010tunneled\030\006 \001(\0132\034.supe" +
- "rvisor.TunneledPortInfo\022\023\n\013description\030\010" +
- " \001(\t\022\014\n\004name\030\t \001(\tJ\004\010\002\020\003\"%\n\022TasksStatusR" +
- "equest\022\017\n\007observe\030\001 \001(\010\"<\n\023TasksStatusRe" +
- "sponse\022%\n\005tasks\030\001 \003(\0132\026.supervisor.TaskS" +
- "tatus\"\204\001\n\nTaskStatus\022\n\n\002id\030\001 \001(\t\022$\n\005stat" +
- "e\030\002 \001(\0162\025.supervisor.TaskState\022\020\n\010termin" +
- "al\030\003 \001(\t\0222\n\014presentation\030\004 \001(\0132\034.supervi" +
- "sor.TaskPresentation\"D\n\020TaskPresentation" +
- "\022\014\n\004name\030\001 \001(\t\022\017\n\007open_in\030\002 \001(\t\022\021\n\topen_" +
- "mode\030\003 \001(\t*C\n\rContentSource\022\016\n\nfrom_othe" +
- "r\020\000\022\017\n\013from_backup\020\001\022\021\n\rfrom_prebuild\020\002*" +
- "?\n\016PortVisibility\022\026\n\022private_visibility\020" +
- "\000\022\025\n\021public_visibility\020\001*e\n\023OnPortExpose" +
- "dAction\022\n\n\006ignore\020\000\022\020\n\014open_browser\020\001\022\020\n" +
- "\014open_preview\020\002\022\n\n\006notify\020\003\022\022\n\016notify_pr" +
- "ivate\020\004*9\n\020PortAutoExposure\022\n\n\006trying\020\000\022" +
- "\r\n\tsucceeded\020\001\022\n\n\006failed\020\002*1\n\tTaskState\022" +
- "\013\n\007opening\020\000\022\013\n\007running\020\001\022\n\n\006closed\020\0022\313\006" +
- "\n\rStatusService\022|\n\020SupervisorStatus\022#.su" +
- "pervisor.SupervisorStatusRequest\032$.super" +
- "visor.SupervisorStatusResponse\"\035\202\323\344\223\002\027\022\025" +
- "/v1/status/supervisor\022\203\001\n\tIDEStatus\022\034.su" +
- "pervisor.IDEStatusRequest\032\035.supervisor.I" +
- "DEStatusResponse\"9\202\323\344\223\0023\022\016/v1/status/ide" +
- "Z!\022\037/v1/status/ide/wait/{wait=true}\022\227\001\n\r" +
- "ContentStatus\022 .supervisor.ContentStatus" +
- "Request\032!.supervisor.ContentStatusRespon" +
- "se\"A\202\323\344\223\002;\022\022/v1/status/contentZ%\022#/v1/st" +
- "atus/content/wait/{wait=true}\022l\n\014BackupS" +
- "tatus\022\037.supervisor.BackupStatusRequest\032 " +
- ".supervisor.BackupStatusResponse\"\031\202\323\344\223\002\023" +
- "\022\021/v1/status/backup\022\225\001\n\013PortsStatus\022\036.su" +
- "pervisor.PortsStatusRequest\032\037.supervisor" +
- ".PortsStatusResponse\"C\202\323\344\223\002=\022\020/v1/status" +
- "/portsZ)\022\'/v1/status/ports/observe/{obse" +
- "rve=true}0\001\022\225\001\n\013TasksStatus\022\036.supervisor" +
- ".TasksStatusRequest\032\037.supervisor.TasksSt" +
- "atusResponse\"C\202\323\344\223\002=\022\020/v1/status/tasksZ)" +
- "\022\'/v1/status/tasks/observe/{observe=true" +
- "}0\001BF\n\030io.gitpod.supervisor.apiZ*github." +
- "com/gitpod-io/gitpod/supervisor/apib\006pro" +
- "to3"
+ "tusResponse.DesktopStatus\032>\n\rDesktopStat" +
+ "us\022\014\n\004link\030\001 \001(\t\022\r\n\005label\030\002 \001(\t\022\020\n\010clien" +
+ "tID\030\003 \001(\t\"$\n\024ContentStatusRequest\022\014\n\004wai" +
+ "t\030\001 \001(\010\"U\n\025ContentStatusResponse\022\021\n\tavai" +
+ "lable\030\001 \001(\010\022)\n\006source\030\002 \001(\0162\031.supervisor" +
+ ".ContentSource\"\025\n\023BackupStatusRequest\"0\n" +
+ "\024BackupStatusResponse\022\030\n\020canary_availabl" +
+ "e\030\001 \001(\010\"%\n\022PortsStatusRequest\022\017\n\007observe" +
+ "\030\001 \001(\010\"=\n\023PortsStatusResponse\022&\n\005ports\030\001" +
+ " \003(\0132\027.supervisor.PortsStatus\"\203\001\n\017Expose" +
+ "dPortInfo\022.\n\nvisibility\030\001 \001(\0162\032.supervis" +
+ "or.PortVisibility\022\013\n\003url\030\002 \001(\t\0223\n\non_exp" +
+ "osed\030\003 \001(\0162\037.supervisor.OnPortExposedAct" +
+ "ion\"\304\001\n\020TunneledPortInfo\022\023\n\013target_port\030" +
+ "\001 \001(\r\022/\n\nvisibility\030\002 \001(\0162\033.supervisor.T" +
+ "unnelVisiblity\022:\n\007clients\030\003 \003(\0132).superv" +
+ "isor.TunneledPortInfo.ClientsEntry\032.\n\014Cl" +
+ "ientsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\r:\002" +
+ "8\001\"\355\001\n\013PortsStatus\022\022\n\nlocal_port\030\001 \001(\r\022\016" +
+ "\n\006served\030\004 \001(\010\022,\n\007exposed\030\005 \001(\0132\033.superv" +
+ "isor.ExposedPortInfo\0223\n\rauto_exposure\030\007 " +
+ "\001(\0162\034.supervisor.PortAutoExposure\022.\n\010tun" +
+ "neled\030\006 \001(\0132\034.supervisor.TunneledPortInf" +
+ "o\022\023\n\013description\030\010 \001(\t\022\014\n\004name\030\t \001(\tJ\004\010\002" +
+ "\020\003\"%\n\022TasksStatusRequest\022\017\n\007observe\030\001 \001(" +
+ "\010\"<\n\023TasksStatusResponse\022%\n\005tasks\030\001 \003(\0132" +
+ "\026.supervisor.TaskStatus\"\204\001\n\nTaskStatus\022\n" +
+ "\n\002id\030\001 \001(\t\022$\n\005state\030\002 \001(\0162\025.supervisor.T" +
+ "askState\022\020\n\010terminal\030\003 \001(\t\0222\n\014presentati" +
+ "on\030\004 \001(\0132\034.supervisor.TaskPresentation\"D" +
+ "\n\020TaskPresentation\022\014\n\004name\030\001 \001(\t\022\017\n\007open" +
+ "_in\030\002 \001(\t\022\021\n\topen_mode\030\003 \001(\t*C\n\rContentS" +
+ "ource\022\016\n\nfrom_other\020\000\022\017\n\013from_backup\020\001\022\021" +
+ "\n\rfrom_prebuild\020\002*?\n\016PortVisibility\022\026\n\022p" +
+ "rivate_visibility\020\000\022\025\n\021public_visibility" +
+ "\020\001*e\n\023OnPortExposedAction\022\n\n\006ignore\020\000\022\020\n" +
+ "\014open_browser\020\001\022\020\n\014open_preview\020\002\022\n\n\006not" +
+ "ify\020\003\022\022\n\016notify_private\020\004*9\n\020PortAutoExp" +
+ "osure\022\n\n\006trying\020\000\022\r\n\tsucceeded\020\001\022\n\n\006fail" +
+ "ed\020\002*1\n\tTaskState\022\013\n\007opening\020\000\022\013\n\007runnin" +
+ "g\020\001\022\n\n\006closed\020\0022\313\006\n\rStatusService\022|\n\020Sup" +
+ "ervisorStatus\022#.supervisor.SupervisorSta" +
+ "tusRequest\032$.supervisor.SupervisorStatus" +
+ "Response\"\035\202\323\344\223\002\027\022\025/v1/status/supervisor\022" +
+ "\203\001\n\tIDEStatus\022\034.supervisor.IDEStatusRequ" +
+ "est\032\035.supervisor.IDEStatusResponse\"9\202\323\344\223" +
+ "\0023\022\016/v1/status/ideZ!\022\037/v1/status/ide/wai" +
+ "t/{wait=true}\022\227\001\n\rContentStatus\022 .superv" +
+ "isor.ContentStatusRequest\032!.supervisor.C" +
+ "ontentStatusResponse\"A\202\323\344\223\002;\022\022/v1/status" +
+ "/contentZ%\022#/v1/status/content/wait/{wai" +
+ "t=true}\022l\n\014BackupStatus\022\037.supervisor.Bac" +
+ "kupStatusRequest\032 .supervisor.BackupStat" +
+ "usResponse\"\031\202\323\344\223\002\023\022\021/v1/status/backup\022\225\001" +
+ "\n\013PortsStatus\022\036.supervisor.PortsStatusRe" +
+ "quest\032\037.supervisor.PortsStatusResponse\"C" +
+ "\202\323\344\223\002=\022\020/v1/status/portsZ)\022\'/v1/status/p" +
+ "orts/observe/{observe=true}0\001\022\225\001\n\013TasksS" +
+ "tatus\022\036.supervisor.TasksStatusRequest\032\037." +
+ "supervisor.TasksStatusResponse\"C\202\323\344\223\002=\022\020" +
+ "/v1/status/tasksZ)\022\'/v1/status/tasks/obs" +
+ "erve/{observe=true}0\001BF\n\030io.gitpod.super" +
+ "visor.apiZ*github.com/gitpod-io/gitpod/s" +
+ "upervisor/apib\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
@@ -13860,7 +14010,7 @@ public io.gitpod.supervisor.api.Status.TaskPresentation getDefaultInstanceForTyp
internal_static_supervisor_IDEStatusResponse_DesktopStatus_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor,
- new java.lang.String[] { "Link", "Label", });
+ new java.lang.String[] { "Link", "Label", "ClientID", });
internal_static_supervisor_ContentStatusRequest_descriptor =
getDescriptor().getMessageTypes().get(4);
internal_static_supervisor_ContentStatusRequest_fieldAccessorTable = new
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/StatusServiceGrpc.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/StatusServiceGrpc.java
index 839fd68daae264..397266de54b431 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/StatusServiceGrpc.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/StatusServiceGrpc.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalOuterClass.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalOuterClass.java
index bc26546c122449..8169d0798541be 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalOuterClass.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalOuterClass.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalServiceGrpc.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalServiceGrpc.java
index 328b5af6480fa6..146dbd8c3e6bad 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalServiceGrpc.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TerminalServiceGrpc.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Token.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Token.java
index e6f68b54209dfa..8a5bea0aad54ad 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Token.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Token.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TokenServiceGrpc.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TokenServiceGrpc.java
index 300af3cc0e76f0..51aadf0d13941a 100644
--- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TokenServiceGrpc.java
+++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/TokenServiceGrpc.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
+// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
diff --git a/components/supervisor-api/status.proto b/components/supervisor-api/status.proto
index a312b68f6a3026..0b16a90a0da789 100644
--- a/components/supervisor-api/status.proto
+++ b/components/supervisor-api/status.proto
@@ -90,6 +90,7 @@ message IDEStatusResponse {
message DesktopStatus {
string link = 1;
string label = 2;
+ string clientID = 3;
}
DesktopStatus desktop = 2;
diff --git a/components/supervisor/frontend/src/index.ts b/components/supervisor/frontend/src/index.ts
index 9b75fe222b595e..ffa333f2c497d3 100644
--- a/components/supervisor/frontend/src/index.ts
+++ b/components/supervisor/frontend/src/index.ts
@@ -102,11 +102,12 @@ const toStop = new DisposableCollection();
toStop.push({ dispose: () => window.removeEventListener('message', hideDesktopIdeEventListener) });
let isDesktopIde: undefined | boolean = undefined;
- let ideStatus: undefined | { desktop: { link: string, label: string } } = undefined;
+ let ideStatus: undefined | { desktop: { link: string, label: string, clientID?: string } } = undefined;
//#region current-frame
let current: HTMLElement = loading.frame;
let stopped = false;
+ let desktopRedirected = false;
const nextFrame = () => {
const instance = gitpodServiceClient.info.latestInstance;
if (instance) {
@@ -118,9 +119,22 @@ const toStop = new DisposableCollection();
if (isDesktopIde && !!ideStatus) {
loading.setState({
desktopIdeLink: ideStatus.desktop.link,
- desktopIdeLabel: ideStatus.desktop.label || "Open Desktop IDE"
+ desktopIdeLabel: ideStatus.desktop.label || "Open Desktop IDE",
+ desktopIdeClientID: ideStatus.desktop.clientID,
});
- // window.open(ideStatus.desktop.link);
+ if (!desktopRedirected) {
+ desktopRedirected = true;
+ try {
+ const desktopLink = new URL(ideStatus.desktop.link)
+ // redirect only if points to desktop application
+ // don't navigate browser to another page
+ if (desktopLink.protocol != 'http:' && desktopLink.protocol != 'https:') {
+ window.location.href = ideStatus.desktop.link;
+ }
+ } catch (e) {
+ console.error('invalid desktop link:', e)
+ }
+ }
return loading.frame;
}
}
diff --git a/components/supervisor/pkg/supervisor/services.go b/components/supervisor/pkg/supervisor/services.go
index 09fd8a599e1dde..7cfec9700886d6 100644
--- a/components/supervisor/pkg/supervisor/services.go
+++ b/components/supervisor/pkg/supervisor/services.go
@@ -43,8 +43,9 @@ type RegisterableRESTService interface {
}
type DesktopIDEStatus struct {
- Link string `json:"link"`
- Label string `json:"label"`
+ Link string `json:"link"`
+ Label string `json:"label"`
+ ClientID string `json:"clientID,omitempty"`
}
type ideReadyState struct {
@@ -148,6 +149,7 @@ func (s *statusService) IDEStatus(ctx context.Context, req *api.IDEStatusRequest
if i != nil {
desktopStatus.Link = i.Link
desktopStatus.Label = i.Label
+ desktopStatus.ClientID = i.ClientID
}
ok = ok && okR
}
diff --git a/installer/pkg/components/server/ide/configmap.go b/installer/pkg/components/server/ide/configmap.go
index a0fbd736799fe6..fae96277b7b86b 100644
--- a/installer/pkg/components/server/ide/configmap.go
+++ b/installer/pkg/components/server/ide/configmap.go
@@ -23,9 +23,40 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
}
typeBrowser := "browser"
typeDesktop := "desktop"
+
+ codeDesktop := "code-desktop"
+ codeDesktopInsiders := "code-desktop-insiders"
+
+ intellij := "intellij"
+ goland := "goland"
+ pycharm := "pycharm"
+ phpstorm := "phpstorm"
idecfg := IDEConfig{
SupervisorImage: common.ImageName(ctx.Config.Repository, workspace.SupervisorImage, ctx.VersionManifest.Components.Workspace.Supervisor.Version),
IDEOptions: IDEOptions{
+ IDEClients: map[string]IDEClient{
+ "vscode": {
+ DefaultDesktopIDE: codeDesktop,
+ DesktopIDEs: []string{codeDesktop},
+ InstallationSteps: []string{
+ "If you don't see an open dialog by the browser, make sure you have VS Code installed on your machine, and then click ${OPEN_LINK_LABEL} below.",
+ },
+ },
+ "vscode-insiders": {
+ DefaultDesktopIDE: codeDesktopInsiders,
+ DesktopIDEs: []string{codeDesktopInsiders},
+ InstallationSteps: []string{
+ "If you don't see an open dialog by the browser, make sure you have VS Code Insiders installed on your machine, and then click ${OPEN_LINK_LABEL} below.",
+ },
+ },
+ "jetbrains-gateway": {
+ DefaultDesktopIDE: intellij,
+ DesktopIDEs: []string{intellij, goland, pycharm, phpstorm},
+ InstallationSteps: []string{
+ "If you don't see an open dialog by the browser, make sure you have JetBrains Gateway with Gitpod Plugin installed on your machine, and then click ${OPEN_LINK_LABEL} below.",
+ },
+ },
+ },
Options: map[string]IDEOption{
"code": {
OrderKey: pointer.String("00"),
@@ -44,14 +75,14 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Image: common.ImageName(ctx.Config.Repository, ide.CodeIDEImage, ctx.VersionManifest.Components.Workspace.CodeImage.Version),
ResolveImageDigest: pointer.Bool(true),
},
- "code-desktop": {
+ codeDesktop: {
OrderKey: pointer.String("02"),
Title: "VS Code",
Type: typeDesktop,
Logo: getIdeLogoPath("vscode"),
Image: common.ImageName(ctx.Config.Repository, ide.CodeDesktopIDEImage, ctx.VersionManifest.Components.Workspace.DesktopIdeImages.CodeDesktopImage.Version),
},
- "code-desktop-insiders": {
+ codeDesktopInsiders: {
OrderKey: pointer.String("03"),
Title: "VS Code",
Type: typeDesktop,
@@ -60,7 +91,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Label: pointer.String("Insiders"),
Image: common.ImageName(ctx.Config.Repository, ide.CodeDesktopInsidersIDEImage, ctx.VersionManifest.Components.Workspace.DesktopIdeImages.CodeDesktopImageInsiders.Version),
},
- "intellij": {
+ intellij: {
OrderKey: pointer.String("04"),
Title: "IntelliJ IDEA",
Type: typeDesktop,
@@ -68,7 +99,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Notes: []string{"While in beta, when you open a workspace with IntelliJ IDEA you will need to use the password “gitpod”."},
Image: common.ImageName(ctx.Config.Repository, ide.IntelliJDesktopIDEImage, ctx.VersionManifest.Components.Workspace.DesktopIdeImages.IntelliJImage.Version),
},
- "goland": {
+ goland: {
OrderKey: pointer.String("05"),
Title: "GoLand",
Type: typeDesktop,
@@ -76,7 +107,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Notes: []string{"While in beta, when you open a workspace with GoLand you will need to use the password “gitpod”."},
Image: common.ImageName(ctx.Config.Repository, ide.GoLandDesktopIdeImage, ctx.VersionManifest.Components.Workspace.DesktopIdeImages.GoLandImage.Version),
},
- "pycharm": {
+ pycharm: {
OrderKey: pointer.String("06"),
Title: "PyCharm",
Type: typeDesktop,
@@ -84,7 +115,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Notes: []string{"While in beta, when you open a workspace with PyCharm you will need to use the password “gitpod”."},
Image: common.ImageName(ctx.Config.Repository, ide.PyCharmDesktopIdeImage, ctx.VersionManifest.Components.Workspace.DesktopIdeImages.PyCharmImage.Version),
},
- "phpstorm": {
+ phpstorm: {
OrderKey: pointer.String("07"),
Title: "PhpStorm",
Type: typeDesktop,
@@ -94,7 +125,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
},
},
DefaultIDE: "code",
- DefaultDesktopIDE: "code-desktop",
+ DefaultDesktopIDE: codeDesktop,
},
}
diff --git a/installer/pkg/components/server/ide/types.go b/installer/pkg/components/server/ide/types.go
index 4cd3cd631ae673..68114a7b1312d8 100644
--- a/installer/pkg/components/server/ide/types.go
+++ b/installer/pkg/components/server/ide/types.go
@@ -17,6 +17,7 @@ type IDEOptions struct {
Options map[string]IDEOption `json:"options"`
DefaultIDE string `json:"defaultIde"`
DefaultDesktopIDE string `json:"defaultDesktopIde"`
+ IDEClients map[string]IDEClient `json:"clients,omitempty"`
}
// IDEOption interface from components/gitpod-protocol/src/ide-protocol.ts
@@ -32,3 +33,10 @@ type IDEOption struct {
Image string `json:"image"`
ResolveImageDigest *bool `json:"resolveImageDigest,omitempty"`
}
+
+// IDEClient interface from components/gitpod-protocol/src/ide-protocol.ts
+type IDEClient struct {
+ DefaultDesktopIDE string `json:"defaultDesktopIDE,omitempty"`
+ DesktopIDEs []string `json:"desktopIDEs,omitempty"`
+ InstallationSteps []string `json:"installationSteps,omitempty"`
+}