You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2016/04/25 23:15:25 UTC

[09/24] mesos git commit: Fixed a bug that causes the task stuck in staging state.

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/5b2aa00d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5b2aa00d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5b2aa00d

Branch: refs/heads/0.28.x
Commit: 5b2aa00da39de776f9a7bfa234bec586431a8dde
Parents: 961edbd
Author: Shuai Lin <li...@gmail.com>
Authored: Sat Mar 19 10:38:47 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Apr 5 15:10:01 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/5b2aa00d/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index af3ff57..630d851 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/5b2aa00d/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 15f0f93..570e791 100644
--- a/src/tests/containerizer/mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/mesos_containerizer_tests.cpp
@@ -712,6 +712,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)