line |
stmt |
code |
1
|
|
# Copyright 2009-2013 Bernhard M. Wiedemann |
2
|
|
# Copyright 2012-2021 SUSE LLC |
3
|
|
# SPDX-License-Identifier: GPL-2.0-or-later |
4
|
|
|
5
|
|
|
6
|
|
use Mojo::Base 'consoles::vnc_base', -signatures; |
7
|
5
|
use autodie ':all'; |
|
5
|
|
|
5
|
|
8
|
5
|
use IPC::Run (); |
|
5
|
|
|
5
|
|
9
|
5
|
require IPC::System::Simple; |
|
5
|
|
|
5
|
|
10
|
|
use Socket; |
11
|
5
|
use File::Path 'mkpath'; |
|
5
|
|
|
5
|
|
12
|
5
|
use File::Which; |
|
5
|
|
|
5
|
|
13
|
5
|
use Time::Seconds; |
|
5
|
|
|
5
|
|
14
|
5
|
|
|
5
|
|
|
5
|
|
15
|
|
# helper function |
16
|
|
# Keep ssh session for the maximum of ServerAliveCountMax x ServerAliveInterval seconds |
17
|
|
# even without receiving any message back from the server, and this will not affect normal |
18
|
|
# ssh disconnect and console switching. Ssh console may not display returned result of |
19
|
|
# long-time run test without these options. TCPKeepAlive ensures that if network goes down |
20
|
|
# or the remote host dies, machines will be properly noticed |
21
|
|
my $server_alive_count_max = $bmwqemu::vars{_SSH_SERVER_ALIVE_COUNT_MAX} // 480; |
22
|
1
|
my $server_alive_interval = $bmwqemu::vars{_SSH_SERVER_ALIVE_INTERVAL} // ONE_MINUTE; |
|
1
|
|
|
1
|
|
|
1
|
|
|
1
|
|
|
1
|
|
23
|
1
|
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"; |
24
|
1
|
$sshopts = "-X $sshopts" if $gui; |
25
|
1
|
return "ssh $sshopts; read"; |
26
|
1
|
} |
27
|
1
|
|
28
|
|
my $display = $self->{DISPLAY}; |
29
|
|
$command = "TERM=xterm $command"; |
30
|
3
|
my $xterm_vt_cmd = which "xterm-console"; |
|
3
|
|
|
3
|
|
|
3
|
|
|
3
|
|
31
|
3
|
die "Missing 'xterm-console'" unless $xterm_vt_cmd; |
32
|
3
|
die('Missing "Xvnc"') unless which('Xvnc'); |
33
|
3
|
die('Missing "icewm"') unless which('icewm'); |
34
|
3
|
die('Missing "xterm"') unless which('xterm'); |
35
|
3
|
if ($self->{args}->{log}) { |
36
|
3
|
mkpath 'ulogs'; |
37
|
3
|
$command = "script -f ulogs/hardware-console-log.txt -c \"$command\""; |
38
|
3
|
} |
39
|
2
|
eval { system("DISPLAY=$display $xterm_vt_cmd -title $window_name -e bash -c '$command' & echo \"xterm PID is \$!\""); }; |
40
|
2
|
die "cant' start xterm on $display (err: $! retval: $?)" if $@; |
41
|
|
} |
42
|
3
|
|
|
3
|
|
43
|
3
|
my $display = $self->{DISPLAY}; |
44
|
|
my $window_name = $args->{window_name}; |
45
|
|
|
46
|
1
|
my $xdotool = $ENV{OS_AUTOINST_XDOTOOL} // which "xdotool"; |
|
1
|
|
|
1
|
|
|
1
|
|
47
|
1
|
die "Missing 'xdotool'" unless $xdotool; |
48
|
1
|
|
49
|
|
# search for YaST Window and grab the id |
50
|
1
|
my $window_id = qx"DISPLAY=$display $xdotool search --sync --onlyvisible --name $window_name"; |
51
|
1
|
$window_id =~ s/\D//g; |
52
|
|
|
53
|
|
# resize and move window to fit in icewm |
54
|
1
|
system("DISPLAY=$display $xdotool windowsize $window_id 100% 100%"); |
55
|
1
|
system("DISPLAY=$display $xdotool windowmove $window_id 0 0"); |
56
|
|
} |
57
|
|
|
58
|
1
|
# uncoverable statement count:1 |
59
|
1
|
# uncoverable statement count:2 |
60
|
|
# uncoverable statement count:3 |
61
|
|
# uncoverable statement count:4 |
62
|
|
listen($s, 1); # uncoverable statement |
63
|
|
my $peer; # uncoverable statement |
64
|
|
accept($peer, $s); # uncoverable statement |
65
|
|
close($s); # uncoverable statement |
66
|
0
|
open(STDIN, "<&", $peer); # uncoverable statement |
|
0
|
|
|
0
|
|
|
0
|
|
67
|
0
|
open(STDOUT, ">&", $peer); # uncoverable statement |
68
|
0
|
close($peer); # uncoverable statement |
69
|
0
|
exec("Xvnc -depth 16 -inetd -SecurityTypes None -ac $display"); # uncoverable statement |
70
|
0
|
} |
71
|
0
|
|
72
|
0
|
# start Xvnc on a random high port and use that port also as $DISPLAY |
73
|
0
|
|
74
|
0
|
my $tcpproto = getprotobyname('tcp'); |
75
|
|
my $s; |
76
|
|
socket($s, PF_INET, SOCK_STREAM, $tcpproto) || die "socket: $!\n"; |
77
|
1
|
bind($s, sockaddr_in(0, INADDR_ANY)); |
|
1
|
|
|
1
|
|
78
|
|
my ($port) = sockaddr_in(getsockname($s)); |
79
|
|
|
80
|
1
|
my $display = ":$port"; |
81
|
1
|
my $pid = fork(); |
82
|
1
|
die unless defined $pid; |
83
|
1
|
start_xvnc($s, $display) unless $pid; |
84
|
1
|
close($s); |
85
|
|
|
86
|
1
|
my $vnc = $self->connect_remote({hostname => 'localhost', port => $port, ikvm => 0, description => 'local Xvnc'}); |
87
|
1
|
# disable checking VNC stalls as this setup would not survive re-connects triggered by the VNC stall |
88
|
1
|
# detection anyways (as Xvnc terminates itself when the connection is closed) |
89
|
1
|
# note: Otherwise jobs are failing with "Error connecting to VNC server localhost ⦠Connection refused" |
90
|
1
|
# (see poo#105882). |
91
|
|
$vnc->check_vnc_stalls(0); |
92
|
1
|
bmwqemu::diag("Connected to Xvnc - PID $pid"); |
93
|
|
$self->{DISPLAY} = $display; |
94
|
|
sleep 1; |
95
|
|
|
96
|
|
# we need a window manager for fullscreen apps to work |
97
|
1
|
system("DISPLAY=$display icewm -c $bmwqemu::scriptdir/consoles/icewm.cfg & echo \"icewm PID is \$!\""); |
98
|
1
|
return; |
99
|
1
|
} |
100
|
1
|
|
101
|
|
1; |