mesos-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ji...@apache.org
Subject [2/3] mesos git commit: Implemented provisioner removing docker whiteout files.
Date Fri, 27 May 2016 06:00:38 GMT
Implemented provisioner removing docker whiteout files.

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


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

Branch: refs/heads/master
Commit: 477ec7893157368f2138a2f022024f0e28b2510e
Parents: b80f89b
Author: Gilbert Song <songzihao1990@gmail.com>
Authored: Thu May 26 23:00:21 2016 -0700
Committer: Jie Yu <yujie.jay@gmail.com>
Committed: Thu May 26 23:00:21 2016 -0700

----------------------------------------------------------------------
 include/mesos/docker/spec.hpp                   |  4 +
 .../mesos/provisioner/provisioner.cpp           | 94 +++++++++++++++++++-
 .../mesos/provisioner/provisioner.hpp           |  6 ++
 3 files changed, 100 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/477ec789/include/mesos/docker/spec.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/docker/spec.hpp b/include/mesos/docker/spec.hpp
index 2ebacc7..b37c773 100644
--- a/include/mesos/docker/spec.hpp
+++ b/include/mesos/docker/spec.hpp
@@ -34,6 +34,10 @@
 namespace docker {
 namespace spec {
 
+// The prefix of whiteout files in a docker image.
+constexpr char WHITEOUT_PREFIX[] = ".wh.";
+
+
 /**
  * Parse the docker image reference. Docker expects the image
  * reference to be in the following format:

http://git-wip-us.apache.org/repos/asf/mesos/blob/477ec789/src/slave/containerizer/mesos/provisioner/provisioner.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/provisioner/provisioner.cpp b/src/slave/containerizer/mesos/provisioner/provisioner.cpp
index fe84096..9e803f6 100644
--- a/src/slave/containerizer/mesos/provisioner/provisioner.cpp
+++ b/src/slave/containerizer/mesos/provisioner/provisioner.cpp
@@ -14,8 +14,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <fts.h>
+
 #include <mesos/type_utils.hpp>
 
+#include <mesos/docker/spec.hpp>
+
 #include <process/collect.hpp>
 #include <process/defer.hpp>
 #include <process/dispatch.hpp>
@@ -37,6 +41,8 @@
 
 using namespace process;
 
+namespace spec = docker::spec;
+
 using std::list;
 using std::string;
 using std::vector;
@@ -260,12 +266,13 @@ Future<ProvisionInfo> ProvisionerProcess::provision(
 
   // Get and then provision image layers from the store.
   return stores.get(image.type()).get()->get(image)
-    .then(defer(self(), &Self::_provision, containerId, lambda::_1));
+    .then(defer(self(), &Self::_provision, containerId, image, lambda::_1));
 }
 
 
 Future<ProvisionInfo> ProvisionerProcess::_provision(
     const ContainerID& containerId,
+    const Image& image,
     const ImageInfo& imageInfo)
 {
   // TODO(jieyu): Choose a backend smartly. For instance, if there is
@@ -302,9 +309,88 @@ Future<ProvisionInfo> ProvisionerProcess::_provision(
       imageInfo.layers,
       rootfs,
       backendDir)
-    .then([rootfs, imageInfo]() -> Future<ProvisionInfo> {
-      return ProvisionInfo{rootfs, imageInfo.dockerManifest};
-    });
+    .then(defer(self(), &Self::__provision, rootfs, image, imageInfo));
+}
+
+
+// This function is currently docker image specific. Depending
+// on docker v1 spec, a docker image may include filesystem
+// changeset, which may need to delete directories or files.
+// The file/dir to be deleted will be labeled by creating a
+// 'whiteout' file, which is at the same location and with the
+// basename of the deleted file or directory prefixed with
+// '.wh.'. Please see:
+// https://github.com/docker/docker/blob/master/image/spec/v1.md
+Future<ProvisionInfo> ProvisionerProcess::__provision(
+    const string& rootfs,
+    const Image& image,
+    const ImageInfo& imageInfo)
+{
+  // Skip single-layered images since no 'whiteout' files needs
+  // to be handled, and this excludes any image using the bind
+  // backend.
+  if (imageInfo.layers.size() == 1 || image.type() != Image::DOCKER) {
+    return ProvisionInfo{rootfs, imageInfo.dockerManifest};
+  }
+
+  char* _rootfs[] = {const_cast<char*>(rootfs.c_str()), nullptr};
+
+  FTS* tree = ::fts_open(_rootfs, FTS_NOCHDIR | FTS_PHYSICAL, nullptr);
+  if (tree == nullptr) {
+    return Failure("Failed to open '" + rootfs + "': " + os::strerror(errno));
+  }
+
+  vector<string> whiteout;
+
+  for (FTSENT *node = ::fts_read(tree);
+       node != nullptr; node = ::fts_read(tree)) {
+    if (node->fts_info == FTS_F &&
+        strings::startsWith(node->fts_name, string(spec::WHITEOUT_PREFIX))) {
+      Path path = Path(node->fts_path);
+
+      whiteout.push_back(path::join(path.dirname(), path.basename().substr(
+          strlen(spec::WHITEOUT_PREFIX))));
+
+      Try<Nothing> rm = os::rm(path.value);
+      if (rm.isError()) {
+        ::fts_close(tree);
+        return Failure(
+            "Failed to remove the whiteout '.wh.' file '" +
+            path.value + "': " + rm.error());
+      }
+    }
+  }
+
+  if (errno != 0) {
+    Error error = ErrnoError();
+    ::fts_close(tree);
+    return Failure(error);
+  }
+
+  if (::fts_close(tree) != 0) {
+    return Failure(
+        "Failed to stop traversing file system: " + os::strerror(errno));
+  }
+
+  foreach (const string& path, whiteout) {
+    if (os::stat::isdir(path)) {
+      Try<Nothing> rmdir = os::rmdir(path);
+      if (rmdir.isError()) {
+        return Failure(
+            "Failed to remove whiteout directory '" +
+            path + "': " + rmdir.error());
+      }
+    } else {
+      Try<Nothing> rm = os::rm(path);
+      if (rm.isError()) {
+        return Failure(
+            "Failed to remove whiteout file '" +
+            path + "': " + rm.error());
+      }
+    }
+  }
+
+  return ProvisionInfo{rootfs, imageInfo.dockerManifest};
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/477ec789/src/slave/containerizer/mesos/provisioner/provisioner.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/provisioner/provisioner.hpp b/src/slave/containerizer/mesos/provisioner/provisioner.hpp
index 457f3ec..48a0505 100644
--- a/src/slave/containerizer/mesos/provisioner/provisioner.hpp
+++ b/src/slave/containerizer/mesos/provisioner/provisioner.hpp
@@ -128,6 +128,12 @@ public:
 private:
   process::Future<ProvisionInfo> _provision(
       const ContainerID& containerId,
+      const Image& image,
+      const ImageInfo& imageInfo);
+
+  process::Future<ProvisionInfo> __provision(
+      const std::string& rootfs,
+      const Image& image,
       const ImageInfo& imageInfo);
 
   process::Future<bool> _destroy(const ContainerID& containerId);


Mime
View raw message