Skip to content

Commit 3c1b994

Browse files
authored
Merge pull request #4170 from norio-nomura/test-port-forwarding.pl-use-socat
hack/test-port-forwarding.pl: support `socat` as listener and writer
2 parents 3cc7ac2 + 067468e commit 3c1b994

File tree

3 files changed

+75
-28
lines changed

3 files changed

+75
-28
lines changed

.github/workflows/test.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ jobs:
177177
- name: Integration tests (WSL2, Windows host)
178178
run: |
179179
$env:PATH = "$pwd\_output\bin;" + 'C:\msys64\usr\bin;' + $env:PATH
180-
pacman -Sy --noconfirm openbsd-netcat diffutils
180+
pacman -Sy --noconfirm openbsd-netcat diffutils socat
181181
$env:MSYS2_ENV_CONV_EXCL = 'HOME_HOST;HOME_GUEST;_LIMA_WINDOWS_EXTRA_PATH'
182182
$env:HOME_HOST = $(cygpath.exe "$env:USERPROFILE")
183183
$env:HOME_GUEST = "/mnt$env:HOME_HOST"
@@ -206,7 +206,7 @@ jobs:
206206
- name: Integration tests (QEMU, Windows host)
207207
run: |
208208
$env:PATH = "$pwd\_output\bin;" + 'C:\msys64\usr\bin;' + 'C:\Program Files\QEMU;' + $env:PATH
209-
pacman -Sy --noconfirm openbsd-netcat diffutils
209+
pacman -Sy --noconfirm openbsd-netcat diffutils socat
210210
$env:MSYS2_ENV_CONV_EXCL = 'HOME_HOST;HOME_GUEST;_LIMA_WINDOWS_EXTRA_PATH'
211211
$env:HOME_HOST = $(cygpath.exe "$env:USERPROFILE")
212212
$env:HOME_GUEST = "$env:HOME_HOST"
@@ -239,7 +239,8 @@ jobs:
239239
# bash: required by test-templates.sh (OS version of bash is too old)
240240
# coreutils: required by test-templates.sh for the "timeout" command
241241
# w3m : required by test-templates.sh for port forwarding tests
242-
run: brew install qemu bash coreutils w3m
242+
# socat: required by test-templates.sh for port forwarding tests
243+
run: brew install qemu bash coreutils w3m socat
243244
- name: "Adjust LIMACTL_CREATE_ARGS"
244245
run: echo "LIMACTL_CREATE_ARGS=${LIMACTL_CREATE_ARGS} --vm-type=qemu" >>$GITHUB_ENV
245246
- name: "Inject `no_timer_check` to kernel cmdline"
@@ -304,7 +305,7 @@ jobs:
304305
run: |
305306
sudo apt-get update
306307
sudo ./hack/install-qemu.sh
307-
sudo apt-get install -y --no-install-recommends w3m
308+
sudo apt-get install -y --no-install-recommends socat w3m
308309
- name: Install ansible-playbook
309310
run: |
310311
sudo apt-get install -y --no-install-recommends ansible
@@ -426,7 +427,7 @@ jobs:
426427
with:
427428
template: templates/default.yaml
428429
- name: Install test dependencies
429-
run: brew install qemu bash coreutils w3m
430+
run: brew install qemu bash coreutils w3m socat
430431
- name: Install socket_vmnet
431432
env:
432433
SOCKET_VMNET_VERSION: v1.2.0
@@ -521,7 +522,7 @@ jobs:
521522
with:
522523
template: templates/${{ matrix.template }}
523524
- name: Install test dependencies
524-
run: brew install bash coreutils w3m
525+
run: brew install bash coreutils w3m socat
525526
- name: Uninstall qemu
526527
run: brew uninstall --ignore-dependencies --force qemu
527528
- name: Test

hack/test-port-forwarding.pl

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# ./hack/test-port-forwarding.pl templates/default.yaml
99
# limactl --tty=false start templates/default.yaml
1010
# git restore templates/default.yaml
11-
# ./hack/test-port-forwarding.pl default
11+
# ./hack/test-port-forwarding.pl default [nc|socat [nc|socat]] [timeout]
1212
#
1313
# TODO: support for ipv6 host addresses
1414

@@ -21,7 +21,23 @@
2121
use Socket qw(inet_ntoa);
2222
use Sys::Hostname qw(hostname);
2323

24+
my $connectionTimeout = 1; # seconds
25+
2426
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;
2541

2642
my $addr = scalar gethostbyname(hostname());
2743
# If hostname address cannot be determines, use localhost to trigger fallback to system_profiler lookup
@@ -146,7 +162,8 @@
146162
set -e
147163
cd $HOME
148164
sudo pkill -x nc || true
149-
rm -f nc.*
165+
sudo pkill -x socat || true
166+
rm -f nc.* socat.*
150167
EOF
151168

152169
# Give the hostagent some time to remove any port forwards from a previous (crashed?) test run
@@ -161,13 +178,19 @@
161178
# Setup a netcat listener on the guest for each test
162179
foreach my $id (0..@test-1) {
163180
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";
167190
}
168191

169192
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";
171194
}
172195

173196
# Make sure the guest- and hostagents had enough time to set up the forwards
@@ -176,8 +199,20 @@
176199
# Try to reach each listener from the host
177200
foreach my $test (@test) {
178201
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': $!";
181216
print $netcat "$test->{log_msg}\n";
182217
# Don't check for errors on close; macOS nc seems to return non-zero exit code even on success
183218
close($netcat);
@@ -204,7 +239,7 @@
204239
unless ($seen{$test->{log_msg}}) {
205240
$err .= "\n Message missing from ha.stderr.log";
206241
}
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");
208243
chomp $log;
209244
if ($test->{mode} eq "forward" && $test->{log_msg} ne $log) {
210245
$err .= "\n Guest received: '$log'";
@@ -241,7 +276,7 @@
241276
}
242277

243278
# Cleanup remaining netcat instances (and port forwards)
244-
print $lima "sudo pkill -x nc";
279+
print $lima "sudo pkill -x $listener";
245280

246281
exit $rc;
247282

hack/test-templates.sh

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ function diagnose() {
152152
mkdir -p failure-logs
153153
cp -pf "$HOME_HOST/.lima/${NAME}"/*.log failure-logs/
154154
limactl shell "$NAME" sudo cat /var/log/cloud-init-output.log | tee failure-logs/cloud-init-output.log
155+
limactl shell "$NAME" sh -c "command -v journalctl >/dev/null && sudo journalctl -b --no-pager" >failure-logs/journal.log
155156
set +x -e
156157
}
157158

@@ -432,24 +433,34 @@ if [[ -n ${CHECKS["container-engine"]} ]]; then
432433
fi
433434

434435
if [[ -n ${CHECKS["port-forwards"]} ]]; then
435-
INFO "Testing port forwarding rules using netcat"
436+
PORT_FORWARDING_CONNECTION_TIMEOUT=1
437+
INFO "Testing port forwarding rules using netcat and socat with connection timeout ${PORT_FORWARDING_CONNECTION_TIMEOUT}s"
436438
set -x
437-
if [ "${NAME}" = "archlinux" ]; then
438-
limactl shell "$NAME" sudo pacman -Syu --noconfirm openbsd-netcat
439+
if [[ ${NAME} == "alpine"* ]]; then
440+
limactl shell "${NAME}" sudo apk add socat
439441
fi
440-
if [ "${NAME}" = "debian" ]; then
441-
limactl shell "$NAME" sudo apt-get install -y netcat-openbsd
442+
if [[ ${NAME} == "archlinux" ]]; then
443+
limactl shell "${NAME}" sudo pacman -Syu --noconfirm openbsd-netcat socat
442444
fi
443-
if [ "${NAME}" == "fedora" ]; then
444-
limactl shell "$NAME" sudo dnf install -y nc
445+
if [[ ${NAME} == "debian" || ${NAME} == "default" || ${NAME} == "docker" || ${NAME} == "test-misc" ]]; then
446+
limactl shell "${NAME}" sudo apt-get install -y netcat-openbsd socat
445447
fi
446-
if [ "${NAME}" = "opensuse" ]; then
447-
limactl shell "$NAME" sudo zypper in -y netcat-openbsd
448+
if [[ ${NAME} == "fedora" || ${NAME} == "wsl2" ]]; then
449+
limactl shell "${NAME}" sudo dnf install -y nc socat
448450
fi
449-
if limactl shell "$NAME" command -v dnf; then
450-
limactl shell "$NAME" sudo dnf install -y nc
451+
if [[ ${NAME} == "opensuse" ]]; then
452+
limactl shell "${NAME}" sudo zypper in -y netcat-openbsd socat
453+
fi
454+
if limactl shell "${NAME}" command -v dnf; then
455+
limactl shell "${NAME}" sudo dnf install -y nc socat
456+
fi
457+
if "${scriptdir}/test-port-forwarding.pl" "${NAME}" socat $PORT_FORWARDING_CONNECTION_TIMEOUT; then
458+
INFO "Port forwarding rules work"
459+
else
460+
ERROR "Port forwarding rules do not work with socat"
461+
diagnose "$NAME"
462+
exit 1
451463
fi
452-
"${scriptdir}/test-port-forwarding.pl" "${NAME}"
453464

454465
if [[ -n ${CHECKS["container-engine"]} || ${NAME} == "alpine"* ]]; then
455466
INFO "Testing that \"${CONTAINER_ENGINE} run\" binds to 0.0.0.0 and is forwarded to the host (non-default behavior, configured via test-port-forwarding.pl)"

0 commit comments

Comments
 (0)