You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by tn...@apache.org on 2014/11/01 09:17:30 UTC
git commit: Fixed Command Executor when shell is false.
Repository: mesos
Updated Branches:
refs/heads/master ae8a51be6 -> 36a26c3ca
Fixed Command Executor when shell is false.
Review: https://reviews.apache.org/r/26622
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/36a26c3c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/36a26c3c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/36a26c3c
Branch: refs/heads/master
Commit: 36a26c3ca7b5a11df0b62540cdd7ad4c58987774
Parents: ae8a51b
Author: R.B. Boyer <ar...@nexusvector.net>
Authored: Sat Nov 1 00:49:33 2014 -0700
Committer: Timothy Chen <tn...@gmail.com>
Committed: Sat Nov 1 00:52:45 2014 -0700
----------------------------------------------------------------------
src/slave/slave.cpp | 28 ++++++++--
src/tests/slave_tests.cpp | 123 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 146 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/36a26c3c/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 96fb5f7..8aa3524 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -2674,15 +2674,33 @@ ExecutorInfo Slave::getExecutorInfo(
executor.set_name("Command Executor " + name);
executor.set_source(task.task_id().value());
- // Copy the CommandInfo to get the URIs and environment, but
- // update it to invoke 'mesos-executor' (unless we couldn't
- // resolve 'mesos-executor' via 'realpath', in which case just
- // echo the error and exit).
- executor.mutable_command()->MergeFrom(task.command());
+ // Copy [uris, environment, container, user] fields from the
+ // CommandInfo to get the URIs and environment, and use them
+ // to invoke 'mesos-executor'.
+ executor.mutable_command()->mutable_uris()->MergeFrom(
+ task.command().uris());
+
+ if (task.command().has_environment()) {
+ executor.mutable_command()->mutable_environment()->MergeFrom(
+ task.command().environment());
+ }
+
+ if (task.command().has_container()) {
+ executor.mutable_command()->mutable_container()->MergeFrom(
+ task.command().container());
+ }
+
+ if (task.command().has_user()) {
+ executor.mutable_command()->set_user(task.command().user());
+ }
Result<string> path = os::realpath(
path::join(flags.launcher_dir, "mesos-executor"));
+ // Strongly enforce a specific shell setting for launching
+ // command executor.
+ executor.mutable_command()->set_shell(true);
+
if (path.isSome()) {
executor.mutable_command()->set_value(path.get());
} else {
http://git-wip-us.apache.org/repos/asf/mesos/blob/36a26c3c/src/tests/slave_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp
index a1bd00c..d2cbaf8 100644
--- a/src/tests/slave_tests.cpp
+++ b/src/tests/slave_tests.cpp
@@ -393,6 +393,129 @@ TEST_F(SlaveTest, MesosExecutorWithOverride)
}
+// Test that we don't let task arguments bleed over as
+// mesos-executor args. For more details of this see MESOS-1873.
+//
+// This assumes the ability to execute '/bin/echo --author'.
+TEST_F(SlaveTest, MesosExecutorCommandTaskWithArgsList)
+{
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ // Need flags for 'executor_registration_timeout'.
+ slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "posix/cpu,posix/mem";
+
+ Try<MesosContainerizer*> containerizer =
+ MesosContainerizer::create(flags, false);
+ CHECK_SOME(containerizer);
+
+ Try<PID<Slave> > slave = StartSlave(containerizer.get());
+ ASSERT_SOME(slave);
+
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .Times(1);
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ AWAIT_READY(offers);
+ EXPECT_NE(0u, offers.get().size());
+
+ // Launch a task with the command executor.
+ TaskInfo task;
+ task.set_name("");
+ task.mutable_task_id()->set_value("1");
+ task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id());
+ task.mutable_resources()->MergeFrom(offers.get()[0].resources());
+
+ // Command executor will run as user running test.
+ CommandInfo command;
+ command.set_shell(false);
+ command.set_value("/bin/echo");
+ command.add_arguments("/bin/echo");
+ command.add_arguments("--author");
+
+ task.mutable_command()->MergeFrom(command);
+
+ vector<TaskInfo> tasks;
+ tasks.push_back(task);
+
+ Future<TaskStatus> statusRunning;
+ Future<TaskStatus> statusFinished;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&statusRunning))
+ .WillOnce(FutureArg<1>(&statusFinished));
+
+ driver.launchTasks(offers.get()[0].id(), tasks);
+
+ AWAIT_READY(statusRunning);
+ EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());
+
+ AWAIT_READY(statusFinished);
+ EXPECT_EQ(TASK_FINISHED, statusFinished.get().state());
+
+ driver.stop();
+ driver.join();
+
+ Shutdown(); // Must shutdown before 'containerizer' gets deallocated.
+}
+
+
+// Don't let args from the CommandInfo struct bleed over into
+// mesos-executor forking. For more details of this see MESOS-1873.
+TEST_F(SlaveTest, GetExecutorInfo)
+{
+ // Create a thin dummy Slave to access underlying getExecutorInfo().
+ // Testing this method should not necessarily require an integration
+ // test as with most other methods here.
+ slave::Flags flags = CreateSlaveFlags();
+ TestContainerizer containerizer;
+ StandaloneMasterDetector detector;
+ Files files;
+ slave::StatusUpdateManager updateManager(flags);
+
+ slave::GarbageCollector gc;
+ Slave slave(flags, &detector, &containerizer, &files, &gc, &updateManager);
+
+ FrameworkID frameworkId;
+ frameworkId.set_value("20141010-221431-251662764-60288-32120-0000");
+
+ // Launch a task with the command executor.
+ TaskInfo task;
+ task.set_name("task");
+ task.mutable_task_id()->set_value("1");
+ task.mutable_slave_id()->set_value(
+ "20141010-221431-251662764-60288-32120-0001");
+ task.mutable_resources()->MergeFrom(
+ Resources::parse("cpus:0.1;mem:32").get());
+
+ CommandInfo command;
+ command.set_shell(false);
+ command.set_value("/bin/echo");
+ command.add_arguments("/bin/echo");
+ command.add_arguments("--author");
+
+ task.mutable_command()->MergeFrom(command);
+
+ const ExecutorInfo& executor = slave.getExecutorInfo(frameworkId, task);
+
+ // Now assert that it actually is running mesos-executor without any
+ // bleedover from the command we intend on running.
+ EXPECT_TRUE(executor.command().shell());
+ EXPECT_FALSE(executor.command().has_container());
+ EXPECT_EQ(0, executor.command().arguments_size());
+ EXPECT_NE(string::npos, executor.command().value().find("mesos-executor"));
+}
+
// This test runs a command without the command user field set. The
// command will verify the assumption that the command is run as the
// slave user (in this case, root).