import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Enumeration;
private ViewChangedListener cacheManagerListener;
private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
-
+ private static final int gossipRouterPortDefault = 12001;
// defaultTransactionTimeout is 60 seconds
private static int DEFAULT_TRANSACTION_TIMEOUT = 60;
*/
private GossipRouter startGossiper() {
boolean amIGossipRouter = false;
- Integer gossipRouterPortDefault = 12001;
Integer gossipRouterPort = gossipRouterPortDefault;
InetAddress gossipRouterAddress = null;
String supernodes_list = System.getProperty("supernodes",
loopbackAddress);
+ /*
+ * Check the environment for the "container" variable, if this is set
+ * and is equal to "lxc", then ODL is running inside an lxc
+ * container, and address resolution of supernodes will be modified
+ * accordingly.
+ */
+ boolean inContainer = "lxc".equals(System.getenv("container"));
StringBuffer sanitized_supernodes_list = new StringBuffer();
List<InetAddress> myAddresses = new ArrayList<InetAddress>();
+ if (inContainer) {
+ logger.trace("DOCKER: Resolving supernode host names using docker container semantics");
+ }
+
StringTokenizer supernodes = new StringTokenizer(supernodes_list, ":");
if (supernodes.hasMoreTokens()) {
// Populate the list of my addresses
}
host = host_port.nextToken();
InetAddress hostAddr;
+ /*
+ * If we are in a container and the hostname begins with a '+', this is
+ * an indication that we should resolve this host name in the context
+ * of a docker container.
+ *
+ * Specifically this means:
+ * '+self' : self reference and the host will be mapped to the value of
+ * HOSTNAME in the environment
+ * '+<name>' : references another container by its name. The docker established
+ * environment variables will be used to resolve the host to an
+ * IP address.
+ */
+ if (inContainer && host != null && host.charAt(0) == '+') {
+ if ("+self".equals(host)) {
+ host = System.getenv("HOSTNAME");
+ } else {
+ String link = System.getenv(host.substring(1).toUpperCase() + "_PORT");
+ if (link != null) {
+ try {
+ host = new URI(link).getHost();
+ } catch (URISyntaxException e) {
+ logger.error("DOCKER: Unable to translate container reference ({}) to host IP Address, will attempt using normal host name",
+ host.substring(1));
+ }
+ }
+ }
+ }
+
try {
hostAddr = InetAddress.getByName(host);
} catch (UnknownHostException ue) {
- logger.error("Host not known");
+ logger.error("Host {} is not known", host);
continue;
}
if (host_port.hasMoreTokens()) {
try {
port_num = Integer.valueOf(port);
} catch (NumberFormatException ne) {
- logger
- .error("Supplied supernode gossiepr port is not recognized, using standard gossipport");
+ logger.error("Supplied supernode gossip port is not recognized, using default gossip port {}",
+ gossipRouterPortDefault);
port_num = gossipRouterPortDefault;
}
if ((port_num > 65535) || (port_num < 0)) {
- logger
- .error("Supplied supernode gossip port is outside a valid TCP port range");
+ logger.error("Supplied supernode gossip port is outside a valid TCP port range");
port_num = gossipRouterPortDefault;
}
}
if (!sanitized_supernodes_list.toString().equals("")) {
sanitized_supernodes_list.append(",");
}
- sanitized_supernodes_list.append(hostAddr.getHostAddress() + "["
- + port_num + "]");
+ sanitized_supernodes_list.append(hostAddr.getHostAddress()).append("[").append(port_num).append("]");
}
if (amIGossipRouter) {