YARN-1253. Changes to LinuxContainerExecutor to run containers as a single dedicated user in non-secure mode. (rvs via tucu)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1529325 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8549c34917
commit
80c5bffc4b
|
@ -854,8 +854,10 @@ KVNO Timestamp Principal
|
||||||
| | The container process has the same Unix user as the NodeManager. |
|
| | The container process has the same Unix user as the NodeManager. |
|
||||||
*--------------------------------------+--------------------------------------+
|
*--------------------------------------+--------------------------------------+
|
||||||
| <<<LinuxContainerExecutor>>> | |
|
| <<<LinuxContainerExecutor>>> | |
|
||||||
| | Supported only on GNU/Linux, this executor runs the containers as the |
|
| | Supported only on GNU/Linux, this executor runs the containers as either the |
|
||||||
| | user who submitted the application. It requires all user accounts to be |
|
| | YARN user who submitted the application (when full security is enabled) or |
|
||||||
|
| | as a dedicated user (defaults to nobody) when full security is not enabled. |
|
||||||
|
| | When full security is enabled, this executor requires all user accounts to be |
|
||||||
| | created on the cluster nodes where the containers are launched. It uses |
|
| | created on the cluster nodes where the containers are launched. It uses |
|
||||||
| | a <setuid> executable that is included in the Hadoop distribution. |
|
| | a <setuid> executable that is included in the Hadoop distribution. |
|
||||||
| | The NodeManager uses this executable to launch and kill containers. |
|
| | The NodeManager uses this executable to launch and kill containers. |
|
||||||
|
|
|
@ -29,6 +29,9 @@ Release 2.3.0 - UNRELEASED
|
||||||
YARN-1010. FairScheduler: decouple container scheduling from nodemanager
|
YARN-1010. FairScheduler: decouple container scheduling from nodemanager
|
||||||
heartbeats. (Wei Yan via Sandy Ryza)
|
heartbeats. (Wei Yan via Sandy Ryza)
|
||||||
|
|
||||||
|
YARN-1253. Changes to LinuxContainerExecutor to run containers as a single
|
||||||
|
dedicated user in non-secure mode. (rvs via tucu)
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
|
|
||||||
YARN-905. Add state filters to nodes CLI (Wei Yan via Sandy Ryza)
|
YARN-905. Add state filters to nodes CLI (Wei Yan via Sandy Ryza)
|
||||||
|
|
|
@ -636,6 +636,26 @@ public class YarnConfiguration extends Configuration {
|
||||||
public static final String NM_LINUX_CONTAINER_GROUP =
|
public static final String NM_LINUX_CONTAINER_GROUP =
|
||||||
NM_PREFIX + "linux-container-executor.group";
|
NM_PREFIX + "linux-container-executor.group";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UNIX user that containers will run as when Linux-container-executor
|
||||||
|
* is used in nonsecure mode (a use case for this is using cgroups).
|
||||||
|
*/
|
||||||
|
public static final String NM_NONSECURE_MODE_LOCAL_USER_KEY = NM_PREFIX +
|
||||||
|
"linux-container-executor.nonsecure-mode.local-user";
|
||||||
|
|
||||||
|
public static final String DEFAULT_NM_NONSECURE_MODE_LOCAL_USER = "nobody";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The allowed pattern for UNIX user names enforced by
|
||||||
|
* Linux-container-executor when used in nonsecure mode (use case for this
|
||||||
|
* is using cgroups). The default value is taken from /usr/sbin/adduser
|
||||||
|
*/
|
||||||
|
public static final String NM_NONSECURE_MODE_USER_PATTERN_KEY = NM_PREFIX +
|
||||||
|
"linux-container-executor.nonsecure-mode.user-pattern";
|
||||||
|
|
||||||
|
public static final String DEFAULT_NM_NONSECURE_MODE_USER_PATTERN =
|
||||||
|
"^[_.A-Za-z0-9][-@_.A-Za-z0-9]{0,255}?[$]?$";
|
||||||
|
|
||||||
/** The type of resource enforcement to use with the
|
/** The type of resource enforcement to use with the
|
||||||
* linux container executor.
|
* linux container executor.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -727,6 +727,21 @@
|
||||||
<name>yarn.nodemanager.linux-container-executor.cgroups.mount-path</name>
|
<name>yarn.nodemanager.linux-container-executor.cgroups.mount-path</name>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<property>
|
||||||
|
<description>The UNIX user that containers will run as when Linux-container-executor
|
||||||
|
is used in nonsecure mode (a use case for this is using cgroups).</description>
|
||||||
|
<name>yarn.nodemanager.linux-container-executor.nonsecure-mode.local-user</name>
|
||||||
|
<value>nobody</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property>
|
||||||
|
<description>The allowed pattern for UNIX user names enforced by
|
||||||
|
Linux-container-executor when used in nonsecure mode (use case for this
|
||||||
|
is using cgroups). The default value is taken from /usr/sbin/adduser</description>
|
||||||
|
<name>yarn.nodemanager.linux-container-executor.nonsecure-mode.user-pattern</name>
|
||||||
|
<value>^[_.A-Za-z0-9][-@_.A-Za-z0-9]{0,255}?[$]?$</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
<property>
|
<property>
|
||||||
<description>T-file compression types used to compress aggregated logs.</description>
|
<description>T-file compression types used to compress aggregated logs.</description>
|
||||||
<name>yarn.nodemanager.log-aggregation.compression-type</name>
|
<name>yarn.nodemanager.log-aggregation.compression-type</name>
|
||||||
|
|
|
@ -24,11 +24,13 @@ import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.util.ReflectionUtils;
|
import org.apache.hadoop.util.ReflectionUtils;
|
||||||
import org.apache.hadoop.util.Shell.ExitCodeException;
|
import org.apache.hadoop.util.Shell.ExitCodeException;
|
||||||
import org.apache.hadoop.util.Shell.ShellCommandExecutor;
|
import org.apache.hadoop.util.Shell.ShellCommandExecutor;
|
||||||
|
@ -48,6 +50,8 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
private static final Log LOG = LogFactory
|
private static final Log LOG = LogFactory
|
||||||
.getLog(LinuxContainerExecutor.class);
|
.getLog(LinuxContainerExecutor.class);
|
||||||
|
|
||||||
|
private String nonsecureLocalUser;
|
||||||
|
private Pattern nonsecureLocalUserPattern;
|
||||||
private String containerExecutorExe;
|
private String containerExecutorExe;
|
||||||
private LCEResourcesHandler resourcesHandler;
|
private LCEResourcesHandler resourcesHandler;
|
||||||
private boolean containerSchedPriorityIsSet = false;
|
private boolean containerSchedPriorityIsSet = false;
|
||||||
|
@ -70,6 +74,24 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
.getInt(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY,
|
.getInt(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY,
|
||||||
YarnConfiguration.DEFAULT_NM_CONTAINER_EXECUTOR_SCHED_PRIORITY);
|
YarnConfiguration.DEFAULT_NM_CONTAINER_EXECUTOR_SCHED_PRIORITY);
|
||||||
}
|
}
|
||||||
|
nonsecureLocalUser = conf.get(
|
||||||
|
YarnConfiguration.NM_NONSECURE_MODE_LOCAL_USER_KEY,
|
||||||
|
YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER);
|
||||||
|
nonsecureLocalUserPattern = Pattern.compile(
|
||||||
|
conf.get(YarnConfiguration.NM_NONSECURE_MODE_USER_PATTERN_KEY,
|
||||||
|
YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_USER_PATTERN));
|
||||||
|
}
|
||||||
|
|
||||||
|
void verifyUsernamePattern(String user) {
|
||||||
|
if (!UserGroupInformation.isSecurityEnabled() &&
|
||||||
|
!nonsecureLocalUserPattern.matcher(user).matches()) {
|
||||||
|
throw new IllegalArgumentException("Invalid user name '" + user + "'," +
|
||||||
|
" it must match '" + nonsecureLocalUserPattern.pattern() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getRunAsUser(String user) {
|
||||||
|
return UserGroupInformation.isSecurityEnabled() ? user : nonsecureLocalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,9 +184,12 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
List<String> localDirs, List<String> logDirs)
|
List<String> localDirs, List<String> logDirs)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
verifyUsernamePattern(user);
|
||||||
|
String runAsUser = getRunAsUser(user);
|
||||||
List<String> command = new ArrayList<String>();
|
List<String> command = new ArrayList<String>();
|
||||||
addSchedPriorityCommand(command);
|
addSchedPriorityCommand(command);
|
||||||
command.addAll(Arrays.asList(containerExecutorExe,
|
command.addAll(Arrays.asList(containerExecutorExe,
|
||||||
|
runAsUser,
|
||||||
user,
|
user,
|
||||||
Integer.toString(Commands.INITIALIZE_CONTAINER.getValue()),
|
Integer.toString(Commands.INITIALIZE_CONTAINER.getValue()),
|
||||||
appId,
|
appId,
|
||||||
|
@ -218,6 +243,9 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
String user, String appId, Path containerWorkDir,
|
String user, String appId, Path containerWorkDir,
|
||||||
List<String> localDirs, List<String> logDirs) throws IOException {
|
List<String> localDirs, List<String> logDirs) throws IOException {
|
||||||
|
|
||||||
|
verifyUsernamePattern(user);
|
||||||
|
String runAsUser = getRunAsUser(user);
|
||||||
|
|
||||||
ContainerId containerId = container.getContainerId();
|
ContainerId containerId = container.getContainerId();
|
||||||
String containerIdStr = ConverterUtils.toString(containerId);
|
String containerIdStr = ConverterUtils.toString(containerId);
|
||||||
|
|
||||||
|
@ -234,7 +262,7 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
List<String> command = new ArrayList<String>();
|
List<String> command = new ArrayList<String>();
|
||||||
addSchedPriorityCommand(command);
|
addSchedPriorityCommand(command);
|
||||||
command.addAll(Arrays.asList(
|
command.addAll(Arrays.asList(
|
||||||
containerExecutorExe, user, Integer
|
containerExecutorExe, runAsUser, user, Integer
|
||||||
.toString(Commands.LAUNCH_CONTAINER.getValue()), appId,
|
.toString(Commands.LAUNCH_CONTAINER.getValue()), appId,
|
||||||
containerIdStr, containerWorkDir.toString(),
|
containerIdStr, containerWorkDir.toString(),
|
||||||
nmPrivateCotainerScriptPath.toUri().getPath().toString(),
|
nmPrivateCotainerScriptPath.toUri().getPath().toString(),
|
||||||
|
@ -293,8 +321,12 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
public boolean signalContainer(String user, String pid, Signal signal)
|
public boolean signalContainer(String user, String pid, Signal signal)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
|
verifyUsernamePattern(user);
|
||||||
|
String runAsUser = getRunAsUser(user);
|
||||||
|
|
||||||
String[] command =
|
String[] command =
|
||||||
new String[] { containerExecutorExe,
|
new String[] { containerExecutorExe,
|
||||||
|
runAsUser,
|
||||||
user,
|
user,
|
||||||
Integer.toString(Commands.SIGNAL_CONTAINER.getValue()),
|
Integer.toString(Commands.SIGNAL_CONTAINER.getValue()),
|
||||||
pid,
|
pid,
|
||||||
|
@ -322,8 +354,12 @@ public class LinuxContainerExecutor extends ContainerExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAsUser(String user, Path dir, Path... baseDirs) {
|
public void deleteAsUser(String user, Path dir, Path... baseDirs) {
|
||||||
|
verifyUsernamePattern(user);
|
||||||
|
String runAsUser = getRunAsUser(user);
|
||||||
|
|
||||||
List<String> command = new ArrayList<String>(
|
List<String> command = new ArrayList<String>(
|
||||||
Arrays.asList(containerExecutorExe,
|
Arrays.asList(containerExecutorExe,
|
||||||
|
runAsUser,
|
||||||
user,
|
user,
|
||||||
Integer.toString(Commands.DELETE_AS_USER.getValue()),
|
Integer.toString(Commands.DELETE_AS_USER.getValue()),
|
||||||
dir == null ? "" : dir.toUri().getPath()));
|
dir == null ? "" : dir.toUri().getPath()));
|
||||||
|
|
|
@ -407,7 +407,7 @@ static int create_container_directories(const char* user, const char *app_id,
|
||||||
const char *container_id, char* const* local_dir, char* const* log_dir, const char *work_dir) {
|
const char *container_id, char* const* local_dir, char* const* log_dir, const char *work_dir) {
|
||||||
// create dirs as 0750
|
// create dirs as 0750
|
||||||
const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP;
|
const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP;
|
||||||
if (app_id == NULL || container_id == NULL || user == NULL) {
|
if (app_id == NULL || container_id == NULL || user == NULL || user_detail == NULL || user_detail->pw_name == NULL) {
|
||||||
fprintf(LOGFILE,
|
fprintf(LOGFILE,
|
||||||
"Either app_id, container_id or the user passed is null.\n");
|
"Either app_id, container_id or the user passed is null.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -758,7 +758,7 @@ int initialize_app(const char *user, const char *app_id,
|
||||||
const char* nmPrivate_credentials_file,
|
const char* nmPrivate_credentials_file,
|
||||||
char* const* local_dirs, char* const* log_roots,
|
char* const* local_dirs, char* const* log_roots,
|
||||||
char* const* args) {
|
char* const* args) {
|
||||||
if (app_id == NULL || user == NULL) {
|
if (app_id == NULL || user == NULL || user_detail == NULL || user_detail->pw_name == NULL) {
|
||||||
fprintf(LOGFILE, "Either app_id is null or the user passed is null.\n");
|
fprintf(LOGFILE, "Either app_id is null or the user passed is null.\n");
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ void display_usage(FILE *stream) {
|
||||||
"Usage: container-executor --mount-cgroups "\
|
"Usage: container-executor --mount-cgroups "\
|
||||||
"hierarchy controller=path...\n");
|
"hierarchy controller=path...\n");
|
||||||
fprintf(stream,
|
fprintf(stream,
|
||||||
"Usage: container-executor user command command-args\n");
|
"Usage: container-executor user yarn-user command command-args\n");
|
||||||
fprintf(stream, "Commands:\n");
|
fprintf(stream, "Commands:\n");
|
||||||
fprintf(stream, " initialize container: %2d appid tokens " \
|
fprintf(stream, " initialize container: %2d appid tokens " \
|
||||||
"nm-local-dirs nm-log-dirs cmd app...\n", INITIALIZE_CONTAINER);
|
"nm-local-dirs nm-log-dirs cmd app...\n", INITIALIZE_CONTAINER);
|
||||||
|
@ -179,17 +179,28 @@ int main(int argc, char **argv) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this string is used for building pathnames, the
|
||||||
|
// process management is done based on the 'user_detail'
|
||||||
|
// global, which was set by 'set_user()' above
|
||||||
|
optind = optind + 1;
|
||||||
|
char *yarn_user_name = argv[optind];
|
||||||
|
if (yarn_user_name == NULL) {
|
||||||
|
fprintf(ERRORFILE, "Invalid yarn user name.\n");
|
||||||
|
return INVALID_USER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
optind = optind + 1;
|
optind = optind + 1;
|
||||||
command = atoi(argv[optind++]);
|
command = atoi(argv[optind++]);
|
||||||
|
|
||||||
fprintf(LOGFILE, "main : command provided %d\n",command);
|
fprintf(LOGFILE, "main : command provided %d\n",command);
|
||||||
fprintf(LOGFILE, "main : user is %s\n", user_detail->pw_name);
|
fprintf(LOGFILE, "main : user is %s\n", user_detail->pw_name);
|
||||||
|
fprintf(LOGFILE, "main : requested yarn user is %s\n", yarn_user_name);
|
||||||
fflush(LOGFILE);
|
fflush(LOGFILE);
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case INITIALIZE_CONTAINER:
|
case INITIALIZE_CONTAINER:
|
||||||
if (argc < 8) {
|
if (argc < 9) {
|
||||||
fprintf(ERRORFILE, "Too few arguments (%d vs 8) for initialize container\n",
|
fprintf(ERRORFILE, "Too few arguments (%d vs 9) for initialize container\n",
|
||||||
argc);
|
argc);
|
||||||
fflush(ERRORFILE);
|
fflush(ERRORFILE);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
@ -198,13 +209,13 @@ int main(int argc, char **argv) {
|
||||||
cred_file = argv[optind++];
|
cred_file = argv[optind++];
|
||||||
local_dirs = argv[optind++];// good local dirs as a comma separated list
|
local_dirs = argv[optind++];// good local dirs as a comma separated list
|
||||||
log_dirs = argv[optind++];// good log dirs as a comma separated list
|
log_dirs = argv[optind++];// good log dirs as a comma separated list
|
||||||
exit_code = initialize_app(user_detail->pw_name, app_id, cred_file,
|
exit_code = initialize_app(yarn_user_name, app_id, cred_file,
|
||||||
extract_values(local_dirs),
|
extract_values(local_dirs),
|
||||||
extract_values(log_dirs), argv + optind);
|
extract_values(log_dirs), argv + optind);
|
||||||
break;
|
break;
|
||||||
case LAUNCH_CONTAINER:
|
case LAUNCH_CONTAINER:
|
||||||
if (argc != 12) {
|
if (argc != 13) {
|
||||||
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 12) for launch container\n",
|
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 13) for launch container\n",
|
||||||
argc);
|
argc);
|
||||||
fflush(ERRORFILE);
|
fflush(ERRORFILE);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
@ -230,7 +241,7 @@ int main(int argc, char **argv) {
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
}
|
}
|
||||||
char** resources_values = extract_values(resources_value);
|
char** resources_values = extract_values(resources_value);
|
||||||
exit_code = launch_container_as_user(user_detail->pw_name, app_id,
|
exit_code = launch_container_as_user(yarn_user_name, app_id,
|
||||||
container_id, current_dir, script_file, cred_file,
|
container_id, current_dir, script_file, cred_file,
|
||||||
pid_file, extract_values(local_dirs),
|
pid_file, extract_values(local_dirs),
|
||||||
extract_values(log_dirs), resources_key,
|
extract_values(log_dirs), resources_key,
|
||||||
|
@ -239,8 +250,8 @@ int main(int argc, char **argv) {
|
||||||
free(resources_value);
|
free(resources_value);
|
||||||
break;
|
break;
|
||||||
case SIGNAL_CONTAINER:
|
case SIGNAL_CONTAINER:
|
||||||
if (argc != 5) {
|
if (argc != 6) {
|
||||||
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 5) for " \
|
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 6) for " \
|
||||||
"signal container\n", argc);
|
"signal container\n", argc);
|
||||||
fflush(ERRORFILE);
|
fflush(ERRORFILE);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
@ -260,12 +271,12 @@ int main(int argc, char **argv) {
|
||||||
fflush(ERRORFILE);
|
fflush(ERRORFILE);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
}
|
}
|
||||||
exit_code = signal_container_as_user(user_detail->pw_name, container_pid, signal);
|
exit_code = signal_container_as_user(yarn_user_name, container_pid, signal);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DELETE_AS_USER:
|
case DELETE_AS_USER:
|
||||||
dir_to_be_deleted = argv[optind++];
|
dir_to_be_deleted = argv[optind++];
|
||||||
exit_code= delete_as_user(user_detail->pw_name, dir_to_be_deleted,
|
exit_code= delete_as_user(yarn_user_name, dir_to_be_deleted,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#define ARRAY_SIZE 1000
|
#define ARRAY_SIZE 1000
|
||||||
|
|
||||||
static char* username = NULL;
|
static char* username = NULL;
|
||||||
|
static char* yarn_username = NULL;
|
||||||
static char** local_dirs = NULL;
|
static char** local_dirs = NULL;
|
||||||
static char** log_dirs = NULL;
|
static char** log_dirs = NULL;
|
||||||
|
|
||||||
|
@ -252,15 +253,15 @@ void test_check_configuration_permissions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_delete_container() {
|
void test_delete_container() {
|
||||||
if (initialize_user(username, local_dirs)) {
|
if (initialize_user(yarn_username, local_dirs)) {
|
||||||
printf("FAIL: failed to initialize user %s\n", username);
|
printf("FAIL: failed to initialize user %s\n", yarn_username);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
char* app_dir = get_app_directory(TEST_ROOT "/local-2", username, "app_1");
|
char* app_dir = get_app_directory(TEST_ROOT "/local-2", yarn_username, "app_1");
|
||||||
char* dont_touch = get_app_directory(TEST_ROOT "/local-2", username,
|
char* dont_touch = get_app_directory(TEST_ROOT "/local-2", yarn_username,
|
||||||
DONT_TOUCH_FILE);
|
DONT_TOUCH_FILE);
|
||||||
char* container_dir = get_container_work_directory(TEST_ROOT "/local-2",
|
char* container_dir = get_container_work_directory(TEST_ROOT "/local-2",
|
||||||
username, "app_1", "container_1");
|
yarn_username, "app_1", "container_1");
|
||||||
char buffer[100000];
|
char buffer[100000];
|
||||||
sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", container_dir);
|
sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", container_dir);
|
||||||
run(buffer);
|
run(buffer);
|
||||||
|
@ -287,7 +288,7 @@ void test_delete_container() {
|
||||||
|
|
||||||
// delete container directory
|
// delete container directory
|
||||||
char * dirs[] = {app_dir, 0};
|
char * dirs[] = {app_dir, 0};
|
||||||
int ret = delete_as_user(username, "container_1" , dirs);
|
int ret = delete_as_user(yarn_username, "container_1" , dirs);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("FAIL: return code from delete_as_user is %d\n", ret);
|
printf("FAIL: return code from delete_as_user is %d\n", ret);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -318,11 +319,11 @@ void test_delete_container() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_delete_app() {
|
void test_delete_app() {
|
||||||
char* app_dir = get_app_directory(TEST_ROOT "/local-2", username, "app_2");
|
char* app_dir = get_app_directory(TEST_ROOT "/local-2", yarn_username, "app_2");
|
||||||
char* dont_touch = get_app_directory(TEST_ROOT "/local-2", username,
|
char* dont_touch = get_app_directory(TEST_ROOT "/local-2", yarn_username,
|
||||||
DONT_TOUCH_FILE);
|
DONT_TOUCH_FILE);
|
||||||
char* container_dir = get_container_work_directory(TEST_ROOT "/local-2",
|
char* container_dir = get_container_work_directory(TEST_ROOT "/local-2",
|
||||||
username, "app_2", "container_1");
|
yarn_username, "app_2", "container_1");
|
||||||
char buffer[100000];
|
char buffer[100000];
|
||||||
sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", container_dir);
|
sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", container_dir);
|
||||||
run(buffer);
|
run(buffer);
|
||||||
|
@ -348,7 +349,7 @@ void test_delete_app() {
|
||||||
run(buffer);
|
run(buffer);
|
||||||
|
|
||||||
// delete container directory
|
// delete container directory
|
||||||
int ret = delete_as_user(username, app_dir, NULL);
|
int ret = delete_as_user(yarn_username, app_dir, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("FAIL: return code from delete_as_user is %d\n", ret);
|
printf("FAIL: return code from delete_as_user is %d\n", ret);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -377,17 +378,17 @@ void test_delete_app() {
|
||||||
|
|
||||||
void test_delete_user() {
|
void test_delete_user() {
|
||||||
printf("\nTesting delete_user\n");
|
printf("\nTesting delete_user\n");
|
||||||
char* app_dir = get_app_directory(TEST_ROOT "/local-1", username, "app_3");
|
char* app_dir = get_app_directory(TEST_ROOT "/local-1", yarn_username, "app_3");
|
||||||
if (mkdirs(app_dir, 0700) != 0) {
|
if (mkdirs(app_dir, 0700) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
char buffer[100000];
|
char buffer[100000];
|
||||||
sprintf(buffer, "%s/local-1/usercache/%s", TEST_ROOT, username);
|
sprintf(buffer, "%s/local-1/usercache/%s", TEST_ROOT, yarn_username);
|
||||||
if (access(buffer, R_OK) != 0) {
|
if (access(buffer, R_OK) != 0) {
|
||||||
printf("FAIL: directory missing before test\n");
|
printf("FAIL: directory missing before test\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (delete_as_user(username, buffer, NULL) != 0) {
|
if (delete_as_user(yarn_username, buffer, NULL) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (access(buffer, R_OK) == 0) {
|
if (access(buffer, R_OK) == 0) {
|
||||||
|
@ -446,7 +447,7 @@ void test_signal_container() {
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
printf("Child container launched as %d\n", child);
|
printf("Child container launched as %d\n", child);
|
||||||
if (signal_container_as_user(username, child, SIGQUIT) != 0) {
|
if (signal_container_as_user(yarn_username, child, SIGQUIT) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
@ -486,7 +487,7 @@ void test_signal_container_group() {
|
||||||
// there's a race condition for child calling change_user and us
|
// there's a race condition for child calling change_user and us
|
||||||
// calling signal_container_as_user, hence sleeping
|
// calling signal_container_as_user, hence sleeping
|
||||||
sleep(3);
|
sleep(3);
|
||||||
if (signal_container_as_user(username, child, SIGKILL) != 0) {
|
if (signal_container_as_user(yarn_username, child, SIGKILL) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
@ -550,7 +551,7 @@ void test_init_app() {
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (child == 0) {
|
} else if (child == 0) {
|
||||||
char *final_pgm[] = {"touch", "my-touch-file", 0};
|
char *final_pgm[] = {"touch", "my-touch-file", 0};
|
||||||
if (initialize_app(username, "app_4", TEST_ROOT "/creds.txt",
|
if (initialize_app(yarn_username, "app_4", TEST_ROOT "/creds.txt",
|
||||||
local_dirs, log_dirs, final_pgm) != 0) {
|
local_dirs, log_dirs, final_pgm) != 0) {
|
||||||
printf("FAIL: failed in child\n");
|
printf("FAIL: failed in child\n");
|
||||||
exit(42);
|
exit(42);
|
||||||
|
@ -568,7 +569,7 @@ void test_init_app() {
|
||||||
printf("FAIL: failed to create app log directory\n");
|
printf("FAIL: failed to create app log directory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
char* app_dir = get_app_directory(TEST_ROOT "/local-1", username, "app_4");
|
char* app_dir = get_app_directory(TEST_ROOT "/local-1", yarn_username, "app_4");
|
||||||
if (access(app_dir, R_OK) != 0) {
|
if (access(app_dir, R_OK) != 0) {
|
||||||
printf("FAIL: failed to create app directory %s\n", app_dir);
|
printf("FAIL: failed to create app directory %s\n", app_dir);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -640,7 +641,7 @@ void test_run_container() {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
char* container_dir = get_container_work_directory(TEST_ROOT "/local-1",
|
char* container_dir = get_container_work_directory(TEST_ROOT "/local-1",
|
||||||
username, "app_4", "container_1");
|
yarn_username, "app_4", "container_1");
|
||||||
const char * pid_file = TEST_ROOT "/pid.txt";
|
const char * pid_file = TEST_ROOT "/pid.txt";
|
||||||
|
|
||||||
pid_t child = fork();
|
pid_t child = fork();
|
||||||
|
@ -649,7 +650,7 @@ void test_run_container() {
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (child == 0) {
|
} else if (child == 0) {
|
||||||
if (launch_container_as_user(username, "app_4", "container_1",
|
if (launch_container_as_user(yarn_username, "app_4", "container_1",
|
||||||
container_dir, script_name, TEST_ROOT "/creds.txt", pid_file,
|
container_dir, script_name, TEST_ROOT "/creds.txt", pid_file,
|
||||||
local_dirs, log_dirs,
|
local_dirs, log_dirs,
|
||||||
"cgroups", cgroups_pids) != 0) {
|
"cgroups", cgroups_pids) != 0) {
|
||||||
|
@ -697,10 +698,22 @@ void test_run_container() {
|
||||||
check_pid_file(cgroups_pids[1], child);
|
check_pid_file(cgroups_pids[1], child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is expected to be executed either by a regular
|
||||||
|
// user or by root. If executed by a regular user it doesn't
|
||||||
|
// test all the functions that would depend on changing the
|
||||||
|
// effective user id. If executed by a super-user everything
|
||||||
|
// gets tested. Here are different ways of execing the test binary:
|
||||||
|
// 1. regular user assuming user == yarn user
|
||||||
|
// $ test-container-executor
|
||||||
|
// 2. regular user with a given yarn user
|
||||||
|
// $ test-container-executor yarn_user
|
||||||
|
// 3. super user with a given user and assuming user == yarn user
|
||||||
|
// # test-container-executor user
|
||||||
|
// 4. super user with a given user and a given yarn user
|
||||||
|
// # test-container-executor user yarn_user
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
LOGFILE = stdout;
|
LOGFILE = stdout;
|
||||||
ERRORFILE = stderr;
|
ERRORFILE = stderr;
|
||||||
int my_username = 0;
|
|
||||||
|
|
||||||
// clean up any junk from previous run
|
// clean up any junk from previous run
|
||||||
if (system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT)) {
|
if (system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT)) {
|
||||||
|
@ -721,11 +734,15 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
create_nm_roots(local_dirs);
|
create_nm_roots(local_dirs);
|
||||||
|
|
||||||
if (getuid() == 0 && argc == 2) {
|
// See the description above of various ways this test
|
||||||
|
// can be executed in order to understand the following logic
|
||||||
|
char* current_username = strdup(getpwuid(getuid())->pw_name);
|
||||||
|
if (getuid() == 0 && (argc == 2 || argc == 3)) {
|
||||||
username = argv[1];
|
username = argv[1];
|
||||||
|
yarn_username = (argc == 3) ? argv[2] : argv[1];
|
||||||
} else {
|
} else {
|
||||||
username = strdup(getpwuid(getuid())->pw_name);
|
username = current_username;
|
||||||
my_username = 1;
|
yarn_username = (argc == 2) ? argv[1] : current_username;
|
||||||
}
|
}
|
||||||
set_nm_uid(geteuid(), getegid());
|
set_nm_uid(geteuid(), getegid());
|
||||||
|
|
||||||
|
@ -783,9 +800,7 @@ int main(int argc, char **argv) {
|
||||||
run("rm -fr " TEST_ROOT);
|
run("rm -fr " TEST_ROOT);
|
||||||
printf("\nFinished tests\n");
|
printf("\nFinished tests\n");
|
||||||
|
|
||||||
if (my_username) {
|
free(current_username);
|
||||||
free(username);
|
|
||||||
}
|
|
||||||
free_configurations();
|
free_configurations();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,14 +31,17 @@ import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
||||||
import org.apache.hadoop.fs.FileContext;
|
import org.apache.hadoop.fs.FileContext;
|
||||||
import org.apache.hadoop.fs.FileStatus;
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
import org.apache.hadoop.fs.FileUtil;
|
import org.apache.hadoop.fs.FileUtil;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerId;
|
import org.apache.hadoop.yarn.api.records.ContainerId;
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
|
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
|
@ -256,4 +259,91 @@ public class TestLinuxContainerExecutor {
|
||||||
|
|
||||||
assertFalse(t.isAlive());
|
assertFalse(t.isAlive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocalUser() throws Exception {
|
||||||
|
try {
|
||||||
|
//nonsecure default
|
||||||
|
Configuration conf = new YarnConfiguration();
|
||||||
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
|
"simple");
|
||||||
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
LinuxContainerExecutor lce = new LinuxContainerExecutor();
|
||||||
|
lce.setConf(conf);
|
||||||
|
Assert.assertEquals(YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER,
|
||||||
|
lce.getRunAsUser("foo"));
|
||||||
|
|
||||||
|
//nonsecure custom setting
|
||||||
|
conf.set(YarnConfiguration.NM_NONSECURE_MODE_LOCAL_USER_KEY, "bar");
|
||||||
|
lce = new LinuxContainerExecutor();
|
||||||
|
lce.setConf(conf);
|
||||||
|
Assert.assertEquals("bar", lce.getRunAsUser("foo"));
|
||||||
|
|
||||||
|
//secure
|
||||||
|
conf = new YarnConfiguration();
|
||||||
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
|
"kerberos");
|
||||||
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
lce = new LinuxContainerExecutor();
|
||||||
|
lce.setConf(conf);
|
||||||
|
Assert.assertEquals("foo", lce.getRunAsUser("foo"));
|
||||||
|
} finally {
|
||||||
|
Configuration conf = new YarnConfiguration();
|
||||||
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
|
"simple");
|
||||||
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonsecureUsernamePattern() throws Exception {
|
||||||
|
try {
|
||||||
|
//nonsecure default
|
||||||
|
Configuration conf = new YarnConfiguration();
|
||||||
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
|
"simple");
|
||||||
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
LinuxContainerExecutor lce = new LinuxContainerExecutor();
|
||||||
|
lce.setConf(conf);
|
||||||
|
lce.verifyUsernamePattern("foo");
|
||||||
|
try {
|
||||||
|
lce.verifyUsernamePattern("foo/x");
|
||||||
|
Assert.fail();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
//NOP
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Assert.fail(ex.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//nonsecure custom setting
|
||||||
|
conf.set(YarnConfiguration.NM_NONSECURE_MODE_USER_PATTERN_KEY, "foo");
|
||||||
|
lce = new LinuxContainerExecutor();
|
||||||
|
lce.setConf(conf);
|
||||||
|
lce.verifyUsernamePattern("foo");
|
||||||
|
try {
|
||||||
|
lce.verifyUsernamePattern("bar");
|
||||||
|
Assert.fail();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
//NOP
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Assert.fail(ex.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//secure, pattern matching does not kick in.
|
||||||
|
conf = new YarnConfiguration();
|
||||||
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
|
"kerberos");
|
||||||
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
lce = new LinuxContainerExecutor();
|
||||||
|
lce.setConf(conf);
|
||||||
|
lce.verifyUsernamePattern("foo");
|
||||||
|
lce.verifyUsernamePattern("foo/w");
|
||||||
|
} finally {
|
||||||
|
Configuration conf = new YarnConfiguration();
|
||||||
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
|
"simple");
|
||||||
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,8 @@ public class TestLinuxContainerExecutorWithMocks {
|
||||||
appSubmitter, appId, workDir, dirsHandler.getLocalDirs(),
|
appSubmitter, appId, workDir, dirsHandler.getLocalDirs(),
|
||||||
dirsHandler.getLogDirs());
|
dirsHandler.getLogDirs());
|
||||||
assertEquals(0, ret);
|
assertEquals(0, ret);
|
||||||
assertEquals(Arrays.asList(appSubmitter, cmd, appId, containerId,
|
assertEquals(Arrays.asList(YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER,
|
||||||
|
appSubmitter, cmd, appId, containerId,
|
||||||
workDir.toString(), "/bin/echo", "/dev/null", pidFile.toString(),
|
workDir.toString(), "/bin/echo", "/dev/null", pidFile.toString(),
|
||||||
StringUtils.join(",", dirsHandler.getLocalDirs()),
|
StringUtils.join(",", dirsHandler.getLocalDirs()),
|
||||||
StringUtils.join(",", dirsHandler.getLogDirs()), "cgroups=none"),
|
StringUtils.join(",", dirsHandler.getLogDirs()), "cgroups=none"),
|
||||||
|
@ -180,18 +181,19 @@ public class TestLinuxContainerExecutorWithMocks {
|
||||||
try {
|
try {
|
||||||
mockExec.startLocalizer(nmPrivateCTokensPath, address, "test", "application_0", "12345", dirsHandler.getLocalDirs(), dirsHandler.getLogDirs());
|
mockExec.startLocalizer(nmPrivateCTokensPath, address, "test", "application_0", "12345", dirsHandler.getLocalDirs(), dirsHandler.getLogDirs());
|
||||||
List<String> result=readMockParams();
|
List<String> result=readMockParams();
|
||||||
Assert.assertEquals(result.size(), 16);
|
Assert.assertEquals(result.size(), 17);
|
||||||
Assert.assertEquals(result.get(0), "test");
|
Assert.assertEquals(result.get(0), YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER);
|
||||||
Assert.assertEquals(result.get(1), "0" );
|
Assert.assertEquals(result.get(1), "test");
|
||||||
Assert.assertEquals(result.get(2),"application_0" );
|
Assert.assertEquals(result.get(2), "0" );
|
||||||
Assert.assertEquals(result.get(3), "/bin/nmPrivateCTokensPath");
|
Assert.assertEquals(result.get(3),"application_0" );
|
||||||
Assert.assertEquals(result.get(7), "-classpath" );
|
Assert.assertEquals(result.get(4), "/bin/nmPrivateCTokensPath");
|
||||||
Assert.assertEquals(result.get(10),"org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer" );
|
Assert.assertEquals(result.get(8), "-classpath" );
|
||||||
Assert.assertEquals(result.get(11), "test");
|
Assert.assertEquals(result.get(11),"org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer" );
|
||||||
Assert.assertEquals(result.get(12), "application_0");
|
Assert.assertEquals(result.get(12), "test");
|
||||||
Assert.assertEquals(result.get(13),"12345" );
|
Assert.assertEquals(result.get(13), "application_0");
|
||||||
Assert.assertEquals(result.get(14),"localhost" );
|
Assert.assertEquals(result.get(14),"12345" );
|
||||||
Assert.assertEquals(result.get(15),"8040" );
|
Assert.assertEquals(result.get(15),"localhost" );
|
||||||
|
Assert.assertEquals(result.get(16),"8040" );
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOG.error("Error:"+e.getMessage(),e);
|
LOG.error("Error:"+e.getMessage(),e);
|
||||||
|
@ -246,7 +248,8 @@ public class TestLinuxContainerExecutorWithMocks {
|
||||||
appSubmitter, appId, workDir, dirsHandler.getLocalDirs(),
|
appSubmitter, appId, workDir, dirsHandler.getLocalDirs(),
|
||||||
dirsHandler.getLogDirs());
|
dirsHandler.getLogDirs());
|
||||||
Assert.assertNotSame(0, ret);
|
Assert.assertNotSame(0, ret);
|
||||||
assertEquals(Arrays.asList(appSubmitter, cmd, appId, containerId,
|
assertEquals(Arrays.asList(YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER,
|
||||||
|
appSubmitter, cmd, appId, containerId,
|
||||||
workDir.toString(), "/bin/echo", "/dev/null", pidFile.toString(),
|
workDir.toString(), "/bin/echo", "/dev/null", pidFile.toString(),
|
||||||
StringUtils.join(",", dirsHandler.getLocalDirs()),
|
StringUtils.join(",", dirsHandler.getLocalDirs()),
|
||||||
StringUtils.join(",", dirsHandler.getLogDirs()),
|
StringUtils.join(",", dirsHandler.getLogDirs()),
|
||||||
|
@ -272,7 +275,8 @@ public class TestLinuxContainerExecutorWithMocks {
|
||||||
String sigVal = String.valueOf(signal.getValue());
|
String sigVal = String.valueOf(signal.getValue());
|
||||||
|
|
||||||
mockExec.signalContainer(appSubmitter, "1000", signal);
|
mockExec.signalContainer(appSubmitter, "1000", signal);
|
||||||
assertEquals(Arrays.asList(appSubmitter, cmd, "1000", sigVal),
|
assertEquals(Arrays.asList(YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER,
|
||||||
|
appSubmitter, cmd, "1000", sigVal),
|
||||||
readMockParams());
|
readMockParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +288,8 @@ public class TestLinuxContainerExecutorWithMocks {
|
||||||
Path dir = new Path("/tmp/testdir");
|
Path dir = new Path("/tmp/testdir");
|
||||||
|
|
||||||
mockExec.deleteAsUser(appSubmitter, dir);
|
mockExec.deleteAsUser(appSubmitter, dir);
|
||||||
assertEquals(Arrays.asList(appSubmitter, cmd, "/tmp/testdir"),
|
assertEquals(Arrays.asList(YarnConfiguration.DEFAULT_NM_NONSECURE_MODE_LOCAL_USER,
|
||||||
|
appSubmitter, cmd, "/tmp/testdir"),
|
||||||
readMockParams());
|
readMockParams());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue