mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 05:37:51 +00:00
resin ssh proxy support
This commit is contained in:
parent
1d06bc1b4f
commit
bc79832e1d
@ -14,6 +14,7 @@ Requisites
|
|||||||
- [Git](https://git-scm.com)
|
- [Git](https://git-scm.com)
|
||||||
- The following executables should be correctly installed in your shell environment:
|
- The following executables should be correctly installed in your shell environment:
|
||||||
- `ssh`: Any recent version of the OpenSSH ssh client (required by `resin sync` and `resin ssh`)
|
- `ssh`: Any recent version of the OpenSSH ssh client (required by `resin sync` and `resin ssh`)
|
||||||
|
- if you need `ssh` to work behind the proxy you also need `proxytunnel`[http://proxytunnel.sourceforge.net/] installed (available as `proxytunnel` package for Ubuntu, for example)
|
||||||
- `rsync`: >= 2.6.9 (required by `resin sync`)
|
- `rsync`: >= 2.6.9 (required by `resin sync`)
|
||||||
|
|
||||||
##### Windows Support
|
##### Windows Support
|
||||||
@ -26,6 +27,7 @@ If you still want to use `cmd.exe` you will have to use a package manager like M
|
|||||||
2. Install the `msys-rsync` and `msys-openssh` packages.
|
2. Install the `msys-rsync` and `msys-openssh` packages.
|
||||||
3. Add MinGW to the `%PATH%` if this hasn't been done by the installer already. The location where the binaries are places is usually `C:\MinGW\msys\1.0\bin`, but it can vary if you selected a different location in the installer.
|
3. Add MinGW to the `%PATH%` if this hasn't been done by the installer already. The location where the binaries are places is usually `C:\MinGW\msys\1.0\bin`, but it can vary if you selected a different location in the installer.
|
||||||
4. Copy your SSH keys to `%homedrive%%homepath\.ssh`.
|
4. Copy your SSH keys to `%homedrive%%homepath\.ssh`.
|
||||||
|
5. Install [proxytunnel](http://proxytunnel.sourceforge.net/)
|
||||||
|
|
||||||
Getting Started
|
Getting Started
|
||||||
---------------
|
---------------
|
||||||
|
@ -94,18 +94,4 @@ exports.pipeContainerStream = Promise.method(function(arg) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
exports.getSubShellCommand = function(command) {
|
exports.getSubShellCommand = require('../../utils/helpers');
|
||||||
var os;
|
|
||||||
os = require('os');
|
|
||||||
if (os.platform() === 'win32') {
|
|
||||||
return {
|
|
||||||
program: 'cmd.exe',
|
|
||||||
args: ['/s', '/c', command]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
program: '/bin/sh',
|
|
||||||
args: ['-c', command]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -17,21 +17,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
var getSubShellCommand;
|
var getSubShellCommand;
|
||||||
|
|
||||||
getSubShellCommand = function(command) {
|
getSubShellCommand = require('../utils/helpers').getSubShellCommand;
|
||||||
var os;
|
|
||||||
os = require('os');
|
|
||||||
if (os.platform() === 'win32') {
|
|
||||||
return {
|
|
||||||
program: 'cmd.exe',
|
|
||||||
args: ['/s', '/c', command]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
program: '/bin/sh',
|
|
||||||
args: ['-c', command]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
signature: 'ssh [uuid]',
|
signature: 'ssh [uuid]',
|
||||||
@ -73,7 +59,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
return patterns.inferOrSelectDevice();
|
return patterns.inferOrSelectDevice();
|
||||||
}).then(function(uuid) {
|
}).then(function(uuid) {
|
||||||
console.info("Connecting with: " + uuid);
|
console.info("Connecting to: " + uuid);
|
||||||
return resin.models.device.get(uuid);
|
return resin.models.device.get(uuid);
|
||||||
}).then(function(device) {
|
}).then(function(device) {
|
||||||
if (!device.is_online) {
|
if (!device.is_online) {
|
||||||
@ -91,8 +77,17 @@ module.exports = {
|
|||||||
throw new Error('Did not find running application container');
|
throw new Error('Did not find running application container');
|
||||||
}
|
}
|
||||||
return Promise["try"](function() {
|
return Promise["try"](function() {
|
||||||
var command, subShellCommand;
|
var command, proxyAuth, proxyConfig, proxyHost, proxytunnelCommand, sshProxyCommand, subShellCommand;
|
||||||
command = "ssh " + verbose + " -t -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ControlMaster=no -p " + options.port + " " + username + "@ssh." + proxyUrl + " enter " + uuid + " " + containerId;
|
sshProxyCommand = '';
|
||||||
|
proxyConfig = global.PROXY_CONFIG;
|
||||||
|
if (proxyConfig) {
|
||||||
|
proxyAuth = proxyConfig.proxyAuth;
|
||||||
|
proxyHost = "-p " + proxyConfig.host + ":" + proxyConfig.port;
|
||||||
|
proxyAuth = proxyAuth ? "-P " + proxyAuth : '';
|
||||||
|
proxytunnelCommand = "proxytunnel " + proxyHost + " " + proxyAuth + " -d %h:%p";
|
||||||
|
sshProxyCommand = "-o ProxyCommand='" + proxytunnelCommand + "'";
|
||||||
|
}
|
||||||
|
command = "ssh " + verbose + " -t -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ControlMaster=no " + sshProxyCommand + " -p " + options.port + " " + username + "@ssh." + proxyUrl + " enter " + uuid + " " + containerId;
|
||||||
subShellCommand = getSubShellCommand(command);
|
subShellCommand = getSubShellCommand(command);
|
||||||
return child_process.spawn(subShellCommand.program, subShellCommand.args, {
|
return child_process.spawn(subShellCommand.program, subShellCommand.args, {
|
||||||
stdio: 'inherit'
|
stdio: 'inherit'
|
||||||
|
@ -47,6 +47,8 @@ try {
|
|||||||
|
|
||||||
globalTunnel.initialize(proxy);
|
globalTunnel.initialize(proxy);
|
||||||
|
|
||||||
|
global.PROXY_CONFIG = globalTunnel.proxyConfig;
|
||||||
|
|
||||||
_ = require('lodash');
|
_ = require('lodash');
|
||||||
|
|
||||||
Promise = require('bluebird');
|
Promise = require('bluebird');
|
||||||
|
@ -110,3 +110,19 @@ exports.getAppInfo = function(application) {
|
|||||||
return app;
|
return app;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.getSubShellCommand = function(command) {
|
||||||
|
var os;
|
||||||
|
os = require('os');
|
||||||
|
if (os.platform() === 'win32') {
|
||||||
|
return {
|
||||||
|
program: 'cmd.exe',
|
||||||
|
args: ['/s', '/c', command]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
program: '/bin/sh',
|
||||||
|
args: ['-c', command]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -58,21 +58,4 @@ exports.pipeContainerStream = Promise.method ({ deviceIp, name, outStream, follo
|
|||||||
return console.log(chalk.red.bold("Container '#{name}' not found."))
|
return console.log(chalk.red.bold("Container '#{name}' not found."))
|
||||||
throw err
|
throw err
|
||||||
|
|
||||||
# A function to reliably execute a command
|
exports.getSubShellCommand = require('../../utils/helpers')
|
||||||
# in all supported operating systems, including
|
|
||||||
# different Windows environments like `cmd.exe`
|
|
||||||
# and `Cygwin` should be encapsulated in a
|
|
||||||
# re-usable package.
|
|
||||||
exports.getSubShellCommand = (command) ->
|
|
||||||
os = require('os')
|
|
||||||
|
|
||||||
if os.platform() is 'win32'
|
|
||||||
return {
|
|
||||||
program: 'cmd.exe'
|
|
||||||
args: [ '/s', '/c', command ]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return {
|
|
||||||
program: '/bin/sh'
|
|
||||||
args: [ '-c', command ]
|
|
||||||
}
|
|
||||||
|
@ -14,26 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
###
|
###
|
||||||
|
|
||||||
# TODO: A function to reliably execute a command
|
{ getSubShellCommand } = require('../utils/helpers')
|
||||||
# in all supported operating systems, including
|
|
||||||
# different Windows environments like `cmd.exe`
|
|
||||||
# and `Cygwin` should be encapsulated in a
|
|
||||||
# re-usable package.
|
|
||||||
# This is literally copy-pasted from the `resin-sync`
|
|
||||||
# module.
|
|
||||||
getSubShellCommand = (command) ->
|
|
||||||
os = require('os')
|
|
||||||
|
|
||||||
if os.platform() is 'win32'
|
|
||||||
return {
|
|
||||||
program: 'cmd.exe'
|
|
||||||
args: [ '/s', '/c', command ]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return {
|
|
||||||
program: '/bin/sh'
|
|
||||||
args: [ '-c', command ]
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
signature: 'ssh [uuid]'
|
signature: 'ssh [uuid]'
|
||||||
@ -68,12 +49,11 @@ module.exports =
|
|||||||
]
|
]
|
||||||
action: (params, options, done) ->
|
action: (params, options, done) ->
|
||||||
child_process = require('child_process')
|
child_process = require('child_process')
|
||||||
Promise = require 'bluebird'
|
Promise = require('bluebird')
|
||||||
resin = require('resin-sdk-preconfigured')
|
resin = require('resin-sdk-preconfigured')
|
||||||
patterns = require('../utils/patterns')
|
patterns = require('../utils/patterns')
|
||||||
|
|
||||||
if not options.port?
|
options.port ?= 22
|
||||||
options.port = 22
|
|
||||||
|
|
||||||
verbose = if options.verbose then '-vvv' else ''
|
verbose = if options.verbose then '-vvv' else ''
|
||||||
|
|
||||||
@ -84,7 +64,7 @@ module.exports =
|
|||||||
return params.uuid if uuidExists
|
return params.uuid if uuidExists
|
||||||
return patterns.inferOrSelectDevice()
|
return patterns.inferOrSelectDevice()
|
||||||
.then (uuid) ->
|
.then (uuid) ->
|
||||||
console.info("Connecting with: #{uuid}")
|
console.info("Connecting to: #{uuid}")
|
||||||
resin.models.device.get(uuid)
|
resin.models.device.get(uuid)
|
||||||
.then (device) ->
|
.then (device) ->
|
||||||
throw new Error('Device is not online') if not device.is_online
|
throw new Error('Device is not online') if not device.is_online
|
||||||
@ -98,11 +78,20 @@ module.exports =
|
|||||||
.then ({ username, uuid, containerId, proxyUrl }) ->
|
.then ({ username, uuid, containerId, proxyUrl }) ->
|
||||||
throw new Error('Did not find running application container') if not containerId?
|
throw new Error('Did not find running application container') if not containerId?
|
||||||
Promise.try ->
|
Promise.try ->
|
||||||
|
sshProxyCommand = ''
|
||||||
|
proxyConfig = global.PROXY_CONFIG
|
||||||
|
if proxyConfig
|
||||||
|
{ proxyAuth } = proxyConfig
|
||||||
|
proxyHost = "-p #{proxyConfig.host}:#{proxyConfig.port}"
|
||||||
|
proxyAuth = if proxyAuth then "-P #{proxyAuth}" else ''
|
||||||
|
proxytunnelCommand = "proxytunnel #{proxyHost} #{proxyAuth} -d %h:%p"
|
||||||
|
sshProxyCommand = "-o ProxyCommand='#{proxytunnelCommand}'"
|
||||||
command = "ssh #{verbose} -t \
|
command = "ssh #{verbose} -t \
|
||||||
-o LogLevel=ERROR \
|
-o LogLevel=ERROR \
|
||||||
-o StrictHostKeyChecking=no \
|
-o StrictHostKeyChecking=no \
|
||||||
-o UserKnownHostsFile=/dev/null \
|
-o UserKnownHostsFile=/dev/null \
|
||||||
-o ControlMaster=no \
|
-o ControlMaster=no \
|
||||||
|
#{sshProxyCommand} \
|
||||||
-p #{options.port} #{username}@ssh.#{proxyUrl} enter #{uuid} #{containerId}"
|
-p #{options.port} #{username}@ssh.#{proxyUrl} enter #{uuid} #{containerId}"
|
||||||
|
|
||||||
subShellCommand = getSubShellCommand(command)
|
subShellCommand = getSubShellCommand(command)
|
||||||
|
@ -38,6 +38,9 @@ catch
|
|||||||
# If that is not set as well the initialize will do nothing
|
# If that is not set as well the initialize will do nothing
|
||||||
globalTunnel.initialize(proxy)
|
globalTunnel.initialize(proxy)
|
||||||
|
|
||||||
|
# TODO: make this a feature of capitano
|
||||||
|
global.PROXY_CONFIG = globalTunnel.proxyConfig
|
||||||
|
|
||||||
_ = require('lodash')
|
_ = require('lodash')
|
||||||
Promise = require('bluebird')
|
Promise = require('bluebird')
|
||||||
capitano = require('capitano')
|
capitano = require('capitano')
|
||||||
|
@ -105,3 +105,21 @@ exports.getAppInfo = (application) ->
|
|||||||
app.arch = config.arch
|
app.arch = config.arch
|
||||||
return app
|
return app
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# A function to reliably execute a command
|
||||||
|
# in all supported operating systems, including
|
||||||
|
# different Windows environments like `cmd.exe`
|
||||||
|
# and `Cygwin`.
|
||||||
|
exports.getSubShellCommand = (command) ->
|
||||||
|
os = require('os')
|
||||||
|
|
||||||
|
if os.platform() is 'win32'
|
||||||
|
return {
|
||||||
|
program: 'cmd.exe'
|
||||||
|
args: [ '/s', '/c', command ]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
program: '/bin/sh'
|
||||||
|
args: [ '-c', command ]
|
||||||
|
}
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
"dockerode": "^2.4.2",
|
"dockerode": "^2.4.2",
|
||||||
"drivelist": "^5.0.16",
|
"drivelist": "^5.0.16",
|
||||||
"etcher-image-write": "^9.0.3",
|
"etcher-image-write": "^9.0.3",
|
||||||
"global-tunnel-ng": "^2.0.0",
|
"global-tunnel-ng": "emirotin/global-tunnel#fix-auth",
|
||||||
"inquirer": "^3.0.6",
|
"inquirer": "^3.0.6",
|
||||||
"is-root": "^1.0.0",
|
"is-root": "^1.0.0",
|
||||||
"js-yaml": "^3.7.0",
|
"js-yaml": "^3.7.0",
|
||||||
|
Loading…
Reference in New Issue
Block a user