reading from crontab db and populating UI
parent
e5b466aa50
commit
035d432b7a
|
@ -1,18 +1,20 @@
|
||||||
Crontab UI
|
Crontab UI
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Easily manage your cron jobs
|
Editing the plain text crontab is error prone for managing jobs, e.g., adding jobs, deleting jobs, or pausing jobs. A small mistake can easily bring down all the jobs and might cost you a lot of time. With Crontab UI, it is very easy to manage crontab. Here are the key features of Crontab UI.
|
||||||
|
|
||||||
1. Easy setup
|
1. Easy setup
|
||||||
2. Easy management of jobs
|
2. Easy and safe adding, deleting or pausing jobs. Easy to maintain hundreds of jobs.
|
||||||
3. Backups
|
3. Backups
|
||||||
4. Download and schedule scripts which are online
|
4. Download and schedule scripts which are online
|
||||||
|
5. Manage crontabs on multiple machines easily. No SSH, No copy-pasting.
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
1. Run jobs as different user
|
1. Run jobs as different user
|
||||||
2. Online backup
|
2. Online backup
|
||||||
3. Profiling jobs
|
3. Profiling jobs
|
||||||
|
4. Logs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
4
app.js
4
app.js
|
@ -18,11 +18,13 @@ app.set('port', (process.env.PORT || 8000));
|
||||||
|
|
||||||
app.get(routes.root, function(req, res) {
|
app.get(routes.root, function(req, res) {
|
||||||
// get all the crontabs
|
// get all the crontabs
|
||||||
|
//crontab.create_new("/usr/bin/find", "0 2 12 * *");
|
||||||
|
//crontab.create_new("/sbin/ping -c 1 192.168.0.1 > /dev/null", "* * * * *");
|
||||||
crontab.crontabs( function(docs){
|
crontab.crontabs( function(docs){
|
||||||
console.log(docs);
|
console.log(docs);
|
||||||
res.render('index', {
|
res.render('index', {
|
||||||
routes : routes,
|
routes : routes,
|
||||||
crontabs : docs
|
crontabs : JSON.stringify(docs)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
10
crontab.js
10
crontab.js
|
@ -6,8 +6,9 @@ db.loadDatabase(function (err) {
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
crontab = function(command, schedule, stopped){
|
crontab = function(name, command, schedule, stopped){
|
||||||
var data = {};
|
var data = {};
|
||||||
|
data.name = name;
|
||||||
data.command = command;
|
data.command = command;
|
||||||
data.schedule = schedule;
|
data.schedule = schedule;
|
||||||
data.stopped = stopped;
|
data.stopped = stopped;
|
||||||
|
@ -15,8 +16,8 @@ crontab = function(command, schedule, stopped){
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.create_new = function(command, schedule){
|
exports.create_new = function(name, command, schedule){
|
||||||
var tab = crontab(command, schedule, false);
|
var tab = crontab(name, command, schedule, false);
|
||||||
db.insert(tab);
|
db.insert(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +36,8 @@ exports.set_crontab = function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fs.writeFile("/tmp/crontab", crontab_string, function(err) {
|
fs.writeFile("/tmp/crontab", crontab_string, function(err) {
|
||||||
//couldnt write
|
exec("crontab /tmp/crontab");
|
||||||
});
|
});
|
||||||
|
|
||||||
exec("crontab /tmp/crontab");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*********** MessageBox ****************/
|
||||||
|
// simply show info. Only close button
|
||||||
|
function infoMessageBox(message, title){
|
||||||
|
$("#modal-body").html(message);
|
||||||
|
$("#modal-title").html(title);
|
||||||
|
$("#modal-button").hide();
|
||||||
|
$("#popup").modal('show');
|
||||||
|
}
|
||||||
|
// modal with full control
|
||||||
|
function messageBox(body, title, ok_text, close_text, callback){
|
||||||
|
$("#modal-body").html(body);
|
||||||
|
$("#modal-title").html(title);
|
||||||
|
if (ok_text) $("#modal-button").html(ok_text);
|
||||||
|
$("#modal-button").show();
|
||||||
|
if(close_text) $("#modal-close-button").html(close_text);
|
||||||
|
$("#modal-button").click(callback);
|
||||||
|
$("#popup").modal("show");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********** crontab actions ****************/
|
||||||
|
|
||||||
|
function deleteJob(_id){
|
||||||
|
// TODO fix this. pass callback properly
|
||||||
|
messageBox("<p> Do you want to delete this Job? </p>", "Confirm delete", null, null, function(){
|
||||||
|
console.log("delete job");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopJob(_id){
|
||||||
|
messageBox("<p> Do you want to stop this Job? </p>", "Confirm stop job", null, null, function(){
|
||||||
|
console.log("stop job");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startJob(_id){
|
||||||
|
messageBox("<p> Do you want to start this Job? </p>", "Confirm start job", null, null, function(){
|
||||||
|
console.log("start job");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function editJob(_id){
|
||||||
|
var job = null;
|
||||||
|
crontabs.forEach(function(crontab){
|
||||||
|
if(crontab._id == _id)
|
||||||
|
job = crontab;
|
||||||
|
});
|
||||||
|
if(job){
|
||||||
|
$("#job").modal("show");
|
||||||
|
$("#job-name").val(job.name);
|
||||||
|
$("#job-command").val(job.command);
|
||||||
|
// if macro not used
|
||||||
|
if(job.schedule.indexOf("@") != 0){
|
||||||
|
var components = job.schedule.split(" ");
|
||||||
|
console.log(components);
|
||||||
|
$("#job-minute").val(components[0]);
|
||||||
|
$("#job-hour").val(components[1]);
|
||||||
|
$("#job-day").val(components[2]);
|
||||||
|
$("#job-month").val(components[3]);
|
||||||
|
$("#job-week").val(components[4]);
|
||||||
|
}
|
||||||
|
schedule = job.schedule;
|
||||||
|
job_command = job.command;
|
||||||
|
job_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function newJob(){
|
||||||
|
$("#job").modal("show");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// script corresponding to job popup management
|
||||||
|
var schedule = "";
|
||||||
|
var job_command = "";
|
||||||
|
function job_string(){
|
||||||
|
$("#job-string").val(schedule + " " + job_command);
|
||||||
|
return schedule + " " + job_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_schedule(){
|
||||||
|
schedule = $("#job-minute").val() + " " +$("#job-hour").val() + " " +$("#job-day").val() + " " +$("#job-month").val() + " " +$("#job-week").val();
|
||||||
|
job_string();
|
||||||
|
}
|
|
@ -2,55 +2,72 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Crontab UI</title>
|
<title>Crontab UI</title>
|
||||||
<script src="jquery.js"></script>
|
<script src="jquery.js"></script>
|
||||||
|
<script src="script.js"></script>
|
||||||
<script src="bootstrap.min.js"></script>
|
<script src="bootstrap.min.js"></script>
|
||||||
<link rel="stylesheet" href="bootstrap.min.css" />
|
<link rel="stylesheet" href="bootstrap.min.css" />
|
||||||
|
<script type="text/javascript">
|
||||||
|
var crontabs = [];
|
||||||
|
$(function () {
|
||||||
|
// initialize tooltips
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
crontabs = JSON.parse('<%- crontabs %>');
|
||||||
|
})
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<% include navbar %>
|
<% include navbar %>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>Jobs</h2>
|
<h2>Cronjobs</h2>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
|
<th></th>
|
||||||
<th>Job</th>
|
<th>Job</th>
|
||||||
<th>Time</th>
|
<th>Time</th>
|
||||||
<th>Last Modified</th>
|
<th>Last Modified</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
<% crontabs.forEach(function(crontab){ %>
|
<% JSON.parse(crontabs).forEach(function(crontab){ %>
|
||||||
|
<!-- color based on crontab state -->
|
||||||
<% if (!crontab.stopped) { %>
|
<% if (!crontab.stopped) { %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><%= crontab.command %></td>
|
|
||||||
<td><%= crontab.schedule %></td>
|
|
||||||
<td><%= crontab.timestamp %></td>
|
|
||||||
<td>
|
|
||||||
<a class="btn btn-primary"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span> Edit</a>
|
|
||||||
<a class="btn btn-info"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a>
|
|
||||||
<a class="btn btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<tr style="background:#3A6DA6;color:#fff">
|
<tr style="background:#3A6DA6;color:#fff">
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<% if (crontab.name) { %>
|
||||||
|
<a class="btn" data-toggle="tooltip" data-placement="right" title="<%= crontab.name %>"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> </a>
|
||||||
|
<% } %>
|
||||||
|
</td>
|
||||||
<td><%= crontab.command %></td>
|
<td><%= crontab.command %></td>
|
||||||
<td><%= crontab.schedule %></td>
|
<td><%= crontab.schedule %></td>
|
||||||
<td><%= crontab.timestamp %></td>
|
<td><%= crontab.timestamp %></td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn-info"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a>
|
|
||||||
<a class="btn btn-danger"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
|
<!-- controls based on crontab state -->
|
||||||
|
<% if (!crontab.stopped) { %>
|
||||||
|
<a class="btn btn-primary" onclick="editJob('<%= crontab._id %>')"><span class="glyphicon glyphicon-edit" aria-hidden="true"></span> Edit</a>
|
||||||
|
<a class="btn btn-info" onclick="stopJob('<%= crontab._id %>')"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a>
|
||||||
|
<% } else { %>
|
||||||
|
<a class="btn btn-info" onclick="startJob('<%= crontab._id %>')"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a>
|
||||||
|
<% } %>
|
||||||
|
<a class="btn btn-danger" onclick="deleteJob('<%= crontab._id %>')"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% } %>
|
|
||||||
<% }); %>
|
<% }); %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<a class="btn btn-primary"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> New</a>
|
<a class="btn btn-primary" onclick="newJob();"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> New</a>
|
||||||
<a class="btn btn-info"><span class="glyphicon glyphicon-floppy-save" aria-hidden="true"></span> Backup</a>
|
<a class="btn btn-info"><span class="glyphicon glyphicon-floppy-save" aria-hidden="true"></span> Backup</a>
|
||||||
<a class="btn btn-info"><span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span> Export</a>
|
<a class="btn btn-info"><span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span> Export</a>
|
||||||
<span id="save-reset">
|
<a class="btn btn-info"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import from crontab</a>
|
||||||
<a class="btn btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Reset</a>
|
<a class="btn btn-success"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Save to crontab</a>
|
||||||
<a class="btn btn-success"><span class="glyphicon glyphicon-save" aria-hidden="true"></span> Save</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
<% include popup.ejs %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<div class="modal fade" id="popup">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title" id="modal-title">Message</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" id="modal-body">
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal" id="modal-close-button">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal" id="modal-button">Ok</button>
|
||||||
|
</div>
|
||||||
|
</div><!-- /.modal-content -->
|
||||||
|
</div><!-- /.modal-dialog -->
|
||||||
|
</div><!-- /.modal -->
|
||||||
|
|
||||||
|
<!-- Job -->
|
||||||
|
<div class="modal fade" id="job">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title" id="job-title">Job</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" id="job-body">
|
||||||
|
<label>Name (Optional)</label>
|
||||||
|
<input type='text' class='form-control' id='job-name'/><br />
|
||||||
|
<label>Command</label>
|
||||||
|
<input type='text' class='form-control' id='job-command' onkeyup="job_command = $(this).val(); job_string();"/><br />
|
||||||
|
<label>Quick Schedule</label><br />
|
||||||
|
<a class="btn btn-primary" onclick="schedule = '@startup'; job_string();">Startup</a>
|
||||||
|
<a class="btn btn-primary" onclick="schedule = '@hourly'; job_string();">Hourly</a>
|
||||||
|
<a class="btn btn-primary" onclick="schedule = '@daily'; job_string();">Daily</a>
|
||||||
|
<a class="btn btn-primary" onclick="schedule = '@monthly'; job_string();">Monthly</a>
|
||||||
|
<a class="btn btn-primary" onclick="schedule = '@yearly'; job_string();">Yearly</a><br /><br />
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">Minute</div>
|
||||||
|
<div class="col-md-2">Hour</div>
|
||||||
|
<div class="col-md-2">Day</div>
|
||||||
|
<div class="col-md-2">Month</div>
|
||||||
|
<div class="col-md-2">Week</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2"><input type="text" class="form-control" id="job-minute" value="*" onclick="this.select();"/></div>
|
||||||
|
<div class="col-md-2"><input type="text" class="form-control" id="job-hour" value="*" onclick="this.select();"/></div>
|
||||||
|
<div class="col-md-2"><input type="text" class="form-control" id="job-day" value="*" onclick="this.select();"/></div>
|
||||||
|
<div class="col-md-2"><input type="text" class="form-control" id="job-month" value="*" onclick="this.select();"/></div>
|
||||||
|
<div class="col-md-2"><input type="text" class="form-control" id="job-week" value="*" onclick="this.select();"/></div>
|
||||||
|
<div class="col-md-2"><a class="btn btn-primary" onclick="set_schedule();">Set</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<label>Job</label>
|
||||||
|
<input type='text' class='form-control' id='job-string' disabled='disabled'/><br />
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Save</button>
|
||||||
|
</div>
|
||||||
|
</div><!-- /.modal-content -->
|
||||||
|
</div><!-- /.modal-dialog -->
|
||||||
|
</div><!-- /.modal -->
|
Loading…
Reference in New Issue