UNPKG

mecano

Version:

Common functions for system deployment.

349 lines (306 loc) 9.83 kB
// Generated by CoffeeScript 1.7.1 var each, exec, fs, misc; each = require('each'); misc = require('./misc'); exec = require('ssh2-exec'); fs = require('ssh2-fs'); /* Conditionnal properties ======================= */ module.exports = { /* `all(options, skip, succeed)` Run all conditions --------------------------------------------------- `opts` Command options `skip` Skip callback, called when a condition is not fulfill. May also be called with on error on failure `succeed` Succeed callback, only called if all the condition succeed */ all: function(options, skip, succeed) { return each([this["if"], this.not_if, this.if_exists, this.not_if_exists, this.should_exist]).on('item', function(condition, next) { return condition(options, skip, next); }).on('error', skip).on('end', succeed); }, /* `if` Run an action for a user defined condition ----------------------------------------------- Work on the property `if` in `options`. When `if` is a boolean, its value determine the output. If it's a callback, the function is called with the `options`, `skip` and `succeed` arguments. If it'a an array, all its element must positively resolve for the condition to pass. Updating the content of a file if we are the owner mecano.render source:'./file' if: (options, skip, succeed) -> fs.stat options.source, (err, stat) -> * File does not exists return skip err if err * Skip if we dont own the file return skip() unless stat.uid is process.getuid() * Succeed if we own the file succeed() */ "if": function(options, skip, succeed) { var ok; if (options["if"] == null) { return succeed(); } ok = true; return each(options["if"]).on('item', function(si, next) { var type; if (!ok) { return next(); } type = typeof si; if (type === 'boolean' || type === 'number') { if (!si) { ok = false; } return next(); } else if (type === 'function') { return si(options, (function() { ok = false; return next.apply(null, arguments); }), next); } else { return next(new Error("Invalid condition type")); } }).on('both', function(err) { if (err || !ok) { return skip(err); } return succeed(); }); }, /* `not_if` Run an action if false ------------------------------- Work on the property `if` in `options`. When `if` is a boolean, its value determine the output. If it's a callback, the function is called with the `options`, `skip` and `succeed` arguments. If it'a an array, all its element must positively resolve for the condition to pass. */ not_if: function(options, skip, succeed) { var ok; if (options.not_if == null) { return succeed(); } ok = true; return each(options.not_if).on('item', function(not_if, next) { var type; if (!ok) { return next(); } type = typeof not_if; if (type === 'boolean' || type === 'number') { if (not_if) { ok = false; } return next(); } else if (type === 'function') { return not_if(options, next, (function() { ok = false; return next.apply(null, arguments); })); } else { return next(new Error("Invalid condition type")); } }).on('both', function(err) { if (err || !ok) { return skip(err); } return succeed(); }); }, /* `if_exists` Run an action if a file exists ---------------------------------------- Work on the property `if_exists` in `options`. The value may be a file path or an array of file paths. You could also set the value to `true`, in which case it will be set with the `destination` option. The callback `succeed` is called if all the provided paths exists otherwise the callback `skip` is called. */ if_exists: function(options, skip, succeed) { if (options.if_exists == null) { return succeed(); } return each(options.if_exists).on('item', function(if_exists, next) { return fs.exists(options.ssh, if_exists, function(err, exists) { if (exists) { return next(); } else { return skip(); } }); }).on('end', succeed); }, /* `not_if_exists` Skip an action if a file exists ----------------------------------------------- Work on the property `not_if_exists` in `options`. The value may be a file path or an array of file paths. You could also set the value to `true`, in which case it will be set with the `destination` option. The callback `succeed` is called if none of the provided paths exists otherwise the callback `skip` is called. */ not_if_exists: function(options, skip, succeed) { if (options.not_if_exists == null) { return succeed(); } return each(options.not_if_exists).on('item', function(not_if_exists, next) { return fs.exists(options.ssh, not_if_exists, function(err, exists) { if (exists) { return next(new Error); } else { return next(); } }); }).on('error', function() { return skip(); }).on('end', succeed); }, /* `if_exec` Run an action if a command is successfully executed ------------------------------------------------------------- Work on the property `if_exec` in `options`. The value may be a single shell command or an array of commands. The callback `succeed` is called if all the provided command were executed successfully otherwise the callback `skip` is called. */ if_exec: function(options, skip, succeed) { if (options.if_exec == null) { return succeed(); } return each(options.if_exec).on('item', function(cmd, next) { var run; if (typeof options.log === "function") { options.log("Execute condition: " + cmd); } options = { cmd: cmd, ssh: options.ssh }; run = exec(options); if (options.stdout) { run.stdout.pipe(options.stdout, { end: false }); } if (options.stderr) { run.stderr.pipe(options.stderr, { end: false }); } return run.on("exit", function(code) { if (code === 0) { return next(); } else { return skip(); } }); }).on('end', succeed); }, /* `not_if_exec` Run an action unless a command is successfully executed --------------------------------------------------------------------- Work on the property `not_if_exec` in `options`. The value may be a single shell command or an array of commands. The callback `succeed` is called if all the provided command were executed with failure otherwise the callback `skip` is called. */ not_if_exec: function(options, skip, succeed) { if (options.not_if_exec == null) { return succeed(); } return each(options.not_if_exec).on('item', function(cmd, next) { var run; if (typeof options.log === "function") { options.log("Execute condition: " + cmd); } options = { cmd: cmd, ssh: options.ssh }; run = exec(options); if (options.stdout) { run.stdout.pipe(options.stdout, { end: false }); } if (options.stderr) { run.stderr.pipe(options.stderr, { end: false }); } return run.on("exit", function(code) { if (code === 0) { return next(new Error); } else { return next(); } }); }).on('error', function() { return skip(); }).on('end', succeed); }, /* `should_exist` Ensure a file exist ---------------------------------- Ensure that an action run if all the files present in the option "should_exist" exist. The value may be a file path or an array of file paths. The callback `succeed` is called if all of the provided paths exists otherwise the callback `skip` is called with an error. */ should_exist: function(options, skip, succeed) { if (options.should_exist == null) { return succeed(); } return each(options.should_exist).on('item', function(should_exist, next) { return fs.exists(options.ssh, should_exist, function(err, exists) { if (exists) { return next(); } else { return next(new Error("File does not exist: " + should_exist)); } }); }).on('error', function(err) { return skip(err); }).on('end', succeed); }, /* `should_not_exist` Ensure a file already exist ---------------------------------------------- Ensure that an action run if none of the files present in the option "should_exist" exist. The value may be a file path or an array of file paths. The callback `succeed` is called if none of the provided paths exists otherwise the callback `skip` is called with an error. */ should_not_exist: function(options, skip, succeed) { if (options.should_not_exist == null) { return succeed(); } return each(options.should_not_exist).on('item', function(should_not_exist, next) { return fs.exists(options.ssh, should_not_exist, function(err, exists) { if (exists) { return next(new Error("File does not exist: " + should_not_exist)); } else { return next(); } }); }).on('error', function(err) { return skip(err); }).on('end', function() { return succeed(); }); } };