You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by al...@apache.org on 2018/08/20 14:29:27 UTC
[mesos] 03/04: Added
`ROOT_CGROUPS_LaunchNestedDebugAfterUnshareMntNamespace` test.
This is an automated email from the ASF dual-hosted git repository.
alexr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 31499a5dc1de29fa2178e6ea9e5398d8c668a933
Author: Andrei Budnik <ab...@mesosphere.com>
AuthorDate: Mon Aug 20 16:28:38 2018 +0200
Added `ROOT_CGROUPS_LaunchNestedDebugAfterUnshareMntNamespace` test.
This test verifies detection of task's `mnt` namespace for a debug
nested container. Debug nested container must enter `mnt` namespace
of the task, so the agent tries to detect task's `mnt` namespace.
This test launches a long-running task which runs a subtask that
unshares `mnt` namespace. The structure of the resulting process tree
is similar to the process tree of the command executor (the task of
the command executor unshares `mnt` ns):
0. root (aka "nanny"/"launcher" process) [root `mnt` namespace]
1. task: sleep 1000 [root `mnt` namespace]
2. subtaks: sleep 1000 [subtask's `mnt` namespace]
We expect that the agent detects task's `mnt` namespace.
Review: https://reviews.apache.org/r/68408/
---
.../nested_mesos_containerizer_tests.cpp | 107 +++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
index b80e40b..295dbc8 100644
--- a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
@@ -1050,6 +1050,113 @@ TEST_F(NestedMesosContainerizerTest,
}
+// This test verifies detection of task's `mnt` namespace for a debug nested
+// container. Debug nested container must enter `mnt` namespace of the task,
+// so the agent tries to detect task's `mnt` namespace. This test launches
+// a long-running task which runs a subtask that unshares `mnt` namespace.
+// The structure of the resulting process tree is similar to the process tree
+// of the command executor (the task of command executor unshares `mnt` ns):
+//
+// 0. root (aka "nanny"/"launcher" process) [root `mnt` namespace]
+// 1. task: sleep 1000 [root `mnt` namespace]
+// 2. subtaks: sleep 1000 [subtask's `mnt` namespace]
+//
+// We expect that the agent detects task's `mnt` namespace.
+TEST_F(NestedMesosContainerizerTest,
+ ROOT_CGROUPS_LaunchNestedDebugAfterUnshareMntNamespace)
+{
+ slave::Flags flags = CreateSlaveFlags();
+ flags.launcher = "linux";
+ flags.isolation = "filesystem/linux";
+
+ 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(id::UUID::random().toString());
+
+ string pipe = path::join(sandbox.get(), "pipe");
+ ASSERT_EQ(0, ::mkfifo(pipe.c_str(), 0700));
+
+ const string cmd =
+ "(unshare -m sh -c"
+ " 'mkdir -p test_mnt; mount tmpfs -t tmpfs test_mnt;"
+ " touch test_mnt/check; exec sleep 1000')&"
+ "echo running > " + pipe + "; exec sleep 1000";
+
+ ExecutorInfo executor = createExecutorInfo("executor", cmd, "cpus:1");
+
+ Try<string> directory = environment->mkdtemp();
+ ASSERT_SOME(directory);
+
+ Future<Containerizer::LaunchResult> launch = containerizer->launch(
+ containerId,
+ createContainerConfig(None(), executor, directory.get()),
+ map<string, string>(),
+ None());
+
+ AWAIT_ASSERT_EQ(Containerizer::LaunchResult::SUCCESS, launch);
+
+ // Wait for the parent container to start running its task
+ // before launching a debug nested container.
+ Result<string> read = os::read(pipe);
+ ASSERT_SOME(read);
+ ASSERT_EQ("running\n", read.get());
+
+ // Launch a nested debug container.
+ ContainerID nestedContainerId;
+ nestedContainerId.mutable_parent()->CopyFrom(containerId);
+ nestedContainerId.set_value(id::UUID::random().toString());
+
+ // Launch a debug container inside the command task and check for the
+ // absence of a file we know to be inside the subtask's mounted directory.
+ launch = containerizer->launch(
+ nestedContainerId,
+ createContainerConfig(
+ createCommandInfo(
+ "LINES=`ls -la test_mnt/check | wc -l`;"
+ "if [ ${LINES} -ne 0 ]; then"
+ " exit 1;"
+ "fi;"),
+ None(),
+ ContainerClass::DEBUG),
+ map<string, string>(),
+ None());
+
+ AWAIT_ASSERT_EQ(Containerizer::LaunchResult::SUCCESS, launch);
+
+ Future<Option<ContainerTermination>> wait =
+ containerizer->wait(nestedContainerId);
+
+ AWAIT_READY(wait);
+ ASSERT_SOME(wait.get());
+ ASSERT_TRUE(wait.get()->has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait.get()->status());
+
+ Future<Option<ContainerTermination>> termination =
+ containerizer->destroy(containerId);
+
+ AWAIT_READY(termination);
+ ASSERT_SOME(termination.get());
+ ASSERT_TRUE(termination.get()->has_status());
+ EXPECT_WTERMSIG_EQ(SIGKILL, termination.get()->status());
+}
+
+
TEST_F(NestedMesosContainerizerTest,
ROOT_CGROUPS_DestroyDebugContainerOnRecover)
{