UNPKG

mecano

Version:

Common functions for system deployment.

244 lines (238 loc) 7.1 kB
// Generated by CoffeeScript 1.11.1 var exec, misc, path, string; module.exports = function(options, callback) { var current_username, result, stds; options.log({ message: "Entering execute", level: 'DEBUG', module: 'mecano/lib/execute' }); stds = options.user_args; if (typeof options.argument === 'string') { options.cmd = options.argument; } if (options.code == null) { options.code = [0]; } if (!Array.isArray(options.code)) { options.code = [options.code]; } if (options.code_skipped == null) { options.code_skipped = []; } if (!Array.isArray(options.code_skipped)) { options.code_skipped = [options.code_skipped]; } if (options.stdin_log == null) { options.stdin_log = true; } if (options.stdout_callback === void 0) { options.stdout_callback = true; } if (options.stderr_callback === void 0) { options.stderr_callback = true; } options.stdout_log = options.hasOwnProperty('stdout_log') ? options.stdout_log : true; options.stderr_log = options.hasOwnProperty('stderr_log') ? options.stderr_log : true; if (typeof options.cmd === 'function') { options.cmd = options.cmd.call(this, options); } if (options.cmd == null) { throw Error("Missing cmd: " + options.cmd); } if (options.trap) { options.cmd = "set -e\n" + options.cmd; } if (options.stdin_log) { options.log({ message: options.cmd, type: 'stdin', module: 'mecano/lib/execute' }); } result = { stdout: null, stderr: null, code: null }; current_username = options.ssh ? options.ssh.config.username : /^win/.test(process.platform) ? process.env['USERPROFILE'].split(path.sep)[2] : process.env['USER']; this.call({ shy: true }, function(_, callback) { var obj; if (options.target) { return callback(null, true); } if (current_username === 'root') { return callback(null, false); } if (!options.uid) { return callback(null, false); } if (!/\d/.test("" + options.uid)) { return callback(null, options.uid !== current_username); } return this.execute(( obj = {}, obj["awk -v val=" + options.uid + " -F "] = " '$3==val{print $1}' /etc/passwd`", obj ), function(err, _, stdout) { if (!err) { options.uid = stdout.trim(); } return callback(err, options.uid !== current_username); }); }); this.call({ "if": function() { return this.status(-1); }, handler: function() { options.cmd = "#!/bin/bash\n\n" + options.cmd; if (options.target == null) { options.target = "/tmp/mecano_" + (string.hash(options.cmd)); } options.log({ message: 'Writing bash script to #{JSON.stringify options.target}', level: 'INFO' }); options.cmd = "su - " + options.uid + " -c 'bash /tmp/mecano_" + (string.hash(options.cmd)) + "'"; return this.file({ target: options.target }); } }); this.call(function(_, callback) { var child, stderr_stream_open, stdout_stream_open; child = exec(options); result.stdout = []; result.stderr = []; if (options.stdout) { child.stdout.pipe(options.stdout, { end: false }); } if (options.stderr) { child.stderr.pipe(options.stderr, { end: false }); } stdout_stream_open = stderr_stream_open = false; if (options.stdout_callback || options.stdout_log) { child.stdout.on('data', function(data) { if (options.stdout_log) { stdout_stream_open = true; } if (options.stdout_log) { options.log({ message: data, type: 'stdout_stream', module: 'mecano/lib/execute' }); } if (options.stdout_callback) { if (Array.isArray(result.stdout)) { return result.stdout.push(data); } else { return console.log('stdout coming after child exit'); } } }); } if (options.stderr_callback || options.stderr_log) { child.stderr.on('data', function(data) { if (options.stderr_log) { stderr_stream_open = true; } if (options.stderr_log) { options.log({ message: data, type: 'stderr_stream', module: 'mecano/lib/execute' }); } if (options.stderr_callback) { if (Array.isArray(result.stderr)) { return result.stderr.push(data); } else { return console.log('stderr coming after child exit'); } } }); } return child.on("exit", function(code) { result.code = code; return setTimeout(function() { var err, status; if (stdout_stream_open && options.stdout_log) { options.log({ message: null, type: 'stdout_stream', module: 'mecano/lib/execute' }); } if (stderr_stream_open && options.stderr_log) { options.log({ message: null, type: 'stderr_stream', module: 'mecano/lib/execute' }); } result.stdout = result.stdout.map(function(d) { return d.toString(); }).join(''); if (options.trim || options.stdout_trim) { result.stdout = result.stdout.trim(); } result.stderr = result.stderr.map(function(d) { return d.toString(); }).join(''); if (options.trim || options.stderr_trim) { result.stderr = result.stderr.trim(); } if (result.stdout && result.stdout !== '' && options.stdout_log) { options.log({ message: result.stdout, type: 'stdout', module: 'mecano/lib/execute' }); } if (result.stderr && result.stderr !== '' && options.stderr_log) { options.log({ message: result.stderr, type: 'stderr', module: 'mecano/lib/execute' }); } if (options.stdout) { child.stdout.unpipe(options.stdout); } if (options.stderr) { child.stderr.unpipe(options.stderr); } if (options.code.indexOf(code) === -1 && options.code_skipped.indexOf(code) === -1) { err = new Error("Invalid Exit Code: " + code); err.code = code; return callback(err, null); } if (options.code_skipped.indexOf(code) === -1) { status = true; } else { options.log({ message: "Skip exit code \"" + code + "\"", level: 'INFO', module: 'mecano/lib/execute' }); } return callback(null, status); }, 1); }); }); return this.then(function(err, status) { return callback(err, status, result.stdout, result.stderr, result.code); }); }; path = require('path'); exec = require('ssh2-exec'); misc = require('../misc'); string = require('../misc/string');