Move tunnel features (#140620)

This commit is contained in:
Alex Ross 2022-01-13 12:13:40 +01:00 committed by GitHub
parent 86eb34a268
commit c393048b98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 50 deletions

View file

@ -227,6 +227,26 @@ export function activate(context: vscode.ExtensionContext) {
const port = (<net.AddressInfo>proxyServer.address()).port;
outputChannel.appendLine(`Going through proxy at port ${port}`);
const r: vscode.ResolverResult = new vscode.ResolvedAuthority('127.0.0.1', port, connectionToken);
r.tunnelFeatures = {
elevation: true,
privacyOptions: vscode.workspace.getConfiguration('testresolver').get('supportPublicPorts') ? [
{
id: 'public',
label: 'Public',
themeIcon: 'eye'
},
{
id: 'other',
label: 'Other',
themeIcon: 'circuit-board'
},
{
id: 'private',
label: 'Private',
themeIcon: 'eye-closed'
}
] : []
};
res(r);
});
context.subscriptions.push({
@ -253,27 +273,6 @@ export function activate(context: vscode.ExtensionContext) {
}, (progress) => doResolve(_authority, progress));
},
tunnelFactory,
tunnelFeatures: {
elevation: true,
public: !!vscode.workspace.getConfiguration('testresolver').get('supportPublicPorts'),
privacyOptions: vscode.workspace.getConfiguration('testresolver').get('supportPublicPorts') ? [
{
id: 'public',
label: 'Public',
themeIcon: 'eye'
},
{
id: 'other',
label: 'Other',
themeIcon: 'circuit-board'
},
{
id: 'private',
label: 'Private',
themeIcon: 'eye-closed'
}
] : []
},
showCandidatePort
});
context.subscriptions.push(authorityResolverDisposable);

View file

@ -6,6 +6,7 @@
import { Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { TunnelPrivacy } from 'vs/platform/remote/common/tunnel';
export const IRemoteAuthorityResolverService = createDecorator<IRemoteAuthorityResolverService>('remoteAuthorityResolverService');
@ -30,6 +31,11 @@ export interface TunnelDescription {
}
export interface TunnelInformation {
environmentTunnels?: TunnelDescription[];
features?: {
elevation: boolean;
public?: boolean;
privacyOptions: TunnelPrivacy[];
}
}
export interface ResolverResult {

View file

@ -60,7 +60,7 @@ export interface TunnelProviderFeatures {
/**
* @deprecated
*/
public: boolean;
public?: boolean;
privacyOptions: TunnelPrivacy[];
}
@ -132,7 +132,8 @@ export interface ITunnelService {
canTunnel(uri: URI): boolean;
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
closeTunnel(remoteHost: string, remotePort: number): Promise<void>;
setTunnelProvider(provider: ITunnelProvider | undefined, features: TunnelProviderFeatures): IDisposable;
setTunnelProvider(provider: ITunnelProvider | undefined): IDisposable;
setTunnelFeatures(features: TunnelProviderFeatures): void;
}
export function extractLocalHostUriMetaDataForPortMapping(uri: URI): { address: string, port: number; } | undefined {
@ -189,7 +190,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
return !!this._tunnelProvider;
}
setTunnelProvider(provider: ITunnelProvider | undefined, features: TunnelProviderFeatures): IDisposable {
setTunnelProvider(provider: ITunnelProvider | undefined): IDisposable {
this._tunnelProvider = provider;
if (!provider) {
// clear features
@ -200,8 +201,7 @@ export abstract class AbstractTunnelService implements ITunnelService {
dispose: () => { }
};
}
this._canElevate = features.elevation;
this._privacyOptions = features.privacyOptions;
this._onAddedTunnelProvider.fire();
return {
dispose: () => {
@ -212,6 +212,11 @@ export abstract class AbstractTunnelService implements ITunnelService {
};
}
setTunnelFeatures(features: TunnelProviderFeatures): void {
this._canElevate = features.elevation;
this._privacyOptions = features.privacyOptions;
}
public get canElevate(): boolean {
return this._canElevate;
}

View file

@ -164,7 +164,7 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
this.remoteExplorerService.onFoundNewCandidates(candidates);
}
async $setTunnelProvider(features: TunnelProviderFeatures): Promise<void> {
async $setTunnelProvider(features?: TunnelProviderFeatures): Promise<void> {
const tunnelProvider: ITunnelProvider = {
forwardPort: (tunnelOptions: TunnelOptions, tunnelCreationOptions: TunnelCreationOptions) => {
const forward = this._proxy.$forwardPort(tunnelOptions, tunnelCreationOptions);
@ -189,7 +189,10 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
});
}
};
this.tunnelService.setTunnelProvider(tunnelProvider, features);
this.tunnelService.setTunnelProvider(tunnelProvider);
if (features) {
this.tunnelService.setTunnelFeatures(features);
}
}
async $setCandidateFilter(): Promise<void> {

View file

@ -1205,7 +1205,7 @@ export interface MainThreadTunnelServiceShape extends IDisposable {
$openTunnel(tunnelOptions: TunnelOptions, source: string | undefined): Promise<TunnelDto | undefined>;
$closeTunnel(remote: { host: string, port: number; }): Promise<void>;
$getTunnels(): Promise<TunnelDescription[]>;
$setTunnelProvider(features: TunnelProviderFeatures): Promise<void>;
$setTunnelProvider(features?: TunnelProviderFeatures): Promise<void>;
$setRemoteTunnelService(processId: number): Promise<void>;
$setCandidateFilter(): Promise<void>;
$onFoundNewCandidates(candidates: CandidatePort[]): Promise<void>;

View file

@ -692,7 +692,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
}
try {
this._register(await this._extHostTunnelService.setTunnelExtensionFunctions(resolver));
this._register(await this._extHostTunnelService.setTunnelFactory(resolver));
performance.mark(`code/extHost/willResolveAuthority/${authorityPrefix}`);
const result = await resolver.resolve(remoteAuthority, { resolveAttempt });
performance.mark(`code/extHost/didResolveAuthorityOK/${authorityPrefix}`);
@ -715,7 +715,10 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
value: {
authority,
options,
tunnelInformation: { environmentTunnels: result.environmentTunnels }
tunnelInformation: {
environmentTunnels: result.environmentTunnels,
features: result.tunnelFeatures
}
}
};
} catch (err) {

View file

@ -55,7 +55,7 @@ export interface IExtHostTunnelService extends ExtHostTunnelServiceShape {
openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise<vscode.Tunnel | undefined>;
getTunnels(): Promise<vscode.TunnelDescription[]>;
onDidChangeTunnels: vscode.Event<void>;
setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable>;
setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable>;
registerPortsAttributesProvider(portSelector: { pid?: number, portRange?: [number, number], commandMatcher?: RegExp }, provider: vscode.PortAttributesProvider): IDisposable;
}
@ -79,7 +79,7 @@ export class ExtHostTunnelService implements IExtHostTunnelService {
async getTunnels(): Promise<vscode.TunnelDescription[]> {
return [];
}
async setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
async setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
return { dispose: () => { } };
}
registerPortsAttributesProvider(portSelector: { pid?: number, portRange?: [number, number] }, provider: vscode.PortAttributesProvider) {

View file

@ -283,7 +283,7 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
}
}
async setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
async setTunnelFactory(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
// Do not wait for any of the proxy promises here.
// It will delay startup and there is nothing that needs to be waited for.
if (provider) {
@ -312,11 +312,13 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
];
}
this._proxy.$setTunnelProvider({
const tunnelFeatures = provider.tunnelFeatures ? {
elevation: !!provider.tunnelFeatures?.elevation,
public: !!provider.tunnelFeatures?.public,
privacyOptions
});
} : undefined;
this._proxy.$setTunnelProvider(tunnelFeatures);
}
} else {
this._forwardPortProvider = undefined;

View file

@ -74,12 +74,16 @@ export class TunnelFactoryContribution extends Disposable implements IWorkbenchC
};
return remoteTunnel;
}
}, {
elevation: !!environmentService.options?.tunnelProvider?.features?.elevation,
public: !!environmentService.options?.tunnelProvider?.features?.public,
privacyOptions
}));
remoteExplorerService.setTunnelInformation(undefined);
const tunnelInformation = environmentService.options?.tunnelProvider?.features ?
{
features: {
elevation: !!environmentService.options?.tunnelProvider?.features?.elevation,
public: !!environmentService.options?.tunnelProvider?.features?.public,
privacyOptions
}
} : undefined;
remoteExplorerService.setTunnelInformation(tunnelInformation);
}
}

View file

@ -920,7 +920,7 @@ class RemoteExplorerService implements IRemoteExplorerService {
constructor(
@IStorageService private readonly storageService: IStorageService,
@ITunnelService tunnelService: ITunnelService,
@ITunnelService private readonly tunnelService: ITunnelService,
@IConfigurationService configurationService: IConfigurationService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService,
@ -960,6 +960,9 @@ class RemoteExplorerService implements IRemoteExplorerService {
}
setTunnelInformation(tunnelInformation: TunnelInformation | undefined): void {
if (tunnelInformation?.features) {
this.tunnelService.setTunnelFeatures(tunnelInformation.features);
}
this.tunnelModel.addEnvironmentTunnels(tunnelInformation?.environmentTunnels);
}

View file

@ -87,6 +87,13 @@ declare module 'vscode' {
*/
environmentTunnels?: TunnelDescription[];
tunnelFeatures?: {
elevation: boolean;
/**
* One of the the options must have the ID "private".
*/
privacyOptions: TunnelPrivacy[];
};
}
export interface TunnelCreationOptions {
@ -146,18 +153,11 @@ declare module 'vscode' {
showCandidatePort?: (host: string, port: number, detail: string) => Thenable<boolean>;
/**
* Lets the resolver declare which tunnel factory features it supports.
* UNDER DISCUSSION! MAY CHANGE SOON.
* @deprecated Return tunnelFeatures as part of the resolver result in tunnelInformation.
*/
tunnelFeatures?: {
elevation: boolean;
/**
* @deprecated Use privacy instead
*/
public: boolean;
/**
* One of the the options must have the ID "private".
*/
privacyOptions: TunnelPrivacy[];
};