Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix re-connecting via VNC over WebSockets #2136

Merged
merged 1 commit into from Jul 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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