YARN-5704. Provide config knobs to control enabling/disabling new/work in progress features in container-executor. Contributed by Sidharta Seethana.
(cherry picked from commit 0992708d79
)
This commit is contained in:
parent
b565fa8e05
commit
3ce02387ea
|
@ -44,6 +44,9 @@ static const int DEFAULT_MIN_USERID = 1000;
|
||||||
|
|
||||||
static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0};
|
static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0};
|
||||||
|
|
||||||
|
static const int DEFAULT_DOCKER_SUPPORT_ENABLED = 0;
|
||||||
|
static const int DEFAULT_TC_SUPPORT_ENABLED = 0;
|
||||||
|
|
||||||
//location of traffic control binary
|
//location of traffic control binary
|
||||||
static const char* TC_BIN = "/sbin/tc";
|
static const char* TC_BIN = "/sbin/tc";
|
||||||
static const char* TC_MODIFY_STATE_OPTS [] = { "-b" , NULL};
|
static const char* TC_MODIFY_STATE_OPTS [] = { "-b" , NULL};
|
||||||
|
@ -412,6 +415,43 @@ int change_user(uid_t user, gid_t group) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int is_feature_enabled(const char* feature_key, int default_value) {
|
||||||
|
char *enabled_str = get_value(feature_key, &executor_cfg);
|
||||||
|
int enabled = default_value;
|
||||||
|
|
||||||
|
if (enabled_str != NULL) {
|
||||||
|
char *end_ptr = NULL;
|
||||||
|
enabled = strtol(enabled_str, &end_ptr, 10);
|
||||||
|
|
||||||
|
if ((enabled_str == end_ptr || *end_ptr != '\0') ||
|
||||||
|
(enabled < 0 || enabled > 1)) {
|
||||||
|
fprintf(LOGFILE, "Illegal value '%s' for '%s' in configuration. "
|
||||||
|
"Using default value: %d.\n", enabled_str, feature_key,
|
||||||
|
default_value);
|
||||||
|
fflush(LOGFILE);
|
||||||
|
free(enabled_str);
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(enabled_str);
|
||||||
|
return enabled;
|
||||||
|
} else {
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int is_docker_support_enabled() {
|
||||||
|
return is_feature_enabled(DOCKER_SUPPORT_ENABLED_KEY,
|
||||||
|
DEFAULT_DOCKER_SUPPORT_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_tc_support_enabled() {
|
||||||
|
return is_feature_enabled(TC_SUPPORT_ENABLED_KEY,
|
||||||
|
DEFAULT_TC_SUPPORT_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
char* check_docker_binary(char *docker_binary) {
|
char* check_docker_binary(char *docker_binary) {
|
||||||
if (docker_binary == NULL) {
|
if (docker_binary == NULL) {
|
||||||
return "docker";
|
return "docker";
|
||||||
|
@ -1113,9 +1153,6 @@ int run_docker(const char *command_file) {
|
||||||
snprintf(docker_command_with_binary, EXECUTOR_PATH_MAX, "%s %s", docker_binary, docker_command);
|
snprintf(docker_command_with_binary, EXECUTOR_PATH_MAX, "%s %s", docker_binary, docker_command);
|
||||||
char **args = extract_values_delim(docker_command_with_binary, " ");
|
char **args = extract_values_delim(docker_command_with_binary, " ");
|
||||||
|
|
||||||
//clean up command file before we exec
|
|
||||||
unlink(command_file);
|
|
||||||
|
|
||||||
int exit_code = -1;
|
int exit_code = -1;
|
||||||
if (execvp(docker_binary, args) != 0) {
|
if (execvp(docker_binary, args) != 0) {
|
||||||
fprintf(ERRORFILE, "Couldn't execute the container launch with args %s - %s",
|
fprintf(ERRORFILE, "Couldn't execute the container launch with args %s - %s",
|
||||||
|
@ -1426,8 +1463,6 @@ int launch_docker_container_as_user(const char * user, const char *app_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
//clean up docker command file
|
|
||||||
unlink(command_file);
|
|
||||||
|
|
||||||
if (exit_code_file != NULL && write_exit_code_file_as_nm(exit_code_file, exit_code) < 0) {
|
if (exit_code_file != NULL && write_exit_code_file_as_nm(exit_code_file, exit_code) < 0) {
|
||||||
fprintf (ERRORFILE,
|
fprintf (ERRORFILE,
|
||||||
|
@ -2057,7 +2092,6 @@ static int run_traffic_control(const char *opts[], char *command_file) {
|
||||||
fprintf(LOGFILE, "failed to execute tc command!\n");
|
fprintf(LOGFILE, "failed to execute tc command!\n");
|
||||||
return TRAFFIC_CONTROL_EXECUTION_FAILED;
|
return TRAFFIC_CONTROL_EXECUTION_FAILED;
|
||||||
}
|
}
|
||||||
unlink(command_file);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
execv(TC_BIN, (char**)args);
|
execv(TC_BIN, (char**)args);
|
||||||
|
|
|
@ -60,7 +60,8 @@ enum errorcodes {
|
||||||
TRAFFIC_CONTROL_EXECUTION_FAILED = 28,
|
TRAFFIC_CONTROL_EXECUTION_FAILED = 28,
|
||||||
DOCKER_RUN_FAILED=29,
|
DOCKER_RUN_FAILED=29,
|
||||||
ERROR_OPENING_FILE = 30,
|
ERROR_OPENING_FILE = 30,
|
||||||
ERROR_READING_FILE = 31
|
ERROR_READING_FILE = 31,
|
||||||
|
FEATURE_DISABLED = 32
|
||||||
};
|
};
|
||||||
|
|
||||||
enum operations {
|
enum operations {
|
||||||
|
@ -88,6 +89,8 @@ enum operations {
|
||||||
#define BANNED_USERS_KEY "banned.users"
|
#define BANNED_USERS_KEY "banned.users"
|
||||||
#define ALLOWED_SYSTEM_USERS_KEY "allowed.system.users"
|
#define ALLOWED_SYSTEM_USERS_KEY "allowed.system.users"
|
||||||
#define DOCKER_BINARY_KEY "docker.binary"
|
#define DOCKER_BINARY_KEY "docker.binary"
|
||||||
|
#define DOCKER_SUPPORT_ENABLED_KEY "feature.docker.enabled"
|
||||||
|
#define TC_SUPPORT_ENABLED_KEY "feature.tc.enabled"
|
||||||
#define TMP_DIR "tmp"
|
#define TMP_DIR "tmp"
|
||||||
|
|
||||||
extern struct passwd *user_detail;
|
extern struct passwd *user_detail;
|
||||||
|
@ -255,6 +258,9 @@ int check_dir(const char* npath, mode_t st_mode, mode_t desired,
|
||||||
int create_validate_dir(const char* npath, mode_t perm, const char* path,
|
int create_validate_dir(const char* npath, mode_t perm, const char* path,
|
||||||
int finalComponent);
|
int finalComponent);
|
||||||
|
|
||||||
|
/** Check if tc (traffic control) support is enabled in configuration. */
|
||||||
|
int is_tc_support_enabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a batch of tc commands that modify interface configuration
|
* Run a batch of tc commands that modify interface configuration
|
||||||
*/
|
*/
|
||||||
|
@ -274,6 +280,8 @@ int traffic_control_read_state(char *command_file);
|
||||||
*/
|
*/
|
||||||
int traffic_control_read_stats(char *command_file);
|
int traffic_control_read_stats(char *command_file);
|
||||||
|
|
||||||
|
/** Check if docker support is enabled in configuration. */
|
||||||
|
int is_docker_support_enabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a docker command passing the command file as an argument
|
* Run a docker command passing the command file as an argument
|
||||||
|
|
|
@ -43,27 +43,73 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void display_usage(FILE *stream) {
|
static void display_usage(FILE *stream) {
|
||||||
char *usage_template =
|
char usage_template[4096];
|
||||||
"Usage: container-executor --checksetup\n" \
|
|
||||||
" container-executor --mount-cgroups <hierarchy> <controller=path>...\n" \
|
usage_template[0] = '\0';
|
||||||
" container-executor --tc-modify-state <command-file>\n" \
|
strcat(usage_template,
|
||||||
" container-executor --tc-read-state <command-file>\n" \
|
"Usage: container-executor --checksetup\n"
|
||||||
" container-executor --tc-read-stats <command-file>\n" \
|
" container-executor --mount-cgroups <hierarchy> "
|
||||||
" container-executor --run-docker <command-file>\n" \
|
"<controller=path>...\n" );
|
||||||
" container-executor <user> <yarn-user> <command> <command-args>\n" \
|
|
||||||
|
if(is_tc_support_enabled()) {
|
||||||
|
strcat(usage_template,
|
||||||
|
" container-executor --tc-modify-state <command-file>\n"
|
||||||
|
" container-executor --tc-read-state <command-file>\n"
|
||||||
|
" container-executor --tc-read-stats <command-file>\n" );
|
||||||
|
} else {
|
||||||
|
strcat(usage_template,
|
||||||
|
"[DISABLED] container-executor --tc-modify-state <command-file>\n"
|
||||||
|
"[DISABLED] container-executor --tc-read-state <command-file>\n"
|
||||||
|
"[DISABLED] container-executor --tc-read-stats <command-file>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_docker_support_enabled()) {
|
||||||
|
strcat(usage_template,
|
||||||
|
" container-executor --run-docker <command-file>\n");
|
||||||
|
} else {
|
||||||
|
strcat(usage_template,
|
||||||
|
"[DISABLED] container-executor --run-docker <command-file>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(usage_template,
|
||||||
|
" container-executor <user> <yarn-user> <command> <command-args>\n"
|
||||||
" where command and command-args: \n" \
|
" where command and command-args: \n" \
|
||||||
" initialize container: %2d appid tokens nm-local-dirs nm-log-dirs cmd app...\n" \
|
" initialize container: %2d appid tokens nm-local-dirs "
|
||||||
" launch container: %2d appid containerid workdir container-script " \
|
"nm-log-dirs cmd app...\n"
|
||||||
"tokens pidfile nm-local-dirs nm-log-dirs resources optional-tc-command-file\n" \
|
" launch container: %2d appid containerid workdir "
|
||||||
" launch docker container: %2d appid containerid workdir container-script " \
|
"container-script tokens pidfile nm-local-dirs nm-log-dirs resources ");
|
||||||
"tokens pidfile nm-local-dirs nm-log-dirs docker-command-file resources optional-tc-command-file\n" \
|
|
||||||
" signal container: %2d container-pid signal\n" \
|
|
||||||
" delete as user: %2d relative-path\n" \
|
|
||||||
" list as user: %2d relative-path\n" ;
|
|
||||||
|
|
||||||
|
if(is_tc_support_enabled()) {
|
||||||
|
strcat(usage_template, "optional-tc-command-file\n");
|
||||||
|
} else {
|
||||||
|
strcat(usage_template, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stream, usage_template, INITIALIZE_CONTAINER, LAUNCH_CONTAINER, LAUNCH_DOCKER_CONTAINER,
|
if(is_docker_support_enabled()) {
|
||||||
SIGNAL_CONTAINER, DELETE_AS_USER, LIST_AS_USER);
|
strcat(usage_template,
|
||||||
|
" launch docker container: %2d appid containerid workdir "
|
||||||
|
"container-script tokens pidfile nm-local-dirs nm-log-dirs "
|
||||||
|
"docker-command-file resources ");
|
||||||
|
} else {
|
||||||
|
strcat(usage_template,
|
||||||
|
"[DISABLED] launch docker container: %2d appid containerid workdir "
|
||||||
|
"container-script tokens pidfile nm-local-dirs nm-log-dirs "
|
||||||
|
"docker-command-file resources ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_tc_support_enabled()) {
|
||||||
|
strcat(usage_template, "optional-tc-command-file\n");
|
||||||
|
} else {
|
||||||
|
strcat(usage_template, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(usage_template,
|
||||||
|
" signal container: %2d container-pid signal\n"
|
||||||
|
" delete as user: %2d relative-path\n"
|
||||||
|
" list as user: %2d relative-path\n");
|
||||||
|
|
||||||
|
fprintf(stream, usage_template, INITIALIZE_CONTAINER, LAUNCH_CONTAINER,
|
||||||
|
LAUNCH_DOCKER_CONTAINER, SIGNAL_CONTAINER, DELETE_AS_USER, LIST_AS_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets up log files for normal/error logging */
|
/* Sets up log files for normal/error logging */
|
||||||
|
@ -144,6 +190,10 @@ static void assert_valid_setup(char *current_executable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void display_feature_disabled_message(const char* name) {
|
||||||
|
fprintf(ERRORFILE, "Feature disabled: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use to store parsed input parmeters for various operations */
|
/* Use to store parsed input parmeters for various operations */
|
||||||
static struct {
|
static struct {
|
||||||
char *cgroups_hierarchy;
|
char *cgroups_hierarchy;
|
||||||
|
@ -200,47 +250,67 @@ static int validate_arguments(int argc, char **argv , int *operation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("--tc-modify-state", argv[1]) == 0) {
|
if (strcmp("--tc-modify-state", argv[1]) == 0) {
|
||||||
if (argc != 3) {
|
if(is_tc_support_enabled()) {
|
||||||
display_usage(stdout);
|
if (argc != 3) {
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
display_usage(stdout);
|
||||||
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
}
|
||||||
|
optind++;
|
||||||
|
cmd_input.traffic_control_command_file = argv[optind++];
|
||||||
|
*operation = TRAFFIC_CONTROL_MODIFY_STATE;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("traffic control");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
}
|
}
|
||||||
optind++;
|
|
||||||
cmd_input.traffic_control_command_file = argv[optind++];
|
|
||||||
*operation = TRAFFIC_CONTROL_MODIFY_STATE;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("--tc-read-state", argv[1]) == 0) {
|
if (strcmp("--tc-read-state", argv[1]) == 0) {
|
||||||
if (argc != 3) {
|
if(is_tc_support_enabled()) {
|
||||||
display_usage(stdout);
|
if (argc != 3) {
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
display_usage(stdout);
|
||||||
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
}
|
||||||
|
optind++;
|
||||||
|
cmd_input.traffic_control_command_file = argv[optind++];
|
||||||
|
*operation = TRAFFIC_CONTROL_READ_STATE;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("traffic control");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
}
|
}
|
||||||
optind++;
|
|
||||||
cmd_input.traffic_control_command_file = argv[optind++];
|
|
||||||
*operation = TRAFFIC_CONTROL_READ_STATE;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("--tc-read-stats", argv[1]) == 0) {
|
if (strcmp("--tc-read-stats", argv[1]) == 0) {
|
||||||
if (argc != 3) {
|
if(is_tc_support_enabled()) {
|
||||||
display_usage(stdout);
|
if (argc != 3) {
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
display_usage(stdout);
|
||||||
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
}
|
||||||
|
optind++;
|
||||||
|
cmd_input.traffic_control_command_file = argv[optind++];
|
||||||
|
*operation = TRAFFIC_CONTROL_READ_STATS;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("traffic control");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
}
|
}
|
||||||
optind++;
|
|
||||||
cmd_input.traffic_control_command_file = argv[optind++];
|
|
||||||
*operation = TRAFFIC_CONTROL_READ_STATS;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("--run-docker", argv[1]) == 0) {
|
if (strcmp("--run-docker", argv[1]) == 0) {
|
||||||
if (argc != 3) {
|
if(is_docker_support_enabled()) {
|
||||||
display_usage(stdout);
|
if (argc != 3) {
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
display_usage(stdout);
|
||||||
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
}
|
||||||
|
optind++;
|
||||||
|
cmd_input.docker_command_file = argv[optind++];
|
||||||
|
*operation = RUN_DOCKER;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("docker");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
}
|
}
|
||||||
optind++;
|
|
||||||
cmd_input.docker_command_file = argv[optind++];
|
|
||||||
*operation = RUN_DOCKER;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
/* Now we have to validate 'run as user' operations that don't use
|
/* Now we have to validate 'run as user' operations that don't use
|
||||||
a 'long option' - we should fix this at some point. The validation/argument
|
a 'long option' - we should fix this at some point. The validation/argument
|
||||||
|
@ -286,51 +356,64 @@ static int validate_run_as_user_commands(int argc, char **argv, int *operation)
|
||||||
*operation = RUN_AS_USER_INITIALIZE_CONTAINER;
|
*operation = RUN_AS_USER_INITIALIZE_CONTAINER;
|
||||||
return 0;
|
return 0;
|
||||||
case LAUNCH_DOCKER_CONTAINER:
|
case LAUNCH_DOCKER_CONTAINER:
|
||||||
//kill me now.
|
if(is_docker_support_enabled()) {
|
||||||
if (!(argc == 14 || argc == 15)) {
|
//kill me now.
|
||||||
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 14 or 15) for launch docker container\n",
|
if (!(argc == 14 || argc == 15)) {
|
||||||
argc);
|
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 14 or 15) for"
|
||||||
fflush(ERRORFILE);
|
" launch docker container\n", argc);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
fflush(ERRORFILE);
|
||||||
}
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
cmd_input.app_id = argv[optind++];
|
cmd_input.app_id = argv[optind++];
|
||||||
cmd_input.container_id = argv[optind++];
|
cmd_input.container_id = argv[optind++];
|
||||||
cmd_input.current_dir = argv[optind++];
|
cmd_input.current_dir = argv[optind++];
|
||||||
cmd_input.script_file = argv[optind++];
|
cmd_input.script_file = argv[optind++];
|
||||||
cmd_input.cred_file = argv[optind++];
|
cmd_input.cred_file = argv[optind++];
|
||||||
cmd_input.pid_file = argv[optind++];
|
cmd_input.pid_file = argv[optind++];
|
||||||
cmd_input.local_dirs = argv[optind++];// good local dirs as a comma separated list
|
// good local dirs as a comma separated list
|
||||||
cmd_input.log_dirs = argv[optind++];// good log dirs as a comma separated list
|
cmd_input.local_dirs = argv[optind++];
|
||||||
cmd_input.docker_command_file = argv[optind++];
|
// good log dirs as a comma separated list
|
||||||
resources = argv[optind++];// key,value pair describing resources
|
cmd_input.log_dirs = argv[optind++];
|
||||||
resources_key = malloc(strlen(resources));
|
cmd_input.docker_command_file = argv[optind++];
|
||||||
resources_value = malloc(strlen(resources));
|
// key,value pair describing resources
|
||||||
if (get_kv_key(resources, resources_key, strlen(resources)) < 0 ||
|
resources = argv[optind++];
|
||||||
get_kv_value(resources, resources_value, strlen(resources)) < 0) {
|
resources_key = malloc(strlen(resources));
|
||||||
fprintf(ERRORFILE, "Invalid arguments for cgroups resources: %s",
|
resources_value = malloc(strlen(resources));
|
||||||
resources);
|
if (get_kv_key(resources, resources_key, strlen(resources)) < 0 ||
|
||||||
fflush(ERRORFILE);
|
get_kv_value(resources, resources_value, strlen(resources)) < 0) {
|
||||||
free(resources_key);
|
fprintf(ERRORFILE, "Invalid arguments for cgroups resources: %s",
|
||||||
free(resources_value);
|
resources);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
fflush(ERRORFILE);
|
||||||
}
|
free(resources_key);
|
||||||
//network isolation through tc
|
free(resources_value);
|
||||||
if (argc == 15) {
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
cmd_input.traffic_control_command_file = argv[optind++];
|
}
|
||||||
}
|
//network isolation through tc
|
||||||
|
if (argc == 15) {
|
||||||
|
if(is_tc_support_enabled()) {
|
||||||
|
cmd_input.traffic_control_command_file = argv[optind++];
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("traffic control");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd_input.resources_key = resources_key;
|
cmd_input.resources_key = resources_key;
|
||||||
cmd_input.resources_value = resources_value;
|
cmd_input.resources_value = resources_value;
|
||||||
cmd_input.resources_values = extract_values(resources_value);
|
cmd_input.resources_values = extract_values(resources_value);
|
||||||
*operation = RUN_AS_USER_LAUNCH_DOCKER_CONTAINER;
|
*operation = RUN_AS_USER_LAUNCH_DOCKER_CONTAINER;
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("docker");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
case LAUNCH_CONTAINER:
|
case LAUNCH_CONTAINER:
|
||||||
//kill me now.
|
//kill me now.
|
||||||
if (!(argc == 13 || argc == 14)) {
|
if (!(argc == 13 || argc == 14)) {
|
||||||
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 13 or 14) for launch container\n",
|
fprintf(ERRORFILE, "Wrong number of arguments (%d vs 13 or 14)"
|
||||||
argc);
|
" for launch container\n", argc);
|
||||||
fflush(ERRORFILE);
|
fflush(ERRORFILE);
|
||||||
return INVALID_ARGUMENT_NUMBER;
|
return INVALID_ARGUMENT_NUMBER;
|
||||||
}
|
}
|
||||||
|
@ -359,7 +442,12 @@ static int validate_run_as_user_commands(int argc, char **argv, int *operation)
|
||||||
|
|
||||||
//network isolation through tc
|
//network isolation through tc
|
||||||
if (argc == 14) {
|
if (argc == 14) {
|
||||||
cmd_input.traffic_control_command_file = argv[optind++];
|
if(is_tc_support_enabled()) {
|
||||||
|
cmd_input.traffic_control_command_file = argv[optind++];
|
||||||
|
} else {
|
||||||
|
display_feature_disabled_message("traffic control");
|
||||||
|
return FEATURE_DISABLED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_input.resources_key = resources_key;
|
cmd_input.resources_key = resources_key;
|
||||||
|
|
Loading…
Reference in New Issue