You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by nn...@apache.org on 2015/10/13 02:01:15 UTC

mesos git commit: Added a new callback enabling custom resource discovery logic.

Repository: mesos
Updated Branches:
  refs/heads/master faae791ab -> 82c2a7866


Added a new callback enabling custom resource discovery logic.

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


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

Branch: refs/heads/master
Commit: 82c2a78667bd4694b0de1be449cffd32ab0156b2
Parents: faae791
Author: Felix Abecassis <fa...@nvidia.com>
Authored: Fri Oct 9 16:45:36 2015 -0700
Committer: Niklas Q. Nielsen <ni...@qni.dk>
Committed: Mon Oct 12 17:00:41 2015 -0700

----------------------------------------------------------------------
 include/mesos/hook.hpp            | 10 +++++++
 src/examples/test_hook_module.cpp | 22 +++++++++++++++
 src/hook/manager.cpp              | 27 ++++++++++++++++++
 src/hook/manager.hpp              |  3 ++
 src/slave/slave.cpp               |  9 +++++-
 src/tests/hook_tests.cpp          | 50 ++++++++++++++++++++++++++++++++++
 6 files changed, 120 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/82c2a786/include/mesos/hook.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/hook.hpp b/include/mesos/hook.hpp
index 2fe060e..0c1042a 100644
--- a/include/mesos/hook.hpp
+++ b/include/mesos/hook.hpp
@@ -123,6 +123,16 @@ public:
   {
     return None();
   }
+
+  // This hook is called from within the slave when it initializes. A module
+  // implementing the hook creates and returns a Resources object with the new
+  // list of resources available on the slave before they are advertised to the
+  // master. These new resources overwrite the previous ones in SlaveInfo.
+  virtual Result<Resources> slaveResourcesDecorator(
+      const SlaveInfo& slaveInfo)
+  {
+    return None();
+  }
 };
 
 } // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/82c2a786/src/examples/test_hook_module.cpp
----------------------------------------------------------------------
diff --git a/src/examples/test_hook_module.cpp b/src/examples/test_hook_module.cpp
index c09d7dd..cd7c184 100644
--- a/src/examples/test_hook_module.cpp
+++ b/src/examples/test_hook_module.cpp
@@ -265,6 +265,28 @@ public:
 
     return result;
   }
+
+
+  virtual Result<Resources> slaveResourcesDecorator(
+      const SlaveInfo& slaveInfo)
+  {
+    LOG(INFO) << "Executing 'slaveResourcesDecorator' hook";
+
+    Resources resources;
+    // Remove the existing "cpus" resource, it will be overwritten by the
+    // current hook. Keep other resources unchanged.
+    foreach (const Resource& resource, slaveInfo.resources()) {
+      if (resource.name() != "cpus") {
+        resources += resource;
+      }
+    }
+
+    // Force the value of "cpus" to 4 and add a new custom resource named "foo"
+    // of type set.
+    resources += Resources::parse("cpus:4;foo:{bar,baz}").get();
+
+    return resources;
+  }
 };
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/82c2a786/src/hook/manager.cpp
----------------------------------------------------------------------
diff --git a/src/hook/manager.cpp b/src/hook/manager.cpp
index 52d53f0..108bd46 100644
--- a/src/hook/manager.cpp
+++ b/src/hook/manager.cpp
@@ -273,5 +273,32 @@ TaskStatus HookManager::slaveTaskStatusDecorator(
   }
 }
 
+Resources HookManager::slaveResourcesDecorator(
+    const SlaveInfo& slaveInfo)
+{
+  // We need a mutable copy of the Resources object. Each hook will see the
+  // changes made by previous hooks, so the order of execution matters. The
+  // execution order is currently unspecified since availableHooks uses a
+  // hashmap.
+  SlaveInfo slaveInfo_ = slaveInfo;
+
+  synchronized (mutex) {
+    foreachpair (const string& name, Hook* hook, availableHooks) {
+      const Result<Resources> result =
+        hook->slaveResourcesDecorator(slaveInfo_);
+
+      // NOTE: Resources remain unchanged if the hook returns None().
+      if (result.isSome()) {
+        slaveInfo_.mutable_resources()->CopyFrom(result.get());
+      } else if (result.isError()) {
+        LOG(WARNING) << "Slave Resources decorator hook failed for "
+                     << "module '" << name << "': " << result.error();
+      }
+    }
+
+    return slaveInfo_.resources();
+  }
+}
+
 } // namespace internal {
 } // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/82c2a786/src/hook/manager.hpp
----------------------------------------------------------------------
diff --git a/src/hook/manager.hpp b/src/hook/manager.hpp
index d35a762..3af1ff8 100644
--- a/src/hook/manager.hpp
+++ b/src/hook/manager.hpp
@@ -74,6 +74,9 @@ public:
   static TaskStatus slaveTaskStatusDecorator(
       const FrameworkID& frameworkId,
       TaskStatus status);
+
+  static Resources slaveResourcesDecorator(
+      const SlaveInfo& slaveInfo);
 };
 
 } // namespace internal {

http://git-wip-us.apache.org/repos/asf/mesos/blob/82c2a786/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index d1c9977..01c5e42 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -351,7 +351,6 @@ void Slave::initialize()
   if (resources.isError()) {
     EXIT(1) << "Failed to determine slave resources: " << resources.error();
   }
-  LOG(INFO) << "Slave resources: " << resources.get();
 
   Attributes attributes;
   if (flags.attributes.isSome()) {
@@ -382,7 +381,15 @@ void Slave::initialize()
   // Initialize slave info.
   info.set_hostname(hostname);
   info.set_port(self().address.port);
+
   info.mutable_resources()->CopyFrom(resources.get());
+  if (HookManager::hooksAvailable()) {
+    info.mutable_resources()->CopyFrom(
+        HookManager::slaveResourcesDecorator(info));
+  }
+
+  LOG(INFO) << "Slave resources: " << info.resources();
+
   info.mutable_attributes()->CopyFrom(attributes);
   // Checkpointing of slaves is always enabled.
   info.set_checkpoint(true);

http://git-wip-us.apache.org/repos/asf/mesos/blob/82c2a786/src/tests/hook_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/hook_tests.cpp b/src/tests/hook_tests.cpp
index c9d35fb..b35ce72 100644
--- a/src/tests/hook_tests.cpp
+++ b/src/tests/hook_tests.cpp
@@ -707,6 +707,56 @@ TEST_F(HookTest, ROOT_DOCKER_VerifySlavePreLaunchDockerHook)
   Shutdown();
 }
 
+// Test that the changes made by the resources decorator hook are correctly
+// propagated to the resource offer.
+TEST_F(HookTest, VerifySlaveResourcesDecorator)
+{
+  Try<PID<Master>> master = StartMaster(CreateMasterFlags());
+  ASSERT_SOME(master);
+
+  MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+  TestContainerizer containerizer(&exec);
+
+  // Start a mock slave since we aren't testing the slave hooks yet.
+  Try<PID<Slave>> slave = StartSlave(&containerizer);
+  ASSERT_SOME(slave);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+    &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+
+  EXPECT_CALL(sched, registered(&driver, _, _));
+
+  Future<vector<Offer>> offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(offers);
+  EXPECT_NE(0u, offers.get().size());
+
+  Resources resources = offers.get()[0].resources();
+
+  // The test hook sets "cpus" to 4.
+  EXPECT_EQ(4, resources.cpus().get());
+
+  // The test hook adds a resource named "foo" of type set with values "bar"
+  // and "baz".
+  EXPECT_EQ(Resources::parse("foo:{bar,baz}").get(), resources.get("foo"));
+
+  // The test hook does not modify "mem", the default value must still be
+  // present.
+  EXPECT_SOME(resources.mem());
+
+  driver.stop();
+  driver.join();
+
+  Shutdown();
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {