Skip to content
This repository has been archived by the owner on Jun 6, 2024. It is now read-only.

vc update #1974

Merged
merged 17 commits into from
Jan 9, 2019
Merged
61 changes: 61 additions & 0 deletions src/webportal/src/app/vc/vc-modal-component.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!-- Modal component for vc add -->
<div class="modal fade" id="virtualClustersList" tabindex="-1" role="dialog" aria-labelledby="virtualClustersAddTitle">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="virtualClustersAddTitle">
Add New Virtual Cluster
</h3>
<h5 class="modal-title">The capacity of new virtual cluster will be split from the "default" virtual cluster</h5>
</div>
<div class="modal-body">
<div class="modal-vc-content row">
<div class="form-group">
<input name="vcname" class="add-vc-fild form-control" placeholder="Virtual Cluster Name">
</div>
<div class="form-group">
<input name="capacity" class="add-vc-fild form-control" placeholder="Virtual Cluster Capacity">
</div>
<button type="button" class="btn btn-lg btn-primary btn-block" id="virtualClustersListAdd">
Add Virtual Cluster
</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

<!-- Modal component for vc edit -->
<div class="modal fade" id="virtualClustersEdit" tabindex="-1" role="dialog" aria-labelledby="virtualClustersEditTitle">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="virtualClustersEditTitle">
Edit Virtual Cluster
</h3>
</div>
<div class="modal-body">
<div class="modal-vc-content">
<div class="form-group edit-group">
<label for="editName" class="edit-group-item">Name</label>
<input id="editName" name="nameEdit" class="add-vc-fild form-control" placeholder="Virtual Cluster Name" readonly>
</div>
<div class="form-group edit-group">
<label for="editCapacity" class="edit-group-item">Capacity</label>
<input id="editCapacity" name="capacityEdit" class="add-vc-fild form-control" placeholder="Virtual Cluster Capacity">
</div>
<div class="remarks">The new capacity can be set in range of 0%~<%= vcDefault.capacity %>%, the variation will be split from or return to default virtual cluster.</div>
<button type="button" class="btn btn-lg btn-primary btn-block" id="virtualClustersListEdit">
Update Virtual Cluster
</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
16 changes: 15 additions & 1 deletion src/webportal/src/app/vc/vc.component.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<section class='content'>
<div class='box'>
<div class='box-body'>
<% if (isAdmin === 'true') { %>
<button class="btn btn-success btn-lg add-vc-btn" id="virtualClustersBtn" onclick="virtualClusterShow()">Add Virtual Cluster</button>
<% } %>
<table id='vc-table' class='table table-bordered table-hover table-condensed' style='vertical-align:middle'>
<thead>
<tr>
Expand All @@ -15,6 +18,7 @@
<th>CPUs</th>
<th>GPUs</th>
<th>Active Jobs</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
Expand Down Expand Up @@ -43,15 +47,25 @@
<td>
<%= data[vcName]['numJobs'] %>
</td>
<td width="8%">
<%= convertState(vcName, data[vcName]['status']) %>
</td>
<td>
<a href="view.html?vcName=<%= vcName %>">View Jobs</a>
&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="<%= yarnWebPortalUri %>/cluster/scheduler?openQueues=<%= vcName %>" target="_blank">Go to Yarn Page</a>
<% if (isAdmin === 'true') { %>
&nbsp;&nbsp;|&nbsp;&nbsp;
<a onclick="deleteVcItem('<%= vcName %>')" class="<%= vcName === 'default' ? 'default' : 'item-btn' %>">Delete</a>
&nbsp;&nbsp;|&nbsp;&nbsp;
<a onclick="editVcItem('<%= vcName %>', '<%= formatNumber(data[vcName]['capacity'], 2) %> %')" class="<%= vcName === 'default' ? 'default' : 'item-btn' %>">Edit</a>
<% } %>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
</section>
<%= modal({'vcDefault': data.default}) %>
</section>
184 changes: 182 additions & 2 deletions src/webportal/src/app/vc/vc.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

//

require('bootstrap/js/modal.js');
require('datatables.net/js/jquery.dataTables.js');
require('datatables.net-bs/js/dataTables.bootstrap.js');
require('datatables.net-bs/css/dataTables.bootstrap.css');
Expand All @@ -27,10 +28,13 @@ const url = require('url');
require('./vc.component.scss');
const vcComponent = require('./vc.component.ejs');
const breadcrumbComponent = require('../job/breadcrumb/breadcrumb.component.ejs');
const vcModelComponent = require('./vc-modal-component.ejs');
const webportalConfig = require('../config/webportal.config.js');
const userAuth = require('../user/user-auth/user-auth.component');

//
let table = null;

let isAdmin = cookies.get('admin');
//

const loadData = (specifiedVc) => {
Expand All @@ -45,6 +49,8 @@ const loadData = (specifiedVc) => {
formatNumber: formatNumber,
yarnWebPortalUri: webportalConfig.yarnWebPortalUri,
grafanaUri: webportalConfig.grafanaUri,
isAdmin,
modal: vcModelComponent,
});
$('#content-wrapper').html(vcHtml);
table = $('#vc-table').dataTable({
Expand All @@ -54,6 +60,7 @@ const loadData = (specifiedVc) => {
{type: 'natural', targets: [0, 1, 2, 3, 4, 5, 6]},
],
}).api();
resizeContentWrapper();
},
error: function() {
alert('Error when loading data.');
Expand All @@ -73,12 +80,174 @@ const formatNumber = (x, precision) => {
const resizeContentWrapper = () => {
$('#content-wrapper').css({'height': $(window).height() + 'px'});
if (table != null) {
$('.dataTables_scrollBody').css('height', (($(window).height() - 265)) + 'px');
$('.dataTables_scrollBody').css('height', (($(window).height() - (isAdmin === 'true' ? 335 : 265))) + 'px');
table.columns.adjust().draw();
}
};

//
const virtualClusterShow = () => {
$('#virtualClustersList input[name="vcname"]').val('');
$('#virtualClustersList input[name="capacity"]').val('');
$('#virtualClustersList').modal('show');
};

//
const virtualClustersAdd = () => {
userAuth.checkToken((token) => {
let vcName = $('#virtualClustersList input[name="vcname"]').val();
let capacity = $('#virtualClustersList input[name="capacity"]').val();
if (!vcName) {
$('#virtualClustersList input[name="vcname"]').focus();
return false;
}
if (!capacity) {
$('#virtualClustersList input[name="capacity"]').focus();
return false;
}
$.ajax({
url: `${webportalConfig.restServerUri}/api/v1/virtual-clusters/${vcName}`,
data: JSON.stringify({
'vcCapacity': capacity,
}),
headers: {
Authorization: `Bearer ${token}`,
},
contentType: 'application/json; charset=utf-8',
type: 'PUT',
dataType: 'json',
success: (data) => {
loadData(url.parse(window.location.href, true).query['vcName']);
$('#virtualClustersList').modal('hide');
alert(data.message);
},
error: (xhr, textStatus, error) => {
const res = JSON.parse(xhr.responseText);
alert(res.message);
},
});
});
};

//
const deleteVcItem = (name) => {
if (name == 'default') return false;
const res = confirm(`Notes:\r1. If there are jobs of this virtual cluster still running, it cannot be deleted.\r2. The capacity of this virtual cluster will be returned to default virtual cluster.\r\rAre you sure to delete ${name}?`);
if (!res) return false;
userAuth.checkToken((token) => {
$.ajax({
url: `${webportalConfig.restServerUri}/api/v1/virtual-clusters/${name}`,
headers: {
Authorization: `Bearer ${token}`,
},
contentType: 'application/json; charset=utf-8',
type: 'DELETE',
dataType: 'json',
success: (data) => {
loadData(url.parse(window.location.href, true).query['vcName']);
alert(data.message);
},
error: (xhr, textStatus, error) => {
const res = JSON.parse(xhr.responseText);
alert(res.message);
},
});
});
};

//
const editVcItem = (name, capacity) => {
if (name == 'default') return false;
$('input[name="nameEdit"]').val(name);
$('input[name="capacityEdit"]').val(capacity);
$('#virtualClustersEdit').modal('show');
};

//
const editVcItemPut = (name, capacity) => {
userAuth.checkToken((token) => {
$.ajax({
url: `${webportalConfig.restServerUri}/api/v1/virtual-clusters/${name}`,
data: JSON.stringify({
'vcCapacity': parseInt(capacity),
}),
headers: {
Authorization: `Bearer ${token}`,
},
contentType: 'application/json; charset=utf-8',
type: 'PUT',
dataType: 'json',
success: (data) => {
$('#virtualClustersEdit').modal('hide');
loadData(url.parse(window.location.href, true).query['vcName']);
alert(data.message);
},
error: (xhr, textStatus, error) => {
const res = JSON.parse(xhr.responseText);
alert(res.message);
},
});
});
};


const changeVcState = (name, state) => {
if (isAdmin !== 'true') return false;
if (name === 'default') return false;
userAuth.checkToken((token) => {
const res = confirm(`Do you want to ${state.toLowerCase() == 'running' ? 'stop' : 'activate'} ${name}?`);
if (!res) return false;
$.ajax({
url: `${webportalConfig.restServerUri}/api/v1/virtual-clusters/${$.trim(name)}/status`,
headers: {
Authorization: `Bearer ${token}`,
},
data: JSON.stringify({
'vcStatus': state.toLowerCase() == 'running' ? 'stopped' : 'running',
}),
contentType: 'application/json; charset=utf-8',
type: 'PUT',
dataType: 'json',
success: (data) => {
loadData(url.parse(window.location.href, true).query['vcName']);
alert(data.message);
},
error: (xhr, textStatus, error) => {
const res = JSON.parse(xhr.responseText);
alert(res.message);
},
});
});
};

const convertState = (name, state) => {
let vcState = '';
let vcStateChage = '';
let vcStateOrdinary = '';
let vcStateTips = '';
if (state === 'RUNNING') {
vcState = 'Running';
vcStateChage = `onclick='changeVcState("${name}", "${state}")'`;
} else if (state === 'STOPPED') {
vcState = 'Stopped';
vcStateChage = `onclick='changeVcState("${name}", "${state}")'`;
} else {
vcState = 'Unknown';
vcStateChage = '';
}
if (isAdmin === 'true' && name !== 'default') {
vcStateTips = 'title="Click To Change Status"';
} else {
vcStateOrdinary = 'state-vc-ordinary';
}
return `<a ${vcStateChage} class="state-vc state-${vcState.toLowerCase()} ${vcStateOrdinary}" ${vcStateTips}>${vcState}</a>`;
};

window.virtualClusterShow = virtualClusterShow;
window.deleteVcItem = deleteVcItem;
window.editVcItem = editVcItem;
window.changeVcState = changeVcState;
window.convertState = convertState;

$(document).ready(() => {
$('#sidebar-menu--vc').addClass('active');
Expand All @@ -87,4 +256,15 @@ $(document).ready(() => {
};
resizeContentWrapper();
loadData(url.parse(window.location.href, true).query['vcName']);

// add VC
$(document).on('click', '#virtualClustersListAdd', () => {
virtualClustersAdd();
});

$(document).on('click', '#virtualClustersListEdit', () => {
let name = $('input[name="nameEdit"]').val();
let capacity = $('input[name="capacityEdit"]').val();
editVcItemPut(name, capacity);
});
});
Loading