UNPKG

run-on-ssh

Version:

Run a node.js script on a given ssh server

141 lines (121 loc) 4.29 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _promise = require('promise'); var _promise2 = _interopRequireDefault(_promise); var _ssh = require('ssh2'); var _ssh2 = _interopRequireDefault(_ssh); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var SSH = function () { function SSH(remote, options) { var _this = this; (0, _classCallCheck3.default)(this, SSH); this._options = options || {}; this.ready = new _promise2.default(function (resolve, reject) { var attempt = function attempt(attemptNumber) { _this._connection = new _ssh2.default(); _this._connection.on('error', function (err) { if (attemptNumber < 5) { console.log('connection failed, retrying in ' + Math.pow(2, attemptNumber) + ' second(s)'); setTimeout(function () { return attempt(attemptNumber + 1); }, 2000 * Math.pow(2, attemptNumber)); } else { reject(err); } }); _this._connection.on('ready', resolve); _this._connection.connect(remote); }; attempt(0); }); } (0, _createClass3.default)(SSH, [{ key: 'exec', value: function exec(commands) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; return this.warm(commands, options).stdin(options.stdin); } }, { key: 'warm', value: function warm(commands) { var _this2 = this; var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; if (Array.isArray(commands)) commands = commands.join(' && '); var debug = (options.debug === undefined ? this._options.debug : options.debug) || false; var setStdin = void 0; var stdin = new _promise2.default(function (resolve) { return setStdin = resolve; }); var result = this.ready.then(function () { return new _promise2.default(function (resolve, reject) { var exitCode = 1; _this2._connection.exec(commands, { pty: options.pty }, function (err, stream) { if (err) return reject(err); var stream_output = ''; var err_output = ''; stream.on('data', function (data) { stream_output += data.toString(); if (debug) { process.stdout.write(data); } }); stream.stderr.on('data', function (data) { err_output += data.toString(); if (debug) { process.stderr.write(data); } }); var pending = 3; function onEnd() { if (--pending === 0) { if (exitCode === 0) { resolve(stream_output); } else { reject(new Error('Command existed with code ' + exitCode + ':\n\n' + stream_output + '\n\n' + err_output)); } } } stream.on('end', function () { onEnd(); }); stream.stderr.on('end', function () { onEnd(); }); stream.on('exit', function (code) { exitCode = code; onEnd(); }); stdin.done(function (data) { if (data) { stream.end(data); } else { stream.end(); } }); }); }); }); this.ready = result.then(null, function () {}); return { stdin: function stdin(data) { setStdin(data); return result; } }; } }, { key: 'close', value: function close() { this.ready = _promise2.default.reject(new Error('Cannot interact with a closed connection')); return _promise2.default.resolve(this._connection.end()); } }]); return SSH; }(); exports.default = SSH;