Commit 990e1f39 authored by Kamil Iskra's avatar Kamil Iskra

Add a new argument to 'exec'

We used to pass the environment for the user job implicitly, as the
environment of argo_nodeos_config.  This wasn't very clean and was
causing problems with, e.g., LD_PRELOAD, which gets filtered out because
argo_nodeos_config is suid root.  So now we pass the environment as a
required, explicit argument.
parent 4fde2b8c
......@@ -526,7 +526,7 @@ enum Option_val
OV_RESET,
/*--exec="name:'c0' argv='argv0 argv1'"*/
/*--exec="name:'c0' argv='argv0 argv1'" env='env1=val1 env2=val2'*/
OV_EXEC
};
......@@ -765,6 +765,7 @@ int main(int argc, char** argv)
}
char** exec_argv = cm->get_exec_argv();
char** exec_env = cm->get_exec_env();
delete cm;
rlock.unlock();
......@@ -775,7 +776,7 @@ int main(int argc, char** argv)
{
if (setuid(getuid()) == -1)
argo_exit(EXIT_FAILURE, "Dropping privileges failed", errno);
execvp(exec_argv[0], exec_argv);
execvpe(exec_argv[0], exec_argv, exec_env);
argo_exit(EXIT_FAILURE, "Command execution failed", errno);
}
......
......@@ -1076,8 +1076,8 @@ void Container_manager::exec(string command)
String_parser sp(command);
sp.parse();
THROW_ON_BAD_INPUT_IF(!sp.has_key("name") || !sp.has_key("argv"),
"Bad exec command");
THROW_ON_BAD_INPUT_IF(!sp.has_key("name") || !sp.has_key("argv") ||
!sp.has_key("env"), "Bad exec command");
string name;
sp.get_string("name", name);
......@@ -1104,6 +1104,21 @@ void Container_manager::exec(string command)
if (*j == '\\')
i->erase(j);
string env;
sp.get_string("env", env);
if (env[0] == '\'') /* Strip ' from both ends. */
env = env.substr(1, env.size() - 2);
vector<string> envs;
split(env, ' ', envs);
/* Remove a single layer of backslashes. */
for (vector<string>::iterator i = envs.begin(); i != envs.end(); ++i)
for (string::iterator j = i->begin(); j != i->end(); ++j)
if (*j == '\\')
i->erase(j);
vector<int> tasks(1, getpid());
cc->add_tasks(tasks);
cc->commit_last_changes();
......@@ -1111,7 +1126,7 @@ void Container_manager::exec(string command)
std::ostringstream ss;
ss << "About to execute";
/* We use global allocators so that _exec_argv survives after
/* We use global allocators so that _exec_* survive after
the container manager is destroyed. */
_exec_argv = new char*[argvs.size() + 1];
for (int i = 0; i < argvs.size(); i++)
......@@ -1122,5 +1137,15 @@ void Container_manager::exec(string command)
}
_exec_argv[argvs.size()] = NULL;
ss << " [environment]";
_exec_env = new char*[envs.size() + 1];
for (int i = 0; i < envs.size(); i++)
{
_exec_env[i] = new char[envs[i].size() + 1];
strcpy(_exec_env[i], envs[i].c_str());
ss << " '" << envs[i] << "'";
}
_exec_env[envs.size()] = NULL;
_logger->log(LOG_TYPE_INFO, ss.str());
}
......@@ -34,6 +34,7 @@ class Container_manager
string _argo_argo_containers_root;
char ** _exec_argv;
char ** _exec_env;
Container_manager(Container_manager& orig) = delete;
Container_manager& operator = (const Container_manager& orig) = delete;
......@@ -235,6 +236,7 @@ class Container_manager
inline Error_behavior get_error_behaviour()const {return _error_behavior;}
inline ILogger* get_logger() const {return _logger;}
inline char** get_exec_argv() const {return _exec_argv;}
inline char** get_exec_env() const {return _exec_env;}
void show_available_resources(string command);
void create_container(string command);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment