This is an automated email from the ASF dual-hosted git repository. alexr pushed a commit to branch 1.5.x in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 966574a31a3f8c5d4f9a5f02eeb1644aff7fdc97 Author: Andrei Budnik <[email protected]> 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/ (cherry picked from commit 31499a5dc1de29fa2178e6ea9e5398d8c668a933) --- .../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 db60bfb..80fd95e 100644 --- a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp +++ b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp @@ -1096,6 +1096,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) {
