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 2015/08/08 02:13:59 UTC

[1/8] mesos git commit: Created a test abstraction for preparing test rootfs.

Repository: mesos
Updated Branches:
  refs/heads/master 7b83081c6 -> fbcc3922d


Created a test abstraction for preparing test rootfs.

Review: https://reviews.apache.org/r/36956


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f077ae66
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f077ae66
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f077ae66

Branch: refs/heads/master
Commit: f077ae6626f04e95e47ee24ffa7ad401ad8ebfae
Parents: 7b83081
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Jul 30 15:07:30 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:30:36 2015 -0700

----------------------------------------------------------------------
 src/Makefile.am                          |   1 +
 src/tests/containerizer/launch_tests.cpp | 132 +++++------------------
 src/tests/containerizer/rootfs.hpp       | 145 ++++++++++++++++++++++++++
 3 files changed, 173 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f077ae66/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 35ebbbd..c213ac7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -665,6 +665,7 @@ libmesos_no_3rdparty_la_SOURCES +=					\
 	tests/containerizer/isolator.hpp				\
 	tests/containerizer/launcher.hpp				\
 	tests/containerizer/memory_test_helper.hpp			\
+	tests/containerizer/rootfs.hpp					\
 	tests/containerizer/setns_test_helper.hpp			\
 	usage/usage.hpp							\
 	watcher/whitelist_watcher.hpp					\

http://git-wip-us.apache.org/repos/asf/mesos/blob/f077ae66/src/tests/containerizer/launch_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/launch_tests.cpp b/src/tests/containerizer/launch_tests.cpp
index 73c8c5f..d211fc0 100644
--- a/src/tests/containerizer/launch_tests.cpp
+++ b/src/tests/containerizer/launch_tests.cpp
@@ -21,25 +21,23 @@
 
 #include <gmock/gmock.h>
 
-#include <stout/foreach.hpp>
 #include <stout/gtest.hpp>
+#include <stout/none.hpp>
+#include <stout/option.hpp>
 #include <stout/os.hpp>
 #include <stout/try.hpp>
 
 #include <process/gtest.hpp>
-#include <process/io.hpp>
 #include <process/reap.hpp>
 #include <process/subprocess.hpp>
 
-#include "mesos/resources.hpp"
-
 #include "slave/containerizer/mesos/launch.hpp"
 
-#include "linux/fs.hpp"
-
 #include "tests/flags.hpp"
 #include "tests/utils.hpp"
 
+#include "tests/containerizer/rootfs.hpp"
+
 using namespace process;
 
 using std::string;
@@ -49,62 +47,15 @@ namespace mesos {
 namespace internal {
 namespace tests {
 
-class Chroot
-{
-public:
-  Chroot(const string& _rootfs)
-    : rootfs(_rootfs) {}
-
-  virtual ~Chroot() {}
+// TODO(jieyu): Move this test to mesos_containerizer_tests.cpp once
+// we have a filesystem isolator that supports changing rootfs.
 
-  virtual Try<Subprocess> run(const string& command) = 0;
-
-  const string rootfs;
-};
-
-
-class BasicLinuxChroot : public Chroot
+class MesosContainerizerLaunchTest : public TemporaryDirectoryTest
 {
 public:
-  static Try<Owned<Chroot>> create(const string& rootfs)
-  {
-    if (!os::exists(rootfs)) {
-      return Error("rootfs does not exist");
-    }
-
-    if (os::system("cp -r /bin " + rootfs + "/") != 0) {
-      return ErrnoError("Failed to copy /bin to chroot");
-    }
-
-    if (os::system("cp -r /lib " + rootfs + "/") != 0) {
-      return ErrnoError("Failed to copy /lib to chroot");
-    }
-
-    if (os::system("cp -r /lib64 " + rootfs + "/") != 0) {
-      return ErrnoError("Failed to copy /lib64 to chroot");
-    }
-
-    vector<string> directories = {"proc", "sys", "dev", "tmp"};
-    foreach (const string& directory, directories) {
-      Try<Nothing> mkdir = os::mkdir(path::join(rootfs, directory));
-      if (mkdir.isError()) {
-        return Error("Failed to create /" + directory + " in chroot: " +
-                     mkdir.error());
-      }
-    }
-
-    // We need to bind mount the rootfs so we can pivot on it.
-    Try<Nothing> mount =
-      fs::mount(rootfs, rootfs, None(), MS_BIND | MS_SLAVE, NULL);
-
-    if (mount.isError()) {
-      return Error("Failed to bind mount chroot rootfs: " + mount.error());
-    }
-
-    return Owned<Chroot>(new BasicLinuxChroot(rootfs));
-  }
-
-  virtual Try<Subprocess> run(const string& _command)
+  Try<Subprocess> run(
+      const string& _command,
+      const Option<string>& rootfs = None())
   {
     slave::MesosContainerizerLaunch::Flags launchFlags;
 
@@ -125,23 +76,15 @@ public:
         path::join(tests::flags.build_dir, "src", "mesos-containerizer"),
         argv,
         Subprocess::PATH("/dev/null"),
-        Subprocess::PIPE(),
+        Subprocess::FD(STDOUT_FILENO),
         Subprocess::FD(STDERR_FILENO),
         launchFlags,
         None(),
         None(),
         lambda::bind(&clone, lambda::_1));
 
-    if (s.isError()) {
-      close(launchFlags.pipe_read.get());
-      close(launchFlags.pipe_write.get());
-    } else {
-      s.get().status().onAny([=]() {
-        // Close when the subprocess terminates.
-        close(launchFlags.pipe_read.get());
-        close(launchFlags.pipe_write.get());
-      });
-    }
+    close(launchFlags.pipe_read.get());
+    close(launchFlags.pipe_write.get());
 
     return s;
   }
@@ -165,47 +108,26 @@ private:
 
     return (*_f)();
   }
-
-  BasicLinuxChroot(const string& rootfs) : Chroot(rootfs) {}
-
-  ~BasicLinuxChroot()
-  {
-    // Because the test process has the rootfs as its cwd the umount
-    // won't actually happen until the
-    // TemporaryDirectoryTest::TearDown() changes back to the original
-    // directory.
-    fs::unmount(rootfs, MNT_DETACH);
-  }
 };
 
 
-template <typename T>
-class LaunchChrootTest : public TemporaryDirectoryTest {};
-
-
-// TODO(idownes): Add tests for OSX chroots.
-typedef ::testing::Types<BasicLinuxChroot> ChrootTypes;
-
-
-TYPED_TEST_CASE(LaunchChrootTest, ChrootTypes);
-
-
-TYPED_TEST(LaunchChrootTest, ROOT_DifferentRoot)
+TEST_F(MesosContainerizerLaunchTest, ROOT_ChangeRootfs)
 {
-  Try<Owned<Chroot>> chroot = TypeParam::create(os::getcwd());
-  ASSERT_SOME(chroot);
+  Try<Owned<Rootfs>> rootfs =
+    LinuxRootfs::create(path::join(os::getcwd(), "rootfs"));
+
+  ASSERT_SOME(rootfs);
 
-  // Add /usr/bin/stat into the chroot.
-  const string usrbin = path::join(chroot.get()->rootfs, "usr", "bin");
-  ASSERT_SOME(os::mkdir(usrbin));
-  ASSERT_EQ(0, os::system("cp /usr/bin/stat " + path::join(usrbin, "stat")));
+  // Add /usr/bin/stat into the rootfs.
+  ASSERT_SOME(rootfs.get()->add("/usr/bin/stat"));
 
   Clock::pause();
 
-  Try<Subprocess> s = chroot.get()->run(
-      "/usr/bin/stat -c %i / >" + path::join("/", "stat.output"));
+  Try<Subprocess> s = run(
+      "/usr/bin/stat -c %i / >" + path::join("/", "stat.output"),
+      rootfs.get()->root);
 
-  CHECK_SOME(s);
+  ASSERT_SOME(s);
 
   // Advance time until the internal reaper reaps the subprocess.
   while (s.get().status().isPending()) {
@@ -220,12 +142,12 @@ TYPED_TEST(LaunchChrootTest, ROOT_DifferentRoot)
   ASSERT_TRUE(WIFEXITED(status));
   ASSERT_EQ(0, WEXITSTATUS(status));
 
-  // Check the chroot has a different root by comparing the inodes.
+  // Check the rootfs has a different root by comparing the inodes.
   Try<ino_t> self = os::stat::inode("/");
   ASSERT_SOME(self);
 
-  Try<string> read = os::read(path::join(chroot.get()->rootfs, "stat.output"));
-  CHECK_SOME(read);
+  Try<string> read = os::read(path::join(rootfs.get()->root, "stat.output"));
+  ASSERT_SOME(read);
 
   Try<ino_t> other = numify<ino_t>(strings::trim(read.get()));
   ASSERT_SOME(other);

http://git-wip-us.apache.org/repos/asf/mesos/blob/f077ae66/src/tests/containerizer/rootfs.hpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/rootfs.hpp b/src/tests/containerizer/rootfs.hpp
new file mode 100644
index 0000000..55dd496
--- /dev/null
+++ b/src/tests/containerizer/rootfs.hpp
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TEST_ROOTFS_HPP__
+#define __TEST_ROOTFS_HPP__
+
+#include <string>
+#include <vector>
+
+#include <process/owned.hpp>
+
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/nothing.hpp>
+#include <stout/os.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+class Rootfs {
+public:
+  virtual ~Rootfs()
+  {
+    if (os::exists(root)) {
+      os::rmdir(root);
+    }
+  }
+
+  // Add a host directory or file to the root filesystem. Note that
+  // the host directory or file needs to be an absolute path.
+  Try<Nothing> add(const std::string& path)
+  {
+    if (!os::exists(path)) {
+      return Error("File or directory not found on the host");
+    }
+
+    if (!strings::startsWith(path, "/")) {
+      return Error("Not an absolute path");
+    }
+
+    // TODO(jieyu): Make sure 'path' is not under 'root'.
+
+    if (os::stat::isdir(path)) {
+      if (os::system("cp -r '" + path + "' '" + root + "'") != 0) {
+        return ErrnoError("Failed to copy '" + path + "' to rootfs");
+      }
+    } else if (os::stat::isfile(path)) {
+      std::string dirname = Path(path).dirname();
+      std::string target = path::join(root, dirname);
+
+      Try<Nothing> mkdir = os::mkdir(target);
+      if (mkdir.isError()) {
+        return Error("Failed to create directory in rootfs: " + mkdir.error());
+      }
+
+      if (os::system("cp '" + path + "' '" + target + "'") != 0) {
+        return ErrnoError("Failed to copy '" + path + "' to rootfs");
+      }
+    } else {
+      return Error("Unsupported file or directory");
+    }
+
+    return Nothing();
+  }
+
+  const std::string root;
+
+protected:
+  Rootfs(const std::string& _root) : root(_root) {}
+};
+
+
+class LinuxRootfs : public Rootfs
+{
+public:
+  static Try<process::Owned<Rootfs>> create(const std::string& root)
+  {
+    process::Owned<Rootfs> rootfs(new LinuxRootfs(root));
+
+    if (!os::exists(root)) {
+      Try<Nothing> mkdir = os::mkdir(root);
+      if (mkdir.isError()) {
+        return Error("Failed to create root directory: " + mkdir.error());
+      }
+    }
+
+    std::vector<std::string> directories = {
+      "/bin",
+      "/lib",
+      "/lib64"
+    };
+
+    foreach (const std::string& directory, directories) {
+      Try<Nothing> result = rootfs->add(directory);
+      if (result.isError()) {
+        return Error("Failed to add '" + directory +
+                     "' to rootfs: " + result.error());
+      }
+    }
+
+    directories = {
+      "/proc",
+      "/sys",
+      "/dev",
+      "/tmp"
+    };
+
+    foreach (const std::string& directory, directories) {
+      Try<Nothing> mkdir = os::mkdir(path::join(root, directory));
+      if (mkdir.isError()) {
+        return Error("Failed to create '" + directory +
+                     "' in rootfs: " + mkdir.error());
+      }
+    }
+
+    return rootfs;
+  }
+
+protected:
+  LinuxRootfs(const std::string& root) : Rootfs(root) {}
+};
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __TEST_ROOTFS_HPP__


[4/8] mesos git commit: Removed the unneeded ExecutorInfo from Container struct in MesosContainerizer.

Posted by ji...@apache.org.
Removed the unneeded ExecutorInfo from Container struct in MesosContainerizer.

Review: https://reviews.apache.org/r/37142


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/39d5e5fe
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/39d5e5fe
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/39d5e5fe

Branch: refs/heads/master
Commit: 39d5e5fee2348d73235e9acee919d3ac21a53a33
Parents: 3a86213
Author: Jie Yu <yu...@gmail.com>
Authored: Wed Aug 5 11:23:40 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:54:14 2015 -0700

----------------------------------------------------------------------
 src/slave/containerizer/mesos/containerizer.cpp | 13 -------------
 src/slave/containerizer/mesos/containerizer.hpp |  3 ---
 2 files changed, 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/39d5e5fe/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 78db4c1..758ed1c 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -477,18 +477,6 @@ Future<Nothing> MesosContainerizerProcess::__recover(
     // containers should be running after recover.
     container->state = RUNNING;
 
-    // Add the default container info to the executor info.
-    // TODO(jieyu): Checkpoint the default container info in case the
-    // slave changes the default container info flag.
-    ExecutorInfo executorInfo = run.executor_info();
-    if (!executorInfo.has_container() &&
-        flags.default_container_info.isSome()) {
-      executorInfo.mutable_container()->CopyFrom(
-          flags.default_container_info.get());
-    }
-
-    container->executorInfo = executorInfo;
-
     containers_[containerId] = Owned<Container>(container);
 
     foreach (const Owned<Isolator>& isolator, isolators) {
@@ -622,7 +610,6 @@ Future<bool> MesosContainerizerProcess::launch(
             << "' of framework '" << executorInfo.framework_id() << "'";
 
   Container* container = new Container();
-  container->executorInfo = executorInfo;
   container->directory = directory;
   container->state = PREPARING;
   container->resources = executorInfo.resources();

http://git-wip-us.apache.org/repos/asf/mesos/blob/39d5e5fe/src/slave/containerizer/mesos/containerizer.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.hpp b/src/slave/containerizer/mesos/containerizer.hpp
index 8bfd622..066d541 100644
--- a/src/slave/containerizer/mesos/containerizer.hpp
+++ b/src/slave/containerizer/mesos/containerizer.hpp
@@ -318,9 +318,6 @@ private:
     // ResourceStatistics limits in usage().
     Resources resources;
 
-    // We keep track of the ExecutorInfo so we have the optional ContainerInfo.
-    ExecutorInfo executorInfo;
-
     // The executor's working directory on the host.
     std::string directory;
 


[3/8] mesos git commit: Added Image to Volume as one of the sources.

Posted by ji...@apache.org.
Added Image to Volume as one of the sources.

Review: https://reviews.apache.org/r/37055


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d9443935
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d9443935
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d9443935

Branch: refs/heads/master
Commit: d9443935557a9254d68625fadd1c6e5d0f268a3f
Parents: ddfab61
Author: Jie Yu <yu...@gmail.com>
Authored: Mon Aug 3 16:07:33 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:54:10 2015 -0700

----------------------------------------------------------------------
 include/mesos/mesos.proto | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/d9443935/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 3e55089..80f56ac 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1228,19 +1228,26 @@ message Image {
  * versa. Both paths can either refer to a directory or a file.
  */
 message Volume {
-  // Absolute path pointing to a directory or file in the container.
-  required string container_path = 1;
-
-  // Absolute path pointing to a directory or file on the host or a path
-  // relative to the container work directory.
-  optional string host_path = 2;
-
   enum Mode {
     RW = 1; // read-write.
     RO = 2; // read-only.
   }
 
   required Mode mode = 3;
+
+  // Absolute path pointing to a directory or file in the container.
+  required string container_path = 1;
+
+  // The following specifies the source of this volume. At most one of
+  // the following should be set.
+
+  // Absolute path pointing to a directory or file on the host or a
+  // path relative to the container work directory.
+  optional string host_path = 2;
+
+  // The source of the volume is an Image which describes a root
+  // filesystem which will be provisioned by Mesos.
+  optional Image image = 4;
 }
 
 


[6/8] mesos git commit: Removed the code of checkpointing container root filesystem path.

Posted by ji...@apache.org.
Removed the code of checkpointing container root filesystem path.

Review: https://reviews.apache.org/r/37105


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/3a862137
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/3a862137
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/3a862137

Branch: refs/heads/master
Commit: 3a862137aa1bcc6acb4ad30fc9d4191904ec5538
Parents: 210dadf
Author: Jie Yu <yu...@gmail.com>
Authored: Tue Aug 4 16:46:05 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:54:14 2015 -0700

----------------------------------------------------------------------
 include/mesos/slave/isolator.proto              |   1 -
 src/common/protobuf_utils.cpp                   |   6 +-
 src/common/protobuf_utils.hpp                   |   3 +-
 src/slave/containerizer/mesos/containerizer.cpp | 183 ++++++++-----------
 src/slave/containerizer/mesos/containerizer.hpp |  42 ++---
 src/slave/containerizer/provisioner.hpp         |   5 +-
 src/slave/paths.cpp                             |  19 --
 src/slave/state.cpp                             |  24 ---
 src/slave/state.hpp                             |   1 -
 9 files changed, 98 insertions(+), 186 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/include/mesos/slave/isolator.proto
----------------------------------------------------------------------
diff --git a/include/mesos/slave/isolator.proto b/include/mesos/slave/isolator.proto
index 3d9222b..39d20c7 100644
--- a/include/mesos/slave/isolator.proto
+++ b/include/mesos/slave/isolator.proto
@@ -54,7 +54,6 @@ message ContainerState
 
   required uint64 pid = 3;            // Executor pid.
   required string directory = 4;      // Executor work directory.
-  optional string rootfs = 5;         // Optional container rootfs.
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/common/protobuf_utils.cpp
----------------------------------------------------------------------
diff --git a/src/common/protobuf_utils.cpp b/src/common/protobuf_utils.cpp
index 3cb6845..4de176b 100644
--- a/src/common/protobuf_utils.cpp
+++ b/src/common/protobuf_utils.cpp
@@ -240,17 +240,13 @@ ContainerState createContainerState(
     const ExecutorInfo& executorInfo,
     const ContainerID& container_id,
     pid_t pid,
-    const std::string& directory,
-    const Option<std::string>& rootfs)
+    const std::string& directory)
 {
   ContainerState state;
   state.mutable_executor_info()->CopyFrom(executorInfo);
   state.mutable_container_id()->CopyFrom(container_id);
   state.set_pid(pid);
   state.set_directory(directory);
-  if (rootfs.isSome()) {
-    state.set_rootfs(rootfs.get());
-  }
   return state;
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/common/protobuf_utils.hpp
----------------------------------------------------------------------
diff --git a/src/common/protobuf_utils.hpp b/src/common/protobuf_utils.hpp
index a4708ed..312bc61 100644
--- a/src/common/protobuf_utils.hpp
+++ b/src/common/protobuf_utils.hpp
@@ -88,8 +88,7 @@ mesos::slave::ContainerState createContainerState(
     const ExecutorInfo& executorInfo,
     const ContainerID& id,
     pid_t pid,
-    const std::string& directory,
-    const Option<std::string>& rootfs);
+    const std::string& directory);
 
 } // namespace slave {
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index e9fc4d7..78db4c1 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -422,8 +422,7 @@ Future<Nothing> MesosContainerizerProcess::recover(
               executorInfo,
               run.get().id.get(),
               run.get().forkedPid.get(),
-              directory,
-              run.get().rootfs);
+              directory);
 
         recoverable.push_back(executorRunState);
       }
@@ -473,10 +472,6 @@ Future<Nothing> MesosContainerizerProcess::__recover(
 
     container->directory = run.directory();
 
-    if (run.has_rootfs()) {
-      container->rootfs = run.rootfs();
-    }
-
     // We only checkpoint the containerizer pid after the container
     // successfully launched, therefore we can assume checkpointed
     // containers should be running after recover.
@@ -551,6 +546,33 @@ void MesosContainerizerProcess::___recover(
 }
 
 
+Future<bool> MesosContainerizerProcess::launch(
+    const ContainerID& containerId,
+    const TaskInfo& taskInfo,
+    const ExecutorInfo& executorInfo,
+    const string& directory,
+    const Option<string>& user,
+    const SlaveID& slaveId,
+    const PID<Slave>& slavePid,
+    bool checkpoint)
+{
+  if (taskInfo.has_container()) {
+    // We return false as this containerizer does not support
+    // handling TaskInfo::ContainerInfo.
+    return false;
+  }
+
+  return launch(
+      containerId,
+      executorInfo,
+      directory,
+      user,
+      slaveId,
+      slavePid,
+      checkpoint);
+}
+
+
 // Launching an executor involves the following steps:
 // 1. Call prepare on each isolator.
 // 2. Fork the executor. The forked child is blocked from exec'ing until it has
@@ -607,38 +629,29 @@ Future<bool> MesosContainerizerProcess::launch(
 
   containers_.put(containerId, Owned<Container>(container));
 
-  return provision(containerId, executorInfo, slaveId, directory, checkpoint)
-    .then(defer(self(),
-                &Self::prepare,
-                containerId,
-                executorInfo,
-                directory,
-                user))
+  return provision(containerId, executorInfo)
     .then(defer(self(),
                 &Self::_launch,
                 containerId,
                 executorInfo,
                 directory,
                 user,
+                lambda::_1,
                 slaveId,
                 slavePid,
-                checkpoint,
-                lambda::_1));
+                checkpoint));
 }
 
 
-Future<Nothing> MesosContainerizerProcess::provision(
+Future<Option<string>> MesosContainerizerProcess::provision(
     const ContainerID& containerId,
-    const ExecutorInfo& executorInfo,
-    const SlaveID& slaveId,
-    const string& directory,
-    bool checkpoint)
+    const ExecutorInfo& executorInfo)
 {
   if (!executorInfo.has_container()) {
     // TODO(idownes): Consider refusing to run a container if the
     // containerizer is configured with an image provisioner but the
     // executor doesn't specify an image.
-    return Nothing();
+    return None();
   }
 
   if (executorInfo.container().type() != ContainerInfo::MESOS) {
@@ -647,7 +660,7 @@ Future<Nothing> MesosContainerizerProcess::provision(
 
   if (!executorInfo.container().mesos().has_image()) {
     // No image to provision.
-    return Nothing();
+    return None();
   }
 
   Image image = executorInfo.container().mesos().image();
@@ -659,75 +672,32 @@ Future<Nothing> MesosContainerizerProcess::provision(
   }
 
   return provisioners[image.type()]->provision(containerId, image)
-    .then(defer(self(),
-                &Self::_provision,
-                containerId,
-                executorInfo,
-                slaveId,
-                checkpoint,
-                lambda::_1));
+    .then([] (const string& rootfs) -> Option<string> { return rootfs; });
 }
 
 
-Future<Nothing> MesosContainerizerProcess::_provision(
-    const ContainerID& containerId,
-    const ExecutorInfo& executorInfo,
-    const SlaveID& slaveId,
-    bool checkpoint,
-    const string& rootfs)
-{
-  if (!containers_.contains(containerId)) {
-    return Failure("Container is already destroyed");
-  }
-
-  containers_[containerId]->rootfs = rootfs;
-
-  if (checkpoint) {
-    const string path = slave::paths::getContainerRootfsPath(
-        slave::paths::getMetaRootDir(flags.work_dir),
-        slaveId,
-        executorInfo.framework_id(),
-        executorInfo.executor_id(),
-        containerId);
-
-    LOG(INFO) << "Checkpointing container " << containerId << " rootfs path '"
-              << rootfs << "' to '" << path << "'";
-
-    Try<Nothing> checkpointed = slave::state::checkpoint(path, rootfs);
-    if (checkpointed.isError()) {
-      return Failure("Failed to checkpoint container rootfs path to '" +
-                     path + "': " + checkpointed.error());
-    }
-  }
-
-  return Nothing();
-}
-
-
-Future<bool> MesosContainerizerProcess::launch(
+Future<bool> MesosContainerizerProcess::_launch(
     const ContainerID& containerId,
-    const TaskInfo& taskInfo,
     const ExecutorInfo& executorInfo,
     const string& directory,
     const Option<string>& user,
+    const Option<string>& rootfs,
     const SlaveID& slaveId,
     const PID<Slave>& slavePid,
     bool checkpoint)
 {
-  if (taskInfo.has_container()) {
-    // We return false as this containerizer does not support
-    // handling TaskInfo::ContainerInfo.
-    return false;
-  }
-
-  return launch(
-      containerId,
-      executorInfo,
-      directory,
-      user,
-      slaveId,
-      slavePid,
-      checkpoint);
+  return prepare(containerId, executorInfo, directory, user, rootfs)
+    .then(defer(self(),
+                &Self::__launch,
+                containerId,
+                executorInfo,
+                directory,
+                user,
+                rootfs,
+                slaveId,
+                slavePid,
+                checkpoint,
+                lambda::_1));
 }
 
 
@@ -759,7 +729,8 @@ Future<list<Option<ContainerPrepareInfo>>> MesosContainerizerProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& user)
+    const Option<string>& user,
+    const Option<string>& rootfs)
 {
   CHECK(containers_.contains(containerId));
 
@@ -776,7 +747,7 @@ Future<list<Option<ContainerPrepareInfo>>> MesosContainerizerProcess::prepare(
                             containerId,
                             executorInfo,
                             directory,
-                            containers_[containerId]->rootfs,
+                            rootfs,
                             user,
                             lambda::_1));
   }
@@ -808,11 +779,12 @@ Future<Nothing> MesosContainerizerProcess::fetch(
 }
 
 
-Future<bool> MesosContainerizerProcess::_launch(
+Future<bool> MesosContainerizerProcess::__launch(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
     const Option<string>& user,
+    const Option<string>& rootfs,
     const SlaveID& slaveId,
     const PID<Slave>& slavePid,
     bool checkpoint,
@@ -829,9 +801,7 @@ Future<bool> MesosContainerizerProcess::_launch(
   // Prepare environment variables for the executor.
   map<string, string> environment = executorEnvironment(
       executorInfo,
-      containers_[containerId]->rootfs.isSome()
-        ? flags.sandbox_directory
-        : directory,
+      rootfs.isSome() ? flags.sandbox_directory : directory,
       slaveId,
       slavePid,
       checkpoint,
@@ -866,11 +836,8 @@ Future<bool> MesosContainerizerProcess::_launch(
 
   launchFlags.command = JSON::Protobuf(executorInfo.command());
 
-  launchFlags.directory = containers_[containerId]->rootfs.isSome()
-    ? flags.sandbox_directory
-    : directory;
-
-  launchFlags.rootfs = containers_[containerId]->rootfs;
+  launchFlags.directory = rootfs.isSome() ? flags.sandbox_directory : directory;
+  launchFlags.rootfs = rootfs;
   launchFlags.user = user;
   launchFlags.pipe_read = pipes[0];
   launchFlags.pipe_write = pipes[1];
@@ -1291,25 +1258,15 @@ void MesosContainerizerProcess::____destroy(
     }
   }
 
-  if (container->rootfs.isNone()) {
-    // No rootfs to clean up so continue.
-    _____destroy(containerId, status, message, killed, Nothing());
-    return;
-  }
-
-  Image::Type type = container->executorInfo.container().mesos().image().type();
-
-  if (!provisioners.contains(type)) {
-    // We should have a provisioner to handle cleaning up the rootfs
-    // but continue clean up even if we don't.
-    LOG(WARNING) << "No provisioner to clean up rootfs for container "
-                 << containerId << " (type '" << type << "'), continuing";
-
-    _____destroy(containerId, status, message, killed, Nothing());
-    return;
+  // Clean up root filesystems used for this container.
+  // NOTE: We need to call 'destroy' for each provisioner because
+  // multiple provisioners might be used for a container.
+  list<Future<bool>> futures;
+  foreachvalue (const Owned<Provisioner>& provisioner, provisioners) {
+    futures.push_back(provisioner->destroy(containerId));
   }
 
-  provisioners[type]->destroy(containerId)
+  await(futures)
     .onAny(defer(self(),
                  &Self::_____destroy,
                  containerId,
@@ -1327,13 +1284,19 @@ void MesosContainerizerProcess::_____destroy(
     const Future<Option<int>>& status,
     Option<string> message,
     bool killed,
-    const Future<Nothing>& future)
+    const Future<list<Future<bool>>>& futures)
 {
   CHECK(containers_.contains(containerId));
 
   Container* container = containers_[containerId].get();
 
-  if (!future.isReady()) {
+  CHECK_READY(futures);
+
+  foreach (const Future<bool> future, futures.get()) {
+    if (future.isReady()) {
+      continue;
+    }
+
     container->promise.fail(
         "Failed to clean up the root filesystem when destroying container: " +
         (future.isFailed() ? future.failure() : "discarded future"));

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/slave/containerizer/mesos/containerizer.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.hpp b/src/slave/containerizer/mesos/containerizer.hpp
index 68e9139..8bfd622 100644
--- a/src/slave/containerizer/mesos/containerizer.hpp
+++ b/src/slave/containerizer/mesos/containerizer.hpp
@@ -181,25 +181,16 @@ private:
       const std::list<mesos::slave::ContainerState>& recovered,
       const hashset<ContainerID>& orphans);
 
-  process::Future<Nothing> provision(
+  process::Future<Option<std::string>> provision(
       const ContainerID& containerId,
-      const ExecutorInfo& executorInfo,
-      const SlaveID& slaveId,
-      const std::string& directory,
-      bool checkpoint);
-
-  process::Future<Nothing> _provision(
-      const ContainerID& containerId,
-      const ExecutorInfo& executorInfo,
-      const SlaveID& slaveId,
-      bool checkpoint,
-      const std::string& rootfs);
+      const ExecutorInfo& executorInfo);
 
   process::Future<std::list<Option<mesos::slave::ContainerPrepareInfo>>>
     prepare(const ContainerID& containerId,
             const ExecutorInfo& executorInfo,
             const std::string& directory,
-            const Option<std::string>& user);
+            const Option<std::string>& user,
+            const Option<std::string>& rootfs);
 
   process::Future<Nothing> fetch(
       const ContainerID& containerId,
@@ -213,6 +204,17 @@ private:
       const ExecutorInfo& executorInfo,
       const std::string& directory,
       const Option<std::string>& user,
+      const Option<std::string>& rootfs,
+      const SlaveID& slaveId,
+      const process::PID<Slave>& slavePid,
+      bool checkpoint);
+
+  process::Future<bool> __launch(
+      const ContainerID& containerId,
+      const ExecutorInfo& executorInfo,
+      const std::string& directory,
+      const Option<std::string>& user,
+      const Option<std::string>& rootfs,
       const SlaveID& slaveId,
       const process::PID<Slave>& slavePid,
       bool checkpoint,
@@ -225,20 +227,20 @@ private:
   // Continues 'destroy()' once isolators has completed.
   void _destroy(const ContainerID& containerId, bool killed);
 
-  // Continues 'destroy()' once all processes have been killed by the launcher.
+  // Continues '_destroy()' once all processes have been killed by the launcher.
   void __destroy(
       const ContainerID& containerId,
       const process::Future<Nothing>& future,
       bool killed);
 
-  // Continues '_destroy()' once we get the exit status of the executor.
+  // Continues '__destroy()' once we get the exit status of the executor.
   void ___destroy(
       const ContainerID& containerId,
       const process::Future<Option<int>>& status,
       const Option<std::string>& message,
       bool killed);
 
-  // Continues '__destroy()' once all isolators have completed
+  // Continues '___destroy()' once all isolators have completed
   // cleanup.
   void ____destroy(
       const ContainerID& containerId,
@@ -247,14 +249,14 @@ private:
       Option<std::string> message,
       bool killed);
 
-  // Continues (and completes) '__destroy()' once any root filessystem
+  // Continues (and completes) '____destroy()' once any root filessystem
   // has been cleaned up.
   void _____destroy(
       const ContainerID& containerId,
       const process::Future<Option<int>>& status,
       Option<std::string> message,
       bool killed,
-      const process::Future<Nothing>& cleanup);
+      const process::Future<std::list<process::Future<bool>>>& futures);
 
   // Call back for when an isolator limits a container and impacts the
   // processes. This will trigger container destruction.
@@ -322,10 +324,6 @@ private:
     // The executor's working directory on the host.
     std::string directory;
 
-    // The path to the container's rootfs, if full filesystem
-    // isolation is used.
-    Option<std::string> rootfs;
-
     State state;
   };
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/slave/containerizer/provisioner.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioner.hpp b/src/slave/containerizer/provisioner.hpp
index 3df6d59..541dd4e 100644
--- a/src/slave/containerizer/provisioner.hpp
+++ b/src/slave/containerizer/provisioner.hpp
@@ -65,8 +65,9 @@ public:
 
   // Destroy a previously provisioned root filesystem. Assumes that
   // all references (e.g., mounts, open files) to the provisioned
-  // filesystem have been removed.
-  virtual process::Future<Nothing> destroy(const ContainerID& containerId) = 0;
+  // filesystem have been removed. Return false if there is no
+  // provisioned root filesystem for the given container.
+  virtual process::Future<bool> destroy(const ContainerID& containerId) = 0;
 };
 
 } // namespace slave {

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/slave/paths.cpp
----------------------------------------------------------------------
diff --git a/src/slave/paths.cpp b/src/slave/paths.cpp
index 404c214..0741616 100644
--- a/src/slave/paths.cpp
+++ b/src/slave/paths.cpp
@@ -51,7 +51,6 @@ const char LIBPROCESS_PID_FILE[] = "libprocess.pid";
 const char EXECUTOR_INFO_FILE[] = "executor.info";
 const char EXECUTOR_SENTINEL_FILE[] = "executor.sentinel";
 const char FORKED_PID_FILE[] = "forked.pid";
-const char CONTAINER_ROOTFS_FILE[] = "rootfs";
 const char TASK_INFO_FILE[] = "task.info";
 const char TASK_UPDATES_FILE[] = "task.updates";
 const char RESOURCES_INFO_FILE[] = "resources.info";
@@ -269,24 +268,6 @@ string getForkedPidPath(
 }
 
 
-string getContainerRootfsPath(
-    const string& rootDir,
-    const SlaveID& slaveId,
-    const FrameworkID& frameworkId,
-    const ExecutorID& executorId,
-    const ContainerID& containerId)
-{
-  return path::join(
-      getExecutorRunPath(
-          rootDir,
-          slaveId,
-          frameworkId,
-          executorId,
-          containerId),
-      CONTAINER_ROOTFS_FILE);
-}
-
-
 Try<list<string>> getTaskPaths(
     const string& rootDir,
     const SlaveID& slaveId,

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/slave/state.cpp
----------------------------------------------------------------------
diff --git a/src/slave/state.cpp b/src/slave/state.cpp
index b9f2d8a..f8a9514 100644
--- a/src/slave/state.cpp
+++ b/src/slave/state.cpp
@@ -534,30 +534,6 @@ Try<RunState> RunState::recover(
 
   state.libprocessPid = process::UPID(pid.get());
 
-  // Read the location of the container's root filesystem, if used.
-  path = paths::getContainerRootfsPath(
-      rootDir, slaveId, frameworkId, executorId, containerId);
-
-  // Because a container root filesystem is optional we'll recover the
-  // path if present but continue to recover normally if it's not.
-  if (os::exists(path)) {
-    Try<string> rootfs = os::read(path);
-    if (rootfs.isError()) {
-      message = "Failed to recover container rootfs from '" + path +
-                "': " + rootfs.error();
-
-      if (strict) {
-        return Error(message);
-      } else {
-        LOG(WARNING) << message;
-        state.errors++;
-        return state;
-      }
-    }
-
-    state.rootfs = rootfs.get();
-  }
-
   return state;
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3a862137/src/slave/state.hpp
----------------------------------------------------------------------
diff --git a/src/slave/state.hpp b/src/slave/state.hpp
index cecf200..5a1a9bb 100644
--- a/src/slave/state.hpp
+++ b/src/slave/state.hpp
@@ -208,7 +208,6 @@ struct RunState
   hashmap<TaskID, TaskState> tasks;
   Option<pid_t> forkedPid;
   Option<process::UPID> libprocessPid;
-  Option<std::string> rootfs;
 
   // Executor terminated and all its updates acknowledged.
   bool completed;


[8/8] mesos git commit: Delegated the container root filesystem provisioning to the filesystem isolator.

Posted by ji...@apache.org.
Delegated the container root filesystem provisioning to the filesystem isolator.

Review: https://reviews.apache.org/r/37159


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8ba2f351
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8ba2f351
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8ba2f351

Branch: refs/heads/master
Commit: 8ba2f3511e0b2e5975b72f69079210ad2e1169b5
Parents: 39d5e5f
Author: Jie Yu <yu...@gmail.com>
Authored: Wed Aug 5 20:58:37 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:54:14 2015 -0700

----------------------------------------------------------------------
 include/mesos/slave/isolator.hpp                |   1 -
 include/mesos/slave/isolator.proto              |   3 +
 src/slave/containerizer/isolator.cpp            |   2 -
 src/slave/containerizer/isolator.hpp            |   2 -
 .../isolators/cgroups/cpushare.cpp              |   1 -
 .../isolators/cgroups/cpushare.hpp              |   1 -
 .../containerizer/isolators/cgroups/mem.cpp     |   1 -
 .../containerizer/isolators/cgroups/mem.hpp     |   1 -
 .../isolators/cgroups/perf_event.cpp            |   1 -
 .../isolators/cgroups/perf_event.hpp            |   1 -
 .../isolators/filesystem/posix.cpp              |  12 +-
 .../isolators/filesystem/posix.hpp              |   1 -
 .../isolators/filesystem/shared.cpp             |   1 -
 .../isolators/filesystem/shared.hpp             |   1 -
 .../containerizer/isolators/namespaces/pid.cpp  |   1 -
 .../containerizer/isolators/namespaces/pid.hpp  |   1 -
 .../isolators/network/port_mapping.cpp          |   1 -
 .../isolators/network/port_mapping.hpp          |   1 -
 src/slave/containerizer/isolators/posix.hpp     |   1 -
 .../containerizer/isolators/posix/disk.cpp      |   1 -
 .../containerizer/isolators/posix/disk.hpp      |   1 -
 src/slave/containerizer/mesos/containerizer.cpp | 156 +++----------------
 src/slave/containerizer/mesos/containerizer.hpp |  39 +----
 src/tests/containerizer/isolator.hpp            |   1 -
 src/tests/containerizer/isolator_tests.cpp      |  11 --
 .../containerizer/mesos_containerizer_tests.cpp |  27 ++--
 src/tests/containerizer/port_mapping_tests.cpp  |  14 --
 27 files changed, 46 insertions(+), 238 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/include/mesos/slave/isolator.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/slave/isolator.hpp b/include/mesos/slave/isolator.hpp
index 22f1e36..970730f 100644
--- a/include/mesos/slave/isolator.hpp
+++ b/include/mesos/slave/isolator.hpp
@@ -74,7 +74,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user) = 0;
 
   // Isolate the executor.

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/include/mesos/slave/isolator.proto
----------------------------------------------------------------------
diff --git a/include/mesos/slave/isolator.proto b/include/mesos/slave/isolator.proto
index 39d20c7..12ea6ac 100644
--- a/include/mesos/slave/isolator.proto
+++ b/include/mesos/slave/isolator.proto
@@ -68,4 +68,7 @@ message ContainerPrepareInfo
 {
   repeated CommandInfo commands = 1;
   optional Environment environment = 2;
+
+  // The root filesystem for the container.
+  optional string rootfs = 3;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolator.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolator.cpp b/src/slave/containerizer/isolator.cpp
index ed610f9..7973100 100644
--- a/src/slave/containerizer/isolator.cpp
+++ b/src/slave/containerizer/isolator.cpp
@@ -68,7 +68,6 @@ Future<Option<ContainerPrepareInfo>> MesosIsolator::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   return dispatch(process.get(),
@@ -76,7 +75,6 @@ Future<Option<ContainerPrepareInfo>> MesosIsolator::prepare(
                   containerId,
                   executorInfo,
                   directory,
-                  rootfs,
                   user);
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolator.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolator.hpp b/src/slave/containerizer/isolator.hpp
index 710c584..fbb7c8a 100644
--- a/src/slave/containerizer/isolator.hpp
+++ b/src/slave/containerizer/isolator.hpp
@@ -53,7 +53,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(
@@ -93,7 +92,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user) = 0;
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/cgroups/cpushare.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/cgroups/cpushare.cpp b/src/slave/containerizer/isolators/cgroups/cpushare.cpp
index 907d7e7..ba748c6 100644
--- a/src/slave/containerizer/isolators/cgroups/cpushare.cpp
+++ b/src/slave/containerizer/isolators/cgroups/cpushare.cpp
@@ -249,7 +249,6 @@ Future<Option<ContainerPrepareInfo>> CgroupsCpushareIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (infos.contains(containerId)) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/cgroups/cpushare.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/cgroups/cpushare.hpp b/src/slave/containerizer/isolators/cgroups/cpushare.hpp
index 6b980f2..54b83a7 100644
--- a/src/slave/containerizer/isolators/cgroups/cpushare.hpp
+++ b/src/slave/containerizer/isolators/cgroups/cpushare.hpp
@@ -58,7 +58,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/cgroups/mem.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/cgroups/mem.cpp b/src/slave/containerizer/isolators/cgroups/mem.cpp
index e343d0b..48d7fbd 100644
--- a/src/slave/containerizer/isolators/cgroups/mem.cpp
+++ b/src/slave/containerizer/isolators/cgroups/mem.cpp
@@ -235,7 +235,6 @@ Future<Option<ContainerPrepareInfo>> CgroupsMemIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (infos.contains(containerId)) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/cgroups/mem.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/cgroups/mem.hpp b/src/slave/containerizer/isolators/cgroups/mem.hpp
index e831878..47f73c3 100644
--- a/src/slave/containerizer/isolators/cgroups/mem.hpp
+++ b/src/slave/containerizer/isolators/cgroups/mem.hpp
@@ -53,7 +53,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/cgroups/perf_event.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/cgroups/perf_event.cpp b/src/slave/containerizer/isolators/cgroups/perf_event.cpp
index 0e421cb..8c3018d 100644
--- a/src/slave/containerizer/isolators/cgroups/perf_event.cpp
+++ b/src/slave/containerizer/isolators/cgroups/perf_event.cpp
@@ -221,7 +221,6 @@ Future<Option<ContainerPrepareInfo>> CgroupsPerfEventIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (infos.contains(containerId)) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/cgroups/perf_event.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/cgroups/perf_event.hpp b/src/slave/containerizer/isolators/cgroups/perf_event.hpp
index 73f245b..c1578b1 100644
--- a/src/slave/containerizer/isolators/cgroups/perf_event.hpp
+++ b/src/slave/containerizer/isolators/cgroups/perf_event.hpp
@@ -49,7 +49,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/filesystem/posix.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/filesystem/posix.cpp b/src/slave/containerizer/isolators/filesystem/posix.cpp
index 4861ee1..eec510c 100644
--- a/src/slave/containerizer/isolators/filesystem/posix.cpp
+++ b/src/slave/containerizer/isolators/filesystem/posix.cpp
@@ -74,7 +74,6 @@ Future<Option<ContainerPrepareInfo>> PosixFilesystemIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (infos.contains(containerId)) {
@@ -83,8 +82,15 @@ Future<Option<ContainerPrepareInfo>> PosixFilesystemIsolatorProcess::prepare(
 
   // Return failure if the container change the filesystem root
   // because the symlinks will become invalid in the new root.
-  if (rootfs.isSome()) {
-    return Failure("Container root filesystems not supported");
+  if (executorInfo.has_container()) {
+    CHECK_EQ(executorInfo.container().type(), ContainerInfo::MESOS);
+
+    if (executorInfo.container().mesos().has_image()) {
+      return Failure("Container root filesystems not supported");
+    }
+
+    // TODO(jieyu): Also return a failure if there exists images in
+    // the specified volumes.
   }
 
   infos.put(containerId, Owned<Info>(new Info(directory)));

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/filesystem/posix.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/filesystem/posix.hpp b/src/slave/containerizer/isolators/filesystem/posix.hpp
index 4c7a6f2..61b81dd 100644
--- a/src/slave/containerizer/isolators/filesystem/posix.hpp
+++ b/src/slave/containerizer/isolators/filesystem/posix.hpp
@@ -44,7 +44,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/filesystem/shared.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/filesystem/shared.cpp b/src/slave/containerizer/isolators/filesystem/shared.cpp
index b30ab3f..4b4520e 100644
--- a/src/slave/containerizer/isolators/filesystem/shared.cpp
+++ b/src/slave/containerizer/isolators/filesystem/shared.cpp
@@ -84,7 +84,6 @@ Future<Option<ContainerPrepareInfo>> SharedFilesystemIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (executorInfo.has_container() &&

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/filesystem/shared.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/filesystem/shared.hpp b/src/slave/containerizer/isolators/filesystem/shared.hpp
index 45e4ba0..a21bc79 100644
--- a/src/slave/containerizer/isolators/filesystem/shared.hpp
+++ b/src/slave/containerizer/isolators/filesystem/shared.hpp
@@ -49,7 +49,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/namespaces/pid.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/namespaces/pid.cpp b/src/slave/containerizer/isolators/namespaces/pid.cpp
index 8e643f4..35cb664 100644
--- a/src/slave/containerizer/isolators/namespaces/pid.cpp
+++ b/src/slave/containerizer/isolators/namespaces/pid.cpp
@@ -163,7 +163,6 @@ Future<Option<ContainerPrepareInfo>> NamespacesPidIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   ContainerPrepareInfo prepareInfo;

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/namespaces/pid.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/namespaces/pid.hpp b/src/slave/containerizer/isolators/namespaces/pid.hpp
index 858e436..b22f5ba 100644
--- a/src/slave/containerizer/isolators/namespaces/pid.hpp
+++ b/src/slave/containerizer/isolators/namespaces/pid.hpp
@@ -66,7 +66,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/network/port_mapping.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/network/port_mapping.cpp b/src/slave/containerizer/isolators/network/port_mapping.cpp
index 8244c34..88c0cbc 100644
--- a/src/slave/containerizer/isolators/network/port_mapping.cpp
+++ b/src/slave/containerizer/isolators/network/port_mapping.cpp
@@ -2086,7 +2086,6 @@ Future<Option<ContainerPrepareInfo>> PortMappingIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (unmanaged.contains(containerId)) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/network/port_mapping.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/network/port_mapping.hpp b/src/slave/containerizer/isolators/network/port_mapping.hpp
index 2599c98..4bca0b8 100644
--- a/src/slave/containerizer/isolators/network/port_mapping.hpp
+++ b/src/slave/containerizer/isolators/network/port_mapping.hpp
@@ -162,7 +162,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/posix.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/posix.hpp b/src/slave/containerizer/isolators/posix.hpp
index ef19749..ee9d275 100644
--- a/src/slave/containerizer/isolators/posix.hpp
+++ b/src/slave/containerizer/isolators/posix.hpp
@@ -66,7 +66,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user)
   {
     if (promises.contains(containerId)) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/posix/disk.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/posix/disk.cpp b/src/slave/containerizer/isolators/posix/disk.cpp
index 6dda77b..c324c79 100644
--- a/src/slave/containerizer/isolators/posix/disk.cpp
+++ b/src/slave/containerizer/isolators/posix/disk.cpp
@@ -107,7 +107,6 @@ Future<Option<ContainerPrepareInfo>> PosixDiskIsolatorProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user)
 {
   if (infos.contains(containerId)) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/isolators/posix/disk.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/posix/disk.hpp b/src/slave/containerizer/isolators/posix/disk.hpp
index 9fa584f..85df5d2 100644
--- a/src/slave/containerizer/isolators/posix/disk.hpp
+++ b/src/slave/containerizer/isolators/posix/disk.hpp
@@ -86,7 +86,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user);
 
   virtual process::Future<Nothing> isolate(

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 758ed1c..e34dec9 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -197,20 +197,12 @@ Try<MesosContainerizer*> MesosContainerizer::create(
     return Error("Failed to create launcher: " + launcher.error());
   }
 
-  Try<hashmap<Image::Type, Owned<Provisioner>>> provisioners =
-    Provisioner::create(flags, fetcher);
-
-  if (provisioners.isError()) {
-    return Error("Failed to create provisioner(s): " + provisioners.error());
-  }
-
   return new MesosContainerizer(
       flags_,
       local,
       fetcher,
       Owned<Launcher>(launcher.get()),
-      isolators,
-      provisioners.get());
+      isolators);
 }
 
 
@@ -219,15 +211,13 @@ MesosContainerizer::MesosContainerizer(
     bool local,
     Fetcher* fetcher,
     const Owned<Launcher>& launcher,
-    const vector<Owned<Isolator>>& isolators,
-    const hashmap<Image::Type, Owned<Provisioner>>& provisioners)
+    const vector<Owned<Isolator>>& isolators)
   : process(new MesosContainerizerProcess(
       flags,
       local,
       fetcher,
       launcher,
-      isolators,
-      provisioners))
+      isolators))
 {
   spawn(process.get());
 }
@@ -441,17 +431,12 @@ Future<Nothing> MesosContainerizerProcess::_recover(
 {
   list<Future<Nothing>> futures;
 
-  // Then recover the provisioners.
-  foreachvalue (const Owned<Provisioner>& provisioner, provisioners) {
-    futures.push_back(provisioner->recover(recoverable, orphans));
-  }
-
   // Then recover the isolators.
   foreach (const Owned<Isolator>& isolator, isolators) {
     futures.push_back(isolator->recover(recoverable, orphans));
   }
 
-  // If all provisioners and isolators recover then continue.
+  // If all isolators recover then continue.
   return collect(futures)
     .then(defer(self(), &Self::__recover, recoverable, orphans));
 }
@@ -616,71 +601,13 @@ Future<bool> MesosContainerizerProcess::launch(
 
   containers_.put(containerId, Owned<Container>(container));
 
-  return provision(containerId, executorInfo)
+  return prepare(containerId, executorInfo, directory, user)
     .then(defer(self(),
                 &Self::_launch,
                 containerId,
                 executorInfo,
                 directory,
                 user,
-                lambda::_1,
-                slaveId,
-                slavePid,
-                checkpoint));
-}
-
-
-Future<Option<string>> MesosContainerizerProcess::provision(
-    const ContainerID& containerId,
-    const ExecutorInfo& executorInfo)
-{
-  if (!executorInfo.has_container()) {
-    // TODO(idownes): Consider refusing to run a container if the
-    // containerizer is configured with an image provisioner but the
-    // executor doesn't specify an image.
-    return None();
-  }
-
-  if (executorInfo.container().type() != ContainerInfo::MESOS) {
-    return Failure("Mesos containerizer can only provision Mesos containers");
-  }
-
-  if (!executorInfo.container().mesos().has_image()) {
-    // No image to provision.
-    return None();
-  }
-
-  Image image = executorInfo.container().mesos().image();
-
-  if (!provisioners.contains(image.type())) {
-    return Failure("ExecutorInfo specifies container image type '" +
-                    stringify(image.type()) +
-                    "' but no suitable provisioner available");
-  }
-
-  return provisioners[image.type()]->provision(containerId, image)
-    .then([] (const string& rootfs) -> Option<string> { return rootfs; });
-}
-
-
-Future<bool> MesosContainerizerProcess::_launch(
-    const ContainerID& containerId,
-    const ExecutorInfo& executorInfo,
-    const string& directory,
-    const Option<string>& user,
-    const Option<string>& rootfs,
-    const SlaveID& slaveId,
-    const PID<Slave>& slavePid,
-    bool checkpoint)
-{
-  return prepare(containerId, executorInfo, directory, user, rootfs)
-    .then(defer(self(),
-                &Self::__launch,
-                containerId,
-                executorInfo,
-                directory,
-                user,
-                rootfs,
                 slaveId,
                 slavePid,
                 checkpoint,
@@ -702,12 +629,11 @@ static Future<list<Option<ContainerPrepareInfo>>> _prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& rootfs,
     const Option<string>& user,
     const list<Option<ContainerPrepareInfo>> prepareInfos)
 {
   // Propagate any failure.
-  return isolator->prepare(containerId, executorInfo, directory, rootfs, user)
+  return isolator->prepare(containerId, executorInfo, directory, user)
     .then(lambda::bind(&accumulate, prepareInfos, lambda::_1));
 }
 
@@ -716,8 +642,7 @@ Future<list<Option<ContainerPrepareInfo>>> MesosContainerizerProcess::prepare(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
-    const Option<string>& user,
-    const Option<string>& rootfs)
+    const Option<string>& user)
 {
   CHECK(containers_.contains(containerId));
 
@@ -734,7 +659,6 @@ Future<list<Option<ContainerPrepareInfo>>> MesosContainerizerProcess::prepare(
                             containerId,
                             executorInfo,
                             directory,
-                            rootfs,
                             user,
                             lambda::_1));
   }
@@ -766,12 +690,11 @@ Future<Nothing> MesosContainerizerProcess::fetch(
 }
 
 
-Future<bool> MesosContainerizerProcess::__launch(
+Future<bool> MesosContainerizerProcess::_launch(
     const ContainerID& containerId,
     const ExecutorInfo& executorInfo,
     const string& directory,
     const Option<string>& user,
-    const Option<string>& rootfs,
     const SlaveID& slaveId,
     const PID<Slave>& slavePid,
     bool checkpoint,
@@ -785,6 +708,19 @@ Future<bool> MesosContainerizerProcess::__launch(
     return Failure("Container is currently being destroyed");
   }
 
+  // Determine the root filesystem for the container. Only one
+  // isolator should return the container root filesystem.
+  Option<string> rootfs;
+  foreach (const Option<ContainerPrepareInfo>& prepareInfo, prepareInfos) {
+    if (prepareInfo.isSome() && prepareInfo.get().has_rootfs()) {
+      if (rootfs.isSome()) {
+        return Failure("Only one isolator should return the container rootfs");
+      } else {
+        rootfs = prepareInfo.get().rootfs();
+      }
+    }
+  }
+
   // Prepare environment variables for the executor.
   map<string, string> environment = executorEnvironment(
       executorInfo,
@@ -1245,56 +1181,6 @@ void MesosContainerizerProcess::____destroy(
     }
   }
 
-  // Clean up root filesystems used for this container.
-  // NOTE: We need to call 'destroy' for each provisioner because
-  // multiple provisioners might be used for a container.
-  list<Future<bool>> futures;
-  foreachvalue (const Owned<Provisioner>& provisioner, provisioners) {
-    futures.push_back(provisioner->destroy(containerId));
-  }
-
-  await(futures)
-    .onAny(defer(self(),
-                 &Self::_____destroy,
-                 containerId,
-                 status,
-                 message,
-                 killed,
-                 lambda::_1));
-
-  return;
-}
-
-
-void MesosContainerizerProcess::_____destroy(
-    const ContainerID& containerId,
-    const Future<Option<int>>& status,
-    Option<string> message,
-    bool killed,
-    const Future<list<Future<bool>>>& futures)
-{
-  CHECK(containers_.contains(containerId));
-
-  Container* container = containers_[containerId].get();
-
-  CHECK_READY(futures);
-
-  foreach (const Future<bool> future, futures.get()) {
-    if (future.isReady()) {
-      continue;
-    }
-
-    container->promise.fail(
-        "Failed to clean up the root filesystem when destroying container: " +
-        (future.isFailed() ? future.failure() : "discarded future"));
-
-    containers_.erase(containerId);
-
-    ++metrics.container_destroy_errors;
-
-    return;
-  }
-
   // If any isolator limited the container then we mark it to killed.
   // Note: We may not see a limitation in time for it to be
   // registered. This could occur if the limitation (e.g., an OOM)

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/slave/containerizer/mesos/containerizer.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.hpp b/src/slave/containerizer/mesos/containerizer.hpp
index 066d541..4c14192 100644
--- a/src/slave/containerizer/mesos/containerizer.hpp
+++ b/src/slave/containerizer/mesos/containerizer.hpp
@@ -33,7 +33,6 @@
 
 #include "slave/containerizer/containerizer.hpp"
 #include "slave/containerizer/launcher.hpp"
-#include "slave/containerizer/provisioner.hpp"
 
 namespace mesos {
 namespace internal {
@@ -57,9 +56,7 @@ public:
       bool local,
       Fetcher* fetcher,
       const process::Owned<Launcher>& launcher,
-      const std::vector<process::Owned<mesos::slave::Isolator>>& isolators,
-      const hashmap<Image::Type, process::Owned<Provisioner>>& provisioners);
-
+      const std::vector<process::Owned<mesos::slave::Isolator>>& isolators);
 
   // Used for testing.
   MesosContainerizer(const process::Owned<MesosContainerizerProcess>& _process);
@@ -116,14 +113,12 @@ public:
       bool _local,
       Fetcher* _fetcher,
       const process::Owned<Launcher>& _launcher,
-      const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators,
-      const hashmap<Image::Type, process::Owned<Provisioner>>& _provisioners)
+      const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators)
     : flags(_flags),
       local(_local),
       fetcher(_fetcher),
       launcher(_launcher),
-      isolators(_isolators),
-      provisioners(_provisioners) {}
+      isolators(_isolators) {}
 
   virtual ~MesosContainerizerProcess() {}
 
@@ -181,16 +176,11 @@ private:
       const std::list<mesos::slave::ContainerState>& recovered,
       const hashset<ContainerID>& orphans);
 
-  process::Future<Option<std::string>> provision(
-      const ContainerID& containerId,
-      const ExecutorInfo& executorInfo);
-
   process::Future<std::list<Option<mesos::slave::ContainerPrepareInfo>>>
     prepare(const ContainerID& containerId,
             const ExecutorInfo& executorInfo,
             const std::string& directory,
-            const Option<std::string>& user,
-            const Option<std::string>& rootfs);
+            const Option<std::string>& user);
 
   process::Future<Nothing> fetch(
       const ContainerID& containerId,
@@ -204,17 +194,6 @@ private:
       const ExecutorInfo& executorInfo,
       const std::string& directory,
       const Option<std::string>& user,
-      const Option<std::string>& rootfs,
-      const SlaveID& slaveId,
-      const process::PID<Slave>& slavePid,
-      bool checkpoint);
-
-  process::Future<bool> __launch(
-      const ContainerID& containerId,
-      const ExecutorInfo& executorInfo,
-      const std::string& directory,
-      const Option<std::string>& user,
-      const Option<std::string>& rootfs,
       const SlaveID& slaveId,
       const process::PID<Slave>& slavePid,
       bool checkpoint,
@@ -249,15 +228,6 @@ private:
       Option<std::string> message,
       bool killed);
 
-  // Continues (and completes) '____destroy()' once any root filessystem
-  // has been cleaned up.
-  void _____destroy(
-      const ContainerID& containerId,
-      const process::Future<Option<int>>& status,
-      Option<std::string> message,
-      bool killed,
-      const process::Future<std::list<process::Future<bool>>>& futures);
-
   // Call back for when an isolator limits a container and impacts the
   // processes. This will trigger container destruction.
   void limited(
@@ -278,7 +248,6 @@ private:
   Fetcher* fetcher;
   const process::Owned<Launcher> launcher;
   const std::vector<process::Owned<mesos::slave::Isolator>> isolators;
-  hashmap<Image::Type, process::Owned<Provisioner>> provisioners;
 
   enum State
   {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/tests/containerizer/isolator.hpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/isolator.hpp b/src/tests/containerizer/isolator.hpp
index fa2fc9b..56ac27b 100644
--- a/src/tests/containerizer/isolator.hpp
+++ b/src/tests/containerizer/isolator.hpp
@@ -49,7 +49,6 @@ public:
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const std::string& directory,
-      const Option<std::string>& rootfs,
       const Option<std::string>& user)
   {
     return prepareInfo;

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/tests/containerizer/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/isolator_tests.cpp b/src/tests/containerizer/isolator_tests.cpp
index ff6e2b7..dd1ae22 100644
--- a/src/tests/containerizer/isolator_tests.cpp
+++ b/src/tests/containerizer/isolator_tests.cpp
@@ -172,7 +172,6 @@ TYPED_TEST(CpuIsolatorTest, UserCpuUsage)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   const string& file = path::join(dir.get(), "mesos_isolator_test_ready");
@@ -282,7 +281,6 @@ TYPED_TEST(CpuIsolatorTest, SystemCpuUsage)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   const string& file = path::join(dir.get(), "mesos_isolator_test_ready");
@@ -394,7 +392,6 @@ TEST_F(RevocableCpuIsolatorTest, ROOT_CGROUPS_RevocableCpu)
         containerId,
         executorInfo,
         os::getcwd(),
-        None(),
         None()));
 
   vector<string> argv{"sleep", "100"};
@@ -475,7 +472,6 @@ TEST_F(LimitedCpuIsolatorTest, ROOT_CGROUPS_Cfs)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   // Generate random numbers to max out a single core. We'll run this for 0.5
@@ -587,7 +583,6 @@ TEST_F(LimitedCpuIsolatorTest, ROOT_CGROUPS_Cfs_Big_Quota)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   int pipes[2];
@@ -671,7 +666,6 @@ TEST_F(LimitedCpuIsolatorTest, ROOT_CGROUPS_Pids_and_Tids)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   // Right after the creation of the cgroup, which happens in
@@ -795,7 +789,6 @@ TYPED_TEST(MemIsolatorTest, MemUsage)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   MemoryTestHelper helper;
@@ -858,7 +851,6 @@ TEST_F(PerfEventIsolatorTest, ROOT_CGROUPS_Sample)
       containerId,
       executorInfo,
       dir.get(),
-      None(),
       None()));
 
   // This first sample is likely to be empty because perf hasn't
@@ -956,7 +948,6 @@ TEST_F(SharedFilesystemIsolatorTest, DISABLED_ROOT_RelativeVolume)
         containerId,
         executorInfo,
         flags.work_dir,
-        None(),
         None());
 
   AWAIT_READY(prepare);
@@ -1061,7 +1052,6 @@ TEST_F(SharedFilesystemIsolatorTest, DISABLED_ROOT_AbsoluteVolume)
         containerId,
         executorInfo,
         flags.work_dir,
-        None(),
         None());
 
   AWAIT_READY(prepare);
@@ -1230,7 +1220,6 @@ TYPED_TEST(UserCgroupIsolatorTest, ROOT_CGROUPS_UserCgroup)
       containerId,
       executorInfo,
       os::getcwd(),
-      None(),
       UNPRIVILEGED_USERNAME));
 
   // Isolators don't provide a way to determine the cgroups they use

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/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 4afa986..5bc7d40 100644
--- a/src/tests/containerizer/mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/mesos_containerizer_tests.cpp
@@ -55,7 +55,6 @@ using mesos::internal::slave::Launcher;
 using mesos::internal::slave::MesosContainerizer;
 using mesos::internal::slave::MesosContainerizerProcess;
 using mesos::internal::slave::PosixLauncher;
-using mesos::internal::slave::Provisioner;
 using mesos::internal::slave::Slave;
 
 using mesos::internal::slave::state::ExecutorState;
@@ -116,8 +115,7 @@ public:
         false,
         fetcher,
         Owned<Launcher>(launcher.get()),
-        isolators,
-        hashmap<Image::Type, Owned<Provisioner>>());
+        isolators);
   }
 
   Try<MesosContainerizer*> CreateContainerizer(
@@ -429,15 +427,13 @@ public:
       bool local,
       Fetcher* fetcher,
       const Owned<Launcher>& launcher,
-      const vector<Owned<Isolator>>& isolators,
-      const hashmap<Image::Type, Owned<Provisioner>>& provisioners)
+      const vector<Owned<Isolator>>& isolators)
     : MesosContainerizerProcess(
           flags,
           local,
           fetcher,
           launcher,
-          isolators,
-          provisioners)
+          isolators)
   {
     // NOTE: See TestContainerizer::setup for why we use
     // 'EXPECT_CALL' and 'WillRepeatedly' here instead of
@@ -477,7 +473,7 @@ public:
     EXPECT_CALL(*this, cleanup(_))
       .WillRepeatedly(Return(Nothing()));
 
-    EXPECT_CALL(*this, prepare(_, _, _, _, _))
+    EXPECT_CALL(*this, prepare(_, _, _, _))
       .WillRepeatedly(Invoke(this, &MockIsolator::_prepare));
   }
 
@@ -487,20 +483,18 @@ public:
           const list<ContainerState>&,
           const hashset<ContainerID>&));
 
-  MOCK_METHOD5(
+  MOCK_METHOD4(
       prepare,
       Future<Option<ContainerPrepareInfo>>(
           const ContainerID&,
           const ExecutorInfo&,
           const string&,
-          const Option<string>&,
           const Option<string>&));
 
   virtual Future<Option<ContainerPrepareInfo>> _prepare(
       const ContainerID& containerId,
       const ExecutorInfo& executorInfo,
       const string& directory,
-      const Option<string>& rootfs,
       const Option<string>& user)
   {
     return None();
@@ -546,8 +540,7 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhileFetching)
       true,
       &fetcher,
       Owned<Launcher>(launcher.get()),
-      vector<Owned<Isolator>>(),
-      hashmap<Image::Type, Owned<Provisioner>>());
+      vector<Owned<Isolator>>());
 
   Future<Nothing> exec;
   Promise<bool> promise;
@@ -602,7 +595,7 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhilePreparing)
   Promise<Option<ContainerPrepareInfo>> promise;
 
   // Simulate a long prepare from the isolator.
-  EXPECT_CALL(*isolator, prepare(_, _, _, _, _))
+  EXPECT_CALL(*isolator, prepare(_, _, _, _))
     .WillOnce(DoAll(FutureSatisfy(&prepare),
                     Return(promise.future())));
 
@@ -613,8 +606,7 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhilePreparing)
       true,
       &fetcher,
       Owned<Launcher>(launcher.get()),
-      {Owned<Isolator>(isolator)},
-      hashmap<Image::Type, Owned<Provisioner>>());
+      {Owned<Isolator>(isolator)});
 
   MesosContainerizer containerizer((Owned<MesosContainerizerProcess>(process)));
 
@@ -691,8 +683,7 @@ TEST_F(MesosContainerizerDestroyTest, LauncherDestroyFailure)
       true,
       &fetcher,
       Owned<Launcher>(launcher),
-      vector<Owned<Isolator>>(),
-      hashmap<Image::Type, Owned<Provisioner>>());
+      vector<Owned<Isolator>>());
 
   MesosContainerizer containerizer((Owned<MesosContainerizerProcess>(process)));
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/8ba2f351/src/tests/containerizer/port_mapping_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/port_mapping_tests.cpp b/src/tests/containerizer/port_mapping_tests.cpp
index 4bee74a..3c9b7c8 100644
--- a/src/tests/containerizer/port_mapping_tests.cpp
+++ b/src/tests/containerizer/port_mapping_tests.cpp
@@ -461,7 +461,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_ContainerToContainerTCP)
         containerId1,
         executorInfo,
         dir1.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -529,7 +528,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_ContainerToContainerTCP)
         containerId2,
         executorInfo,
         dir2.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation2);
@@ -623,7 +621,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_ContainerToContainerUDP)
         containerId1,
         executorInfo,
         dir1.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -691,7 +688,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_ContainerToContainerUDP)
         containerId2,
         executorInfo,
         dir2.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation2);
@@ -787,7 +783,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_HostToContainerUDP)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -905,7 +900,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_HostToContainerTCP)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1031,7 +1025,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_ContainerICMPExternal)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1118,7 +1111,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_ContainerICMPInternal)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1208,7 +1200,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_ContainerARPExternal)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1304,7 +1295,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_DNS)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1396,7 +1386,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_TooManyContainers)
         containerId1,
         executorInfo,
         dir1.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1448,7 +1437,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_TooManyContainers)
         containerId2,
         executorInfo,
         dir2.get(),
-        None(),
         None());
 
   AWAIT_FAILED(preparation2);
@@ -1514,7 +1502,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_SmallEgressLimit)
         containerId,
         executorInfo,
         dir.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);
@@ -1669,7 +1656,6 @@ TEST_F(PortMappingIsolatorTest, ROOT_NC_PortMappingStatistics)
         containerId,
         executorInfo,
         dir1.get(),
-        None(),
         None());
 
   AWAIT_READY(preparation1);


[7/8] mesos git commit: Stopped mutating executor info with default container info.

Posted by ji...@apache.org.
Stopped mutating executor info with default container info.

Review: https://reviews.apache.org/r/37091


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/210dadf0
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/210dadf0
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/210dadf0

Branch: refs/heads/master
Commit: 210dadf002dcee838e4a6fd245aea6f4601103d8
Parents: d944393
Author: Jie Yu <yu...@gmail.com>
Authored: Tue Aug 4 12:00:02 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:54:14 2015 -0700

----------------------------------------------------------------------
 src/slave/containerizer/mesos/containerizer.cpp | 36 ++++++++++++++------
 src/slave/slave.cpp                             | 15 +-------
 2 files changed, 27 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/210dadf0/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 0222245..e9fc4d7 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -482,7 +482,17 @@ Future<Nothing> MesosContainerizerProcess::__recover(
     // containers should be running after recover.
     container->state = RUNNING;
 
-    container->executorInfo = run.executor_info();
+    // Add the default container info to the executor info.
+    // TODO(jieyu): Checkpoint the default container info in case the
+    // slave changes the default container info flag.
+    ExecutorInfo executorInfo = run.executor_info();
+    if (!executorInfo.has_container() &&
+        flags.default_container_info.isSome()) {
+      executorInfo.mutable_container()->CopyFrom(
+          flags.default_container_info.get());
+    }
+
+    container->executorInfo = executorInfo;
 
     containers_[containerId] = Owned<Container>(container);
 
@@ -552,7 +562,7 @@ void MesosContainerizerProcess::___recover(
 //    executor.
 Future<bool> MesosContainerizerProcess::launch(
     const ContainerID& containerId,
-    const ExecutorInfo& executorInfo,
+    const ExecutorInfo& _executorInfo,
     const string& directory,
     const Option<string>& user,
     const SlaveID& slaveId,
@@ -560,22 +570,28 @@ Future<bool> MesosContainerizerProcess::launch(
     bool checkpoint)
 {
   if (containers_.contains(containerId)) {
-    LOG(ERROR) << "Cannot start already running container '"
-               << containerId << "'";
     return Failure("Container already started");
   }
 
-  // We support MESOS containers or ExecutorInfos with no
-  // ContainerInfo given.
+  // NOTE: We make a copy of the executor info because we may mutate
+  // it with default container info.
+  ExecutorInfo executorInfo = _executorInfo;
+
   if (executorInfo.has_container() &&
       executorInfo.container().type() != ContainerInfo::MESOS) {
     return false;
   }
 
-  const CommandInfo& command = executorInfo.command();
-  if (command.has_container()) {
-    // We return false as this containerizer does not support
-    // handling ContainerInfo.
+  // Add the default container info to the executor info.
+  // TODO(jieyu): Rename the flag to be default_mesos_container_info.
+  if (!executorInfo.has_container() &&
+      flags.default_container_info.isSome()) {
+    executorInfo.mutable_container()->CopyFrom(
+        flags.default_container_info.get());
+  }
+
+  // MesosContainerizer does not support ContainerInfo in CommandInfo.
+  if (executorInfo.command().has_container()) {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/210dadf0/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index f181b1b..9061e67 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -3269,23 +3269,10 @@ ExecutorInfo Slave::getExecutorInfo(
           "cpus:" + stringify(DEFAULT_EXECUTOR_CPUS) + ";" +
           "mem:" + stringify(DEFAULT_EXECUTOR_MEM.megabytes())).get());
 
-    // Add in any default ContainerInfo.
-    if (!executor.has_container() && flags.default_container_info.isSome()) {
-      executor.mutable_container()->CopyFrom(
-          flags.default_container_info.get());
-    }
-
     return executor;
   }
 
-  ExecutorInfo executor = task.executor();
-
-  // Add in any default ContainerInfo.
-  if (!executor.has_container() && flags.default_container_info.isSome()) {
-    executor.mutable_container()->CopyFrom(flags.default_container_info.get());
-  }
-
-  return executor;
+  return task.executor();
 }
 
 


[2/8] mesos git commit: Moved ContainerInfo::Image definition to the top level.

Posted by ji...@apache.org.
Moved ContainerInfo::Image definition to the top level.

Review: https://reviews.apache.org/r/37054


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ddfab613
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ddfab613
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ddfab613

Branch: refs/heads/master
Commit: ddfab613acdb998ede64d80abeb49300a88959c4
Parents: f077ae6
Author: Jie Yu <yu...@gmail.com>
Authored: Mon Aug 3 13:04:44 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:50:50 2015 -0700

----------------------------------------------------------------------
 include/mesos/mesos.proto                       | 59 +++++++++++---------
 src/slave/containerizer/mesos/containerizer.cpp |  9 ++-
 src/slave/containerizer/mesos/containerizer.hpp |  8 +--
 src/slave/containerizer/provisioner.cpp         |  7 ++-
 src/slave/containerizer/provisioner.hpp         |  4 +-
 .../containerizer/mesos_containerizer_tests.cpp | 11 ++--
 6 files changed, 51 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/ddfab613/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index a6748d1..3e55089 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1191,6 +1191,39 @@ message RateLimits {
 
 
 /**
+ * Describe an image used by tasks or executors. Note that it's only
+ * for tasks or executors launched by MesosContainerizer currently.
+ */
+message Image {
+  enum Type {
+    APPC = 1;
+  }
+
+  // Protobuf for specifying an Appc container image. See:
+  // https://github.com/appc/spec/blob/master/spec/aci.md
+  message AppC {
+    // The name of the image.
+    required string name = 1;
+
+    // An image ID is a string of the format "hash-value", where
+    // "hash" is the hash algorithm used and "value" is the hex
+    // encoded string of the digest. Currently the only permitted
+    // hash algorithm is sha512.
+    required string id = 2;
+
+    // Optional labels. Suggested labels: "version", "os", and "arch".
+    optional Labels labels = 3;
+  }
+
+  required Type type = 1;
+
+  // Only one of the following image messages should be set to match
+  // the type.
+  optional AppC appc = 2;
+}
+
+
+/**
  * Describes a volume mapping either from host to container or vice
  * versa. Both paths can either refer to a directory or a file.
  */
@@ -1258,32 +1291,6 @@ message ContainerInfo {
     optional bool force_pull_image = 6;
   }
 
-  message Image {
-    enum Type {
-      APPC = 1;
-    }
-
-    // Protobuf for specifying an Appc container image. See:
-    // https://github.com/appc/spec/blob/master/spec/aci.md
-    message AppC {
-      // The name of the image.
-      required string name = 1;
-
-      // An image ID is a string of the format "hash-value", where "hash"
-      // is the hash algorithm used and "value" is the hex encoded string of
-      // the digest. Currently the only permitted hash algorithm is sha512.
-      required string id = 2;
-
-      // Optional labels. Suggested labels: "version", "os", and "arch".
-      optional Labels labels = 3;
-    }
-
-    required Type type = 1;
-    // Only one of the following image messages should be set to match
-    // the type.
-    optional AppC appc = 2;
-  }
-
   message MesosInfo {
     optional Image image = 1;
   }

http://git-wip-us.apache.org/repos/asf/mesos/blob/ddfab613/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 6d07ff1..0222245 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -197,7 +197,7 @@ Try<MesosContainerizer*> MesosContainerizer::create(
     return Error("Failed to create launcher: " + launcher.error());
   }
 
-  Try<hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>> provisioners =
+  Try<hashmap<Image::Type, Owned<Provisioner>>> provisioners =
     Provisioner::create(flags, fetcher);
 
   if (provisioners.isError()) {
@@ -220,7 +220,7 @@ MesosContainerizer::MesosContainerizer(
     Fetcher* fetcher,
     const Owned<Launcher>& launcher,
     const vector<Owned<Isolator>>& isolators,
-    const hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>& provisioners)
+    const hashmap<Image::Type, Owned<Provisioner>>& provisioners)
   : process(new MesosContainerizerProcess(
       flags,
       local,
@@ -634,7 +634,7 @@ Future<Nothing> MesosContainerizerProcess::provision(
     return Nothing();
   }
 
-  ContainerInfo::Image image = executorInfo.container().mesos().image();
+  Image image = executorInfo.container().mesos().image();
 
   if (!provisioners.contains(image.type())) {
     return Failure("ExecutorInfo specifies container image type '" +
@@ -1281,8 +1281,7 @@ void MesosContainerizerProcess::____destroy(
     return;
   }
 
-  ContainerInfo::Image::Type type =
-    container->executorInfo.container().mesos().image().type();
+  Image::Type type = container->executorInfo.container().mesos().image().type();
 
   if (!provisioners.contains(type)) {
     // We should have a provisioner to handle cleaning up the rootfs

http://git-wip-us.apache.org/repos/asf/mesos/blob/ddfab613/src/slave/containerizer/mesos/containerizer.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.hpp b/src/slave/containerizer/mesos/containerizer.hpp
index 8851d30..68e9139 100644
--- a/src/slave/containerizer/mesos/containerizer.hpp
+++ b/src/slave/containerizer/mesos/containerizer.hpp
@@ -58,8 +58,7 @@ public:
       Fetcher* fetcher,
       const process::Owned<Launcher>& launcher,
       const std::vector<process::Owned<mesos::slave::Isolator>>& isolators,
-      const hashmap<ContainerInfo::Image::Type,
-                    process::Owned<Provisioner>>& provisioners);
+      const hashmap<Image::Type, process::Owned<Provisioner>>& provisioners);
 
 
   // Used for testing.
@@ -118,8 +117,7 @@ public:
       Fetcher* _fetcher,
       const process::Owned<Launcher>& _launcher,
       const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators,
-      const hashmap<ContainerInfo::Image::Type,
-                    process::Owned<Provisioner>>& _provisioners)
+      const hashmap<Image::Type, process::Owned<Provisioner>>& _provisioners)
     : flags(_flags),
       local(_local),
       fetcher(_fetcher),
@@ -278,7 +276,7 @@ private:
   Fetcher* fetcher;
   const process::Owned<Launcher> launcher;
   const std::vector<process::Owned<mesos::slave::Isolator>> isolators;
-  hashmap<ContainerInfo::Image::Type, process::Owned<Provisioner>> provisioners;
+  hashmap<Image::Type, process::Owned<Provisioner>> provisioners;
 
   enum State
   {

http://git-wip-us.apache.org/repos/asf/mesos/blob/ddfab613/src/slave/containerizer/provisioner.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioner.cpp b/src/slave/containerizer/provisioner.cpp
index df52e36..efc7e69 100644
--- a/src/slave/containerizer/provisioner.cpp
+++ b/src/slave/containerizer/provisioner.cpp
@@ -24,11 +24,12 @@ namespace mesos {
 namespace internal {
 namespace slave {
 
-Try<hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>>
-  Provisioner::create(const Flags& flags, Fetcher* fetcher)
+Try<hashmap<Image::Type, Owned<Provisioner>>> Provisioner::create(
+    const Flags& flags,
+    Fetcher* fetcher)
 {
   // TODO(tnachen): Load provisioners when one of them is available.
-  return hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>();
+  return hashmap<Image::Type, Owned<Provisioner>>();
 }
 
 } // namespace slave {

http://git-wip-us.apache.org/repos/asf/mesos/blob/ddfab613/src/slave/containerizer/provisioner.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioner.hpp b/src/slave/containerizer/provisioner.hpp
index cb4d511..3df6d59 100644
--- a/src/slave/containerizer/provisioner.hpp
+++ b/src/slave/containerizer/provisioner.hpp
@@ -45,7 +45,7 @@ class Provisioner
 public:
   virtual ~Provisioner() {}
 
-  static Try<hashmap<ContainerInfo::Image::Type, process::Owned<Provisioner>>>
+  static Try<hashmap<Image::Type, process::Owned<Provisioner>>>
     create(const Flags& flags, Fetcher* fetcher);
 
   // Recover root filesystems for containers from the run states and
@@ -61,7 +61,7 @@ public:
   // image and return the absolute path to the root filesystem.
   virtual process::Future<std::string> provision(
       const ContainerID& containerId,
-      const ContainerInfo::Image& image) = 0;
+      const Image& image) = 0;
 
   // Destroy a previously provisioned root filesystem. Assumes that
   // all references (e.g., mounts, open files) to the provisioned

http://git-wip-us.apache.org/repos/asf/mesos/blob/ddfab613/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 213fa4b..4afa986 100644
--- a/src/tests/containerizer/mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/mesos_containerizer_tests.cpp
@@ -117,7 +117,7 @@ public:
         fetcher,
         Owned<Launcher>(launcher.get()),
         isolators,
-        hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>());
+        hashmap<Image::Type, Owned<Provisioner>>());
   }
 
   Try<MesosContainerizer*> CreateContainerizer(
@@ -430,8 +430,7 @@ public:
       Fetcher* fetcher,
       const Owned<Launcher>& launcher,
       const vector<Owned<Isolator>>& isolators,
-      const hashmap<ContainerInfo::Image::Type,
-                    Owned<Provisioner>>& provisioners)
+      const hashmap<Image::Type, Owned<Provisioner>>& provisioners)
     : MesosContainerizerProcess(
           flags,
           local,
@@ -548,7 +547,7 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhileFetching)
       &fetcher,
       Owned<Launcher>(launcher.get()),
       vector<Owned<Isolator>>(),
-      hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>());
+      hashmap<Image::Type, Owned<Provisioner>>());
 
   Future<Nothing> exec;
   Promise<bool> promise;
@@ -615,7 +614,7 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhilePreparing)
       &fetcher,
       Owned<Launcher>(launcher.get()),
       {Owned<Isolator>(isolator)},
-      hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>());
+      hashmap<Image::Type, Owned<Provisioner>>());
 
   MesosContainerizer containerizer((Owned<MesosContainerizerProcess>(process)));
 
@@ -693,7 +692,7 @@ TEST_F(MesosContainerizerDestroyTest, LauncherDestroyFailure)
       &fetcher,
       Owned<Launcher>(launcher),
       vector<Owned<Isolator>>(),
-      hashmap<ContainerInfo::Image::Type, Owned<Provisioner>>());
+      hashmap<Image::Type, Owned<Provisioner>>());
 
   MesosContainerizer containerizer((Owned<MesosContainerizerProcess>(process)));
 


[5/8] mesos git commit: Fixed a bug in the MesosContainerizer creation logic.

Posted by ji...@apache.org.
Fixed a bug in the MesosContainerizer creation logic.

Review: https://reviews.apache.org/r/37194


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/fbcc3922
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/fbcc3922
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/fbcc3922

Branch: refs/heads/master
Commit: fbcc3922db92e40e889daf43695f5580301235f1
Parents: 8ba2f35
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Aug 6 11:17:46 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 7 16:54:14 2015 -0700

----------------------------------------------------------------------
 src/slave/containerizer/mesos/containerizer.cpp | 65 +++++++++++++-------
 1 file changed, 43 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/fbcc3922/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index e34dec9..2cbb879 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -28,8 +28,10 @@
 #include <process/subprocess.hpp>
 
 #include <stout/fs.hpp>
+#include <stout/lambda.hpp>
 #include <stout/os.hpp>
 #include <stout/path.hpp>
+#include <stout/strings.hpp>
 
 #include "common/protobuf_utils.hpp"
 
@@ -43,7 +45,7 @@
 #include "slave/containerizer/launcher.hpp"
 #ifdef __linux__
 #include "slave/containerizer/linux_launcher.hpp"
-#endif // __linux__
+#endif
 
 #include "slave/containerizer/isolators/posix.hpp"
 
@@ -102,22 +104,30 @@ Try<MesosContainerizer*> MesosContainerizer::create(
     Fetcher* fetcher)
 {
   string isolation;
+
   if (flags.isolation == "process") {
     LOG(WARNING) << "The 'process' isolation flag is deprecated, "
                  << "please update your flags to"
                  << " '--isolation=posix/cpu,posix/mem'.";
+
     isolation = "posix/cpu,posix/mem";
   } else if (flags.isolation == "cgroups") {
     LOG(WARNING) << "The 'cgroups' isolation flag is deprecated, "
                  << "please update your flags to"
                  << " '--isolation=cgroups/cpu,cgroups/mem'.";
+
     isolation = "cgroups/cpu,cgroups/mem";
   } else {
     isolation = flags.isolation;
   }
 
-  // A filesystem isolator is required for persistent volumes; use the
-  // filesystem/posix isolator if necessary.
+  // One and only one filesystem isolator is required. The filesystem
+  // isolator is responsible for preparing the filesystems for containers
+  // (e.g., prepare filesystem roots, volumes, etc.). If the user does
+  // not specify a filesystem isolator, the default 'filesystem/posix'
+  // isolator will be used.
+  //
+  // TODO(jieyu): Check that only one filesystem isolator is used.
   if (!strings::contains(isolation, "filesystem/")) {
     isolation += ",filesystem/posix";
   }
@@ -129,8 +139,15 @@ Try<MesosContainerizer*> MesosContainerizer::create(
   LOG(INFO) << "Using isolation: " << isolation;
 
   // Create a MesosContainerizerProcess using isolators and a launcher.
-  static const hashmap<string, Try<Isolator*> (*)(const Flags&)> creators = {
+  const hashmap<string, lambda::function<Try<Isolator*>(const Flags&)>>
+    creators = {
+    // Filesystem isolators.
     {"filesystem/posix", &PosixFilesystemIsolatorProcess::create},
+#ifdef __linux__
+    {"filesystem/shared", &SharedFilesystemIsolatorProcess::create},
+#endif
+
+    // Runtime isolators.
     {"posix/cpu", &PosixCpuIsolatorProcess::create},
     {"posix/mem", &PosixMemIsolatorProcess::create},
     {"posix/disk", &PosixDiskIsolatorProcess::create},
@@ -138,9 +155,8 @@ Try<MesosContainerizer*> MesosContainerizer::create(
     {"cgroups/cpu", &CgroupsCpushareIsolatorProcess::create},
     {"cgroups/mem", &CgroupsMemIsolatorProcess::create},
     {"cgroups/perf_event", &CgroupsPerfEventIsolatorProcess::create},
-    {"filesystem/shared", &SharedFilesystemIsolatorProcess::create},
     {"namespaces/pid", &NamespacesPidIsolatorProcess::create},
-#endif // __linux__
+#endif
 #ifdef WITH_NETWORK_ISOLATOR
     {"network/port_mapping", &PortMappingIsolatorProcess::create},
 #endif
@@ -149,31 +165,36 @@ Try<MesosContainerizer*> MesosContainerizer::create(
   vector<Owned<Isolator>> isolators;
 
   foreach (const string& type, strings::tokenize(isolation, ",")) {
+    Owned<Isolator> isolator;
+
     if (creators.contains(type)) {
-      Try<Isolator*> isolator = creators.at(type)(flags_);
-      if (isolator.isError()) {
+      Try<Isolator*> _isolator = creators.at(type)(flags_);
+      if (_isolator.isError()) {
         return Error(
-            "Could not create isolator " + type + ": " + isolator.error());
-      } else {
-        isolators.push_back(Owned<Isolator>(isolator.get()));
+            "Could not create isolator " + type + ": " + _isolator.error());
       }
+
+      isolator.reset(_isolator.get());
     } else if (ModuleManager::contains<Isolator>(type)) {
-      Try<Isolator*> isolator = ModuleManager::create<Isolator>(type);
-      if (isolator.isError()) {
+      Try<Isolator*> _isolator = ModuleManager::create<Isolator>(type);
+      if (_isolator.isError()) {
         return Error(
-            "Could not create isolator " + type + ": " + isolator.error());
-      } else {
-        if (type == "filesystem/shared") {
-          // Filesystem isolator must be the first isolator used for prepare()
-          // so any volume mounts are performed before anything else runs.
-          isolators.insert(isolators.begin(), Owned<Isolator>(isolator.get()));
-        } else {
-          isolators.push_back(Owned<Isolator>(isolator.get()));
-        }
+            "Could not create isolator " + type + ": " + _isolator.error());
       }
+
+      isolator.reset(_isolator.get());
     } else {
       return Error("Unknown or unsupported isolator: " + type);
     }
+
+    // NOTE: The filesystem isolator must be the first isolator used
+    // so that the runtime isolators can have a consistent view on the
+    // prepared filesystem (e.g., any volume mounts are performed).
+    if (strings::contains(type, "filesystem/")) {
+      isolators.insert(isolators.begin(), isolator);
+    } else {
+      isolators.push_back(isolator);
+    }
   }
 
 #ifdef __linux__