Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Projets publics
Ravada-Mirror
Commits
7cbf3e4a
Commit
7cbf3e4a
authored
Dec 11, 2019
by
Francesc Guasch
Browse files
wip(frontend): improve machine settings
issue #1196
parent
1612c647
Changes
11
Hide whitespace changes
Inline
Side-by-side
lib/Ravada/Front.pm
View file @
7cbf3e4a
...
...
@@ -585,14 +585,21 @@ Returns a reference to a list of the ISOs known by the system
=cut
sub
iso_file
($self, $vm_type) {
my
$cache
=
$self
->
_cache_get
("
list_isos
");
return
$cache
if
$cache
;
my
$req
=
Ravada::
Request
->
list_isos
(
vm_type
=>
$vm_type
);
return
[]
if
!
$req
;
$self
->
wait_request
(
$req
);
return
[]
if
$req
->
status
ne
'
done
';
my
$isos
=
decode_json
(
$req
->
output
());
$self
->
_cache_store
("
list_isos
",
$isos
);
return
$isos
;
}
...
...
@@ -706,8 +713,6 @@ Return true if alive, false otherwise.
sub
ping_backend
{
my
$self
=
shift
;
return
1
if
$self
->
_ping_backend_localhost
();
my
$req
=
Ravada::
Request
->
ping_backend
();
$self
->
wait_request
(
$req
,
2
);
...
...
@@ -1098,6 +1103,22 @@ sub add_node($self,%arg) {
return
$req
->
id
;
}
sub
_cache_store
($self, $key, $value, $timeout=60) {
$self
->
{
cache
}
->
{
$key
}
=
[
$value
,
time
+
$timeout
];
}
sub
_cache_get
($self, $key) {
delete
$self
->
{
cache
}
->
{
$key
}
if
exists
$self
->
{
cache
}
->
{
$key
}
&&
$self
->
{
cache
}
->
{
$key
}
->
[
1
]
<
time
;
return
if
!
exists
$self
->
{
cache
}
->
{
$key
};
return
$self
->
{
cache
}
->
{
$key
}
->
[
0
];
}
sub
list_network_interfaces
($self, %args) {
my
$vm_type
=
delete
$args
{
vm_type
}
or
confess
"
Error: missing vm_type
";
...
...
lib/Ravada/Request.pm
View file @
7cbf3e4a
...
...
@@ -553,7 +553,7 @@ sub _new_request {
$args
{
args
}
=
encode_json
(
$args
{
args
});
}
_init_connector
()
if
!
$CONNECTOR
||
!
$$CONNECTOR
;
if
(
$args
{
command
}
=~
/^(clone|manage_pools)$/
)
{
if
(
$args
{
command
}
=~
/^(clone|manage_pools
|list_isos
)$/
)
{
if
(
_duplicated_request
(
$args
{
command
},
$args
{
args
})
||
(
$args
{
command
}
ne
'
clone
'
&&
done_recently
(
undef
,
60
,
$args
{
command
})))
{
# warn "Warning: duplicated request for $args{command} $args{args}";
...
...
lib/Ravada/WebSocket.pm
View file @
7cbf3e4a
...
...
@@ -10,6 +10,7 @@ use Moose;
no
warnings
"
experimental::signatures
";
use
feature
qw(signatures)
;
my
$DEBUG
=
0
;
has
clients
=>
(
is
=>
'
ro
'
...
...
@@ -25,12 +26,14 @@ has ravada => (
my
%SUB
=
(
list_alerts
=>
\
&_list_alerts
,
list_isos
=>
\
&_list_isos
,
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
,
request
=>
\
&_request
);
######################################################################
...
...
@@ -62,6 +65,19 @@ sub _list_alerts($rvd, $args) {
return
[
@ret2
,
@ret
];
}
sub
_list_isos
($rvd, $args) {
my
(
$type
)
=
$args
->
{
channel
}
=~
m{/(.*)}
;
$type
=
'
KVM
'
if
!
defined
$type
;
return
$rvd
->
iso_file
(
$type
);
}
sub
_request
($rvd, $args) {
my
(
$id_request
)
=
$args
->
{
channel
}
=~
m{/(.*)}
;
my
$req
=
Ravada::
Request
->
open
(
$id_request
);
return
{
status
=>
$req
->
status
,
error
=>
$req
->
error
};
}
sub
_list_machines
($rvd, $args) {
my
$login
=
$args
->
{
login
}
or
die
"
Error: no login arg
"
.
Dumper
(
$args
);
my
$user
=
Ravada::Auth::
SQL
->
new
(
name
=>
$login
)
...
...
@@ -172,6 +188,7 @@ sub BUILD {
my
$ret
=
$exec
->
(
$self
->
ravada
,
$self
->
clients
->
{
$key
});
my
$old_ret
=
$self
->
clients
->
{
$key
}
->
{
ret
};
if
(
_different
(
$ret
,
$old_ret
))
{
warn
"
WS: send
$channel
"
if
$DEBUG
;
$ws_client
->
send
(
{
json
=>
$ret
}
);
$self
->
clients
->
{
$key
}
->
{
ret
}
=
$ret
;
}
...
...
@@ -182,6 +199,9 @@ sub BUILD {
sub
subscribe
($self, %args) {
my
$ws
=
$args
{
ws
};
my
%args2
=
%args
;
delete
$args2
{
ws
};
warn
"
Subscribe
"
.
Dumper
(
\
%args2
)
if
$DEBUG
;
$self
->
clients
->
{
$ws
}
=
{
ws
=>
$ws
,
%args
...
...
public/js/ravada.js
View file @
7cbf3e4a
...
...
@@ -191,12 +191,30 @@
});
}
};
$scope
.
subscribe_ws
=
function
(
url
)
{
subscribe_isos
=
function
(
url
)
{
var
ws
=
new
WebSocket
(
url
);
ws
.
onopen
=
function
(
event
)
{
ws
.
send
(
'
list_isos
'
)
};
ws
.
onmessage
=
function
(
event
)
{
var
data
=
JSON
.
parse
(
event
.
data
);
$scope
.
$apply
(
function
()
{
$scope
.
list_isos
=
data
;
});
}
};
subscribe_ws
=
function
(
url
)
{
subscribe_machine_info
(
url
);
subscribe_requests
(
url
);
subscribe_isos
(
url
);
};
$scope
.
init
=
function
(
id
)
{
var
url_ws
;
$scope
.
init
=
function
(
id
,
url
)
{
url_ws
=
url
;
$scope
.
showmachineId
=
id
;
subscribe_ws
(
url_ws
);
$http
.
get
(
'
/machine/info/
'
+
$scope
.
showmachineId
+
'
.json
'
)
.
then
(
function
(
response
)
{
$scope
.
showmachine
=
response
.
data
;
...
...
@@ -206,12 +224,13 @@
}
$scope
.
init_ldap_access
();
$scope
.
list_ldap_attributes
();
$scope
.
list_interfaces
();
list_interfaces
();
$scope
.
hardware_types
=
Object
.
keys
(
response
.
data
.
hardware
);
$scope
.
copy_ram
=
$scope
.
showmachine
.
max_mem
/
1024
/
1024
;
});
};
$scope
.
list_interfaces
=
function
()
{
list_interfaces
=
function
()
{
if
(
!
$scope
.
network_nats
)
{
$http
.
get
(
'
/network/interfaces/
'
+
$scope
.
showmachine
.
type
+
'
/nat
'
)
.
then
(
function
(
response
)
{
...
...
@@ -278,11 +297,29 @@
}
};
subscribe_request
=
function
(
id_request
,
action
)
{
var
ws
=
new
WebSocket
(
url_ws
);
ws
.
onopen
=
function
(
event
)
{
ws
.
send
(
'
request/
'
+
id_request
)
};
ws
.
onmessage
=
function
(
event
)
{
var
data
=
JSON
.
parse
(
event
.
data
);
action
(
data
);
}
};
$scope
.
rename
=
function
(
machineId
,
old_name
)
{
if
(
$scope
.
new_name_duplicated
||
$scope
.
new_name_invalid
)
return
;
$scope
.
rename_requested
=
1
;
$scope
.
rename_request
=
{
'
status
'
:
'
requested
'
};
$http
.
get
(
'
/machine/rename/
'
+
machineId
+
'
/
'
+
$scope
.
new_name
);
+
$scope
.
new_name
).
then
(
function
(
response
)
{
subscribe_request
(
response
.
data
.
req
,
function
(
data
)
{
$scope
.
$apply
(
function
()
{
$scope
.
rename_request
=
data
;
});
});
});
};
$scope
.
cancel_rename
=
function
(
old_name
)
{
$scope
.
new_name
=
old_name
;
...
...
@@ -340,6 +377,7 @@
});
};
$scope
.
copy_machine
=
function
()
{
$scope
.
copy_request
=
{
'
status
'
:
'
requested
'
};
$http
.
post
(
'
/machine/copy/
'
,
JSON
.
stringify
({
'
id_base
'
:
$scope
.
showmachine
.
id
,
'
copy_number
'
:
$scope
.
copy_number
...
...
@@ -347,6 +385,13 @@
,
'
new_name
'
:
$scope
.
new_name
})
).
then
(
function
(
response
)
{
// if there are many , we pick the last one
id_request
=
response
.
data
.
request
[
response
.
data
.
request
.
length
-
1
];
subscribe_request
(
id_request
,
function
(
data
)
{
$scope
.
$apply
(
function
()
{
$scope
.
copy_request
=
data
;
});
});
});
};
...
...
rvd_front.pl
View file @
7cbf3e4a
...
...
@@ -1904,7 +1904,6 @@ sub manage_machine {
$c
->
stash
(
errors
=>
\
@errors
);
return
$c
->
render
(
template
=>
'
main/settings_machine
'
,
nodes
=>
[
$RAVADA
->
list_vms
(
$domain
->
type
)]
,
isos
=>
$RAVADA
->
iso_file
(
$domain
->
type
)
,
list_clones
=>
[
map
{
$_
->
{
name
}
}
$domain
->
clones
]
,
action
=>
$c
->
req
->
url
->
to_abs
->
path
);
...
...
templates/main/admin_machines.html.ep
View file @
7cbf3e4a
...
...
@@ -286,7 +286,7 @@
<i
class=
"fa fa-desktop"
></i>
</a>
</div>
<div
ng-show=
"{{machine.is_locked}}"
ng-cloak
>
Machine
locked by
<a
href=
"/request/{{machine.is_locked}}.html"
><
%=
l
'
process
'
%
></a></div>
<div
ng-show=
"{{machine.is_locked}}"
ng-cloak
>
Machine
<a
href=
"/request/{{machine.is_locked}}.html"
><
%=
l
'
locked
'
%
></a></div>
<div
ng-show=
"{{machine.is_base}} && !{{machine.is_locked}}"
ng-cloak
><span
class=
"badge badge-pill badge-light"
><
%=
l
'
This
Machine
is
a
base
'
%
></span></div>
</td>
...
...
@@ -417,7 +417,7 @@
<i
class=
"fa fa-desktop"
></i>
</a>
</div>
<div
ng-show=
"{{child.is_locked}}"
ng-cloak
><
%=
l
'
Machine
locked
by
'
%
><a
href=
"/request/{{child.is_locked}}.html"
>
<
%=
l
'
process
'
%
></a></div>
<div
ng-show=
"{{child.is_locked}}"
ng-cloak
><
%=
l
'
Machine
'
%
>
<a
href=
"/request/{{child.is_locked}}.html"
>
<
%=
l
'
locked
'
%
></a></div>
</td>
<td
class=
"lgMachToggle"
><span
class=
"badge badge-info"
title=
"<%=l 'Node'%>"
>
{{child.node}}
</span></td>
</tr>
...
...
templates/main/manage_machine_new_disk.html.ep
View file @
7cbf3e4a
...
...
@@ -43,10 +43,9 @@
<label for="file"><%=l 'ISO file' %></label>
</div>
<div class="col-lg-3">
<select name="file" ng-model="add_disk.file">
% for (@$isos) {
<option value="<%= $_ %>"><%= $_ %></option>
% }
<select name="file" ng-model="add_disk.file"
ng-options="iso for iso in list_isos"
>
</select>
</div>
</div>
...
...
templates/main/settings_machine.html.ep
View file @
7cbf3e4a
...
...
@@ -8,7 +8,8 @@
<!--BASES AND DOMAINS LIST-->
<div
class=
"page-header"
>
<div
class=
"card"
ng-controller=
"singleMachinePage"
ng-init=
"init(<%= $id %>)"
>
ng-controller=
"singleMachinePage"
ng-init=
"init(<%= $id %>, '<%= url_for('ws_subscribe')->to_abs %>' )"
>
<div
class=
"card-header"
>
% if ($domain->is_base) {
<h2><
%=
l
'
Virtual
Machine
'
%
>
...
...
templates/main/vm_copy.html.ep
View file @
7cbf3e4a
...
...
@@ -33,10 +33,19 @@
<input class="form-control" ng-model="copy_ram" type="text" size="3">
</div>
</div>
<div ng-show="copy_request" class="alert alert-info">
Copy {{shownamchine.name}} {{copy_request.status}}.
<br/>
{{copy_request.error}}
</div>
<div ng-hide="copy_request && copy_request.status !== 'done'">
<button type="reset" class="btn btn-outline-secondary mr-2"><%=l 'Cancel' %></button>
<button class="btn btn-primary"
ng-click="copy_machine()"
ng-disabled="copy_number <1 || copy_number == 1 && (new_name_duplicated || new_name_invalid || new_name === showmachine.name)"><%=l 'Submit' %></button>
ng-disabled="copy_number <1 || copy_number == 1 && (new_name_duplicated || new_name_invalid || new_name === showmachine.name )
|| (copy_request && copy_request.status !== 'done')"><%=l 'Submit' %></button>
</div>
</div>
<div class="form-group has-error">
<label ng-show="copy_number==1 && new_name_duplicated"
...
...
templates/main/vm_hardware.html.ep
View file @
7cbf3e4a
...
...
@@ -79,10 +79,9 @@
<p class="text-right"><%=l 'ISO file' %></p>
</div>
<div class="col-lg-2">
<select name="file" ng-model="item.file">
% for (@$isos) {
<option value="<%= $_ %>"><%= $_ %></option>
% }
<select name="file" ng-model="item.file"
ng-options="iso for iso in list_isos"
>
</select>
</div>
</div>
...
...
templates/main/vm_rename.html.ep
View file @
7cbf3e4a
...
...
@@ -7,11 +7,17 @@
<div class="alert alert-danger" role="alert" ng-show="showmachine.is_hibernated">
This machine is hibernated and can't be renamed.
</div>
<div ng-hide="pending_requests">
<input class="form-control" type="text" name="new_name" ng-model="new_name"
ng-change="validate_new_name(showmachine.name)"
ng-disabled="showmachine.is_active || showmachine.is_hibernated"
ng-disabled="showmachine.is_active || showmachine.is_hibernated
|| (rename_request && rename_request.status !== 'done')"
>
<div ng-show="rename_request" class="alert alert-info">
Rename {{shownamchine.name}} {{rename_request.status}}.
<br/>
{{rename_request.error}}
</div>
<div ng-hide="rename_request && rename_request.status !== 'done'">
<input type="reset" class="btn btn-outline-secondary mt-3" value="<%=l 'Cancel' %>" onclick = "location='/admin/machines'"/>
<button type="button" class="btn btn-primary mt-3" ng-disabled="showmachine.is_active || showmachine.is_hibernated || new_name_duplicated || new_name_invalid || message_rename"
ng-click="rename(showmachine.id, showmachine.name)">
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment