@theia/remote 1.47.1 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/electron-browser/port-forwarding/port-forwading-contribution.d.ts +6 -0
- package/lib/electron-browser/port-forwarding/port-forwading-contribution.d.ts.map +1 -0
- package/lib/electron-browser/port-forwarding/port-forwading-contribution.js +40 -0
- package/lib/electron-browser/port-forwarding/port-forwading-contribution.js.map +1 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-service.d.ts +19 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-service.d.ts.map +1 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-service.js +76 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-service.js.map +1 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-widget.d.ts +17 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-widget.d.ts.map +1 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-widget.js +125 -0
- package/lib/electron-browser/port-forwarding/port-forwarding-widget.js.map +1 -0
- package/lib/electron-browser/remote-frontend-contribution.d.ts.map +1 -1
- package/lib/electron-browser/remote-frontend-contribution.js +1 -3
- package/lib/electron-browser/remote-frontend-contribution.js.map +1 -1
- package/lib/electron-browser/remote-frontend-module.d.ts +1 -0
- package/lib/electron-browser/remote-frontend-module.d.ts.map +1 -1
- package/lib/electron-browser/remote-frontend-module.js +16 -2
- package/lib/electron-browser/remote-frontend-module.js.map +1 -1
- package/lib/electron-browser/remote-registry-contribution.d.ts +1 -1
- package/lib/electron-browser/remote-registry-contribution.d.ts.map +1 -1
- package/lib/electron-browser/remote-registry-contribution.js +6 -3
- package/lib/electron-browser/remote-registry-contribution.js.map +1 -1
- package/lib/electron-common/remote-port-forwarding-provider.d.ts +11 -0
- package/lib/electron-common/remote-port-forwarding-provider.d.ts.map +1 -0
- package/lib/electron-common/remote-port-forwarding-provider.js +21 -0
- package/lib/electron-common/remote-port-forwarding-provider.js.map +1 -0
- package/lib/electron-node/remote-backend-module.d.ts.map +1 -1
- package/lib/electron-node/remote-backend-module.js +5 -0
- package/lib/electron-node/remote-backend-module.js.map +1 -1
- package/lib/electron-node/remote-port-forwarding-provider.d.ts +11 -0
- package/lib/electron-node/remote-port-forwarding-provider.d.ts.map +1 -0
- package/lib/electron-node/remote-port-forwarding-provider.js +53 -0
- package/lib/electron-node/remote-port-forwarding-provider.js.map +1 -0
- package/lib/electron-node/remote-types.d.ts +11 -1
- package/lib/electron-node/remote-types.d.ts.map +1 -1
- package/lib/electron-node/setup/remote-setup-service.d.ts +5 -1
- package/lib/electron-node/setup/remote-setup-service.d.ts.map +1 -1
- package/lib/electron-node/setup/remote-setup-service.js +7 -2
- package/lib/electron-node/setup/remote-setup-service.js.map +1 -1
- package/lib/electron-node/ssh/remote-ssh-connection-provider.d.ts +1 -1
- package/lib/electron-node/ssh/remote-ssh-connection-provider.d.ts.map +1 -1
- package/lib/electron-node/ssh/remote-ssh-connection-provider.js +2 -2
- package/lib/electron-node/ssh/remote-ssh-connection-provider.js.map +1 -1
- package/package.json +6 -6
- package/src/electron-browser/port-forwarding/port-forwading-contribution.ts +33 -0
- package/src/electron-browser/port-forwarding/port-forwarding-service.ts +84 -0
- package/src/electron-browser/port-forwarding/port-forwarding-widget.tsx +140 -0
- package/src/electron-browser/remote-frontend-contribution.ts +1 -3
- package/src/electron-browser/remote-frontend-module.ts +22 -3
- package/src/electron-browser/remote-registry-contribution.ts +9 -6
- package/src/electron-browser/style/port-forwarding-widget.css +44 -0
- package/src/electron-common/remote-port-forwarding-provider.ts +29 -0
- package/src/electron-node/remote-backend-module.ts +6 -0
- package/src/electron-node/remote-port-forwarding-provider.ts +50 -0
- package/src/electron-node/remote-types.ts +14 -1
- package/src/electron-node/setup/remote-setup-service.ts +12 -3
- package/src/electron-node/ssh/remote-ssh-connection-provider.ts +2 -2
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { Command, CommandHandler, Emitter, Event } from '@theia/core';
|
|
18
18
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
|
-
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
|
20
|
-
import { WindowSearchParams } from '@theia/core/lib/common/window';
|
|
19
|
+
import { WindowService, WindowReloadOptions } from '@theia/core/lib/browser/window/window-service';
|
|
21
20
|
|
|
22
21
|
export const RemoteRegistryContribution = Symbol('RemoteRegistryContribution');
|
|
23
22
|
|
|
@@ -33,15 +32,19 @@ export abstract class AbstractRemoteRegistryContribution implements RemoteRegist
|
|
|
33
32
|
|
|
34
33
|
abstract registerRemoteCommands(registry: RemoteRegistry): void;
|
|
35
34
|
|
|
36
|
-
protected openRemote(port: string, newWindow: boolean): void {
|
|
35
|
+
protected openRemote(port: string, newWindow: boolean, workspace?: string): void {
|
|
37
36
|
const searchParams = new URLSearchParams(location.search);
|
|
38
37
|
const localPort = searchParams.get('localPort') || searchParams.get('port');
|
|
39
|
-
const options:
|
|
40
|
-
port
|
|
38
|
+
const options: WindowReloadOptions = {
|
|
39
|
+
search: { port }
|
|
41
40
|
};
|
|
42
41
|
if (localPort) {
|
|
43
|
-
options.localPort = localPort;
|
|
42
|
+
options.search!.localPort = localPort;
|
|
44
43
|
}
|
|
44
|
+
if (workspace) {
|
|
45
|
+
options.hash = workspace;
|
|
46
|
+
}
|
|
47
|
+
|
|
45
48
|
if (newWindow) {
|
|
46
49
|
this.windowService.openNewDefaultWindow(options);
|
|
47
50
|
} else {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2024 TypeFox and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
.port-table {
|
|
18
|
+
width: 100%;
|
|
19
|
+
margin: calc(var(--theia-ui-padding) * 2);
|
|
20
|
+
table-layout: fixed;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.port-table-header {
|
|
24
|
+
text-align: left;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.forward-port-button {
|
|
28
|
+
margin-left: 0;
|
|
29
|
+
width: 100%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.button-cell {
|
|
33
|
+
display: flex;
|
|
34
|
+
padding-right: var(--theia-ui-padding);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.forwarded-address:hover {
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
text-decoration: underline;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.port-edit-input-error {
|
|
43
|
+
outline-color: var(--theia-inputValidation-errorBorder);
|
|
44
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export const RemoteRemotePortForwardingProviderPath = '/remote/port-forwarding';
|
|
18
|
+
|
|
19
|
+
export const RemotePortForwardingProvider = Symbol('RemoteSSHConnectionProvider');
|
|
20
|
+
|
|
21
|
+
export interface ForwardedPort {
|
|
22
|
+
port: number;
|
|
23
|
+
address?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface RemotePortForwardingProvider {
|
|
27
|
+
forwardPort(connectionPort: number, portToForward: ForwardedPort): Promise<void>;
|
|
28
|
+
portRemoved(port: ForwardedPort): Promise<void>;
|
|
29
|
+
}
|
|
@@ -37,11 +37,17 @@ import { RemoteCopyContribution, RemoteCopyRegistry } from './setup/remote-copy-
|
|
|
37
37
|
import { MainCopyContribution } from './setup/main-copy-contribution';
|
|
38
38
|
import { RemoteNativeDependencyContribution } from './setup/remote-native-dependency-contribution';
|
|
39
39
|
import { AppNativeDependencyContribution } from './setup/app-native-dependency-contribution';
|
|
40
|
+
import { RemotePortForwardingProviderImpl } from './remote-port-forwarding-provider';
|
|
41
|
+
import { RemotePortForwardingProvider, RemoteRemotePortForwardingProviderPath } from '../electron-common/remote-port-forwarding-provider';
|
|
40
42
|
|
|
41
43
|
export const remoteConnectionModule = ConnectionContainerModule.create(({ bind, bindBackendService }) => {
|
|
42
44
|
bind(RemoteSSHConnectionProviderImpl).toSelf().inSingletonScope();
|
|
43
45
|
bind(RemoteSSHConnectionProvider).toService(RemoteSSHConnectionProviderImpl);
|
|
44
46
|
bindBackendService(RemoteSSHConnectionProviderPath, RemoteSSHConnectionProvider);
|
|
47
|
+
|
|
48
|
+
bind(RemotePortForwardingProviderImpl).toSelf().inSingletonScope();
|
|
49
|
+
bind(RemotePortForwardingProvider).toService(RemotePortForwardingProviderImpl);
|
|
50
|
+
bindBackendService(RemoteRemotePortForwardingProviderPath, RemotePortForwardingProvider);
|
|
45
51
|
});
|
|
46
52
|
|
|
47
53
|
export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
18
|
+
import { ForwardedPort, RemotePortForwardingProvider } from '../electron-common/remote-port-forwarding-provider';
|
|
19
|
+
import { createServer, Server } from 'net';
|
|
20
|
+
import { RemoteConnectionService } from './remote-connection-service';
|
|
21
|
+
|
|
22
|
+
@injectable()
|
|
23
|
+
export class RemotePortForwardingProviderImpl implements RemotePortForwardingProvider {
|
|
24
|
+
|
|
25
|
+
@inject(RemoteConnectionService)
|
|
26
|
+
protected readonly connectionService: RemoteConnectionService;
|
|
27
|
+
|
|
28
|
+
protected forwardedPorts: Map<number, Server> = new Map();
|
|
29
|
+
|
|
30
|
+
async forwardPort(connectionPort: number, portToForward: ForwardedPort): Promise<void> {
|
|
31
|
+
const currentConnection = this.connectionService.getConnectionFromPort(connectionPort);
|
|
32
|
+
if (!currentConnection) {
|
|
33
|
+
throw new Error(`No connection found for port ${connectionPort}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const server = createServer(socket => {
|
|
37
|
+
currentConnection?.forwardOut(socket, portToForward.port);
|
|
38
|
+
}).listen(portToForward.port, portToForward.address);
|
|
39
|
+
this.forwardedPorts.set(portToForward.port, server);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async portRemoved(forwardedPort: ForwardedPort): Promise<void> {
|
|
43
|
+
const proxy = this.forwardedPorts.get(forwardedPort.port);
|
|
44
|
+
if (proxy) {
|
|
45
|
+
proxy.close();
|
|
46
|
+
this.forwardedPorts.delete(forwardedPort.port);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
|
@@ -49,8 +49,21 @@ export interface RemoteConnection extends Disposable {
|
|
|
49
49
|
localPort: number;
|
|
50
50
|
remotePort: number;
|
|
51
51
|
onDidDisconnect: Event<void>;
|
|
52
|
-
forwardOut(socket: net.Socket): void;
|
|
52
|
+
forwardOut(socket: net.Socket, port?: number): void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* execute a single command on the remote machine
|
|
56
|
+
*/
|
|
53
57
|
exec(cmd: string, args?: string[], options?: RemoteExecOptions): Promise<RemoteExecResult>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* execute a command on the remote machine and wait for a specific output
|
|
61
|
+
* @param tester function which returns true if the output is as expected
|
|
62
|
+
*/
|
|
54
63
|
execPartial(cmd: string, tester: RemoteExecTester, args?: string[], options?: RemoteExecOptions): Promise<RemoteExecResult>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* copy files from local to remote
|
|
67
|
+
*/
|
|
55
68
|
copy(localPath: string | Buffer | NodeJS.ReadableStream, remotePath: string): Promise<void>;
|
|
56
69
|
}
|
|
@@ -29,6 +29,11 @@ export interface RemoteSetupOptions {
|
|
|
29
29
|
nodeDownloadTemplate?: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
export interface RemoteSetupResult {
|
|
33
|
+
applicationDirectory: string;
|
|
34
|
+
nodeDirectory: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
@injectable()
|
|
33
38
|
export class RemoteSetupService {
|
|
34
39
|
|
|
@@ -47,7 +52,7 @@ export class RemoteSetupService {
|
|
|
47
52
|
@inject(ApplicationPackage)
|
|
48
53
|
protected readonly applicationPackage: ApplicationPackage;
|
|
49
54
|
|
|
50
|
-
async setup(options: RemoteSetupOptions): Promise<
|
|
55
|
+
async setup(options: RemoteSetupOptions): Promise<RemoteSetupResult> {
|
|
51
56
|
const {
|
|
52
57
|
connection,
|
|
53
58
|
report,
|
|
@@ -86,12 +91,16 @@ export class RemoteSetupService {
|
|
|
86
91
|
report('Starting application on remote...');
|
|
87
92
|
const port = await this.startApplication(connection, platform, applicationDirectory, remoteNodeDirectory);
|
|
88
93
|
connection.remotePort = port;
|
|
94
|
+
return {
|
|
95
|
+
applicationDirectory: libDir,
|
|
96
|
+
nodeDirectory: remoteNodeDirectory
|
|
97
|
+
};
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
protected async startApplication(connection: RemoteConnection, platform: RemotePlatform, remotePath: string, nodeDir: string): Promise<number> {
|
|
92
101
|
const nodeExecutable = this.scriptService.joinPath(platform, nodeDir, ...(platform.os === OS.Type.Windows ? ['node.exe'] : ['bin', 'node']));
|
|
93
102
|
const mainJsFile = this.scriptService.joinPath(platform, remotePath, 'lib', 'backend', 'main.js');
|
|
94
|
-
const localAddressRegex = /listening on http:\/\/
|
|
103
|
+
const localAddressRegex = /listening on http:\/\/0.0.0.0:(\d+)/;
|
|
95
104
|
let prefix = '';
|
|
96
105
|
if (platform.os === OS.Type.Windows) {
|
|
97
106
|
// We might to switch to PowerShell beforehand on Windows
|
|
@@ -101,7 +110,7 @@ export class RemoteSetupService {
|
|
|
101
110
|
// This way, our current working directory is set as expected
|
|
102
111
|
const result = await connection.execPartial(`${prefix}cd "${remotePath}";${nodeExecutable}`,
|
|
103
112
|
stdout => localAddressRegex.test(stdout),
|
|
104
|
-
[mainJsFile, '--hostname=
|
|
113
|
+
[mainJsFile, '--hostname=0.0.0.0', `--port=${connection.remotePort ?? 0}`, '--remote']);
|
|
105
114
|
|
|
106
115
|
const match = localAddressRegex.exec(result.stdout);
|
|
107
116
|
if (!match) {
|
|
@@ -278,8 +278,8 @@ export class RemoteSSHConnection implements RemoteConnection {
|
|
|
278
278
|
return sftpClient;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
forwardOut(socket: net.Socket): void {
|
|
282
|
-
this.client.forwardOut(socket.localAddress!, socket.localPort!, '127.0.0.1', this.remotePort, (err, stream) => {
|
|
281
|
+
forwardOut(socket: net.Socket, port?: number): void {
|
|
282
|
+
this.client.forwardOut(socket.localAddress!, socket.localPort!, '127.0.0.1', port ?? this.remotePort, (err, stream) => {
|
|
283
283
|
if (err) {
|
|
284
284
|
console.debug('Proxy message rejected', err);
|
|
285
285
|
} else {
|