Skip to content

Commit

Permalink
Fix re-connecting via VNC over WebSockets
Browse files Browse the repository at this point in the history
* Before overriding the VNC hostname to `127.0.0.1` (to connect to
  `dewebsockify`), save the original hostname.
* When checking whether VNC over WebSockets should be enabled, compare the
  configured `VIRSH_GUEST` with the saved hostname and not the overridden
  one.
* This should fix the problems mentioned in
  https://progress.opensuse.org/issues/114820
  • Loading branch information
Martchus committed Jul 29, 2022
1 parent 1a85ca4 commit 33e2b56
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
3 changes: 2 additions & 1 deletion consoles/VMWare.pm
Expand Up @@ -117,7 +117,7 @@ sub launch_vnc_server ($self, $listen_port) {

sub deduce_url_from_vars ($vnc_console) {
return undef unless $bmwqemu::vars{VMWARE_VNC_OVER_WS};
return undef unless $vnc_console->hostname eq ($bmwqemu::vars{VIRSH_GUEST} // '');
return undef unless ($vnc_console->original_hostname // $vnc_console->hostname) eq ($bmwqemu::vars{VIRSH_GUEST} // '');
my $host = $bmwqemu::vars{VMWARE_HOST} or die "VMWARE_VNC_OVER_WS set but not VMWARE_HOST\n";
my $user = $bmwqemu::vars{VMWARE_USERNAME} // 'root';
my $password = $bmwqemu::vars{VMWARE_PASSWORD} or die "VMWARE_VNC_OVER_WS set but not VMWARE_PASSWORD\n";
Expand All @@ -128,6 +128,7 @@ sub setup_for_vnc_console ($vnc_console) {
return undef unless my $ws_url = $vnc_console->vmware_vnc_over_ws_url // deduce_url_from_vars($vnc_console);
my $self = $vnc_console->{_vmware_handler} //= consoles::VMWare->new;
log::diag 'Establishing VNC connection over WebSockets via ' . Mojo::URL->new($ws_url)->to_string;
$vnc_console->original_hostname($vnc_console->hostname) unless $vnc_console->original_hostname;
$vnc_console->hostname('127.0.0.1');
$vnc_console->description('VNC over WebSockets server provided by VMWare');
$self->configure_from_url($ws_url);
Expand Down
2 changes: 1 addition & 1 deletion consoles/VNC.pm
Expand Up @@ -18,7 +18,7 @@ has [qw(description hostname port username password socket name width height dep
no_endian_conversion _pixinfo _colourmap _framebuffer _rfb_version screen_on
_bpp _true_colour _do_endian_conversion absolute ikvm keymap _last_update_received
_last_update_requested check_vnc_stalls _vnc_stalled vncinfo old_ikvm dell
vmware_vnc_over_ws_url)];
vmware_vnc_over_ws_url original_hostname)];

our $VERSION = '0.40';

Expand Down
19 changes: 13 additions & 6 deletions t/27-consoles-vmware.t
Expand Up @@ -46,18 +46,22 @@ subtest 'test configuration with fake URL' => sub {
is consoles::VMWare::setup_for_vnc_console($fake_vnc), undef, 'noop if URL not set';

$fake_vnc->set_always(vmware_vnc_over_ws_url => 'https://root:secret%23@foo.bar');
$fake_vnc->set_always(hostname => 'original-hostname');
$fake_vnc->set_always(original_hostname => undef);
$fake_vnc->set_always(port => 12345);
$fake_vnc->set_true(qw(hostname description));
$fake_vnc->set_true(qw(description));
$fake_vnc->clear;

my $vmware;
combined_like { $vmware = consoles::VMWare::setup_for_vnc_console($fake_vnc) }
qr{Establishing VNC connection over WebSockets via https://foo\.bar}, 'log message present without secrets';
ok $vmware, 'VMWare "console" returned if URL is set' or return undef;
$fake_vnc->called_pos_ok(2, 'hostname', 'hostname assigned');
$fake_vnc->called_args_pos_is(2, 2, '127.0.0.1', 'hostname set to localhost');
$fake_vnc->called_pos_ok(3, 'description', 'description assigned');
$fake_vnc->called_args_pos_is(3, 2, 'VNC over WebSockets server provided by VMWare', 'description set accordingly');
$fake_vnc->called_pos_ok(4, 'original_hostname', 'hostname saved as original hostname');
$fake_vnc->called_args_pos_is(4, 2, 'original-hostname', 'original hostname set to hostname');
$fake_vnc->called_pos_ok(5, 'hostname', 'hostname assigned');
$fake_vnc->called_args_pos_is(5, 2, '127.0.0.1', 'hostname set to localhost');
$fake_vnc->called_pos_ok(6, 'description', 'description assigned');
$fake_vnc->called_args_pos_is(6, 2, 'VNC over WebSockets server provided by VMWare', 'description set accordingly');
is_deeply \@dewebsockify_args, [12345, 'wss://foo', 'session'], 'dewebsockify called with expected args'
or diag explain \@dewebsockify_args;
is $vmware->host, 'foo.bar', 'hostname set';
Expand Down Expand Up @@ -105,7 +109,7 @@ subtest 'deducing VNC over WebSockets URL from vars' => sub {
is consoles::VMWare::deduce_url_from_vars($vnc_console), undef, 'no URL if VMWARE_VNC_OVER_WS not set';

$bmwqemu::vars{VMWARE_VNC_OVER_WS} = 1;
$vnc_console->set_always(hostname => 'foo');
$vnc_console->set_always(original_hostname => undef)->set_always(hostname => 'foo');
is consoles::VMWare::deduce_url_from_vars($vnc_console), undef, 'no URL if VIRSH_GUEST not matching';

$vnc_console->set_always(hostname => $bmwqemu::vars{VIRSH_GUEST} = 'virsh-guest-host');
Expand All @@ -117,6 +121,9 @@ subtest 'deducing VNC over WebSockets URL from vars' => sub {
$bmwqemu::vars{VMWARE_USERNAME} = 'foo';
$bmwqemu::vars{VMWARE_PASSWORD} = 'bar';
is consoles::VMWare::deduce_url_from_vars($vnc_console), 'https://foo:bar@the-host', 'URL deduced from vars';

$vnc_console->set_always(original_hostname => $bmwqemu::vars{VIRSH_GUEST})->set_always(hostname => '127.0.0.1');
is consoles::VMWare::deduce_url_from_vars($vnc_console), 'https://foo:bar@the-host', 'original hostname used to check if VIRSH_GUEST matching';
};

subtest 'turning WebSocket into normal socket via dewebsockify' => sub {
Expand Down

0 comments on commit 33e2b56

Please sign in to comment.