mecano
Version:
Common functions for system deployment.
163 lines (156 loc) • 5.17 kB
JavaScript
// Generated by CoffeeScript 1.11.1
var connect, exec, fs, misc, util;
module.exports = {
handler: function(options) {
var rebooting, ref;
options.log({
message: "Entering ssh.root",
level: 'DEBUG',
module: 'mecano/lib/ssh/root'
});
if (options.host == null) {
options.host = options.ip;
}
if (options.username == null) {
options.username = null;
}
if (options.password == null) {
options.password = null;
}
if (options.selinux == null) {
options.selinux = false;
}
if (options.selinux === true) {
options.selinux = 'permissive';
}
if (options.selinux && ((ref = options.selinux) !== 'enforcing' && ref !== 'permissive' && ref !== 'disabled')) {
throw Error("Invalid option \"selinux\": " + options.selinux);
}
rebooting = false;
this.call({
"if": options.public_key_path,
unless: options.public_key
}, function(_, callback) {
return misc.path.normalize(options.public_key_path, (function(_this) {
return function(location) {
return fs.readFile(location, 'ascii', function(err, content) {
if (err && err.code === 'ENOENT') {
return callback(Error("Private key doesnt exists: " + (JSON.stringify(location))));
}
if (err) {
return callback(err);
}
options.public_key = content;
return callback();
});
};
})(this));
});
this.call({
"if": options.private_key_path,
unless: options.private_key
}, function(_, callback) {
return misc.path.normalize(options.private_key_path, (function(_this) {
return function(location) {
return fs.readFile(location, 'ascii', function(err, content) {
if (err && err.code === 'ENOENT') {
return callback(Error("Private key doesnt exists: " + (JSON.stringify(location))));
}
if (err) {
return callback(err);
}
options.private_key = content;
return callback();
});
};
})(this));
});
this.call(function(_, callback) {
return connect(options, function(err, ssh) {
var child, cmd;
if (err) {
return callback(err);
}
cmd = [];
cmd.push("sed -i.back 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config;");
if (options.public_key) {
cmd.push("mkdir -p /root/.ssh; chmod 700 /root/.ssh;\necho '" + options.public_key + "' >> /root/.ssh/authorized_keys;");
}
cmd.push("sed -i.back 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config;\nselinux=\"" + (options.selinux || '') + "\";\nif [ -n \"$selinux\" ] && [ -f /etc/selinux/config ] && grep ^SELINUX=\"$selinux\" /etc/selinux/config;\nthen\n sed -i.back \"s/^SELINUX=enforcing/SELINUX=$selinux/\" /etc/selinux/config;\n reboot;\n exit 2;\nfi;");
cmd = cmd.join('\n');
if (options.username !== 'root') {
cmd = cmd.replace(/\n/g, ' ');
if (typeof options.cmd === 'function') {
cmd = options.cmd(cmd);
} else if (typeof options.cmd === 'string') {
cmd = options.cmd + " " + cmd;
} else {
options.cmd = 'sudo ';
if (options.user) {
options.cmd += "-u " + options.user + " ";
}
if (options.password) {
options.cmd = "echo -e \"" + options.password + "\\n\" | " + options.cmd + " -S ";
}
options.cmd += "-- sh -c \"" + cmd + "\"";
cmd = options.cmd;
}
}
child = exec({
ssh: ssh,
cmd: cmd
}, function(err) {
if ((err != null ? err.code : void 0) === 2) {
err = null;
rebooting = true;
}
return callback(err);
});
child.stdout.on('data', function(data) {
return options.log({
message: data,
type: 'stdout'
});
});
child.stdout.on('end', function(data) {
return options.log({
message: null,
type: 'stdout'
});
});
child.stderr.on('data', function(data) {
return options.log({
message: data,
type: 'stderr'
});
});
return child.stderr.on('end', function(data) {
return options.log({
message: null,
type: 'stderr'
});
});
});
});
return this.call({
retry: true,
"if": rebooting
}, function(_, callback) {
return connect(config, (function(_this) {
return function(err, conn) {
if (!conn) {
return callback(err);
}
conn.end();
conn.on('error', callback);
return conn.on('end', callback);
};
})(this));
});
}
};
fs = require('fs');
util = require('util');
connect = require('ssh2-connect');
exec = require('ssh2-exec');
misc = require('../misc');