Skip to content

Commit

Permalink
YARN-7677. Docker image cannot set HADOOP_CONF_DIR. Contributed by Ji…
Browse files Browse the repository at this point in the history
…m Brennan
  • Loading branch information
jlowe committed Jan 31, 2018
1 parent d481344 commit 12eaae3
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 66 deletions.
Expand Up @@ -346,7 +346,6 @@ public void writeLaunchEnv(OutputStream out, Map<String, String> environment,
public void writeLaunchEnv(OutputStream out, Map<String, String> environment,
Map<Path, List<String>> resources, List<String> command, Path logDir,
String user, String outFilename) throws IOException {
updateEnvForWhitelistVars(environment);

ContainerLaunch.ShellScriptBuilder sb =
ContainerLaunch.ShellScriptBuilder.create();
Expand All @@ -364,6 +363,19 @@ public void writeLaunchEnv(OutputStream out, Map<String, String> environment,
for (Map.Entry<String, String> env : environment.entrySet()) {
sb.env(env.getKey(), env.getValue());
}
// Whitelist environment variables are treated specially.
// Only add them if they are not already defined in the environment.
// Add them using special syntax to prevent them from eclipsing
// variables that may be set explicitly in the container image (e.g,
// in a docker image)
for(String var : whitelistVars) {
if (!environment.containsKey(var)) {
String val = getNMEnvVar(var);
if (val != null) {
sb.whitelistedEnv(var, val);
}
}
}
}

if (resources != null) {
Expand Down Expand Up @@ -663,23 +675,6 @@ protected boolean isContainerActive(ContainerId containerId) {
}
}

/**
* Propagate variables from the nodemanager's environment into the
* container's environment if unspecified by the container.
* @param env the environment to update
* @see org.apache.hadoop.yarn.conf.YarnConfiguration#NM_ENV_WHITELIST
*/
protected void updateEnvForWhitelistVars(Map<String, String> env) {
for(String var : whitelistVars) {
if (!env.containsKey(var)) {
String val = getNMEnvVar(var);
if (val != null) {
env.put(var, val);
}
}
}
}

@VisibleForTesting
protected String getNMEnvVar(String varname) {
return System.getenv(varname);
Expand Down
Expand Up @@ -66,7 +66,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*;
Expand Down Expand Up @@ -472,13 +471,6 @@ public void prepareContainer(ContainerPrepareContext ctx) throws IOException {
}
}

@Override
protected void updateEnvForWhitelistVars(Map<String, String> env) {
if (linuxContainerRuntime.useWhitelistEnv(env)) {
super.updateEnvForWhitelistVars(env);
}
}

@Override
public int launchContainer(ContainerStartContext ctx)
throws IOException, ConfigurationException {
Expand Down
Expand Up @@ -1135,6 +1135,9 @@ public final void stderr(Path stderrDir, String stdErrFile) throws IOException {

public abstract void env(String key, String value) throws IOException;

public abstract void whitelistedEnv(String key, String value)
throws IOException;

public abstract void echo(String echoStr) throws IOException;

public final void symlink(Path src, Path dst) throws IOException {
Expand Down Expand Up @@ -1254,6 +1257,11 @@ public void env(String key, String value) throws IOException {
line("export ", key, "=\"", value, "\"");
}

@Override
public void whitelistedEnv(String key, String value) throws IOException {
line("export ", key, "=${", key, ":-", "\"", value, "\"}");
}

@Override
public void echo(final String echoStr) throws IOException {
line("echo \"" + echoStr + "\"");
Expand Down Expand Up @@ -1344,6 +1352,11 @@ public void env(String key, String value) throws IOException {
errorCheck();
}

@Override
public void whitelistedEnv(String key, String value) throws IOException {
env(key, value);
}

@Override
public void echo(final String echoStr) throws IOException {
lineWithLenCheck("@echo \"", echoStr, "\"");
Expand Down Expand Up @@ -1443,8 +1456,6 @@ public void sanitizeEnv(Map<String, String> environment, Path pwd,

environment.put(Environment.PWD.name(), pwd.toString());

putEnvIfAbsent(environment, Environment.HADOOP_CONF_DIR.name());

if (!Shell.WINDOWS) {
environment.put("JVM_PID", "$$");
}
Expand Down
Expand Up @@ -37,7 +37,6 @@
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*;

Expand Down Expand Up @@ -73,11 +72,6 @@ public void initialize(Configuration conf, Context nmContext)
this.conf = conf;
}

@Override
public boolean useWhitelistEnv(Map<String, String> env) {
return true;
}

@Override
public void prepareContainer(ContainerRuntimeContext ctx)
throws ContainerExecutionException {
Expand Down
Expand Up @@ -94,17 +94,6 @@ public void initialize(Configuration conf, Context nmContext)
}
}

@Override
public boolean useWhitelistEnv(Map<String, String> env) {
try {
LinuxContainerRuntime runtime = pickContainerRuntime(env);
return runtime.useWhitelistEnv(env);
} catch (ContainerExecutionException e) {
LOG.debug("Unable to determine runtime");
return false;
}
}

@VisibleForTesting
LinuxContainerRuntime pickContainerRuntime(
Map<String, String> environment) throws ContainerExecutionException {
Expand Down
Expand Up @@ -366,13 +366,6 @@ public Set<String> getCapabilities() {
return capabilities;
}

@Override
public boolean useWhitelistEnv(Map<String, String> env) {
// Avoid propagating nodemanager environment variables into the container
// so those variables can be picked up from the Docker image instead.
return false;
}

private String runDockerVolumeCommand(DockerVolumeCommand dockerVolumeCommand,
Container container) throws ContainerExecutionException {
try {
Expand Down
Expand Up @@ -24,8 +24,6 @@
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;

import java.util.Map;

/**
* An abstraction for various container runtime implementations. Examples
* include Process Tree, Docker, Appc runtimes etc. These implementations
Expand Down Expand Up @@ -85,13 +83,4 @@ void reapContainer(ContainerRuntimeContext ctx)
* and hostname
*/
String[] getIpAndHost(Container container) throws ContainerExecutionException;

/**
* Whether to propagate the whitelist of environment variables from the
* nodemanager environment into the container environment.
* @param env the container's environment variables
* @return true if whitelist variables should be propagated, false otherwise
* @see org.apache.hadoop.yarn.conf.YarnConfiguration#NM_ENV_WHITELIST
*/
boolean useWhitelistEnv(Map<String, String> env);
}
Expand Up @@ -337,7 +337,8 @@ protected String getNMEnvVar(String varname) {
Assert.assertFalse(shellContent.contains("HADOOP_HDFS_HOME"));
// Available in env and in whitelist
Assert.assertTrue(shellContent.contains(
"export HADOOP_YARN_HOME=\"nodemanager_yarn_home\""));
"export HADOOP_YARN_HOME=${HADOOP_YARN_HOME:-\"nodemanager_yarn_home\"}"
));
fos.flush();
fos.close();
}
Expand Down Expand Up @@ -382,9 +383,12 @@ protected String getNMEnvVar(String varname) {
// Whitelisted variable overridden by container
Assert.assertTrue(shellContent.contains(
"export HADOOP_MAPRED_HOME=\"/opt/hadoopbuild\""));
// Verify no whitelisted variables inherited from NM env
// Available in env but not in whitelist
Assert.assertFalse(shellContent.contains("HADOOP_HDFS_HOME"));
Assert.assertFalse(shellContent.contains("HADOOP_YARN_HOME"));
// Available in env and in whitelist
Assert.assertTrue(shellContent.contains(
"export HADOOP_YARN_HOME=${HADOOP_YARN_HOME:-\"nodemanager_yarn_home\"}"
));
fos.flush();
fos.close();
}
Expand Down

0 comments on commit 12eaae3

Please sign in to comment.