You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by gi...@apache.org on 2017/08/15 03:53:54 UTC

[1/8] mesos git commit: Fixed a bug in the test `NamespacesIsolatorTest`.

Repository: mesos
Updated Branches:
  refs/heads/master 2fe2bb26a -> 2e3a5b134


Fixed a bug in the test `NamespacesIsolatorTest`.

In this test, we used the command `stat -c %i` to get the current
process's pid/ipc namespace inode, that is not correct since
`/proc/self/ns/pid` and `/proc/self/ns/ipc` are symbol links, we
should get the inode that the link references rather than the link
itself. So we need to add a `-L` option in the `stat` command.

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


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

Branch: refs/heads/master
Commit: c568583408be47d5990c163b3d8ef0f3ca3993e0
Parents: 36f11dd
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:51:58 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:31 2017 -0700

----------------------------------------------------------------------
 src/tests/containerizer/isolator_tests.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/c5685834/src/tests/containerizer/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/isolator_tests.cpp b/src/tests/containerizer/isolator_tests.cpp
index f3c541c..a390038 100644
--- a/src/tests/containerizer/isolator_tests.cpp
+++ b/src/tests/containerizer/isolator_tests.cpp
@@ -109,7 +109,7 @@ TEST_F(NamespacesIsolatorTest, ROOT_PidNamespace)
 
   // Write the command's pid namespace inode and init name to files.
   const string command =
-    "stat -c %i /proc/self/ns/pid > ns && (cat /proc/1/comm > init)";
+    "stat -Lc %i /proc/self/ns/pid > ns && (cat /proc/1/comm > init)";
 
   process::Future<bool> launch = containerizer.get()->launch(
       containerId,
@@ -173,7 +173,7 @@ TEST_F(NamespacesIsolatorTest, ROOT_IPCNamespace)
   ASSERT_NE(hostShmmax.get(), shmmaxValue);
 
   const string command =
-    "stat -c %i /proc/self/ns/ipc > ns;"
+    "stat -Lc %i /proc/self/ns/ipc > ns;"
     "echo " + stringify(shmmaxValue) + " > /proc/sys/kernel/shmmax;"
     "cp /proc/sys/kernel/shmmax shmmax";
 


[7/8] mesos git commit: Added the test `ROOT_CGROUPS_LaunchNestedSharePidNamespace`.

Posted by gi...@apache.org.
Added the test `ROOT_CGROUPS_LaunchNestedSharePidNamespace`.

Added the test `ROOT_CGROUPS_LaunchNestedSharePidNamespace`.

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


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

Branch: refs/heads/master
Commit: 63e848a4817824b5b9e92d6d0150da8a9d7b3a58
Parents: 829a7a5
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:52:01 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:32 2017 -0700

----------------------------------------------------------------------
 .../nested_mesos_containerizer_tests.cpp        | 142 +++++++++++++++++++
 1 file changed, 142 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/63e848a4/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
index e466434..f8b4423 100644
--- a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
@@ -827,6 +827,148 @@ TEST_F(NestedMesosContainerizerTest,
 }
 
 
+// This test verifies that nested container can share pid namespace
+// with its parent container or have its own pid namespace based on
+// the field `ContainerInfo.linux_info.share_pid_namespace`.
+TEST_F(NestedMesosContainerizerTest,
+       ROOT_CGROUPS_LaunchNestedSharePidNamespace)
+{
+  slave::Flags flags = CreateSlaveFlags();
+  flags.launcher = "linux";
+  flags.isolation = "cgroups/cpu,filesystem/linux,namespaces/pid";
+
+  Fetcher fetcher(flags);
+
+  Try<MesosContainerizer*> create = MesosContainerizer::create(
+      flags,
+      true,
+      &fetcher);
+
+  ASSERT_SOME(create);
+
+  Owned<MesosContainerizer> containerizer(create.get());
+
+  SlaveState state;
+  state.id = SlaveID();
+
+  AWAIT_READY(containerizer->recover(state));
+
+  // Launch the parent container.
+  ContainerID containerId;
+  containerId.set_value(UUID::random().toString());
+
+  Try<string> directory = environment->mkdtemp();
+  ASSERT_SOME(directory);
+
+  Future<bool> launch = containerizer->launch(
+      containerId,
+      createContainerConfig(
+          None(),
+          createExecutorInfo(
+              "executor",
+              "stat -Lc %i /proc/self/ns/pid > ns && sleep 1000",
+              "cpus:1"),
+          directory.get()),
+      map<string, string>(),
+      None());
+
+  AWAIT_ASSERT_TRUE(launch);
+
+  // Launch the first nested container which will share pid namespace
+  // with the parent container.
+  ContainerID nestedContainerId1;
+  nestedContainerId1.mutable_parent()->CopyFrom(containerId);
+  nestedContainerId1.set_value(UUID::random().toString());
+
+  ContainerInfo container;
+  container.set_type(ContainerInfo::MESOS);
+  container.mutable_linux_info()->set_share_pid_namespace(true);
+
+  launch = containerizer->launch(
+      nestedContainerId1,
+      createContainerConfig(
+          createCommandInfo("stat -Lc %i /proc/self/ns/pid > ns"),
+          container),
+      map<string, string>(),
+      None());
+
+  AWAIT_ASSERT_TRUE(launch);
+
+  Future<Option<ContainerTermination>> wait = containerizer->wait(
+      nestedContainerId1);
+
+  AWAIT_READY(wait);
+  ASSERT_SOME(wait.get());
+  ASSERT_TRUE(wait.get()->has_status());
+  EXPECT_WEXITSTATUS_EQ(0, wait.get()->status());
+
+  // Launch the second nested container which will have its own pid namespace.
+  ContainerID nestedContainerId2;
+  nestedContainerId2.mutable_parent()->CopyFrom(containerId);
+  nestedContainerId2.set_value(UUID::random().toString());
+
+  container.mutable_linux_info()->set_share_pid_namespace(false);
+
+  launch = containerizer->launch(
+      nestedContainerId2,
+      createContainerConfig(
+          createCommandInfo("stat -Lc %i /proc/self/ns/pid > ns"),
+          container),
+      map<string, string>(),
+      None());
+
+  AWAIT_ASSERT_TRUE(launch);
+
+  wait = containerizer->wait(nestedContainerId2);
+
+  AWAIT_READY(wait);
+  ASSERT_SOME(wait.get());
+  ASSERT_TRUE(wait.get()->has_status());
+  EXPECT_WEXITSTATUS_EQ(0, wait.get()->status());
+
+  // Get parent container's pid namespace.
+  Try<string> parentPidNamespace = os::read(path::join(directory.get(), "ns"));
+  ASSERT_SOME(parentPidNamespace);
+
+  // Get first nested container's pid namespace.
+  const string sandboxPath1 =
+    getSandboxPath(directory.get(), nestedContainerId1);
+
+  ASSERT_TRUE(os::exists(sandboxPath1));
+
+  Try<string> pidNamespace1 = os::read(path::join(sandboxPath1, "ns"));
+  ASSERT_SOME(pidNamespace1);
+
+  // Get second nested container's pid namespace.
+  const string sandboxPath2 =
+    getSandboxPath(directory.get(), nestedContainerId2);
+
+  ASSERT_TRUE(os::exists(sandboxPath2));
+
+  Try<string> pidNamespace2 = os::read(path::join(sandboxPath2, "ns"));
+
+  ASSERT_SOME(pidNamespace2);
+
+  // Check the first nested container shares the pid namespace
+  // with the parent container.
+  EXPECT_EQ(stringify(parentPidNamespace.get()),
+            stringify(pidNamespace1.get()));
+
+  // Check the second nested container has its own pid namespace.
+  EXPECT_NE(stringify(parentPidNamespace.get()),
+            stringify(pidNamespace2.get()));
+
+  wait = containerizer->wait(containerId);
+
+  containerizer->destroy(containerId);
+
+  AWAIT_READY(wait);
+  ASSERT_SOME(wait.get());
+  ASSERT_TRUE(wait.get()->has_status());
+  EXPECT_WTERMSIG_EQ(SIGKILL, wait.get()->status());
+}
+
+
 TEST_F(NestedMesosContainerizerTest,
        ROOT_CGROUPS_INTERNET_CURL_LaunchNestedDebugCheckMntNamespace)
 {


[8/8] mesos git commit: Added a test `DefaultExecutorTest.ROOT_MultiTaskgroupSharePidNamespace`.

Posted by gi...@apache.org.
Added a test `DefaultExecutorTest.ROOT_MultiTaskgroupSharePidNamespace`.

Added a test `DefaultExecutorTest.ROOT_MultiTaskgroupSharePidNamespace`.

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


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

Branch: refs/heads/master
Commit: 2e3a5b1347e5ff8c3bfa6d80d14c1f9e883887d3
Parents: 63e848a
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:52:03 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 20:49:14 2017 -0700

----------------------------------------------------------------------
 src/tests/default_executor_tests.cpp | 174 +++++++++++++++++++++++++++++-
 1 file changed, 173 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/2e3a5b13/src/tests/default_executor_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/default_executor_tests.cpp b/src/tests/default_executor_tests.cpp
index 3ac9f29..afe0afa 100644
--- a/src/tests/default_executor_tests.cpp
+++ b/src/tests/default_executor_tests.cpp
@@ -1373,6 +1373,178 @@ TEST_P(DefaultExecutorTest, ReservedResources)
 }
 
 
+#ifdef __linux__
+// This test verifies that tasks from two different
+// task groups can share the same pid namespace.
+TEST_P(DefaultExecutorTest, ROOT_MultiTaskgroupSharePidNamespace)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.containerizers = GetParam();
+  flags.launcher = "linux";
+  flags.isolation = "cgroups/cpu,filesystem/linux,namespaces/pid";
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags);
+  ASSERT_SOME(slave);
+
+  auto scheduler = std::make_shared<v1::MockHTTPScheduler>();
+
+  v1::FrameworkInfo frameworkInfo = v1::DEFAULT_FRAMEWORK_INFO;
+
+  Future<Nothing> connected;
+  EXPECT_CALL(*scheduler, connected(_))
+    .WillOnce(DoAll(v1::scheduler::SendSubscribe(frameworkInfo),
+                    FutureSatisfy(&connected)));
+
+  v1::scheduler::TestMesos mesos(
+      master.get()->pid,
+      ContentType::PROTOBUF,
+      scheduler);
+
+  AWAIT_READY(connected);
+
+  Future<v1::scheduler::Event::Subscribed> subscribed;
+  EXPECT_CALL(*scheduler, subscribed(_, _))
+    .WillOnce(FutureArg<1>(&subscribed));
+
+  Future<v1::scheduler::Event::Offers> offers1;
+  EXPECT_CALL(*scheduler, offers(_, _))
+    .WillOnce(FutureArg<1>(&offers1));
+
+  EXPECT_CALL(*scheduler, heartbeat(_))
+    .WillRepeatedly(Return()); // Ignore heartbeats.
+
+  AWAIT_READY(subscribed);
+
+  v1::FrameworkID frameworkId(subscribed->framework_id());
+  v1::ExecutorInfo executorInfo = v1::createExecutorInfo(
+      "test_default_executor",
+      None(),
+      "cpus:0.1;mem:32;disk:32",
+      v1::ExecutorInfo::DEFAULT);
+
+  // Update `executorInfo` with the subscribed `frameworkId`.
+  executorInfo.mutable_framework_id()->CopyFrom(frameworkId);
+
+  AWAIT_READY(offers1);
+  EXPECT_FALSE(offers1->offers().empty());
+
+  const v1::Offer& offer1 = offers1->offers(0);
+  const v1::AgentID& agentId = offer1.agent_id();
+
+  // Create the first task which will share pid namespace with its parent.
+  v1::TaskInfo taskInfo1 = v1::createTask(
+      agentId,
+      v1::Resources::parse("cpus:0.1;mem:32;disk:32").get(),
+      "stat -Lc %i /proc/self/ns/pid > ns && sleep 1000");
+
+  mesos::v1::ContainerInfo* containerInfo = taskInfo1.mutable_container();
+  containerInfo->set_type(mesos::v1::ContainerInfo::MESOS);
+  containerInfo->mutable_linux_info()->set_share_pid_namespace(true);
+
+  Future<v1::scheduler::Event::Update> update1;
+  EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&update1));
+
+  Future<v1::scheduler::Event::Offers> offers2;
+  EXPECT_CALL(*scheduler, offers(_, _))
+    .WillOnce(FutureArg<1>(&offers2))
+    .WillRepeatedly(Return());
+
+  // Launch the first task group.
+  v1::Offer::Operation launchGroup = v1::LAUNCH_GROUP(
+      executorInfo,
+      v1::createTaskGroupInfo({taskInfo1}));
+
+  mesos.send(v1::createCallAccept(frameworkId, offer1, {launchGroup}));
+
+  AWAIT_READY(update1);
+
+  ASSERT_EQ(TASK_RUNNING, update1->status().state());
+  EXPECT_EQ(taskInfo1.task_id(), update1->status().task_id());
+  EXPECT_TRUE(update1->status().has_timestamp());
+
+  AWAIT_READY(offers2);
+  EXPECT_FALSE(offers2->offers().empty());
+
+  const v1::Offer& offer2 = offers2->offers(0);
+
+  // Create the second task which will share pid namespace with its parent.
+  v1::TaskInfo taskInfo2 = v1::createTask(
+      agentId,
+      v1::Resources::parse("cpus:0.1;mem:32;disk:32").get(),
+      "stat -Lc %i /proc/self/ns/pid > ns && sleep 1000");
+
+  containerInfo = taskInfo2.mutable_container();
+  containerInfo->set_type(mesos::v1::ContainerInfo::MESOS);
+  containerInfo->mutable_linux_info()->set_share_pid_namespace(true);
+
+  Future<v1::scheduler::Event::Update> update2;
+  EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&update2));
+
+  // Launch the second task group.
+  launchGroup = v1::LAUNCH_GROUP(
+      executorInfo,
+      v1::createTaskGroupInfo({taskInfo2}));
+
+  mesos.send(v1::createCallAccept(frameworkId, offer2, {launchGroup}));
+
+  AWAIT_READY(update2);
+
+  ASSERT_EQ(TASK_RUNNING, update2->status().state());
+  EXPECT_EQ(taskInfo2.task_id(), update2->status().task_id());
+  EXPECT_TRUE(update2->status().has_timestamp());
+
+  string executorSandbox = slave::paths::getExecutorLatestRunPath(
+      flags.work_dir,
+      devolve(agentId),
+      devolve(frameworkId),
+      devolve(executorInfo.executor_id()));
+
+  string pidNamespacePath1 = path::join(
+      executorSandbox,
+      "tasks",
+      taskInfo1.task_id().value(),
+      "ns");
+
+  string pidNamespacePath2 = path::join(
+      executorSandbox,
+      "tasks",
+      taskInfo2.task_id().value(),
+      "ns");
+
+  // Wait up to 5 seconds for each of the two tasks to
+  // write its pid namespace inode into its sandbox.
+  Duration waited = Duration::zero();
+  do {
+    if (os::exists(pidNamespacePath1) && os::exists(pidNamespacePath2)) {
+      break;
+    }
+
+    os::sleep(Seconds(1));
+    waited += Seconds(1);
+  } while (waited < Seconds(5));
+
+  EXPECT_TRUE(os::exists(pidNamespacePath1));
+  EXPECT_TRUE(os::exists(pidNamespacePath2));
+
+  Try<string> pidNamespace1 = os::read(pidNamespacePath1);
+  ASSERT_SOME(pidNamespace1);
+
+  Try<string> pidNamespace2 = os::read(pidNamespacePath2);
+  ASSERT_SOME(pidNamespace2);
+
+  // Check the two tasks share the same pid namespace.
+  EXPECT_EQ(strings::trim(pidNamespace1.get()),
+            strings::trim(pidNamespace2.get()));
+}
+#endif // __linux__
+
+
 struct LauncherAndIsolationParam
 {
   LauncherAndIsolationParam(const string& _launcher, const string& _isolation)
@@ -1508,7 +1680,7 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(
       "echo abc > task_volume_path/file");
 
   // TODO(gilbert): Refactor the following code once the helper
-  // to create a 'sandbox_path' volume is suppported.
+  // to create a 'sandbox_path' volume is supported.
   mesos::v1::ContainerInfo* containerInfo = taskInfo.mutable_container();
   containerInfo->set_type(mesos::v1::ContainerInfo::MESOS);
 


[2/8] mesos git commit: Added pid ns sharing based on agent flag and protobuf message field.

Posted by gi...@apache.org.
Added pid ns sharing based on agent flag and protobuf message field.

Added pid ns sharing based on agent flag and protobuf message field.

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


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

Branch: refs/heads/master
Commit: 36f11dd39a389fbe4128bd6ffffe9afb179e4f6c
Parents: 03e093f
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:51:57 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:31 2017 -0700

----------------------------------------------------------------------
 .../mesos/isolators/namespaces/pid.cpp          | 33 ++++++++++++++++----
 .../mesos/isolators/namespaces/pid.hpp          |  4 ++-
 2 files changed, 30 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/36f11dd3/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp b/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp
index f1dfc9f..42bc2e1 100644
--- a/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp
+++ b/src/slave/containerizer/mesos/isolators/namespaces/pid.cpp
@@ -22,6 +22,7 @@
 
 #include "slave/containerizer/mesos/isolators/namespaces/pid.hpp"
 
+using process::Failure;
 using process::Future;
 using process::Owned;
 
@@ -61,12 +62,13 @@ Try<Isolator*> NamespacesPidIsolatorProcess::create(const Flags& flags)
   }
 
   return new MesosIsolator(Owned<MesosIsolatorProcess>(
-      new NamespacesPidIsolatorProcess()));
+      new NamespacesPidIsolatorProcess(flags)));
 }
 
 
-NamespacesPidIsolatorProcess::NamespacesPidIsolatorProcess()
-  : ProcessBase(process::ID::generate("pid-namespace-isolator")) {}
+NamespacesPidIsolatorProcess::NamespacesPidIsolatorProcess(const Flags& _flags)
+  : ProcessBase(process::ID::generate("pid-namespace-isolator")),
+    flags(_flags) {}
 
 
 bool NamespacesPidIsolatorProcess::supportsNesting()
@@ -81,20 +83,39 @@ Future<Option<ContainerLaunchInfo>> NamespacesPidIsolatorProcess::prepare(
 {
   ContainerLaunchInfo launchInfo;
 
+  bool sharePidNamespace =
+    containerConfig.container_info().linux_info().share_pid_namespace();
+
   if (containerId.has_parent()) {
     // If we are a nested container, then we want to enter our
     // parent's pid namespace before cloning a new one.
     launchInfo.add_enter_namespaces(CLONE_NEWPID);
 
-    // However, if we are a nested container in the `DEBUG` class,
-    // then we don't want to clone a new PID namespace at all, so we
-    // short cirucuit here.
+    // For nested container in the `DEBUG` class, we don't want to clone a
+    // new pid namespace at all, so we short circuit here.
     if (containerConfig.has_container_class() &&
         containerConfig.container_class() == ContainerClass::DEBUG) {
       return launchInfo;
     }
+  } else {
+    // If sharing agent pid namespace with top-level container is disallowed,
+    // but the framework requests it by setting the `share_pid_namespace` field
+    // to true, the container launch will be rejected.
+    if (flags.disallow_sharing_agent_pid_namespace && sharePidNamespace) {
+      return Failure(
+          "Sharing agent pid namespace with "
+          "top-level container is not allowed");
+    }
+  }
+
+  // For the container which wants to share pid namespace
+  // with its parent, just return immediately.
+  if (sharePidNamespace) {
+    return launchInfo;
   }
 
+  // For the container which does not want to share pid namespace with
+  // its parent, make sure we will clone a new pid namespace for it.
   launchInfo.add_clone_namespaces(CLONE_NEWPID);
 
   // Mount /proc with standard options for the container's pid

http://git-wip-us.apache.org/repos/asf/mesos/blob/36f11dd3/src/slave/containerizer/mesos/isolators/namespaces/pid.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/namespaces/pid.hpp b/src/slave/containerizer/mesos/isolators/namespaces/pid.hpp
index 2b316db..6b4ba06 100644
--- a/src/slave/containerizer/mesos/isolators/namespaces/pid.hpp
+++ b/src/slave/containerizer/mesos/isolators/namespaces/pid.hpp
@@ -39,7 +39,9 @@ public:
       const mesos::slave::ContainerConfig& containerConfig);
 
 private:
-  NamespacesPidIsolatorProcess();
+  NamespacesPidIsolatorProcess(const Flags& flags);
+
+  const Flags flags;
 };
 
 } // namespace slave {


[5/8] mesos git commit: Added test `NamespacesIsolatorTest.ROOT_SharePidNamespaceWhenDisallow`.

Posted by gi...@apache.org.
Added test `NamespacesIsolatorTest.ROOT_SharePidNamespaceWhenDisallow`.

Added test `NamespacesIsolatorTest.ROOT_SharePidNamespaceWhenDisallow`.

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


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

Branch: refs/heads/master
Commit: 829a7a57abdfdc4bba4f2918fc822fb70033202b
Parents: fdc3554
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:52:00 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:32 2017 -0700

----------------------------------------------------------------------
 src/tests/containerizer/isolator_tests.cpp | 40 ++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/829a7a57/src/tests/containerizer/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/isolator_tests.cpp b/src/tests/containerizer/isolator_tests.cpp
index f8860ae..5072baf 100644
--- a/src/tests/containerizer/isolator_tests.cpp
+++ b/src/tests/containerizer/isolator_tests.cpp
@@ -68,11 +68,18 @@ public:
     containerId.set_value(UUID::random().toString());
   }
 
-  Try<Owned<MesosContainerizer>> createContainerizer(const string& isolation)
+  Try<Owned<MesosContainerizer>> createContainerizer(
+      const string& isolation,
+      const Option<bool>& disallowSharingAgentPidNamespace = None())
   {
     slave::Flags flags = CreateSlaveFlags();
     flags.isolation = isolation;
 
+    if (disallowSharingAgentPidNamespace.isSome()) {
+      flags.disallow_sharing_agent_pid_namespace =
+        disallowSharingAgentPidNamespace.get();
+    }
+
     fetcher.reset(new Fetcher(flags));
 
     Try<MesosContainerizer*> _containerizer =
@@ -214,6 +221,37 @@ TEST_F(NamespacesIsolatorTest, ROOT_SharePidNamespace)
 }
 
 
+// This test verifies launching a top-level container to share
+// pid namespace with agent will fail when the agent flag
+// `--disallow_sharing_agent_pid_namespace` is set to true.
+TEST_F(NamespacesIsolatorTest, ROOT_SharePidNamespaceWhenDisallow)
+{
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer("filesystem/linux,namespaces/pid", true);
+
+  ASSERT_SOME(containerizer);
+
+  const string command = "sleep 1000";
+
+  mesos::slave::ContainerConfig containerConfig = createContainerConfig(
+      None(),
+      createExecutorInfo("executor", command),
+      directory);
+
+  ContainerInfo* container = containerConfig.mutable_container_info();
+  container->set_type(ContainerInfo::MESOS);
+  container->mutable_linux_info()->set_share_pid_namespace(true);
+
+  process::Future<bool> launch = containerizer.get()->launch(
+      containerId,
+      containerConfig,
+      std::map<string, string>(),
+      None());
+
+  AWAIT_FAILED(launch);
+}
+
+
 // The IPC namespace has its own copy of the svipc(7) tunables. We verify
 // that we are correctly entering the IPC namespace by verifying that we
 // can set shmmax some different value than that of the host namespace.


[6/8] mesos git commit: Added a test `NamespacesIsolatorTest.ROOT_SharePidNamespace`.

Posted by gi...@apache.org.
Added a test `NamespacesIsolatorTest.ROOT_SharePidNamespace`.

Added a test `NamespacesIsolatorTest.ROOT_SharePidNamespace`.

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


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

Branch: refs/heads/master
Commit: fdc3554d085e2dd70124ffa7b64e0847b46b1a12
Parents: c568583
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:51:59 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:32 2017 -0700

----------------------------------------------------------------------
 src/tests/containerizer/isolator_tests.cpp | 61 +++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/fdc3554d/src/tests/containerizer/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/isolator_tests.cpp b/src/tests/containerizer/isolator_tests.cpp
index a390038..f8860ae 100644
--- a/src/tests/containerizer/isolator_tests.cpp
+++ b/src/tests/containerizer/isolator_tests.cpp
@@ -30,6 +30,8 @@
 
 #include <mesos/mesos.hpp>
 
+#include <mesos/slave/containerizer.hpp>
+
 #ifdef __linux__
 #include "linux/ns.hpp"
 #endif
@@ -105,6 +107,7 @@ TEST_F(NamespacesIsolatorTest, ROOT_PidNamespace)
 {
   Try<Owned<MesosContainerizer>> containerizer =
     createContainerizer("filesystem/linux,namespaces/pid");
+
   ASSERT_SOME(containerizer);
 
   // Write the command's pid namespace inode and init name to files.
@@ -154,6 +157,63 @@ TEST_F(NamespacesIsolatorTest, ROOT_PidNamespace)
 }
 
 
+// This test verifies a top-level container can share pid namespace
+// with the agent when the field `share_pid_namespace` is set as
+// true in `ContainerInfo.linux_info`. Please note that the agent flag
+// `--disallow_sharing_agent_pid_namespace` is set to
+// false by default, that means top-level container is allowed to share
+// pid namespace with agent.
+TEST_F(NamespacesIsolatorTest, ROOT_SharePidNamespace)
+{
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer("filesystem/linux,namespaces/pid");
+
+  ASSERT_SOME(containerizer);
+
+  // Write the command's pid namespace inode to file.
+  const string command = "stat -Lc %i /proc/self/ns/pid > ns";
+
+  mesos::slave::ContainerConfig containerConfig = createContainerConfig(
+      None(),
+      createExecutorInfo("executor", command),
+      directory);
+
+  ContainerInfo* container = containerConfig.mutable_container_info();
+  container->set_type(ContainerInfo::MESOS);
+  container->mutable_linux_info()->set_share_pid_namespace(true);
+
+  process::Future<bool> launch = containerizer.get()->launch(
+      containerId,
+      containerConfig,
+      std::map<string, string>(),
+      None());
+
+  AWAIT_READY(launch);
+  ASSERT_TRUE(launch.get());
+
+  // Wait on the container.
+  Future<Option<ContainerTermination>> wait =
+    containerizer.get()->wait(containerId);
+
+  AWAIT_READY(wait);
+  ASSERT_SOME(wait.get());
+
+  // Check the executor exited correctly.
+  EXPECT_TRUE(wait->get().has_status());
+  EXPECT_EQ(0, wait->get().status());
+
+  // Check that the command was run in the same pid namespace.
+  Try<ino_t> testPidNamespace = ns::getns(::getpid(), "pid");
+  ASSERT_SOME(testPidNamespace);
+
+  Try<string> containerPidNamespace = os::read(path::join(directory, "ns"));
+  ASSERT_SOME(containerPidNamespace);
+
+  EXPECT_EQ(stringify(testPidNamespace.get()),
+            strings::trim(containerPidNamespace.get()));
+}
+
+
 // The IPC namespace has its own copy of the svipc(7) tunables. We verify
 // that we are correctly entering the IPC namespace by verifying that we
 // can set shmmax some different value than that of the host namespace.
@@ -161,6 +221,7 @@ TEST_F(NamespacesIsolatorTest, ROOT_IPCNamespace)
 {
   Try<Owned<MesosContainerizer>> containerizer =
     createContainerizer("namespaces/ipc");
+
   ASSERT_SOME(containerizer);
 
   // Value we will set the child namespace shmmax to.


[3/8] mesos git commit: Introduced `--disallow_sharing_agent_pid_namespace` agent flag.

Posted by gi...@apache.org.
Introduced `--disallow_sharing_agent_pid_namespace` agent flag.

Introduced `--disallow_sharing_agent_pid_namespace` agent flag.

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


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

Branch: refs/heads/master
Commit: 03e093f5d09e35a54e4373692d47a46d58fae4d0
Parents: dc1908a
Author: Qian Zhang <zh...@gmail.com>
Authored: Sun Aug 13 19:51:56 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:31 2017 -0700

----------------------------------------------------------------------
 docs/configuration.md | 14 ++++++++++++++
 src/slave/flags.cpp   | 10 ++++++++++
 src/slave/flags.hpp   |  1 +
 3 files changed, 25 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/03e093f5/docs/configuration.md
----------------------------------------------------------------------
diff --git a/docs/configuration.md b/docs/configuration.md
index 6ab2d1a..e43f9ea 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -2046,6 +2046,20 @@ sandbox is mapped to.
 </tr>
 <tr>
   <td>
+    --[no-]disallow_sharing_agent_pid_namespace
+  </td>
+  <td>
+If set to <code>true</code>, each top-level container will have its own pid
+namespace, and if the framework requests to share the agent pid namespace for
+the top level container, the container launch will be rejected. If set to
+<code>false</code>, the top-level containers will share the pid namespace with
+agent if the framework requests it. This flag will be ignored if the
+`namespaces/pid` isolator is not enabled.
+(default: false)
+  </td>
+</tr>
+<tr>
+  <td>
     --[no-]strict
   </td>
   <td>

http://git-wip-us.apache.org/repos/asf/mesos/blob/03e093f5/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index 4171604..3b02f3e 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -639,6 +639,16 @@ mesos::internal::slave::Flags::Flags()
       "\n"
       "This flag has the same syntax as `--effective_capabilities`."
      );
+
+  add(&Flags::disallow_sharing_agent_pid_namespace,
+      "disallow_sharing_agent_pid_namespace",
+      "If set to `true`, each top-level container will have its own pid\n"
+      "namespace, and if the framework requests to share the agent pid\n"
+      "namespace for the top level container, the container launch will be\n"
+      "rejected. If set to `false`, the top-level containers will share the\n"
+      "pid namespace with agent if the framework requests it. This flag will\n"
+      "be ignored if the `namespaces/pid` isolator is not enabled.\n",
+      false);
 #endif
 
   add(&Flags::firewall_rules,

http://git-wip-us.apache.org/repos/asf/mesos/blob/03e093f5/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index 032880d..2970fea 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -113,6 +113,7 @@ public:
   std::string systemd_runtime_directory;
   Option<CapabilityInfo> effective_capabilities;
   Option<CapabilityInfo> bounding_capabilities;
+  bool disallow_sharing_agent_pid_namespace;
 #endif
   Option<Firewall> firewall_rules;
   Option<Path> credential;


[4/8] mesos git commit: Added container PID namespace control protobuf field in LinuxInfo.

Posted by gi...@apache.org.
Added container PID namespace control protobuf field in LinuxInfo.

User facing interface for container configurable PID namespace.

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


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

Branch: refs/heads/master
Commit: dc1908a333453dab195307d28404913336bd594e
Parents: 2fe2bb2
Author: Gilbert Song <so...@gmail.com>
Authored: Sun Aug 13 19:51:54 2017 -0700
Committer: Gilbert Song <so...@gmail.com>
Committed: Mon Aug 14 15:40:31 2017 -0700

----------------------------------------------------------------------
 include/mesos/mesos.proto    | 8 ++++++++
 include/mesos/v1/mesos.proto | 8 ++++++++
 2 files changed, 16 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/dc1908a3/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index e39926e..d91c968 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -2742,6 +2742,14 @@ message LinuxInfo {
   // Represents the set of capabilities that the task will
   // be executed with.
   optional CapabilityInfo effective_capabilities = 3;
+
+  // If set as 'true', the container shares the pid namespace with
+  // its parent. If the container is a top level container, it will
+  // share the pid namespace with the agent. If the container is a
+  // nested container, it will share the pid namespace with its
+  // parent container. This field will be ignored if 'namespaces/pid'
+  // isolator is not enabled.
+  optional bool share_pid_namespace = 4;
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/dc1908a3/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index 2979f9e..6a1d011 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -2725,6 +2725,14 @@ message LinuxInfo {
   // Represents the set of capabilities that the task will
   // be executed with.
   optional CapabilityInfo effective_capabilities = 3;
+
+  // If set as 'true', the container shares the pid namespace with
+  // its parent. If the container is a top level container, it will
+  // share the pid namespace with the agent. If the container is a
+  // nested container, it will share the pid namespace with its
+  // parent container. This field will be ignored if 'namespaces/pid'
+  // isolator is not enabled.
+  optional bool share_pid_namespace = 4;
 }