1
0
mirror of https://github.com/newnius/YAO-portal.git synced 2025-12-13 00:56:44 +00:00

init & add agent & add job

This commit is contained in:
2019-01-15 10:02:28 +08:00
parent 71f1f10e2c
commit d0a4b891b5
321 changed files with 24657 additions and 1 deletions

144
static/agent.js Executable file
View File

@@ -0,0 +1,144 @@
function register_events_agent() {
$('#btn-agent-add').click(function (e) {
$('#form-agent-submit-type').val('add');
$('#modal-agent').modal('show');
});
$("#form-agent-submit").click(function (e) {
var ip = $('#form-agent-ip').val();
var alias = $('#form-agent-alias').val();
var cluster = $('#form-agent-cluster').val();
/* TODO validate form */
$('#modal-agent').modal('hide');
if ($('#form-agent-submit-type').val() !== 'add')
return;
var ajax = $.ajax({
url: window.config.BASE_URL + "/service?action=agent_add",
type: 'POST',
data: {
ip: ip,
alias: alias,
cluster: cluster
}
});
ajax.done(function (res) {
if (res["errno"] !== 0) {
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
}
$('#table-agent').bootstrapTable("refresh");
});
ajax.fail(function (jqXHR, textStatus) {
$("#modal-msg-content").html("Request failed : " + jqXHR.statusText);
$("#modal-msg").modal('show');
$('#table-agent').bootstrapTable("refresh");
});
});
}
function load_agents(cluster) {
$("#table-agent").bootstrapTable({
url: window.config.BASE_URL + '/service?action=agent_list&who=' + cluster,
responseHandler: agentResponseHandler,
sidePagination: 'server',
cache: true,
striped: true,
pagination: true,
pageSize: 10,
pageList: [10, 25, 50, 100, 200],
search: false,
showColumns: true,
showRefresh: true,
showToggle: false,
showPaginationSwitch: true,
minimumCountColumns: 2,
clickToSelect: false,
sortName: 'nobody',
sortOrder: 'desc',
smartDisplay: true,
mobileResponsive: true,
showExport: true,
columns: [{
field: 'alias',
title: 'Alias',
align: 'center',
valign: 'middle',
escape: true
}, {
field: 'ip',
title: 'IP',
align: 'center',
valign: 'middle',
formatter: long2ip
}, {
field: 'cluster',
title: 'Cluster',
align: 'center',
valign: 'middle'
}, {
field: 'operate',
title: 'Operate',
align: 'center',
events: agentOperateEvents,
formatter: agentOperateFormatter
}]
});
}
function agentResponseHandler(res) {
if (res['errno'] === 0) {
var tmp = {};
tmp["total"] = res["count"];
tmp["rows"] = res["agents"];
return tmp;
}
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
return [];
}
function agentOperateFormatter(value, row, index) {
var div = '<div class="btn-group" role="group" aria-label="...">';
div += '<button class="btn btn-default view"><i class="glyphicon glyphicon-eye-open"></i>&nbsp;</button>';
div += '<button class="btn btn-default remove"><i class="glyphicon glyphicon-remove"></i>&nbsp;</button>';
div += '</div>';
return div;
}
window.agentOperateEvents = {
'click .view': function (e, value, row, index) {
$('#form-agent-id').val(row.id);
$('#form-agent-ip').val(long2ip(row.ip));
$('#form-agent-alias').val(row.alias);
$('#form-agent-token').val(row.token);
$('#form-agent-submit-type').val('view');
$('#modal-agent').modal('show');
},
'click .remove': function (e, value, row, index) {
if (!confirm('Are you sure to remove this agent?')) {
return;
}
var ajax = $.ajax({
url: window.config.BASE_URL + "/service?action=agent_remove",
type: 'POST',
data: {id: row.id}
});
ajax.done(function (res) {
if (res["errno"] !== 0) {
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
}
$('#table-agent').bootstrapTable("refresh");
});
ajax.fail(function (jqXHR, textStatus) {
$("#modal-msg-content").html("Request failed : " + jqXHR.statusText);
$("#modal-msg").modal('show');
$('#table-agent').bootstrapTable("refresh");
});
}
};

5
static/config.js Normal file
View File

@@ -0,0 +1,5 @@
window.config = {
'BASE_URL': 'http://127.0.0.1' /* No '/' at the end */
};

233
static/job.js Executable file
View File

@@ -0,0 +1,233 @@
function register_events_job() {
$('#btn-job-add').click(function (e) {
$('#modal-job').modal('show');
});
$("#form-job-submit").click(function (e) {
var name = $('#form-job-name').val();
var image = $('#form-job-image').val();
var workspace = $('#form-job-workspace').val();
var cluster = $('#form-job-cluster').val();
var priority = $('#form-job-priority').val();
var run_before = $('#form-job-run-before').val();
if (run_before.length !== 0) {
run_before = moment(run_before).unix();
}
var tasks = [];
/* TODO validate form */
$('#modal-job').modal('hide');
var ajax = $.ajax({
url: window.config.BASE_URL + "/service?action=job_submit",
type: 'POST',
data: {
name: name,
image: image,
workspace: workspace,
cluster: cluster,
priority: priority,
run_before: run_before,
tasks: JSON.stringify(tasks)
}
});
ajax.done(function (res) {
if (res["errno"] !== 0) {
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
}
$('#table-job').bootstrapTable("refresh");
});
ajax.fail(function (jqXHR, textStatus) {
$("#modal-msg-content").html("Request failed : " + jqXHR.statusText);
$("#modal-msg").modal('show');
$('#table-job').bootstrapTable("refresh");
});
});
}
function load_jobs(scope) {
$("#table-job").bootstrapTable({
url: window.config.BASE_URL + '/service?action=job_list&who=' + scope,
responseHandler: jobResponseHandler,
sidePagination: 'server',
cache: true,
striped: true,
pagination: true,
pageSize: 10,
pageList: [10, 25, 50, 100, 200],
search: false,
showColumns: true,
showRefresh: true,
showToggle: false,
showPaginationSwitch: true,
minimumCountColumns: 2,
clickToSelect: false,
sortName: 'nobody',
sortOrder: 'desc',
smartDisplay: true,
mobileResponsive: true,
showExport: true,
columns: [{
field: 'created_by',
title: 'Created By',
align: 'center',
valign: 'middle',
formatter: UIDFormatter,
visible: scope === 'all'
}, {
field: 'name',
title: 'Name',
align: 'center',
valign: 'middle',
escape: true
}, {
field: 'image',
title: 'Docker Image',
align: 'center',
valign: 'middle',
visible: false,
escape: true
}, {
field: 'workspace',
title: 'Workspace',
align: 'center',
valign: 'middle',
visible: false,
formatter: workspaceFormatter
}, {
field: 'virtual_cluster',
title: 'Virtual Cluster',
align: 'center',
valign: 'middle',
formatter: clusterFormatter
}, {
field: 'priority',
title: 'Priority',
align: 'center',
valign: 'middle',
formatter: priorityFormatter
}, {
field: 'run_before',
title: 'Run Before',
align: 'center',
valign: 'middle',
visible: false,
formatter: timeFormatter
}, {
field: 'created_at',
title: 'Created At',
align: 'center',
valign: 'middle',
formatter: timeFormatter
}, {
field: 'status',
title: 'Status',
align: 'center',
valign: 'middle',
formatter: statusFormatter,
visible: true
}, {
field: 'operate',
title: 'Operate',
align: 'center',
events: jobOperateEvents,
formatter: jobOperateFormatter
}]
});
}
var UIDFormatter = function (UID) {
return UID;
};
var workspaceFormatter = function (workspace) {
return workspace;
};
var clusterFormatter = function (cluster) {
return cluster;
};
var priorityFormatter = function (status) {
switch (status) {
case '1':
return '<span class="text-normal">Low</span>';
case '25':
return '<span class="text-info">Medium</span>';
case '50':
return '<span class="text-success">High</span>';
case '99':
return '<span class="text-danger">Urgent</span>';
}
return 'Unknown (' + status + ')';
};
var statusFormatter = function (status) {
switch (status) {
case '0':
return '<span class="text-normal">Pending</span>';
case '1':
return '<span class="text-info">Running</span>';
case '2':
return '<span class="text-success">Finished</span>';
case '3':
return '<span class="text-danger">Stopped</span>';
}
return 'Unknown(' + status + ')';
};
function jobResponseHandler(res) {
if (res['errno'] === 0) {
var tmp = {};
tmp["total"] = res["count"];
tmp["rows"] = res["jobs"];
return tmp;
}
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
return [];
}
function jobOperateFormatter(value, row, index) {
var div = '<div class="btn-group" role="group" aria-label="...">';
if (page_type === 'jobs')
div += '<button class="btn btn-default view"><i class="glyphicon glyphicon-eye-open"></i>&nbsp;</button>';
if (page_type === 'jobs' && (row.status === '0' || row.status === '1'))
div += '<button class="btn btn-default stop"><i class="glyphicon glyphicon-remove"></i>&nbsp;</button>';
div += '</div>';
return div;
}
window.jobOperateEvents = {
'click .view': function (e, value, row, index) {
var formattedData = JSON.stringify(row, null, '\t');
$('#modal-job-description-content').text(formattedData);
$('#modal-job-description').modal('show');
},
'click .stop': function (e, value, row, index) {
if (!confirm('Are you sure to stop this job?')) {
return;
}
var ajax = $.ajax({
url: window.config.BASE_URL + "/service?action=job_stop",
type: 'POST',
data: {id: row.id}
});
ajax.done(function (res) {
if (res["errno"] !== 0) {
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
}
$('#table-link').bootstrapTable("refresh");
});
ajax.fail(function (jqXHR, textStatus) {
$("#modal-msg-content").html("Request failed : " + jqXHR.statusText);
$("#modal-msg").modal('show');
$('#table-job').bootstrapTable("refresh");
});
}
};

7
static/main.js Executable file
View File

@@ -0,0 +1,7 @@
$(function () {
$('#main-tabs a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
});

27
static/script.js Normal file
View File

@@ -0,0 +1,27 @@
$(function () {
$("#btn-signout").click(function (e) {
e.preventDefault();
var ajax = $.ajax({
url: window.config.BASE_URL + "/service?action=user_signout",
type: 'POST',
data: {}
});
ajax.done(function (res) {
window.location.pathname = "/";
});
});
$("#btn-oauth-login").click(function (e) {
e.preventDefault();
var ajax = $.ajax({
url: window.config.BASE_URL + "/service?action=oauth_get_url",
type: 'POST',
data: {}
});
ajax.done(function (res) {
window.location.href = res['url'];
});
});
$('.date-picker').datetimepicker();
});

32
static/style.css Executable file
View File

@@ -0,0 +1,32 @@
/* make sticky footer */
body, html {
height: 100%;
}
footer, .push {
height: 36px;
}
footer, footer .ul, footer .breadcrumb {
margin-bottom: 0;
background-color: transparent;
text-align: center;
}
footer a:link, footer a:visited {
text-decoration: none;
color: #777;
}
footer a:hover {
text-decoration: underline;
color: #000000;
}
.wrapper {
min-height: 100%;
margin: 0 auto -36px; /* the bottom margin is the negative value of the footer's height */
}
/* end */

110
static/ucenter.js Executable file
View File

@@ -0,0 +1,110 @@
$(function () {
console.log(page_type);
switch (page_type) {
case "logs":
load_logs('self');
break;
case "logs_all":
load_logs('all');
break;
case "jobs":
register_events_job();
load_jobs('self');
break;
case "agents":
register_events_agent();
load_agents('');
break;
default:
break;
}
});
function load_logs(scope) {
$("#table-log").bootstrapTable({
url: window.config.BASE_URL + '/service?action=log_gets&who=' + scope,
responseHandler: logResponseHandler,
sidePagination: 'server',
cache: true,
striped: true,
pagination: true,
pageSize: 10,
pageList: [10, 25, 50, 100, 200],
search: false,
showColumns: false,
showRefresh: false,
showToggle: false,
showPaginationSwitch: false,
minimumCountColumns: 2,
clickToSelect: false,
sortName: 'default',
sortOrder: 'desc',
smartDisplay: true,
mobileResponsive: true,
showExport: false,
columns: [{
field: 'scope',
title: 'UID',
align: 'center',
valign: 'middle',
sortable: false,
visible: scope === 'all'
}, {
field: 'tag',
title: 'Tag',
align: 'center',
valign: 'middle',
sortable: false,
visible: scope === 'all'
}, {
field: 'time',
title: 'Time',
align: 'center',
valign: 'middle',
sortable: false,
formatter: timeFormatter
}, {
field: 'ip',
title: 'IP',
align: 'center',
valign: 'middle',
sortable: false,
formatter: long2ip
}, {
field: 'content',
title: 'Result',
align: 'center',
valign: 'middle',
sortable: false,
formatter: resultFormatter
}, {
field: 'content',
title: 'Content',
align: 'center',
valign: 'middle',
sortable: false,
visible: scope === 'all',
escape: true
}]
});
}
var logResponseHandler = function (res) {
if (res['errno'] === 0) {
var tmp = {};
tmp["total"] = res["count"];
tmp["rows"] = res["logs"];
return tmp;
}
$("#modal-msg-content").html(res["msg"]);
$("#modal-msg").modal('show');
return [];
};
var resultFormatter = function (json) {
var res = JSON.parse(json);
if (res['response'] === 0) {
return '<span class="text-success">Success</span>';
}
return '<span class="text-dander">Fail</span>';
};

100
static/util.js Normal file
View File

@@ -0,0 +1,100 @@
function timeFormatter(unixTimestamp) {
if (unixTimestamp === null) {
return null;
}
var d = new Date(unixTimestamp * 1000);
d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000);
return formatDate(d, '%Y-%M-%d %H:%m');
}
function formatDate(date, fmt) {
function pad(value) {
return (value.toString().length < 2) ? '0' + value : value;
}
return fmt.replace(/%([a-zA-Z])/g, function (_, fmtCode) {
switch (fmtCode) {
case 'Y':
return date.getUTCFullYear();
case 'M':
return pad(date.getUTCMonth() + 1);
case 'n':
return date.getUTCMonth() + 1;
case 'd':
return pad(date.getUTCDate());
case 'H':
return pad(date.getUTCHours());
case 'm':
return pad(date.getUTCMinutes());
case 's':
return pad(date.getUTCSeconds());
default:
throw new Error('Unsupported format code: ' + fmtCode);
}
});
}
function long2ip(ip) {
// discuss at: http://locutus.io/php/long2ip/
// original by: Waldo Malqui Silva (http://waldo.malqui.info)
if (!isFinite(ip)) {
return false;
}
return [ip >>> 24, ip >>> 16 & 0xFF, ip >>> 8 & 0xFF, ip & 0xFF].join('.')
}
//http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
// https://stackoverflow.com/questions/736513/how-do-i-parse-a-url-into-hostname-and-path-in-javascript
function isURL(url) {
var parser = document.createElement('a');
parser.href = url;
var protocal = parser.protocol; // => "http:"
var host = parser.host; // => "example.com:3000"
var hostname = parser.hostname; // => "example.com"
var port = parser.port; // => "3000"
var pathname = parser.pathname; // => "/pathname/"
var hash = parser.hash; // => "#hash"
var search = parser.search; // => "?search=test"
var origin = parser.origin; // => "http://example.com:3000"
if (protocal === "http:" || protocal === "https:") {
return hostname !== '';
}
return false;
}
function getCookieByName(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function isCSRFSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!isCSRFSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRF-Token", getCookieByName('csrf_token'));
}
}
});