UNPKG

balena-cli

Version:

The official balena Command Line Interface

167 lines (161 loc) • 7.03 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@oclif/core"); const lazy_1 = require("../../utils/lazy"); const validation_1 = require("../../utils/validation"); class DeviceSSHCmd extends core_1.Command { async run() { const { args: params, flags: options } = await this.parse(_a); if ((0, validation_1.validateLocalHostnameOrIp)(params.fleetOrDevice)) { const { performLocalDeviceSSH } = await Promise.resolve().then(() => require('../../utils/device/ssh')); return await performLocalDeviceSSH({ hostname: params.fleetOrDevice, port: options.port || 'local', forceTTY: options.tty, verbose: options.verbose, service: params.service, }); } const { getProxyConfig } = await Promise.resolve().then(() => require('../../utils/helpers')); const { getOnlineTargetDeviceUuid, checkLoggedIn, checkNotUsingOfflineMode, } = await Promise.resolve().then(() => require('../../utils/patterns')); const sdk = (0, lazy_1.getBalenaSdk)(); const proxyConfig = getProxyConfig(); const useProxy = !!proxyConfig && !options.noproxy; await checkNotUsingOfflineMode(); await checkLoggedIn(); const deviceUuid = await getOnlineTargetDeviceUuid(sdk, params.fleetOrDevice); const { which } = await Promise.resolve().then(() => require('../../utils/which')); const [whichProxytunnel, { username }, proxyUrl] = await Promise.all([ useProxy ? which('proxytunnel', false) : undefined, sdk.auth.getUserInfo(), sdk.settings.get('proxyUrl'), ]); const getSshProxyCommand = () => { if (!proxyConfig) { return; } if (!whichProxytunnel) { console.warn((0, lazy_1.stripIndent) ` Proxy is enabled but the \`proxytunnel\` binary cannot be found. Please install it if you want to route the \`balena ssh\` requests through the proxy. Alternatively you can pass \`--noproxy\` param to the \`balena ssh\` command to ignore the proxy config for the \`ssh\` requests. Attempting the unproxied request for now.`); return; } const p = proxyConfig; if (p.username && p.password) { process.env.PROXYUSER = p.username; process.env.PROXYPASS = p.password; } return [ 'proxytunnel', `--proxy=${p.host}:${p.port}`, '--dest=%h:%p', ...(options.verbose ? ['--verbose'] : []), ]; }; const proxyCommand = useProxy ? getSshProxyCommand() : undefined; let containerId; if (params.service != null) { const { getContainerIdForService } = await Promise.resolve().then(() => require('../../utils/device/ssh')); containerId = await getContainerIdForService({ deviceUuid, hostname: `ssh.${proxyUrl}`, port: options.port || 'cloud', proxyCommand, service: params.service, username, }); } let accessCommand; if (containerId != null) { accessCommand = `enter ${deviceUuid} ${containerId}`; } else { accessCommand = `host ${deviceUuid}`; } const { runRemoteCommand } = await Promise.resolve().then(() => require('../../utils/ssh')); await runRemoteCommand({ cmd: accessCommand, hostname: `ssh.${proxyUrl}`, port: options.port || 'cloud', proxyCommand, username, verbose: options.verbose, }); } } _a = DeviceSSHCmd; DeviceSSHCmd.aliases = ['ssh']; DeviceSSHCmd.deprecateAliases = true; DeviceSSHCmd.description = (0, lazy_1.stripIndent) ` Open a SSH prompt on a device's host OS or service container. Start a shell on a local or remote device. If a service name is not provided, a shell will be opened on the host OS. If a fleet is provided, an interactive menu will be presented for the selection of an online device. A shell will then be opened for the host OS or service container of the chosen device. For local devices, the IP address and .local domain name are supported. If the device is referenced by IP or \`.local\` address, the connection is initiated directly to balenaOS on port \`22222\` via an openssh-compatible client. Otherwise, any connection initiated remotely traverses the balenaCloud VPN. Commands may be piped to the standard input for remote execution (see examples). Note however that remote command execution on service containers (as opposed to the host OS) is not currently possible when a device UUID is used (instead of an IP address) because of a balenaCloud backend limitation. Note: \`balena ssh\` requires an openssh-compatible client to be correctly installed in your shell environment. For more information (including Windows support) please check: https://github.com/balena-io/balena-cli/blob/master/INSTALL.md#additional-dependencies, `; DeviceSSHCmd.examples = [ '$ balena device ssh MyFleet', '$ balena device ssh f49cefd', '$ balena device ssh f49cefd my-service', '$ balena device ssh f49cefd --port <port>', '$ balena device ssh 192.168.0.1 --verbose', '$ balena device ssh f49cefd.local my-service', '$ echo "uptime; exit;" | balena device ssh f49cefd', '$ echo "uptime; exit;" | balena device ssh 192.168.0.1 myService', ]; DeviceSSHCmd.args = { fleetOrDevice: core_1.Args.string({ description: 'fleet name/slug, device uuid, or address of local device', required: true, }), service: core_1.Args.string({ description: 'service name, if connecting to a container', required: false, ignoreStdin: true, }), }; DeviceSSHCmd.flags = { port: core_1.Flags.integer({ description: (0, lazy_1.stripIndent) ` SSH server port number (default 22222) if the target is an IP address or .local hostname. Otherwise, port number for the balenaCloud gateway (default 22).`, char: 'p', parse: async (p) => (0, validation_1.parseAsInteger)(p, 'port'), }), tty: core_1.Flags.boolean({ default: false, description: 'force pseudo-terminal allocation (bypass TTY autodetection for stdin)', char: 't', }), verbose: core_1.Flags.boolean({ default: false, description: 'increase verbosity', char: 'v', }), noproxy: core_1.Flags.boolean({ default: false, description: 'bypass global proxy configuration for the ssh connection', }), }; DeviceSSHCmd.primary = true; DeviceSSHCmd.offlineCompatible = true; exports.default = DeviceSSHCmd; //# sourceMappingURL=ssh.js.map