diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerStatus.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerStatus.java index 4f56535..6e90dba 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerStatus.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerStatus.java @@ -151,4 +151,28 @@ public static ContainerStatus newInstance(ContainerId containerId, @Private @Unstable public abstract void setCapability(Resource capability); + + /** + * Get the IP address where the container runs. + * @return The IP address where the container runs. + */ + @Public + @Unstable + public abstract String getIp(); + + @Private + @Unstable + public abstract void setIp(String ip); + + /** + * Get the hostname where the container runs. + * @return The hostname where the container runs. + */ + @Public + @Unstable + public abstract String getHost(); + + @Private + @Unstable + public abstract void setHost(String host); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto index 6c337cf..f5c7033 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto @@ -524,6 +524,8 @@ message ContainerStatusProto { optional int32 exit_status = 4 [default = -1000]; optional ResourceProto capability = 5; optional ExecutionTypeProto executionType = 6 [default = GUARANTEED]; + optional string ip = 7; + optional string host = 8; } enum ContainerExitStatusProto { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ContainerStatusPBImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ContainerStatusPBImpl.java index f1fdae9..432bca9 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ContainerStatusPBImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ContainerStatusPBImpl.java @@ -211,6 +211,44 @@ public synchronized void setCapability(Resource capability) { builder.setCapability(convertToProtoFormat(capability)); } + @Override + public String getIp() { + ContainerStatusProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasIp()) { + return null; + } + return p.getIp(); + } + + @Override + public void setIp(String ip) { + maybeInitBuilder(); + if (ip == null) { + builder.clearIp(); + return; + } + builder.setIp(ip); + } + + @Override + public String getHost() { + ContainerStatusProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasHost()) { + return null; + } + return p.getHost(); + } + + @Override + public void setHost(String host) { + maybeInitBuilder(); + if (host == null) { + builder.clearIp(); + return; + } + builder.setIp(host); + } + private ContainerStateProto convertToProtoFormat(ContainerState e) { return ProtoUtils.convertToProtoFormat(e); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java index f08db5a..25f12ea 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java @@ -626,6 +626,16 @@ public void activateContainer(ContainerId containerId, Path pidFilePath) { } } + public void setHostFilePath(Container container, Path hostFilePath) { + // Only DockerContainerRuntime uses this to set the path of the file into + // which ip/host info is written. + } + + public String[] getIpAndHost(Container container) { + // Only DockerContainerRuntime implements this + return null; + } + /** * Mark the container as inactive. For inactive containers this * method has no effect. diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java index 04e38fa..193242b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java @@ -462,6 +462,16 @@ public int launchContainer(ContainerStartContext ctx) throws IOException { } @Override + public void setHostFilePath(Container container, Path hostFilePath) { + linuxContainerRuntime.setHostFilePath(container, hostFilePath); + } + + @Override + public String[] getIpAndHost(Container container) { + return linuxContainerRuntime.getIpAndHost(container); + } + + @Override public int reacquireContainer(ContainerReacquisitionContext ctx) throws IOException, InterruptedException { ContainerId containerId = ctx.getContainerId(); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/Container.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/Container.java index 2278786..84d3cb2 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/Container.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/Container.java @@ -68,6 +68,8 @@ void setLogDir(String logDir); + void setIpAndHost(String[] ipAndHost); + String toString(); Priority getPriority(); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java index 193dfea..a0aa987 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java @@ -115,6 +115,8 @@ private int remainingRetryAttempts; private String workDir; private String logDir; + private String host; + private String ip; /** The NM-wide configuration - not specific to this container */ private final Configuration daemonConf; @@ -507,9 +509,12 @@ public ContainerLaunchContext getLaunchContext() { public ContainerStatus cloneAndGetContainerStatus() { this.readLock.lock(); try { - return BuilderUtils.newContainerStatus(this.containerId, + ContainerStatus status = BuilderUtils.newContainerStatus(this.containerId, getCurrentState(), diagnostics.toString(), exitCode, getResource(), this.containerTokenIdentifier.getExecutionType()); + status.setIp(ip); + status.setHost(host); + return status; } finally { this.readLock.unlock(); } @@ -567,6 +572,12 @@ public void setWorkDir(String workDir) { } @Override + public void setIpAndHost(String[] ipAndHost) { + this.ip = ipAndHost[0]; + this.host = ipAndHost[1]; + } + + @Override public String getLogDir() { return logDir; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java index 81b6c1f..9b1f94d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java @@ -111,7 +111,9 @@ private long maxKillWaitTime = 2000; protected Path pidFilePath = null; - + // DockerLinuxContainerRuntime will get the docker container's ip and hostname + // and store it in the host file. + protected Path hostFilePath = null; protected final LocalDirsHandlerService dirsHandler; public ContainerLaunch(Context context, Configuration configuration, @@ -227,6 +229,8 @@ public Integer call() { // pid file should be in nm private dir so that it is not // accessible by users pidFilePath = dirsHandler.getLocalPathForWrite(pidFileSubpath); + String hostFileSubpath = getHostFileSubpath(appIdStr, containerIdStr); + hostFilePath = dirsHandler.getLocalPathForWrite(hostFileSubpath); List localDirs = dirsHandler.getLocalDirs(); List logDirs = dirsHandler.getLogDirs(); List filecacheDirs = getNMFilecacheDirs(localDirs); @@ -416,6 +420,7 @@ protected int launchContainer(ContainerStartContext ctx) throws IOException { return ExitCode.TERMINATED.getExitCode(); } else { exec.activateContainer(containerId, pidFilePath); + exec.setHostFilePath(container, hostFilePath); return exec.launchContainer(ctx); } } @@ -542,7 +547,11 @@ protected String getPidFileSubpath(String appIdStr, String containerIdStr) { return getContainerPrivateDir(appIdStr, containerIdStr) + Path.SEPARATOR + String.format(ContainerLaunch.PID_FILE_NAME_FMT, containerIdStr); } - + + protected String getHostFileSubpath(String appIdStr, String containerIdStr) { + return getContainerPrivateDir(appIdStr, containerIdStr) + + Path.SEPARATOR + String.format("%s.host", containerIdStr); + } /** * Cleanup the container. * Cancels the launch if launch has not started yet or signals @@ -636,6 +645,10 @@ public void cleanupContainer() throws IOException { lfs.delete(pidFilePath, false); lfs.delete(pidFilePath.suffix(EXIT_CODE_FILE_SUFFIX), false); } + if (hostFilePath != null) { + FileContext lfs = FileContext.getLocalFSFileContext(); + lfs.delete(hostFilePath, false); + } } } @@ -776,13 +789,13 @@ public static String getRelativeContainerLogDir(String appIdStr, return appIdStr + Path.SEPARATOR + containerIdStr; } - protected String getContainerPrivateDir(String appIdStr, + protected static String getContainerPrivateDir(String appIdStr, String containerIdStr) { return getAppPrivateDir(appIdStr) + Path.SEPARATOR + containerIdStr + Path.SEPARATOR; } - private String getAppPrivateDir(String appIdStr) { + private static String getAppPrivateDir(String appIdStr) { return ResourceLocalizationService.NM_PRIVATE_DIR + Path.SEPARATOR + appIdStr; } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/RecoveredContainerLaunch.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/RecoveredContainerLaunch.java index 3cd31b7..3519b5e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/RecoveredContainerLaunch.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/RecoveredContainerLaunch.java @@ -39,7 +39,6 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerEventType; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerExitEvent; import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerReacquisitionContext; -import org.apache.hadoop.yarn.util.ConverterUtils; /** * This is a ContainerLaunch which has been recovered after an NM restart (for @@ -77,11 +76,17 @@ public Integer call() { boolean notInterrupted = true; try { - File pidFile = locatePidFile(appIdStr, containerIdStr); + File[] files = locatePidAndHostFile(appIdStr, containerIdStr); + File pidFile = files[0]; + File hostFile = files[1]; if (pidFile != null) { String pidPathStr = pidFile.getPath(); pidFilePath = new Path(pidPathStr); exec.activateContainer(containerId, pidFilePath); + if (hostFile != null) { + hostFilePath = new Path(hostFile.getPath()); + exec.setHostFilePath(container, hostFilePath); + } retCode = exec.reacquireContainer( new ContainerReacquisitionContext.Builder() .setContainer(container) @@ -126,15 +131,26 @@ public Integer call() { return 0; } - private File locatePidFile(String appIdStr, String containerIdStr) { + // file[0] is pid file, file[1] is host file which contains ip and host info. + private File[] locatePidAndHostFile(String appIdStr, String containerIdStr) { String pidSubpath= getPidFileSubpath(appIdStr, containerIdStr); + String hostSubpath = getHostFileSubpath(appIdStr, containerIdStr); + File[] files = new File[2]; for (String dir : getContext().getLocalDirsHandler(). getLocalDirsForRead()) { File pidFile = new File(dir, pidSubpath); if (pidFile.exists()) { - return pidFile; + files[0] = pidFile; + } + + File hostFile = new File(dir, hostSubpath); + if (hostFile.exists()) { + files[1] = hostFile; + } + if (files[0] != null && files[1] != null) { + return files; } } - return null; + return files; } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/privileged/PrivilegedOperationExecutor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/privileged/PrivilegedOperationExecutor.java index f865c14..b6e0b48 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/privileged/PrivilegedOperationExecutor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/privileged/PrivilegedOperationExecutor.java @@ -115,7 +115,7 @@ public static PrivilegedOperationExecutor getInstance(Configuration conf) { fullCommand.toArray(new String[fullCommand.size()]); if (LOG.isDebugEnabled()) { - LOG.debug("Privileged Execution Command Array: " + + LOG.info("Privileged Execution Command Array: " + Arrays.toString(fullCommandArray)); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java index e78f460..2378605 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java @@ -25,6 +25,7 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation; @@ -33,6 +34,8 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException; import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.List; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*; @@ -148,4 +151,23 @@ public void reapContainer(ContainerRuntimeContext ctx) throws ContainerExecutionException { } + + @Override + public void setHostFilePath(Container container, Path path) { + + } + + @Override + public String[] getIpAndHost(Container container) { + String[] ipAndHost = new String[2]; + try { + InetAddress address = InetAddress.getLocalHost(); + ipAndHost[0] = address.getHostAddress(); + ipAndHost[1] = address.getHostName(); + } catch (UnknownHostException e) { + LOG.error("Unable to get Local hostname and ip for " + container + .getContainerId()); + } + return ipAndHost; + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DelegatingLinuxContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DelegatingLinuxContainerRuntime.java index 75abfb0..bff8ded 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DelegatingLinuxContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DelegatingLinuxContainerRuntime.java @@ -25,6 +25,7 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationExecutor; import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException; @@ -106,4 +107,16 @@ public void reapContainer(ContainerRuntimeContext ctx) runtime.reapContainer(ctx); } + + @Override + public void setHostFilePath(Container container, Path path) { + LinuxContainerRuntime runtime = pickContainerRuntime(container); + runtime.setHostFilePath(container, path); + } + + @Override + public String[] getIpAndHost(Container container) { + LinuxContainerRuntime runtime = pickContainerRuntime(container); + return runtime.getIpAndHost(container); + } } \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java index 0cfdd05..b98da18 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java @@ -30,6 +30,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; @@ -46,6 +47,11 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants; import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -55,6 +61,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*; @@ -89,6 +97,8 @@ private String defaultNetwork; private CGroupsHandler cGroupsHandler; private AccessControlList privilegedContainersAcl; + private ConcurrentMap hostFiles = + new ConcurrentHashMap<>(); public static boolean isDockerContainerRequested( Map env) { @@ -419,7 +429,10 @@ public void launchContainer(ContainerRuntimeContext ctx) logDirs), commandFile, resourcesOpts); - + Path path = hostFiles.get(ctx.getContainer().getContainerId()); + if (path != null) { + launchOp.appendArgs(path.toString()); + } String tcCommandFile = ctx.getExecutionAttribute(TC_COMMAND_FILE); if (tcCommandFile != null) { @@ -490,4 +503,49 @@ public void reapContainer(ContainerRuntimeContext ctx) throws ContainerExecutionException { } + + @Override + public void setHostFilePath(Container container, Path path) { + hostFiles.put(container.getContainerId(), path); + } + + @Override + public String[] getIpAndHost(Container container) { + Path path = hostFiles.get(container.getContainerId()); + return readIpAndHost(path); + } + + public String[] readIpAndHost(Path path) { + if (path == null) { + return null; + } + LOG.debug("Read ip and host from: " + path); + BufferedReader bufReader = null; + try { + File file = new File(path.toString()); + if (file.exists()) { + FileInputStream fis = new FileInputStream(file); + bufReader = new BufferedReader(new InputStreamReader(fis, "UTF-8")); + String line = bufReader.readLine(); + if (line != null) { + String temp = line.trim(); + if (!temp.isEmpty()) { + String[] ipAndHost = temp.split(" "); + return ipAndHost; + } + } + } + } catch (Exception e) { + LOG.error("Error when reading from " + path); + } finally { + if (bufReader != null) { + try { + bufReader.close(); + } catch (IOException e) { + LOG.error("Error in closing " + path); + } + } + } + return null; + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java index e6a66bd..d72b995 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java @@ -18,10 +18,8 @@ package org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; @@ -45,8 +43,10 @@ import org.apache.hadoop.yarn.util.ResourceCalculatorPlugin; import org.apache.hadoop.yarn.util.ResourceCalculatorProcessTree; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; +import java.util.Arrays; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; public class ContainersMonitorImpl extends AbstractService implements ContainersMonitor { @@ -447,6 +447,16 @@ public void run() { containerMetricsUnregisterDelayMs); usageMetrics.recordProcessId(pId); } + Container container = context.getContainers().get(containerId); + String[] ipAndHost = containerExecutor.getIpAndHost(container); + if (ipAndHost != null && ipAndHost.length == 2) { + container.setIpAndHost(ipAndHost); + LOG.info(containerId + "'s ip = " + ipAndHost[0] + + ", and hostname = " + ipAndHost[1]); + } else { + LOG.info("Can not get both ip and hostname: " + Arrays + .toString(ipAndHost)); + } } } // End of initializing any uninitialized processTrees diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/runtime/ContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/runtime/ContainerRuntime.java index e05f3fc..89278d7 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/runtime/ContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/runtime/ContainerRuntime.java @@ -22,6 +22,8 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; /** An abstraction for various container runtime implementations. Examples * include Process Tree, Docker, Appc runtimes etc., These implementations @@ -47,4 +49,9 @@ void signalContainer(ContainerRuntimeContext ctx) /** Any container cleanup that may be required. */ void reapContainer(ContainerRuntimeContext ctx) throws ContainerExecutionException; + + void setHostFilePath(Container container, Path path); + + /** Return the host and ip of the container */ + String[] getIpAndHost(Container container); } \ No newline at end of file diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c index e40101c..9a813f8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c @@ -219,11 +219,8 @@ static int write_pid_to_cgroup_as_root(const char* cgroup_file, pid_t pid) { return 0; } -/** - * Write the pid of the current process into the pid file. - * pid_file: Path to pid file where pid needs to be written to - */ -static int write_pid_to_file_as_nm(const char* pid_file, pid_t pid) { + +static int write_file_as_nm(const char* file, char* content) { uid_t user = geteuid(); gid_t group = getegid(); if (change_effective_user(nm_uid, nm_gid) != 0) { @@ -232,53 +229,74 @@ static int write_pid_to_file_as_nm(const char* pid_file, pid_t pid) { return -1; } - char *temp_pid_file = concatenate("%s.tmp", "pid_file_path", 1, pid_file); - fprintf(LOGFILE, "Writing to tmp file %s\n", temp_pid_file); + char *temp_file = concatenate("%s.tmp", "tmp_file_path", 1, file); + fprintf(LOGFILE, "Writing to tmp file %s\n", temp_file); fflush(LOGFILE); // create with 700 - int pid_fd = open(temp_pid_file, O_WRONLY|O_CREAT|O_EXCL, S_IRWXU); - if (pid_fd == -1) { - fprintf(LOGFILE, "Can't open file %s as node manager - %s\n", temp_pid_file, + int fd = open(temp_file, O_WRONLY|O_CREAT|O_EXCL, S_IRWXU); + if (fd == -1) { + fprintf(LOGFILE, "Can't open file %s as node manager - %s\n", temp_file, strerror(errno)); fflush(LOGFILE); - free(temp_pid_file); + free(temp_file); return -1; } - // write pid to temp file - char pid_buf[21]; - snprintf(pid_buf, 21, "%" PRId64, (int64_t)pid); - ssize_t written = write(pid_fd, pid_buf, strlen(pid_buf)); - close(pid_fd); + // write content to temp file + ssize_t written = write(fd, content, strlen(content)); + close(fd); if (written == -1) { - fprintf(LOGFILE, "Failed to write pid to file %s as node manager - %s\n", - temp_pid_file, strerror(errno)); + fprintf(LOGFILE, "Failed to write content to tmp file %s as node manager - %s\n", + temp_file, strerror(errno)); fflush(LOGFILE); - free(temp_pid_file); + free(temp_file); return -1; } // rename temp file to actual pid file // use rename as atomic - if (rename(temp_pid_file, pid_file)) { - fprintf(LOGFILE, "Can't move pid file from %s to %s as node manager - %s\n", - temp_pid_file, pid_file, strerror(errno)); + + if (rename(temp_file, file)) { + fprintf(LOGFILE, "Can't rename file from %s to %s as node manager - %s\n", + temp_file, file, strerror(errno)); fflush(LOGFILE); - unlink(temp_pid_file); - free(temp_pid_file); + unlink(temp_file); + free(temp_file); return -1; } - + fprintf(LOGFILE, "Renamed file from %s to %s as node manager\n", temp_file, file); // Revert back to the calling user. if (change_effective_user(user, group)) { - free(temp_pid_file); + free(temp_file); return -1; } - free(temp_pid_file); + free(temp_file); return 0; } + +/** + * Write the pid of the current process into the pid file. + * pid_file: Path to pid file where pid needs to be written to + */ +static int write_pid_to_file_as_nm(const char* pid_file, pid_t pid) { + // write pid to temp file + char pid_buf[21]; + snprintf(pid_buf, 21, "%" PRId64, (int64_t)pid); + fprintf(LOGFILE, "Write (pid=%s) to %s as nm \n", pid_buf, pid_file); + return write_file_as_nm(pid_file, pid_buf); +} + +/** + * Write ip and host of docker container into the host file. + */ +static int write_ip_host_to_file_as_nm(const char* host_file, char* ip, char* host) { + char * ipAndHost = concatenate("%s %s", "ip_host", 2, ip, host); + fprintf(LOGFILE, "Write (ip = %s), (hostname = %s) to %s as nm \n", ip, host, host_file); + return write_file_as_nm(host_file, ipAndHost); +} + /** * Write the exit code of the container into the exit code file * exit_code_file: Path to exit code file where exit code needs to be written @@ -1236,7 +1254,8 @@ int launch_docker_container_as_user(const char * user, const char *app_id, const char *pid_file, char* const* local_dirs, char* const* log_dirs, const char *command_file, const char *resources_key, - char* const* resources_values) { + char* const* resources_values, + const char *host_file) { int exit_code = -1; char *script_file_dest = NULL; char *cred_file_dest = NULL; @@ -1299,25 +1318,29 @@ int launch_docker_container_as_user(const char * user, const char *app_id, snprintf(docker_command_with_binary, EXECUTOR_PATH_MAX, "%s %s", docker_binary, docker_command); - fprintf(LOGFILE, "Launching docker container...\n"); + fprintf(LOGFILE, "Launching docker container...%s\n", docker_command_with_binary); FILE* start_docker = popen(docker_command_with_binary, "r"); if (pclose (start_docker) != 0) { fprintf (ERRORFILE, - "Could not invoke docker %s.\n", docker_command_with_binary); + "Could not invoke: %s \n", docker_command_with_binary); fflush(ERRORFILE); exit_code = UNABLE_TO_EXECUTE_CONTAINER_SCRIPT; goto cleanup; } snprintf(docker_inspect_command, EXECUTOR_PATH_MAX, - "%s inspect --format {{.State.Pid}} %s", + "%s inspect --format '{{.State.Pid}} {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} {{.Config.Hostname}}' %s", docker_binary, container_id); - fprintf(LOGFILE, "Inspecting docker container...\n"); + fprintf(LOGFILE, "Inspecting docker container...%s \n", docker_inspect_command); FILE* inspect_docker = popen(docker_inspect_command, "r"); int pid = 0; - int res = fscanf (inspect_docker, "%d", &pid); + char *ip = malloc(EXECUTOR_PATH_MAX); + char *hostname = malloc(EXECUTOR_PATH_MAX); + + int res = fscanf (inspect_docker, "%d %s %s", &pid, ip, hostname); + fprintf(LOGFILE, "Inspected docker pid=%d, ip=%s, hostname=%s \n", pid, ip, hostname); if (pclose (inspect_docker) != 0 || res <= 0) { fprintf (ERRORFILE, @@ -1327,6 +1350,21 @@ int launch_docker_container_as_user(const char * user, const char *app_id, goto cleanup; } + if (strlen(ip) == 0) { + fprintf(ERRORFILE, "Could not inspect docker to get ip %s.\n", docker_inspect_command); + fflush(ERRORFILE); + } + if (strlen(hostname) == 0) { + fprintf(ERRORFILE, "Could not inspect docker to get hostname %s.\n", docker_inspect_command); + fflush(ERRORFILE); + } + + if (strlen(ip) > 0 && strlen(hostname) > 0) { + write_ip_host_to_file_as_nm(host_file, ip, hostname); + } + free(ip); + free(hostname); + if (pid != 0) { fprintf(LOGFILE, "Writing to cgroup task files...\n"); // cgroups-based resource enforcement @@ -1412,7 +1450,7 @@ int launch_docker_container_as_user(const char * user, const char *app_id, cleanup: //clean up docker command file unlink(command_file); - + unlink(host_file); if (exit_code_file != NULL && write_exit_code_file_as_nm(exit_code_file, exit_code) < 0) { fprintf (ERRORFILE, "Could not write exit code to file %s.\n", exit_code_file); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h index df5b7d8..7482bbf 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h @@ -133,7 +133,8 @@ int launch_docker_container_as_user(const char * user, const char *app_id, const char *pid_file, char* const* local_dirs, char* const* log_dirs, const char *command_file,const char *resources_key, - char* const* resources_values); + char* const* resources_values, + const char *host_file); /* * Function used to launch a container as the provided user. It does the following : diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c index 222467a..3d21d9e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c @@ -160,6 +160,7 @@ static struct { const char * script_file; const char * current_dir; const char * pid_file; + const char * host_file; const char *dir_to_be_deleted; int container_pid; int signal; @@ -314,8 +315,9 @@ static int validate_run_as_user_commands(int argc, char **argv, int *operation) free(resources_value); return INVALID_ARGUMENT_NUMBER; } + cmd_input.host_file = argv[optind++]; //network isolation through tc - if (argc == 15) { + if (argc == 16) { cmd_input.traffic_control_command_file = argv[optind++]; } @@ -483,7 +485,8 @@ int main(int argc, char **argv) { extract_values(cmd_input.log_dirs), cmd_input.docker_command_file, cmd_input.resources_key, - cmd_input.resources_values); + cmd_input.resources_values, + cmd_input.host_file); break; case RUN_AS_USER_LAUNCH_CONTAINER: if (cmd_input.traffic_control_command_file != NULL) { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java index a29b174..0676633 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java @@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileUtil; +import org.apache.hadoop.fs.FileContext; import org.apache.hadoop.fs.Path; import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerLaunchContext; @@ -45,6 +46,7 @@ import org.mockito.Mockito; import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; @@ -82,6 +84,7 @@ private Path nmPrivateContainerScriptPath; private Path nmPrivateTokensPath; private Path pidFilePath; + private Path hostFilePath; private List localDirs; private List logDirs; private List filecacheDirs; @@ -129,6 +132,7 @@ public void setup() { nmPrivateContainerScriptPath = new Path("/test_script_path"); nmPrivateTokensPath = new Path("/test_private_tokens_path"); pidFilePath = new Path("/test_pid_file_path"); + hostFilePath = new Path("/host_file_path"); localDirs = new ArrayList<>(); logDirs = new ArrayList<>(); filecacheDirs = new ArrayList<>(); @@ -210,8 +214,8 @@ private PrivilegedOperation capturePrivilegedOperation() } @SuppressWarnings("unchecked") - private PrivilegedOperation capturePrivilegedOperationAndVerifyArgs() - throws PrivilegedOperationException { + private PrivilegedOperation capturePrivilegedOperationAndVerifyArgs( + boolean hasHostFile) throws PrivilegedOperationException { PrivilegedOperation op = capturePrivilegedOperation(); @@ -222,8 +226,12 @@ private PrivilegedOperation capturePrivilegedOperationAndVerifyArgs() //This invocation of container-executor should use 13 arguments in a // specific order (sigh.) - Assert.assertEquals(13, args.size()); - + if (hasHostFile) { + Assert.assertEquals(14, args.size()); + Assert.assertEquals(hostFilePath.toString(), args.get(13)); + } else { + Assert.assertEquals(13, args.size()); + } //verify arguments Assert.assertEquals(runAsUser, args.get(0)); Assert.assertEquals(user, args.get(1)); @@ -257,19 +265,42 @@ private String getExpectedTestCapabilitiesArgumentString() { return expectedCapabilitiesString.toString(); } + private File writeIpAndHost() throws IOException { + File tmpDir = new File("target", this.getClass().getSimpleName() + "-tmpDir"); + tmpDir.mkdirs(); + hostFilePath = new Path(tmpDir.getAbsolutePath(), "host_file"); + FileWriter ipHostWriter = new FileWriter(hostFilePath.toString()); + ipHostWriter.write("127.0.0.1 localhost"); + ipHostWriter.close(); + return tmpDir; + } + + private void verifyIpAndHost(DockerLinuxContainerRuntime runtime, File tmpDir) + throws IOException { + String[] ipAndHost = runtime.getIpAndHost(container); + Assert.assertEquals("127.0.0.1", ipAndHost[0]); + Assert.assertEquals("localhost", ipAndHost[1]); + FileContext localFS = FileContext.getLocalFSFileContext(); + localFS.delete(new Path(tmpDir.getAbsolutePath()), true); + } + @Test public void testDockerContainerLaunch() throws ContainerExecutionException, PrivilegedOperationException, IOException { DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime( mockExecutor, mockCGroupsHandler); + File tmpDir = writeIpAndHost(); + runtime.setHostFilePath(container, hostFilePath); + runtime.initialize(conf); runtime.launchContainer(builder.build()); - - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(true); List args = op.getArguments(); String dockerCommandFile = args.get(11); + verifyIpAndHost(runtime, tmpDir); + //This is the expected docker invocation for this case StringBuffer expectedCommandTemplate = new StringBuffer("run --name=%1$s ") .append("--user=%2$s -d ") @@ -372,7 +403,7 @@ public void testContainerLaunchWithNetworkingDefaults() //this should cause no failures. runtime.launchContainer(builder.build()); - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(false); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -426,7 +457,7 @@ public void testContainerLaunchWithCustomNetworks() //this should cause no failures. runtime.initialize(conf); runtime.launchContainer(builder.build()); - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(false); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -463,7 +494,7 @@ public void testContainerLaunchWithCustomNetworks() customNetwork2); runtime.launchContainer(builder.build()); - op = capturePrivilegedOperationAndVerifyArgs(); + op = capturePrivilegedOperationAndVerifyArgs(false); args = op.getArguments(); dockerCommandFile = args.get(11); @@ -516,7 +547,7 @@ public void testLaunchPrivilegedContainersInvalidEnvVar() "invalid-value"); runtime.launchContainer(builder.build()); - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(false); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -624,7 +655,7 @@ public void testLaunchPrivilegedContainersWithEnabledSettingAndDefaultACL() "true"); runtime.launchContainer(builder.build()); - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(false); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -719,7 +750,7 @@ public void testMountSourceTarget() "test_dir/test_resource_file:test_mount"); runtime.launchContainer(builder.build()); - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(false); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -771,7 +802,7 @@ public void testMountMultiple() "test_dir/test_resource_file:test_mount2"); runtime.launchContainer(builder.build()); - PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(false); List args = op.getArguments(); String dockerCommandFile = args.get(11); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MockContainer.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MockContainer.java index b21ba4b..7513fdf 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MockContainer.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/webapp/MockContainer.java @@ -174,7 +174,13 @@ public String getLogDir() { public void setLogDir(String logDir) { } + @Override public Priority getPriority() { return Priority.UNDEFINED; } + + @Override + public void setIpAndHost(String[] ipAndHost) { + + } }