Skip to content

Commit c947c3b

Browse files
Feat rdp client file (#2148)
feat: render RDP display file closes #2142 Co-authored-by: Roger Ferre <[email protected]>
1 parent 14e0b0a commit c947c3b

File tree

6 files changed

+165
-18
lines changed

6 files changed

+165
-18
lines changed

lib/Ravada/Domain.pm

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,8 +1358,14 @@ sub _store_display($self, $display, $display_old=undef) {
13581358
$self->_set_display_ip(\%display_new) if !exists $display->{ip} || !$display->{ip};
13591359
if (!exists $display_new{ip} || !$display_new{ip}) {
13601360
unlock_hash(%display_new);
1361-
$display_new{ip} = $self->_vm->ip;
1362-
$display_new{listen_ip} = $display_new{ip};
1361+
$display_new{listen_ip} = $self->_vm->ip;
1362+
my $display_ip = ( $self->_vm->nat_ip
1363+
or $self->_vm->display_ip
1364+
or $self->_vm->public_ip
1365+
or $self->_vm->ip
1366+
);
1367+
1368+
$display_new{ip} = $display_ip;
13631369
}
13641370

13651371
if ( !$display_old ) {
@@ -1369,7 +1375,6 @@ sub _store_display($self, $display, $display_old=undef) {
13691375
$display_old = $self->_get_display($display->{driver})
13701376
}
13711377

1372-
my $ip = ( $display_new{ip} or $display_old->{ip} );
13731378
my $driver = ( $display_new{driver} or $display_old->{driver} );
13741379
if (exists $display_new{port} && $display_new{port}
13751380
&& (!exists $display_new{id_vm} || !$display_new{id_vm}) ) {
@@ -2135,6 +2140,59 @@ sub display($self, $user) {
21352140
return $display;
21362141
}
21372142

2143+
sub _display_file_rdp($self,$display) {
2144+
2145+
my $ret = "screen mode id:i:2
2146+
use multimon:i:0
2147+
desktopwidth:i:1280
2148+
desktopheight:i:1024
2149+
session bpp:i:32
2150+
winposstr:s:0,1,14,5,1280,1000
2151+
compression:i:1
2152+
keyboardhook:i:2
2153+
audiocapturemode:i:0
2154+
videoplaybackmode:i:1
2155+
connection type:i:7
2156+
networkautodetect:i:1
2157+
bandwidthautodetect:i:1
2158+
displayconnectionbar:i:1
2159+
enableworkspacereconnect:i:0
2160+
disable wallpaper:i:0
2161+
allow font smoothing:i:0
2162+
allow desktop composition:i:0
2163+
disable full window drag:i:1
2164+
disable menu anims:i:1
2165+
disable themes:i:0
2166+
disable cursor setting:i:0
2167+
bitmapcachepersistenable:i:1
2168+
full address:s:".$display->{ip}.":".$display->{port}."\n"
2169+
."audiomode:i:0
2170+
redirectprinters:i:0
2171+
redirectcomports:i:0
2172+
redirectsmartcards:i:0
2173+
redirectclipboard:i:1
2174+
redirectposdevices:i:0
2175+
autoreconnection enabled:i:1
2176+
authentication level:i:0
2177+
prompt for credentials:i:0
2178+
negotiate security layer:i:1
2179+
remoteapplicationmode:i:0
2180+
alternate shell:s:
2181+
shell working directory:s:
2182+
gatewayhostname:s:
2183+
gatewayusagemethod:i:4
2184+
gatewaycredentialssource:i:4
2185+
gatewayprofileusagemethod:i:0
2186+
promptcredentialonce:i:0
2187+
gatewaybrokeringtype:i:0
2188+
use redirection server name:i:0
2189+
rdgiskdcproxy:i:0
2190+
kdcproxyname:s:
2191+
drivestoredirect:s:*
2192+
username:s:
2193+
";
2194+
}
2195+
21382196
# taken from isard-vdi thanks to @tuxinthejungle Alberto Larraz
21392197
sub _display_file_spice($self,$display, $tls = 0) {
21402198

@@ -3802,6 +3860,7 @@ sub _open_exposed_port($self, $internal_port, $name, $restricted, $remote_ip=und
38023860
." WHERE id_domain=? AND internal_port=?"
38033861
);
38043862
$sth->execute($internal_ip, $self->id, $internal_port);
3863+
38053864
$self->_update_display_port_exposed($name, $local_ip, $public_port, $internal_port);
38063865

38073866
if ( !$> && $public_port ) {
@@ -3862,10 +3921,14 @@ sub _update_display_port_exposed($self, $name, $local_ip, $public_port, $interna
38623921
." SET ip=?,listen_ip=?,port=?,is_active=?,id_vm=? "
38633922
." WHERE driver=? AND id_domain=?"
38643923
);
3924+
my $display_ip = ( $self->_vm->nat_ip
3925+
or $self->_vm->display_ip
3926+
or $local_ip );
3927+
38653928
my $is_builtin;
38663929
for (1 .. 10) {
38673930
eval {
3868-
$sth->execute($local_ip, $local_ip, $public_port,1, $self->_vm->id
3931+
$sth->execute($display_ip, $local_ip, $public_port,1, $self->_vm->id
38693932
,$name, $self->id);
38703933
};
38713934
warn "Warning: $@".Dumper([$name, $public_port]) if $@;

lib/Ravada/Domain/Void.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ sub _set_display($self, $listen_ip=$self->_vm->listen_ip) {
156156
# my $ip = ($self->_vm->nat_ip or $self->_vm->ip());
157157
my $port = 'auto';
158158
$port = $self->_new_free_port() if $self->is_active();
159-
my $display_data = { driver => 'void', ip => $listen_ip, port =>$port
159+
my $display_data = { driver => 'void', listen_ip => $listen_ip, port =>$port
160160
, is_builtin => 1
161161
, xistorra => 1
162162
};

lib/Ravada/Front/Domain.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ sub _get_controller_display($self) {
217217
my %file_extension = (
218218
'spice' => 'vv'
219219
,'spice-tls' => 'tls.vv'
220+
,'rdp' => 'rdp'
220221
);
221222

222223
my $sth = $$CONNECTOR->dbh->prepare(

script/rvd_front

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,26 @@ get '/machine/display/(:driver)/(:id).(#extension)' => sub {
17271727
|| $USER->can_view_all
17281728
;
17291729

1730+
if ($extension eq 'vv') {
1731+
return _display_file_spice($c, $domain, $extension, $display);
1732+
} elsif ($extension eq 'rdp' ) {
1733+
return _display_file_rdp($c, $domain, $extension, $display);
1734+
} else {
1735+
return not_found($c);
1736+
}
1737+
};
1738+
1739+
sub _display_file_rdp($c, $domain, $extension, $display) {
1740+
$c->res->headers->content_type('application/x-rdp');
1741+
$c->res->headers->content_disposition(
1742+
"inline;filename=".$domain->id.".$extension");
1743+
1744+
my $format = $extension;
1745+
$format =~ s/^(\w+)\.(\w+)/$2/;
1746+
return $c->render(data => $domain->_display_file_rdp($display), format => $format);
1747+
};
1748+
1749+
sub _display_file_spice($c, $domain, $extension, $display) {
17301750
$c->res->headers->content_type('application/x-virt-viewer');
17311751
$c->res->headers->content_disposition(
17321752
"inline;filename=".$domain->id.".$extension");
@@ -1738,6 +1758,7 @@ get '/machine/display/(:driver)/(:id).(#extension)' => sub {
17381758
return $c->render(data => $domain->_display_file_spice($display, $tls), format => $format);
17391759
};
17401760

1761+
17411762
# Network ##########################################################3
17421763

17431764
get '/network/interfaces/(:vm_type)/(:type)' => sub {

t/lib/Test/Ravada.pm

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,31 +3218,44 @@ sub create_ram_fs($dir=undef,$size=1024*1024) {
32183218
sub wait_ip($id_domain0, $seconds=60) {
32193219

32203220
my $domain;
3221+
if (!ref($id_domain0) && $id_domain0 =~ /^\d+$/) {
3222+
$domain = Ravada::Front::Domain->open($id_domain0);
3223+
}
32213224
for my $count ( 0 .. $seconds ) {
32223225
my $id_domain = $id_domain0;
3223-
if (ref($id_domain0)) {
3224-
if (ref($id_domain0) =~ /Ravada/) {
3225-
$id_domain = $id_domain0->id;
3226+
$id_domain = $domain->id if $domain;
3227+
if (!$domain) {
3228+
if (ref($id_domain0)) {
3229+
if (ref($id_domain0) =~ /Ravada/) {
3230+
$id_domain = $id_domain0->id;
3231+
} else {
3232+
$id_domain = $id_domain0->{id};
3233+
}
32263234
} else {
3227-
$id_domain = $id_domain0->{id};
3235+
if ($id_domain0 !~ /^\d+$/) {
3236+
$id_domain = _search_domain_by_name($id_domain0);
3237+
if ( !$id_domain ) {
3238+
sleep 1;
3239+
next;
3240+
}
3241+
} else {
3242+
$id_domain = $id_domain0;
3243+
}
32283244
}
3229-
}
32303245

3231-
if ($id_domain0 !~ /^\d+$/) {
3232-
$id_domain = _search_domain_by_name($id_domain);
3233-
next if !$id_domain;
3246+
eval{ $domain = Ravada::Front::Domain->open($id_domain) };
3247+
warn $@ if $@ && $@ !~ /Unknown domain/;
32343248
}
32353249

32363250
Ravada::Request->refresh_machine(
32373251
id_domain => $id_domain
32383252
,uid => user_admin->id
3253+
,_force => 1
32393254
);
3255+
wait_request();
32403256

32413257
my $info;
3242-
eval {
3243-
$domain = Ravada::Front::Domain->open($id_domain);
32443258
$info = $domain->info(user_admin);
3245-
};
32463259
warn $@ if $@ && $@ !~ /Unknown domain/;
32473260
return if $@ || ($count && !$domain->is_active);
32483261
return $info->{ip} if exists $info->{ip} && $info->{ip};

t/vm/n10_nat.t

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ my $FILE_CONFIG = "t/etc/ravada.conf";
1818
init( );
1919

2020
my $NAT_IP = '2.2.2.2';
21-
2221
my $REMOTE_IP = '9.9.9.9';
23-
2422
my $CHAIN = 'RAVADA';
23+
24+
my $BASE;
2525
##################################################################################
2626

2727
sub _search_other_ip($ip) {
@@ -66,6 +66,43 @@ sub test_route($vm) {
6666
}
6767
}
6868

69+
sub test_nat_rdp($vm) {
70+
my $domain = $BASE->clone(user => user_admin
71+
,name => new_domain_name);
72+
73+
Ravada::Request->add_hardware(
74+
name => 'display'
75+
,uid => user_admin->id
76+
,data => { driver => 'rdp' }
77+
,id_domain => $domain->id
78+
);
79+
$vm->nat_ip($NAT_IP);
80+
wait_request();
81+
my $req = Ravada::Request->start_domain(
82+
uid => user_admin->id
83+
,id_domain => $domain->id
84+
,remote_ip => $REMOTE_IP
85+
);
86+
wait_request(debug=>0);
87+
88+
wait_ip($domain);
89+
90+
die "Error: no ip found for ".$domain->name if !$domain->ip;
91+
92+
$req->status('requested');
93+
wait_request(debug=>0);
94+
95+
my $sth = connector->dbh->prepare("SELECT * FROM domain_displays "
96+
." WHERE id_domain=?");
97+
$sth->execute($domain->id);
98+
while (my $row = $sth->fetchrow_hashref) {
99+
is($row->{listen_ip}, $vm->ip,"listen_ip ".$row->{driver});
100+
is($row->{ip},$NAT_IP,"ip ".$row->{driver}) or exit;
101+
}
102+
$vm->nat_ip('');
103+
}
104+
105+
69106
sub test_nat($vm_name) {
70107
my $domain = create_domain($vm_name);
71108

@@ -204,6 +241,15 @@ sub test_chain($vm_name, %args) {
204241

205242
}
206243
}
244+
245+
sub _import_base($vm) {
246+
if ($vm->type eq 'KVM') {
247+
$BASE = import_domain($vm);
248+
} else {
249+
$BASE = create_domain($vm);
250+
}
251+
}
252+
207253
##################################################################################
208254

209255
clean();
@@ -225,6 +271,9 @@ for my $vm_name ( vm_names() ) {
225271
diag($msg) if !$vm;
226272
skip $msg,10 if !$vm;
227273

274+
_import_base($vm);
275+
test_nat_rdp($vm);
276+
228277
test_route($vm);
229278
test_nat($vm_name);
230279
}

0 commit comments

Comments
 (0)