UNPKG

mecano

Version:

Common functions for system deployment.

130 lines (117 loc) 5.09 kB
# `exec` `execute([goptions], options, callback)` Run a command locally or with ssh if `host` or `ssh` is provided. each = require 'each' exec = require 'ssh2-exec' misc = require './misc' conditions = require './misc/conditions' child = require './misc/child' ## Options * `cmd` String, Object or array; Command to execute. * `code` Expected code(s) returned by the command, int or array of int, default to 0. * `code_skipped` Expected code(s) returned by the command if it has no effect, executed will not be incremented, int or array of int. * `trap_on_error` Exit immediately if a commands exits with a non-zero status. * `cwd` Current working directory. * `env` Environment variables, default to `process.env`. * `gid` Unix group id. * `log` Function called with a log related messages. * `ssh` Run the action on a remote server using SSH, an ssh2 instance or an configuration object used to initialize the SSH connection. * `stdout` Writable Stream in which commands output will be piped. * `stderr` Writable Stream in which commands error will be piped. * `uid` Unix user id. ## Callback parameters * `err` Error if any enriched with the "code" property. * `executed` Number of executed commandes. * `stdout` Stdout value(s) unless `stdout` option is provided. * `stderr` Stderr value(s) unless `stderr` option is provided. ## Create a user over SSH: This example create a user on a remote server with the `useradd` command. It print the error message if the command failed or an information message. The "code_skipped" option indicates that the command is considered successfull but without any impact if it exits with a status equal to "9". ```javascript mecano.execute({ ssh: ssh cmd: "useradd myfriend" code_skipped: 9 }, function(err, created, stdout, stderr){ if(err){ console.log(err.message); }else if(created){ console.log("User created"); }else{ console.log("User already exists"); } }) ``` ## Implementation module.exports = (goptions, options, callback) -> [goptions, options, callback] = misc.args arguments result = child() finish = (err, created, stdout, stderr) -> callback err, created, stdout, stderr if callback result.end err, created isArray = Array.isArray options misc.options options, (err, options) -> return finish err if err executed = 0 stdouts = [] stderrs = [] escape = (cmd) -> esccmd = '' for char in cmd if char is '$' esccmd += '\\' esccmd += char esccmd stds = if callback then callback.length > 2 else false each( options ) .parallel(goptions.parallel) .on 'item', (options, i, next) -> # Validate parameters options = { cmd: options } if typeof options is 'string' return next new Error "Missing cmd: #{options.cmd}" unless options.cmd? options.code ?= [0] options.code = [options.code] unless Array.isArray options.code options.code_skipped ?= [] options.code_skipped = [options.code_skipped] unless Array.isArray options.code_skipped if options.trap_on_error options.cmd = "set -e\n#{options.cmd}" # Start real work cmd = () -> options.log? "Execute: #{options.cmd}" run = exec options stdout = stderr = [] if options.stdout run.stdout.pipe options.stdout, end: false if stds run.stdout.on 'data', (data) -> stdout.push data if options.stderr run.stderr.pipe options.stderr, end: false if stds run.stderr.on 'data', (data) -> stderr.push data run.on "exit", (code) -> # Givent some time because the "exit" event is sometimes # called before the "stdout" "data" event when runing # `make test` setTimeout -> stdouts.push if stds then stdout.join('') else undefined stderrs.push if stds then stderr.join('') else undefined if options.stdout run.stdout.unpipe options.stdout if options.stderr run.stderr.unpipe options.stderr if options.code.indexOf(code) is -1 and options.code_skipped.indexOf(code) is -1 err = new Error "Invalid exec code #{code}" err.code = code return next err executed++ if options.code_skipped.indexOf(code) is -1 next() , 1 conditions.all options, next, cmd .on 'both', (err) -> stdouts = stdouts[0] unless isArray stderrs = stderrs[0] unless isArray finish err, executed, stdouts, stderrs result