run-on-ssh
Version:
Run a node.js script on a given ssh server
141 lines (121 loc) • 4.29 kB
JavaScript
;
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;