1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-26 06:50:09 +03:00

Feature #507: Improved and fixed small bugs. Autorefresh and action conditions

now in place.
This commit is contained in:
Hector Sanjuan 2011-03-22 21:44:28 +01:00
parent 9ce115b9e4
commit 5d00477bf6
10 changed files with 207 additions and 247 deletions

View File

@ -57,7 +57,7 @@ function showTab(tabname){
$(document).ready(function () {
$(".tab").hide();
$(".outer-west ul li a").click(function(){
$(".outer-west ul li a").live("click",function(){
var tab = $(this).attr('href');
showTab(tab);
return false;
@ -97,6 +97,5 @@ $(document).ready(function () {
, spacing_closed: 12 // ALL panes
});
showTab("#dashboard");
});

View File

@ -160,6 +160,9 @@ $(document).ready(function(){
});
emptyDashboard();
if (uid!=0) {
$("td.oneadmin").hide();
}
});

View File

@ -110,8 +110,7 @@ var host_actions = {
type: "create",
call : OpenNebula.Host.create,
callback : addHostElement,
error : onError,
notify:False,
error : onError
},
"Host.create_dialog" : {
@ -132,16 +131,14 @@ var host_actions = {
type: "single",
call: OpenNebula.Host.show,
callback: updateHostElement,
error: onError,
notify:False
error: onError
},
"Host.showinfo" : {
type: "single",
call: OpenNebula.Host.show,
callback: updateHostInfo,
error: onError,
notify: False
error: onError
},
"Host.refresh" : {
@ -152,7 +149,13 @@ var host_actions = {
},
callback: function(){},
error: onError,
notify: False
},
"Host.autorefresh" : {
type: "custom",
call : function() {
OpenNebula.Host.list({timeout: true, success: updateHostsView,error: onError});
}
},
"Host.enable" : {
@ -162,8 +165,7 @@ var host_actions = {
Sunstone.runAction("Host.show",req.request.data[0]);
},
dataTable: function() { return dataTable_hosts },
error : onError,
notify:True,
error : onError
},
"Host.disable" : {
@ -173,8 +175,7 @@ var host_actions = {
Sunstone.runAction("Host.show",req.request.data[0]);
},
dataTable: function() { return dataTable_hosts },
error : onError,
notify:True,
error : onError
},
"Host.delete" : {
@ -182,8 +183,7 @@ var host_actions = {
call : OpenNebula.Host.delete,
callback : deleteHostElement,
dataTable: function() { return dataTable_hosts },
error : onError,
notify:True,
error : onError
},
"Host.list" : {
@ -193,8 +193,7 @@ var host_actions = {
OpenNebula.Cluster.list({success: updateClustersView, error: onError});
},
callback: function(){},
error: onError,
notify:True,
error: onError
},
"Cluster.create" : {
@ -204,8 +203,7 @@ var host_actions = {
//OpenNebula.Cluster.list({success: updateClustersView, error: onError});
Sunstone.runAction("Cluster.list");
},
error : onError,
notify:True
error : onError
},
"Cluster.create_dialog" : {
@ -218,7 +216,13 @@ var host_actions = {
call: OpenNebula.Cluster.list,
callback: updateClustersView,
error: onError,
notify:True
},
"Cluster.autorefresh" : {
type: "custom",
call: function () {
OpenNebula.Cluster.list({timeout: true, success: updateClustersView,error: onError});
}
},
"Cluster.delete" : {
@ -228,8 +232,7 @@ var host_actions = {
//OpenNebula.Cluster.list({success: updateClustersView, error: onError});
Sunstone.runAction("Cluster.list");
},
error : onError,
notify:True,
error : onError
},
"Cluster.addhost" : {
@ -239,16 +242,14 @@ var host_actions = {
Sunstone.runAction("Host.show",req.request.data);
},
dataTable: function() { return dataTable_hosts },
error : onError,
notify:True,
error : onError
},
"Cluster.removehost" : {
type: "multiple",
call : OpenNebula.Cluster.removehost,
callback : deleteHostElement,
error : onError,
notify:True,
error : onError
}
};
@ -286,6 +287,7 @@ var host_buttons = {
tip: "Select the cluster you want to remove",
condition : True
},
"action_list" : { //Special button
type: "select",
actions: { "Cluster.addhost": {
@ -321,9 +323,8 @@ var host_info_panel = {
}
};
for (action in host_actions){
Sunstone.addAction(action,host_actions[action]);
}
Sunstone.addActions(host_actions);
// title, content, buttons, id
Sunstone.addMainTab('hosts_tab','Hosts & Clusters',hosts_tab_content,host_buttons);
@ -614,7 +615,21 @@ function popUpCreateClusterDialog(){
return false;
}
function setHostAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_hosts.fnGetNodes());
var filter = $("#datatable_hosts_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Host.autorefresh");
}
},INTERVAL+someTime());
}
function setClusterAutorefresh(){
setInterval(function(){
Sunstone.runAction("Cluster.autorefresh");
},INTERVAL+someTime());
}
//Document ready
$(document).ready(function(){
@ -643,19 +658,9 @@ $(document).ready(function(){
setupCreateHostDialog();
setupCreateClusterDialog();
setHostAutorefresh();
setClusterAutorefresh();
//set refresh interval
setInterval(function(){
var nodes = $('input:checked',dataTable_hosts.fnGetNodes());
var filter = $("#datatable_hosts_filter input").attr("value");
if (!nodes.length && !filter.length){
OpenNebula.Host.list({timeout: true, success: updateHostsView,error: onError});
}
},60000);
setInterval(function(){
OpenNebula.Cluster.list({timeout: true, success: updateClustersView,error: onError});
},64000);
initCheckAllBoxes(dataTable_hosts);
tableCheckboxesListener(dataTable_hosts);

View File

@ -164,8 +164,7 @@ var image_actions = {
type: "create",
call: OpenNebula.Image.register,
callback: addImageElement,
error: onError,
notify: False,
error: onError
},
"Image.create_dialog" : {
@ -177,24 +176,21 @@ var image_actions = {
type: "list",
call: OpenNebula.Image.list,
callback: updateImagesView,
error: onError,
notify: False
error: onError
},
"Image.show" : {
type : "single",
call: OpenNebula.Image.show,
callback: updateImageElement,
error: onError,
notify: False
error: onError
},
"Image.showinfo" : {
type: "single",
call: OpenNebula.Image.show,
callback: updateImageInfo,
error: onError,
notify : False
error: onError
},
"Image.refresh" : {
@ -203,7 +199,13 @@ var image_actions = {
waitingNodes(dataTable_images);
Sunstone.runAction("Image.list");
},
notify: False
},
"Image.autorefresh" : {
type: "custom",
call: function() {
OpenNebula.Image.list({timeout: true, success: updateImagesView, error: onError});
}
},
"Image.addattr" : {
@ -226,9 +228,8 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
},
error: onError
},
"Image.addattr_dialog" : {
type: "custom",
@ -259,7 +260,6 @@ var image_actions = {
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
},
"Image.rmattr_dialog" : {
@ -274,8 +274,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
},
"Image.disable" : {
@ -285,8 +284,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
},
"Image.persistent" : {
@ -296,8 +294,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
},
"Image.nonpersistent" : {
@ -307,8 +304,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
},
"Image.publish" : {
@ -318,8 +314,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
},
"Image.unpublish" : {
@ -329,8 +324,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
},
"Image.delete" : {
@ -340,8 +334,7 @@ var image_actions = {
Sunstone.runAction("Image.show",req.request.data[0]);
},
dataTable: function(){return dataTable_images},
error: onError,
notify: False
error: onError
}
}
@ -429,11 +422,7 @@ var image_info_panel = {
}
for (action in image_actions){
Sunstone.addAction(action,image_actions[action]);
}
Sunstone.addActions(image_actions);
Sunstone.addMainTab('images_tab',"Images",images_tab_content,image_buttons);
Sunstone.addInfoPanel('image_info_panel',image_info_panel);
@ -796,6 +785,16 @@ function popUpCreateImageDialog(){
$('#create_image_dialog').dialog('open');
}
function setImageAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_images.fnGetNodes());
var filter = $("#datatable_images_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Image.autorefresh");
}
},INTERVAL+someTime());
}
$(document).ready(function(){
dataTable_images = $("#datatable_images").dataTable({
@ -820,14 +819,7 @@ $(document).ready(function(){
setupCreateImageDialog();
setupImageAttributesDialogs();
setupTips($('#create_image_dialog'));
setInterval(function(){
var nodes = $('input:checked',dataTable_images.fnGetNodes());
var filter = $("#datatable_images_filter input").attr("value");
if (!nodes.length && !filter.length){
OpenNebula.Image.list({timeout: true, success: updateImagesView, error: onError});
}
},78000);
setImageAutorefresh();
initCheckAllBoxes(dataTable_images);
tableCheckboxesListener(dataTable_images);

View File

@ -59,8 +59,7 @@ var user_actions = {
type: "create",
call: OpenNebula.User.create,
callback: addUserElement,
error: onError,
notify: False
error: onError
},
"User.create_dialog" : {
@ -72,8 +71,7 @@ var user_actions = {
type: "list",
call: OpenNebula.User.list,
callback: updateUsersView,
error: onError,
notify: False
error: onError
},
"User.refresh" : {
@ -81,16 +79,24 @@ var user_actions = {
call: function () {
waitingNodes(dataTable_users);
Sunstone.runAction("User.list");
}
},
},
"User.autorefresh" : {
type: "custom",
call: function(){
OpenNebula.User.list({timeout: true, success: updateUsersView, error: onError});
},
condition: function(){ uid == 0 },
notify: false
},
"User.delete" : {
type: "multiple",
call: OpenNebula.User.delete,
callback: deleteUserElement,
dataTable: function(){return dataTable_users},
error: onError,
notify: False
error: onError
},
}
@ -113,10 +119,7 @@ var user_buttons = {
}
}
for (action in user_actions){
Sunstone.addAction(action,user_actions[action]);
}
Sunstone.addActions(user_actions);
Sunstone.addMainTab('users_tab',"Users",users_tab_content,user_buttons,false,function(){return uid==0;});
@ -194,39 +197,46 @@ function popUpCreateUserDialog(){
}
function setUserAutorefresh(){
setInterval(function(){
var checked = $('input:checked',dataTable_users.fnGetNodes());
var filter = $("#datatable_users_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("User.autorefresh");
}
},INTERVAL+someTime());
}
$(document).ready(function(){
dataTable_users = $("#datatable_users").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"sPaginationType": "full_numbers",
"bAutoWidth":false,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1] }
]
});
dataTable_users.fnClearTable();
addElement([
if (uid==0) {
dataTable_users = $("#datatable_users").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"sPaginationType": "full_numbers",
"bAutoWidth":false,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1] }
]
});
dataTable_users.fnClearTable();
addElement([
spinner,
'',''],dataTable_users);
Sunstone.runAction("User.list");
Sunstone.runAction("User.list");
setupCreateUserDialog();
setupCreateUserDialog();
setUserAutorefresh();
initCheckAllBoxes(dataTable_users);
tableCheckboxesListener(dataTable_users);
}
//TODO user oneadmin
setInterval(function(){
var nodes = $('input:checked',dataTable_users.fnGetNodes());
var filter = $("#datatable_users_filter input").attr("value");
if (!nodes.length && !filter.length){
OpenNebula.User.list({timeout: true, success: updateUsersView, error: onError});
}
},74000); //so that not all refreshing is done at the same time
initCheckAllBoxes(dataTable_users);
tableCheckboxesListener(dataTable_users);
})

View File

@ -489,8 +489,7 @@ var vm_actions = {
type: "create",
call: OpenNebula.VM.create,
callback: addVMachineElement,
error: onError,
notify: False
error: onError
},
"VM.create_dialog" : {
@ -502,24 +501,21 @@ var vm_actions = {
type: "list",
call: OpenNebula.VM.list,
callback: updateVMachinesView,
error: onError,
notify: False
error: onError
},
"VM.show" : {
type: "single",
call: OpenNebula.VM.show,
callback: updateVMachineElement,
error: onError,
notify: False
error: onError
},
"VM.showinfo" : {
type: "single",
call: OpenNebula.VM.show,
callback: updateVMInfo,
error: onError,
notify: False
error: onError
},
"VM.refresh" : {
@ -528,7 +524,13 @@ var vm_actions = {
waitingNodes(dataTable_vMachines);
Sunstone.runAction("VM.list");
},
notify: False
},
"VM.autorefresh" : {
type: "custom",
call : function() {
OpenNebula.VM.list({timeout: true, success: updateVMachinesView,error: onError});
},
},
"VM.deploy" : {
@ -539,7 +541,6 @@ var vm_actions = {
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
},
"VM.migrate" : {
@ -549,8 +550,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.livemigrate" : {
@ -560,8 +560,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.hold" : {
@ -571,8 +570,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.release" : {
@ -582,8 +580,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.suspend" : {
@ -593,8 +590,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.resume" : {
@ -604,8 +600,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.stop" : {
@ -615,8 +610,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.restart" : {
@ -626,8 +620,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.shutdown" : {
@ -637,8 +630,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.cancel" : {
@ -648,8 +640,7 @@ var vm_actions = {
Sunstone.runAction("VM.show",req.request.data[0]);
},
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.delete" : {
@ -657,8 +648,7 @@ var vm_actions = {
call: OpenNebula.VM.delete,
callback: deleteVMachineElement,
dataTable: function(){return dataTable_vMachines},
error: onError,
notify: False
error: onError
},
"VM.log" : {
@ -685,15 +675,12 @@ var vm_actions = {
error: function(request,error_json){
$("#vm_log pre").html('');
onError(request,error_json);
},
notify: False
}
}
}
var vm_buttons = {
"VM.refresh" : {
type: "image",
@ -818,10 +805,7 @@ var vm_info_panel = {
}
}
for (action in vm_actions){
Sunstone.addAction(action,vm_actions[action]);
}
Sunstone.addActions(vm_actions);
Sunstone.addMainTab('vms_tab',"Virtual Machines",vms_tab_content,vm_buttons);
Sunstone.addInfoPanel('vm_info_panel',vm_info_panel);
@ -1694,6 +1678,16 @@ function popUpCreateVMDialog(){
$('#create_vm_dialog').dialog('open');
}
function setVMAutorefresh(){
setInterval(function(){
var checked = $('input:checked',dataTable_vMachines.fnGetNodes());
var filter = $("#datatable_vmachines_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("VM.autorefresh");
}
},INTERVAL+someTime()); //so that not all refreshing is done at the same time
}
$(document).ready(function(){
dataTable_vMachines = $("#datatable_vmachines").dataTable({
@ -1716,14 +1710,7 @@ $(document).ready(function(){
Sunstone.runAction("VM.list");
setupCreateVMDialog();
setInterval(function(){
var nodes = $('input:checked',dataTable_vMachines.fnGetNodes());
var filter = $("#datatable_vmachines_filter input").attr("value");
if (!nodes.length && !filter.length){
OpenNebula.VM.list({timeout: true, success: updateVMachinesView,error: onError});
}
},72000); //so that not all refreshing is done at the same time
setVMAutorefresh();
initCheckAllBoxes(dataTable_vMachines);
tableCheckboxesListener(dataTable_vMachines);

View File

@ -174,6 +174,13 @@ var vnet_actions = {
notify: False
},
"Network.autorefresh" : {
type: "custom",
call: function() {
OpenNebula.Network.list({timeout: true, success: updateVNetworksView, error: onError});
}
},
"Network.publish" : {
type: "multiple",
call: OpenNebula.Network.publish,
@ -252,10 +259,7 @@ var vnet_info_panel = {
}
}
for (action in vnet_actions){
Sunstone.addAction(action,vnet_actions[action]);
}
Sunstone.addActions(vnet_actions);
Sunstone.addMainTab('vnets_tab',"Virtual Networks",vnets_tab_content, vnet_buttons);
Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel);
@ -526,6 +530,16 @@ function popUpCreateVnetDialog() {
$('#create_vn_dialog').dialog('open');
}
function setVNetAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_vNetworks.fnGetNodes());
var filter = $("#datatable_vnetworks_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Network.autorefresh");
}
},INTERVAL+someTime());
}
$(document).ready(function(){
@ -549,14 +563,7 @@ $(document).ready(function(){
Sunstone.runAction("Network.list");
setupCreateVNetDialog();
setInterval(function(){
var nodes = $('input:checked',dataTable_vNetworks.fnGetNodes());
var filter = $("#datatable_vnetworks_filter input").attr("value");
if (!nodes.length && !filter.length){
OpenNebula.Network.list({timeout: true, success: updateVNetworksView, error: onError});
}
},68000);
setVNetAutorefresh();
initCheckAllBoxes(dataTable_vNetworks);
tableCheckboxesListener(dataTable_vNetworks);

View File

@ -16,70 +16,10 @@
/* Some useful functions for Sunstone default plugins */
var INTERVAL=60000;
function emptyDashboard(){
$("#dashboard .value_td span").html(spinner);
}
function updateDashboard(what,json_info){
db = $('#dashboard');
switch (what){
case "hosts":
total_hosts=json_info.length;
active_hosts=0;
$.each(json_info,function(){
if (parseInt(this.HOST.STATE) < 3){
active_hosts++;}
});
$('#total_hosts',db).html(total_hosts);
$('#active_hosts',db).html(active_hosts);
break;
case "clusters":
total_clusters=json_info.length;
$('#total_clusters',db).html(total_clusters);
break;
case "vms":
total_vms=json_info.length;
running_vms=0;
failed_vms=0;
$.each(json_info,function(){
vm_state = parseInt(this.VM.STATE);
if (vm_state == 3){
running_vms++;
}
else if (vm_state == 7) {
failed_vms++;
}
});
$('#total_vms',db).html(total_vms);
$('#running_vms',db).html(running_vms);
$('#failed_vms',db).html(failed_vms);
break;
case "vnets":
public_vnets=0;
total_vnets=json_info.length;
$.each(json_info,function(){
if (parseInt(this.VNET.PUBLIC)){
public_vnets++;}
});
$('#total_vnets',db).html(total_vnets);
$('#public_vnets',db).html(public_vnets);
break;
case "users":
total_users=json_info.length;
$('#total_users',db).html(total_users);
break;
case "images":
total_images=json_info.length;
public_images=0;
$.each(json_info,function(){
if (parseInt(this.IMAGE.PUBLIC)){
public_images++;}
});
$('#total_images',db).html(total_images);
$('#public_images',db).html(public_images);
break;
}
function someTime(){
return Math.floor(Math.random()*30000);
}
function pad(number,length) {

View File

@ -53,6 +53,12 @@ var Sunstone = {
SunstoneCfg["actions"][action] = null;
},
"addActions" : function(actions) {
for (action in actions){
Sunstone.addAction(action,actions[action]);
}
},
"addMainTab" : function(tab_id,title_arg,content_arg, buttons_arg,refresh,condition_f) {
SunstoneCfg["tabs"][tab_id] = {title: title_arg,
content: content_arg,
@ -143,11 +149,20 @@ var Sunstone = {
}
var action_cfg = actions[action];
var notify = action_cfg.notify;
var condition = action_cfg["condition"];
if (condition && !condition() && notify){
//we do not meet the condition to run this action
notifyError("This action cannot be run");
return;
}
var call = action_cfg["call"];
var callback = action_cfg["callback"];
var err = action_cfg["error"];
var notify = action_cfg.notify;
$('div#confirm_with_select_dialog').dialog("close");
$('div#confirm_dialog').dialog("close");
@ -275,6 +290,8 @@ $(document).ready(function(){
$('.action_list:visible').hide();
});
showTab('#dashboard_tab');
});
@ -367,7 +384,7 @@ function insertButtonsInTab(tab_name){
}//if tab exists
}
// We do not insert info panels code, we generate it dinamicly when
// We do not insert info panels code, we generate it dynamicly when
// we need it with getInfoPanelHTML()
//~ function insertInfoPanels(){
//~ var panels = SunstoneCfg["info_panels"];

View File

@ -20,6 +20,7 @@
<link rel="stylesheet" type="text/css" href="/css/application.css" />
<link rel="stylesheet" type="text/css" href="/css/layout.css" />
<script type="text/javascript" src="/js/opennebula.js"></script>
<script type="text/javascript" src="/js/layout.js"></script>
<script type="text/javascript" src="/js/sunstone.js"></script>
<script type="text/javascript" src="/js/sunstone-util.js"></script>
<script type="text/javascript" src="/js/plugins/dashboard-tab.js"></script>
@ -28,7 +29,6 @@
<script type="text/javascript" src="/js/plugins/vnets-tab.js"></script>
<script type="text/javascript" src="/js/plugins/images-tab.js"></script>
<script type="text/javascript" src="/js/plugins/users-tab.js"></script>
<script type="text/javascript" src="/js/layout.js"></script>
</head>
<body>