YARN-4253. Standardize on using PrivilegedOperationExecutor for all invocations of container-executor in LinuxContainerExecutor. Contributed by Sidharta Seethana.
This commit is contained in:
parent
2a98724342
commit
8d59293089
@ -931,6 +931,9 @@ Release 2.8.0 - UNRELEASED
|
||||
|
||||
YARN-4017. container-executor overuses PATH_MAX. (Sidharta Seethana via vvasudev)
|
||||
|
||||
YARN-4253. Standardize on using PrivilegedOperationExecutor for all
|
||||
invocations of container-executor in LinuxContainerExecutor. (Sidharta Seethana via vvasudev)
|
||||
|
||||
Release 2.7.2 - UNRELEASED
|
||||
|
||||
INCOMPATIBLE CHANGES
|
||||
|
@ -26,8 +26,6 @@
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
import org.apache.hadoop.util.ReflectionUtils;
|
||||
import org.apache.hadoop.util.Shell.ExitCodeException;
|
||||
import org.apache.hadoop.util.Shell.ShellCommandExecutor;
|
||||
import org.apache.hadoop.util.StringUtils;
|
||||
import org.apache.hadoop.yarn.api.ApplicationConstants;
|
||||
import org.apache.hadoop.yarn.api.records.ContainerId;
|
||||
@ -78,7 +76,6 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||
|
||||
private String nonsecureLocalUser;
|
||||
private Pattern nonsecureLocalUserPattern;
|
||||
private String containerExecutorExe;
|
||||
private LCEResourcesHandler resourcesHandler;
|
||||
private boolean containerSchedPriorityIsSet = false;
|
||||
private int containerSchedPriorityAdjustment = 0;
|
||||
@ -97,14 +94,14 @@ public LinuxContainerExecutor(LinuxContainerRuntime linuxContainerRuntime) {
|
||||
@Override
|
||||
public void setConf(Configuration conf) {
|
||||
super.setConf(conf);
|
||||
containerExecutorExe = getContainerExecutorExecutablePath(conf);
|
||||
|
||||
resourcesHandler = ReflectionUtils.newInstance(
|
||||
conf.getClass(YarnConfiguration.NM_LINUX_CONTAINER_RESOURCES_HANDLER,
|
||||
DefaultLCEResourcesHandler.class, LCEResourcesHandler.class), conf);
|
||||
resourcesHandler.setConf(conf);
|
||||
|
||||
if (conf.get(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY) != null) {
|
||||
if (conf.get(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY)
|
||||
!= null) {
|
||||
containerSchedPriorityIsSet = true;
|
||||
containerSchedPriorityAdjustment = conf
|
||||
.getInt(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY,
|
||||
@ -150,7 +147,8 @@ protected String getContainerExecutorExecutablePath(Configuration conf) {
|
||||
new File(hadoopBin, "container-executor").getAbsolutePath();
|
||||
return null == conf
|
||||
? defaultPath
|
||||
: conf.get(YarnConfiguration.NM_LINUX_CONTAINER_EXECUTOR_PATH, defaultPath);
|
||||
: conf.get(YarnConfiguration.NM_LINUX_CONTAINER_EXECUTOR_PATH,
|
||||
defaultPath);
|
||||
}
|
||||
|
||||
protected void addSchedPriorityCommand(List<String> command) {
|
||||
@ -162,29 +160,27 @@ protected void addSchedPriorityCommand(List<String> command) {
|
||||
|
||||
@Override
|
||||
public void init() throws IOException {
|
||||
Configuration conf = super.getConf();
|
||||
|
||||
// Send command to executor which will just start up,
|
||||
// verify configuration/permissions and exit
|
||||
List<String> command = new ArrayList<String>(
|
||||
Arrays.asList(containerExecutorExe,
|
||||
"--checksetup"));
|
||||
String[] commandArray = command.toArray(new String[command.size()]);
|
||||
ShellCommandExecutor shExec = new ShellCommandExecutor(commandArray);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("checkLinuxExecutorSetup: " + Arrays.toString(commandArray));
|
||||
}
|
||||
try {
|
||||
shExec.execute();
|
||||
} catch (ExitCodeException e) {
|
||||
int exitCode = shExec.getExitCode();
|
||||
PrivilegedOperation checkSetupOp = new PrivilegedOperation(
|
||||
PrivilegedOperation.OperationType.CHECK_SETUP, (String) null);
|
||||
PrivilegedOperationExecutor privilegedOperationExecutor =
|
||||
PrivilegedOperationExecutor.getInstance(conf);
|
||||
|
||||
privilegedOperationExecutor.executePrivilegedOperation(checkSetupOp,
|
||||
false);
|
||||
} catch (PrivilegedOperationException e) {
|
||||
int exitCode = e.getExitCode();
|
||||
LOG.warn("Exit code from container executor initialization is : "
|
||||
+ exitCode, e);
|
||||
logOutput(shExec.getOutput());
|
||||
|
||||
throw new IOException("Linux container executor not configured properly"
|
||||
+ " (error=" + exitCode + ")", e);
|
||||
}
|
||||
|
||||
Configuration conf = super.getConf();
|
||||
|
||||
try {
|
||||
resourceHandlerChain = ResourceHandlerModule
|
||||
.getConfiguredResourceHandlerChain(conf);
|
||||
@ -193,7 +189,8 @@ public void init() throws IOException {
|
||||
}
|
||||
} catch (ResourceHandlerException e) {
|
||||
LOG.error("Failed to bootstrap configured resource subsystems! ", e);
|
||||
throw new IOException("Failed to bootstrap configured resource subsystems!");
|
||||
throw new IOException(
|
||||
"Failed to bootstrap configured resource subsystems!");
|
||||
}
|
||||
|
||||
try {
|
||||
@ -224,47 +221,56 @@ public void startLocalizer(LocalizerStartContext ctx)
|
||||
|
||||
verifyUsernamePattern(user);
|
||||
String runAsUser = getRunAsUser(user);
|
||||
List<String> command = new ArrayList<String>();
|
||||
addSchedPriorityCommand(command);
|
||||
command.addAll(Arrays.asList(containerExecutorExe,
|
||||
PrivilegedOperation initializeContainerOp = new PrivilegedOperation(
|
||||
PrivilegedOperation.OperationType.INITIALIZE_CONTAINER, (String) null);
|
||||
List<String> prefixCommands = new ArrayList<>();
|
||||
|
||||
addSchedPriorityCommand(prefixCommands);
|
||||
initializeContainerOp.appendArgs(
|
||||
runAsUser,
|
||||
user,
|
||||
Integer.toString(PrivilegedOperation.RunAsUserCommand.INITIALIZE_CONTAINER.getValue()),
|
||||
Integer.toString(
|
||||
PrivilegedOperation.RunAsUserCommand.INITIALIZE_CONTAINER
|
||||
.getValue()),
|
||||
appId,
|
||||
nmPrivateContainerTokensPath.toUri().getPath().toString(),
|
||||
StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
|
||||
localDirs),
|
||||
StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR,
|
||||
logDirs)));
|
||||
logDirs));
|
||||
|
||||
File jvm = // use same jvm as parent
|
||||
new File(new File(System.getProperty("java.home"), "bin"), "java");
|
||||
command.add(jvm.toString());
|
||||
command.add("-classpath");
|
||||
command.add(System.getProperty("java.class.path"));
|
||||
initializeContainerOp.appendArgs(jvm.toString());
|
||||
initializeContainerOp.appendArgs("-classpath");
|
||||
initializeContainerOp.appendArgs(System.getProperty("java.class.path"));
|
||||
String javaLibPath = System.getProperty("java.library.path");
|
||||
if (javaLibPath != null) {
|
||||
command.add("-Djava.library.path=" + javaLibPath);
|
||||
}
|
||||
command.addAll(ContainerLocalizer.getJavaOpts(getConf()));
|
||||
buildMainArgs(command, user, appId, locId, nmAddr, localDirs);
|
||||
String[] commandArray = command.toArray(new String[command.size()]);
|
||||
ShellCommandExecutor shExec = new ShellCommandExecutor(commandArray);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("initApplication: " + Arrays.toString(commandArray));
|
||||
initializeContainerOp.appendArgs("-Djava.library.path=" + javaLibPath);
|
||||
}
|
||||
|
||||
initializeContainerOp.appendArgs(ContainerLocalizer.getJavaOpts(getConf()));
|
||||
|
||||
List<String> localizerArgs = new ArrayList<>();
|
||||
|
||||
buildMainArgs(localizerArgs, user, appId, locId, nmAddr, localDirs);
|
||||
initializeContainerOp.appendArgs(localizerArgs);
|
||||
|
||||
try {
|
||||
shExec.execute();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
logOutput(shExec.getOutput());
|
||||
}
|
||||
} catch (ExitCodeException e) {
|
||||
int exitCode = shExec.getExitCode();
|
||||
Configuration conf = super.getConf();
|
||||
PrivilegedOperationExecutor privilegedOperationExecutor =
|
||||
PrivilegedOperationExecutor.getInstance(conf);
|
||||
|
||||
privilegedOperationExecutor.executePrivilegedOperation(prefixCommands,
|
||||
initializeContainerOp, null, null, false);
|
||||
|
||||
} catch (PrivilegedOperationException e) {
|
||||
int exitCode = e.getExitCode();
|
||||
LOG.warn("Exit code from container " + locId + " startLocalizer is : "
|
||||
+ exitCode, e);
|
||||
logOutput(shExec.getOutput());
|
||||
|
||||
throw new IOException("Application " + appId + " initialization failed" +
|
||||
" (exitCode=" + exitCode + ") with output: " + shExec.getOutput(), e);
|
||||
" (exitCode=" + exitCode + ") with output: " + e.getOutput(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,8 +313,8 @@ public int launchContainer(ContainerStartContext ctx) throws IOException {
|
||||
if (ops != null) {
|
||||
List<PrivilegedOperation> resourceOps = new ArrayList<>();
|
||||
|
||||
resourceOps.add(new PrivilegedOperation
|
||||
(PrivilegedOperation.OperationType.ADD_PID_TO_CGROUP,
|
||||
resourceOps.add(new PrivilegedOperation(
|
||||
PrivilegedOperation.OperationType.ADD_PID_TO_CGROUP,
|
||||
resourcesOptions));
|
||||
|
||||
for (PrivilegedOperation op : ops) {
|
||||
@ -333,7 +339,8 @@ public int launchContainer(ContainerStartContext ctx) throws IOException {
|
||||
resourcesOptions = operation.getArguments().get(0);
|
||||
} catch (PrivilegedOperationException e) {
|
||||
LOG.error("Failed to squash cgroup operations!", e);
|
||||
throw new ResourceHandlerException("Failed to squash cgroup operations!");
|
||||
throw new ResourceHandlerException(
|
||||
"Failed to squash cgroup operations!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,7 +383,8 @@ public int launchContainer(ContainerStartContext ctx) throws IOException {
|
||||
|
||||
linuxContainerRuntime.launchContainer(builder.build());
|
||||
} else {
|
||||
LOG.info("Container was marked as inactive. Returning terminated error");
|
||||
LOG.info(
|
||||
"Container was marked as inactive. Returning terminated error");
|
||||
return ExitCode.TERMINATED.getExitCode();
|
||||
}
|
||||
} catch (ContainerExecutionException e) {
|
||||
@ -481,7 +489,8 @@ public boolean signalContainer(ContainerSignalContext ctx)
|
||||
linuxContainerRuntime.signalContainer(runtimeContext);
|
||||
} catch (ContainerExecutionException e) {
|
||||
int retCode = e.getExitCode();
|
||||
if (retCode == PrivilegedOperation.ResultCode.INVALID_CONTAINER_PID.getValue()) {
|
||||
if (retCode == PrivilegedOperation.ResultCode.INVALID_CONTAINER_PID
|
||||
.getValue()) {
|
||||
return false;
|
||||
}
|
||||
LOG.warn("Error in signalling container " + pid + " with " + signal
|
||||
@ -501,17 +510,20 @@ public void deleteAsUser(DeletionAsUserContext ctx) {
|
||||
List<Path> baseDirs = ctx.getBasedirs();
|
||||
|
||||
verifyUsernamePattern(user);
|
||||
String runAsUser = getRunAsUser(user);
|
||||
|
||||
String runAsUser = getRunAsUser(user);
|
||||
String dirString = dir == null ? "" : dir.toUri().getPath();
|
||||
|
||||
List<String> command = new ArrayList<String>(
|
||||
Arrays.asList(containerExecutorExe,
|
||||
PrivilegedOperation deleteAsUserOp = new PrivilegedOperation(
|
||||
PrivilegedOperation.OperationType.DELETE_AS_USER, (String) null);
|
||||
|
||||
deleteAsUserOp.appendArgs(
|
||||
runAsUser,
|
||||
user,
|
||||
Integer.toString(PrivilegedOperation.
|
||||
RunAsUserCommand.DELETE_AS_USER.getValue()),
|
||||
dirString));
|
||||
dirString);
|
||||
|
||||
List<String> pathsToDelete = new ArrayList<String>();
|
||||
if (baseDirs == null || baseDirs.size() == 0) {
|
||||
LOG.info("Deleting absolute path : " + dir);
|
||||
@ -521,25 +533,21 @@ public void deleteAsUser(DeletionAsUserContext ctx) {
|
||||
Path del = dir == null ? baseDir : new Path(baseDir, dir);
|
||||
LOG.info("Deleting path : " + del);
|
||||
pathsToDelete.add(del.toString());
|
||||
command.add(baseDir.toUri().getPath());
|
||||
deleteAsUserOp.appendArgs(baseDir.toUri().getPath());
|
||||
}
|
||||
}
|
||||
String[] commandArray = command.toArray(new String[command.size()]);
|
||||
ShellCommandExecutor shExec = new ShellCommandExecutor(commandArray);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("deleteAsUser: " + Arrays.toString(commandArray));
|
||||
}
|
||||
|
||||
try {
|
||||
shExec.execute();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
logOutput(shExec.getOutput());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
int exitCode = shExec.getExitCode();
|
||||
Configuration conf = super.getConf();
|
||||
PrivilegedOperationExecutor privilegedOperationExecutor =
|
||||
PrivilegedOperationExecutor.getInstance(conf);
|
||||
|
||||
privilegedOperationExecutor.executePrivilegedOperation(deleteAsUserOp,
|
||||
false);
|
||||
} catch (PrivilegedOperationException e) {
|
||||
int exitCode = e.getExitCode();
|
||||
LOG.error("DeleteAsUser for " + StringUtils.join(" ", pathsToDelete)
|
||||
+ " returned with exit code: " + exitCode, e);
|
||||
LOG.error("Output from LinuxContainerExecutor's deleteAsUser follows:");
|
||||
logOutput(shExec.getOutput());
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,25 +569,24 @@ public boolean isContainerAlive(ContainerLivenessContext ctx)
|
||||
|
||||
public void mountCgroups(List<String> cgroupKVs, String hierarchy)
|
||||
throws IOException {
|
||||
List<String> command = new ArrayList<String>(
|
||||
Arrays.asList(containerExecutorExe, "--mount-cgroups", hierarchy));
|
||||
command.addAll(cgroupKVs);
|
||||
|
||||
String[] commandArray = command.toArray(new String[command.size()]);
|
||||
ShellCommandExecutor shExec = new ShellCommandExecutor(commandArray);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("mountCgroups: " + Arrays.toString(commandArray));
|
||||
}
|
||||
|
||||
try {
|
||||
shExec.execute();
|
||||
} catch (IOException e) {
|
||||
int ret_code = shExec.getExitCode();
|
||||
PrivilegedOperation mountCGroupsOp = new PrivilegedOperation(
|
||||
PrivilegedOperation.OperationType.MOUNT_CGROUPS, hierarchy);
|
||||
Configuration conf = super.getConf();
|
||||
|
||||
mountCGroupsOp.appendArgs(cgroupKVs);
|
||||
PrivilegedOperationExecutor privilegedOperationExecutor =
|
||||
PrivilegedOperationExecutor.getInstance(conf);
|
||||
|
||||
privilegedOperationExecutor.executePrivilegedOperation(mountCGroupsOp,
|
||||
false);
|
||||
} catch (PrivilegedOperationException e) {
|
||||
int exitCode = e.getExitCode();
|
||||
LOG.warn("Exception in LinuxContainerExecutor mountCgroups ", e);
|
||||
logOutput(shExec.getOutput());
|
||||
|
||||
throw new IOException("Problem mounting cgroups " + cgroupKVs +
|
||||
"; exit code = " + ret_code + " and output: " + shExec.getOutput(), e);
|
||||
"; exit code = " + exitCode + " and output: " + e.getOutput(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user