You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/04/06 00:01:22 UTC

[1/2] mesos git commit: Introduced a new agent flag docker_config.

Repository: mesos
Updated Branches:
  refs/heads/master 3ef4d3eb4 -> 7c4e1ffe5


Introduced a new agent flag docker_config.

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


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

Branch: refs/heads/master
Commit: 7c8285cf6bf0ec290570bf11f9f29d1997faef90
Parents: 3ef4d3e
Author: Gilbert Song <so...@gmail.com>
Authored: Tue Apr 5 14:56:01 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Apr 5 14:59:39 2016 -0700

----------------------------------------------------------------------
 docs/configuration.md | 22 ++++++++++++++++++++++
 src/slave/flags.cpp   | 17 +++++++++++++++++
 src/slave/flags.hpp   |  2 ++
 3 files changed, 41 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/7c8285cf/docs/configuration.md
----------------------------------------------------------------------
diff --git a/docs/configuration.md b/docs/configuration.md
index 621d272..309a5a0 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -1065,6 +1065,28 @@ containerizer.
 </tr>
 <tr>
   <td>
+    --docker_config=VALUE
+  </td>
+  <td>
+The default docker config file for slave. Can be provided either as a
+path pointing to the slave local docker config file, or as a JSON-formatted
+string. The format of the docker config file should be identical to docker's
+default one (e.g., either <code>~/.docker/config.json</code> or
+<code>~/.dockercfg</code>).
+Example JSON (<code>~/.docker/config.json</code>):
+<pre><code>{
+  "auths": {
+    "https://index.docker.io/v1/": {
+      "auth": "xXxXxXxXxXx=",
+      "email": "username@example.com"
+    }
+  }
+}
+</code></pre>
+  </td>
+</tr>
+<tr>
+  <td>
     --[no-]docker_kill_orphans
   </td>
   <td>

http://git-wip-us.apache.org/repos/asf/mesos/blob/7c8285cf/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index 04d4b61..315cf47 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -498,6 +498,23 @@ mesos::internal::slave::Flags::Flags()
       "path used by the slave's docker image.\n",
       "/var/run/docker.sock");
 
+  add(&Flags::docker_config,
+      "docker_config",
+      "The default docker config file for slave. Can be provided either as a\n"
+      "path pointing to the slave local docker config file, or as a\n"
+      "JSON-formatted string. The format of the docker config file should be\n"
+      "identical to docker's default one (e.g., either\n"
+      "`~/.docker/config.json` or `~/.dockercfg`).\n"
+      "Example JSON (`~/.docker/config.json`):\n"
+      "{\n"
+      "  \"auths\": {\n"
+      "    \"https://index.docker.io/v1/\": {\n"
+      "      \"auth\": \"xXxXxXxXxXx=\",\n"
+      "      \"email\": \"username@example.com\"\n"
+      "    }\n"
+      "  }\n"
+      "}");
+
   add(&Flags::sandbox_directory,
       "sandbox_directory",
       "The absolute path for the directory in the container where the\n"

http://git-wip-us.apache.org/repos/asf/mesos/blob/7c8285cf/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index d0c606e..69e1b01 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -113,6 +113,8 @@ public:
 
   bool docker_kill_orphans;
   std::string docker_socket;
+  Option<JSON::Object> docker_config;
+
 #ifdef ENABLE_NVIDIA_GPU_SUPPORT
   Option<std::vector<unsigned int>> nvidia_gpu_devices;
 #endif


[2/2] mesos git commit: Implemented slave default docker config file support.

Posted by ji...@apache.org.
Implemented slave default docker config file support.

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


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

Branch: refs/heads/master
Commit: 7c4e1ffe5d850c565c8d2ea475c189ce12b09386
Parents: 7c8285c
Author: Gilbert Song <so...@gmail.com>
Authored: Tue Apr 5 15:01:02 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Apr 5 15:01:02 2016 -0700

----------------------------------------------------------------------
 src/docker/docker.cpp              | 87 +++++++++++++++++++++++++++------
 src/docker/docker.hpp              | 15 ++++--
 src/slave/containerizer/docker.cpp |  3 +-
 src/tests/mesos.cpp                |  5 +-
 src/tests/mesos.hpp                |  3 +-
 5 files changed, 91 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/7c4e1ffe/src/docker/docker.cpp
----------------------------------------------------------------------
diff --git a/src/docker/docker.cpp b/src/docker/docker.cpp
index 386f2f4..bb9ddde 100755
--- a/src/docker/docker.cpp
+++ b/src/docker/docker.cpp
@@ -97,13 +97,14 @@ static Future<Nothing> checkError(const string& cmd, const Subprocess& s)
 Try<Owned<Docker>> Docker::create(
     const string& path,
     const string& socket,
-    bool validate)
+    bool validate,
+    const Option<JSON::Object>& config)
 {
   if (!strings::startsWith(socket, "/")) {
     return Error("Invalid Docker socket path: " + socket);
   }
 
-  Owned<Docker> docker(new Docker(path, socket));
+  Owned<Docker> docker(new Docker(path, socket, config));
   if (!validate) {
     return docker;
   }
@@ -651,11 +652,8 @@ Future<Nothing> Docker::run(
 
   map<string, string> environment = os::environment();
 
-  // Currently the Docker CLI picks up dockerconfig by looking for
-  // the config file in the $HOME directory. If one of the URIs
-  // provided is a docker config file we want docker to be able to
-  // pick it up from the sandbox directory where we store all the
-  // URI downloads.
+  // NOTE: This is non-relevant to pick up a docker config file,
+  // which is necessary for private registry.
   environment["HOME"] = sandboxDirectory;
 
   Try<Subprocess> s = subprocess(
@@ -1073,7 +1071,7 @@ Future<Docker::Image> Docker::pull(
 
   if (force) {
     // Skip inspect and docker pull the image.
-    return Docker::__pull(*this, directory, image, path, socket);
+    return Docker::__pull(*this, directory, image, path, socket, config);
   }
 
   argv.push_back(path);
@@ -1115,6 +1113,7 @@ Future<Docker::Image> Docker::pull(
         dockerImage,
         path,
         socket,
+        config,
         output));
 }
 
@@ -1126,6 +1125,7 @@ Future<Docker::Image> Docker::_pull(
     const string& image,
     const string& path,
     const string& socket,
+    const Option<JSON::Object>& config,
     Future<string> output)
 {
   Option<int> status = s.status().get();
@@ -1136,7 +1136,7 @@ Future<Docker::Image> Docker::_pull(
 
   output.discard();
 
-  return Docker::__pull(docker, directory, image, path, socket);
+  return Docker::__pull(docker, directory, image, path, socket, config);
 }
 
 
@@ -1145,7 +1145,8 @@ Future<Docker::Image> Docker::__pull(
     const string& directory,
     const string& image,
     const string& path,
-    const string& socket)
+    const string& socket,
+    const Option<JSON::Object>& config)
 {
   vector<string> argv;
   argv.push_back(path);
@@ -1158,10 +1159,57 @@ Future<Docker::Image> Docker::__pull(
 
   VLOG(1) << "Running " << cmd;
 
-  // Set HOME variable to pick up .dockercfg.
-  map<string, string> environment = os::environment();
+  // Set the HOME path where docker config file locates.
+  Option<string> home;
+  if (config.isSome()) {
+    Try<string> _home = os::mkdtemp();
+
+    if (_home.isError()) {
+      return Failure("Failed to create temporary directory for docker config"
+                     "file: " + _home.error());
+    }
+
+    home = _home.get();
+
+    Result<JSON::Object> auths = config->find<JSON::Object>("auths");
+    if (auths.isError()) {
+      return Failure("Failed to find 'auths' in docker config file: " +
+                     auths.error());
+    }
+
+    const string path = auths.isSome()
+      ? path::join(home.get(), ".docker")
+      : home.get();
+
+    Try<Nothing> mkdir = os::mkdir(path);
+    if (mkdir.isError()) {
+      return Failure("Failed to create path '" + path + "': " + mkdir.error());
+    }
 
-  environment["HOME"] = directory;
+    const string file = path::join(path, auths.isSome()
+        ? "config.json"
+        : ".dockercfg");
+
+    Try<Nothing> write = os::write(file, stringify(config.get()));
+    if (write.isError()) {
+      return Failure("Failed to write docker config file to '" +
+                     file + "': " + write.error());
+    }
+  }
+
+  // Currently the Docker CLI picks up .docker/config.json (old
+  // .dockercfg by looking for the config file in the $HOME
+  // directory. The docker config file can either be specified by
+  // the agent flag '--docker_config', or by one of the URIs
+  // provided which is a docker config file we want docker to be
+  // able to pick it up from the sandbox directory where we store
+  // all the URI downloads.
+  // TODO(gilbert): Deprecate the fetching docker config file
+  // specified as URI method on 0.30.0 release.
+  map<string, string> environment = os::environment();
+  environment["HOME"] = home.isSome()
+    ? home.get()
+    : directory;
 
   Try<Subprocess> s_ = subprocess(
       path,
@@ -1188,7 +1236,18 @@ Future<Docker::Image> Docker::__pull(
         cmd,
         directory,
         image))
-    .onDiscard(lambda::bind(&commandDiscarded, s_.get(), cmd));
+    .onDiscard(lambda::bind(&commandDiscarded, s_.get(), cmd))
+    .onAny([home]() {
+      if (home.isSome()) {
+        Try<Nothing> rmdir = os::rmdir(home.get());
+
+        if (rmdir.isError()) {
+          LOG(WARNING) << "Failed to remove docker config file temporary"
+                       << "'HOME' directory '" << home.get() << "': "
+                       << rmdir.error();
+        }
+      }
+    });
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/7c4e1ffe/src/docker/docker.hpp
----------------------------------------------------------------------
diff --git a/src/docker/docker.hpp b/src/docker/docker.hpp
index 7802f23..da6e9a2 100644
--- a/src/docker/docker.hpp
+++ b/src/docker/docker.hpp
@@ -47,7 +47,8 @@ public:
   static Try<process::Owned<Docker>> create(
       const std::string& path,
       const std::string& socket,
-      bool validate = true);
+      bool validate = true,
+      const Option<JSON::Object>& config = None());
 
   virtual ~Docker() {}
 
@@ -170,8 +171,11 @@ public:
 protected:
   // Uses the specified path to the Docker CLI tool.
   Docker(const std::string& _path,
-         const std::string& _socket)
-       : path(_path), socket("unix://" + _socket) {}
+         const std::string& _socket,
+         const Option<JSON::Object>& _config)
+       : path(_path),
+         socket("unix://" + _socket),
+         config(_config) {}
 
 private:
   static process::Future<Nothing> _run(
@@ -240,6 +244,7 @@ private:
       const std::string& image,
       const std::string& path,
       const std::string& socket,
+      const Option<JSON::Object>& config,
       process::Future<std::string> output);
 
   static process::Future<Image> __pull(
@@ -247,7 +252,8 @@ private:
       const std::string& directory,
       const std::string& image,
       const std::string& path,
-      const std::string& socket);
+      const std::string& socket,
+      const Option<JSON::Object>& config);
 
   static process::Future<Image> ___pull(
       const Docker& docker,
@@ -265,6 +271,7 @@ private:
 
   const std::string path;
   const std::string socket;
+  const Option<JSON::Object> config;
 };
 
 #endif // __DOCKER_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/7c4e1ffe/src/slave/containerizer/docker.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/docker.cpp b/src/slave/containerizer/docker.cpp
index 9314d1f..0576eab 100644
--- a/src/slave/containerizer/docker.cpp
+++ b/src/slave/containerizer/docker.cpp
@@ -141,7 +141,8 @@ Try<DockerContainerizer*> DockerContainerizer::create(
   Try<Owned<Docker>> create = Docker::create(
       flags.docker,
       flags.docker_socket,
-      true);
+      true,
+      flags.docker_config);
 
   if (create.isError()) {
     return Error("Failed to create docker: " + create.error());

http://git-wip-us.apache.org/repos/asf/mesos/blob/7c4e1ffe/src/tests/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp
index f31163b..cf38dbb 100644
--- a/src/tests/mesos.cpp
+++ b/src/tests/mesos.cpp
@@ -566,8 +566,9 @@ MockContainerLogger::~MockContainerLogger() {}
 
 MockDocker::MockDocker(
     const string& path,
-    const string& socket)
-  : Docker(path, socket)
+    const string& socket,
+    const Option<JSON::Object>& config)
+  : Docker(path, socket, config)
 {
   EXPECT_CALL(*this, ps(_, _))
     .WillRepeatedly(Invoke(this, &MockDocker::_ps));

http://git-wip-us.apache.org/repos/asf/mesos/blob/7c4e1ffe/src/tests/mesos.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.hpp b/src/tests/mesos.hpp
index 98f9710..3b565b4 100644
--- a/src/tests/mesos.hpp
+++ b/src/tests/mesos.hpp
@@ -1384,7 +1384,8 @@ class MockDocker : public Docker
 public:
   MockDocker(
       const std::string& path,
-      const std::string& socket);
+      const std::string& socket,
+      const Option<JSON::Object>& config = None());
   virtual ~MockDocker();
 
   MOCK_CONST_METHOD9(