|
8 | 8 | # ./hack/test-port-forwarding.pl templates/default.yaml |
9 | 9 | # limactl --tty=false start templates/default.yaml |
10 | 10 | # git restore templates/default.yaml |
11 | | -# ./hack/test-port-forwarding.pl default |
| 11 | +# ./hack/test-port-forwarding.pl default [nc|socat [nc|socat]] [timeout] |
12 | 12 | # |
13 | 13 | # TODO: support for ipv6 host addresses |
14 | 14 |
|
|
21 | 21 | use Socket qw(inet_ntoa); |
22 | 22 | use Sys::Hostname qw(hostname); |
23 | 23 |
|
| 24 | +my $connectionTimeout = 1; # seconds |
| 25 | + |
24 | 26 | my $instance = shift; |
| 27 | +my $listener; |
| 28 | +my $writer; |
| 29 | +while (my $arg = shift) { |
| 30 | + if ($arg eq "nc" || $arg eq "socat") { |
| 31 | + $listener = $arg unless defined $listener; |
| 32 | + $writer = $arg if defined $listener && !defined $writer; |
| 33 | + } elsif ($arg =~ /^\d+$/) { |
| 34 | + $connectionTimeout = $arg; |
| 35 | + } else { |
| 36 | + die "Usage: $0 [instance|yaml-file] [nc|socat [nc|socat]] [timeout]\n"; |
| 37 | + } |
| 38 | +} |
| 39 | +$listener ||= "nc"; |
| 40 | +$writer ||= $listener; |
25 | 41 |
|
26 | 42 | my $addr = scalar gethostbyname(hostname()); |
27 | 43 | # If hostname address cannot be determines, use localhost to trigger fallback to system_profiler lookup |
|
146 | 162 | set -e |
147 | 163 | cd $HOME |
148 | 164 | sudo pkill -x nc || true |
149 | | -rm -f nc.* |
| 165 | +sudo pkill -x socat || true |
| 166 | +rm -f nc.* socat.* |
150 | 167 | EOF |
151 | 168 |
|
152 | 169 | # Give the hostagent some time to remove any port forwards from a previous (crashed?) test run |
|
161 | 178 | # Setup a netcat listener on the guest for each test |
162 | 179 | foreach my $id (0..@test-1) { |
163 | 180 | my $test = $test[$id]; |
164 | | - my $nc = "nc -l $test->{guest_ip} $test->{guest_port}"; |
165 | | - if ($instance =~ /^alpine/) { |
166 | | - $nc = "nc -l -s $test->{guest_ip} -p $test->{guest_port}"; |
| 181 | + my $cmd; |
| 182 | + if ($listener eq "nc") { |
| 183 | + $cmd = "nc -l $test->{guest_ip} $test->{guest_port}"; |
| 184 | + if ($instance =~ /^alpine/) { |
| 185 | + $cmd = "nc -l -s $test->{guest_ip} -p $test->{guest_port}"; |
| 186 | + } |
| 187 | + } elsif ($listener eq "socat") { |
| 188 | + my $proto = $test->{guest_ip} =~ /:/ ? "TCP6" : "TCP"; |
| 189 | + $cmd = "socat -u $proto-LISTEN:$test->{guest_port},bind=$test->{guest_ip} STDOUT"; |
167 | 190 | } |
168 | 191 |
|
169 | 192 | my $sudo = $test->{guest_port} < 1024 ? "sudo " : ""; |
170 | | - print $lima "${sudo}${nc} >nc.${id} 2>/dev/null &\n"; |
| 193 | + print $lima "${sudo}${cmd} >$listener.${id} 2>/dev/null &\n"; |
171 | 194 | } |
172 | 195 |
|
173 | 196 | # Make sure the guest- and hostagents had enough time to set up the forwards |
|
176 | 199 | # Try to reach each listener from the host |
177 | 200 | foreach my $test (@test) { |
178 | 201 | next if $test->{host_port} == $sshLocalPort; |
179 | | - my $nc = $test->{host_socket} eq "" ? "nc -w 1 $test->{host_ip} $test->{host_port}" : "nc -w 1 -U $test->{host_socket}"; |
180 | | - open(my $netcat, "| $nc") or die "Can't run '$nc': $!"; |
| 202 | + my $cmd; |
| 203 | + if ($writer eq "nc") { |
| 204 | + if ($Config{osname} eq "darwin") { |
| 205 | + # macOS nc doesn't support -w for connection timeout, so use -G instead |
| 206 | + $cmd = $test->{host_socket} eq "" ? "nc -G $connectionTimeout $test->{host_ip} $test->{host_port}" : "nc -G $connectionTimeout -U $test->{host_socket}"; |
| 207 | + } else { |
| 208 | + $cmd = $test->{host_socket} eq "" ? "nc -w $connectionTimeout $test->{host_ip} $test->{host_port}" : "nc -w $connectionTimeout -U $test->{host_socket}"; |
| 209 | + } |
| 210 | + } elsif ($writer eq "socat") { |
| 211 | + my $tcp_dest = $test->{host_ip} =~ /:/ ? "TCP6:[$test->{host_ip}]:$test->{host_port}" : "TCP:$test->{host_ip}:$test->{host_port}"; |
| 212 | + $cmd = $test->{host_socket} eq "" ? "socat -u STDIN $tcp_dest,connect-timeout=$connectionTimeout" : "socat -u STDIN UNIX-CONNECT:$test->{host_socket}"; |
| 213 | + } |
| 214 | + print "Running: $cmd\n"; |
| 215 | + open(my $netcat, "| $cmd") or die "Can't run '$cmd': $!"; |
181 | 216 | print $netcat "$test->{log_msg}\n"; |
182 | 217 | # Don't check for errors on close; macOS nc seems to return non-zero exit code even on success |
183 | 218 | close($netcat); |
|
204 | 239 | unless ($seen{$test->{log_msg}}) { |
205 | 240 | $err .= "\n Message missing from ha.stderr.log"; |
206 | 241 | } |
207 | | - my $log = qx(limactl shell --workdir / $instance sh -c "cd; cat nc.$id"); |
| 242 | + my $log = qx(limactl shell --workdir / $instance sh -c "cd; cat $listener.$id"); |
208 | 243 | chomp $log; |
209 | 244 | if ($test->{mode} eq "forward" && $test->{log_msg} ne $log) { |
210 | 245 | $err .= "\n Guest received: '$log'"; |
|
241 | 276 | } |
242 | 277 |
|
243 | 278 | # Cleanup remaining netcat instances (and port forwards) |
244 | | -print $lima "sudo pkill -x nc"; |
| 279 | +print $lima "sudo pkill -x $listener"; |
245 | 280 |
|
246 | 281 | exit $rc; |
247 | 282 |
|
|
0 commit comments