New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPARK-6440][CORE]Handle IPv6 addresses properly when constructing URI #5424
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ import scala.util.Try | |
import scala.util.control.{ControlThrowable, NonFatal} | ||
|
||
import com.google.common.io.{ByteStreams, Files} | ||
import com.google.common.net.InetAddresses | ||
import com.google.common.util.concurrent.ThreadFactoryBuilder | ||
import org.apache.commons.lang3.SystemUtils | ||
import org.apache.hadoop.conf.Configuration | ||
|
@@ -789,13 +790,14 @@ private[spark] object Utils extends Logging { | |
* Get the local host's IP address in dotted-quad format (e.g. 1.2.3.4). | ||
* Note, this is typically not used from within core spark. | ||
*/ | ||
lazy val localIpAddress: String = findLocalIpAddress() | ||
lazy val localIpAddressHostname: String = getAddressHostName(localIpAddress) | ||
lazy val localIpAddress: InetAddress = findLocalInetAddress() | ||
lazy val localIpAddressHostname: String = localIpAddress.getHostName | ||
lazy val localIpAddressURI: String = InetAddresses.toUriString(localIpAddress) | ||
|
||
private def findLocalIpAddress(): String = { | ||
private def findLocalInetAddress(): InetAddress = { | ||
val defaultIpOverride = System.getenv("SPARK_LOCAL_IP") | ||
if (defaultIpOverride != null) { | ||
defaultIpOverride | ||
InetAddress.getByName(defaultIpOverride) | ||
} else { | ||
val address = InetAddress.getLocalHost | ||
if (address.isLoopbackAddress) { | ||
|
@@ -806,23 +808,28 @@ private[spark] object Utils extends Logging { | |
// It's more proper to pick ip address following system output order. | ||
val activeNetworkIFs = NetworkInterface.getNetworkInterfaces.toList | ||
val reOrderedNetworkIFs = if (isWindows) activeNetworkIFs else activeNetworkIFs.reverse | ||
|
||
for (ni <- reOrderedNetworkIFs) { | ||
for (addr <- ni.getInetAddresses if !addr.isLinkLocalAddress && | ||
!addr.isLoopbackAddress && addr.isInstanceOf[Inet4Address]) { | ||
val addresses = ni.getInetAddresses.toList | ||
.filter { addr => !addr.isLinkLocalAddress && !addr.isLoopbackAddress } | ||
if ( !addresses.isEmpty ) { | ||
val addr = addresses.find( _.isInstanceOf[Inet4Address] ).getOrElse(addresses.head) | ||
// because of Inet6Address.toHostName may add interface at the end if it knows about it | ||
val strippedAddress = InetAddress.getByAddress(addr.getAddress) | ||
// We've found an address that looks reasonable! | ||
logWarning("Your hostname, " + InetAddress.getLocalHost.getHostName + " resolves to" + | ||
" a loopback address: " + address.getHostAddress + "; using " + addr.getHostAddress + | ||
" instead (on interface " + ni.getName + ")") | ||
" a loopback address: " + address.getHostAddress + "; using " + | ||
strippedAddress.getHostAddress + " instead (on interface " + ni.getName + ")") | ||
logWarning("Set SPARK_LOCAL_IP if you need to bind to another address") | ||
return addr.getHostAddress | ||
return strippedAddress | ||
} | ||
} | ||
logWarning("Your hostname, " + InetAddress.getLocalHost.getHostName + " resolves to" + | ||
" a loopback address: " + address.getHostAddress + ", but we couldn't find any" + | ||
" external IP address!") | ||
logWarning("Set SPARK_LOCAL_IP if you need to bind to another address") | ||
} | ||
address.getHostAddress | ||
address | ||
} | ||
} | ||
|
||
|
@@ -845,6 +852,13 @@ private[spark] object Utils extends Logging { | |
customHostname.getOrElse(localIpAddressHostname) | ||
} | ||
|
||
/** | ||
* Get the local machine's URI. | ||
*/ | ||
def localHostURI(): String = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this intended to be an IP address or host name? looks like IP address. But then some of the changes above are changing a host name to an IP address. That might be OK but it's not obvious? what's the motivation there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is named There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. I'm wondering when you wouldn't want to use the "URI safe" name? they're identical in almost every case. Hm. I suppose the safer thing is to only format for URIs where, well, creating URIs. I'll have to dig into this more but generally want to minimize the change here and narrowly address the formatting issue There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand how to use "URI safe" name, something like |
||
customHostname.getOrElse(localIpAddressURI) | ||
} | ||
|
||
def getAddressHostName(address: String): String = { | ||
InetAddress.getByName(address).getHostName | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tell me more about what this fixes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's all about finding our external IP address: old logic was to use external ipv4 || 127.0.0.1.
That transformes it to ipv4 || ipv6 || 127.0.0.1
Whenewer we don't have any ipv4 it's better to use ipv6 than 127.0.0.1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, though I don't think that was the thrust of this JIRA, which was simply to format IPv6 addresses correctly. I think the reasoning makes some sense though.
Nits: can you
filterNot(addr => addr.isLinkLocalAddress || addr.isLoopbackAddress)
and
if (addresses.notEmpty) {
? andfind(_.isInstanceOf[Inet4Address])
? Just questions of style in this block.It might be worth a comment to the effect of your reply above here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, i agree with that. Should i make additional commit or change existing one?
*
nonEmpty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just push more commits to this branch