From b01183bda2466199047bd59a9dd96f9ba7359f37 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 26 Nov 2020 12:02:58 +0100 Subject: [PATCH] Add extension source to forwarded ports Part of microsoft/vscode-remote-release#4021 --- .../api/browser/mainThreadTunnelService.ts | 4 ++-- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostTunnelService.ts | 5 +++-- .../api/node/extHostTunnelService.ts | 5 +++-- .../contrib/remote/browser/tunnelView.ts | 22 +++++++++++++++---- .../remote/common/remoteExplorerService.ts | 12 +++++----- 7 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTunnelService.ts b/src/vs/workbench/api/browser/mainThreadTunnelService.ts index 25723794d5f..ac9b8356202 100644 --- a/src/vs/workbench/api/browser/mainThreadTunnelService.ts +++ b/src/vs/workbench/api/browser/mainThreadTunnelService.ts @@ -26,8 +26,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun this._register(tunnelService.onTunnelClosed(() => this._proxy.$onDidTunnelsChange())); } - async $openTunnel(tunnelOptions: TunnelOptions): Promise { - const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label); + async $openTunnel(tunnelOptions: TunnelOptions, source: string): Promise { + const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source); if (tunnel) { return TunnelDto.fromServiceTunnel(tunnel); } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index b2452d35d20..ac04adb6547 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -859,7 +859,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, openTunnel: (forward: vscode.TunnelOptions) => { checkProposedApiEnabled(extension); - return extHostTunnelService.openTunnel(forward).then(value => { + return extHostTunnelService.openTunnel(extension, forward).then(value => { if (!value) { throw new Error('cannot open tunnel'); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 69f4f321c84..b71262bcfec 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -955,7 +955,7 @@ export interface MainThreadWindowShape extends IDisposable { } export interface MainThreadTunnelServiceShape extends IDisposable { - $openTunnel(tunnelOptions: TunnelOptions): Promise; + $openTunnel(tunnelOptions: TunnelOptions, source: string | undefined): Promise; $closeTunnel(remote: { host: string, port: number }): Promise; $getTunnels(): Promise; $setTunnelProvider(): Promise; diff --git a/src/vs/workbench/api/common/extHostTunnelService.ts b/src/vs/workbench/api/common/extHostTunnelService.ts index 7444920d47d..29a50ae2700 100644 --- a/src/vs/workbench/api/common/extHostTunnelService.ts +++ b/src/vs/workbench/api/common/extHostTunnelService.ts @@ -10,6 +10,7 @@ import { RemoteTunnel, TunnelCreationOptions, TunnelOptions } from 'vs/platform/ import { IDisposable } from 'vs/base/common/lifecycle'; import { Emitter } from 'vs/base/common/event'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; export interface TunnelDto { remoteAddress: { port: number, host: string }; @@ -32,7 +33,7 @@ export interface Tunnel extends vscode.Disposable { export interface IExtHostTunnelService extends ExtHostTunnelServiceShape { readonly _serviceBrand: undefined; - openTunnel(forward: TunnelOptions): Promise; + openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise; getTunnels(): Promise; onDidChangeTunnels: vscode.Event; setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise; @@ -51,7 +52,7 @@ export class ExtHostTunnelService implements IExtHostTunnelService { this._proxy = extHostRpc.getProxy(MainContext.MainThreadTunnelService); } - async openTunnel(forward: TunnelOptions): Promise { + async openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise { return undefined; } async getTunnels(): Promise { diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts index de8123426f7..922451d1079 100644 --- a/src/vs/workbench/api/node/extHostTunnelService.ts +++ b/src/vs/workbench/api/node/extHostTunnelService.ts @@ -17,6 +17,7 @@ import { IExtHostTunnelService, TunnelDto } from 'vs/workbench/api/common/extHos import { asPromise } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; import { TunnelOptions, TunnelCreationOptions } from 'vs/platform/remote/common/tunnel'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; class ExtensionTunnel implements vscode.Tunnel { private _onDispose: Emitter = new Emitter(); @@ -53,8 +54,8 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe } } - async openTunnel(forward: TunnelOptions): Promise { - const tunnel = await this._proxy.$openTunnel(forward); + async openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise { + const tunnel = await this._proxy.$openTunnel(forward, extension.displayName); if (tunnel) { const disposableTunnel: vscode.Tunnel = new ExtensionTunnel(tunnel.remoteAddress, tunnel.localAddress, () => { return this._proxy.$closeTunnel(tunnel.remoteAddress); diff --git a/src/vs/workbench/contrib/remote/browser/tunnelView.ts b/src/vs/workbench/contrib/remote/browser/tunnelView.ts index 7b249a140f9..00b4171a24b 100644 --- a/src/vs/workbench/contrib/remote/browser/tunnelView.ts +++ b/src/vs/workbench/contrib/remote/browser/tunnelView.ts @@ -384,7 +384,7 @@ interface ITunnelGroup { class TunnelItem implements ITunnelItem { static createFromTunnel(tunnel: Tunnel, type: TunnelType = TunnelType.Forwarded, closeable?: boolean) { - return new TunnelItem(type, tunnel.remoteHost, tunnel.remotePort, tunnel.localAddress, tunnel.localPort, closeable === undefined ? tunnel.closeable : closeable, tunnel.name, tunnel.description ?? tunnel.runningProcess); + return new TunnelItem(type, tunnel.remoteHost, tunnel.remotePort, tunnel.localAddress, tunnel.localPort, closeable === undefined ? tunnel.closeable : closeable, tunnel.name, tunnel.description ?? tunnel.runningProcess, tunnel.source); } constructor( @@ -396,6 +396,7 @@ class TunnelItem implements ITunnelItem { public closeable?: boolean, public name?: string, private _description?: string, + private source?: string ) { } get label(): string { if (this.name) { @@ -435,11 +436,24 @@ class TunnelItem implements ITunnelItem { } get description(): string | undefined { + const description: string[] = []; + + if (this.name && this.localAddress) { + description.push(nls.localize('remote.tunnelsView.forwardedPortDescription0', "{0} \u2192 {1}", this.remotePort, TunnelItem.compactLongAddress(this.localAddress))); + } + if (this._description) { - return this._description; - } else if (this.name && this.localAddress) { - return nls.localize('remote.tunnelsView.forwardedPortDescription0', "{0} \u2192 {1}", this.remotePort, TunnelItem.compactLongAddress(this.localAddress)); + description.push(this._description); + } + + if (this.source) { + description.push(this.source); + } + + if (description.length > 0) { + return description.join(' \u2022 '); } + return undefined; } } diff --git a/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/src/vs/workbench/services/remote/common/remoteExplorerService.ts index 63808d13255..189e1ba5501 100644 --- a/src/vs/workbench/services/remote/common/remoteExplorerService.ts +++ b/src/vs/workbench/services/remote/common/remoteExplorerService.ts @@ -48,6 +48,7 @@ export interface Tunnel { description?: string; closeable?: boolean; runningProcess: string | undefined; + source?: string; } export function makeAddress(host: string, port: number): string { @@ -177,7 +178,7 @@ export class TunnelModel extends Disposable { } } - async forward(remote: { host: string, port: number }, local?: number, name?: string): Promise { + async forward(remote: { host: string, port: number }, local?: number, name?: string, source?: string): Promise { const existingTunnel = mapHasAddressLocalhostOrAllInterfaces(this.forwarded, remote.host, remote.port); if (!existingTunnel) { const authority = this.environmentService.remoteAuthority; @@ -194,7 +195,8 @@ export class TunnelModel extends Disposable { name: name, closeable: true, localAddress: tunnel.localAddress, - runningProcess: mapHasAddressLocalhostOrAllInterfaces(this._candidates, remote.host, remote.port)?.detail + runningProcess: mapHasAddressLocalhostOrAllInterfaces(this._candidates, remote.host, remote.port)?.detail, + source }; const key = makeAddress(remote.host, remote.port); this.forwarded.set(key, newForward); @@ -313,7 +315,7 @@ export interface IRemoteExplorerService { onDidChangeEditable: Event; setEditable(tunnelItem: ITunnelItem | undefined, data: IEditableData | null): void; getEditableData(tunnelItem: ITunnelItem | undefined): IEditableData | undefined; - forward(remote: { host: string, port: number }, localPort?: number, name?: string): Promise; + forward(remote: { host: string, port: number }, localPort?: number, name?: string, source?: string): Promise; close(remote: { host: string, port: number }): Promise; setTunnelInformation(tunnelInformation: TunnelInformation | undefined): void; setCandidateFilter(filter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined): IDisposable; @@ -360,8 +362,8 @@ class RemoteExplorerService implements IRemoteExplorerService { return this._tunnelModel; } - forward(remote: { host: string, port: number }, local?: number, name?: string): Promise { - return this.tunnelModel.forward(remote, local, name); + forward(remote: { host: string, port: number }, local?: number, name?: string, source?: string): Promise { + return this.tunnelModel.forward(remote, local, name, source); } close(remote: { host: string, port: number }): Promise { -- GitLab