Repository: mesos
Updated Branches:
  refs/heads/master ec5ff7540 -> 6cf8b26a7


Include ContainerInfo in command ExecutorInfo

Always copy ContainerInfo to ExecutorInfo

Remove MesosContainerizer check for TaskInfo->ContainerInfo

Review: https://reviews.apache.org/r/39769


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6cf8b26a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6cf8b26a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6cf8b26a

Branch: refs/heads/master
Commit: 6cf8b26a74060bbc12b15122c65c65cb335ceeba
Parents: ec5ff75
Author: Spike Curtis <[email protected]>
Authored: Fri Nov 6 14:57:58 2015 -0500
Committer: Kapil Arya <[email protected]>
Committed: Fri Nov 6 17:48:14 2015 -0500

----------------------------------------------------------------------
 src/slave/slave.cpp       |  13 ++++-
 src/tests/slave_tests.cpp | 128 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/6cf8b26a/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 4f1e3e3..0f9ed82 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -3252,8 +3252,7 @@ ExecutorInfo Slave::getExecutorInfo(
     executor.mutable_executor_id()->set_value(task.task_id().value());
     executor.mutable_framework_id()->CopyFrom(frameworkInfo.id());
 
-    if (task.has_container() &&
-        task.container().type() != ContainerInfo::MESOS) {
+    if (task.has_container()) {
       // Store the container info in the executor info so it will
       // be checkpointed. This allows the correct containerizer to
       // recover this task on restart.
@@ -3266,6 +3265,16 @@ ExecutorInfo Slave::getExecutorInfo(
 
     if (hasRootfs) {
       ContainerInfo* container = executor.mutable_container();
+
+      // For command-tasks, we are now copying the entire `task.container` into
+      // the `executorInfo`. Thus, `executor.container` now has the image if
+      // `task.container` had one. However, in case of rootfs, we want to run
+      // the command executor in the host filesystem and prepare/mount the 
image
+      // into the container as a volume (command executor will use pivot_root 
to
+      // mount the image). For this reason, we need to strip the image in
+      // `executor.container.mesos`.
+      container->mutable_mesos()->clear_image();
+
       container->set_type(ContainerInfo::MESOS);
       Volume* volume = container->add_volumes();
       volume->mutable_image()->CopyFrom(task.container().mesos().image());

http://git-wip-us.apache.org/repos/asf/mesos/blob/6cf8b26a/src/tests/slave_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp
index 6b89eaf..ac102f1 100644
--- a/src/tests/slave_tests.cpp
+++ b/src/tests/slave_tests.cpp
@@ -573,6 +573,134 @@ TEST_F(SlaveTest, GetExecutorInfo)
   EXPECT_NE(string::npos, executor.command().value().find("mesos-executor"));
 }
 
+// Ensure getExecutorInfo for mesos-executor gets the ContainerInfo, if
+// present.  This ensures the MesosContainerizer can get the NetworkInfo even
+// when using the command executor.
+TEST_F(SlaveTest, GetExecutorInfoForTaskWithContainer)
+{
+  TestContainerizer containerizer;
+  StandaloneMasterDetector detector;
+
+  MockSlave slave(CreateSlaveFlags(), &detector, &containerizer);
+
+  // Launch a task with the command executor and ContainerInfo with
+  // NetworkInfo.
+  TaskInfo task;
+  task.set_name("task");
+  task.mutable_task_id()->set_value("1");
+  task.mutable_slave_id()->set_value(
+      "20141010-221431-251662764-60288-12345-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);
+
+  ContainerInfo *container = task.mutable_container();
+  container->set_type(ContainerInfo::MESOS);
+
+  NetworkInfo *network = container->add_network_infos();
+  network->set_ip_address("4.3.2.1");
+  network->add_groups("public");
+
+  FrameworkInfo frameworkInfo;
+  frameworkInfo.mutable_id()->set_value(
+      "20141010-221431-251662764-60288-12345-0000");
+  const ExecutorInfo& executor = slave.getExecutorInfo(frameworkInfo, task);
+
+  // Now assert that the executor has both the command and ContainerInfo
+  EXPECT_TRUE(executor.command().shell());
+  // CommandInfo.container is not included.  In this test the ContainerInfo
+  // must be included in Executor.container (copied from TaskInfo.container).
+  EXPECT_FALSE(executor.command().has_container());
+  EXPECT_TRUE(executor.has_container());
+
+  EXPECT_EQ("4.3.2.1", executor.container().network_infos(0).ip_address());
+  EXPECT_EQ(1, executor.container().network_infos(0).groups_size());
+  EXPECT_EQ("public", executor.container().network_infos(0).groups(0));
+}
+
+// This tests ensures that MesosContainerizer will launch a command executor
+// even if it contains a ContainerInfo in the TaskInfo.  Prior to 0.26.0, this
+// was only used to launch Docker containers, so MesosContainerizer would fail
+// the launch.
+TEST_F(SlaveTest, LaunchTaskInfoWithContainerInfo)
+{
+  Try<PID<Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  // Need flags for 'executor_registration_timeout'.
+  slave::Flags flags = CreateSlaveFlags();
+  flags.isolation = "posix/cpu,posix/mem";
+
+  Fetcher fetcher;
+
+  Try<MesosContainerizer*> containerizer =
+    MesosContainerizer::create(flags, false, &fetcher);
+  CHECK_SOME(containerizer);
+
+  StandaloneMasterDetector detector;
+  MockSlave slave(flags, &detector, containerizer.get());
+
+  // Launch a task with the command executor and ContainerInfo with
+  // NetworkInfo.
+  TaskInfo task;
+  task.set_name("task");
+  task.mutable_task_id()->set_value("1");
+  task.mutable_slave_id()->set_value(
+      "20141010-221431-251662764-60288-12345-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);
+
+  ContainerID containerId;
+  containerId.set_value(UUID::random().toString());
+  ContainerInfo *container = task.mutable_container();
+  container->set_type(ContainerInfo::MESOS);
+
+  NetworkInfo *network = container->add_network_infos();
+  network->set_ip_address("4.3.2.1");
+  network->add_groups("public");
+
+  FrameworkInfo frameworkInfo;
+  frameworkInfo.mutable_id()->set_value(
+      "20141010-221431-251662764-60288-12345-0000");
+  const ExecutorInfo& executor = slave.getExecutorInfo(frameworkInfo, task);
+
+  Future<bool> result;
+  SlaveID slaveID;
+  slaveID.set_value(UUID::random().toString());
+  result = containerizer.get()->launch(
+      containerId,
+      task,
+      executor,
+      "/tmp",
+      "test",
+      slaveID,
+      slave.self(),
+      false);
+  AWAIT_READY(result);
+
+  // TODO(spikecurtis): With agent capabilities (MESOS-3362), the
+  // Containerizer should fail this request since none of the listed
+  // isolators can handle NetworkInfo, which implies
+  // IP-per-container.
+  EXPECT_TRUE(result.get());
+  Shutdown(); // Must shutdown before 'containerizer' gets deallocated.
+}
+
 
 // This test runs a command without the command user field set. The
 // command will verify the assumption that the command is run as the

Reply via email to