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/03/19 18:41:19 UTC
mesos git commit: Fixed a bug that causes the task stuck in staging
state.
Repository: mesos
Updated Branches:
refs/heads/master 4edd79b68 -> 4d2b1b793
Fixed a bug that causes the task stuck in staging state.
Review: https://reviews.apache.org/r/44435/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4d2b1b79
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4d2b1b79
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4d2b1b79
Branch: refs/heads/master
Commit: 4d2b1b793e07a9c90b984ca330a3d7bc9e1404cc
Parents: 4edd79b
Author: Shuai Lin <li...@gmail.com>
Authored: Sat Mar 19 10:38:47 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Sat Mar 19 10:41:10 2016 -0700
----------------------------------------------------------------------
src/slave/containerizer/mesos/containerizer.cpp | 10 ++
.../containerizer/mesos_containerizer_tests.cpp | 116 +++++++++++++++++++
2 files changed, 126 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/4d2b1b79/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 4638d08..ee7a265 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -672,6 +672,16 @@ Future<bool> MesosContainerizerProcess::launch(
container->state = PREPARING;
container->resources = executorInfo.resources();
+ // TODO(lins05): It's possible that we call provisioner->destroy
+ // while provisioner->provision is in progress. This could cause
+ // leaking of the provisioned directory. See MESOS-4985.
+
+ // We need to set the `launchInfos` to be a ready future initially
+ // before we starting calling isolator->prepare() because otherwise,
+ // the destroy will wait forever trying to wait for this future to
+ // be ready , which it never will. See MESOS-4878.
+ container->launchInfos = list<Option<ContainerLaunchInfo>>();
+
containers_.put(containerId, Owned<Container>(container));
if (!executorInfo.has_container()) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/4d2b1b79/src/tests/containerizer/mesos_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/mesos_containerizer_tests.cpp b/src/tests/containerizer/mesos_containerizer_tests.cpp
index e849932..f3ca32b 100644
--- a/src/tests/containerizer/mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/mesos_containerizer_tests.cpp
@@ -703,6 +703,122 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhilePreparing)
}
+class MesosContainerizerProvisionerTest : public MesosTest {};
+
+
+class MockProvisioner : public mesos::internal::slave::Provisioner
+{
+public:
+ MockProvisioner() {}
+ MOCK_METHOD2(recover,
+ Future<Nothing>(const list<ContainerState>&,
+ const hashset<ContainerID>&));
+
+ MOCK_METHOD2(provision,
+ Future<mesos::internal::slave::ProvisionInfo>(
+ const ContainerID&,
+ const Image&));
+
+ MOCK_METHOD1(destroy, Future<bool>(const ContainerID&));
+};
+
+
+// This test verifies that when the provision fails, the containerizer
+// can be destroyed successfully.
+TEST_F(MesosContainerizerProvisionerTest, ProvisionFailed)
+{
+ slave::Flags flags = CreateSlaveFlags();
+
+ Try<Launcher*> launcher_ = PosixLauncher::create(flags);
+ ASSERT_SOME(launcher_);
+
+ TestLauncher* launcher = new TestLauncher(Owned<Launcher>(launcher_.get()));
+
+ MockProvisioner* provisioner = new MockProvisioner();
+
+ Future<Nothing> provision;
+
+ // Simulate a provision failure.
+ EXPECT_CALL(*provisioner, provision(_, _))
+ .WillOnce(DoAll(FutureSatisfy(&provision),
+ Return(Failure("provision failure"))));
+
+ EXPECT_CALL(*provisioner, destroy(_))
+ .WillOnce(Return(true));
+
+ Fetcher fetcher;
+
+ Try<ContainerLogger*> logger =
+ ContainerLogger::create(flags.container_logger);
+
+ ASSERT_SOME(logger);
+
+ MesosContainerizerProcess* process = new MesosContainerizerProcess(
+ flags,
+ true,
+ &fetcher,
+ Owned<ContainerLogger>(logger.get()),
+ Owned<Launcher>(launcher),
+ Owned<Provisioner>(provisioner),
+ vector<Owned<Isolator>>());
+
+ MesosContainerizer containerizer((Owned<MesosContainerizerProcess>(process)));
+
+ ContainerID containerId;
+ containerId.set_value("test_container");
+
+ TaskInfo taskInfo;
+ CommandInfo commandInfo;
+ taskInfo.mutable_command()->MergeFrom(commandInfo);
+
+ Image image;
+ image.set_type(Image::DOCKER);
+ Image::Docker dockerImage;
+ dockerImage.set_name(UUID::random().toString());
+ image.mutable_docker()->CopyFrom(dockerImage);
+
+ ContainerInfo::MesosInfo mesosInfo;
+ mesosInfo.mutable_image()->CopyFrom(image);
+
+ ContainerInfo containerInfo;
+ containerInfo.set_type(ContainerInfo::MESOS);
+ containerInfo.mutable_mesos()->CopyFrom(mesosInfo);
+
+ ExecutorInfo executorInfo = CREATE_EXECUTOR_INFO("executor", "exit 0");
+ executorInfo.mutable_container()->CopyFrom(containerInfo);
+
+ Future<bool> launch = containerizer.launch(
+ containerId,
+ taskInfo,
+ executorInfo,
+ os::getcwd(),
+ None(),
+ SlaveID(),
+ PID<Slave>(),
+ false);
+
+ AWAIT_READY(provision);
+
+ AWAIT_FAILED(launch);
+
+ Future<containerizer::Termination> wait = containerizer.wait(containerId);
+
+ containerizer.destroy(containerId);
+
+ AWAIT_READY(wait);
+
+ containerizer::Termination termination = wait.get();
+
+ // TODO(lins05): Improve the assertion once we add the
+ // "PROVISIONING" state. See MESOS-4985.
+ EXPECT_EQ(
+ "Container destroyed while preparing isolators",
+ termination.message());
+
+ EXPECT_FALSE(termination.has_status());
+}
+
+
// This action destroys the container using the real launcher and
// waits until the destroy is complete.
ACTION_P(InvokeDestroyAndWait, launcher)