Skip to content

Commit

Permalink
Feat: device domain (#2022)
Browse files Browse the repository at this point in the history
feat: show domain that has locked the device
  • Loading branch information
frankiejol committed Feb 12, 2024
1 parent 7f2fe1e commit fbbcd26
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 15 deletions.
2 changes: 1 addition & 1 deletion MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ lib/Ravada/I18N/ca.po
lib/Ravada/NetInterface.pm
lib/Ravada/Auth.pm
lib/Ravada/Domain.pm
lib/Ravada/Network.pm
lib/Ravada/Routes.pm
script/rvd_front
script/rvd_back
61 changes: 54 additions & 7 deletions lib/Ravada/WebSocket.pm
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,7 @@ sub _list_host_devices($rvd, $args) {

my @found;
while (my $row = $sth->fetchrow_hashref) {
$row->{devices} = decode_json($row->{devices}) if $row->{devices};
$row->{_domains} = _list_domains_with_device($rvd, $row->{id});
_list_domains_with_device($rvd, $row);
push @found, $row;
next unless _its_been_a_while_channel($args->{channel});
my $req = Ravada::Request->list_host_devices(
Expand All @@ -250,17 +249,65 @@ sub _list_host_devices($rvd, $args) {
return \@found;
}

sub _list_domains_with_device($rvd,$id_hd) {
my $sth=$rvd->_dbh->prepare("SELECT d.name FROM domains d,host_devices_domain hdd"
sub _list_domains_with_device($rvd,$row) {
my $id_hd = $row->{id};

my %devices;
eval {
my $devices = decode_json($row->{devices});
%devices = map { $_ => { name => $_ } } @$devices;
} if $row->{devices};
my $sth=$rvd->_dbh->prepare("SELECT d.id,d.name,d.is_base, d.status, l.id, l.name "
." FROM host_devices_domain hdd, domains d"
." LEFT JOIN host_devices_domain_locked l"
." ON d.id=l.id_domain "
." WHERE d.id= hdd.id_domain "
." AND hdd.id_host_device=?"
." ORDER BY d.name"
);
$sth->execute($id_hd);
my ( @domains, @bases);
while ( my ($id,$name,$is_base, $status, $is_locked, $device) = $sth->fetchrow ) {
$is_locked = 0 if !$is_locked || $status ne 'active';
$device = '' if !$device;
my $domain = { id => $id ,name => $name, is_locked => $is_locked
,is_base => $is_base ,device => $device
};
$devices{$device}->{domain} = $domain if exists $devices{$device} && $is_locked;
if ($is_base) {
push @bases, ($domain);
} else {
push @domains, ($domain);
}
}
for my $dev ( values %devices ) {
_get_domain_with_device($rvd, $dev);
}

$row->{_domains} = \@domains;
$row->{_bases} = \@bases;
$row->{devices} = [values %devices];
}

sub _get_domain_with_device($rvd, $dev) {
my $sql =
"SELECT d.id, d.name, d.is_base, d.status "
." FROM host_devices_domain_locked l, domains d "
." WHERE l.id_domain = d.id "
." AND l.name=?"
;

my $sth = $rvd->_dbh->prepare($sql);
$sth->execute($dev->{name});
my @domains;
while ( my ($name) = $sth->fetchrow ) {
push @domains,($name);
while ( my ($id,$name,$is_base, $status, $is_locked, $device) = $sth->fetchrow ) {
$is_locked = 0 if !$is_locked || $status ne 'active';
$device = '' if !$device;
my $domain = { id => $id ,name => $name, is_locked => $is_locked
,is_base => $is_base ,device => $device
};
$dev->{domain} = $domain;# if $is_locked;
}
return \@domains;
}

sub _list_requests($rvd, $args) {
Expand Down
124 changes: 120 additions & 4 deletions t/device/10_templates.t
Original file line number Diff line number Diff line change
Expand Up @@ -583,14 +583,102 @@ sub _mangle_dom_hd_kvm($domain) {
$domain->reload_config($xml);
}

sub test_templates_change_devices($vm) {
return if $vm->type ne 'Void';
sub _create_host_devices($vm, $n) {
if ($vm->type eq 'Void') {
return _create_host_devices_void($vm,$n);
} elsif ($vm->type eq 'KVM') {
return _create_host_devices_kvm($vm,$n);
} else {
die "Error: I don't know how to create host devices for ".$vm->type;
}
}

sub _create_host_devices_void($vm, $n) {
my $path = "/var/tmp/$</ravada/dev";
my @hds;
for my $count ( 1 .. $n ) {
my $hd = _mock_hd($vm , $path);
push @hds,($hd);
}
return @hds;
}

sub _create_host_devices_kvm($vm,$n) {
my $templates = Ravada::HostDevice::Templates::list_templates($vm->type);
ok(@$templates);

my ($template) = grep { $_->{list_command} =~ /lspci/ } @$templates;

my @hds;
for ( 1 .. $n ) {
my $id_hd = $vm->add_host_device(template => $template->{name});
my $hd = Ravada::HostDevice->search_by_id($id_hd);

my $config = config_host_devices('pci');
$hd->_data('list_filter' => $config);
push @hds,($hd);
}

return @hds;

}

sub test_frontend_list($vm) {

my ($hd1, $hd2) = _create_host_devices($vm, 2);

if (scalar($hd1->list_devices) != scalar($hd2->list_devices)) {
die "Error: expecting the same count of devices in both mock hds";
}

my $domain = _create_domain_hd($vm, $hd1);
$domain->start(user_admin);

my $ws_args = {
channel => '/'.$vm->id
,login => user_admin->name
};
my $front_devices = Ravada::WebSocket::_list_host_devices(rvd_front(), $ws_args);
is(scalar(@$front_devices),2) or exit;

my ($dev_attached) = ($domain->list_host_devices_attached);

my $found=0;
for my $fd ( @$front_devices ) {
for my $dev ( @{$fd->{devices}} ) {
if ($dev->{name} eq $dev_attached->{name}) {
ok($dev->{domain} , "Expecting domains listed in ".$dev->{name}) or next;
is($dev->{domain}->{id}, $domain->id,"Expecting ".$domain->name." attached in ".$dev->{name});
$found++ if $dev->{domain}->{id} == $domain->id;
}
}
}
is($found,2) or die Dumper($front_devices);

remove_domain($domain);

_remove_host_devices($vm);
}

sub _mock_hd($vm, $path) {

my ($template, $name) = _mock_devices($vm , $path);

my $id_hd = $vm->add_host_device(template => $template->{name});
my $hd = Ravada::HostDevice->search_by_id($id_hd);

$hd->_data(list_command => "ls $path");
$hd->_data(list_filter => $name);

return $hd;
}

sub _mock_devices($vm, $path) {
my $templates = Ravada::HostDevice::Templates::list_templates($vm->type);
ok(@$templates);

my ($template) = grep { $_->{list_command} eq 'lsusb' } @$templates;

my $path = "/var/tmp/$</ravada/dev";
make_path($path) if !-e $path;

my $name = base_domain_name()." Mock_device ID";
Expand All @@ -610,6 +698,15 @@ sub test_templates_change_devices($vm) {
close $out;
}

return ($template, $name);
}

sub test_templates_change_devices($vm) {
return if $vm->type ne 'Void';

my $path = "/var/tmp/$</ravada/dev";
my ($template, $name) = _mock_devices($vm, $path);

$vm->add_host_device(template => $template->{name});
my ($hostdev) = $vm->list_host_devices();
$hostdev->_data(list_command => "ls $path");
Expand Down Expand Up @@ -666,7 +763,11 @@ sub test_templates_change_filter($vm) {

$domain->remove(user_admin);
}
_remove_host_devices($vm);

}

sub _remove_host_devices($vm) {
for my $hd ( $vm->list_host_devices ) {
my $req = Ravada::Request->remove_host_device(
uid => user_admin->id
Expand All @@ -676,7 +777,6 @@ sub test_templates_change_filter($vm) {
is($req->status,'done');
is($req->error, '') or exit;
}

}

sub test_templates($vm) {
Expand Down Expand Up @@ -705,8 +805,11 @@ sub test_templates($vm) {

_fix_host_device($host_device) if $vm->type eq 'KVM';

warn 11;
test_hd_in_domain($vm, $host_device);
warn 12;
test_hd_dettach($vm, $host_device);
warn 13;

my $req = Ravada::Request->list_host_devices(
uid => user_admin->id
Expand Down Expand Up @@ -833,13 +936,26 @@ for my $vm_name ( vm_names()) {

diag("Testing host devices in $vm_name");

test_frontend_list($vm);

warn 1;

test_templates_gone_usb_2($vm);

warn 2;

test_templates_gone_usb($vm);
warn 3;
test_templates_changed_usb($vm);

warn 4;
test_templates_start_nohd($vm);
warn 5;
test_templates_change_filter($vm);

warn 6;
test_templates($vm);
warn 7;
test_templates_change_devices($vm);

}
Expand Down
2 changes: 1 addition & 1 deletion templates/main/admin_machines.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
,active_machine: machine.status == 'active'
}"
title ="<%=l 'Manage machine' %>">{{machine.name}}</a> {{machine.comment}}
<span class="comment" ng-show="machine.is_volatile"><%=l 'Volatile' %></span>
<span class="comme497461nt" ng-show="machine.is_volatile"><%=l 'Volatile' %></span>
<button ng-show="machine.has_clones && !filter"
type="button"
class="badge badge-light text-blue"
Expand Down
61 changes: 60 additions & 1 deletion templates/main/node_hostdev.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,67 @@
<div ng-show="!hdev.devices"><i class="fa fa-sync-alt fa-spin"></i></div>
<ul>
<li ng-repeat="device in hdev.devices">
{{device}}
{{device.name}}
<a class="badge badge-primary" href="/machine/manage/{{device.domain.id}}.html#!#v-pills-hostdev"
ng-show="device.domain">{{device.domain.name}}</a>
</li>
</ul>
<div ng-show="hdev._bases.length" class="ml-0">
<b>Bases</b>
<i ng-click="show_bases[hdev.id]=true" ng-show="!show_bases[hdev.id]"
class="fa fa-caret-right"></i>
<i ng-click="show_bases[hdev.id]=false" ng-show="show_bases[hdev.id]"
class="fa fa-caret-down"></i>
<div ng-show="show_bases[hdev.id]">
<div class="row ml-0 pl-0" ng-repeat="domain in hdev._bases">
<div class="col col-sm-1 ml-0 pl-0" align="right">
</div>
<div class="col col-sm-10 ml-0 pl-0">
<a href="/machine/manage/{{domain.id}}.html"
class="machine"
>
<span ng-class="disabled">{{domain.name}}</span>
</a>
</div>
</div>
</div>


</div>

<div ng-show="hdev._domains.length" class="ml-0">
<b>Machines</b>
<i ng-click="show_domains[hdev.id]=true" ng-show="!show_domains[hdev.id]"
class="fa fa-caret-right"></i>
<i ng-click="show_domains[hdev.id]=false" ng-show="show_domains[hdev.id]"
class="fa fa-caret-down"></i>
<div ng-show="show_domains[hdev.id]">
<div class="row ml-0 pl-0" ng-repeat="domain in hdev._domains">
<div class="col col-md-1 ml-0 pl-0" align="right">
<a ng-show="domain.is_locked"
align="right"
title="<%=l 'locked' %>"
><i class="fa fa-arrow-right"></i>
</a>
</div>
<div class="col col-md-11 ml-0 pl-0">
<a href="/machine/manage/{{domain.id}}.html"
class="machine"
ng-class="{
machine: domain.is_locked==0
,active_machine: domain.is_locked>0
}"

><b ng-show="domain.is_locked">{{domain.name}}</b>
<span ng-class="disabled" ng-show="domain.is_locked==0">{{domain.name}}</span>
</a>
<span ng-show="domain.is_locked" class="ml-4"><small>{{domain.device}}</small></span>
</div>
</div>
</div>

</div>


</div>
</div>
9 changes: 8 additions & 1 deletion templates/main/vm_hostdev.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@
ng-click="toggle_host_device(hdev.id)"/> <b>{{hdev.name}}</b>
<ul>
<li ng-repeat="device in hdev.devices">
{{device}}
{{device.name}}
<span class="badge badge-primary" ng-show="showmachine.is_active && device.domain && device.domain.is_locked"><%=l 'locked' %></span>
<a href="/machine/manage/{{device.domain.id}}.html"
class="badge badge-danger"
ng-show="device.domain && device.domain.is_locked && device.domain.id != showmachine.id">
<%=l 'locked by' %>
{{device.domain.name}}
</a>
</li>
</ul>
</div>
Expand Down

0 comments on commit fbbcd26

Please sign in to comment.