You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/10/07 16:38:57 UTC
[07/10] mesos git commit: Refactored and simplified
LinuxFilesystemIsolatorTests.
Refactored and simplified LinuxFilesystemIsolatorTests.
Review: https://reviews.apache.org/r/52539
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a089d4a7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a089d4a7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a089d4a7
Branch: refs/heads/master
Commit: a089d4a7f28f6f5990ebeb264c89609aca4bb287
Parents: 351d232
Author: Jie Yu <yu...@gmail.com>
Authored: Tue Oct 4 13:35:07 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Oct 7 09:31:17 2016 -0700
----------------------------------------------------------------------
.../containerizer/filesystem_isolator_tests.cpp | 967 ++++++++-----------
src/tests/mesos.hpp | 6 +-
2 files changed, 421 insertions(+), 552 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a089d4a7/src/tests/containerizer/filesystem_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/filesystem_isolator_tests.cpp b/src/tests/containerizer/filesystem_isolator_tests.cpp
index ad0506e..5e75a2c 100644
--- a/src/tests/containerizer/filesystem_isolator_tests.cpp
+++ b/src/tests/containerizer/filesystem_isolator_tests.cpp
@@ -18,8 +18,6 @@
#include <mesos/mesos.hpp>
-#include <mesos/slave/container_logger.hpp>
-
#include <process/owned.hpp>
#include <process/gtest.hpp>
@@ -28,7 +26,6 @@
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/gtest.hpp>
-#include <stout/hashmap.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/uuid.hpp>
@@ -38,26 +35,17 @@
#include "slave/paths.hpp"
#include "slave/containerizer/mesos/containerizer.hpp"
-#include "slave/containerizer/mesos/linux_launcher.hpp"
#include "slave/containerizer/mesos/isolators/filesystem/linux.hpp"
-#include "slave/containerizer/mesos/isolators/volume/image.hpp"
-
-#include "slave/containerizer/mesos/provisioner/backend.hpp"
-#include "slave/containerizer/mesos/provisioner/paths.hpp"
-#include "slave/containerizer/mesos/provisioner/backends/copy.hpp"
-
-#include "tests/flags.hpp"
+#include "tests/cluster.hpp"
#include "tests/mesos.hpp"
-#include "tests/containerizer/rootfs.hpp"
-#include "tests/containerizer/store.hpp"
+#include "tests/containerizer/docker_archive.hpp"
using process::Future;
using process::Owned;
using process::PID;
-using process::Shared;
using std::map;
using std::string;
@@ -65,22 +53,14 @@ using std::vector;
using mesos::internal::master::Master;
-using mesos::internal::slave::Backend;
+using mesos::internal::slave::Containerizer;
using mesos::internal::slave::Fetcher;
-using mesos::internal::slave::Launcher;
using mesos::internal::slave::LinuxFilesystemIsolatorProcess;
-using mesos::internal::slave::LinuxLauncher;
using mesos::internal::slave::MesosContainerizer;
-using mesos::internal::slave::MesosContainerizerProcess;
-using mesos::internal::slave::Provisioner;
-using mesos::internal::slave::ProvisionerProcess;
using mesos::internal::slave::Slave;
-using mesos::internal::slave::Store;
-using mesos::internal::slave::VolumeImageIsolatorProcess;
using mesos::master::detector::MasterDetector;
-using mesos::slave::ContainerLogger;
using mesos::slave::ContainerTermination;
using mesos::slave::Isolator;
@@ -105,97 +85,7 @@ protected:
MesosTest::TearDown();
}
- // This helper creates a MesosContainerizer instance that uses the
- // LinuxFilesystemIsolator. The filesystem isolator takes a
- // TestAppcProvisioner which provisions APPC images by copying files
- // from the host filesystem.
- // 'images' is a map of imageName -> rootfsPath.
- // TODO(xujyan): The current assumption of one rootfs per image name
- // is inconsistent with the real provisioner and we should fix it.
- Try<Owned<MesosContainerizer>> createContainerizer(
- const slave::Flags& flags,
- const hashmap<string, string>& images)
- {
- // Create the root filesystems.
- hashmap<string, Shared<Rootfs>> rootfses;
- foreachpair (const string& imageName, const string& rootfsPath, images) {
- Try<Owned<Rootfs>> rootfs = LinuxRootfs::create(rootfsPath);
-
- if (rootfs.isError()) {
- return Error("Failed to create LinuxRootfs: " + rootfs.error());
- }
-
- rootfses.put(imageName, rootfs.get().share());
- }
-
- Owned<Store> store(new TestStore(rootfses));
- hashmap<Image::Type, Owned<Store>> stores;
- stores[Image::APPC] = store;
-
- hashmap<string, Owned<Backend>> backends = Backend::create(flags);
-
- const string rootDir = slave::paths::getProvisionerDir(flags.work_dir);
-
- if (!os::exists(rootDir)) {
- Try<Nothing> mkdir = os::mkdir(rootDir);
- if (mkdir.isError()) {
- return Error("Failed to create root dir: " + mkdir.error());
- }
- }
-
- Owned<ProvisionerProcess> provisionerProcess(new ProvisionerProcess(
- flags,
- rootDir,
- stores,
- backends));
-
- Owned<Provisioner> _provisioner(new Provisioner(provisionerProcess));
- Shared<Provisioner> provisioner = _provisioner.share();
-
- Try<Isolator*> linuxIsolator =
- LinuxFilesystemIsolatorProcess::create(flags);
-
- if (linuxIsolator.isError()) {
- return Error(
- "Failed to create LinuxFilesystemIsolatorProcess: " +
- linuxIsolator.error());
- }
-
- Try<Isolator*> imageIsolator =
- VolumeImageIsolatorProcess::create(flags, provisioner);
-
- if (imageIsolator.isError()) {
- return Error(
- "Failed to create VolumeImageIsolatorProcess: " +
- imageIsolator.error());
- }
-
- Try<Launcher*> launcher = LinuxLauncher::create(flags);
-
- if (launcher.isError()) {
- return Error("Failed to create LinuxLauncher: " + launcher.error());
- }
-
- // Create and initialize a new container logger.
- Try<ContainerLogger*> logger =
- ContainerLogger::create(flags.container_logger);
-
- if (logger.isError()) {
- return Error("Failed to create container logger: " + logger.error());
- }
-
- return Owned<MesosContainerizer>(
- new MesosContainerizer(
- flags,
- true,
- &fetcher,
- Owned<ContainerLogger>(logger.get()),
- Owned<Launcher>(launcher.get()),
- provisioner,
- {Owned<Isolator>(linuxIsolator.get()),
- Owned<Isolator>(imageIsolator.get())}));
- }
-
+ // TODO(jieyu): Move this to the common test utils file.
ContainerInfo createContainerInfo(
const Option<string>& imageName = None(),
const vector<Volume>& volumes = vector<Volume>())
@@ -205,10 +95,10 @@ protected:
if (imageName.isSome()) {
Image* image = info.mutable_mesos()->mutable_image();
- image->set_type(Image::APPC);
+ image->set_type(Image::DOCKER);
- Image::Appc* appc = image->mutable_appc();
- appc->set_name(imageName.get());
+ Image::Docker* docker = image->mutable_docker();
+ docker->set_name(imageName.get());
}
foreach (const Volume& volume, volumes) {
@@ -218,7 +108,6 @@ protected:
return info;
}
-private:
Fetcher fetcher;
};
@@ -227,27 +116,35 @@ private:
// properly changed to the one that's provisioned by the provisioner.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystem)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
- "[ ! -d '" + os::getcwd() + "' ]");
+ "[ ! -d '" + sandbox.get() + "' ]");
executor.mutable_container()->CopyFrom(createContainerInfo("test_image"));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -257,35 +154,39 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystem)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
+// This test verifies that the metrics about the number of executors
+// that have root filesystem specified is correctly reported.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_Metrics)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
// Use a long running task so we can reliably capture the moment it's alive.
ExecutorInfo executor = createExecutorInfo(
@@ -294,10 +195,10 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_Metrics)
executor.mutable_container()->CopyFrom(createContainerInfo("test_image"));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -307,29 +208,22 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_Metrics)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Check metrics.
JSON::Object stats = Metrics();
EXPECT_EQ(1u, stats.values.count(
"containerizer/mesos/filesystem/containers_new_rootfs"));
EXPECT_EQ(
1, stats.values["containerizer/mesos/filesystem/containers_new_rootfs"]);
- containerizer.get()->destroy(containerId);
+ containerizer->destroy(containerId);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->wait(containerId);
AWAIT_READY(wait);
ASSERT_SOME(wait.get());
-
- // Executor was killed.
- EXPECT_TRUE(wait->get().has_status());
- EXPECT_EQ(9, wait->get().status());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WTERMSIG_EQ(SIGKILL, wait->get().status());
}
@@ -338,16 +232,24 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_Metrics)
// in the container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
+
+ Owned<Containerizer> containerizer(create.get());
- ASSERT_SOME(containerizer);
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
@@ -357,10 +259,10 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
"test_image",
{createVolumeFromHostPath("/tmp", "tmp", Volume::RW)}));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -370,20 +272,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
EXPECT_SOME_EQ("abc\n", os::read(path::join(directory, "tmp", "file")));
}
@@ -394,29 +290,40 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
// container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
- "test -d /tmp/sandbox");
+ "test -d /tmp/dir");
executor.mutable_container()->CopyFrom(createContainerInfo(
"test_image",
- {createVolumeFromHostPath("/tmp", os::getcwd(), Volume::RW)}));
+ {createVolumeFromHostPath("/tmp", sandbox.get(), Volume::RW)}));
+
+ string dir = path::join(sandbox.get(), "dir");
+ ASSERT_SOME(os::mkdir(dir));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -426,20 +333,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -448,32 +349,40 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
// in the container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHost)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
"test -f /tmp/test/file.txt");
- const string file = path::join(os::getcwd(), "file");
+ string file = path::join(sandbox.get(), "file");
ASSERT_SOME(os::touch(file));
executor.mutable_container()->CopyFrom(createContainerInfo(
"test_image",
{createVolumeFromHostPath("/tmp/test/file.txt", file, Volume::RW)}));
- const string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -485,15 +394,12 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHost)
AWAIT_READY_FOR(launch, Seconds(60));
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -502,29 +408,40 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHost)
// mount namespace. The mount point will be created in the sandbox.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHostSandboxMountPoint)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
- "test -d mountpoint/sandbox");
+ "test -d mountpoint/dir");
executor.mutable_container()->CopyFrom(createContainerInfo(
"test_image",
- {createVolumeFromHostPath("mountpoint", os::getcwd(), Volume::RW)}));
+ {createVolumeFromHostPath("mountpoint", sandbox.get(), Volume::RW)}));
- string directory = path::join(os::getcwd(), "sandbox");
+ string dir = path::join(sandbox.get(), "dir");
+ ASSERT_SOME(os::mkdir(dir));
+
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -534,20 +451,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHostSandboxMountPoint)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -556,32 +467,40 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHostSandboxMountPoint)
// mount namespace. The mount point will be created in the sandbox.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHostSandboxMountPoint)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
"test -f mountpoint/file.txt");
- const string file = path::join(os::getcwd(), "file");
+ string file = path::join(sandbox.get(), "file");
ASSERT_SOME(os::touch(file));
executor.mutable_container()->CopyFrom(createContainerInfo(
"test_image",
{createVolumeFromHostPath("mountpoint/file.txt", file, Volume::RW)}));
- const string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -593,15 +512,12 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHostSandboxMountPoint)
AWAIT_READY_FOR(launch, Seconds(60));
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -609,20 +525,24 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHostSandboxMountPoint)
// the container's root filesystem.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithRootFilesystem)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- // Need this otherwise the persistent volumes are not created
- // within the slave work_dir and thus not retrievable.
- flags.work_dir = os::getcwd();
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ ASSERT_SOME(create);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ Owned<Containerizer> containerizer(create.get());
- ASSERT_SOME(containerizer);
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
@@ -638,16 +558,16 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithRootFilesystem)
// Create a persistent volume.
string volume = slave::paths::getPersistentVolumePath(
- os::getcwd(),
+ flags.work_dir,
"test_role",
"persistent_volume_id");
ASSERT_SOME(os::mkdir(volume));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -657,41 +577,41 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithRootFilesystem)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file")));
}
+// This test verifies that persistent volumes are properly mounted if
+// the container does not specify a root filesystem.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithoutRootFilesystem)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- // Need this otherwise the persistent volumes are not created
- // within the slave work_dir and thus not retrievable.
- flags.work_dir = os::getcwd();
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ ASSERT_SOME(create);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ Owned<Containerizer> containerizer(create.get());
- ASSERT_SOME(containerizer);
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
@@ -707,22 +627,16 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithoutRootFilesystem)
// Create a persistent volume.
string volume = slave::paths::getPersistentVolumePath(
- os::getcwd(),
+ flags.work_dir,
"test_role",
"persistent_volume_id");
ASSERT_SOME(os::mkdir(volume));
- // To make sure the sandbox directory has the container ID in its
- // path so it doesn't get unmounted by the launcher.
- string directory = slave::paths::createExecutorDirectory(
- flags.work_dir,
- SlaveID(),
- FrameworkID(),
- executor.executor_id(),
- containerId);
+ string directory = path::join(flags.work_dir, "sandbox");
+ ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -732,20 +646,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithoutRootFilesystem)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file")));
}
@@ -756,16 +664,24 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithoutRootFilesystem)
// root filesystem is not specified.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithoutRootFilesystem)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
@@ -773,12 +689,12 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithoutRootFilesystem)
executor.mutable_container()->CopyFrom(createContainerInfo(
None(),
- {createVolumeFromAppcImage("rootfs", "test_image", Volume::RW)}));
+ {createVolumeFromDockerImage("rootfs", "test_image", Volume::RW)}));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -788,20 +704,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithoutRootFilesystem)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -810,31 +720,39 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithoutRootFilesystem)
// root filesystem is specified.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithRootFilesystem)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image_rootfs"));
+ AWAIT_READY(DockerArchive::create(registry, "test_image_volume"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer =
- createContainerizer(
- flags,
- {{"test_image_rootfs", path::join(os::getcwd(), "test_image_rootfs")},
- {"test_image_volume", path::join(os::getcwd(), "test_image_volume")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
ExecutorInfo executor = createExecutorInfo(
"test_executor",
- "[ ! -d '" + os::getcwd() + "' ] && [ -d rootfs/bin ]");
+ "[ ! -d '" + sandbox.get() + "' ] && [ -d rootfs/bin ]");
executor.mutable_container()->CopyFrom(createContainerInfo(
"test_image_rootfs",
- {createVolumeFromAppcImage("rootfs", "test_image_volume", Volume::RW)}));
+ {createVolumeFromDockerImage(
+ "rootfs", "test_image_volume", Volume::RW)}));
- string directory = path::join(os::getcwd(), "sandbox");
+ string directory = path::join(flags.work_dir, "sandbox");
ASSERT_SOME(os::mkdir(directory));
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -844,21 +762,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithRootFilesystem)
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copy.
- AWAIT_READY_FOR(launch, Seconds(240));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->wait(containerId);
- // Because destroy rootfs spents a lot of time, we use 30s as timeout here.
- AWAIT_READY_FOR(wait, Seconds(30));
+ AWAIT_READY(wait);
ASSERT_SOME(wait.get());
-
- // Check the executor exited correctly.
- EXPECT_TRUE(wait->get().has_status());
- EXPECT_EQ(0, wait->get().status());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -866,11 +777,22 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithRootFilesystem)
// launched simultaneously with no interference.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_MultipleContainers)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image1"));
+ AWAIT_READY(DockerArchive::create(registry, "test_image2"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
+
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
+
+ ASSERT_SOME(create);
- // Need this otherwise the persistent volumes are not created
- // within the slave work_dir and thus not retrievable.
- flags.work_dir = os::getcwd();
+ Owned<Containerizer> containerizer(create.get());
ContainerID containerId1;
containerId1.set_value(UUID::random().toString());
@@ -878,23 +800,9 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_MultipleContainers)
ContainerID containerId2;
containerId2.set_value(UUID::random().toString());
- Try<Owned<MesosContainerizer>> containerizer =
- createContainerizer(
- flags,
- {{"test_image1", path::join(os::getcwd(), "test_image1")},
- {"test_image2", path::join(os::getcwd(), "test_image2")}});
-
- ASSERT_SOME(containerizer);
-
- SlaveID slaveId;
- slaveId.set_value("test_agent");
-
- // First launch container 1 which has a long running task which
- // guarantees that its work directory mount is in the host mount
- // table when container 2 is launched.
ExecutorInfo executor1 = createExecutorInfo(
"test_executor1",
- "sleep 1000"); // Long running task.
+ "sleep 1000");
executor1.mutable_container()->CopyFrom(createContainerInfo("test_image1"));
@@ -907,102 +815,94 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_MultipleContainers)
"volume"));
string volume = slave::paths::getPersistentVolumePath(
- os::getcwd(),
+ flags.work_dir,
"test_role",
"persistent_volume_id");
ASSERT_SOME(os::mkdir(volume));
- string directory1 = slave::paths::createExecutorDirectory(
- flags.work_dir,
- slaveId,
- DEFAULT_FRAMEWORK_INFO.id(),
- executor1.executor_id(),
- containerId1);
+ string directory1 = path::join(flags.work_dir, "sandbox");
+ ASSERT_SOME(os::mkdir(directory1));
- Future<bool> launch1 = containerizer.get()->launch(
+ Future<bool> launch1 = containerizer->launch(
containerId1,
None(),
executor1,
directory1,
None(),
- slaveId,
+ SlaveID(),
map<string, string>(),
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copy.
- AWAIT_READY_FOR(launch1, Seconds(120));
+ AWAIT_READY(launch1);
- // Now launch container 2 which will copy the host mount table with
- // container 1's work directory mount in it.
ExecutorInfo executor2 = createExecutorInfo(
"test_executor2",
- "[ ! -d '" + os::getcwd() + "' ]");
+ "[ ! -d '" + sandbox.get() + "' ]");
executor2.mutable_container()->CopyFrom(createContainerInfo("test_image2"));
- string directory2 = slave::paths::createExecutorDirectory(
- flags.work_dir,
- slaveId,
- DEFAULT_FRAMEWORK_INFO.id(),
- executor2.executor_id(),
- containerId2);
+ string directory2 = path::join(flags.work_dir, "sandbox");
+ ASSERT_SOME(os::mkdir(directory2));
- Future<bool> launch2 = containerizer.get()->launch(
+ Future<bool> launch2 = containerizer->launch(
containerId2,
None(),
executor2,
directory2,
None(),
- slaveId,
+ SlaveID(),
map<string, string>(),
false);
- // Need to wait for Rootfs copy.
- AWAIT_READY_FOR(launch1, Seconds(60));
-
- containerizer.get()->destroy(containerId1);
+ AWAIT_READY(launch1);
// Wait on the containers.
Future<Option<ContainerTermination>> wait1 =
- containerizer.get()->wait(containerId1);
+ containerizer->wait(containerId1);
Future<Option<ContainerTermination>> wait2 =
- containerizer.get()->wait(containerId2);
+ containerizer->wait(containerId2);
- AWAIT_READY_FOR(wait1, Seconds(60));
+ containerizer->destroy(containerId1);
+
+ AWAIT_READY(wait1);
ASSERT_SOME(wait1.get());
+ ASSERT_TRUE(wait1->get().has_status());
+ EXPECT_WTERMSIG_EQ(SIGKILL, wait1->get().status());
- AWAIT_READY_FOR(wait2, Seconds(60));
+ AWAIT_READY(wait2);
ASSERT_SOME(wait2.get());
-
- // Executor 1 was forcefully killed.
- EXPECT_TRUE(wait1->get().has_status());
- EXPECT_EQ(9, wait1->get().status());
-
- // Executor 2 exited normally.
- EXPECT_TRUE(wait2->get().has_status());
- EXPECT_EQ(0, wait2->get().status());
+ ASSERT_TRUE(wait2->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait2->get().status());
}
// This test verifies that the environment variables for sandbox
// (i.e., MESOS_DIRECTORY and MESOS_SANDBOX) are set properly.
+// TODO(jieyu): Make this an end to end integration tests.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_SandboxEnvironmentVariable)
{
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- ContainerID containerId;
- containerId.set_value(UUID::random().toString());
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
- string directory = path::join(os::getcwd(), "sandbox");
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
+
+ string directory = path::join(sandbox.get(), "sandbox");
ASSERT_SOME(os::mkdir(directory));
Try<string> script = strings::format(
@@ -1027,7 +927,7 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_SandboxEnvironmentVariable)
PID<Slave>(),
false);
- Future<bool> launch = containerizer.get()->launch(
+ Future<bool> launch = containerizer->launch(
containerId,
None(),
executor,
@@ -1037,20 +937,14 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_SandboxEnvironmentVariable)
environment,
false);
- // Wait for the launch to complete.
- // Need to wait for Rootfs copy.
- AWAIT_READY_FOR(launch, Seconds(60));
+ AWAIT_READY(launch);
- // Wait on the container.
- Future<Option<ContainerTermination>> wait =
- containerizer.get()->wait(containerId);
+ Future<Option<ContainerTermination>> wait = containerizer->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());
+ ASSERT_TRUE(wait->get().has_status());
+ EXPECT_WEXITSTATUS_EQ(0, wait->get().status());
}
@@ -1133,27 +1027,30 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_WorkDirMountNeeded)
}
-// This test verifies that the root filesystem of the container is
-// properly changed to the one that's provisioned by the provisioner.
-// Also runs the command executor with the new root filesystem.
-TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystemCommandExecutor)
+// End to end Mesos integration tests for linux filesystem isolator.
+class LinuxFilesystemIsolatorMesosTest : public LinuxFilesystemIsolatorTest {};
+
+
+// This test verifies that the framework can launch a command task
+// that specifies a container image.
+TEST_F(LinuxFilesystemIsolatorMesosTest,
+ ROOT_ChangeRootFilesystemCommandExecutor)
{
Try<Owned<cluster::Master>> master = StartMaster();
ASSERT_SOME(master);
- slave::Flags flags = CreateSlaveFlags();
- flags.image_provisioner_backend = "copy";
-
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
- ASSERT_SOME(containerizer);
+ slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
Owned<MasterDetector> detector = master.get()->createDetector();
- Try<Owned<cluster::Slave>> slave =
- StartSlave(detector.get(), containerizer.get().get(), flags);
+ Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -1164,9 +1061,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystemCommandExecutor)
master.get()->pid,
DEFAULT_CREDENTIAL);
- Future<FrameworkID> frameworkId;
EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureArg<1>(&frameworkId));
+ .Times(1);
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -1175,8 +1071,6 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystemCommandExecutor)
driver.start();
- AWAIT_READY(frameworkId);
-
AWAIT_READY(offers);
ASSERT_NE(0u, offers->size());
@@ -1187,12 +1081,7 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystemCommandExecutor)
offer.resources(),
"test -d " + flags.sandbox_directory);
- ContainerInfo containerInfo;
- Image* image = containerInfo.mutable_mesos()->mutable_image();
- image->set_type(Image::APPC);
- image->mutable_appc()->set_name("test_image");
- containerInfo.set_type(ContainerInfo::MESOS);
- task.mutable_container()->CopyFrom(containerInfo);
+ task.mutable_container()->CopyFrom(createContainerInfo("test_image"));
driver.launchTasks(offer.id(), {task});
@@ -1203,9 +1092,9 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystemCommandExecutor)
.WillOnce(FutureArg<1>(&statusRunning))
.WillOnce(FutureArg<1>(&statusFinished));
- // Need to wait for Rootfs copying.
- AWAIT_READY_FOR(statusRunning, Seconds(60));
+ AWAIT_READY(statusRunning);
EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
AWAIT_READY(statusFinished);
EXPECT_EQ(TASK_FINISHED, statusFinished->state());
@@ -1214,28 +1103,26 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystemCommandExecutor)
}
-// This test verifies that the root filesystem of the container is
-// properly changed to the one that's provisioned by the provisioner.
-// Also runs the command executor with the new root filesystem.
-TEST_F(LinuxFilesystemIsolatorTest,
- ROOT_ChangeRootFilesystemCommandExecutorWithVolumes)
+// This test verifies that the framework can launch a command task
+// that specifies both container image and host volumes.
+TEST_F(LinuxFilesystemIsolatorMesosTest,
+ ROOT_ChangeRootFilesystemCommandExecutorWithHostVolumes)
{
Try<Owned<cluster::Master>> master = StartMaster();
ASSERT_SOME(master);
- slave::Flags flags = CreateSlaveFlags();
- flags.image_provisioner_backend = "copy";
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
-
- ASSERT_SOME(containerizer);
+ slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
Owned<MasterDetector> detector = master.get()->createDetector();
- Try<Owned<cluster::Slave>> slave =
- StartSlave(detector.get(), containerizer.get().get(), flags);
+ Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -1246,9 +1133,8 @@ TEST_F(LinuxFilesystemIsolatorTest,
master.get()->pid,
DEFAULT_CREDENTIAL);
- Future<FrameworkID> frameworkId;
EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureArg<1>(&frameworkId));
+ .Times(1);
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -1257,8 +1143,6 @@ TEST_F(LinuxFilesystemIsolatorTest,
driver.start();
- AWAIT_READY(frameworkId);
-
AWAIT_READY(offers);
ASSERT_NE(0u, offers->size());
@@ -1267,13 +1151,13 @@ TEST_F(LinuxFilesystemIsolatorTest,
// Preparing two volumes:
// - host_path: dir1, container_path: /tmp
// - host_path: dir2, container_path: relative_dir
- const string dir1 = path::join(os::getcwd(), "dir1");
+ string dir1 = path::join(sandbox.get(), "dir1");
ASSERT_SOME(os::mkdir(dir1));
- const string testFile = path::join(dir1, "testfile");
+ string testFile = path::join(dir1, "testfile");
ASSERT_SOME(os::touch(testFile));
- const string dir2 = path::join(os::getcwd(), "dir2");
+ string dir2 = path::join(sandbox.get(), "dir2");
ASSERT_SOME(os::mkdir(dir2));
TaskInfo task = createTask(
@@ -1282,19 +1166,10 @@ TEST_F(LinuxFilesystemIsolatorTest,
"test -f /tmp/testfile && test -d " +
path::join(flags.sandbox_directory, "relative_dir"));
- ContainerInfo containerInfo;
- Image* image = containerInfo.mutable_mesos()->mutable_image();
- image->set_type(Image::APPC);
- image->mutable_appc()->set_name("test_image");
- containerInfo.set_type(ContainerInfo::MESOS);
-
- // We are assuming the image created by the tests have /tmp to be
- // able to mount the directory.
- containerInfo.add_volumes()->CopyFrom(
- createVolumeFromHostPath("/tmp", dir1, Volume::RW));
- containerInfo.add_volumes()->CopyFrom(
- createVolumeFromHostPath("relative_dir", dir2, Volume::RW));
- task.mutable_container()->CopyFrom(containerInfo);
+ task.mutable_container()->CopyFrom(createContainerInfo(
+ "test_image",
+ {createVolumeFromHostPath("/tmp", dir1, Volume::RW),
+ createVolumeFromHostPath("relative_dir", dir2, Volume::RW)}));
driver.launchTasks(offer.id(), {task});
@@ -1307,6 +1182,7 @@ TEST_F(LinuxFilesystemIsolatorTest,
AWAIT_READY(statusRunning);
EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
AWAIT_READY(statusFinished);
EXPECT_EQ(TASK_FINISHED, statusFinished->state());
@@ -1315,32 +1191,27 @@ TEST_F(LinuxFilesystemIsolatorTest,
}
-// This test verifies that a command task with new root filesystem
-// with persistent volumes works correctly.
-TEST_F(LinuxFilesystemIsolatorTest,
+// This test verifies that the framework can launch a command task
+// that specifies both container image and persistent volumes.
+TEST_F(LinuxFilesystemIsolatorMesosTest,
ROOT_ChangeRootFilesystemCommandExecutorPersistentVolume)
{
Try<Owned<cluster::Master>> master = StartMaster();
ASSERT_SOME(master);
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
- flags.image_provisioner_backend = "copy";
flags.resources = "cpus:2;mem:1024;disk(role1):1024";
-
- // Need this otherwise the persistent volumes are not created
- // within the slave work_dir and thus not retrievable.
- flags.work_dir = os::getcwd();
-
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
-
- ASSERT_SOME(containerizer);
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
Owned<MasterDetector> detector = master.get()->createDetector();
- Try<Owned<cluster::Slave>> slave =
- StartSlave(detector.get(), containerizer.get().get(), flags);
+ Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -1371,7 +1242,7 @@ TEST_F(LinuxFilesystemIsolatorTest,
Offer offer = offers.get()[0];
- const string dir1 = path::join(os::getcwd(), "dir1");
+ string dir1 = path::join(sandbox.get(), "dir1");
ASSERT_SOME(os::mkdir(dir1));
Resource persistentVolume = createPersistentVolume(
@@ -1392,17 +1263,10 @@ TEST_F(LinuxFilesystemIsolatorTest,
offer.slave_id(),
Resources::parse("cpus:1;mem:512").get() + persistentVolume,
"echo abc > path1/file");
- ContainerInfo containerInfo;
- Image* image = containerInfo.mutable_mesos()->mutable_image();
- image->set_type(Image::APPC);
- image->mutable_appc()->set_name("test_image");
- containerInfo.set_type(ContainerInfo::MESOS);
-
- // We are assuming the image created by the tests have /tmp to be
- // able to mount the directory.
- containerInfo.add_volumes()->CopyFrom(
- createVolumeFromHostPath("/tmp", dir1, Volume::RW));
- task.mutable_container()->CopyFrom(containerInfo);
+
+ task.mutable_container()->CopyFrom(createContainerInfo(
+ "test_image",
+ {createVolumeFromHostPath("/tmp", dir1, Volume::RW)}));
// Create the persistent volumes and launch task via `acceptOffers`.
driver.acceptOffers(
@@ -1419,6 +1283,7 @@ TEST_F(LinuxFilesystemIsolatorTest,
AWAIT_READY(statusRunning);
EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
AWAIT_READY(statusFinished);
EXPECT_EQ(TASK_FINISHED, statusFinished->state());
@@ -1426,7 +1291,7 @@ TEST_F(LinuxFilesystemIsolatorTest,
ExecutorID executorId;
executorId.set_value(task.task_id().value());
- const string& directory = slave::paths::getExecutorLatestRunPath(
+ string directory = slave::paths::getExecutorLatestRunPath(
flags.work_dir,
offer.slave_id(),
frameworkId.get(),
@@ -1434,7 +1299,7 @@ TEST_F(LinuxFilesystemIsolatorTest,
EXPECT_FALSE(os::exists(path::join(directory, "path1")));
- const string& volumePath = slave::paths::getPersistentVolumePath(
+ string volumePath = slave::paths::getPersistentVolumePath(
flags.work_dir,
"role1",
"id1");
@@ -1453,26 +1318,36 @@ TEST_F(LinuxFilesystemIsolatorTest,
// filesystem root, the executor (command executor) itself does not
// change filesystem root (uses the host filesystem). We need to add a
// test to test the scenario that the executor itself changes rootfs.
-TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
+TEST_F(LinuxFilesystemIsolatorMesosTest,
+ ROOT_RecoverOrphanedPersistentVolume)
{
Try<Owned<cluster::Master>> master = StartMaster();
ASSERT_SOME(master);
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
- flags.image_provisioner_backend = "copy";
flags.resources = "cpus:2;mem:1024;disk(role1):1024";
- flags.isolation = "disk/du,filesystem/linux";
+ flags.isolation = "filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
- Try<Owned<MesosContainerizer>> containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ Try<MesosContainerizer*> create =
+ MesosContainerizer::create(flags, true, &fetcher);
+
+ ASSERT_SOME(create);
- ASSERT_SOME(containerizer);
+ Owned<Containerizer> containerizer(create.get());
Owned<MasterDetector> detector = master.get()->createDetector();
- Try<Owned<cluster::Slave>> slave =
- StartSlave(detector.get(), containerizer.get().get(), flags);
+ Try<Owned<cluster::Slave>> slave = StartSlave(
+ detector.get(),
+ containerizer.get(),
+ flags);
+
ASSERT_SOME(slave);
MockScheduler sched;
@@ -1486,9 +1361,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
master.get()->pid,
DEFAULT_CREDENTIAL);
- Future<FrameworkID> frameworkId;
EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureArg<1>(&frameworkId));
+ .Times(1);
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -1497,14 +1371,12 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
driver.start();
- AWAIT_READY(frameworkId);
-
AWAIT_READY(offers);
EXPECT_FALSE(offers->empty());
Offer offer = offers.get()[0];
- const string dir1 = path::join(os::getcwd(), "dir1");
+ string dir1 = path::join(sandbox.get(), "dir1");
ASSERT_SOME(os::mkdir(dir1));
Resource persistentVolume = createPersistentVolume(
@@ -1522,17 +1394,9 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
Resources::parse("cpus:1;mem:512").get() + persistentVolume,
"sleep 1000");
- ContainerInfo containerInfo;
- Image* image = containerInfo.mutable_mesos()->mutable_image();
- image->set_type(Image::APPC);
- image->mutable_appc()->set_name("test_image");
- containerInfo.set_type(ContainerInfo::MESOS);
-
- // We are assuming the image created by the tests have /tmp to be
- // able to mount the directory.
- containerInfo.add_volumes()->CopyFrom(
- createVolumeFromHostPath("/tmp", dir1, Volume::RW));
- task.mutable_container()->CopyFrom(containerInfo);
+ task.mutable_container()->CopyFrom(createContainerInfo(
+ "test_image",
+ {createVolumeFromHostPath("/tmp", dir1, Volume::RW)}));
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(&driver, _))
@@ -1553,7 +1417,7 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
// Wait for the ACK to be checkpointed.
AWAIT_READY(ack);
- Future<hashset<ContainerID>> containers = containerizer.get()->containers();
+ Future<hashset<ContainerID>> containers = containerizer->containers();
AWAIT_READY(containers);
EXPECT_EQ(1u, containers.get().size());
@@ -1568,25 +1432,26 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
ASSERT_SOME(os::rmdir(slave::paths::getMetaRootDir(flags.work_dir)));
// Recreate the containerizer using the same helper as above.
- containerizer = createContainerizer(
- flags,
- {{"test_image", path::join(os::getcwd(), "test_image")}});
+ containerizer.reset();
- slave = StartSlave(detector.get(), containerizer.get().get(), flags);
+ create = MesosContainerizer::create(flags, true, &fetcher);
+ containerizer.reset(create.get());
+
+ slave = StartSlave(detector.get(), containerizer.get(), flags);
ASSERT_SOME(slave);
// Wait until slave recovery is complete.
Future<Nothing> _recover = FUTURE_DISPATCH(_, &Slave::_recover);
- AWAIT_READY_FOR(_recover, Seconds(60));
+ AWAIT_READY(_recover);
// Wait until the orphan containers are cleaned up.
- AWAIT_READY_FOR(containerizer.get()->wait(containerId), Seconds(60));
+ AWAIT_READY(containerizer->wait(containerId));
Try<fs::MountInfoTable> table = fs::MountInfoTable::read();
ASSERT_SOME(table);
// All mount targets should be under this directory.
- const string directory = slave::paths::getSandboxRootDir(flags.work_dir);
+ string directory = slave::paths::getSandboxRootDir(flags.work_dir);
// Verify that the orphaned container's persistent volume and
// the rootfs are unmounted.
@@ -1600,25 +1465,30 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_RecoverOrphanedPersistentVolume)
}
-// This test verifies that the volume usage accounting for sandboxes with
-// bind-mounted volumes works correctly by creating a file within the volume
-// the size of which exceeds the sandbox quota.
-TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeUsageExceedsSandboxQuota)
+// This test verifies that the volume usage accounting for sandboxes
+// with bind-mounted volumes (while linux filesystem isolator is used)
+// works correctly by creating a file within the volume the size of
+// which exceeds the sandbox quota.
+TEST_F(LinuxFilesystemIsolatorMesosTest,
+ ROOT_VolumeUsageExceedsSandboxQuota)
{
- FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
- frameworkInfo.set_role("role1");
-
Try<Owned<cluster::Master>> master = StartMaster();
ASSERT_SOME(master);
+ string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
slave::Flags flags = CreateSlaveFlags();
- flags.isolation = "disk/du,filesystem/linux";
+ flags.resources = "cpus:2;mem:128;disk(role1):128";
+ flags.isolation = "disk/du,filesystem/linux,docker/runtime";
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(sandbox.get(), "store");
+ flags.image_providers = "docker";
// NOTE: We can't pause the clock because we need the reaper to reap
// the 'du' subprocess.
flags.container_disk_watch_interval = Milliseconds(1);
flags.enforce_container_disk_quota = true;
- flags.resources = "cpus:2;mem:128;disk(role1):128";
Owned<MasterDetector> detector = master.get()->createDetector();
@@ -1626,6 +1496,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeUsageExceedsSandboxQuota)
ASSERT_SOME(slave);
MockScheduler sched;
+ FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+ frameworkInfo.set_role("role1");
MesosSchedulerDriver driver(
&sched,
@@ -1633,9 +1505,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeUsageExceedsSandboxQuota)
master.get()->pid,
DEFAULT_CREDENTIAL);
- Future<FrameworkID> frameworkId;
EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureArg<1>(&frameworkId));
+ .Times(1);
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -1644,8 +1515,6 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeUsageExceedsSandboxQuota)
driver.start();
- AWAIT_READY(frameworkId);
-
AWAIT_READY(offers);
ASSERT_NE(0u, offers->size());
http://git-wip-us.apache.org/repos/asf/mesos/blob/a089d4a7/src/tests/mesos.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.hpp b/src/tests/mesos.hpp
index 8d2d7f4..54c035d 100644
--- a/src/tests/mesos.hpp
+++ b/src/tests/mesos.hpp
@@ -434,7 +434,7 @@ inline Volume createVolumeFromHostPath(
}
-inline Volume createVolumeFromAppcImage(
+inline Volume createVolumeFromDockerImage(
const std::string& containerPath,
const std::string& imageName,
const Volume::Mode& mode)
@@ -442,8 +442,8 @@ inline Volume createVolumeFromAppcImage(
Volume volume;
volume.set_container_path(containerPath);
volume.set_mode(mode);
- volume.mutable_image()->set_type(Image::APPC);
- volume.mutable_image()->mutable_appc()->set_name(imageName);
+ volume.mutable_image()->set_type(Image::DOCKER);
+ volume.mutable_image()->mutable_docker()->set_name(imageName);
return volume;
}