diff options
4 files changed, 12 insertions, 178 deletions
diff --git a/defaults/src/main/java/com/yahoo/vespa/defaults/Defaults.java b/defaults/src/main/java/com/yahoo/vespa/defaults/Defaults.java index 8a9be7891ae..441773a14c9 100644 --- a/defaults/src/main/java/com/yahoo/vespa/defaults/Defaults.java +++ b/defaults/src/main/java/com/yahoo/vespa/defaults/Defaults.java @@ -55,15 +55,6 @@ public class Defaults { if (vespaHostEnv.isPresent() && ! vespaHostEnv.get().trim().isEmpty()) { return vespaHostEnv.get().trim(); } - try { - Process p = Runtime.getRuntime().exec("hostname"); - BufferedReader r = new BufferedReader( - new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8)); - String line = r.readLine(); - if (line != null && ! line.trim().isEmpty()) { - return line; - } - } catch (java.io.IOException e) {} return "localhost"; } diff --git a/defaults/src/vespa/defaults.cpp b/defaults/src/vespa/defaults.cpp index 05e621d2dc2..dcb5e38584d 100644 --- a/defaults/src/vespa/defaults.cpp +++ b/defaults/src/vespa/defaults.cpp @@ -18,7 +18,6 @@ namespace { const char *defaultHome = "/opt/vespa"; const char *defaultUser = "vespa"; const char *defaultHost = "localhost"; -char hostbuf[HOST_BUF_SZ]; int defaultWebServicePort = 8080; int defaultPortBase = 19000; int defaultPortConfigServerRpc = 19070; @@ -60,22 +59,16 @@ void findDefaults() { } } env = getenv("VESPA_USER"); - if (env != NULL) { - if (*env != '0' && getpwnam(env) == 0) { + if (env != NULL && *env != '\0') { + if (getpwnam(env) == 0) { fprintf(stderr, "warning\tbad VESPA_USER '%s' (ignored)\n", env); } else { defaultUser = env; } } env = getenv("VESPA_HOSTNAME"); - if (env != NULL) { + if (env != NULL && *env != '\0') { defaultHost = env; - } else { - int err = gethostname(hostbuf, HOST_BUF_SZ); - hostbuf[HOST_BUF_SZ-1] = '\0'; - if (err == 0 && strlen(hostbuf) > 0 && strlen(hostbuf) < HOST_BUF_SZ-1) { - defaultHost = hostbuf; - } } long p = getNumFromEnv("VESPA_WEB_SERVICE_PORT"); if (p > 0) { diff --git a/vespajlib/src/main/java/com/yahoo/net/HostName.java b/vespajlib/src/main/java/com/yahoo/net/HostName.java index 157239e456f..9a48c82c369 100644 --- a/vespajlib/src/main/java/com/yahoo/net/HostName.java +++ b/vespajlib/src/main/java/com/yahoo/net/HostName.java @@ -1,181 +1,36 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.net; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Utilities for getting the hostname of the system running the JVM. * - * @author Ulf Lilleengen - * @author bratseth - * @author hakon + * @author arnej */ public class HostName { - private static final Logger logger = Logger.getLogger(HostName.class.getName()); - private static String preferredHostName = null; /** - * Return a public and fully qualified hostname for localhost that resolves to an IP address on - * a network interface. Normally this is the same as the 'hostname' command, but on dev machines on WiFi - * that IP isn't configured, so we find the DNS entry corresponding to the WiFi IP address. + * Return a public and fully qualified hostname for localhost that + * resolves to an IP address on a network interface. * * @return the preferred name of localhost - * @throws RuntimeException if accessing the network or the 'hostname' command fails */ public static synchronized String getLocalhost() { if (preferredHostName == null) { - try { - preferredHostName = getPreferredHostName(); - } catch (Exception e) { - throw new RuntimeException("Failed to find a preferred hostname", e); - } + preferredHostName = getPreferredHostName(); } return preferredHostName; } - private static String getPreferredHostName() throws Exception { - // Prefer the system hostname - String systemHostName = getSystemHostName(); - if (isReachable(systemHostName)) { - return systemHostName; - } - - // Try to find an IP address that resolves in DNS, starting with IPv4 addresses as an optimization. - - List<InetAddress> reachableNonLocalIp4Addresses = new ArrayList<>(); - List<InetAddress> reachableNonLocalIp6Addresses = new ArrayList<>(); - for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) { - for (InetAddress ipAddress : Collections.list(networkInterface.getInetAddresses())) { - if (!isReachable(ipAddress)) { - continue; - } - - if (ipAddress instanceof Inet4Address) { - reachableNonLocalIp4Addresses.add(ipAddress); - } else { - reachableNonLocalIp6Addresses.add(ipAddress); - } - } - } - - Optional<String> reachableHostName = getAnyHostNameInDns(reachableNonLocalIp4Addresses); - if (reachableHostName.isPresent()) { - return reachableHostName.get(); - } - - reachableHostName = getAnyHostNameInDns(reachableNonLocalIp6Addresses); - if (reachableHostName.isPresent()) { - return reachableHostName.get(); - } - - // Use textual representation of IP address since we failed to find a canonical DNS name above. - - if (!reachableNonLocalIp4Addresses.isEmpty()) { - return reachableNonLocalIp4Addresses.get(0).getHostName(); - } else if (!reachableNonLocalIp6Addresses.isEmpty()) { - return reachableNonLocalIp6Addresses.get(0).getHostName(); - } - - // Fall back to InetAddress' localhost. - - return InetAddress.getLocalHost().getCanonicalHostName(); - } - - private static Optional<String> getAnyHostNameInDns(List<InetAddress> ipAddresses) { - for (InetAddress ipAddress : ipAddresses) { - // Caveat: This call typically takes seconds on a Mac, and with 5 or so addresses - // it is important to avoid calling this too often. That's why we do it here. - // We should actually have called this first, then gotten the hostname's InetAddress - // address (which may not match ipAddress), and used it for the above reachability test. - String hostname = ipAddress.getCanonicalHostName(); - if (Objects.equals(hostname, ipAddress.getHostAddress())) { - // getCanonicalHostName() failed to get the fully qualified domain name - continue; - } - - return Optional.of(hostname); - } - - return Optional.empty(); - } - - /** - * DO NOT USE: Package-private for testing purposes (all testing machines should have a hostname) - */ - static String getSystemHostName() throws Exception { - String env = System.getenv("VESPA_HOSTNAME"); - if (env != null && ! env.trim().isEmpty()) { - return env.trim(); - } - Process process = Runtime.getRuntime().exec("hostname"); - BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); - String hostname = in.readLine(); - process.waitFor(); - if (process.exitValue() != 0) { - throw new RuntimeException("Command 'hostname' failed with exit code " + process.exitValue()); - } - return hostname; - } - - private static Optional<String> getHostNameIfReachable(InetAddress ipAddress) { - if (!isReachable(ipAddress)) { - return Optional.empty(); - } - - // Caveat: This call typically takes seconds on a Mac, and with 5 or so addresses - // it is important to avoid calling this too often. That's why we do it here. - // We should actually have called this first, then gotten the hostname's InetAddress - // address (which may not match ipAddress), and used it for the above reachability test. - String hostname = ipAddress.getCanonicalHostName(); - if (Objects.equals(hostname, ipAddress.getHostAddress())) { - // getCanonicalHostName() failed to get the fully qualified domain name - return Optional.empty(); - } - - return Optional.of(hostname); - } - - private static boolean isReachable(String hostname) { - try { - InetAddress ipAddress = InetAddress.getByName(hostname); - return isReachable(ipAddress); - } catch (UnknownHostException e) { - return false; - } - } - - private static boolean isReachable(InetAddress ipAddress) { - try { - // ping says ~50ms on my Fedora Lenovo, but that seems a lot for pinging oneself - hakon - int timeoutMs = 100; - if ( ! ipAddress.isReachable(timeoutMs)) { - // The network interface may be down, ignore address - logger.log(Level.INFO, ipAddress.toString() + - " is unreachable w/" + timeoutMs + "ms timeout, ignoring address"); - return false; - } - - return true; - } catch (IOException e) { - // Why would this be different from !isReachable ? - logger.log(Level.INFO, "Failed testing reachability of " + ipAddress + ", ignoring address", e); - return false; + static private String getPreferredHostName() { + Optional<String> vespaHostEnv = Optional.ofNullable(System.getenv("VESPA_HOSTNAME")); + if (vespaHostEnv.isPresent() && ! vespaHostEnv.get().trim().isEmpty()) { + return vespaHostEnv.get().trim(); } + return "localhost"; } public static void setHostNameForTestingOnly(String hostName) { diff --git a/vespajlib/src/test/java/com/yahoo/net/HostNameTestCase.java b/vespajlib/src/test/java/com/yahoo/net/HostNameTestCase.java index 2c7fb0a29f6..d46e183a81e 100644 --- a/vespajlib/src/test/java/com/yahoo/net/HostNameTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/net/HostNameTestCase.java @@ -15,9 +15,4 @@ public class HostNameTestCase { assertFalse(HostName.getLocalhost().isEmpty()); } - @Test - public void testSystemHostnameIsFound() throws Exception { - assertFalse(HostName.getSystemHostName().isEmpty()); - } - } |