mecano
Version:
Common functions for system deployment.
344 lines (337 loc) • 10.4 kB
JavaScript
// Generated by CoffeeScript 1.7.1
var child, conditions, each, execute, misc;
each = require('each');
misc = require('./misc');
conditions = require('./misc/conditions');
child = require('./misc/child');
execute = require('./execute');
module.exports = function(goptions, options, callback) {
var installed, updates, _ref;
_ref = misc.args(arguments, {
parallel: 1
}), goptions = _ref[0], options = _ref[1], callback = _ref[2];
installed = updates = null;
return misc.options(options, function(err, options) {
var serviced;
if (err) {
return callback(err);
}
serviced = 0;
return each(options).parallel(goptions.parallel).on('item', function(options, next) {
var action, chkinstalled, chkname, chkupdates, finish, install, modified, pkgname, srvname, started, startup_add, startup_del, startuped;
if (!options.ssh) {
return next(new Error('Restricted to Yum over SSH'));
}
pkgname = options.yum_name || options.name;
chkname = options.chk_name || options.srv_name || options.name;
srvname = options.srv_name || options.name;
if ((options.startup != null) && typeof options.startup !== 'string') {
options.startup = options.startup ? '2345' : '';
}
modified = false;
if (installed == null) {
installed = options.installed;
}
if (updates == null) {
updates = options.updates;
}
chkinstalled = function() {
var cache, decide;
if (!pkgname) {
return startuped();
}
cache = function() {
var c;
if (typeof options.log === "function") {
options.log("List installed packages");
}
c = options.cache ? '-C' : '';
return execute({
ssh: options.ssh,
cmd: "yum -C list installed",
code_skipped: 1,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err, executed, stdout) {
var pkg, start, _i, _len;
if (err) {
return next(err);
}
stdout = stdout.split('\n');
start = false;
installed = [];
for (_i = 0, _len = stdout.length; _i < _len; _i++) {
pkg = stdout[_i];
if (pkg.trim() === 'Installed Packages') {
start = true;
}
if (!start) {
continue;
}
if (pkg = /^([^\. ]+?)\./.exec(pkg)) {
installed.push(pkg[1]);
}
}
return decide();
});
};
decide = function() {
if (installed.indexOf(pkgname) !== -1) {
return chkupdates();
} else {
return install();
}
};
if (installed) {
return decide();
} else {
return cache();
}
};
chkupdates = function() {
var cache, decide;
cache = function() {
var c;
if (typeof options.log === "function") {
options.log("List available updates");
}
c = options.cache ? '-C' : '';
return execute({
ssh: options.ssh,
cmd: "yum " + c + " list updates",
code_skipped: 1,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err, executed, stdout) {
var pkg, start, _i, _len;
if (err) {
return next(err);
}
stdout = stdout.split('\n');
start = false;
updates = [];
for (_i = 0, _len = stdout.length; _i < _len; _i++) {
pkg = stdout[_i];
if (pkg.trim() === 'Updated Packages') {
start = true;
}
if (!start) {
continue;
}
if (pkg = /^([^\. ]+?)\./.exec(pkg)) {
updates.push(pkg[1]);
}
}
return decide();
});
};
decide = function() {
if (updates.indexOf(pkgname) !== -1) {
return install();
} else {
if (typeof options.log === "function") {
options.log("No available update");
}
return startuped();
}
};
if (updates) {
return decide();
} else {
return cache();
}
};
install = function() {
if (typeof options.log === "function") {
options.log("Package installation: " + pkgname);
}
return execute({
ssh: options.ssh,
cmd: "yum install -y " + pkgname,
code_skipped: 1,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err, succeed) {
var installedIndex, updatesIndex;
if (err) {
return next(err);
}
installedIndex = installed.indexOf(pkgname);
if (installedIndex === -1) {
installed.push(pkgname);
}
if (updates) {
updatesIndex = updates.indexOf(pkgname);
if (updatesIndex !== -1) {
updates.splice(updatesIndex, 1);
}
}
if (!succeed) {
return next(new Error("No package " + pkgname + " available."));
}
if (installedIndex !== -1) {
modified = true;
}
return startuped();
});
};
startuped = function() {
if (options.startup == null) {
return started();
}
if (typeof options.log === "function") {
options.log("List startup services");
}
return execute({
ssh: options.ssh,
cmd: "chkconfig --list " + chkname,
code_skipped: 1,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err, registered, stdout, stderr) {
var c, current_startup, level, status, _i, _len, _ref1, _ref2;
if (err) {
return next(err);
}
if (/^error/.test(stderr)) {
return next(new Error("Invalid chkconfig name " + chkname));
}
current_startup = '';
if (registered) {
_ref1 = stdout.split(' ').pop().trim().split('\t');
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
c = _ref1[_i];
_ref2 = c.split(':'), level = _ref2[0], status = _ref2[1];
if (['on', 'marche'].indexOf(status) > -1) {
current_startup += level;
}
}
}
if (options.startup === current_startup) {
return started();
}
modified = true;
if (options.startup != null) {
return startup_add();
} else {
return startup_del();
}
});
};
startup_add = function() {
var cmd, i, startup_off, startup_on, _i;
if (typeof options.log === "function") {
options.log("Add startup service");
}
startup_on = startup_off = '';
for (i = _i = 0; _i < 6; i = ++_i) {
if (options.startup.indexOf(i) !== -1) {
startup_on += i;
} else {
startup_off += i;
}
}
cmd = "chkconfig --add " + chkname + ";";
if (startup_on) {
cmd += "chkconfig --level " + startup_on + " " + chkname + " on;";
}
if (startup_off) {
cmd += "chkconfig --level " + startup_off + " " + chkname + " off;";
}
return execute({
ssh: options.ssh,
cmd: cmd,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err) {
if (err) {
return next(err);
}
return started();
});
};
startup_del = function() {
if (typeof options.log === "function") {
options.log("Remove startup service");
}
return execute({
ssh: options.ssh,
cmd: "chkconfig --del " + chkname,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err) {
if (err) {
return next(err);
}
return started();
});
};
started = function() {
if (['start', 'stop', 'restart'].indexOf(options.action) === -1) {
return action();
}
if (typeof options.log === "function") {
options.log("Check if service " + srvname + " is started");
}
return execute({
ssh: options.ssh,
cmd: "service " + srvname + " status",
code_skipped: [3, 1],
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err, started) {
if (err) {
return next(err);
}
if (started) {
if (options.action !== 'start') {
return action();
}
} else {
if (options.action !== 'stop') {
return action();
}
}
return finish();
});
};
action = function() {
if (!options.action) {
return finish();
}
if (typeof options.log === "function") {
options.log("Start/stop the service");
}
return execute({
ssh: options.ssh,
cmd: "service " + srvname + " " + options.action,
log: options.log,
stdout: options.stdout,
stderr: options.stderr
}, function(err, executed) {
if (err) {
return next(err);
}
modified = true;
return finish();
});
};
finish = function() {
if (modified) {
serviced++;
}
return next();
};
return conditions.all(options, next, chkinstalled);
}).on('both', function(err) {
return callback(err, serviced, installed, updates);
});
});
};