This is an automated email from the ASF dual-hosted git repository. lhotari pushed a commit to branch lh-fix-auditor-race-condition in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
commit 79baa3fc7048d6237a0eb7128105891906f7a1dd Author: Lari Hotari <[email protected]> AuthorDate: Fri Mar 13 13:31:13 2026 +0200 Fix issue running tests in docker with multiple loopback interfaces and IPs --- .../main/java/org/apache/bookkeeper/net/DNS.java | 21 +++++++++++++++++++-- .../apache/bookkeeper/conf/TestBKConfiguration.java | 21 ++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/net/DNS.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/net/DNS.java index 68ff662126..2c714ef88f 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/net/DNS.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/net/DNS.java @@ -202,7 +202,7 @@ public class DNS { /** - * Returns the first available IP address associated with the provided + * Returns the first available IP address with a resolvable hostname associated with the provided * network interface or the local host IP if "default" is given. * * @param strInterface The name of the network interface or subinterface to query @@ -214,7 +214,24 @@ public class DNS { public static String getDefaultIP(String strInterface) throws UnknownHostException { String[] ips = getIPs(strInterface); - return ips[0]; + UnknownHostException lastException = null; + for (String ip : ips) { + String resolved = null; + try { + resolved = InetAddress.getByName(ip).getHostName(); + } catch (UnknownHostException e) { + // skip ip addresses that cannot be resolved to a hostname + lastException = e; + continue; + } + if (resolved.equals(ip)) { + lastException = new UnknownHostException( + "IP address " + ip + " for " + strInterface + " interface cannot be resolved to a hostname"); + continue; + } + return ip; + } + throw lastException; } /** diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/conf/TestBKConfiguration.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/conf/TestBKConfiguration.java index 4b1d64fc94..b823649140 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/conf/TestBKConfiguration.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/conf/TestBKConfiguration.java @@ -23,10 +23,14 @@ package org.apache.bookkeeper.conf; import java.net.NetworkInterface; import java.net.SocketException; +import java.net.UnknownHostException; import java.util.Collections; import java.util.Enumeration; +import java.util.LinkedHashSet; +import java.util.Set; import org.apache.bookkeeper.bookie.storage.ldb.DbLedgerStorage; import org.apache.bookkeeper.common.allocator.PoolingPolicy; +import org.apache.bookkeeper.net.DNS; import org.apache.bookkeeper.util.PortManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,12 +73,27 @@ public class TestBKConfiguration { private static String getLoopbackInterfaceName() { try { + Set<String> loopbackInterfaces = new LinkedHashSet<>(); Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces(); for (NetworkInterface nif : Collections.list(nifs)) { if (nif.isLoopback()) { - return nif.getName(); + String nifName = nif.getName(); + try { + DNS.getDefaultIP(nifName); + } catch (UnknownHostException e) { + // skip interfaces that don't have a resolvable hostname + continue; + } + loopbackInterfaces.add(nifName); } } + // prefer lo if available to avoid issues on Linux + if (loopbackInterfaces.contains("lo")) { + return "lo"; + } + if (!loopbackInterfaces.isEmpty()) { + return loopbackInterfaces.iterator().next(); + } } catch (SocketException se) { LOG.warn("Exception while figuring out loopback interface. Will use null.", se); return null;
