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/06/18 00:14:38 UTC

mesos git commit: Added Mesos metadata when invoking CNI plugins.

Repository: mesos
Updated Branches:
  refs/heads/master f4ce11d94 -> fb53757e7


Added Mesos metadata when invoking CNI plugins.

https://reviews.apache.org/r/48527


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

Branch: refs/heads/master
Commit: fb53757e73379faa74809351521146a920b60790
Parents: f4ce11d
Author: Dan Osborne <da...@projectcalico.org>
Authored: Fri Jun 17 17:09:31 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jun 17 17:14:33 2016 -0700

----------------------------------------------------------------------
 .../mesos/isolators/network/cni/cni.cpp         | 74 ++++++++++++++++++--
 .../mesos/isolators/network/cni/cni.hpp         |  1 +
 src/tests/containerizer/cni_isolator_tests.cpp  |  1 +
 3 files changed, 71 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/fb53757e/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp b/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp
index 7a58995..9fc709e 100644
--- a/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp
+++ b/src/slave/containerizer/mesos/isolators/network/cni/cni.cpp
@@ -920,15 +920,68 @@ Future<Nothing> NetworkCniIsolatorProcess::attach(
         "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
   }
 
+  // Inject Mesos metadata to the network configuration JSON that will
+  // be passed to the plugin. Currently, we only pass in NetworkInfo
+  // for the given network.
   const NetworkConfigInfo& networkConfig =
     networkConfigs[containerNetwork.networkName];
 
+  Try<string> read = os::read(networkConfig.path);
+  if (read.isError()) {
+    return Failure(
+        "Failed to read CNI network configuration file: '" +
+        networkConfig.path + "': " + read.error());
+  }
+
+  Try<JSON::Object> parse = JSON::parse<JSON::Object>(read.get());
+  if (parse.isError()) {
+    return Failure(
+        "Failed to parse CNI network configuration file: '" +
+        networkConfig.path + "': " + parse.error());
+  }
+
+  JSON::Object networkConfigJson = parse.get();
+
+  // Note that 'args' might or might not be specified in the network
+  // configuration file. We need to deal with both cases.
+  Result<JSON::Object> _args = networkConfigJson.at<JSON::Object>("args");
+  if (_args.isError()) {
+    return Failure(
+        "Invalid 'args' found in CNI network configuration file '" +
+        networkConfig.path + "': " + _args.error());
+  }
+
+  JSON::Object args = _args.isSome() ? _args.get() : JSON::Object();
+
+  // Make sure 'org.apache.mesos' is not set. It is reserved by Mesos.
+  if (args.values.count("org.apache.mesos") > 0) {
+    return Failure(
+        "'org.apache.mesos' in 'args' should not be set in CNI network "
+        "configuration file. It is reserved by Mesos");
+  }
+
+  CHECK_SOME(containerNetwork.networkInfo);
+  mesos::NetworkInfo networkInfo = containerNetwork.networkInfo.get();
+
+  JSON::Object mesos;
+  mesos.values["network_info"] = JSON::protobuf(networkInfo);
+  args.values["org.apache.mesos"] = mesos;
+  networkConfigJson.values["args"] = args;
+
+  // TODO(jieyu): Checkpoint the network configuration JSON so that we
+  // can use the same JSON during cleanup.
+
   // Invoke the CNI plugin.
   const string& plugin = networkConfig.config.type();
+
+  VLOG(1) << "Invoking CNI plugin '" << plugin
+          << "' with network configuration '"
+          << stringify(networkConfigJson) << "'";
+
   Try<Subprocess> s = subprocess(
       path::join(pluginDir.get(), plugin),
       {plugin},
-      Subprocess::PATH(networkConfig.path),
+      Subprocess::PIPE(),
       Subprocess::PIPE(),
       Subprocess::PATH("/dev/null"),
       NO_SETSID,
@@ -940,7 +993,10 @@ Future<Nothing> NetworkCniIsolatorProcess::attach(
         "Failed to execute the CNI plugin '" + plugin + "': " + s.error());
   }
 
-  return await(s->status(), io::read(s->out().get()))
+  return await(
+      io::write(s->in().get(), stringify(networkConfigJson)),
+      s->status(),
+      io::read(s->out().get()))
     .then(defer(
         PID<NetworkCniIsolatorProcess>(this),
         &NetworkCniIsolatorProcess::_attach,
@@ -955,12 +1011,20 @@ Future<Nothing> NetworkCniIsolatorProcess::_attach(
     const ContainerID& containerId,
     const string& networkName,
     const string& plugin,
-    const tuple<Future<Option<int>>, Future<string>>& t)
+    const tuple<Future<Nothing>, Future<Option<int>>, Future<string>>& t)
 {
   CHECK(infos.contains(containerId));
   CHECK(infos[containerId]->containerNetworks.contains(networkName));
 
-  Future<Option<int>> status = std::get<0>(t);
+  Future<Nothing> input = std::get<0>(t);
+  if (!input.isReady()) {
+    return Failure(
+        "Failed to send CNI network configuration to "
+        "plugin '" + plugin + "': " +
+        (input.isFailed() ? input.failure() : "discarded"));
+  }
+
+  Future<Option<int>> status = std::get<1>(t);
   if (!status.isReady()) {
     return Failure(
         "Failed to get the exit status of the CNI plugin '" +
@@ -975,7 +1039,7 @@ Future<Nothing> NetworkCniIsolatorProcess::_attach(
 
   // CNI plugin will print result (in case of success) or error (in
   // case of failure) to stdout.
-  Future<string> output = std::get<1>(t);
+  Future<string> output = std::get<2>(t);
   if (!output.isReady()) {
     return Failure(
         "Failed to read stdout from the CNI plugin '" +

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb53757e/src/slave/containerizer/mesos/isolators/network/cni/cni.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/network/cni/cni.hpp b/src/slave/containerizer/mesos/isolators/network/cni/cni.hpp
index 09890ce..2206a86 100644
--- a/src/slave/containerizer/mesos/isolators/network/cni/cni.hpp
+++ b/src/slave/containerizer/mesos/isolators/network/cni/cni.hpp
@@ -134,6 +134,7 @@ private:
       const std::string& networkName,
       const std::string& plugin,
       const std::tuple<
+          process::Future<Nothing>,
           process::Future<Option<int>>,
           process::Future<std::string>>& t);
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/fb53757e/src/tests/containerizer/cni_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/cni_isolator_tests.cpp b/src/tests/containerizer/cni_isolator_tests.cpp
index b9fbd38..a51f24b 100644
--- a/src/tests/containerizer/cni_isolator_tests.cpp
+++ b/src/tests/containerizer/cni_isolator_tests.cpp
@@ -97,6 +97,7 @@ public:
     cniPluginDir = path::join(sandbox.get(), "plugins");
     ASSERT_SOME(os::mkdir(cniPluginDir));
 
+    // TODO(jieyu): Verify that Mesos metadata is set properly.
     Try<Nothing> write = os::write(
         path::join(cniPluginDir, "mockPlugin"),
         strings::format(R"~(