Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package os-autoinst for openSUSE:Factory checked in at 2026-11-03 17:55:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/os-autoinst (Old) and /work/SRC/openSUSE:Factory/.os-autoinst.new.1257 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "os-autoinst" Tue Nov 3 17:55:00 2026 rev:635 rq:1394537 version:5.1793633037.0524715 Changes: -------- --- /work/SRC/openSUSE:Factory/os-autoinst/os-autoinst.changes 2026-10-23 20:29:48.200368234 +0200 +++ /work/SRC/openSUSE:Factory/.os-autoinst.new.1257/os-autoinst.changes 2026-11-03 17:57:30.022174841 +0100 @@ -1,0 +2,9 @@ +Mon Nov 02 15:24:10 UTC 2026 - [email protected] + +- Update to version 5.1793633037.0524715: + * feat: Configurable SSH port for remote SSH consoles + * fix(consoles): Fix localXvnc in containers + * build: Add prepare-dev-environment top-level target + * fix(svirt): Fix xz detection in the VMware datastore copy script + +------------------------------------------------------------------- Old: ---- os-autoinst-5.1792683987.d65739f.obscpio New: ---- os-autoinst-5.1793633037.0524715.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ os-autoinst-devel-test.spec ++++++ --- /var/tmp/diff_new_pack.sijhEY/_old 2026-11-03 17:57:35.400399736 +0100 +++ /var/tmp/diff_new_pack.sijhEY/_new 2026-11-03 17:57:35.402399820 +0100 @@ -18,7 +18,7 @@ %define short_name os-autoinst-devel Name: %{short_name}-test -Version: 5.1792683987.d65739f +Version: 5.1793633037.0524715 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ os-autoinst-openvswitch-test.spec ++++++ --- /var/tmp/diff_new_pack.sijhEY/_old 2026-11-03 17:57:35.441401450 +0100 +++ /var/tmp/diff_new_pack.sijhEY/_new 2026-11-03 17:57:35.443401534 +0100 @@ -19,7 +19,7 @@ %define name_ext -test %define short_name os-autoinst-openvswitch Name: %{short_name}%{?name_ext} -Version: 5.1792683987.d65739f +Version: 5.1793633037.0524715 Release: 0 Summary: test package for %{short_name} License: GPL-2.0-or-later ++++++ os-autoinst-test.spec ++++++ --- /var/tmp/diff_new_pack.sijhEY/_old 2026-11-03 17:57:35.489403458 +0100 +++ /var/tmp/diff_new_pack.sijhEY/_new 2026-11-03 17:57:35.491403541 +0100 @@ -19,7 +19,7 @@ %define name_ext -test %define short_name os-autoinst Name: %{short_name}%{?name_ext} -Version: 5.1792683987.d65739f +Version: 5.1793633037.0524715 Release: 0 Summary: test package for os-autoinst License: GPL-2.0-or-later ++++++ os-autoinst.spec ++++++ --- /var/tmp/diff_new_pack.sijhEY/_old 2026-11-03 17:57:35.547405883 +0100 +++ /var/tmp/diff_new_pack.sijhEY/_new 2026-11-03 17:57:35.554406176 +0100 @@ -17,7 +17,7 @@ Name: os-autoinst -Version: 5.1792683987.d65739f +Version: 5.1793633037.0524715 Release: 0 Summary: OS-level test automation License: GPL-2.0-or-later ++++++ os-autoinst-5.1792683987.d65739f.obscpio -> os-autoinst-5.1793633037.0524715.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/CMakeLists.txt new/os-autoinst-5.1793633037.0524715/CMakeLists.txt --- old/os-autoinst-5.1792683987.d65739f/CMakeLists.txt 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/CMakeLists.txt 2026-11-02 16:23:57.000000000 +0100 @@ -149,6 +149,11 @@ endforeach () endif () add_custom_target( + setup-fonts + COMMENT "Ensuring X11/Fontconfig fonts required by localXvnc (icewm, xterm) are available in container builds" + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-fonts" +) +add_custom_target( symlinks COMMENT "Symlinking created executables into source directory" COMMAND mkdir -p "${CMAKE_CURRENT_SOURCE_DIR}/ppmclibs/blib/arch/auto/tinycv" @@ -158,6 +163,11 @@ ${OUT_OF_SOURCE_TREE_BUILD_COMMANDS} ) add_dependencies(symlinks videoencoder snd2png debugviewer tinycv) +add_custom_target( + prepare-dev-environment + COMMENT "Preparing development environment (symlinks and container fonts)" +) +add_dependencies(prepare-dev-environment symlinks setup-fonts) # create installable versions of isotovideo and cv.pm set(OS_AUTOINST_VERSION "" CACHE STRING "os-autoinst version to set for the installation") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/Makefile new/os-autoinst-5.1793633037.0524715/Makefile --- old/os-autoinst-5.1792683987.d65739f/Makefile 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/Makefile 2026-11-02 16:23:57.000000000 +0100 @@ -3,8 +3,8 @@ build := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))build .PHONY: all -all: build/build.ninja ## Build all and create symlinks - ninja -C ${build} symlinks +all: build/build.ninja ## Build all and prepare development environment + ninja -C ${build} prepare-dev-environment .PHONY: help help: build/build.ninja ## Display this help diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/VMWare.pm new/os-autoinst-5.1793633037.0524715/consoles/VMWare.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/VMWare.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/VMWare.pm 2026-11-02 16:23:57.000000000 +0100 @@ -405,7 +405,7 @@ if _verified "\$dest"; then echo "VMware image \$dest ready" else - if [ "\\\${input_file##*.}" = "xz" ]; then + if [ "\${input_file##*.}" = "xz" ]; then if ! _verified "\$dest_xz"; then $copy_xz fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/icewm.cfg new/os-autoinst-5.1793633037.0524715/consoles/icewm.cfg --- old/os-autoinst-5.1792683987.d65739f/consoles/icewm.cfg 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/icewm.cfg 2026-11-02 16:23:57.000000000 +0100 @@ -1,5 +1,18 @@ # IceWM configuration file for use in openQA +# Default fonts +TitleFontName="fixed" +MenuFontName="fixed" +StatusFontName="fixed" +QuickSwitchFontName="fixed" +NormalFontName="fixed" +ActiveButtonFontName="fixed" +NormalButtonFontName="fixed" +ToolButtonFontName="fixed" +NormalWorkspaceFontName="fixed" +ActiveWorkspaceFontName="fixed" +ToolTipFontName="fixed" + # Hide taskbar ShowTaskBar=0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/localXvnc.pm new/os-autoinst-5.1793633037.0524715/consoles/localXvnc.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/localXvnc.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/localXvnc.pm 2026-11-02 16:23:57.000000000 +0100 @@ -5,6 +5,7 @@ package consoles::localXvnc; use Mojo::Base 'consoles::vnc_base', -signatures; +use Mojo::File 'path'; use autodie ':all'; use IPC::Run (); require IPC::System::Simple; @@ -19,10 +20,11 @@ # ssh disconnect and console switching. Ssh console may not display returned result of # long-time run test without these options. TCPKeepAlive ensures that if network goes down # or the remote host dies, machines will be properly noticed -sub sshCommand ($self, $username, $host, $gui = undef) { +sub sshCommand ($self, $username, $host, $port = undef, $gui = undef) { my $server_alive_count_max = $bmwqemu::vars{_SSH_SERVER_ALIVE_COUNT_MAX} // 480; my $server_alive_interval = $bmwqemu::vars{_SSH_SERVER_ALIVE_INTERVAL} // ONE_MINUTE; - my $sshopts = "-o TCPKeepAlive=yes -o ServerAliveCountMax=$server_alive_count_max -o ServerAliveInterval=$server_alive_interval -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAuthentication=no $username\@$host"; + my $port_opt = ($port && $port != 22) ? "-p $port " : ''; + my $sshopts = "-o TCPKeepAlive=yes -o ServerAliveCountMax=$server_alive_count_max -o ServerAliveInterval=$server_alive_interval -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAuthentication=no ${port_opt}$username\@$host"; $sshopts = "-X $sshopts" if $gui; return "ssh $sshopts; read"; } @@ -62,10 +64,13 @@ system "DISPLAY=$display $xdotool windowmove $window_id 0 0"; } -# uncoverable statement count:1 -# uncoverable statement count:2 -# uncoverable statement count:3 -# uncoverable statement count:4 +sub _ensure_font_dir ($dir = '/usr/share/fonts/misc') { + return unless -d $dir && -w $dir; + my $fonts_dir = "$dir/fonts.dir"; + return if (-s $fonts_dir // 0) > 2; + path($fonts_dir)->spew("3\n6x13.pcf.gz fixed\n6x13.pcf.gz -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1\neurlatgr.pcf.gz eurlatgr\n"); +} + sub start_xvnc ($s, $display) { listen $s, 1; # uncoverable statement my $peer; # uncoverable statement @@ -74,7 +79,9 @@ open STDIN, '<&', $peer; # uncoverable statement open STDOUT, '>&', $peer; # uncoverable statement close $peer; # uncoverable statement - exec "Xvnc -depth 16 -inetd -SecurityTypes None -ac $display"; # uncoverable statement + _ensure_font_dir(); # uncoverable statement + my $fp = -d '/usr/share/fonts/misc' ? ' -fp /usr/share/fonts/misc' : ''; # uncoverable statement + exec "Xvnc -depth 16 -inetd -SecurityTypes None -ac$fp $display"; # uncoverable statement } sub activate ($self) { @@ -103,7 +110,7 @@ sleep 1; # we need a window manager for fullscreen apps to work - system qq{DISPLAY=$display icewm -c $bmwqemu::topdir/consoles/icewm.cfg & echo "icewm PID is \$!"}; + system qq{DISPLAY=$display icewm --replace -c $bmwqemu::topdir/consoles/icewm.cfg & echo "icewm PID is \$!"}; return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/network_console.pm new/os-autoinst-5.1793633037.0524715/consoles/network_console.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/network_console.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/network_console.pm 2026-11-02 16:23:57.000000000 +0100 @@ -23,4 +23,6 @@ # to be overwritten sub connect_remote ($self, $args) { } +sub ssh_port ($self, $args) { $args->{port} // $bmwqemu::vars{SUT_SSH_PORT} // 22 } + 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/sshIucvconn.pm new/os-autoinst-5.1793633037.0524715/consoles/sshIucvconn.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/sshIucvconn.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/sshIucvconn.pm 2026-11-02 16:23:57.000000000 +0100 @@ -12,11 +12,12 @@ sub connect_remote ($self, $args) { my $hostname = $args->{hostname}; + my $port = $self->ssh_port($args); my $zvmguest = $bmwqemu::vars{ZVM_GUEST}; ($zvmguest) = $zvmguest =~ /(.*?)\..*$/; # ssh connection to SUT for agetty - my $ttyconn = $self->backend->new_ssh_connection(hostname => $hostname, password => $args->{password}, username => 'root'); + my $ttyconn = $self->backend->new_ssh_connection(hostname => $hostname, password => $args->{password}, username => 'root', port => $port); # start agetty to ensure that iucvconn is not killed my $chan = $ttyconn->channel() || $ttyconn->die_with_error(); @@ -31,7 +32,7 @@ $self->{ttyconn} = $ttyconn; # ssh connection to SUT for iucvconn - my ($ssh, $serialchan) = $self->backend->start_ssh_serial(hostname => $args->{hostname}, password => $args->{password}, username => 'root'); + my ($ssh, $serialchan) = $self->backend->start_ssh_serial(hostname => $hostname, password => $args->{password}, username => 'root', port => $port); # start iucvconn diag("ssh iucvconn: grabbing serial console for guest: $zvmguest"); $ssh->blocking(1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/sshVirtsh.pm new/os-autoinst-5.1793633037.0524715/consoles/sshVirtsh.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/sshVirtsh.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/sshVirtsh.pm 2026-11-02 16:23:57.000000000 +0100 @@ -23,6 +23,9 @@ has [qw(instance name vmm_family vmm_type vmm_firmware)]; +# the hypervisor SSH target is not the SUT, so the SUT_SSH_PORT fallback must not apply +sub ssh_port ($self, $args) { $args->{port} // 22 } + sub new ($class, $testapi_console = undef, $args = {}) { my $self = $class->SUPER::new($testapi_console, $args); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/sshX3270.pm new/os-autoinst-5.1793633037.0524715/consoles/sshX3270.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/sshX3270.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/sshX3270.pm 2026-11-02 16:23:57.000000000 +0100 @@ -7,7 +7,7 @@ use Mojo::Base 'consoles::localXvnc', -signatures; sub activate ($self) { - my $sshcommand = $self->sshCommand('root', $bmwqemu::vars{PARMFILE}->{Hostname}); + my $sshcommand = $self->sshCommand('root', $bmwqemu::vars{PARMFILE}->{Hostname}, $self->ssh_port($self->{args})); my $display = $self->{backend}->{consoles}->{worker}->{DISPLAY}; my $sshpassword = $testapi::password; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/consoles/sshXtermVt.pm new/os-autoinst-5.1793633037.0524715/consoles/sshXtermVt.pm --- old/os-autoinst-5.1792683987.d65739f/consoles/sshXtermVt.pm 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/consoles/sshXtermVt.pm 2026-11-02 16:23:57.000000000 +0100 @@ -20,11 +20,12 @@ my $hostname = $ssh_args->{hostname} || die 'we need a hostname to ssh to'; my $password = $ssh_args->{password} || $testapi::password; my $username = $ssh_args->{username} || 'root'; - my $sshcommand = $self->sshCommand($username, $hostname, $gui); + my $port = $self->ssh_port($ssh_args); + my $sshcommand = $self->sshCommand($username, $hostname, $port, $gui); my $serial = $self->{args}->{serial}; # Wait that ssh server on SUT is live on network - if (!$self->wait_for_ssh_port($hostname, timeout => ($bmwqemu::vars{SSH_XTERM_WAIT_SUT_ALIVE_TIMEOUT} // 120))) { + if (!$self->wait_for_ssh_port($hostname, timeout => ($bmwqemu::vars{SSH_XTERM_WAIT_SUT_ALIVE_TIMEOUT} // 120), port => $port)) { bmwqemu::diag("$hostname does not seems to have an active SSH server. Continuing anyway."); } $self->callxterm($sshcommand, "ssh:$testapi_console"); @@ -35,7 +36,8 @@ my ($ssh, $serialchan) = $self->backend->start_ssh_serial( hostname => $hostname, password => $password, - username => 'root' + username => 'root', + port => $port, ); # start iucvconn diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/container/os-autoinst_dev/Dockerfile new/os-autoinst-5.1793633037.0524715/container/os-autoinst_dev/Dockerfile --- old/os-autoinst-5.1792683987.d65739f/container/os-autoinst_dev/Dockerfile 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/container/os-autoinst_dev/Dockerfile 2026-11-02 16:23:57.000000000 +0100 @@ -29,6 +29,7 @@ aspell-spell \ cmake \ cpio \ + dejavu-fonts \ diffutils \ ffmpeg \ file \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/dependencies.yaml new/os-autoinst-5.1793633037.0524715/dependencies.yaml --- old/os-autoinst-5.1792683987.d65739f/dependencies.yaml 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/dependencies.yaml 2026-11-02 16:23:57.000000000 +0100 @@ -112,6 +112,7 @@ sudo: which: diffutils: + dejavu-fonts: spellcheck_requires: aspell-spell: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/doc/backend_vars.md new/os-autoinst-5.1793633037.0524715/doc/backend_vars.md --- old/os-autoinst-5.1792683987.d65739f/doc/backend_vars.md 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/doc/backend_vars.md 2026-11-02 16:23:57.000000000 +0100 @@ -29,6 +29,7 @@ | SSH_COMMAND_TIMEOUT_S | integer | 300 | Timeout in seconds for any SSH based command in SSH based consoles, disabled for a value of 0. It can be overriden by particular run_ssh_cmd() calls. Check out the documentation of this function for details. | | SSH_CONNECT_RETRY | integer | 5 | Maximum retries to connect to SSH based console targets | | SSH_CONNECT_RETRY_INTERVAL | float | 10 | Interval in seconds between retries to connect to SSH based console targets. Related to SSH_CONNECT_RETRY | +| SUT_SSH_PORT | integer | 22 | SSH port used by the SUT SSH consoles (`sshXtermVt`, `sshIucvconn`). Set to a forwarded high port (e.g. 10022) when reaching the SUT through a local SSH tunnel. Does not affect hypervisor SSH (e.g. `sshVirtsh`). | | VNC_STALL_THRESHOLD | integer | 4 | Time after which is VNC considered stalled | | VNC_TYPING_LIMIT | integer | 30 | Maximum number of keys per second | | VNC_CONNECT_TIMEOUT_LOCAL | integer | 10 | Timeout for local VNC connections in seconds | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/t/27-consoles-local_xvnc.t new/os-autoinst-5.1793633037.0524715/t/27-consoles-local_xvnc.t --- old/os-autoinst-5.1792683987.d65739f/t/27-consoles-local_xvnc.t 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/t/27-consoles-local_xvnc.t 2026-11-02 16:23:57.000000000 +0100 @@ -9,7 +9,7 @@ use Test::MockObject; use Test::MockModule; use Test::Output qw(stderr_like); -use Mojo::File qw(tempdir); +use Mojo::File qw(tempdir path); use Mojo::Util qw(scope_guard); use POSIX qw(_exit); use Socket; @@ -33,6 +33,20 @@ my $c = consoles::localXvnc->new('sut', {}); like $c->sshCommand('user', 'localhost'), qr/^ssh/, 'can call sshCommand'; +subtest 'sshCommand port handling' => sub { + my @cases = ( + {desc => 'no port given', args => [], like => qr/ssh .*user\@localhost; read$/, unlike => qr/-p /}, + {desc => 'default port 22 omits -p', args => [22], like => qr/ssh .*user\@localhost; read$/, unlike => qr/-p /}, + {desc => 'custom port adds -p before destination', args => [10022], like => qr/ssh .*-p 10022 user\@localhost; read$/}, + {desc => 'custom port combined with gui forwarding', args => [10022, 1], like => qr/^ssh -X .*-p 10022 user\@localhost; read$/}, + ); + for my $case (@cases) { + my ($port, $gui) = @{$case->{args}}; + my $cmd = $c->sshCommand('user', 'localhost', $port, $gui); + like $cmd, $case->{like}, "sshCommand: $case->{desc}"; + unlike $cmd, $case->{unlike}, "sshCommand: $case->{desc} (negative)" if $case->{unlike}; + } +}; my $socket_mock = Test::MockModule->new('Socket'); my $vnc_base_mock = Test::MockModule->new('consoles::vnc_base'); my $vnc_mock = Test::MockObject->new->set_true('check_vnc_stalls'); @@ -51,4 +65,25 @@ is $c->fullscreen({window_name => 'foo'}), 1, 'can call fullscreen'; is $c->disable, undef, 'can call disable'; +subtest '_ensure_font_dir populates a writable, unindexed font dir' => sub { + my $fontdir = tempdir '/tmp/fontdir-XXXX'; + consoles::localXvnc::_ensure_font_dir($fontdir); + is path("$fontdir/fonts.dir")->slurp, + "3\n6x13.pcf.gz fixed\n6x13.pcf.gz -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1\neurlatgr.pcf.gz eurlatgr\n", + 'fonts.dir written verbatim'; +}; + +subtest '_ensure_font_dir skips a missing dir' => sub { + my $missing = "$dir/no-such-font-dir"; + consoles::localXvnc::_ensure_font_dir($missing); + ok !-e "$missing/fonts.dir", 'nothing written for a missing dir'; +}; + +subtest '_ensure_font_dir leaves a populated fonts.dir untouched' => sub { + my $fontdir = tempdir '/tmp/fontdir-XXXX'; + path("$fontdir/fonts.dir")->spew("already indexed content\n"); + consoles::localXvnc::_ensure_font_dir($fontdir); + is path("$fontdir/fonts.dir")->slurp, "already indexed content\n", 'existing fonts.dir preserved'; +}; + done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshIucvconn.t new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshIucvconn.t --- old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshIucvconn.t 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshIucvconn.t 2026-11-02 16:23:57.000000000 +0100 @@ -19,15 +19,18 @@ my $exec_flag = 1; $bmwqemu::vars{ZVM_GUEST} = 'guest.what'; +my (@ssh_conn_args, @serial_args); my $backend_mock = Test::MockObject->new(); -$backend_mock->mock('new_ssh_connection', sub($self, %args) { +$backend_mock->mock('new_ssh_connection', sub ($self, %args) { + push @ssh_conn_args, \%args; my $ttyconn_mock = Test::MockObject->new; $ttyconn_mock->mock('channel', sub { return Test::MockObject->new->set_true('blocking', 'pty')->set_always(exec => $exec_flag); }); return $ttyconn_mock->set_false('error'); }); -$backend_mock->mock('start_ssh_serial', sub($self, %args) { +$backend_mock->mock('start_ssh_serial', sub ($self, %args) { + push @serial_args, \%args; my $ssh_mock = Test::MockObject->new; $ssh_mock->set_true('blocking')->set_always(error => 'unknown SSH error'); my $serialchan_mock = Test::MockObject->new; @@ -46,6 +49,23 @@ ok $c->kill_ssh(), 'kill_ssh executed successfully'; }; +subtest 'connect_remote uses configured SUT port for all SSH connections' => sub { + my @cases = ( + {desc => 'custom port from console args', args => {%$args, port => 10022}, port => 10022}, + {desc => 'port defaults to 22 without SUT_SSH_PORT', args => {%$args}, port => 22}, + {desc => 'SUT_SSH_PORT used when no port arg', args => {%$args}, vars => 10022, port => 10022}, + {desc => 'args port wins over SUT_SSH_PORT', args => {%$args, port => 2222}, vars => 10022, port => 2222}, + ); + for my $case (@cases) { + @ssh_conn_args = @serial_args = (); + local $bmwqemu::vars{SUT_SSH_PORT} = $case->{vars}; + my $c = consoles::sshIucvconn->new($testapi_console, $case->{args}); + stderr_like { $c->connect_remote($case->{args}) } qr/serial console for guest/, "connect_remote: $case->{desc}"; + is $ssh_conn_args[0]{port}, $case->{port}, "agetty SSH connection: $case->{desc}"; + is $serial_args[0]{port}, $case->{port}, "iucvconn SSH connection: $case->{desc}"; + } +}; + subtest 'connect_remote test warning output' => sub { $exec_flag = 0; my $c = consoles::sshIucvconn->new($testapi_console, $args); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshVirtsh.t new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshVirtsh.t --- old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshVirtsh.t 1970-01-01 01:00:00.000000000 +0100 +++ new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshVirtsh.t 2026-11-02 16:23:57.000000000 +0100 @@ -0,0 +1,22 @@ +#!/usr/bin/perl + +# Copyright SUSE LLC +# SPDX-License-Identifier: GPL-2.0-or-later + +use Test::Most; +use Mojo::Base -signatures; +use Test::Warnings qw(:all :report_warnings); +use FindBin '$Bin'; +use lib "$Bin/../external/os-autoinst-common/lib"; +use OpenQA::Test::TimeLimit '5'; +use consoles::sshVirtsh; + +my $c = consoles::sshVirtsh->new('sut', {}); +is $c->ssh_port({}), 22, 'hypervisor SSH port defaults to 22'; +{ + local $bmwqemu::vars{SUT_SSH_PORT} = 10022; + is $c->ssh_port({}), 22, 'hypervisor SSH port ignores SUT_SSH_PORT'; + is $c->ssh_port({port => 2222}), 2222, 'explicit hypervisor port from args wins'; +} + +done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshX3270.t new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshX3270.t --- old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshX3270.t 1970-01-01 01:00:00.000000000 +0100 +++ new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshX3270.t 2026-11-02 16:23:57.000000000 +0100 @@ -0,0 +1,83 @@ +#!/usr/bin/perl + +# Copyright SUSE LLC +# SPDX-License-Identifier: GPL-2.0-or-later + +use Mojo::Base -signatures; +use Test::Most; +use Test::Mock::Time; +use Test::MockModule; +use Test::MockObject; +use Test::Output qw(stdout_from); +use Test::Warnings qw(:all :report_warnings); +use FindBin '$Bin'; +use lib "$Bin/../external/os-autoinst-common/lib"; +use OpenQA::Test::TimeLimit '5'; +use bmwqemu; +use consoles::sshX3270; +use testapi; + +subtest 'ssh_port resolution from console args and SUT_SSH_PORT' => sub { + my $c = consoles::sshX3270->new('sut', {}); + is $c->ssh_port({}), 22, 'ssh_port defaults to 22 when neither args nor SUT_SSH_PORT set'; + local $bmwqemu::vars{SUT_SSH_PORT} = 10022; + is $c->ssh_port({}), 10022, 'ssh_port falls back to SUT_SSH_PORT'; + is $c->ssh_port({port => 2222}), 2222, 'explicit port in console args overrides SUT_SSH_PORT'; +}; + +subtest 'activate connects via s3270 and supplies credentials after prompt' => sub { + local $bmwqemu::vars{PARMFILE} = {Hostname => 'testhost'}; + local $testapi::password = 'secret'; + + my @sent; + my $attempts = 0; + my $s3270_mock = Test::MockObject->new; + $s3270_mock->mock(send_3270 => sub ($self, $cmd = '', %args) { + push @sent, $cmd; + if ($cmd eq 'Snap(Ascii)') { + $attempts++; + return {command_output => ['Connecting to testhost...']} if $attempts == 1; + return {command_output => ['Password: ']}; + } + return {command_status => 'ok'}; + }); + + my $sshx3270_mock = Test::MockModule->new('consoles::sshX3270', no_strict => 1); + $sshx3270_mock->mock(new_3270_console => sub ($self, $args) { return {console => $s3270_mock} }); + + my $c = consoles::sshX3270->new('sut', {port => 10022}); + $c->{backend} = {consoles => {worker => {DISPLAY => ':1'}}}; + + my $output = stdout_from { $c->activate }; + like $output, qr/Connecting to testhost/, 'activate logs command output during password prompt search'; + like $sent[0], qr/Connect\("-e TERM=vt100 ssh .*-p 10022 root\@testhost; read"\)/, 's3270 connect command contains configured port and target'; + is $sent[1], 'Snap', 'snap requested before polling screen content'; + is $sent[2], 'Snap(Ascii)', 'ascii snap queried for initial password prompt check'; + is $sent[3], 'Snap', 'snap requested before second poll'; + is $sent[4], 'Snap(Ascii)', 'ascii snap queried for second password prompt check'; + is $sent[5], 'String("secret")', 'password string sent to terminal after prompt detected'; + is $sent[6], 'ENTER', 'enter key sent after password'; +}; + +subtest 'activate dies when password prompt is not seen within timeout' => sub { + local $bmwqemu::vars{PARMFILE} = {Hostname => 'testhost'}; + local $testapi::password = 'secret'; + + my $s3270_mock = Test::MockObject->new; + $s3270_mock->mock(send_3270 => sub ($self, $cmd = '', %args) { + return {command_output => ['Connecting...']} if $cmd eq 'Snap(Ascii)'; + return {command_status => 'ok'}; + }); + + my $sshx3270_mock = Test::MockModule->new('consoles::sshX3270', no_strict => 1); + $sshx3270_mock->mock(new_3270_console => sub ($self, $args) { return {console => $s3270_mock} }); + + my $c = consoles::sshX3270->new('sut', {}); + $c->{backend} = {consoles => {worker => {DISPLAY => ':1'}}}; + + throws_ok { + stdout_from { $c->activate }; + } qr/ssh password prompt timeout/, 'activate aborts with timeout when password prompt never appears'; +}; + +done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshXtermVt.t new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshXtermVt.t --- old/os-autoinst-5.1792683987.d65739f/t/27-consoles-sshXtermVt.t 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/t/27-consoles-sshXtermVt.t 2026-11-02 16:23:57.000000000 +0100 @@ -47,4 +47,23 @@ like $captured_output, qr/Wait for SSH on host testhost/, 'Captured expected debug log'; ok $c->kill_ssh(), 'kill_ssh executed successfully'; +subtest 'activate resolves SSH port from args and SUT_SSH_PORT' => sub { + my $sshxterm_mock = Test::MockModule->new('consoles::sshXtermVt'); + my (@ssh_command_args, @wait_args); + $sshxterm_mock->redefine(sshCommand => sub ($self, @args) { @ssh_command_args = @args; 'ssh-cmd' }); + $sshxterm_mock->redefine(wait_for_ssh_port => sub ($self, @args) { @wait_args = @args; 1 }); + my @cases = ( + {desc => 'SUT_SSH_PORT used when no args port', args => {hostname => 'testhost'}, port => 10022}, + {desc => 'args port wins over SUT_SSH_PORT', args => {hostname => 'testhost', port => 2222}, port => 2222}, + ); + for my $case (@cases) { + local $bmwqemu::vars{SUT_SSH_PORT} = 10022; + @ssh_command_args = @wait_args = (); + stderr_from { consoles::sshXtermVt->new('sut', $case->{args})->activate }; + my %wait_opts = @wait_args[1 .. $#wait_args]; + is $ssh_command_args[2], $case->{port}, "SSH command: $case->{desc}"; + is $wait_opts{port}, $case->{port}, "SSH readiness check: $case->{desc}"; + } +}; + done_testing(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/t/27-consoles-vmware.t new/os-autoinst-5.1793633037.0524715/t/27-consoles-vmware.t --- old/os-autoinst-5.1792683987.d65739f/t/27-consoles-vmware.t 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/t/27-consoles-vmware.t 2026-11-02 16:23:57.000000000 +0100 @@ -329,6 +329,30 @@ ok $path_occurrences <= 3, 'path interpolation is minimized in favor of shell variables'; }; + subtest 'an xz-compressed image is decompressed before publishing' => sub { + my $xz_name = 'disk.vmdk.xz'; + my $payload = 'vmdk payload that xz-compresses well'; + my $raw = path($my_test_basedir, "$xz_name.raw"); + $raw->spew($payload); + my $xz_source = path($my_test_basedir, $nfs_ds, 'iso')->make_path->child($xz_name); + is system(qq{xz -c "$raw" > "$xz_source"}), 0, 'the compressed asset is created'; + my $xz_digest = Digest::SHA->new(256)->addfile($xz_source->to_string)->hexdigest; + my $dest_uncompressed = path("$vmware_openqa_datastore/disk.vmdk"); + my $dest_xz = path("$vmware_openqa_datastore/$xz_name"); + $dest_uncompressed->remove; + $dest_xz->remove; + $bmwqemu::vars{CHECKSUM_ISO} = uc $xz_digest; + $bmwqemu::vars{ISO} = "/var/lib/openqa/share/factory/iso/$xz_name"; + lives_ok { consoles::VMWare::provide_image_in_datastore($svirt, $xz_source, $vmware_openqa_datastore) } 'the xz image is provided'; + like $last_cmd, qr/"\$\{input_file##\*\.\}"/, 'the xz branch is chosen via unescaped shell parameter expansion'; + like $last_output, qr/Verified .* against its published checksum/, 'the compressed asset is verified'; + like $last_output, qr/Decompressed .* to /, 'the compressed asset is decompressed into place'; + is $dest_uncompressed->slurp, $payload, 'the published image is the decompressed payload, not the raw xz'; + ok -e $dest_xz, 'the compressed asset stays in the datastore'; + is_deeply $vmware_openqa_datastore->list->grep(qr/\.part$/)->to_array, [], 'no temporary file left behind'; + $bmwqemu::vars{ISO} = "/var/lib/openqa/share/factory/iso/$iso"; + }; + subtest 'mismatching checksum leaves the destination untouched' => sub { $dest->remove; $bmwqemu::vars{CHECKSUM_ISO} = 'b' x 64; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/tools/setup-fonts new/os-autoinst-5.1793633037.0524715/tools/setup-fonts --- old/os-autoinst-5.1792683987.d65739f/tools/setup-fonts 1970-01-01 01:00:00.000000000 +0100 +++ new/os-autoinst-5.1793633037.0524715/tools/setup-fonts 2026-11-02 16:23:57.000000000 +0100 @@ -0,0 +1,28 @@ +#!/bin/bash +# Setup required X11 and fontconfig fonts for localXvnc in container environments + +set -euo pipefail + +# Font root prefix, overridable via FONTS_ROOT (default /usr/share/fonts) +fonts_root="${FONTS_ROOT:-/usr/share/fonts}" +misc_dir="$fonts_root/misc" +fonts_dir="$misc_dir/fonts.dir" + +# Populate minimal fonts.dir if the misc dir is present, writable, and unindexed +if [[ -d "$misc_dir" && -w "$misc_dir" ]]; then + if [[ ! -s "$fonts_dir" || $(wc -c < "$fonts_dir") -le 2 ]]; then + cat << 'EOF' > "$fonts_dir" +3 +6x13.pcf.gz fixed +6x13.pcf.gz -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1 +eurlatgr.pcf.gz eurlatgr +EOF + fi +fi + +# Ensure basic sans font is installed for icewm in container environments +if command -v zypper > /dev/null 2>&1 && command -v fc-list > /dev/null 2>&1 && [[ -w "$fonts_root" ]]; then + if ! fc-list : family 2> /dev/null | grep -qi "sans"; then + zypper -n in --no-recommends dejavu-fonts 2> /dev/null || true + fi +fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1792683987.d65739f/xt/30-make.t new/os-autoinst-5.1793633037.0524715/xt/30-make.t --- old/os-autoinst-5.1792683987.d65739f/xt/30-make.t 2026-10-22 17:46:27.000000000 +0200 +++ new/os-autoinst-5.1793633037.0524715/xt/30-make.t 2026-11-02 16:23:57.000000000 +0100 @@ -22,11 +22,11 @@ chdir "$dir/os-autoinst" or die "Failed to change directory to $dir/os-autoinst"; my $cleanup = scope_guard sub { chdir $Bin; undef $dir }; is $?, 0, 'prepare working copy with git (exit code)'; -like qx{make -n}, qr/ninja.*symlinks/, 'build default'; +like qx{make -n}, qr/ninja.*prepare-dev-environment/, 'build default'; is $?, 0, 'build default (exit code)'; like qx{rm -rf build && make help}, qr/help: HELP/, 'call specific make target initially'; chdir '..' or die 'Failed to change directory to ..'; like qx{rm -rf os-autoinst/build && make -C os-autoinst help}, qr/help: HELP/, 'call make with target initially from outside'; like qx{make -C os-autoinst help}, qr/help: HELP/, 'call make again with target from outside'; -like qx{make -C os-autoinst -n}, qr/ninja.*symlinks/, 'call make from outside without arguments'; +like qx{make -C os-autoinst -n}, qr/ninja.*prepare-dev-environment/, 'call make from outside without arguments'; done_testing; ++++++ os-autoinst.obsinfo ++++++ --- /var/tmp/diff_new_pack.sijhEY/_old 2026-11-03 17:57:38.123513605 +0100 +++ /var/tmp/diff_new_pack.sijhEY/_new 2026-11-03 17:57:38.137514191 +0100 @@ -1,5 +1,5 @@ name: os-autoinst -version: 5.1792683987.d65739f -mtime: 1792683987 -commit: d65739f82b142e3ea7c26d7b873ec5b80361ca8c +version: 5.1793633037.0524715 +mtime: 1793633037 +commit: 0524715633bbafaa621225c14105f8ce5dfb0c77
