Commit a9b9a23f authored by Francesc Guasch's avatar Francesc Guasch
Browse files

refactor(frontend): websockets admin and list bases

issue #1196
parent 77c337ef
......@@ -26,8 +26,11 @@ has ravada => (
my %SUB = (
list_alerts => \&_list_alerts
,list_machines => \&_list_machines
,list_machines_user => \&_list_machines_user
,list_bases_anonymous => \&_list_bases_anonymous
,list_requests => \&_list_requests
,machine_info => \&_get_machine_info
,ping_backend => \&_ping_backend
);
######################################################################
......@@ -74,6 +77,20 @@ sub _list_machines($rvd, $args) {
return $rvd->list_machines($user);
}
sub _list_machines_user($rvd, $args) {
my $login = $args->{login} or die "Error: no login arg ".Dumper($args);
my $user = Ravada::Auth::SQL->new(name => $login)
or die "Error: uknown user $login";
return $rvd->list_machines_user($user)
}
sub _list_bases_anonymous($rvd, $args) {
my $remote_ip = $args->{remote_ip} or die "Error: no remote_ip arg ".Dumper($args);
return $rvd->list_bases_anonymous($remote_ip);
}
sub _list_requests($rvd, $args) {
my $login = $args->{login} or die "Error: no login arg ".Dumper($args);
my $user = Ravada::Auth::SQL->new(name => $login) or die "Error: uknown user $login";
......@@ -100,6 +117,18 @@ sub _get_machine_info($rvd, $args) {
return $info;
}
sub _ping_backend($rvd, $args) {
my $requests = $rvd->list_requests(undef, 120, 1);
return 1 if !scalar(@$requests);
warn Dumper($requests);
my @requests2 = grep { $_->{status} ne 'requested' } @$requests;
return 0 if !scalar(@requests2) && grep { $_->{command} eq 'ping_backend'} @$requests;
warn "***".Dumper(map { [ $_->{command} => $_->{status} ] } @requests2);
return scalar (@requests2);
}
sub _different_list($list1, $list2) {
return 1 if scalar(@$list1) != scalar (@$list2);
for my $i (0 .. scalar(@$list1)-1) {
......
......@@ -119,7 +119,6 @@ ravadaApp.directive("solShowMachine", swMach)
$http.get('/pingbackend.json').then(function(response) {
$scope.pingbe_fail = !response.data;
});
$scope.getMachines = function() {
if( $scope.check_netdata && $scope.check_netdata != "0" ) {
var url = $scope.check_netdata;
$scope.check_netdata = 0;
......@@ -138,62 +137,76 @@ ravadaApp.directive("solShowMachine", swMach)
$http.get("/session/monitoring/0");
});
}
if(!$scope.modalOpened){
if ($scope.list_machines_busy) {
return ;
}
$scope.list_machines_busy = true;
$http.get("/requests.json").then(function(response) {
$scope.requests=response.data;
$scope.download_done=false;
$scope.download_working =false;
for (var i = 0; i < $scope.requests.length; i++){
if ( $scope.requests[i].command == 'download') {
if ($scope.requests[i].status == 'done') {
$scope.download_done=true;
} else {
$scope.download_working=true;
$scope.subscribe_all=function(url) {
subscribe_list_machines(url);
subscribe_list_requests(url);
};
subscribe_list_machines= function(url) {
var ws = new WebSocket(url);
ws.onopen = function (event) { ws.send('list_machines') };
ws.onmessage = function (event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.list_machines = [];
var mach;
for (var i=0, iLength = data.length; i<iLength; i++){
mach = data[i];
if (!mach.id_base){
$scope.list_machines[mach.id] = mach;
$scope.list_machines[mach.id].childs = [];
}
}
}
}
});
$http.get("/list_machines.json").then(function(response) {
$scope.list_machines_busy = false;
$scope.list_machines = [];
var mach;
for (var i=0, iLength = response.data.length; i<iLength; i++){
mach = response.data[i];
if (!mach.id_base){
$scope.list_machines[mach.id] = mach;
$scope.list_machines[mach.id].childs = [];
}
}
$scope.n_clones = 0;
for (var i=0, iLength = response.data.length; i<iLength; i++){
mach = response.data[i];
if (mach.id_base){
$scope.list_machines[mach.id_base].childs.push(mach);
$scope.n_clones++;
}
}
for (var i = $scope.list_machines.length-1; i >= 0; i--){
if (!$scope.list_machines[i]){
$scope.list_machines.splice(i,1);
}
}
if ($scope.auto_hide_clones) {
$scope.hide_clones = 0;
if ($scope.n_clones > $scope.n_clones_hide ) {
$scope.hide_clones = 1;
}
$scope.n_clones = 0;
for (var i=0, iLength = data.length; i<iLength; i++){
mach = data[i];
if (mach.id_base){
$scope.list_machines[mach.id_base].childs.push(mach);
$scope.n_clones++;
}
}
if ($scope.auto_hide_clones) {
$scope.hide_clones = 0;
if ($scope.n_clones > $scope.n_clones_hide ) {
$scope.hide_clones = 1;
}
}
for (var i = $scope.list_machines.length-1; i >= 0; i--){
if (!$scope.list_machines[i]){
$scope.list_machines.splice(i,1);
}
mach = $scope.list_machines[i];
if (!mach.id_base && typeof $scope.show_clones[mach.id] == 'undefined') {
$scope.show_clones[mach.id] = !$scope.hide_clones;
}
}
});
}
}
,function (error){;
$scope.list_machines_busy = false;
}
subscribe_list_requests = function(url) {
$scope.show_requests = false;
var ws = new WebSocket(url);
ws.onopen = function (event) { ws.send('list_requests') };
ws.onmessage = function (event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.requests= data;
$scope.download_done=false;
$scope.download_working =false;
for (var i = 0; i < $scope.requests.length; i++){
if ( $scope.requests[i].command == 'download') {
if ($scope.requests[i].status == 'done') {
$scope.download_done=true;
} else {
$scope.download_working=true;
}
}
}
});
}
);
}
};
$scope.orderParam = ['name'];
$scope.auto_hide_clones = true;
$scope.orderMachineList = function(type1,type2){
......@@ -204,10 +217,17 @@ ravadaApp.directive("solShowMachine", swMach)
else $scope.orderParam = [type1,'-'+type2];
}
$scope.hide_clones = true;
$scope.hideClones = function(){
$scope.hide_clones = !$scope.hide_clones;
$scope.auto_hide_clones = false;
}
$scope.showClones = function(value){
$scope.auto_hide_clones = false;
$scope.hide_clones = !value;
for (var i = $scope.list_machines.length-1; i >= 0; i--){
mach = $scope.list_machines[i];
if (!mach.id_base) {
$scope.show_clones[mach.id] = value;
}
}
}
$scope.request = function(request, args) {
$http.post('/request/'+request+'/'
,JSON.stringify(args)
......@@ -219,7 +239,6 @@ ravadaApp.directive("solShowMachine", swMach)
$scope.action = function(target,action,machineId){
$http.get('/'+target+'/'+action+'/'+machineId+'.json')
.then(function() {
$scope.getMachines();
});
};
$scope.set_autostart= function(machineId, value) {
......@@ -264,8 +283,7 @@ ravadaApp.directive("solShowMachine", swMach)
$scope.rename= {new_name: 'new_name'};
$scope.show_rename = false;
$scope.new_name_duplicated=false;
$scope.getMachines();
$interval($scope.getMachines,3000);
$scope.show_clones = {};
};
function usersPageC($scope, $http, $interval, request) {
......@@ -390,8 +408,6 @@ ravadaApp.directive("solShowMachine", swMach)
$scope.backend = response.data[0];
});
$scope.validate_node_name = function() {
console.log($scope.name);
$http.get('/node/exists/'+$scope.name)
.then(duplicated_callback, unique_callback);
......
......@@ -107,16 +107,17 @@
}
};
$scope.list_machines_user = function() {
var seconds = 1000;
if ($scope.refresh <= 0) {
var url = '/list_machines_user.json';
if ($scope.anonymous) {
url = '/list_bases_anonymous.json';
}
$http.get(url).then(function(response) {
$scope.machines = response.data;
$scope.subscribe_list_machines_user = function(url) {
var channel = 'list_machines_user';
if ($scope.anonymous) {
channel = 'list_bases_anonymous';
}
var ws = new WebSocket(url);
ws.onopen = function(event) { ws.send(channel) };
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.machines = data;
$scope.public_bases = 0;
$scope.private_bases = 0;
for (var i = 0; i < $scope.machines.length; i++) {
......@@ -126,29 +127,27 @@
$scope.private_bases++;
}
}
}, function error(response) {
console.log(response.status);
});
$scope.refresh = 5;
} else {
$scope.refresh--;
}
$timeout(function() {
$scope.list_machines_user();
}, seconds);
};
$url_list = "/list_bases.json";
if ( typeof $_anonymous !== 'undefined' && $_anonymous ) {
$url_list = "/list_bases_anonymous.json";
}
$http.get($url_list).then(function(response) {
$scope.list_bases= response.data;
});
subscribe_ping_backend= function(url) {
var ws = new WebSocket(url);
ws.onopen = function(event) { ws.send('ping_backend') };
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.pingbe_fail = !data;
});
}
};
$scope.subscribe_ws = function(url) {
subscribe_list_machines_user(url);
subscribe_ping_backend(url);
};
$http.get('/pingbackend.json').then(function(response) {
$scope.pingbe_fail = !response.data;
});
$scope.only_public = false;
$scope.toggle_only_public=function() {
......@@ -160,6 +159,31 @@
};
function singleMachinePageC($scope, $http, $interval, request, $location) {
subscribe_machine_info= function(url) {
var ws = new WebSocket(url);
ws.onopen = function(event) { ws.send('machine_info/'+$scope.showmachineId) };
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.showmachine = data;
});
}
};
subscribe_requests = function(url) {
var ws = new WebSocket(url);
ws.onopen = function(event) { ws.send('list_requests') };
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.alerts_ws = data;
});
}
};
$scope.subscribe_ws = function(url) {
subscribe_machine_info(url);
subscribe_requests(url);
};
$scope.init = function(id) {
$scope.showmachineId=id;
$http.get('/machine/info/'+$scope.showmachineId+'.json')
......@@ -169,7 +193,6 @@
$scope.new_name=$scope.showmachine.name+"-2";
$scope.validate_new_name($scope.showmachine.name);
}
$scope.refresh_machine();
$scope.init_ldap_access();
$scope.list_ldap_attributes();
$scope.list_interfaces();
......@@ -196,27 +219,10 @@
$http.get('/pingbackend.json').then(function(response) {
$scope.pingbe_fail = !response.data;
});
/* $scope.getSingleMachine = function(){
$http.get("/list_machines.json").then(function(response) {
for (var i=0, iLength=response.data.length; i<iLength; i++) {
if (response.data[i].id == $scope.showmachineId) {
$scope.showmachine = response.data[i];
if (!$scope.new_name) {
$scope.new_name = $scope.showmachine.name;
}
$scope.domain = response.data[i];
return;
}
}
window.location.href = "/admin/machines";
});
};
*/
$scope.machine_info = function(id) {
$http.get('/machine/info/'+$scope.showmachineId+'.json')
.then(function(response) {
$scope.showmachine=response.data;
$scope.list_nodes();
});
};
$scope.remove = function(machineId) {
......@@ -266,7 +272,6 @@
$scope.rename_requested=1;
$http.get('/machine/rename/'+machineId+'/'
+$scope.new_name);
$scope.refresh_machine();
};
$scope.cancel_rename=function(old_name) {
$scope.new_name = old_name;
......@@ -302,22 +307,12 @@
if (! value) {
value_show = false;
}
$scope.add_message("Setting "+$scope.showmachine.name+" "+field+" to "+value_show);
$http.get("/machine/set/"+$scope.showmachine.id+"/"+field+"/"+value);
};
$scope.set = function(field) {
$scope.add_message("Setting "+$scope.showmachine.name+" "+field+" to "
+$scope.showmachine[field]);
$http.get("/machine/set/"+$scope.showmachine.id+"/"+field+"/"+$scope.showmachine[field]);
};
$scope.add_message = function(text) {
$scope.message.push(text);
setTimeout(function () {
$scope.message = [];
}, 5000);
};
$scope.set_public = function(machineId, value) {
if (value) value=1;
else value=0;
......@@ -331,8 +326,6 @@
}
$http.get("/machine/"+url+"/" +vmId+ "/" +machineId+".json")
.then(function(response) {
$scope.getReqs();
$scope.refresh_machine();
});
};
$scope.copy_machine = function() {
......@@ -343,47 +336,11 @@
,'new_name': $scope.new_name
})
).then(function(response) {
$scope.getReqs();
$scope.refresh_machine();
});
};
//On load code
// $scope.showmachineId = window.location.pathname.split("/")[3].split(".")[0] || -1 ;
$scope.refresh_machine = function() {
if(!$scope.showmachine || $scope.refreshing_machine) { return }
$scope.refreshing_machine = true;
$http.get('/machine/requests/'+$scope.showmachine.id+'.json').then(function(response) {
$scope.refreshing_machine = false;
$scope.requests = response.data;
var pending = 0;
for (var i in response.data) {
if(response.data[i].status != 'done') {
pending++;
}
}
$scope.pending_requests = pending;
if ($scope.requests.length) {
setTimeout(function () {
$scope.refresh_machine();
}, 2000);
}
if( pending < $scope.pending_before) {
if($scope.showmachine) {
$scope.machine_info($scope.showmachine.id);
}
setTimeout(function () {
$scope.machine_info($scope.showmachine.id);
}, 2000);
} else {
setTimeout(function () {
$scope.refresh_machine();
}, 30000);
}
$scope.pending_before = pending;
});
};
$scope.add_hardware = function(hardware, number, extra) {
if (hardware == 'disk' && ! extra) {
$scope.show_new_disk = true;
......@@ -399,10 +356,6 @@
,'data': extra
})
).then(function(response) {
$scope.pending_before++;
if (!$scope.requests || !$scope.requests.length) {
$scope.refresh_machine();
}
});
};
$scope.remove_hardware = function(hardware, index, item, confirmation) {
......@@ -415,10 +368,6 @@
item.remove = false;
$http.get('/machine/hardware/remove/'
+$scope.showmachine.id+'/'+hardware+'/'+index).then(function(response) {
$scope.pending_before++;
if (!$scope.requests || !$scope.requests.length) {
$scope.refresh_machine();
}
});
};
......@@ -455,7 +404,6 @@
,'id_port': id_port
})
).then(function(response) {
$scope.refresh_machine();
});
$scope.init_new_port();
};
......@@ -466,7 +414,6 @@
,'port': port
})
).then(function(response) {
$scope.refresh_machine();
});
};
......@@ -515,7 +462,7 @@
$scope.new_port_name = null;
$scope.new_port_restricted = false;
};
$scope.list_nodes = function() {
list_nodes = function() {
$http.get('/list_nodes.json').then(function(response) {
$scope.nodes = response.data;
});
......@@ -539,7 +486,6 @@
,'data': new_settings
})
).then(function(response) {
$scope.getReqs();
});
};
......@@ -562,7 +508,6 @@
,'data': new_settings
})
).then(function(response) {
$scope.getReqs();
});
};
$scope.add_disk = {
......@@ -576,12 +521,7 @@
$scope.pending_before = 10;
// $scope.getSingleMachine();
// $scope.updatePromise = $interval($scope.getSingleMachine,3000);
$scope.getReqs= function() {
$http.get('/requests.json').then(function(response) {
$scope.requests=response.data;
});
};
$scope.getReqs();
list_nodes();
$scope.list_ldap_attributes();
};
......@@ -791,22 +731,26 @@
};
function notifCrtl($scope, $interval, $http, request){
$scope.getAlerts = function() {
$http.get('/unshown_messages.json').then(function(response) {
$scope.alerts= response.data;
},function error(response) {
if ( response.status == 403 && (typeof $_anonymous == "undefined" || !$_anonymous)) {
window.location.href="/logout";
}
});
};
$interval($scope.getAlerts,10000);
$scope.closeAlert = function(index) {
var message = $scope.alerts.splice(index, 1);
var toGet = '/messages/read/'+message[0].id+'.html';
var message = $scope.alerts_ws.splice(index, 1);
var toGet = '/messages/read/'+message[0].id+'.json';
$http.get(toGet);
};
$scope.getAlerts();
$scope.subscribe_alerts = function(url) {
var ws = new WebSocket(url);
ws.onopen = function(event) { ws.send('list_alerts') };
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
$scope.$apply(function () {
$scope.alerts_ws = data;
});
}
}
$scope.alerts_ws = [];
};
/*
......
......@@ -3,7 +3,7 @@
%= include 'bootstrap/header'
<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top" role="document">
<div id="wrapper">
<div ng-controller="machinesPage" ng-init="n_clones_hide=<%= $n_clones_hide %>;check_netdata='<%= $check_netdata %>'" >
<div ng-controller="machinesPage" ng-init="subscribe_all('<%= url_for('ws_subscribe')->to_abs %>');n_clones_hide=<%= $n_clones_hide %>;check_netdata='<%= $check_netdata %>'" >
%= include 'bootstrap/navigation'
<div id="page-wrapper">
<div id="admin-content">
......@@ -126,10 +126,10 @@
ng-hide="orderParam[0] !== '-name'"></i>
<%=l 'Machine Name' %></div>
<div style="float:right" ng-show="n_clones">
<a ng-show="hide_clones" ng-click="hideClones()"
<a ng-show="hide_clones" ng-click="showClones(true)"
class="badge badge-primary dropdown-toggle text-white"
align="right"><%=l 'show clones' %></a>
<a ng-show="!hide_clones" ng-click="hideClones()"
<a ng-show="!hide_clones" ng-click="showClones(false)"
class="badge badge-primary dropdown-toggle text-white"
align="right"><%=l 'hide clones' %></a>
</div>
......@@ -161,6 +161,14 @@
ng-class="{disabled: !machine.can_manage}"
title ="<%=l 'Manage machine' %>"><b
ng-cloak>{{machine.name}}</b></a> {{machine.comment}}
<button ng-show="machine.has_clones" type="button"
class="badge badge-light text-blue"
ng-click="show_clones[machine.id] = !show_clones[machine.id]"
title="<%=l 'Show/Hide clones' %>">
<b ng-show="show_clones[machine.id]" >-</b>
<b ng-show="!show_clones[machine.id]">+</b>
</button>