mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Add hybrid automatic port detection (#178687)
* Hybrid port detection * Use correct source for autoforwarded * Watch for port closure in output forwarder * Update setting description
This commit is contained in:
parent
fdc9c7cccb
commit
d4d0d2a3e4
|
@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
|
|||
import { MainThreadTunnelServiceShape, MainContext, ExtHostContext, ExtHostTunnelServiceShape, CandidatePortSource, PortAttributesProviderSelector, TunnelDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { TunnelDtoConverter } from 'vs/workbench/api/common/extHostTunnelService';
|
||||
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||
import { CandidatePort, IRemoteExplorerService, makeAddress, PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_OUTPUT, PORT_AUTO_SOURCE_SETTING_PROCESS, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { CandidatePort, IRemoteExplorerService, makeAddress, PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_OUTPUT, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, RemoteTunnel, ProvidedPortAttributes, PortAttributesProvider, TunnelProtocol } from 'vs/platform/tunnel/common/tunnel';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
|
@ -42,7 +42,7 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
|
|||
|
||||
private processFindingEnabled(): boolean {
|
||||
return (!!this.configurationService.getValue(PORT_AUTO_FORWARD_SETTING) || this.tunnelService.hasTunnelProvider)
|
||||
&& (this.configurationService.getValue(PORT_AUTO_SOURCE_SETTING) === PORT_AUTO_SOURCE_SETTING_PROCESS);
|
||||
&& (this.configurationService.getValue(PORT_AUTO_SOURCE_SETTING) !== PORT_AUTO_SOURCE_SETTING_OUTPUT);
|
||||
}
|
||||
|
||||
async $setRemoteTunnelService(processId: number): Promise<void> {
|
||||
|
|
|
@ -6,7 +6,7 @@ import * as nls from 'vs/nls';
|
|||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { Extensions, IViewContainersRegistry, IViewsRegistry, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { Attributes, AutoTunnelSource, IRemoteExplorerService, makeAddress, mapHasAddressLocalhostOrAllInterfaces, OnPortForward, PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_OUTPUT, PORT_AUTO_SOURCE_SETTING_PROCESS, TUNNEL_VIEW_CONTAINER_ID, TUNNEL_VIEW_ID } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { Attributes, AutoTunnelSource, IRemoteExplorerService, makeAddress, mapHasAddressLocalhostOrAllInterfaces, OnPortForward, PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_HYBRID, PORT_AUTO_SOURCE_SETTING_OUTPUT, PORT_AUTO_SOURCE_SETTING_PROCESS, TUNNEL_VIEW_CONTAINER_ID, TUNNEL_VIEW_ID, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { forwardedPortsViewEnabled, ForwardPortAction, OpenPortInBrowserAction, TunnelPanel, TunnelPanelDescriptor, TunnelViewModel, OpenPortInPreviewAction, openPreviewEnabledContext } from 'vs/workbench/contrib/remote/browser/tunnelView';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
@ -202,7 +202,10 @@ export class AutomaticPortForwarding extends Disposable implements IWorkbenchCon
|
|||
} else {
|
||||
const useProc = () => (configurationService.getValue(PORT_AUTO_SOURCE_SETTING) === PORT_AUTO_SOURCE_SETTING_PROCESS);
|
||||
if (useProc()) {
|
||||
this._register(new ProcAutomaticPortForwarding(configurationService, remoteExplorerService, notificationService,
|
||||
this._register(new ProcAutomaticPortForwarding(false, configurationService, remoteExplorerService, notificationService,
|
||||
openerService, externalOpenerService, tunnelService, hostService, logService, contextKeyService));
|
||||
} else if (configurationService.getValue(PORT_AUTO_SOURCE_SETTING) === PORT_AUTO_SOURCE_SETTING_HYBRID) {
|
||||
this._register(new ProcAutomaticPortForwarding(true, configurationService, remoteExplorerService, notificationService,
|
||||
openerService, externalOpenerService, tunnelService, hostService, logService, contextKeyService));
|
||||
}
|
||||
this._register(new OutputAutomaticPortForwarding(terminalService, notificationService, openerService, externalOpenerService,
|
||||
|
@ -433,6 +436,10 @@ class OutputAutomaticPortForwarding extends Disposable {
|
|||
this.tryStartStopUrlFinder();
|
||||
}));
|
||||
this.tryStartStopUrlFinder();
|
||||
|
||||
if (configurationService.getValue(PORT_AUTO_SOURCE_SETTING) === PORT_AUTO_SOURCE_SETTING_HYBRID) {
|
||||
this._register(this.tunnelService.onTunnelClosed(tunnel => this.notifier.hide([tunnel.port])));
|
||||
}
|
||||
}
|
||||
|
||||
private tryStartStopUrlFinder() {
|
||||
|
@ -484,6 +491,7 @@ class ProcAutomaticPortForwarding extends Disposable {
|
|||
private portsFeatures: IDisposable | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly unforwardOnly: boolean,
|
||||
private readonly configurationService: IConfigurationService,
|
||||
readonly remoteExplorerService: IRemoteExplorerService,
|
||||
readonly notificationService: INotificationService,
|
||||
|
@ -613,12 +621,24 @@ class ProcAutomaticPortForwarding extends Disposable {
|
|||
|
||||
private async handleCandidateUpdate(removed: Map<string, { host: string; port: number }>) {
|
||||
const removedPorts: number[] = [];
|
||||
let autoForwarded: Set<string>;
|
||||
if (this.unforwardOnly) {
|
||||
autoForwarded = new Set();
|
||||
for (const entry of this.remoteExplorerService.tunnelModel.forwarded.entries()) {
|
||||
if (entry[1].source.source === TunnelSource.Auto) {
|
||||
autoForwarded.add(entry[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
autoForwarded = this.autoForwarded;
|
||||
}
|
||||
|
||||
for (const removedPort of removed) {
|
||||
const key = removedPort[0];
|
||||
const value = removedPort[1];
|
||||
if (this.autoForwarded.has(key)) {
|
||||
if (autoForwarded.has(key)) {
|
||||
await this.remoteExplorerService.close(value);
|
||||
this.autoForwarded.delete(key);
|
||||
autoForwarded.delete(key);
|
||||
removedPorts.push(value.port);
|
||||
} else if (this.notifiedOnly.has(key)) {
|
||||
this.notifiedOnly.delete(key);
|
||||
|
@ -628,6 +648,10 @@ class ProcAutomaticPortForwarding extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.unforwardOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (removedPorts.length > 0) {
|
||||
await this.notifier.hide(removedPorts);
|
||||
}
|
||||
|
|
|
@ -324,11 +324,12 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
|
|||
},
|
||||
'remote.autoForwardPortsSource': {
|
||||
type: 'string',
|
||||
markdownDescription: localize('remote.autoForwardPortsSource', "Sets the source from which ports are automatically forwarded when {0} is true. On Windows and Mac remotes, the `process` option has no effect and `output` will be used. Requires a reload to take effect.", '`#remote.autoForwardPorts#`'),
|
||||
enum: ['process', 'output'],
|
||||
markdownDescription: localize('remote.autoForwardPortsSource', "Sets the source from which ports are automatically forwarded when {0} is true. On Windows and Mac remotes, the `process` and `hybrid` options have no effect and `output` will be used. Requires a reload to take effect.", '`#remote.autoForwardPorts#`'),
|
||||
enum: ['process', 'output', 'hybrid'],
|
||||
enumDescriptions: [
|
||||
localize('remote.autoForwardPortsSource.process', "Ports will be automatically forwarded when discovered by watching for processes that are started and include a port."),
|
||||
localize('remote.autoForwardPortsSource.output', "Ports will be automatically forwarded when discovered by reading terminal and debug output. Not all processes that use ports will print to the integrated terminal or debug console, so some ports will be missed. Ports forwarded based on output will not be \"un-forwarded\" until reload or until the port is closed by the user in the Ports view.")
|
||||
localize('remote.autoForwardPortsSource.output', "Ports will be automatically forwarded when discovered by reading terminal and debug output. Not all processes that use ports will print to the integrated terminal or debug console, so some ports will be missed. Ports forwarded based on output will not be \"un-forwarded\" until reload or until the port is closed by the user in the Ports view."),
|
||||
localize('remote.autoForwardPortsSource.hybrid', "Ports will be automatically forwarded when discovered by reading terminal and debug output. Not all processes that use ports will print to the integrated terminal or debug console, so some ports will be missed. Ports will be \"un-forwarded\" by watching for processes that listen on that port to be terminated.")
|
||||
],
|
||||
default: 'process'
|
||||
},
|
||||
|
|
|
@ -35,6 +35,7 @@ export const PORT_AUTO_FORWARD_SETTING = 'remote.autoForwardPorts';
|
|||
export const PORT_AUTO_SOURCE_SETTING = 'remote.autoForwardPortsSource';
|
||||
export const PORT_AUTO_SOURCE_SETTING_PROCESS = 'process';
|
||||
export const PORT_AUTO_SOURCE_SETTING_OUTPUT = 'output';
|
||||
export const PORT_AUTO_SOURCE_SETTING_HYBRID = 'hybrid';
|
||||
|
||||
export enum TunnelType {
|
||||
Candidate = 'Candidate',
|
||||
|
|
Loading…
Reference in a new issue