| 
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 | +        $cmd = $test->{host_socket} eq "" ? "nc -w $connectionTimeout $test->{host_ip} $test->{host_port}" : "nc -w $connectionTimeout -U $test->{host_socket}";  | 
 | 205 | +    } elsif ($writer eq "socat") {  | 
 | 206 | +        my $tcp_dest = $test->{host_ip} =~ /:/ ? "TCP6:[$test->{host_ip}]:$test->{host_port}" : "TCP:$test->{host_ip}:$test->{host_port}";  | 
 | 207 | +        $cmd = $test->{host_socket} eq "" ? "socat -u STDIN $tcp_dest,connect-timeout=$connectionTimeout" : "socat -u STDIN UNIX-CONNECT:$test->{host_socket}";  | 
 | 208 | +    }  | 
 | 209 | +    print "Running: $cmd\n";  | 
 | 210 | +    open(my $netcat, "| $cmd") or die "Can't run '$cmd': $!";  | 
181 | 211 |     print $netcat "$test->{log_msg}\n";  | 
182 | 212 |     # Don't check for errors on close; macOS nc seems to return non-zero exit code even on success  | 
183 | 213 |     close($netcat);  | 
 | 
204 | 234 |     unless ($seen{$test->{log_msg}}) {  | 
205 | 235 |         $err .= "\n   Message missing from ha.stderr.log";  | 
206 | 236 |     }  | 
207 |  | -    my $log = qx(limactl shell --workdir / $instance sh -c "cd; cat nc.$id");  | 
 | 237 | +    my $log = qx(limactl shell --workdir / $instance sh -c "cd; cat $listener.$id");  | 
208 | 238 |     chomp $log;  | 
209 | 239 |     if ($test->{mode} eq "forward" && $test->{log_msg} ne $log) {  | 
210 | 240 |         $err .= "\n   Guest received: '$log'";  | 
 | 
241 | 271 | }  | 
242 | 272 | 
 
  | 
243 | 273 | # Cleanup remaining netcat instances (and port forwards)  | 
244 |  | -print $lima "sudo pkill -x nc";  | 
 | 274 | +print $lima "sudo pkill -x $listener";  | 
245 | 275 | 
 
  | 
246 | 276 | exit $rc;  | 
247 | 277 | 
 
  | 
 | 
0 commit comments