Commit 5b4ee92b authored by Roberto P. Rubio's avatar Roberto P. Rubio
Browse files

Añade botón reboot

parent 08d982b6
......@@ -1010,6 +1010,7 @@ sub _alias_grants($self) {
my %alias= (
remove_clone => 'remove_clones'
,shutdown_clone => 'shutdown_clones'
,reboot_clone => 'reboot_clones'
);
my $sth_old = $CONNECTOR->dbh->prepare("SELECT id FROM grant_types_alias"
......@@ -1031,6 +1032,7 @@ sub _add_grants($self) {
$self->_add_grant('rename_all', 0,"Can rename any virtual machine.");
$self->_add_grant('rename_clones', 0,"Can rename clones from virtual machines owned by the user.");
$self->_add_grant('shutdown', 1,"Can shutdown own virtual machines.");
$self->_add_grant('reboot', 1,"Can reboot own virtual machines.");
$self->_add_grant('screenshot', 1,"Can get a screenshot of own virtual machines.");
$self->_add_grant('start_many',0,"Can have more than one machine started.");
$self->_add_grant('expose_ports',0,"Can expose virtual machine ports.");
......@@ -1106,6 +1108,7 @@ sub _enable_grants($self) {
,'remove', 'remove_all', 'remove_clone', 'remove_clone_all'
,'screenshot'
,'shutdown', 'shutdown_all', 'shutdown_clone'
,'reboot', 'reboot_all', 'reboot_clone'
,'screenshot'
,'start_many'
);
......@@ -3459,6 +3462,48 @@ sub _cmd_force_shutdown {
}
sub _cmd_reboot {
my $self = shift;
my $request = shift;
my $uid = $request->args('uid');
my $name = $request->defined_arg('name');
my $id_domain = $request->defined_arg('id_domain');
my $timeout = ($request->args('timeout') or 60);
my $id_vm = $request->defined_arg('id_vm');
confess "ERROR: Missing id_domain or name" if !$id_domain && !$name;
my $domain;
if ($name) {
if ($id_vm) {
my $vm = Ravada::VM->open($id_vm);
$domain = $vm->search_domain($name);
} else {
$domain = $self->search_domain($name);
}
die "Unknown domain '$name'\n" if !$domain;
}
if ($id_domain) {
my $domain2 = Ravada::Domain->open(id => $id_domain, id_vm => $id_vm);
die "ERROR: Domain $id_domain is ".$domain2->name." not $name."
if $domain && $domain->name ne $domain2->name;
$domain = $domain2;
die "Unknown domain '$id_domain'\n" if !$domain
}
Ravada::Request->refresh_machine(
uid => $uid
,id_domain => $id_domain
,after_request => $request->id
);
my $user = Ravada::Auth::SQL->search_by_id( $uid);
$domain->reboot(timeout => $timeout, user => $user
, request => $request);
}
sub _cmd_list_vm_types {
my $self = shift;
my $request = shift;
......@@ -3688,7 +3733,7 @@ sub _cmd_list_network_interfaces($self, $request) {
sub _cmd_list_isos($self, $request){
my $vm_type = $request->args('vm_type');
my $vm = Ravada::VM->open( type => $vm_type );
$vm->refresh_storage();
my @isos = sort { "\L$a" cmp "\L$b" } $vm->search_volume_path_re(qr(.*\.iso$));
......@@ -4021,6 +4066,7 @@ sub _req_method {
,cleanup => \&_cmd_cleanup
,download => \&_cmd_download
,shutdown => \&_cmd_shutdown
,reboot => \&_cmd_reboot
,hybernate => \&_cmd_hybernate
,set_driver => \&_cmd_set_driver
,screenshot => \&_cmd_screenshot
......
......@@ -429,7 +429,7 @@ sub can_list_clones {
return 1 if $self->can_remove_clone_all()
|| $self->can_list_machines();
return 0;
}
=head2 can_list_machines
......@@ -534,9 +534,9 @@ Arguments: password
sub compare_password {
my $self = shift;
my $password = shift or die "ERROR: password required\n";
_init_connector();
my $sth= $$CON->dbh->prepare("SELECT password FROM users WHERE name=?");
$sth->execute($self->name);
my $hex_pass = $sth->fetchrow();
......@@ -594,7 +594,7 @@ sub remove($self) {
Returns if the user is allowed to perform a privileged action
if ($user->can_do("remove")) {
if ($user->can_do("remove")) {
...
=cut
......@@ -630,7 +630,7 @@ Returns if the user is allowed to perform a privileged action in a virtual machi
=cut
sub can_do_domain($self, $grant, $domain) {
my %valid_grant = map { $_ => 1 } qw(change_settings shutdown rename);
my %valid_grant = map { $_ => 1 } qw(change_settings shutdown reboot rename);
confess "Invalid grant here '$grant'" if !$valid_grant{$grant};
return 0 if !$self->can_do($grant) && !$self->_domain_id_base($domain);
......@@ -798,7 +798,7 @@ sub revoke_all_permissions($self,$user) {
Grant an user a specific permission, or revoke it
$admin_user->grant($user2,"clone"); # both are
$admin_user->grant($user2,"clone"); # both are
$admin_user->grant($user3,"clone",1); # the same
$admin_user->grant($user4,"clone",0); # revoke a grant
......@@ -940,7 +940,7 @@ sub can_manage_machine($self, $domain) {
|| ($self->can_remove_clone_all && $domain->id_base)
|| ($self->can_remove && $domain->id_owner == $self->id);
if ( ($self->can_remove_clones || $self->can_change_settings_clones || $self->can_rename_clones)
if ( ($self->can_remove_clones || $self->can_change_settings_clones || $self->can_rename_clones)
&& $domain->id_base ) {
my $base = Ravada::Front::Domain->open($domain->id_base);
return 1 if $base->id_owner == $self->id;
......
......@@ -28,6 +28,7 @@ use Ravada::Domain::Driver;
use Ravada::Utils;
our $TIMEOUT_SHUTDOWN = 20;
our $TIMEOUT_REBOOT = 20;
our $CONNECTOR;
our $MIN_FREE_MEMORY = 1024*1024;
......@@ -54,6 +55,8 @@ requires 'shutdown';
requires 'shutdown_now';
requires 'force_shutdown';
requires '_do_force_shutdown';
requires 'reboot';
requires 'reboot_now';
requires 'pause';
requires 'resume';
......@@ -105,6 +108,12 @@ has 'timeout_shutdown' => (
,default => $TIMEOUT_SHUTDOWN
);
has 'timeout_reboot' => (
isa => 'Int'
,is => 'ro'
,default => $TIMEOUT_REBOOT
);
has 'readonly' => (
isa => 'Int'
,is => 'ro'
......@@ -176,6 +185,11 @@ after 'shutdown' => \&_post_shutdown;
around 'shutdown_now' => \&_around_shutdown_now;
around 'force_shutdown' => \&_around_shutdown_now;
before 'reboot' => \&_pre_shutdown;
after 'reboot' => \&_post_shutdown;
around 'reboot_now' => \&_around_reboot_now;
before 'remove_base' => \&_pre_remove_base;
after 'remove_base' => \&_post_remove_base;
after 'spinoff' => \&_post_spinoff;
......@@ -2223,6 +2237,8 @@ sub _post_spinoff($self) {
sub _pre_shutdown_domain {}
sub _pre_reboot_domain {}
sub _post_remove_base_domain {}
sub _remove_base_db {
......@@ -2549,6 +2565,8 @@ sub _around_shutdown_now {
$self->_post_shutdown(user => $user) if $self->is_known();
}
sub _around_reboot_now { _around_shutdown_now(@_); }
sub _around_name($orig,$self) {
return $self->{_name} if $self->{_name};
......
......@@ -49,6 +49,7 @@ has readonly => (
##################################################
#
our $TIMEOUT_SHUTDOWN = 60;
our $TIMEOUT_REBOOT = 60;
our $OUT;
our %SET_DRIVER_SUB = (
......@@ -777,8 +778,8 @@ sub _pre_shutdown_domain {
my ($state, $reason) = $self->domain->get_state();
if ($state == Sys::Virt::Domain::STATE_PMSUSPENDED_UNKNOWN
|| $state == Sys::Virt::Domain::STATE_PMSUSPENDED_DISK_UNKNOWN
if ($state == Sys::Virt::Domain::STATE_PMSUSPENDED_UNKNOWN
|| $state == Sys::Virt::Domain::STATE_PMSUSPENDED_DISK_UNKNOWN
|| $state == Sys::Virt::Domain::STATE_PMSUSPENDED) {
$self->domain->pm_wakeup();
for ( 1 .. 10 ) {
......@@ -853,6 +854,48 @@ sub _do_force_shutdown {
warn $@ if $@;
}
=head2 reboot
Stops the domain
=cut
sub reboot {
my $self = shift;
my %args = @_;
my $req = $args{req};
if (!$self->is_active) {
$req->status("done") if $req;
$req->error("Domain is down") if $req;
return;
}
return $self->_do_reboot();
}
sub _do_reboot {
my $self = shift;
warn "_do_reboot";
warn "RET" and
return if !$self->domain->is_active;
eval { $self->domain->reboot() };
warn ">>> $@";
die $@ if $@;
}
=head2 reboot_now
Reboots uncleanly the domain
=cut
sub reboot_now {
my $self = shift;
return $self->_do_reboot() if $self->is_active;
}
=head2 pause
......@@ -1937,12 +1980,12 @@ sub _set_controller_usb($self,$numero, $data={}) {
$numero = $count+1 if !defined $numero;
if ( $numero > $count ) {
my $missing = $numero-$count-1;
for my $i (0..$missing) {
my $controller = $devices->addNewChild(undef,"redirdev");
$controller->setAttribute(bus => 'usb');
$controller->setAttribute(type => $tipo );
}
}
}
$self->_vm->connect if !$self->_vm->vm;
my $new_domain = $self->_vm->vm->define_domain($doc->toString);
......@@ -1973,7 +2016,7 @@ sub _set_controller_network($self, $number, $data) {
sub remove_controller($self, $name, $index=0) {
my $sub = $REMOVE_CONTROLLER_SUB{$name};
die "I can't get controller $name for domain ".$self->name
." ".$self->type
."\n".Dumper(\%REMOVE_CONTROLLER_SUB)
......
......@@ -234,6 +234,17 @@ sub shutdown_now {
return $self->shutdown(user => $user);
}
sub reboot {
my $self = shift;
$self->_store(is_active => 0);
}
sub reboot_now {
my $self = shift;
my $user = shift;
return $self->reboot(user => $user);
}
sub start($self, @args) {
my %args;
%args = @args if scalar(@args) % 2 == 0;
......@@ -559,7 +570,7 @@ sub set_max_memory {
sub set_memory {
my $self = shift;
my $value = shift;
$self->_set_info(memory => $value );
}
......
......@@ -224,6 +224,8 @@ sub init_available_actions($user, $m) {
$m->{can_start} = 0;
$m->{can_start} = 1 if $m->{id_owner} == $user->id || $user->is_admin;
$m->{can_reboot} = $m->{can_shutdown} && $m->{can_start};
$m->{can_view} = 0;
$m->{can_view} = 1 if $m->{id_owner} == $user->id || $user->is_admin;
......@@ -932,6 +934,7 @@ sub list_requests($self, $id_domain_req=undef, $seconds=60) {
next if ( $command eq 'force_shutdown'
|| $command eq 'start'
|| $command eq 'shutdown'
|| $command eq 'reboot'
|| $command eq 'hibernate'
)
&& time - $epoch_date_changed > 5
......
......@@ -152,7 +152,7 @@ sub migrate { confess "TODO" }
sub name($self) {
return $self->{_data}->{name} if exists $self->{_data} && $self->{_data}->{name};
return $self->_data('name')
return $self->_data('name')
}
sub pause { confess "TODO" }
......@@ -176,6 +176,8 @@ sub set_max_mem { confess "TODO" }
sub set_memory { confess "TODO" }
sub shutdown { confess "TODO" }
sub shutdown_now { confess "TODO" }
sub reboot { confess "TODO" }
sub reboot_now { confess "TODO" }
sub spinoff { confess "TODO" }
sub start { confess "TODO" }
......
......@@ -66,6 +66,8 @@ our %VALID_ARG = (
,shutdown_domain => { name => 2, id_domain => 2, uid => 1, timeout => 2, at => 2
, id_vm => 2 }
,force_shutdown_domain => { id_domain => 1, uid => 1, at => 2, id_vm => 2 }
,reboot_domain => { name => 2, id_domain => 2, uid => 1, timeout => 2, at => 2
, id_vm => 2 }
,screenshot => { id_domain => 1 }
,domain_autostart => { id_domain => 1 , uid => 1, value => 2 }
,copy_screenshot => { id_domain => 1 }
......@@ -128,7 +130,7 @@ our %VALID_ARG = (
);
our %CMD_SEND_MESSAGE = map { $_ => 1 }
qw( create start shutdown prepare_base remove remove_base rename_domain screenshot download
qw( create start shutdown reboot prepare_base remove remove_base rename_domain screenshot download
clone
set_base_vm remove_base_vm
domain_autostart hibernate hybernate
......@@ -136,7 +138,7 @@ our %CMD_SEND_MESSAGE = map { $_ => 1 }
add_hardware remove_hardware set_driver change_hardware
expose remove_expose
rebase rebase_volumes
shutdown_node start_node
shutdown_node reboot_node start_node
);
our %CMD_NO_DUPLICATE = map { $_ => 1 }
......@@ -146,6 +148,7 @@ qw(
);
our $TIMEOUT_SHUTDOWN = 120;
our $TIMEOUT_REBOOT = 20;
our $CONNECTOR;
......@@ -452,7 +455,7 @@ sub _check_args {
Requests to stop a domain now !
my $req = Ravada::Request->shutdown_domain( name => 'name' , uid => $user->id );
my $req = Ravada::Request->force_shutdown_domain( name => 'name' , uid => $user->id );
=cut
......@@ -495,6 +498,33 @@ sub shutdown_domain {
return $self->_new_request(command => 'shutdown' , args => $args);
}
=head2 reboot_domain
Requests to reboot a domain
my $req = Ravada::Request->reboot_domain( name => 'name' , uid => $user->id );
my $req = Ravada::Request->reboot_domain( name => 'name' , uid => $user->id
,timeout => $timeout );
=cut
sub reboot_domain {
my $proto = shift;
my $class=ref($proto) || $proto;
my $args = _check_args('reboot_domain', @_ );
$args->{timeout} = $TIMEOUT_REBOOT if !exists $args->{timeout};
confess "ERROR: You must supply either id_domain or name ".Dumper($args)
if !$args->{id_domain} && !$args->{name};
my $self = {};
bless($self,$class);
return $self->_new_request(command => 'reboot' , args => $args);
}
=head2 new_request
Creates a new request
......
......@@ -556,6 +556,13 @@ get '/machine/shutdown/(:id).(:type)' => sub {
return shutdown_machine($c);
};
get '/machine/reboot/(:id).(:type)' => sub {
my $c = shift;
return access_denied($c) if !$USER ->can_reboot($c->stash('id'));
return reboot_machine($c);
};
any '/machine/remove/(:id).(:type)' => sub {
my $c = shift;
return access_denied($c) if !$USER->can_remove_machine($c->stash('id'));
......@@ -2212,6 +2219,19 @@ sub shutdown_machine {
return $c->render(json => { req => $req->id });
}
sub reboot_machine {
my $c = shift;
return login($c) if !_logged_in($c);
my ($domain, $type) = _search_requested_machine($c);
my $req;
$req = Ravada::Request->reboot_domain(id_domain => $domain->id, uid => $USER->id);
return $c->redirect_to('/machines') if $type eq 'html';
return $c->render(json => { req => $req->id });
}
sub _do_remove_machine {
my $c = shift;
return login($c) if !_logged_in($c);
......
......@@ -13,6 +13,7 @@ INSERT INTO grant_types(name,description) VALUES('create_base',"can create bases
INSERT INTO grant_types(name,description) VALUES('change_settings_clones',"can change the settings of any virtual machine cloned from one base owned by the user.");
INSERT INTO grant_types(name,description) VALUES('remove_clone',"can remove clones from virtual machines owned by the user.");
INSERT INTO grant_types(name,description) VALUES('shutdown_clone',"can shutdown clones from virtual machines owned by the user.");
INSERT INTO grant_types(name,description) VALUES('reboot_clone',"can reboot clones from virtual machines owned by the user.");
INSERT INTO grant_types(name,description) VALUES('hibernate_clone',"can hibernate clones from virtual machines owned by the user.");
/* operators should be allowed these */
......@@ -24,6 +25,7 @@ INSERT INTO grant_types(name,description) VALUES('hibernate_clone_all',"can hibe
INSERT INTO grant_types(name,description) VALUES('clone_all',"can clone any virtual machine.");
INSERT INTO grant_types(name,description) VALUES('remove_all',"can remove any virtual machine.");
INSERT INTO grant_types(name,description) VALUES('shutdown_all',"can shutdown any virtual machine.");
INSERT INTO grant_types(name,description) VALUES('reboot_all',"can reboot any virtual machine.");
INSERT INTO grant_types(name,description) VALUES('hibernate_all',"can hibernate any virtual machine.");
INSERT INTO grant_types(name,description) VALUES('screenshot_all',"can take a screenshot of any virtual machine.");
......
......@@ -10,47 +10,62 @@
<br><br>
<div>
<div ng-show="showmachine.can_hibernate">
<button type="button" class="btn btn-warning btn-sm"
ng-click="action('machine','hibernate',showmachine.id)"
ng-disabled="!showmachine.is_active"
title="<%=l 'Hibernate' %>">
<i class="fa fa-pause"></i>
</button>
<span><%=l 'Hibernate' %></span>
<br><br>
</div>
<div ng-show="showmachine.is_active">
<div ng-show="showmachine.can_shutdown">
<button type="button" class="btn btn-danger btn-sm"
ng-click="action('machine','shutdown',showmachine.id)"
ng-disabled="!showmachine.is_active"
title="<%=l 'ShutDown' %>">
<i class="fa fa-power-off"></i>
</button>
<span><%=l 'ShutDown' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_hibernate">
<button type="button" class="btn btn-warning btn-sm"
ng-click="action('machine','hibernate',showmachine.id)"
ng-disabled="!showmachine.is_active"
title="<%=l 'Hibernate' %>">
<i class="fa fa-pause"></i>
</button>
<span><%=l 'Hibernate' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_shutdown">
<button type="button" class="btn btn-danger btn-sm"
ng-click="action('machine','shutdown',showmachine.id, { force: true })"
ng-disabled="!showmachine.is_active"
title="<%=l 'Force ShutDown' %>">
<i class="fa fa-power-off"></i>
</button>
<span><%=l 'Force ShutDown' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_shutdown">
<button type="button" class="btn btn-danger btn-sm"
ng-click="action('machine','shutdown',showmachine.id)"
ng-disabled="!showmachine.is_active"
title="<%=l 'ShutDown' %>">
<i class="fa fa-power-off"></i>
</button>
<span><%=l 'ShutDown' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_shutdown">
<button type="button" class="btn btn-danger btn-sm"
ng-click="action('machine','shutdown',showmachine.id, { force: true })"
ng-disabled="!showmachine.is_active"
title="<%=l 'Force ShutDown' %>">
<i class="fa fa-power-off"></i>
</button>
<span><%=l 'Force ShutDown' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_reboot">
<button type="button" class="btn btn-danger btn-sm"
ng-click="action('machine','reboot',showmachine.id)"
ng-disabled="!showmachine.is_active"
title="<%=l 'Reboot' %>">
<i class="fa fa-power-off"></i>
</button>
<span><%=l 'Reboot' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_view">
<a type="button" class="btn btn-primary btn-sm"
ng-href="/machine/view/{{showmachine.id}}.html"
title="<%=l 'View' %>">
<i class="fa fa-desktop"></i>
</a>
<span><%=l 'View' %></span>
<br><br>
</div>
<div ng-show="showmachine.can_view">
<a type="button" class="btn btn-primary btn-sm"
ng-href="/machine/view/{{showmachine.id}}.html"
title="<%=l 'View' %>">
<i class="fa fa-desktop"></i>
</a>
<span><%=l 'View' %></span>
<br><br>
</div>
</div>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment