From 07543d2c37fb79118092e2931dcef8f730278691 Mon Sep 17 00:00:00 2001 From: Deborah Brouwer Date: Tue, 23 Jan 2024 14:39:56 -0800 Subject: [PATCH] Add service_port_delta config for livehandler Instead of hard-coding the service port delta for the livehandler, make the service port delta configurable while still defaulting to the expected value of 2. This allows cloud and/or containerized setups to access the web UI through a non-standard port while continuing to access the livehandler through a reverse proxy just by setting the service port delta to 0. Issue: https://progress.opensuse.org/issues/153499 --- assets/javascripts/openqa.js | 8 +------- assets/javascripts/running.js | 4 +++- assets/javascripts/ws_console.js | 2 +- etc/openqa/openqa.ini | 7 +++++++ lib/OpenQA/Setup.pm | 1 + lib/OpenQA/WebAPI/Controller/API/V1/Worker.pm | 5 ++++- lib/OpenQA/WebAPI/Controller/Developer.pm | 6 +++++- lib/OpenQA/WebAPI/Controller/Test.pm | 1 + lib/OpenQA/Worker/Job.pm | 2 +- lib/OpenQA/Worker/WebUIConnection.pm | 2 ++ t/24-worker-engine.t | 1 + t/24-worker-jobs.t | 1 + t/24-worker-overall.t | 1 + t/config.t | 3 +++ templates/webapi/developer/ws_console.html.ep | 2 +- templates/webapi/test/live.html.ep | 1 + 16 files changed, 34 insertions(+), 13 deletions(-) mode change 100644 => 100755 assets/javascripts/ws_console.js mode change 100644 => 100755 t/24-worker-engine.t mode change 100644 => 100755 t/24-worker-jobs.t mode change 100644 => 100755 t/24-worker-overall.t diff --git a/assets/javascripts/openqa.js b/assets/javascripts/openqa.js index 17a21cc68a2..a3a9f671d86 100644 --- a/assets/javascripts/openqa.js +++ b/assets/javascripts/openqa.js @@ -145,13 +145,7 @@ function makeWsUrlAbsolute(url, servicePortDelta) { // don't put a port in the URL if there's no explicit port port = ''; } else { - if (port !== 80 || port !== 443) { - // if not using default ports we assume we're not accessing the web UI via Apache/NGINX - // reverse proxy - // -> so if not specified otherwise, we're further assuming a connection to the livehandler - // daemon which is supposed to run under the + 2 - port += servicePortDelta ? servicePortDelta : 2; - } + if (port !== 80 || port !== 443) port += servicePortDelta; port = ':' + port; } diff --git a/assets/javascripts/running.js b/assets/javascripts/running.js index a98ef17ba9c..eb1ad482ac5 100644 --- a/assets/javascripts/running.js +++ b/assets/javascripts/running.js @@ -445,6 +445,7 @@ var developerMode = { // state of the page elements and the web socket connection to web UI develWsUrl: undefined, // URL for developer session web socket connection statusOnlyWsUrl: undefined, // URL for status-only web socket connection + servicePortDelta: undefined, // delta from web UI port on which to directly connect to livehandler wsConnection: undefined, // current WebSocket object hasWsError: false, // whether an web socket error occurred (cleared when we finally receive a message from os-autoinst) useDeveloperWsRoute: undefined, // whether the developer web socket route is used @@ -544,6 +545,7 @@ function setupDeveloperPanel() { // find URLs for web socket connections developerMode.develWsUrl = panel.data('developer-url'); developerMode.statusOnlyWsUrl = panel.data('status-only-url'); + developerMode.servicePortDelta = panel.data('service-port-delta'); // setup toggle for body var panelHeader = panel.find('.card-header'); @@ -973,7 +975,7 @@ function setupWebsocketConnection() { developerMode.useDeveloperWsRoute = false; url = developerMode.statusOnlyWsUrl; } - url = makeWsUrlAbsolute(url); + url = makeWsUrlAbsolute(url, developerMode.servicePortDelta); // establish ws connection console.log('Establishing ws connection to ' + url); diff --git a/assets/javascripts/ws_console.js b/assets/javascripts/ws_console.js old mode 100644 new mode 100755 index e5c44202800..ac860b3b310 --- a/assets/javascripts/ws_console.js +++ b/assets/javascripts/ws_console.js @@ -105,7 +105,7 @@ function setupWebSocketConsole() { if (!url.length) { return; } - url = makeWsUrlAbsolute(url); + url = makeWsUrlAbsolute(url, form.data('service-port-delta')); // establish and handle web socket connection window.wsUrl = url; diff --git a/etc/openqa/openqa.ini b/etc/openqa/openqa.ini index b030564d968..3d8dc3360a2 100644 --- a/etc/openqa/openqa.ini +++ b/etc/openqa/openqa.ini @@ -91,6 +91,13 @@ ## collapsing parallel children by default completely) #parallel_children_collapsable_results = passed softfailed +## For the developer mode panel: if not accessing the web UI via Apache/NGINX reverse +## proxy, then connect to the livehandler daemon at the + service_port_delta. +## The livehandler daemon is supposed to run under the + 2. +## If you want to keep using a reverse proxy while accessing the web UI through a custom port +## (e.g. 8080) then just set `service_port_delta = 0`. +# service_port_delta = 2 + #[scm git] # name of remote to get updates from before committing changes (e.g. origin, leave out-commented to disable remote update) #update_remote = origin diff --git a/lib/OpenQA/Setup.pm b/lib/OpenQA/Setup.pm index a82ba395ee8..6785b69afb5 100644 --- a/lib/OpenQA/Setup.pm +++ b/lib/OpenQA/Setup.pm @@ -52,6 +52,7 @@ sub read_config ($app) { auto_clone_limit => 20, force_result_regex => '', parallel_children_collapsable_results => join(' ', OK_RESULTS), + service_port_delta => 2, }, rate_limits => { search => 5, diff --git a/lib/OpenQA/WebAPI/Controller/API/V1/Worker.pm b/lib/OpenQA/WebAPI/Controller/API/V1/Worker.pm index 2785fdf2d86..cabc7edf7ff 100644 --- a/lib/OpenQA/WebAPI/Controller/API/V1/Worker.pm +++ b/lib/OpenQA/WebAPI/Controller/API/V1/Worker.pm @@ -202,7 +202,10 @@ sub create { my %event_data = (id => $id, host => $host, instance => $instance); $self->emit_event('openqa_worker_register', \%event_data); - $self->render(json => {id => $id}); + $self->render( + json => { + id => $id, + service_port_delta => $self->config->{global}->{service_port_delta}}); } =over 4 diff --git a/lib/OpenQA/WebAPI/Controller/Developer.pm b/lib/OpenQA/WebAPI/Controller/Developer.pm index e011ea1cc0c..4ff4b8fdf06 100644 --- a/lib/OpenQA/WebAPI/Controller/Developer.pm +++ b/lib/OpenQA/WebAPI/Controller/Developer.pm @@ -18,7 +18,11 @@ sub ws_console ($self) { my $ws_url = $self->determine_os_autoinst_web_socket_url($job); $ws_url = $ws_url ? determine_web_ui_web_socket_url($job->id) : undef if $use_proxy; - return $self->render(job => $job, ws_url => ($ws_url // ''), use_proxy => $use_proxy); + return $self->render( + job => $job, + ws_url => ($ws_url // ''), + use_proxy => $use_proxy, + service_port_delta => $self->config->{global}->{service_port_delta}); } 1; diff --git a/lib/OpenQA/WebAPI/Controller/Test.pm b/lib/OpenQA/WebAPI/Controller/Test.pm index 34c14959323..d95f7c586ce 100644 --- a/lib/OpenQA/WebAPI/Controller/Test.pm +++ b/lib/OpenQA/WebAPI/Controller/Test.pm @@ -374,6 +374,7 @@ sub live ($self) { developer_session => $job->developer_session, is_devel_mode_accessible => $current_user && $current_user->is_operator, current_user_id => $current_user ? $current_user->id : 'undefined', + service_port_delta => $self->config->{global}->{service_port_delta}, }); $self->render('test/live'); } diff --git a/lib/OpenQA/Worker/Job.pm b/lib/OpenQA/Worker/Job.pm index 453b6801890..c500b6bd90f 100644 --- a/lib/OpenQA/Worker/Job.pm +++ b/lib/OpenQA/Worker/Job.pm @@ -966,7 +966,7 @@ sub post_upload_progress_to_liveviewhandler { my $job_id = $self->id; $self->client->send( post => "/liveviewhandler/api/v1/jobs/$job_id/upload_progress", - service_port_delta => 2, # liveviewhandler is supposed to run on web UI port + 2 + service_port_delta => $self->client->service_port_delta, json => \%new_progress_info, non_critical => 1, callback => sub { diff --git a/lib/OpenQA/Worker/WebUIConnection.pm b/lib/OpenQA/Worker/WebUIConnection.pm index 137e14728b5..52fdf14c041 100644 --- a/lib/OpenQA/Worker/WebUIConnection.pm +++ b/lib/OpenQA/Worker/WebUIConnection.pm @@ -20,6 +20,7 @@ has 'worker_id'; # the ID the web UI uses to track this worker (populated on has 'testpool_server'; # testpool server for this web UI host has 'working_directory'; # share directory for this web UI host has 'cache_directory'; # cache directory for this web UI host +has 'service_port_delta'; # delta from web UI port on which to directly connect to livehandler # the websocket connection to receive commands from the web UI and send the status (Mojo::Transaction::WebSockets instance) has 'websocket_connection'; @@ -106,6 +107,7 @@ sub register ($self) { $self->_set_status($status => {error_message => $error_message}); return undef; } + $self->service_port_delta($json_res->{service_port_delta}); my $worker_id = $json_res->{id}; $self->worker_id($worker_id); if (!defined $worker_id) { diff --git a/t/24-worker-engine.t b/t/24-worker-engine.t old mode 100644 new mode 100755 index 53e23639566..d1586332459 --- a/t/24-worker-engine.t +++ b/t/24-worker-engine.t @@ -51,6 +51,7 @@ use OpenQA::Utils qw(testcasedir productdir needledir locate_asset base_host); use Mojo::Base -base; has worker_id => 1; has webui_host => 'localhost'; + has service_port_delta => 2; } $ENV{OPENQA_CONFIG} = "$FindBin::Bin/data/24-worker-overall"; diff --git a/t/24-worker-jobs.t b/t/24-worker-jobs.t old mode 100644 new mode 100755 index 86a3b39b2dc..624c4da110e --- a/t/24-worker-jobs.t +++ b/t/24-worker-jobs.t @@ -91,6 +91,7 @@ sub wait_until_uploading_logs_and_assets_concluded { package Test::FakeClient; use Mojo::Base -base; has worker_id => 1; + has service_port_delta => 2; has webui_host => 'not relevant here'; has working_directory => 'not relevant here'; has testpool_server => 'not relevant here'; diff --git a/t/24-worker-overall.t b/t/24-worker-overall.t old mode 100644 new mode 100755 index 587b9f44895..2ee4e90ae0b --- a/t/24-worker-overall.t +++ b/t/24-worker-overall.t @@ -40,6 +40,7 @@ $ENV{OPENQA_LOGFILE} = undef; use Mojo::Base -base; has webui_host => 'fake'; has worker_id => 42; + has service_port_delta => 2; has api_calls => sub { [] }; sub send { my ($self, $method, $path, %args) = @_; diff --git a/t/config.t b/t/config.t index 0cbbfd0ad9b..2f47e2f5e1d 100644 --- a/t/config.t +++ b/t/config.t @@ -180,6 +180,7 @@ subtest 'Test configuration default modes' => sub { # Test configuration generation with "test" mode $test_config->{_openid_secret} = $config->{_openid_secret}; $test_config->{logging}->{level} = "debug"; + $test_config->{global}->{service_port_delta} = 2; is ref delete $config->{global}->{auto_clone_regex}, 'Regexp', 'auto_clone_regex parsed as regex'; is_deeply $config, $test_config, '"test" configuration'; @@ -188,6 +189,7 @@ subtest 'Test configuration default modes' => sub { $app->mode("development"); $config = read_config($app, 'reading config from default with mode development'); $test_config->{_openid_secret} = $config->{_openid_secret}; + $test_config->{global}->{service_port_delta} = 2; delete $config->{global}->{auto_clone_regex}; is_deeply $config, $test_config, 'right "development" configuration'; @@ -197,6 +199,7 @@ subtest 'Test configuration default modes' => sub { $config = read_config($app, 'reading config from default with mode foo_bar'); $test_config->{_openid_secret} = $config->{_openid_secret}; $test_config->{auth}->{method} = "OpenID"; + $test_config->{global}->{service_port_delta} = 2; delete $config->{global}->{auto_clone_regex}; delete $test_config->{logging}; is_deeply $config, $test_config, 'right default configuration'; diff --git a/templates/webapi/developer/ws_console.html.ep b/templates/webapi/developer/ws_console.html.ep index 633ed704826..b05761673d9 100644 --- a/templates/webapi/developer/ws_console.html.ep +++ b/templates/webapi/developer/ws_console.html.ep @@ -10,7 +10,7 @@ %= include 'layouts/info'

WebSocket console for job <%= $job->name %>

-
+ % if ($ws_url) {

% if ($use_proxy) { diff --git a/templates/webapi/test/live.html.ep b/templates/webapi/test/live.html.ep index f19909599e8..da21f3ab4ab 100644 --- a/templates/webapi/test/live.html.ep +++ b/templates/webapi/test/live.html.ep @@ -3,6 +3,7 @@ id="developer-panel" data-developer-url="<%= $ws_developer_url %>" data-status-only-url="<%= $ws_status_only_url %>" + data-service-port-delta="<%= $service_port_delta %>" data-is-accessible="<%= ($is_devel_mode_accessible) ? ('true') : ('false') %>" data-own-user-id="<%= $current_user_id %>">