Repository: mesos
Updated Branches:
  refs/heads/master dcc87a160 -> 0ba6b89b7


Added usage() for the docker containerizer.

Added one unit test for this.


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

Branch: refs/heads/master
Commit: 1f994fd1c4e28987d022c815200a42e854a4aa69
Parents: 1bb4bd7
Author: Yifan Gu <[email protected]>
Authored: Thu Jun 26 23:56:58 2014 -0700
Committer: Benjamin Hindman <[email protected]>
Committed: Mon Aug 4 15:08:15 2014 -0700

----------------------------------------------------------------------
 src/slave/containerizer/docker.cpp          | 39 ++++++++++-
 src/slave/containerizer/isolators/posix.hpp | 14 +++-
 src/tests/docker_containerizer_tests.cpp    | 86 ++++++++++++++++++++++++
 src/usage/usage.cpp                         |  4 +-
 src/usage/usage.hpp                         |  2 +-
 5 files changed, 137 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/1f994fd1/src/slave/containerizer/docker.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/docker.cpp 
b/src/slave/containerizer/docker.cpp
index 3c7f810..5968916 100644
--- a/src/slave/containerizer/docker.cpp
+++ b/src/slave/containerizer/docker.cpp
@@ -36,6 +36,9 @@
 #include "slave/containerizer/containerizer.hpp"
 #include "slave/containerizer/docker.hpp"
 
+#include "usage/usage.hpp"
+
+
 using std::list;
 using std::map;
 using std::string;
@@ -130,6 +133,10 @@ private:
       const bool& killed,
       const Future<Option<int > >& status);
 
+  Future<ResourceStatistics> _usage(
+    const ContainerID& containerId,
+    const Future<Docker::Container> container);
+
   // Call back for when the executor exits. This will trigger
   // container destroy.
   void reaped(const ContainerID& containerId);
@@ -623,9 +630,35 @@ Future<Nothing> DockerContainerizerProcess::update(
 Future<ResourceStatistics> DockerContainerizerProcess::usage(
     const ContainerID& containerId)
 {
-  // TODO(benh): Implement! Look up Docker container ID then read
-  // cgroups files ala ./isolators/cgroups/cpushare.cpp.
-  return ResourceStatistics();
+#ifndef __linux__
+  return Failure("Does not support usage() on non-linux platform");
+#endif // __linux__
+
+  if (!promises.contains(containerId)) {
+    return Failure("Unknown container: " + stringify(containerId));
+  }
+
+  // Construct the Docker container name.
+  string name = DOCKER_NAME_PREFIX + stringify(containerId);
+  return docker.inspect(name)
+    .then(defer(self(), &Self::_usage, containerId, lambda::_1));
+}
+
+
+Future<ResourceStatistics> DockerContainerizerProcess::_usage(
+    const ContainerID& containerId,
+    const Future<Docker::Container> container)
+{
+  pid_t pid = container.get().pid();
+  if (pid == 0) {
+    return Failure("Container is not running");
+  }
+  Try<ResourceStatistics> usage =
+    mesos::internal::usage(pid, true, true);
+  if (usage.isError()) {
+    return Failure(usage.error());
+  }
+  return usage.get();
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/1f994fd1/src/slave/containerizer/isolators/posix.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/posix.hpp 
b/src/slave/containerizer/isolators/posix.hpp
index 17bbd10..f120aaf 100644
--- a/src/slave/containerizer/isolators/posix.hpp
+++ b/src/slave/containerizer/isolators/posix.hpp
@@ -160,7 +160,12 @@ public:
     }
 
     // Use 'mesos-usage' but only request 'cpus_' values.
-    return mesos::internal::usage(pids.get(containerId).get(), false, true);
+    Try<ResourceStatistics> usage =
+      mesos::internal::usage(pids.get(containerId).get(), false, true);
+    if (usage.isError()) {
+      return Failure(usage.error());
+    }
+    return usage.get();
   }
 
 private:
@@ -188,7 +193,12 @@ public:
     }
 
     // Use 'mesos-usage' but only request 'mem_' values.
-    return mesos::internal::usage(pids.get(containerId).get(), true, false);
+    Try<ResourceStatistics> usage =
+      mesos::internal::usage(pids.get(containerId).get(), true, false);
+    if (usage.isError()) {
+      return Failure(usage.error());
+    }
+    return usage.get();
   }
 
 private:

http://git-wip-us.apache.org/repos/asf/mesos/blob/1f994fd1/src/tests/docker_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/docker_containerizer_tests.cpp 
b/src/tests/docker_containerizer_tests.cpp
index a6ba9da..3941d5a 100644
--- a/src/tests/docker_containerizer_tests.cpp
+++ b/src/tests/docker_containerizer_tests.cpp
@@ -172,3 +172,89 @@ TEST_F(DockerContainerizerTest, DOCKER_Launch)
 
   Shutdown();
 }
+
+// This test tests DockerContainerizer::usage()
+TEST_F(DockerContainerizerTest, DOCKER_Usage)
+{
+  Try<PID<Master> > master = StartMaster();
+  ASSERT_SOME(master);
+
+  slave::Flags flags = CreateSlaveFlags();
+
+  Docker docker("docker");
+
+  MockDockerContainerizer dockerContainer(flags, true, docker);
+
+  Try<PID<Slave> > slave = StartSlave((slave::Containerizer*) 
&dockerContainer);
+  ASSERT_SOME(slave);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+    &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+
+  Future<FrameworkID> frameworkId;
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .WillOnce(FutureArg<1>(&frameworkId));
+
+  Future<vector<Offer> > offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(frameworkId);
+
+  AWAIT_READY(offers);
+  EXPECT_NE(0u, offers.get().size());
+
+  const Offer& offer = offers.get()[0];
+
+  TaskInfo task;
+  task.set_name("");
+  task.mutable_task_id()->set_value("1");
+  task.mutable_slave_id()->CopyFrom(offer.slave_id());
+  task.mutable_resources()->CopyFrom(offer.resources());
+
+  CommandInfo command;
+  CommandInfo::ContainerInfo* containerInfo = command.mutable_container();
+  containerInfo->set_image("docker://busybox");
+  command.set_value("sleep 120");
+
+  task.mutable_command()->CopyFrom(command);
+
+  Future<TaskStatus> statusRunning;
+
+  vector<TaskInfo> tasks;
+  tasks.push_back(task);
+
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillRepeatedly(DoDefault());
+
+  // Usage() should fail since the container is not launched.
+  Future<ResourceStatistics> usage =
+    dockerContainer.usage(dockerContainer.lastContainerId);
+
+  AWAIT_FAILED(usage);
+
+  driver.launchTasks(offers.get()[0].id(), tasks);
+
+  AWAIT_READY_FOR(statusRunning, Seconds(60));
+  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());
+
+  usage = dockerContainer.usage(dockerContainer.lastContainerId);
+  AWAIT_READY(usage);
+  // TODO(yifan): Verify the usage.
+
+  dockerContainer.destroy(dockerContainer.lastContainerId);
+
+  // Usage() should fail again since the container is destroyed
+  usage = dockerContainer.usage(dockerContainer.lastContainerId);
+  AWAIT_FAILED(usage);
+
+  driver.stop();
+  driver.join();
+
+  Shutdown();
+}

http://git-wip-us.apache.org/repos/asf/mesos/blob/1f994fd1/src/usage/usage.cpp
----------------------------------------------------------------------
diff --git a/src/usage/usage.cpp b/src/usage/usage.cpp
index 29014d1..bb6c0ea 100644
--- a/src/usage/usage.cpp
+++ b/src/usage/usage.cpp
@@ -30,12 +30,12 @@
 namespace mesos {
 namespace internal {
 
-ResourceStatistics usage(pid_t pid, bool mem, bool cpus)
+Try<ResourceStatistics> usage(pid_t pid, bool mem, bool cpus)
 {
   Try<os::ProcessTree> pstree = os::pstree(pid);
 
   if (pstree.isError()) {
-    return ResourceStatistics();
+    return Error("Failed to get usage: " + pstree.error());
   }
 
   ResourceStatistics statistics;

http://git-wip-us.apache.org/repos/asf/mesos/blob/1f994fd1/src/usage/usage.hpp
----------------------------------------------------------------------
diff --git a/src/usage/usage.hpp b/src/usage/usage.hpp
index 5a76746..e0ad2e2 100644
--- a/src/usage/usage.hpp
+++ b/src/usage/usage.hpp
@@ -29,7 +29,7 @@ namespace internal {
 // Collects resource usage of a process tree rooted at 'pid'. Only
 // collects the 'mem_*' values if 'mem' is true and the 'cpus_*'
 // values if 'cpus' is true.
-ResourceStatistics usage(pid_t pid, bool mem = true, bool cpus = true);
+Try<ResourceStatistics> usage(pid_t pid, bool mem = true, bool cpus = true);
 
 } // namespace internal {
 } // namespace mesos {

Reply via email to