SSH local forward
This commit is contained in:
+224
-8
@@ -3358,7 +3358,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -3391,7 +3391,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -3399,6 +3399,60 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"localForwards": {
|
||||
"type": "array",
|
||||
"description": "%c_cpp.debuggers.host.localForward.description%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"bindAddress": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.bindAddress.description%",
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.port.description%"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.host.description%",
|
||||
"default": ""
|
||||
},
|
||||
"hostPort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.hostPort.description%"
|
||||
},
|
||||
"localSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.localSocket.description%",
|
||||
"default": ""
|
||||
},
|
||||
"remoteSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.remoteSocket.description%",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3461,7 +3515,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -3494,7 +3548,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -3502,6 +3556,60 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"localForwards": {
|
||||
"type": "array",
|
||||
"description": "%c_cpp.debuggers.host.localForward.description%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"bindAddress": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.bindAddress.description%",
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.port.description%"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.host.description%",
|
||||
"default": ""
|
||||
},
|
||||
"hostPort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.hostPort.description%"
|
||||
},
|
||||
"localSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.localSocket.description%",
|
||||
"default": ""
|
||||
},
|
||||
"remoteSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.remoteSocket.description%",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3925,7 +4033,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -3958,7 +4066,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -3966,6 +4074,60 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"localForwards": {
|
||||
"type": "array",
|
||||
"description": "%c_cpp.debuggers.host.localForward.description%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"bindAddress": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.bindAddress.description%",
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.port.description%"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.host.description%",
|
||||
"default": ""
|
||||
},
|
||||
"hostPort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.hostPort.description%"
|
||||
},
|
||||
"localSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.localSocket.description%",
|
||||
"default": ""
|
||||
},
|
||||
"remoteSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.remoteSocket.description%",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4028,7 +4190,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -4061,7 +4223,7 @@
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
@@ -4069,6 +4231,60 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"localForwards": {
|
||||
"type": "array",
|
||||
"description": "%c_cpp.debuggers.host.localForward.description%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"bindAddress": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.bindAddress.description%",
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.port.description%"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.host.description%",
|
||||
"default": ""
|
||||
},
|
||||
"hostPort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.hostPort.description%"
|
||||
},
|
||||
"localSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.localSocket.description%",
|
||||
"default": ""
|
||||
},
|
||||
"remoteSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.remoteSocket.description%",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -305,6 +305,13 @@
|
||||
"c_cpp.debuggers.host.hostName.description": "Host name.",
|
||||
"c_cpp.debuggers.host.port.description": "SSH port on the host. Default is 22.",
|
||||
"c_cpp.debuggers.host.jumpHost.description": "Connect to the target host by first making a connection to the jump hosts.",
|
||||
"c_cpp.debuggers.host.localForward.description": "Forward connections to the given TCP port or Unix socket on the local (client) host to the given host and port, or Unix socket, on the remote side",
|
||||
"c_cpp.debuggers.host.localForward.bindAddress.description": "Local address",
|
||||
"c_cpp.debuggers.host.localForward.port.description": "Local port",
|
||||
"c_cpp.debuggers.host.localForward.host.description": "Host name",
|
||||
"c_cpp.debuggers.host.localForward.hostPort.description": "Host port",
|
||||
"c_cpp.debuggers.host.localForward.localSocket.description": "Local socket",
|
||||
"c_cpp.debuggers.host.localForward.remoteSocket.description": "Remote socket",
|
||||
"c_cpp.debuggers.deploySteps.description": "Steps needed to deploy the application. Order matters.",
|
||||
"c_cpp.debuggers.deploySteps.scp.description": "Copy files using SCP.",
|
||||
"c_cpp.debuggers.deploySteps.scp.files.description": "Files to be copied via SCP. Supports path pattern.",
|
||||
|
||||
@@ -981,7 +981,9 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
|
||||
}
|
||||
const host: util.ISshHostInfo = { hostName: step.host.hostName, user: step.host.user, port: step.host.port };
|
||||
const jumpHosts: util.ISshHostInfo[] = step.host.jumpHosts;
|
||||
const sshResult: util.ProcessReturnType = await ssh(host, step.command, config.sshPath, jumpHosts, step.continueOn, cancellationToken);
|
||||
const localForwards: util.ISshLocalForwardInfo[] = step.host.localForwards;
|
||||
const continueOn: string = step.continueOn;
|
||||
const sshResult: util.ProcessReturnType = await ssh(host, step.command, config.sshPath, jumpHosts, localForwards, continueOn, cancellationToken);
|
||||
if (!sshResult.succeeded || cancellationToken?.isCancellationRequested) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,14 @@
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ISshHostInfo, ProcessReturnType } from '../common';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { ISshHostInfo, ISshLocalForwardInfo, ProcessReturnType } from '../common';
|
||||
import { defaultSystemInteractor } from './commandInteractors';
|
||||
import { runSshTerminalCommandWithLogin } from './sshCommandRunner';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
||||
export async function scp(files: vscode.Uri[], host: ISshHostInfo, targetDir: string, scpPath?: string, jumpHosts?: ISshHostInfo[], cancellationToken?: vscode.CancellationToken): Promise<ProcessReturnType> {
|
||||
const args: string[] = [];
|
||||
if (jumpHosts && jumpHosts.length > 0) {
|
||||
@@ -22,7 +26,7 @@ export async function scp(files: vscode.Uri[], host: ISshHostInfo, targetDir: st
|
||||
return runSshTerminalCommandWithLogin(host, { systemInteractor: defaultSystemInteractor, nickname: 'scp', command: `"${scpPath || 'scp'}" ${args.join(' ')}`, token: cancellationToken });
|
||||
}
|
||||
|
||||
export function ssh(host: ISshHostInfo, command: string, sshPath?: string, jumpHosts?: ISshHostInfo[], continueOn?: string, cancellationToken?: vscode.CancellationToken): Promise<ProcessReturnType> {
|
||||
export function ssh(host: ISshHostInfo, command: string, sshPath?: string, jumpHosts?: ISshHostInfo[], localForwards?: ISshLocalForwardInfo[], continueOn?: string, cancellationToken?: vscode.CancellationToken): Promise<ProcessReturnType> {
|
||||
const args: string[] = [];
|
||||
if (jumpHosts && jumpHosts.length > 0) {
|
||||
args.push('-J', jumpHosts.map(getFullHostAddress).join(','));
|
||||
@@ -31,6 +35,9 @@ export function ssh(host: ISshHostInfo, command: string, sshPath?: string, jumpH
|
||||
// lower case p
|
||||
args.push('-p', `${host.port}`);
|
||||
}
|
||||
if (localForwards) {
|
||||
localForwards.forEach(info => args.push(...localForwardToArgs(info)));
|
||||
}
|
||||
args.push(getFullHostAddressNoPort(host), `"${command}"`);
|
||||
|
||||
return runSshTerminalCommandWithLogin(host, {
|
||||
@@ -42,6 +49,44 @@ export function ssh(host: ISshHostInfo, command: string, sshPath?: string, jumpH
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes one local forward info and convert it to '-L' args in ssh.
|
||||
*/
|
||||
function localForwardToArgs(localForward: ISshLocalForwardInfo): string[] {
|
||||
// Do not combine error checking and arg conversion for clarity.
|
||||
if (localForward.localSocket && (localForward.bindAddress || localForward.port)) {
|
||||
throw Error(localize('local.forward.local.conflict', '"localSocket" cannot be specifed at the same time with "bindAddress" or "port" in localForwards'));
|
||||
}
|
||||
if (!localForward.localSocket && !localForward.port) {
|
||||
throw Error(localize('local.forward.local.missing', '"port" or "localSocket" required in localForwards'));
|
||||
}
|
||||
if (localForward.remoteSocket && (localForward.host || localForward.hostPort)) {
|
||||
throw Error(localize('local.forward.remote.conflict', '"remoteSocket" cannot be specifed at the same time with "host" or "hostPort" in localForwards'));
|
||||
}
|
||||
if (!localForward.remoteSocket && (!localForward.host || !localForward.hostPort)) {
|
||||
throw Error(localize('local.forward.remote.missing', '"host" and "hostPort", or "remoteSocket" required in localForwards'));
|
||||
}
|
||||
|
||||
let arg: string = '';
|
||||
if (localForward.localSocket) {
|
||||
arg += `${localForward.localSocket}:`;
|
||||
}
|
||||
if (localForward.bindAddress) {
|
||||
arg += `${localForward.bindAddress}:`;
|
||||
}
|
||||
if (localForward.port) {
|
||||
arg += `${localForward.port}:`;
|
||||
}
|
||||
if (localForward.remoteSocket) {
|
||||
arg += `${localForward.remoteSocket}`;
|
||||
}
|
||||
if (localForward.host && localForward.hostPort) {
|
||||
arg += `${localForward.host}:${localForward.hostPort}`;
|
||||
}
|
||||
|
||||
return ['-L', arg];
|
||||
}
|
||||
|
||||
/** user@host */
|
||||
function getFullHostAddressNoPort(host: ISshHostInfo): string {
|
||||
return host.user ? `${host.user}@${host.hostName}` : `${host.hostName}`;
|
||||
|
||||
@@ -1550,3 +1550,12 @@ export interface ISshHostInfo {
|
||||
user?: string;
|
||||
port?: number | string;
|
||||
}
|
||||
|
||||
export interface ISshLocalForwardInfo {
|
||||
bindAddress?: string;
|
||||
port?: number | string;
|
||||
host?: string;
|
||||
hostPort?: number | string;
|
||||
localSocket?: string;
|
||||
remoteSocket?: string;
|
||||
}
|
||||
|
||||
@@ -256,15 +256,15 @@
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf":[
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
}
|
||||
],
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
"default": 22
|
||||
},
|
||||
@@ -289,20 +289,74 @@
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf":[
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$"
|
||||
}
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.port.description%",
|
||||
"default": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"localForwards": {
|
||||
"type": "array",
|
||||
"description": "%c_cpp.debuggers.host.localForward.description%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"bindAddress": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.bindAddress.description%",
|
||||
"default": ""
|
||||
},
|
||||
"port": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.port.description%"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.host.description%",
|
||||
"default": ""
|
||||
},
|
||||
"hostPort": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\d+$|^\\${.+}$"
|
||||
}
|
||||
],
|
||||
"description": "%c_cpp.debuggers.host.localForward.hostPort.description%"
|
||||
},
|
||||
"localSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.localSocket.description%",
|
||||
"default": ""
|
||||
},
|
||||
"remoteSocket": {
|
||||
"type": "string",
|
||||
"description": "%c_cpp.debuggers.host.localForward.remoteSocket.description%",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -654,10 +708,10 @@
|
||||
"default": {}
|
||||
},
|
||||
"variables": {
|
||||
"$ref": "#/definitions/Variables"
|
||||
"$ref": "#/definitions/Variables"
|
||||
},
|
||||
"deploySteps": {
|
||||
"$ref": "#/definitions/DeploySteps"
|
||||
"$ref": "#/definitions/DeploySteps"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -774,10 +828,10 @@
|
||||
"description": "%c_cpp.debuggers.symbolLoadInfo.description%"
|
||||
},
|
||||
"variables": {
|
||||
"$ref": "#/definitions/Variables"
|
||||
"$ref": "#/definitions/Variables"
|
||||
},
|
||||
"deploySteps": {
|
||||
"$ref": "#/definitions/DeploySteps"
|
||||
"$ref": "#/definitions/DeploySteps"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user