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 2019/07/13 17:18:13 UTC
[mesos] 02/06: Added the test
`NamespacesIsolatorTest.ROOT_PrivateIPCNamespace`.
This is an automated email from the ASF dual-hosted git repository.
gilbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit f26b2aa93553a1a7e845b194cb9ff49fb72bae22
Author: Qian Zhang <zh...@gmail.com>
AuthorDate: Sat Jul 13 10:07:54 2019 -0700
Added the test `NamespacesIsolatorTest.ROOT_PrivateIPCNamespace`.
Review: https://reviews.apache.org/r/70849/
---
src/tests/containerizer/isolator_tests.cpp | 159 +++++++++++++++++++++++++++++
1 file changed, 159 insertions(+)
diff --git a/src/tests/containerizer/isolator_tests.cpp b/src/tests/containerizer/isolator_tests.cpp
index 82081d3..fad6eb4 100644
--- a/src/tests/containerizer/isolator_tests.cpp
+++ b/src/tests/containerizer/isolator_tests.cpp
@@ -584,6 +584,165 @@ TEST_F(NamespacesIsolatorTest, ROOT_ShareIPCNamespace)
ASSERT_TRUE(termination.get()->has_status());
EXPECT_WTERMSIG_EQ(SIGKILL, termination.get()->status());
}
+
+
+// This test verifies that nested container with private IPC mode will
+// have its own IPC namespace and /dev/shm.
+TEST_F(NamespacesIsolatorTest, ROOT_PrivateIPCNamespace)
+{
+ // Create containerizer with `--default_shm_size=64MB`.
+ Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
+ "filesystem/linux,namespaces/ipc",
+ None(),
+ None(),
+ Megabytes(64));
+
+ ASSERT_SOME(containerizer);
+
+ // Launch a top-level container with `PRIVATE` IPC mode, check its /dev/shm
+ // size is correctly set to the default value, touch a file in its /dev/shm,
+ // and write its IPC namespace inode to a file in its sandbox.
+ const string command =
+ "df -m /dev/shm | grep -w 64 && "
+ "touch /dev/shm/root &&"
+ "stat -Lc %i /proc/self/ns/ipc > ns && "
+ "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_ipc_mode(LinuxInfo::PRIVATE);
+
+ process::Future<Containerizer::LaunchResult> launch =
+ containerizer.get()->launch(
+ containerId,
+ containerConfig,
+ std::map<string, string>(),
+ None());
+
+ AWAIT_ASSERT_EQ(Containerizer::LaunchResult::SUCCESS, launch);
+
+ // Wait until the `ns` file is created in the sandbox.
+ Duration waited = Duration::zero();
+
+ do {
+ if (os::exists(path::join(directory, "ns"))) {
+ break;
+ }
+
+ os::sleep(Seconds(1));
+ waited += Seconds(1);
+ } while (waited < process::TEST_AWAIT_TIMEOUT);
+
+ EXPECT_LT(waited, process::TEST_AWAIT_TIMEOUT);
+
+ // Launch a nested container with `PRIVATE` IPC mode, check its /dev/shm
+ // size is correctly set to the default value and the file created by the
+ // top-level container does not exist in its /dev/shm, touch a file in its
+ // /dev/shm and write its IPC namespace inode to a file in its sandbox.
+ ContainerID nestedContainerId1;
+ nestedContainerId1.mutable_parent()->CopyFrom(containerId);
+ nestedContainerId1.set_value(id::UUID::random().toString());
+
+ ContainerInfo containerInfo;
+ containerInfo.set_type(ContainerInfo::MESOS);
+ containerInfo.mutable_linux_info()->set_ipc_mode(LinuxInfo::PRIVATE);
+
+ launch = containerizer.get()->launch(
+ nestedContainerId1,
+ createContainerConfig(
+ createCommandInfo(
+ "df -m /dev/shm | grep -w 64 &&"
+ "test ! -e /dev/shm/root &&"
+ "touch /dev/shm/nested1 &&"
+ "stat -Lc %i /proc/self/ns/ipc > ns && "
+ "sleep 1000"),
+ containerInfo),
+ std::map<string, string>(),
+ None());
+
+ AWAIT_ASSERT_EQ(Containerizer::LaunchResult::SUCCESS, launch);
+
+ // Wait until the `ns` file is created in the sandbox.
+ waited = Duration::zero();
+ const string nestedSandboxPath1 =
+ getSandboxPath(directory, nestedContainerId1);
+
+ do {
+ if (os::exists(path::join(nestedSandboxPath1, "ns"))) {
+ break;
+ }
+
+ os::sleep(Seconds(1));
+ waited += Seconds(1);
+ } while (waited < process::TEST_AWAIT_TIMEOUT);
+
+ EXPECT_LT(waited, process::TEST_AWAIT_TIMEOUT);
+
+ // Launch another nested container with private IPC mode and 128MB
+ // /dev/shm, check its /dev/shm size is correctly set to 128MB and
+ // the files created by the top-level container and the first nested
+ // container do not exist in its /dev/shm, write its IPC namespace
+ // inode to a file in its sandbox.
+ ContainerID nestedContainerId2;
+ nestedContainerId2.mutable_parent()->CopyFrom(containerId);
+ nestedContainerId2.set_value(id::UUID::random().toString());
+
+ containerInfo.mutable_linux_info()->set_shm_size(128);
+
+ launch = containerizer.get()->launch(
+ nestedContainerId2,
+ createContainerConfig(
+ createCommandInfo(
+ "df -m /dev/shm | grep -w 128 &&"
+ "test ! -e /dev/shm/root &&"
+ "test ! -e /dev/shm/nested1 &&"
+ "stat -Lc %i /proc/self/ns/ipc > ns"),
+ containerInfo),
+ std::map<string, string>(),
+ None());
+
+ AWAIT_ASSERT_EQ(Containerizer::LaunchResult::SUCCESS, launch);
+
+ Future<Option<ContainerTermination>> wait = containerizer.get()->wait(
+ nestedContainerId2);
+
+ AWAIT_READY(wait);
+ ASSERT_SOME(wait.get());
+ ASSERT_TRUE(wait.get()->has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait.get()->status());
+
+ // Check top-level container and the two nested containers
+ // have their own IPC namespaces.
+ Try<uint64_t> rootIpcNamespace = readValue(path::join(directory, "ns"));
+ ASSERT_SOME(rootIpcNamespace);
+
+ Try<uint64_t> nestedIpcNamespace1 =
+ readValue(path::join(nestedSandboxPath1, "ns"));
+
+ ASSERT_SOME(nestedIpcNamespace1);
+
+ Try<uint64_t> nestedIpcNamespace2 =
+ readValue(path::join(getSandboxPath(directory, nestedContainerId2), "ns"));
+
+ ASSERT_SOME(nestedIpcNamespace2);
+
+ EXPECT_NE(rootIpcNamespace.get(), nestedIpcNamespace1.get());
+ EXPECT_NE(rootIpcNamespace.get(), nestedIpcNamespace2.get());
+ EXPECT_NE(nestedIpcNamespace1.get(), nestedIpcNamespace2.get());
+
+ Future<Option<ContainerTermination>> termination =
+ containerizer.get()->destroy(containerId);
+
+ AWAIT_READY(termination);
+ ASSERT_SOME(termination.get());
+ ASSERT_TRUE(termination.get()->has_status());
+ EXPECT_WTERMSIG_EQ(SIGKILL, termination.get()->status());
+}
#endif // __linux__
} // namespace tests {