You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
5.7 KiB
207 lines
5.7 KiB
/*jshint esversion: 6*/
|
|
//load database
|
|
var Datastore = require('nedb');
|
|
var db = new Datastore({ filename: __dirname + '/crontabs/crontab.db' });
|
|
|
|
db.loadDatabase(function (err) {
|
|
if (err) throw err; // no hope, just terminate
|
|
});
|
|
|
|
var exec = require('child_process').exec;
|
|
var fs = require('fs');
|
|
var cron_parser = require("cron-parser");
|
|
var os = require("os");
|
|
|
|
exports.log_folder = __dirname + '/crontabs/logs';
|
|
exports.env_file = __dirname + '/crontabs/env.db';
|
|
|
|
crontab = function(name, command, schedule, stopped, logging, mailing){
|
|
var data = {};
|
|
data.name = name;
|
|
data.command = command;
|
|
data.schedule = schedule;
|
|
if(stopped !== null) {
|
|
data.stopped = stopped;
|
|
}
|
|
data.timestamp = (new Date()).toString();
|
|
data.logging = logging;
|
|
if (!mailing)
|
|
mailing = {};
|
|
data.mailing = mailing;
|
|
return data;
|
|
};
|
|
|
|
exports.create_new = function(name, command, schedule, logging, mailing){
|
|
var tab = crontab(name, command, schedule, false, logging, mailing);
|
|
tab.created = new Date().valueOf();
|
|
db.insert(tab);
|
|
};
|
|
|
|
exports.update = function(data){
|
|
db.update({_id: data._id}, crontab(data.name, data.command, data.schedule, null, data.logging, data.mailing));
|
|
};
|
|
|
|
exports.status = function(_id, stopped){
|
|
db.update({_id: _id},{$set: {stopped: stopped}});
|
|
};
|
|
|
|
exports.remove = function(_id){
|
|
db.remove({_id: _id}, {});
|
|
};
|
|
|
|
// Iterates through all the crontab entries in the db and calls the callback with the entries
|
|
exports.crontabs = function(callback){
|
|
db.find({}).sort({ created: -1 }).exec(function(err, docs){
|
|
for(var i=0; i<docs.length; i++){
|
|
if(docs[i].schedule == "@reboot")
|
|
docs[i].next = "Next Reboot";
|
|
else
|
|
docs[i].next = cron_parser.parseExpression(docs[i].schedule).next().toString();
|
|
}
|
|
callback(docs);
|
|
});
|
|
};
|
|
|
|
// Set actual crontab file from the db
|
|
exports.set_crontab = function(env_vars, callback){
|
|
exports.crontabs( function(tabs){
|
|
var crontab_string = "";
|
|
if (env_vars) {
|
|
crontab_string = env_vars + "\n";
|
|
}
|
|
tabs.forEach(function(tab){
|
|
if(!tab.stopped) {
|
|
if (tab.logging && tab.logging == "true") {
|
|
let tmp_log = "/tmp/" + tab._id + ".log";
|
|
let log_file = exports.log_folder + "/" + tab._id + ".log";
|
|
if(tab.command[tab.command.length-1] != ";") // add semicolon
|
|
tab.command +=";";
|
|
// hook is in beta
|
|
if (tab.hook){
|
|
let tmp_hook = "/tmp/" + tab._id + ".hook";
|
|
crontab_string += tab.schedule + " ({ " + tab.command + " } | tee " + tmp_hook + ") 3>&1 1>&2 2>&3 | tee " + tmp_log +
|
|
"; if test -f " + tmp_log +
|
|
"; then date >> " + log_file +
|
|
"; cat " + tmp_log + " >> " + log_file +
|
|
"; rm " + tmp_log +
|
|
"; fi; if test -f " + tmp_hook +
|
|
"; then " + tab.hook + " < " + tmp_hook +
|
|
"; rm " + tmp_hook +
|
|
"; fi \n";
|
|
} else {
|
|
crontab_string += tab.schedule + " { " + tab.command + " } 2> " + tmp_log +
|
|
"; if test -f " + tmp_log +
|
|
"; then date >> " + log_file +
|
|
"; cat " + tmp_log + " >> " + log_file +
|
|
"; rm " + tmp_log +
|
|
"; fi \n";
|
|
}
|
|
}
|
|
else {
|
|
crontab_string += tab.schedule + " " + tab.command + "\n";
|
|
}
|
|
}
|
|
});
|
|
|
|
fs.writeFile(exports.env_file, env_vars, function(err) {
|
|
if (err) callback(err);
|
|
|
|
fs.writeFile("/tmp/crontab", crontab_string, function(err) {
|
|
if (err) return callback(err);
|
|
|
|
exec("crontab /tmp/crontab", function(err) {
|
|
if (err) return callback(err);
|
|
else callback();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
exports.get_backup_names = function(){
|
|
var backups = [];
|
|
fs.readdirSync(__dirname + '/crontabs').forEach(function(file){
|
|
// file name begins with backup
|
|
if(file.indexOf("backup") === 0){
|
|
backups.push(file);
|
|
}
|
|
});
|
|
|
|
// Sort by date. Newest on top
|
|
for(var i=0; i<backups.length; i++){
|
|
var Ti = backups[i].split("backup")[1];
|
|
Ti = new Date(Ti.substring(0, Ti.length-3)).valueOf();
|
|
for(var j=0; j<i; j++){
|
|
var Tj = backups[j].split("backup")[1];
|
|
Tj = new Date(Tj.substring(0, Tj.length-3)).valueOf();
|
|
if(Ti > Tj){
|
|
var temp = backups[i];
|
|
backups[i] = backups[j];
|
|
backups[j] = temp;
|
|
}
|
|
}
|
|
}
|
|
|
|
return backups;
|
|
};
|
|
|
|
exports.backup = function(){
|
|
//TODO check if it failed
|
|
fs.createReadStream( __dirname + '/crontabs/crontab.db').pipe(fs.createWriteStream( __dirname + '/crontabs/backup ' + (new Date()).toString().replace("+", " ") + '.db'));
|
|
};
|
|
|
|
exports.restore = function(db_name){
|
|
fs.createReadStream( __dirname + '/crontabs/' + db_name).pipe(fs.createWriteStream( __dirname + '/crontabs/crontab.db'));
|
|
db.loadDatabase(); // reload the database
|
|
};
|
|
|
|
exports.reload_db = function(){
|
|
db.loadDatabase();
|
|
};
|
|
|
|
exports.get_env = function(){
|
|
if (fs.existsSync(exports.env_file)) {
|
|
return fs.readFileSync(exports.env_file , 'utf8').replace("\n", "\n");
|
|
}
|
|
return "";
|
|
};
|
|
|
|
exports.import_crontab = function(){
|
|
exec("crontab -l", function(error, stdout, stderr){
|
|
var lines = stdout.split("\n");
|
|
var namePrefix = new Date().getTime();
|
|
|
|
lines.forEach(function(line, index){
|
|
var regex = /^((\@[a-zA-Z]+\s)|(([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s))/;
|
|
var command = line.replace(regex, '').trim();
|
|
var schedule = line.replace(command, '').trim();
|
|
|
|
var is_valid = false;
|
|
try { is_valid = cron_parser.parseString(line).expressions.length > 0; } catch (e){}
|
|
|
|
if(command && schedule && is_valid){
|
|
var name = namePrefix + '_' + index;
|
|
|
|
db.findOne({ command: command, schedule: schedule }, function(err, doc) {
|
|
if(err) {
|
|
throw err;
|
|
}
|
|
if(!doc){
|
|
exports.create_new(name, command, schedule, null);
|
|
}
|
|
else{
|
|
doc.command = command;
|
|
doc.schedule = schedule;
|
|
exports.update(doc);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
exports.autosave_crontab = function(callback) {
|
|
let env_vars = exports.get_env();
|
|
exports.set_crontab(env_vars, callback);
|
|
};
|