You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by tn...@apache.org on 2015/09/25 18:33:07 UTC

[15/17] mesos git commit: Add Docker local store recover.

Add Docker local store recover.


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

Branch: refs/heads/master
Commit: fb2df960a805132e58624ee0d73eaa098d57d67a
Parents: 11dc584
Author: Timothy Chen <tn...@gmail.com>
Authored: Mon Sep 7 23:07:55 2015 -0700
Committer: Timothy Chen <tn...@apache.org>
Committed: Fri Sep 25 09:02:05 2015 -0700

----------------------------------------------------------------------
 src/Makefile.am                                 |   8 +-
 src/slave/containerizer/provisioners/docker.cpp | 109 ++++++----------
 src/slave/containerizer/provisioners/docker.hpp |   1 -
 .../provisioners/docker/local_store.cpp         | 123 ++++++++++---------
 .../provisioners/docker/local_store.hpp         |  21 ++--
 .../provisioners/docker/reference_store.cpp     |  28 ++---
 .../provisioners/docker/reference_store.hpp     |  11 +-
 .../containerizer/provisioners/docker/store.hpp |  17 ++-
 8 files changed, 147 insertions(+), 171 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 65def70..cd8b2ca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -529,6 +529,10 @@ libmesos_no_3rdparty_la_SOURCES =					\
 	slave/containerizer/provisioner/appc/store.cpp			\
 	slave/containerizer/provisioner/backend.cpp			\
 	slave/containerizer/provisioner/backends/copy.cpp		\
+	slave/containerizer/provisioner/docker.cpp			\
+	slave/containerizer/provisioner/docker/local_store.cpp		\
+	slave/containerizer/provisioner/docker/paths.cpp		\
+	slave/containerizer/provisioner/docker/reference_store.cpp	\
 	slave/containerizer/provisioner/docker/registry_client.cpp	\
 	slave/containerizer/provisioner/docker/token_manager.cpp	\
 	slave/resource_estimators/noop.cpp				\
@@ -701,10 +705,6 @@ if OS_LINUX
   libmesos_no_3rdparty_la_SOURCES += slave/containerizer/isolators/filesystem/shared.cpp
   libmesos_no_3rdparty_la_SOURCES += slave/containerizer/linux_launcher.cpp
   libmesos_no_3rdparty_la_SOURCES += slave/containerizer/provisioner/backends/bind.cpp
-  libmesos_no_3rdparty_la_SOURCES += slave/containerizer/provisioner/docker.cpp
-  libmesos_no_3rdparty_la_SOURCES += slave/containerizer/provisioner/docker/local_store.cpp
-  libmesos_no_3rdparty_la_SOURCES += slave/containerizer/provisioner/docker/paths.cpp
-  libmesos_no_3rdparty_la_SOURCES += slave/containerizer/provisioner/docker/reference_store.cpp
 else
   EXTRA_DIST += linux/cgroups.cpp
   EXTRA_DIST += linux/fs.cpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker.cpp b/src/slave/containerizer/provisioners/docker.cpp
index 32e1a3b..b1f737f 100644
--- a/src/slave/containerizer/provisioners/docker.cpp
+++ b/src/slave/containerizer/provisioners/docker.cpp
@@ -30,10 +30,14 @@
 #include <process/owned.hpp>
 #include <process/sequence.hpp>
 
-#include "linux/fs.hpp"
+#include "slave/containerizer/provisioners/backend.hpp"
+#include "slave/containerizer/provisioners/paths.hpp"
 
+#include "slave/containerizer/provisioners/docker/paths.hpp"
 #include "slave/containerizer/provisioners/docker/store.hpp"
 
+#include "slave/paths.hpp"
+
 using namespace process;
 using namespace mesos::internal::slave;
 
@@ -68,20 +72,18 @@ public:
 
 private:
   DockerProvisionerProcess(
-      const Flags& flags,
-      const process::Owned<Store>& store,
-      const process::Owned<mesos::internal::slave::Backend>& backend);
+      const string& _rootDir,
+      const Flags& _flags,
+      const process::Owned<Store>& _store,
+      const hashmap<std::string, process::Owned<Backend>>& _backends);
 
   process::Future<std::string> _provision(
+      const DockerImage& image,
       const ContainerID& containerId,
-      const DockerImage& image);
-
-  process::Future<DockerImage> fetch(
-      const std::string& name,
-      const std::string& sandbox);
+      const string& rootfs);
 
+  const string& rootDir;
   const Flags flags;
-
   process::Owned<Store> store;
   hashmap<string, process::Owned<Backend>> backends;
 
@@ -92,7 +94,6 @@ private:
   };
 
   hashmap<ContainerID, Owned<Info>> infos;
-
 };
 
 
@@ -179,24 +180,17 @@ Try<Owned<DockerProvisionerProcess>> DockerProvisionerProcess::create(
     const Flags& flags,
     Fetcher* fetcher)
 {
-  string _root =
+  string rootDir =
     slave::paths::getProvisionerDir(flags.work_dir, Image::DOCKER);
 
-  Try<Nothing> mkdir = os::mkdir(_root);
-  if (mkdir.isError()) {
-    return Error("Failed to create provisioner root directory '" +
-                 _root + "': " + mkdir.error());
-  }
-
-  Result<string> root = os::realpath(_root);
-  if (root.isError()) {
-    return Error(
-        "Failed to resolve the realpath of provisioner root directory '" +
-        _root + "': " + root.error());
+  if (!os::exists(rootDir)) {
+    Try<Nothing> mkdir = os::mkdir(rootDir);
+    if (mkdir.isError()) {
+      return Error("Failed to create Docker provisioner root directory '" +
+                   rootDir + "': " + mkdir.error());
+    }
   }
 
-  CHECK_SOME(root); // Can't be None since we just created it.
-
   hashmap<string, Owned<Backend>> backends = Backend::create(flags);
   if (backends.empty()) {
     return Error("No usable Docker provisioner backend created");
@@ -214,6 +208,7 @@ Try<Owned<DockerProvisionerProcess>> DockerProvisionerProcess::create(
 
   return Owned<DockerProvisionerProcess>(
       new DockerProvisionerProcess(
+          rootDir,
           flags,
           store.get(),
           backends));
@@ -221,10 +216,12 @@ Try<Owned<DockerProvisionerProcess>> DockerProvisionerProcess::create(
 
 
 DockerProvisionerProcess::DockerProvisionerProcess(
+    const string& _rootDir,
     const Flags& _flags,
     const Owned<Store>& _store,
     const hashmap<string, Owned<Backend>>& _backends)
-  : flags(_flags),
+  : rootDir(_rootDir),
+    flags(_flags),
     store(_store),
     backends(_backends) {}
 
@@ -252,7 +249,7 @@ Future<Nothing> DockerProvisionerProcess::recover(
   // be destroyed by the containerizer using the normal cleanup path. See
   // MESOS-2367 for details.
   Try<hashmap<ContainerID, string>> containers =
-    provisioners::paths::listContainers(root);
+    provisioners::paths::listContainers(rootDir);
 
   if (containers.isError()) {
     return Failure("Failed to list the containers managed by Docker "
@@ -265,7 +262,7 @@ Future<Nothing> DockerProvisionerProcess::recover(
       Owned<Info> info = Owned<Info>(new Info());
 
       Try<hashmap<string, hashmap<string, string>>> rootfses =
-        provisioners::paths::listContainerRootfses(root, containerId);
+        provisioners::paths::listContainerRootfses(rootDir, containerId);
 
       if (rootfses.isError()) {
         return Failure("Unable to list rootfses belonged to container '" +
@@ -289,7 +286,7 @@ Future<Nothing> DockerProvisionerProcess::recover(
 
     // Destroy (unknown) orphan container's rootfses.
     Try<hashmap<string, hashmap<string, string>>> rootfses =
-      provisioners::paths::listContainerRootfses(root, containerId);
+      provisioners::paths::listContainerRootfses(rootDir, containerId);
 
     if (rootfses.isError()) {
       return Failure("Unable to find rootfses for container '" +
@@ -340,7 +337,7 @@ Future<string> DockerProvisionerProcess::provision(
 
   string rootfsId = UUID::random().toString();
   string rootfs = provisioners::paths::getContainerRootfsDir(
-      root, containerId, flags.docker_backend, rootfsId);
+      rootDir, containerId, flags.docker_backend, rootfsId);
 
   if (!infos.contains(containerId)) {
     infos.put(containerId, Owned<Info>(new Info()));
@@ -348,63 +345,29 @@ Future<string> DockerProvisionerProcess::provision(
 
   infos[containerId]->rootfses[flags.docker_backend].put(rootfsId, rootfs);
 
-
-  return fetch(image.docker().name())
-    .then(defer(self(),
-                &Self::_provision,
-                containerId,
-                lambda::_1));
+  return store->get(image.docker().name())
+    .then(defer(self(), &Self::_provision, lambda::_1, containerId, rootfs));
 }
 
 
 Future<string> DockerProvisionerProcess::_provision(
+    const DockerImage& image,
     const ContainerID& containerId,
-    const DockerImage& image)
+    const string& rootfs)
 {
   CHECK(backends.contains(flags.docker_backend));
 
-  // Create root directory.
-  string base = path::join(flags.docker_rootfs_dir,
-                           stringify(containerId));
-
-  string rootfs = path::join(base, "rootfs");
-
-  Try<Nothing> mkdir = os::mkdir(base);
-  if (mkdir.isError()) {
-    return Failure("Failed to create directory for container filesystem: " +
-                    mkdir.error());
-  }
-
   LOG(INFO) << "Provisioning rootfs for container '" << containerId << "'"
-            << " to '" << base << "'";
+            << " to '" << rootfs << "'";
 
   vector<string> layerPaths;
   foreach (const string& layerId, image.layers) {
-    layerPaths.push_back(path::join(flags.docker_store_dir, layerId, "rootfs"));
+    layerPaths.push_back(
+        paths::getImageLayerRootfsPath(flags.docker_store_dir, layerId));
   }
 
-
-  return backends[flags.docker_backend]->provision(layerPaths, base)
-    .then([rootfs]() -> Future<string> {
-      // Bind mount the rootfs to itself so we can pivot_root. We do
-      // it now so any subsequent mounts by the containerizer or
-      // isolators are correctly handled by pivot_root.
-      Try<Nothing> mount =
-        fs::mount(rootfs, rootfs, None(), MS_BIND | MS_SHARED, NULL);
-      if (mount.isError()) {
-        return Failure("Failure to bind mount rootfs: " + mount.error());
-      }
-
-      return rootfs;
-    });
-}
-
-
-// Fetch an image and all dependencies.
-Future<DockerImage> DockerProvisionerProcess::fetch(
-    const string& name)
-{
-  return store->get(name);
+  return backends[flags.docker_backend]->provision(layerPaths, rootfs)
+    .then([rootfs]() -> Future<string> { return rootfs; });
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker.hpp b/src/slave/containerizer/provisioners/docker.hpp
index 850ce85..35e23c9 100644
--- a/src/slave/containerizer/provisioners/docker.hpp
+++ b/src/slave/containerizer/provisioners/docker.hpp
@@ -41,7 +41,6 @@
 #include <mesos/resources.hpp>
 
 #include "slave/containerizer/provisioner.hpp"
-#include "slave/containerizer/provisioners/backend.hpp"
 
 #include "slave/flags.hpp"
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker/local_store.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker/local_store.cpp b/src/slave/containerizer/provisioners/docker/local_store.cpp
index aec7df9..c6a9efe 100644
--- a/src/slave/containerizer/provisioners/docker/local_store.cpp
+++ b/src/slave/containerizer/provisioners/docker/local_store.cpp
@@ -62,10 +62,13 @@ public:
 
   process::Future<DockerImage> get(const std::string& name);
 
+  process::Future<Nothing> recover();
+
 private:
   LocalStoreProcess(
-      const Flags& flags,
-      Owned<ReferenceStore> _refStore);
+      const Flags& _flags,
+      Owned<ReferenceStore> _refStore)
+    : flags(_flags), refStore(_refStore) {}
 
   process::Future<Nothing> untarImage(
       const std::string& tarPath,
@@ -73,7 +76,7 @@ private:
 
   process::Future<DockerImage> putImage(
       const std::string& name,
-      const std::string& staging)
+      const std::string& staging);
 
   Result<std::string> getParentId(
       const std::string& staging,
@@ -81,18 +84,17 @@ private:
 
   process::Future<Nothing> putLayers(
       const std::string& staging,
-      const std::list<std::string>& layers)
+      const std::list<std::string>& layers);
 
   process::Future<Nothing> putLayer(
       const std::string& staging,
-      const std::string& id)
+      const std::string& id);
 
   process::Future<Nothing> moveLayer(
       const std::string& staging,
-      const std::string& id)
+      const std::string& id);
 
   const Flags flags;
-
   process::Owned<ReferenceStore> refStore;
 };
 
@@ -117,42 +119,17 @@ Try<Owned<Store>> LocalStore::create(
     const Flags& flags,
     Fetcher* fetcher)
 {
-  if (!os::exists(flags.docker_store_dir)) {
-    Try<Nothing> mkdir = os::mkdir(flags.docker_store_dir);
-    if (mkdir.isError()) {
-      return Error("Failed to create Docker store directory: " + mkdir.error());
-    }
-  }
-
-  if (!os::exists(paths::getStagingDir(flags.docker_store_dir))) {
-    Try<Nothing> mkdir =
-      os::mkdir(paths::getStagingDir(flags.docker_store_dir));
-    if (mkdir.isError()) {
-      return Error("Failed to create Docker store staging directory: " +
-                   mkdir.error());
-    }
-  }
-
   Try<Owned<LocalStoreProcess>> process =
     LocalStoreProcess::create(flags, fetcher);
   if (process.isError()) {
     return Error(process.error());
   }
 
-  Try<Owned<ReferenceStore>> refStore = ReferenceStore::create(flags);
-  if (refStore.isError()) {
-    return Error(refStore);
-  }
-
-  return Owned<Store>(new LocalStore(process.get(), refStore.get()));
+  return Owned<Store>(new LocalStore(process.get()));
 }
 
 
-LocalStore::LocalStore(
-    Owned<LocalStoreProcess> process,
-    Owned<ReferenceStore> refStore)
-  : process(process),
-    _refStore(refStore)
+LocalStore::LocalStore(Owned<LocalStoreProcess> _process) : process(_process)
 {
   process::spawn(CHECK_NOTNULL(process.get()));
 }
@@ -165,49 +142,81 @@ LocalStore::~LocalStore()
 }
 
 
-Future<Option<DockerImage>> LocalStore::get(const string& name)
+Future<DockerImage> LocalStore::get(const string& name)
 {
   return dispatch(process.get(), &LocalStoreProcess::get, name);
 }
 
 
+Future<Nothing> LocalStore::recover()
+{
+  return dispatch(process.get(), &LocalStoreProcess::recover);
+}
+
+
 Try<Owned<LocalStoreProcess>> LocalStoreProcess::create(
     const Flags& flags,
     Fetcher* fetcher)
 {
-  return Owned<LocalStoreProcess>(new LocalStoreProcess(flags));
-}
+  if (!os::exists(flags.docker_store_dir)) {
+    Try<Nothing> mkdir = os::mkdir(flags.docker_store_dir);
+    if (mkdir.isError()) {
+      return Error("Failed to create Docker store directory: " + mkdir.error());
+    }
+  }
+
+  if (!os::exists(paths::getStagingDir(flags.docker_store_dir))) {
+    Try<Nothing> mkdir =
+      os::mkdir(paths::getStagingDir(flags.docker_store_dir));
+    if (mkdir.isError()) {
+      return Error("Failed to create Docker store staging directory: " +
+                   mkdir.error());
+    }
+  }
 
+  Try<Owned<ReferenceStore>> refStore = ReferenceStore::create(flags);
+  if (refStore.isError()) {
+    return Error(refStore.error());
+  }
 
-LocalStoreProcess::LocalStoreProcess(const Flags& flags)
-  : flags(flags), refStore(ReferenceStore::create(flags).get()) {}
+  return Owned<LocalStoreProcess>(new LocalStoreProcess(flags, refStore.get()));
+}
 
 
 Future<DockerImage> LocalStoreProcess::get(const string& name)
 {
-  Option<DockerImage> image = refStore->get(name);
-  if (image.isSome()) {
-    return image.get();
-  }
+  return refStore->get(name)
+    .then(defer(self(),
+                [this, &name](
+                    const Option<DockerImage>& image) -> Future<DockerImage> {
+      if (image.isSome()) {
+        return image.get();
+      }
 
-  string tarPath =
-    paths::getLocalImageTarPath(flags.docker_discovery_local_dir, name);
-  if (!os::exists(tarPath)) {
-    return Failure("No Docker image tar archive found");
-  }
+      string tarPath =
+        paths::getLocalImageTarPath(flags.docker_discovery_local_dir, name);
+      if (!os::exists(tarPath)) {
+        return Failure("No Docker image tar archive found");
+      }
 
-  // Create a temporary staging directory.
-  Try<string> staging =
-    os::mkdtemp(paths::getTempStaging(flags.docker_store_dir));
-  if (staging.isError()) {
-    return Failure("Failed to create a staging directory");
-  }
+      // Create a temporary staging directory.
+      Try<string> staging =
+        os::mkdtemp(paths::getTempStaging(flags.docker_store_dir));
+      if (staging.isError()) {
+        return Failure("Failed to create a staging directory");
+      }
 
-  return untarImage(tarPath, staging.get())
-    .then(defer(self(), &Self::putImage, name, staging.get()));
+      return untarImage(tarPath, staging.get())
+        .then(defer(self(), &Self::putImage, name, staging.get()));
+    }));
 }
 
 
+Future<Nothing> LocalStoreProcess::recover()
+{
+  return refStore->recover();
+}
+
 Future<Nothing> LocalStoreProcess::untarImage(
     const string& tarPath,
     const string& staging)
@@ -376,7 +385,7 @@ Future<Nothing> LocalStoreProcess::putLayer(
 
   const string imageLayerPath =
     paths::getImageLayerPath(flags.docker_store_dir, id);
-  if (!os::exists()) {
+  if (!os::exists(imageLayerPath)) {
     Try<Nothing> mkdir = os::mkdir(imageLayerPath);
     if (mkdir.isError()) {
       return Failure("Failed to create Image layer directory '" +

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker/local_store.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker/local_store.hpp b/src/slave/containerizer/provisioners/docker/local_store.hpp
index 2f0c9f1..b650b5e 100644
--- a/src/slave/containerizer/provisioners/docker/local_store.hpp
+++ b/src/slave/containerizer/provisioners/docker/local_store.hpp
@@ -26,8 +26,17 @@ namespace internal {
 namespace slave {
 namespace docker {
 
+// Forward declaration.
 class LocalStoreProcess;
+class ReferenceStore;
 
+
+/**
+ * LocalStore assumes Docker images are stored in a local directory
+ * (configured with flags.docker_discovery_local_dir), with all the
+ * images saved as tar with the name as the image name with tag (e.g:
+ * ubuntu:14.04.tar).
+ */
 class LocalStore : public Store
 {
 public:
@@ -37,18 +46,12 @@ public:
       const Flags& flags,
       Fetcher* fetcher);
 
-  /**
-   * Put assumes the image tar archive is located in the directory specified in
-   * the slave flag docker_discovery_local_dir and is named with <name>.tar .
-   */
-  virtual process::Future<DockerImage> put(
-      const std::string& name,
-      const std::string& sandbox);
+  virtual process::Future<DockerImage> get(const std::string& name);
 
-  virtual process::Future<Option<DockerImage>> get(const std::string& name);
+  virtual process::Future<Nothing> recover();
 
 private:
-  explicit LocalStore(process::Owned<LocalStoreProcess> process);
+  explicit LocalStore(process::Owned<LocalStoreProcess> _process);
 
   LocalStore(const LocalStore&); // Not copyable.
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker/reference_store.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker/reference_store.cpp b/src/slave/containerizer/provisioners/docker/reference_store.cpp
index 1567248..4b72319 100644
--- a/src/slave/containerizer/provisioners/docker/reference_store.cpp
+++ b/src/slave/containerizer/provisioners/docker/reference_store.cpp
@@ -54,18 +54,15 @@ class ReferenceStoreProcess : public process::Process<ReferenceStoreProcess>
 public:
   ~ReferenceStoreProcess() {}
 
-  // Explicitly use 'initialize' since we are overloading below.
-  using process::ProcessBase::initialize;
-
-  void initialize();
-
   static Try<process::Owned<ReferenceStoreProcess>> create(const Flags& flags);
 
-  process::Future<DockerImage> put(
+  Future<DockerImage> put(
       const std::string& name,
       const std::list<std::string>& layers);
 
-  process::Future<Option<DockerImage>> get(const std::string& name);
+  Future<Option<DockerImage>> get(const std::string& name);
+
+  Future<Nothing> recover();
 
   // TODO(chenlily): Implement removal of unreferenced images.
 
@@ -109,9 +106,9 @@ ReferenceStore::~ReferenceStore()
 }
 
 
-void ReferenceStore::initialize()
+Future<Nothing> ReferenceStore::recover()
 {
-  process::dispatch(process.get(), &ReferenceStoreProcess::initialize);
+  return process::dispatch(process.get(), &ReferenceStoreProcess::recover);
 }
 
 
@@ -194,7 +191,7 @@ Try<Nothing> ReferenceStoreProcess::persist()
 }
 
 
-void ReferenceStoreProcess::initialize()
+Future<Nothing> ReferenceStoreProcess::recover()
 {
   string storedImagesPath = paths::getStoredImagesPath(flags.docker_store_dir);
 
@@ -202,15 +199,14 @@ void ReferenceStoreProcess::initialize()
   if (!os::exists(storedImagesPath)) {
     LOG(INFO) << "No images to load from disk. Docker provisioner image "
               << "storage path: " << storedImagesPath << " does not exist.";
-    return;
+    return Nothing();
   }
 
   Result<DockerProvisionerImages> images =
     ::protobuf::read<DockerProvisionerImages>(storedImagesPath);
   if (images.isError()) {
-    LOG(ERROR) << "Failed to read protobuf for Docker provisioner image: "
-               << images.error();
-    return;
+    return Failure("Failed to read protobuf for Docker provisioner image: " +
+                   images.error());
   }
 
   for (int i = 0; i < images.get().images_size(); i++) {
@@ -224,7 +220,7 @@ void ReferenceStoreProcess::initialize()
       layers.push_back(layerId);
 
       if (!os::exists(
-              paths::getImageLayerPath(flags.docker_store_dir, layerId))) {
+              paths::getImageLayerRootfsPath(flags.docker_store_dir, layerId))) {
         missingLayers.push_back(layerId);
       }
     }
@@ -243,6 +239,8 @@ void ReferenceStoreProcess::initialize()
   }
 
   LOG(INFO) << "Loaded " << storedImages.size() << " Docker images.";
+
+  return Nothing();
 }
 
 } // namespace docker {

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker/reference_store.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker/reference_store.hpp b/src/slave/containerizer/provisioners/docker/reference_store.hpp
index 66b7573..be652ae 100644
--- a/src/slave/containerizer/provisioners/docker/reference_store.hpp
+++ b/src/slave/containerizer/provisioners/docker/reference_store.hpp
@@ -56,12 +56,6 @@ class ReferenceStore
 public:
   ~ReferenceStore();
 
-  /**
-   * Recover all Docker Images that are on disk by checking if all
-   * layer dependencies for that layer are present on disk.
-   */
-  void initialize();
-
   static Try<process::Owned<ReferenceStore>> create(const Flags& flags);
 
   /**
@@ -85,6 +79,11 @@ public:
    */
   process::Future<Option<DockerImage>> get(const std::string& name);
 
+  /**
+   * Recover all stored DockerImage and its layer references.
+   */
+  process::Future<Nothing> recover();
+
 private:
   explicit ReferenceStore(process::Owned<ReferenceStoreProcess> process);
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb2df960/src/slave/containerizer/provisioners/docker/store.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/provisioners/docker/store.hpp b/src/slave/containerizer/provisioners/docker/store.hpp
index b9cb770..a9201d5 100644
--- a/src/slave/containerizer/provisioners/docker/store.hpp
+++ b/src/slave/containerizer/provisioners/docker/store.hpp
@@ -49,14 +49,19 @@ public:
   virtual ~Store() {}
 
   /**
-  * Get image by name.
-  *
-  * @param name The name of the Docker image to retrieve from store.
-  *
-  * @return The DockerImage that holds the Docker layers.
-  */
+   * Get image by name.
+   *
+   * @param name The name of the Docker image to retrieve from store.
+   *
+   * @return The DockerImage that holds the Docker layers.
+   */
   virtual process::Future<DockerImage> get(const std::string& name) = 0;
 
+  /**
+   * Recover all stored images
+   */
+  virtual process::Future<Nothing> recover() = 0;
+
   // TODO(chenlily): Implement removing an image.
 
 protected: