Introduced v1 API.

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


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

Branch: refs/heads/master
Commit: b923cb529de9095f79d677fe4a977975bcd794b3
Parents: b3293b2
Author: Benjamin Hindman <[email protected]>
Authored: Wed Aug 5 23:07:52 2015 -0700
Committer: Benjamin Hindman <[email protected]>
Committed: Sat Aug 8 16:43:09 2015 -0700

----------------------------------------------------------------------
 include/mesos/scheduler.hpp                |   53 -
 include/mesos/v1/attributes.hpp            |  121 ++
 include/mesos/v1/mesos.hpp                 |  408 +++++++
 include/mesos/v1/mesos.proto               | 1377 +++++++++++++++++++++++
 include/mesos/v1/resources.hpp             |  390 +++++++
 include/mesos/v1/scheduler.hpp             |   84 ++
 include/mesos/v1/scheduler/scheduler.hpp   |   50 +
 include/mesos/v1/scheduler/scheduler.proto |  334 ++++++
 include/mesos/v1/values.hpp                |   71 ++
 src/Makefile.am                            |  114 +-
 src/common/protobuf_utils.cpp              |  148 ---
 src/common/protobuf_utils.hpp              |   18 +-
 src/examples/event_call_framework.cpp      |   38 +-
 src/internal/devolve.cpp                   |  114 ++
 src/internal/devolve.hpp                   |   66 ++
 src/internal/evolve.cpp                    |  260 +++++
 src/internal/evolve.hpp                    |   82 ++
 src/master/contender.hpp                   |    2 +
 src/master/master.hpp                      |   12 +-
 src/scheduler/scheduler.cpp                |   51 +-
 src/tests/mesos.hpp                        |   29 +-
 src/tests/scheduler_driver_tests.cpp       |  399 +++++++
 src/tests/scheduler_tests.cpp              |  540 ++-------
 src/tests/slave_tests.cpp                  |    2 -
 src/v1/attributes.cpp                      |  229 ++++
 src/v1/mesos.cpp                           |  363 ++++++
 src/v1/resources.cpp                       | 1264 +++++++++++++++++++++
 src/v1/values.cpp                          |  588 ++++++++++
 28 files changed, 6496 insertions(+), 711 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/scheduler.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/scheduler.hpp b/include/mesos/scheduler.hpp
index cd235a1..ee198b6 100644
--- a/include/mesos/scheduler.hpp
+++ b/include/mesos/scheduler.hpp
@@ -19,17 +19,12 @@
 #ifndef __MESOS_SCHEDULER_HPP__
 #define __MESOS_SCHEDULER_HPP__
 
-#include <functional>
 #include <mutex>
-#include <queue>
 #include <string>
 #include <vector>
 
 #include <mesos/mesos.hpp>
 
-#include <mesos/scheduler/scheduler.hpp>
-
-
 // Mesos scheduler interface and scheduler driver. A scheduler is used
 // to interact with Mesos in order run distributed computations.
 //
@@ -466,54 +461,6 @@ private:
   std::string schedulerId;
 };
 
-
-namespace scheduler {
-
-// Interface to Mesos for a scheduler. Abstracts master detection
-// (connection and disconnection) and authentication if some
-// credentials are provided.
-//
-// Expects three callbacks, 'connected', 'disconnected', and
-// 'received' which will get invoked _serially_ when it's determined
-// that we've connected, disconnected, or received events from the
-// master. Note that we drop events while disconnected but it's
-// possible to receive a batch of events across a
-// disconnected/connected transition before getting the disconnected
-// and then connected callback.
-//
-// TODO(benh): Don't include events in 'received' that occured after a
-// disconnected/connected transition.
-class Mesos
-{
-public:
-  Mesos(const std::string& master,
-        const std::function<void(void)>& connected,
-        const std::function<void(void)>& disconnected,
-        const std::function<void(const std::queue<Event>&)>& received);
-
-  // Same as the above constructor but takes 'credential' as argument.
-  // The credential will be used for authenticating with the master.
-  Mesos(const std::string& master,
-        const Credential& credential,
-        const std::function<void(void)>& connected,
-        const std::function<void(void)>& disconnected,
-        const std::function<void(const std::queue<Event>&)>& received);
-
-  virtual ~Mesos();
-
-  // Attempts to send a call to the master.
-  //
-  // Some local validation of calls is performed which may generate
-  // events without ever being sent to the master. This includes when
-  // calls are sent but no master is currently detected (i.e., we're
-  // disconnected).
-  virtual void send(const Call& call);
-
-private:
-  MesosProcess* process;
-};
-
-} // namespace scheduler {
 } // namespace mesos {
 
 #endif // __MESOS_SCHEDULER_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/v1/attributes.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/attributes.hpp b/include/mesos/v1/attributes.hpp
new file mode 100644
index 0000000..8f33aa7
--- /dev/null
+++ b/include/mesos/v1/attributes.hpp
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MESOS_V1_ATTRIBUTES_HPP__
+#define __MESOS_V1_ATTRIBUTES_HPP__
+
+#include <iterator>
+#include <string>
+
+#include <mesos/v1/mesos.hpp>
+
+#include <stout/option.hpp>
+
+namespace mesos {
+namespace v1 {
+
+std::ostream& operator << (std::ostream& stream, const Attribute& attribute);
+
+
+class Attributes
+{
+public:
+  Attributes() {}
+
+  /*implicit*/
+  Attributes(const google::protobuf::RepeatedPtrField<Attribute>& _attributes)
+  {
+    attributes.MergeFrom(_attributes);
+  }
+
+  /*implicit*/
+  Attributes(const Attributes& that)
+  {
+    attributes.MergeFrom(that.attributes);
+  }
+
+  Attributes& operator = (const Attributes& that)
+  {
+    if (this != &that) {
+      attributes.Clear();
+      attributes.MergeFrom(that.attributes);
+    }
+
+    return *this;
+  }
+
+  bool operator == (const Attributes& that) const;
+
+
+  bool operator != (const Attributes& that) const
+  {
+    return !(*this == that);
+  }
+
+  size_t size() const
+  {
+    return attributes.size();
+  }
+
+  // Using this operator makes it easy to copy a attributes object into
+  // a protocol buffer field.
+  operator const google::protobuf::RepeatedPtrField<Attribute>& () const
+  {
+    return attributes;
+  }
+
+  void add(const Attribute& attribute)
+  {
+    attributes.Add()->MergeFrom(attribute);
+  }
+
+  const Attribute get(int index) const
+  {
+    return attributes.Get(index);
+  }
+
+  const Option<Attribute> get(const Attribute& thatAttribute) const;
+
+  template <typename T>
+  T get(const std::string& name, const T& t) const;
+
+  typedef google::protobuf::RepeatedPtrField<Attribute>::iterator
+  iterator;
+
+  typedef google::protobuf::RepeatedPtrField<Attribute>::const_iterator
+  const_iterator;
+
+  iterator begin() { return attributes.begin(); }
+  iterator end() { return attributes.end(); }
+
+  const_iterator begin() const { return attributes.begin(); }
+  const_iterator end() const { return attributes.end(); }
+
+  static Attribute parse(const std::string& name, const std::string& value);
+  static Attributes parse(const std::string& s);
+
+  static bool isValid(const Attribute& attribute);
+
+private:
+  google::protobuf::RepeatedPtrField<Attribute> attributes;
+};
+
+} // namespace v1 {
+} // namespace mesos {
+
+#endif // __MESOS_V1_ATTRIBUTES_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/v1/mesos.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.hpp b/include/mesos/v1/mesos.hpp
new file mode 100644
index 0000000..f74bed8
--- /dev/null
+++ b/include/mesos/v1/mesos.hpp
@@ -0,0 +1,408 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MESOS_V1_HPP__
+#define __MESOS_V1_HPP__
+
+#include <ostream>
+
+#include <boost/functional/hash.hpp>
+
+#include <mesos/v1/mesos.pb.h> // ONLY USEFUL AFTER RUNNING PROTOC.
+
+namespace mesos {
+namespace v1 {
+
+bool operator == (const CommandInfo& left, const CommandInfo& right);
+bool operator == (const CommandInfo::URI& left, const CommandInfo::URI& right);
+bool operator == (const Credential& left, const Credential& right);
+bool operator == (const Environment& left, const Environment& right);
+bool operator == (const ExecutorInfo& left, const ExecutorInfo& right);
+bool operator == (const MasterInfo& left, const MasterInfo& right);
+
+bool operator == (
+    const ResourceStatistics& left,
+    const ResourceStatistics& right);
+
+bool operator == (const AgentInfo& left, const AgentInfo& right);
+bool operator == (const Volume& left, const Volume& right);
+
+bool operator == (const URL& left, const URL& right);
+
+bool operator == (const TaskStatus& left, const TaskStatus& right);
+bool operator != (const TaskStatus& left, const TaskStatus& right);
+
+inline bool operator == (const ContainerID& left, const ContainerID& right)
+{
+  return left.value() == right.value();
+}
+
+
+inline bool operator == (const ExecutorID& left, const ExecutorID& right)
+{
+  return left.value() == right.value();
+}
+
+
+inline bool operator == (const FrameworkID& left, const FrameworkID& right)
+{
+  return left.value() == right.value();
+}
+
+
+inline bool operator == (const FrameworkInfo& left, const FrameworkInfo& right)
+{
+  return (left.name() == right.name()) && (left.user() == right.user());
+}
+
+
+inline bool operator == (const OfferID& left, const OfferID& right)
+{
+  return left.value() == right.value();
+}
+
+
+inline bool operator == (const AgentID& left, const AgentID& right)
+{
+  return left.value() == right.value();
+}
+
+
+inline bool operator == (const TaskID& left, const TaskID& right)
+{
+  return left.value() == right.value();
+}
+
+
+inline bool operator == (const ContainerID& left, const std::string& right)
+{
+  return left.value() == right;
+}
+
+
+inline bool operator == (const ExecutorID& left, const std::string& right)
+{
+  return left.value() == right;
+}
+
+
+inline bool operator == (const FrameworkID& left, const std::string& right)
+{
+  return left.value() == right;
+}
+
+
+inline bool operator == (const OfferID& left, const std::string& right)
+{
+  return left.value() == right;
+}
+
+
+inline bool operator == (const AgentID& left, const std::string& right)
+{
+  return left.value() == right;
+}
+
+
+inline bool operator == (const TaskID& left, const std::string& right)
+{
+  return left.value() == right;
+}
+
+
+inline bool operator != (const ContainerID& left, const ContainerID& right)
+{
+  return left.value() != right.value();
+}
+
+
+inline bool operator != (const ExecutorID& left, const ExecutorID& right)
+{
+  return left.value() != right.value();
+}
+
+
+inline bool operator != (const FrameworkID& left, const FrameworkID& right)
+{
+  return left.value() != right.value();
+}
+
+
+inline bool operator != (const AgentID& left, const AgentID& right)
+{
+  return left.value() != right.value();
+}
+
+
+inline bool operator < (const ContainerID& left, const ContainerID& right)
+{
+  return left.value() < right.value();
+}
+
+
+inline bool operator < (const ExecutorID& left, const ExecutorID& right)
+{
+  return left.value() < right.value();
+}
+
+
+inline bool operator < (const FrameworkID& left, const FrameworkID& right)
+{
+  return left.value() < right.value();
+}
+
+
+inline bool operator < (const OfferID& left, const OfferID& right)
+{
+  return left.value() < right.value();
+}
+
+
+inline bool operator < (const AgentID& left, const AgentID& right)
+{
+  return left.value() < right.value();
+}
+
+
+inline bool operator < (const TaskID& left, const TaskID& right)
+{
+  return left.value() < right.value();
+}
+
+
+inline std::size_t hash_value(const CommandInfo::URI& uri)
+{
+  size_t seed = 0;
+
+  if (uri.extract()) {
+    seed += 11;
+  }
+
+  if (uri.executable()) {
+    seed += 2003;
+  }
+
+  boost::hash_combine(seed, uri.value());
+  return seed;
+}
+
+
+inline std::size_t hash_value(const ContainerID& containerId)
+{
+  size_t seed = 0;
+  boost::hash_combine(seed, containerId.value());
+  return seed;
+}
+
+
+inline std::size_t hash_value(const ExecutorID& executorId)
+{
+  size_t seed = 0;
+  boost::hash_combine(seed, executorId.value());
+  return seed;
+}
+
+
+inline std::size_t hash_value(const FrameworkID& frameworkId)
+{
+  size_t seed = 0;
+  boost::hash_combine(seed, frameworkId.value());
+  return seed;
+}
+
+
+inline std::size_t hash_value(const OfferID& offerId)
+{
+  size_t seed = 0;
+  boost::hash_combine(seed, offerId.value());
+  return seed;
+}
+
+
+inline std::size_t hash_value(const AgentID& agentId)
+{
+  size_t seed = 0;
+  boost::hash_combine(seed, agentId.value());
+  return seed;
+}
+
+
+inline std::size_t hash_value(const TaskID& taskId)
+{
+  size_t seed = 0;
+  boost::hash_combine(seed, taskId.value());
+  return seed;
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ACLs& acls)
+{
+  return stream << acls.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ContainerID& containerId)
+{
+  return stream << containerId.value();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ContainerInfo& containerInfo)
+{
+  return stream << containerInfo.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ExecutorID& executorId)
+{
+  return stream << executorId.value();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ExecutorInfo& executor)
+{
+  return stream << executor.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const FrameworkID& frameworkId)
+{
+  return stream << frameworkId.value();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const MasterInfo& master)
+{
+  return stream << master.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const OfferID& offerId)
+{
+  return stream << offerId.value();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const RateLimits& limits)
+{
+  return stream << limits.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const AgentID& agentId)
+{
+  return stream << agentId.value();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const AgentInfo& agent)
+{
+  return stream << agent.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const TaskID& taskId)
+{
+  return stream << taskId.value();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const TaskInfo& task)
+{
+  return stream << task.DebugString();
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const TaskState& state)
+{
+  return stream << TaskState_Name(state);
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const std::vector<TaskID>& taskIds)
+{
+  stream << "[ ";
+  for (auto it = taskIds.begin(); it != taskIds.end(); ++it) {
+    if (it != taskIds.begin()) {
+      stream << ", ";
+    }
+    stream << *it;
+  }
+  stream << " ]";
+  return stream;
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const FrameworkInfo::Capability& capability)
+{
+  return stream << FrameworkInfo::Capability::Type_Name(capability.type());
+}
+
+
+template <typename T>
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const google::protobuf::RepeatedPtrField<T>& messages)
+{
+  stream << "[ ";
+  for (auto it = messages.begin(); it != messages.end(); ++it) {
+    if (it != messages.begin()) {
+      stream << ", ";
+    }
+    stream << *it;
+  }
+  stream << " ]";
+  return stream;
+}
+
+} // namespace v1 {
+} // namespace mesos {
+
+#endif // __MESOS_V1_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
new file mode 100644
index 0000000..382b978
--- /dev/null
+++ b/include/mesos/v1/mesos.proto
@@ -0,0 +1,1377 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mesos.v1;
+
+option java_package = "org.apache.mesos.v1";
+option java_outer_classname = "Protos";
+
+
+/**
+ * Status is used to indicate the state of the scheduler and executor
+ * driver after function calls.
+ */
+enum Status {
+  DRIVER_NOT_STARTED = 1;
+  DRIVER_RUNNING = 2;
+  DRIVER_ABORTED = 3;
+  DRIVER_STOPPED = 4;
+}
+
+
+/**
+ * A unique ID assigned to a framework. A framework can reuse this ID
+ * in order to do failover (see MesosSchedulerDriver).
+ */
+message FrameworkID {
+  required string value = 1;
+}
+
+
+/**
+ * A unique ID assigned to an offer.
+ */
+message OfferID {
+  required string value = 1;
+}
+
+
+/**
+ * A unique ID assigned to an agent. Currently, an agent gets a new ID
+ * whenever it (re)registers with Mesos. Framework writers shouldn't
+ * assume any binding between an agent ID and and a hostname.
+ */
+message AgentID {
+  required string value = 1;
+}
+
+
+/**
+ * A framework generated ID to distinguish a task. The ID must remain
+ * unique while the task is active. However, a framework can reuse an
+ * ID _only_ if a previous task with the same ID has reached a
+ * terminal state (e.g., TASK_FINISHED, TASK_LOST, TASK_KILLED, etc.).
+ */
+message TaskID {
+  required string value = 1;
+}
+
+
+/**
+ * A framework generated ID to distinguish an executor. Only one
+ * executor with the same ID can be active on the same agent at a
+ * time.
+ */
+message ExecutorID {
+  required string value = 1;
+}
+
+
+/**
+ * An agent generated ID to distinguish a container. The ID must be
+ * unique between any active or completed containers on the agent. In
+ * particular, containers for different runs of the same (framework,
+ * executor) pair must be unique.
+ */
+message ContainerID {
+  required string value = 1;
+}
+
+
+/**
+ * A network address.
+ *
+ * TODO(bmahler): Use this more widely.
+ */
+message Address {
+  // May contain a hostname, IP address, or both.
+  optional string hostname = 1;
+  optional string ip = 2;
+
+  required int32 port = 3;
+}
+
+
+/**
+ * Represents a URL.
+ */
+message URL {
+  required string scheme = 1;
+  required Address address = 2;
+  optional string path = 3;
+  repeated Parameter query = 4;
+  optional string fragment = 5;
+}
+
+
+/**
+ * Describes a framework.
+ */
+message FrameworkInfo {
+  // Used to determine the Unix user that an executor or task should
+  // be launched as. If the user field is set to an empty string Mesos
+  // will automagically set it to the current user.
+  required string user = 1;
+
+  // Name of the framework that shows up in the Mesos Web UI.
+  required string name = 2;
+
+  // Note that 'id' is only available after a framework has
+  // registered, however, it is included here in order to facilitate
+  // scheduler failover (i.e., if it is set then the
+  // MesosSchedulerDriver expects the scheduler is performing
+  // failover).
+  optional FrameworkID id = 3;
+
+  // The amount of time that the master will wait for the scheduler to
+  // failover before it tears down the framework by killing all its
+  // tasks/executors. This should be non-zero if a framework expects
+  // to reconnect after a failover and not lose its tasks/executors.
+  optional double failover_timeout = 4 [default = 0.0];
+
+  // If set, framework pid, executor pids and status updates are
+  // checkpointed to disk by the agents. Checkpointing allows a
+  // restarted agent to reconnect with old executors and recover
+  // status updates, at the cost of disk I/O.
+  optional bool checkpoint = 5 [default = false];
+
+  // Used to group frameworks for allocation decisions, depending on
+  // the allocation policy being used.
+  optional string role = 6 [default = "*"];
+
+  // Used to indicate the current host from which the scheduler is
+  // registered in the Mesos Web UI. If set to an empty string Mesos
+  // will automagically set it to the current hostname if one is
+  // available.
+  optional string hostname = 7;
+
+  // This field should match the credential's principal the framework
+  // uses for authentication. This field is used for framework API
+  // rate limiting and dynamic reservations. It should be set even
+  // if authentication is not enabled if these features are desired.
+  optional string principal = 8;
+
+  // This field allows a framework to advertise its web UI, so that
+  // the Mesos web UI can link to it. It is expected to be a full URL,
+  // for example http://my-scheduler.example.com:8080/.
+  optional string webui_url = 9;
+
+  message Capability {
+    enum Type {
+      // Receive offers with revocable resources. See 'Resource'
+      // message for details.
+      // TODO(vinod): This is currently a no-op.
+      REVOCABLE_RESOURCES = 1;
+    }
+
+    required Type type = 1;
+  }
+
+  // This field allows a framework to advertise its set of
+  // capabilities (e.g., ability to receive offers for revocable
+  // resources).
+  repeated Capability capabilities = 10;
+}
+
+
+/**
+ * Describes a health check for a task or executor (or any arbitrary
+ * process/command). A "strategy" is picked by specifying one of the
+ * optional fields; currently only 'command' is supported.
+ * Specifying more than one strategy is an error.
+ */
+message HealthCheck {
+  // Describes an HTTP health check. This is not fully implemented and not
+  // recommended for use - see MESOS-2533.
+  message HTTP {
+    // Port to send the HTTP request.
+    required uint32 port = 1;
+
+    // HTTP request path.
+    optional string path = 2 [default = "/"];
+
+    // TODO(benh): Implement:
+    // Whether or not to use HTTPS.
+    // optional bool ssl = 3 [default = false];
+
+    // Expected response statuses. Not specifying any statuses implies
+    // that any returned status is acceptable.
+    repeated uint32 statuses = 4;
+
+    // TODO(benh): Include an 'optional bytes data' field for checking
+    // for specific data in the response.
+  }
+
+  // HTTP health check - not yet recommended for use, see MESOS-2533.
+  optional HTTP http = 1;
+
+  // TODO(benh): Consider adding a URL health check strategy which
+  // allows doing something similar to the HTTP strategy but
+  // encapsulates all the details in a single string field.
+
+  // TODO(benh): Other possible health check strategies could include
+  // one for TCP/UDP.
+
+  // Amount of time to wait until starting the health checks.
+  optional double delay_seconds = 2 [default = 15.0];
+
+  // Interval between health checks.
+  optional double interval_seconds = 3 [default = 10.0];
+
+  // Amount of time to wait for the health check to complete.
+  optional double timeout_seconds = 4 [default = 20.0];
+
+  // Number of consecutive failures until considered unhealthy.
+  optional uint32 consecutive_failures = 5 [default = 3];
+
+  // Amount of time to allow failed health checks since launch.
+  optional double grace_period_seconds = 6 [default = 10.0];
+
+  // Command health check.
+  optional CommandInfo command = 7;
+}
+
+
+/**
+ * Describes a command, executed via: '/bin/sh -c value'. Any URIs specified
+ * are fetched before executing the command.  If the executable field for an
+ * uri is set, executable file permission is set on the downloaded file.
+ * Otherwise, if the downloaded file has a recognized archive extension
+ * (currently [compressed] tar and zip) it is extracted into the executor's
+ * working directory. This extraction can be disabled by setting `extract` to
+ * false. In addition, any environment variables are set before executing
+ * the command (so they can be used to "parameterize" your command).
+ */
+message CommandInfo {
+  message URI {
+    required string value = 1;
+    optional bool executable = 2;
+
+    // In case the fetched file is recognized as an archive, extract
+    // its contents into the sandbox. Note that a cached archive is
+    // not copied from the cache to the sandbox in case extraction
+    // originates from an archive in the cache.
+    optional bool extract = 3 [default = true];
+
+    // If this field is "true", the fetcher cache will be used. If not,
+    // fetching bypasses the cache and downloads directly into the
+    // sandbox directory, no matter whether a suitable cache file is
+    // available or not. The former directs the fetcher to download to
+    // the file cache, then copy from there to the sandbox. Subsequent
+    // fetch attempts with the same URI will omit downloading and copy
+    // from the cache as long as the file is resident there. Cache files
+    // may get evicted at any time, which then leads to renewed
+    // downloading. See also "docs/fetcher.md" and
+    // "docs/fetcher-cache-internals.md".
+    optional bool cache = 4;
+  }
+
+  // Describes a container.
+  // Not all containerizers currently implement ContainerInfo, so it
+  // is possible that a launched task will fail due to supplying this
+  // attribute.
+  // NOTE: The containerizer API is currently in an early beta or
+  // even alpha state. Some details, like the exact semantics of an
+  // "image" or "options" are not yet hardened.
+  // TODO(tillt): Describe the exact scheme and semantics of "image"
+  // and "options".
+  message ContainerInfo {
+    // URI describing the container image name.
+    required string image = 1;
+
+    // Describes additional options passed to the containerizer.
+    repeated string options = 2;
+  }
+
+  // NOTE: MesosContainerizer does currently not support this
+  // attribute and tasks supplying a 'container' will fail.
+  optional ContainerInfo container = 4;
+
+  repeated URI uris = 1;
+
+  optional Environment environment = 2;
+
+  // There are two ways to specify the command:
+  // 1) If 'shell == true', the command will be launched via shell
+  //           (i.e., /bin/sh -c 'value'). The 'value' specified will be
+  //           treated as the shell command. The 'arguments' will be ignored.
+  // 2) If 'shell == false', the command will be launched by passing
+  //           arguments to an executable. The 'value' specified will be
+  //           treated as the filename of the executable. The 'arguments'
+  //           will be treated as the arguments to the executable. This is
+  //           similar to how POSIX exec families launch processes (i.e.,
+  //           execlp(value, arguments(0), arguments(1), ...)).
+  // NOTE: The field 'value' is changed from 'required' to 'optional'
+  // in 0.20.0. It will only cause issues if a new framework is
+  // connecting to an old master.
+  optional bool shell = 6 [default = true];
+  optional string value = 3;
+  repeated string arguments = 7;
+
+  // Enables executor and tasks to run as a specific user. If the user
+  // field is present both in FrameworkInfo and here, the CommandInfo
+  // user value takes precedence.
+  optional string user = 5;
+}
+
+
+/**
+ * Describes information about an executor. The 'data' field can be
+ * used to pass arbitrary bytes to an executor.
+ */
+message ExecutorInfo {
+  required ExecutorID executor_id = 1;
+  optional FrameworkID framework_id = 8; // TODO(benh): Make this required.
+  required CommandInfo command = 7;
+  // Executor provided with a container will launch the container
+  // with the executor's CommandInfo and we expect the container to
+  // act as a Mesos executor.
+  optional ContainerInfo container = 11;
+  repeated Resource resources = 5;
+  optional string name = 9;
+
+  // 'source' is an identifier style string used by frameworks to
+  // track the source of an executor. This is useful when it's
+  // possible for different executor ids to be related semantically.
+  //
+  // NOTE: 'source' is exposed alongside the resource usage of the
+  // executor via JSON on the agent. This allows users to import usage
+  // information into a time series database for monitoring.
+  optional string source = 10;
+
+  optional bytes data = 4;
+
+  // Service discovery information for the executor. It is not
+  // interpreted or acted upon by Mesos. It is up to a service
+  // discovery system to use this information as needed and to handle
+  // executors without service discovery information.
+  optional DiscoveryInfo discovery = 12;
+}
+
+
+/**
+ * Describes a master. This will probably have more fields in the
+ * future which might be used, for example, to link a framework webui
+ * to a master webui.
+ */
+message MasterInfo {
+  required string id = 1;
+
+  // The IP address (only IPv4) as a packed 4-bytes integer,
+  // stored in network order.  Deprecated, use `address.ip` instead.
+  required uint32 ip = 2;
+
+  // The TCP port the Master is listening on for incoming
+  // HTTP requests; deprecated, use `address.port` instead.
+  required uint32 port = 3 [default = 5050];
+
+  // In the default implementation, this will contain information
+  // about both the IP address, port and Master name; it should really
+  // not be relied upon by external tooling/frameworks and be
+  // considered an "internal" implementation field.
+  optional string pid = 4;
+
+  // The server's hostname, if available; it may be unreliable
+  // in environments where the DNS configuration does not resolve
+  // internal hostnames (eg, some public cloud providers).
+  // Deprecated, use `address.hostname` instead.
+  optional string hostname = 5;
+
+  // The running Master version, as a string; taken from the
+  // generated "master/version.hpp".
+  optional string version = 6;
+
+  // The full IP address (supports both IPv4 and IPv6 formats)
+  // and supersedes the use of `ip`, `port` and `hostname`.
+  // Since Mesos 0.24.
+  optional Address address = 7;
+}
+
+
+/**
+ * Describes an agent. Note that the 'id' field is only available
+ * after an agent is registered with the master, and is made available
+ * here to facilitate re-registration.  If checkpoint is set, the
+ * agent is checkpointing its own information and potentially
+ * frameworks' information (if a framework has checkpointing enabled).
+ */
+message AgentInfo {
+  required string hostname = 1;
+  optional int32 port = 8 [default = 5051];
+  repeated Resource resources = 3;
+  repeated Attribute attributes = 5;
+  optional AgentID id = 6;
+}
+
+
+/**
+ * Describes an Attribute or Resource "value". A value is described
+ * using the standard protocol buffer "union" trick.
+ */
+message Value {
+  enum Type {
+    SCALAR = 0;
+    RANGES = 1;
+    SET = 2;
+    TEXT = 3;
+  }
+
+  message Scalar {
+    required double value = 1;
+  }
+
+  message Range {
+    required uint64 begin = 1;
+    required uint64 end = 2;
+  }
+
+  message Ranges {
+    repeated Range range = 1;
+  }
+
+  message Set {
+    repeated string item = 1;
+  }
+
+  message Text {
+    required string value = 1;
+  }
+
+  required Type type = 1;
+  optional Scalar scalar = 2;
+  optional Ranges ranges = 3;
+  optional Set set = 4;
+  optional Text text = 5;
+}
+
+
+/**
+ * Describes an attribute that can be set on a machine. For now,
+ * attributes and resources share the same "value" type, but this may
+ * change in the future and attributes may only be string based.
+ */
+message Attribute {
+  required string name = 1;
+  required Value.Type type = 2;
+  optional Value.Scalar scalar = 3;
+  optional Value.Ranges ranges = 4;
+  optional Value.Set set = 6;
+  optional Value.Text text = 5;
+}
+
+
+/**
+ * Describes a resource on a machine. A resource can take on one of
+ * three types: scalar (double), a list of finite and discrete ranges
+ * (e.g., [1-10, 20-30]), or a set of items. A resource is described
+ * using the standard protocol buffer "union" trick.
+ *
+ * TODO(benh): Add better support for "expected" resources (e.g.,
+ * cpus, memory, disk, network).
+ */
+message Resource {
+  required string name = 1;
+  required Value.Type type = 2;
+  optional Value.Scalar scalar = 3;
+  optional Value.Ranges ranges = 4;
+  optional Value.Set set = 5;
+  optional string role = 6 [default = "*"];
+
+  message ReservationInfo {
+    // Describes a dynamic reservation. A dynamic reservation is
+    // acquired by an operator via the '/reserve' HTTP endpoint or by
+    // a framework via the offer cycle by sending back an
+    // 'Offer::Operation::Reserve' message.
+    // NOTE: We currently do not allow frameworks with role "*" to
+    // make dynamic reservations.
+
+    // This field indicates the principal of the operator or framework
+    // that reserved this resource. It is used in conjunction with the
+    // "unreserve" ACL to determine whether the entity attempting to
+    // unreserve this resource is permitted to do so.
+    // NOTE: This field should match the FrameworkInfo.principal of
+    // the framework that reserved this resource.
+    required string principal = 1;
+  }
+
+  // If this is set, this resource was dynamically reserved by an
+  // operator or a framework. Otherwise, this resource is either unreserved
+  // or statically reserved by an operator via the --resources flag.
+  optional ReservationInfo reservation = 8;
+
+  message DiskInfo {
+    // Describes a persistent disk volume.
+    // A persistent disk volume will not be automatically garbage
+    // collected if the task/executor/agent terminates, but is
+    // re-offered to the framework(s) belonging to the 'role'.
+    // A framework can set the ID (if it is not set yet) to express
+    // the intention to create a new persistent disk volume from a
+    // regular disk resource. To reuse a previously created volume, a
+    // framework can launch a task/executor when it receives an offer
+    // with a persistent volume, i.e., ID is set.
+    // NOTE: Currently, we do not allow a persistent disk volume
+    // without a reservation (i.e., 'role' should not be '*').
+    message Persistence {
+      // A unique ID for the persistent disk volume.
+      // NOTE: The ID needs to be unique per role on each agent.
+      required string id = 1;
+    }
+
+    optional Persistence persistence = 1;
+
+    // Describes how this disk resource will be mounted in the
+    // container. If not set, the disk resource will be used as the
+    // sandbox. Otherwise, it will be mounted according to the
+    // 'container_path' inside 'volume'. The 'host_path' inside
+    // 'volume' is ignored.
+    // NOTE: If 'volume' is set but 'persistence' is not set, the
+    // volume will be automatically garbage collected after
+    // task/executor terminates. Currently, if 'persistence' is set,
+    // 'volume' must be set.
+    optional Volume volume = 2;
+  }
+
+  optional DiskInfo disk = 7;
+
+  message RevocableInfo {}
+
+  // If this is set, the resources are revocable, i.e., any tasks or
+  // executors launched using these resources could get preempted or
+  // throttled at any time. This could be used by frameworks to run
+  // best effort tasks that do not need strict uptime or performance
+  // guarantees. Note that if this is set, 'disk' or 'reservation'
+  // cannot be set.
+  optional RevocableInfo revocable = 9;
+}
+
+/**
+ * When the network bandwidth caps are enabled and the container
+ * is over its limit, outbound packets may be either delayed or
+ * dropped completely either because it exceeds the maximum bandwidth
+ * allocation for a single container (the cap) or because the combined
+ * network traffic of multiple containers on the host exceeds the
+ * transmit capacity of the host (the share). We can report the
+ * following statistics for each of these conditions exported directly
+ * from the Linux Traffic Control Queueing Discipline.
+ *
+ * id         : name of the limiter, e.g. 'tx_bw_cap'
+ * backlog    : number of packets currently delayed
+ * bytes      : total bytes seen
+ * drops      : number of packets dropped in total
+ * overlimits : number of packets which exceeded allocation
+ * packets    : total packets seen
+ * qlen       : number of packets currently queued
+ * rate_bps   : throughput in bytes/sec
+ * rate_pps   : throughput in packets/sec
+ * requeues   : number of times a packet has been delayed due to
+ *              locking or device contention issues
+ *
+ * More information on the operation of Linux Traffic Control can be
+ * found at http://www.lartc.org/lartc.html.
+ */
+message TrafficControlStatistics {
+  required string id = 1;
+  optional uint64 backlog = 2;
+  optional uint64 bytes = 3;
+  optional uint64 drops = 4;
+  optional uint64 overlimits = 5;
+  optional uint64 packets = 6;
+  optional uint64 qlen = 7;
+  optional uint64 ratebps = 8;
+  optional uint64 ratepps = 9;
+  optional uint64 requeues = 10;
+}
+
+
+/**
+ * A snapshot of resource usage statistics.
+ */
+message ResourceStatistics {
+  required double timestamp = 1; // Snapshot time, in seconds since the Epoch.
+
+  optional uint32 processes = 30;
+  optional uint32 threads = 31;
+
+  // CPU Usage Information:
+  // Total CPU time spent in user mode, and kernel mode.
+  optional double cpus_user_time_secs = 2;
+  optional double cpus_system_time_secs = 3;
+
+  // Number of CPUs allocated.
+  optional double cpus_limit = 4;
+
+  // cpu.stat on process throttling (for contention issues).
+  optional uint32 cpus_nr_periods = 7;
+  optional uint32 cpus_nr_throttled = 8;
+  optional double cpus_throttled_time_secs = 9;
+
+  // Memory Usage Information:
+
+  // mem_total_bytes was added in 0.23.0 to represent the total memory
+  // of a process in RAM (as opposed to in Swap). This was previously
+  // reported as mem_rss_bytes, which was also changed in 0.23.0 to
+  // represent only the anonymous memory usage, to keep in sync with
+  // Linux kernel's (arguably erroneous) use of terminology.
+  optional uint64 mem_total_bytes = 36;
+
+  // Total memory + swap usage. This is set if swap is enabled.
+  optional uint64 mem_total_memsw_bytes = 37;
+
+  // Hard memory limit for a container.
+  optional uint64 mem_limit_bytes = 6;
+
+  // Soft memory limit for a container.
+  optional uint64 mem_soft_limit_bytes = 38;
+
+  // Broken out memory usage information: pagecache, rss (anonymous),
+  // mmaped files and swap.
+
+  // TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in
+  // 0.23.0 and will be removed in 0.24.0.
+  optional uint64 mem_file_bytes = 10;
+  optional uint64 mem_anon_bytes = 11;
+
+  // mem_cache_bytes is added in 0.23.0 to represent page cache usage.
+  optional uint64 mem_cache_bytes = 39;
+
+  // Since 0.23.0, mem_rss_bytes is changed to represent only
+  // anonymous memory usage. Note that neither its requiredness, type,
+  // name nor numeric tag has been changed.
+  optional uint64 mem_rss_bytes = 5;
+
+  optional uint64 mem_mapped_file_bytes = 12;
+  // This is only set if swap is enabled.
+  optional uint64 mem_swap_bytes = 40;
+
+  // Number of occurrences of different levels of memory pressure
+  // events reported by memory cgroup. Pressure listening (re)starts
+  // with these values set to 0 when agent (re)starts. See
+  // https://www.kernel.org/doc/Documentation/cgroups/memory.txt for
+  // more details.
+  optional uint64 mem_low_pressure_counter = 32;
+  optional uint64 mem_medium_pressure_counter = 33;
+  optional uint64 mem_critical_pressure_counter = 34;
+
+  // Disk Usage Information for executor working directory.
+  optional uint64 disk_limit_bytes = 26;
+  optional uint64 disk_used_bytes = 27;
+
+  // Perf statistics.
+  optional PerfStatistics perf = 13;
+
+  // Network Usage Information:
+  optional uint64 net_rx_packets = 14;
+  optional uint64 net_rx_bytes = 15;
+  optional uint64 net_rx_errors = 16;
+  optional uint64 net_rx_dropped = 17;
+  optional uint64 net_tx_packets = 18;
+  optional uint64 net_tx_bytes = 19;
+  optional uint64 net_tx_errors = 20;
+  optional uint64 net_tx_dropped = 21;
+
+  // The kernel keeps track of RTT (round-trip time) for its TCP
+  // sockets. RTT is a way to tell the latency of a container.
+  optional double net_tcp_rtt_microsecs_p50 = 22;
+  optional double net_tcp_rtt_microsecs_p90 = 23;
+  optional double net_tcp_rtt_microsecs_p95 = 24;
+  optional double net_tcp_rtt_microsecs_p99 = 25;
+
+  optional double net_tcp_active_connections = 28;
+  optional double net_tcp_time_wait_connections = 29;
+
+  // Network traffic flowing into or out of a container can be delayed
+  // or dropped due to congestion or policy inside and outside the
+  // container.
+  repeated TrafficControlStatistics net_traffic_control_statistics = 35;
+}
+
+
+/**
+ * Describes a snapshot of the resource usage for executors.
+ */
+message ResourceUsage {
+  message Executor {
+    required ExecutorInfo executor_info = 1;
+
+    // This includes resources used by the executor itself
+    // as well as its active tasks.
+    repeated Resource allocated = 2;
+
+    // Current resource usage. If absent, the containerizer
+    // cannot provide resource usage.
+    optional ResourceStatistics statistics = 3;
+  }
+
+  repeated Executor executors = 1;
+
+  // Agent's total resources including checkpointed dynamic
+  // reservations and persistent volumes.
+  repeated Resource total = 2;
+}
+
+
+/**
+ * Describes a sample of events from "perf stat". Only available on
+ * Linux.
+ *
+ * NOTE: Each optional field matches the name of a perf event (see
+ * "perf list") with the following changes:
+ * 1. Names are downcased.
+ * 2. Hyphens ('-') are replaced with underscores ('_').
+ * 3. Events with alternate names use the name "perf stat" returns,
+ *    e.g., for the event "cycles OR cpu-cycles" perf always returns
+ *    cycles.
+ */
+message PerfStatistics {
+  required double timestamp = 1; // Start of sample interval, in seconds since 
the Epoch.
+  required double duration = 2;  // Duration of sample interval, in seconds.
+
+  // Hardware event.
+  optional uint64 cycles = 3;
+  optional uint64 stalled_cycles_frontend = 4;
+  optional uint64 stalled_cycles_backend = 5;
+  optional uint64 instructions = 6;
+  optional uint64 cache_references = 7;
+  optional uint64 cache_misses = 8;
+  optional uint64 branches = 9;
+  optional uint64 branch_misses = 10;
+  optional uint64 bus_cycles = 11;
+  optional uint64 ref_cycles = 12;
+
+  // Software event.
+  optional double cpu_clock = 13;
+  optional double task_clock = 14;
+  optional uint64 page_faults = 15;
+  optional uint64 minor_faults = 16;
+  optional uint64 major_faults = 17;
+  optional uint64 context_switches = 18;
+  optional uint64 cpu_migrations = 19;
+  optional uint64 alignment_faults = 20;
+  optional uint64 emulation_faults = 21;
+
+  // Hardware cache event.
+  optional uint64 l1_dcache_loads = 22;
+  optional uint64 l1_dcache_load_misses = 23;
+  optional uint64 l1_dcache_stores = 24;
+  optional uint64 l1_dcache_store_misses = 25;
+  optional uint64 l1_dcache_prefetches = 26;
+  optional uint64 l1_dcache_prefetch_misses = 27;
+  optional uint64 l1_icache_loads = 28;
+  optional uint64 l1_icache_load_misses = 29;
+  optional uint64 l1_icache_prefetches = 30;
+  optional uint64 l1_icache_prefetch_misses = 31;
+  optional uint64 llc_loads = 32;
+  optional uint64 llc_load_misses = 33;
+  optional uint64 llc_stores = 34;
+  optional uint64 llc_store_misses = 35;
+  optional uint64 llc_prefetches = 36;
+  optional uint64 llc_prefetch_misses = 37;
+  optional uint64 dtlb_loads = 38;
+  optional uint64 dtlb_load_misses = 39;
+  optional uint64 dtlb_stores = 40;
+  optional uint64 dtlb_store_misses = 41;
+  optional uint64 dtlb_prefetches = 42;
+  optional uint64 dtlb_prefetch_misses = 43;
+  optional uint64 itlb_loads = 44;
+  optional uint64 itlb_load_misses = 45;
+  optional uint64 branch_loads = 46;
+  optional uint64 branch_load_misses = 47;
+  optional uint64 node_loads = 48;
+  optional uint64 node_load_misses = 49;
+  optional uint64 node_stores = 50;
+  optional uint64 node_store_misses = 51;
+  optional uint64 node_prefetches = 52;
+  optional uint64 node_prefetch_misses = 53;
+}
+
+
+/**
+ * Describes a request for resources that can be used by a framework
+ * to proactively influence the allocator.  If 'agent_id' is provided
+ * then this request is assumed to only apply to resources on that
+ * agent.
+ */
+message Request {
+  optional AgentID agent_id = 1;
+  repeated Resource resources = 2;
+}
+
+
+/**
+ * Describes some resources available on a agent. An offer only
+ * contains resources from a single agent.
+ */
+message Offer {
+  required OfferID id = 1;
+  required FrameworkID framework_id = 2;
+  required AgentID agent_id = 3;
+  required string hostname = 4;
+
+  // URL for reaching the agent running on the host.
+  optional URL url = 8;
+
+  repeated Resource resources = 5;
+  repeated Attribute attributes = 7;
+  repeated ExecutorID executor_ids = 6;
+
+  // Defines an operation that can be performed against offers.
+  message Operation {
+    enum Type {
+      LAUNCH = 1;
+      RESERVE = 2;
+      UNRESERVE = 3;
+      CREATE = 4;
+      DESTROY = 5;
+    }
+
+    message Launch {
+      repeated TaskInfo task_infos = 1;
+    }
+
+    message Reserve {
+      repeated Resource resources = 1;
+    }
+
+    message Unreserve {
+      repeated Resource resources = 1;
+    }
+
+    message Create {
+      repeated Resource volumes = 1;
+    }
+
+    message Destroy {
+      repeated Resource volumes = 1;
+    }
+
+    required Type type = 1;
+    optional Launch launch = 2;
+    optional Reserve reserve = 3;
+    optional Unreserve unreserve = 4;
+    optional Create create = 5;
+    optional Destroy destroy = 6;
+  }
+}
+
+
+/**
+ * Describes a task. Passed from the scheduler all the way to an
+ * executor (see SchedulerDriver::launchTasks and
+ * Executor::launchTask). Either ExecutorInfo or CommandInfo should be set.
+ * A different executor can be used to launch this task, and subsequent tasks
+ * meant for the same executor can reuse the same ExecutorInfo struct.
+ */
+message TaskInfo {
+  required string name = 1;
+  required TaskID task_id = 2;
+  required AgentID agent_id = 3;
+  repeated Resource resources = 4;
+  optional ExecutorInfo executor = 5;
+  optional CommandInfo command = 7;
+  // Task provided with a container will launch the container as part
+  // of this task paired with the task's CommandInfo.
+  optional ContainerInfo container = 9;
+  optional bytes data = 6;
+  // A health check for the task (currently in *alpha* and initial
+  // support will only be for TaskInfo's that have a CommandInfo).
+  optional HealthCheck health_check = 8;
+
+  // Labels are free-form key value pairs which are exposed through
+  // master and agent endpoints. Labels will not be interpreted or
+  // acted upon by Mesos itself. As opposed to the data field, labels
+  // will be kept in memory on master and agent processes. Therefore,
+  // labels should be used to tag tasks with light-weight meta-data.
+  optional Labels labels = 10;
+
+  // Service discovery information for the task. It is not interpreted
+  // or acted upon by Mesos. It is up to a service discovery system
+  // to use this information as needed and to handle tasks without
+  // service discovery information.
+  optional DiscoveryInfo discovery = 11;
+}
+
+
+/**
+ * Describes possible task states. IMPORTANT: Mesos assumes tasks that
+ * enter terminal states (see below) imply the task is no longer
+ * running and thus clean up any thing associated with the task
+ * (ultimately offering any resources being consumed by that task to
+ * another task).
+ */
+enum TaskState {
+  TASK_STAGING = 6; // Initial state. Framework status updates should not use.
+  TASK_STARTING = 0;
+  TASK_RUNNING = 1;
+  TASK_FINISHED = 2; // TERMINAL. The task finished successfully.
+  TASK_FAILED = 3; // TERMINAL. The task failed to finish successfully.
+  TASK_KILLED = 4; // TERMINAL. The task was killed by the executor.
+  TASK_LOST = 5; // TERMINAL. The task failed but can be rescheduled.
+  TASK_ERROR = 7; // TERMINAL. The task description contains an error.
+}
+
+
+/**
+ * Describes the current status of a task.
+ */
+message TaskStatus {
+  // Describes the source of the task status update.
+  enum Source {
+    SOURCE_MASTER = 0;
+    SOURCE_AGENT = 1;
+    SOURCE_EXECUTOR = 2;
+  }
+
+  // Detailed reason for the task status update.
+  //
+  // TODO(bmahler): Differentiate between agent removal reasons
+  // (e.g. unhealthy vs. unregistered for maintenance).
+  enum Reason {
+    REASON_COMMAND_EXECUTOR_FAILED = 0;
+    REASON_EXECUTOR_PREEMPTED = 17;
+    REASON_EXECUTOR_TERMINATED = 1;
+    REASON_EXECUTOR_UNREGISTERED = 2;
+    REASON_FRAMEWORK_REMOVED = 3;
+    REASON_GC_ERROR = 4;
+    REASON_INVALID_FRAMEWORKID = 5;
+    REASON_INVALID_OFFERS = 6;
+    REASON_MASTER_DISCONNECTED = 7;
+    REASON_MEMORY_LIMIT = 8;
+    REASON_RECONCILIATION = 9;
+    REASON_RESOURCES_UNKNOWN = 18;
+    REASON_AGENT_DISCONNECTED = 10;
+    REASON_AGENT_REMOVED = 11;
+    REASON_AGENT_RESTARTED = 12;
+    REASON_AGENT_UNKNOWN = 13;
+    REASON_TASK_INVALID = 14;
+    REASON_TASK_UNAUTHORIZED = 15;
+    REASON_TASK_UNKNOWN = 16;
+  }
+
+  required TaskID task_id = 1;
+  required TaskState state = 2;
+  optional string message = 4; // Possible message explaining state.
+  optional Source source = 9;
+  optional Reason reason = 10;
+  optional bytes data = 3;
+  optional AgentID agent_id = 5;
+  optional ExecutorID executor_id = 7; // TODO(benh): Use in master/agent.
+  optional double timestamp = 6;
+
+  // Statuses that are delivered reliably to the scheduler will
+  // include a 'uuid'. The status is considered delivered once
+  // it is acknowledged by the scheduler. Schedulers can choose
+  // to either explicitly acknowledge statuses or let the scheduler
+  // driver implicitly acknowledge (default).
+  //
+  // TODO(bmahler): This is currently overwritten in the scheduler
+  // driver and executor driver, but executors will need to set this
+  // to a valid RFC-4122 UUID if using the HTTP API.
+  optional bytes uuid = 11;
+
+  // Describes whether the task has been determined to be healthy
+  // (true) or unhealthy (false) according to the HealthCheck field in
+  // the command info.
+  optional bool healthy = 8;
+
+  // Labels are free-form key value pairs which are exposed through
+  // master and agent endpoints. Labels will not be interpreted or
+  // acted upon by Mesos itself. As opposed to the data field, labels
+  // will be kept in memory on master and agent processes. Therefore,
+  // labels should be used to tag TaskStatus message with light-weight
+  // meta-data.
+  optional Labels labels = 12;
+}
+
+
+/**
+ * Describes possible filters that can be applied to unused resources
+ * (see SchedulerDriver::launchTasks) to influence the allocator.
+ */
+message Filters {
+  // Time to consider unused resources refused. Note that all unused
+  // resources will be considered refused and use the default value
+  // (below) regardless of whether Filters was passed to
+  // SchedulerDriver::launchTasks. You MUST pass Filters with this
+  // field set to change this behavior (i.e., get another offer which
+  // includes unused resources sooner or later than the default).
+  optional double refuse_seconds = 1 [default = 5.0];
+}
+
+
+/**
+* Describes a collection of environment variables. This is used with
+* CommandInfo in order to set environment variables before running a
+* command.
+*/
+message Environment {
+  message Variable {
+    required string name = 1;
+    required string value = 2;
+  }
+
+  repeated Variable variables = 1;
+}
+
+
+/**
+ * A generic (key, value) pair used in various places for parameters.
+ */
+message Parameter {
+  required string key = 1;
+  required string value = 2;
+}
+
+
+/**
+ * Collection of Parameter.
+ */
+message Parameters {
+  repeated Parameter parameter = 1;
+}
+
+
+/**
+ * Credential used in various places for authentication and
+ * authorization.
+ *
+ * NOTE: A 'principal' is different from 'FrameworkInfo.user'. The
+ * former is used for authentication and authorization while the
+ * latter is used to determine the default user under which the
+ * framework's executors/tasks are run.
+ */
+message Credential {
+  required string principal = 1;
+  optional bytes secret = 2;
+}
+
+
+/**
+ * Credentials used for framework authentication, HTTP authentication
+ * (where the common 'username' and 'password' are captured as
+ * 'principal' and 'secret' respectively), etc.
+ */
+message Credentials {
+  repeated Credential credentials = 1;
+}
+
+
+/**
+ * ACLs used for authorization.
+ */
+message ACL {
+
+  // Entity is used to describe a subject(s) or an object(s) of an ACL.
+  // NOTE:
+  // To allow everyone access to an Entity set its type to 'ANY'.
+  // To deny access to an Entity set its type to 'NONE'.
+  message Entity {
+    enum Type {
+      SOME = 0;
+      ANY = 1;
+      NONE = 2;
+    }
+    optional Type type = 1 [default = SOME];
+    repeated string values = 2; // Ignored for ANY/NONE.
+  }
+
+  // ACLs.
+  message RegisterFramework {
+    // Subjects.
+    required Entity principals = 1; // Framework principals.
+
+    // Objects.
+    required Entity roles = 2; // Roles for resource offers.
+  }
+
+  message RunTask {
+    // Subjects.
+    required Entity principals = 1; // Framework principals.
+
+    // Objects.
+    required Entity users = 2; // Users to run the tasks/executors as.
+  }
+
+  // Which principals are authorized to shutdown frameworks of other
+  // principals.
+  message ShutdownFramework {
+    // Subjects.
+    required Entity principals = 1;
+
+    // Objects.
+    required Entity framework_principals = 2;
+  }
+}
+
+
+/**
+ * Collection of ACL.
+ *
+ * Each authorization request is evaluated against the ACLs in the order
+ * they are defined.
+ *
+ * For simplicity, the ACLs for a given action are not aggregated even
+ * when they have the same subjects or objects. The first ACL that
+ * matches the request determines whether that request should be
+ * permitted or not. An ACL matches iff both the subjects
+ * (e.g., clients, principals) and the objects (e.g., urls, users,
+ * roles) of the ACL match the request.
+ *
+ * If none of the ACLs match the request, the 'permissive' field
+ * determines whether the request should be permitted or not.
+ *
+ * TODO(vinod): Do aggregation of ACLs when possible.
+ *
+ */
+message ACLs {
+  optional bool permissive = 1 [default = true];
+  repeated ACL.RegisterFramework register_frameworks = 2;
+  repeated ACL.RunTask run_tasks = 3;
+  repeated ACL.ShutdownFramework shutdown_frameworks = 4;
+}
+
+
+/**
+ * Rate (queries per second, QPS) limit for messages from a framework to 
master.
+ * Strictly speaking they are the combined rate from all frameworks of the same
+ * principal.
+ */
+message RateLimit {
+  // Leaving QPS unset gives it unlimited rate (i.e., not throttled),
+  // which also implies unlimited capacity.
+  optional double qps = 1;
+
+  // Principal of framework(s) to be throttled. Should match
+  // FrameworkInfo.princpal and Credential.principal (if using authentication).
+  required string principal = 2;
+
+  // Max number of outstanding messages from frameworks of this principal
+  // allowed by master before the next message is dropped and an error is sent
+  // back to the sender. Messages received before the capacity is reached are
+  // still going to be processed after the error is sent.
+  // If unspecified, this principal is assigned unlimited capacity.
+  // NOTE: This value is ignored if 'qps' is not set.
+  optional uint64 capacity = 3;
+}
+
+
+/**
+ * Collection of RateLimit.
+ * Frameworks without rate limits defined here are not throttled unless
+ * 'aggregate_default_qps' is specified.
+ */
+message RateLimits {
+  // Items should have unique principals.
+  repeated RateLimit limits = 1;
+
+  // All the frameworks not specified in 'limits' get this default rate.
+  // This rate is an aggregate rate for all of them, i.e., their combined
+  // traffic is throttled together at this rate.
+  optional double aggregate_default_qps = 2;
+
+  // All the frameworks not specified in 'limits' get this default capacity.
+  // This is an aggregate value similar to 'aggregate_default_qps'.
+  optional uint64 aggregate_default_capacity = 3;
+}
+
+
+/**
+ * Describe an image used by tasks or executors. Note that it's only
+ * for tasks or executors launched by MesosContainerizer currently.
+ */
+message Image {
+  enum Type {
+    APPC = 1;
+  }
+
+  // Protobuf for specifying an Appc container image. See:
+  // https://github.com/appc/spec/blob/master/spec/aci.md
+  message AppC {
+    // The name of the image.
+    required string name = 1;
+
+    // An image ID is a string of the format "hash-value", where
+    // "hash" is the hash algorithm used and "value" is the hex
+    // encoded string of the digest. Currently the only permitted
+    // hash algorithm is sha512.
+    required string id = 2;
+
+    // Optional labels. Suggested labels: "version", "os", and "arch".
+    optional Labels labels = 3;
+  }
+
+  required Type type = 1;
+
+  // Only one of the following image messages should be set to match
+  // the type.
+  optional AppC appc = 2;
+}
+
+
+/**
+ * Describes a volume mapping either from host to container or vice
+ * versa. Both paths can either refer to a directory or a file.
+ */
+message Volume {
+  enum Mode {
+    RW = 1; // read-write.
+    RO = 2; // read-only.
+  }
+
+  required Mode mode = 3;
+
+  // Absolute path pointing to a directory or file in the container.
+  required string container_path = 1;
+
+  // The following specifies the source of this volume. At most one of
+  // the following should be set.
+
+  // Absolute path pointing to a directory or file on the host or a
+  // path relative to the container work directory.
+  optional string host_path = 2;
+
+  // The source of the volume is an Image which describes a root
+  // filesystem which will be provisioned by Mesos.
+  optional Image image = 4;
+}
+
+
+/**
+ * Describes a container configuration and allows extensible
+ * configurations for different container implementations.
+ */
+message ContainerInfo {
+  // All container implementation types.
+  enum Type {
+    DOCKER = 1;
+    MESOS = 2;
+  }
+
+  message DockerInfo {
+    // The docker image that is going to be passed to the registry.
+    required string image = 1;
+
+    // Network options.
+    enum Network {
+      HOST = 1;
+      BRIDGE = 2;
+      NONE = 3;
+    }
+
+    optional Network network = 2 [default = HOST];
+
+    message PortMapping {
+      required uint32 host_port = 1;
+      required uint32 container_port = 2;
+      // Protocol to expose as (ie: tcp, udp).
+      optional string protocol = 3;
+    }
+
+    repeated PortMapping port_mappings = 3;
+
+    optional bool privileged = 4 [default = false];
+
+    // Allowing arbitrary parameters to be passed to docker CLI.
+    // Note that anything passed to this field is not guaranteed
+    // to be supported moving forward, as we might move away from
+    // the docker CLI.
+    repeated Parameter parameters = 5;
+
+    // With this flag set to true, the docker containerizer will
+    // pull the docker image from the registry even if the image
+    // is already downloaded on the agent.
+    optional bool force_pull_image = 6;
+  }
+
+  message MesosInfo {
+    optional Image image = 1;
+  }
+
+  required Type type = 1;
+  repeated Volume volumes = 2;
+  optional string hostname = 4;
+
+  // Only one of the following *Info messages should be set to match
+  // the type.
+  optional DockerInfo docker = 3;
+  optional MesosInfo mesos = 5;
+}
+
+
+/**
+ * Collection of labels.
+ */
+message Labels {
+    repeated Label labels = 1;
+}
+
+
+/**
+ * Key, value pair used to store free form user-data.
+ */
+message Label {
+  required string key = 1;
+  optional string value = 2;
+}
+
+
+/**
+ * Named port used for service discovery.
+ */
+message Port {
+  required uint32 number = 1;
+  optional string name = 2;
+  optional string protocol = 3;
+}
+
+
+/**
+ * Collection of ports.
+ */
+message Ports {
+  repeated Port ports = 1;
+}
+
+
+/**
+* Service discovery information.
+* The visibility field restricts discovery within a framework
+* (FRAMEWORK), within a Mesos cluster (CLUSTER), or  places no
+* restrictions (EXTERNAL).
+* The environment, location, and version fields provide first class
+* support for common attributes used to differentiate between
+* similar services. The environment may receive values such as
+* PROD/QA/DEV, the location field may receive values like
+* EAST-US/WEST-US/EUROPE/AMEA, and the version field may receive
+* values like v2.0/v0.9. The exact use of these fields is up to each
+* service discovery system.
+*/
+message DiscoveryInfo {
+  enum Visibility {
+    FRAMEWORK = 0;
+    CLUSTER = 1;
+    EXTERNAL = 2;
+  }
+
+  required Visibility visibility = 1;
+  optional string name = 2;
+  optional string environment = 3;
+  optional string location = 4;
+  optional string version = 5;
+  optional Ports ports = 6;
+  optional Labels labels = 7;
+}

http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/v1/resources.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/resources.hpp b/include/mesos/v1/resources.hpp
new file mode 100644
index 0000000..bb9bede
--- /dev/null
+++ b/include/mesos/v1/resources.hpp
@@ -0,0 +1,390 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MESOS_V1_RESOURCES_HPP__
+#define __MESOS_V1_RESOURCES_HPP__
+
+#include <map>
+#include <iostream>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <mesos/v1/mesos.hpp>
+#include <mesos/v1/values.hpp>
+
+#include <stout/bytes.hpp>
+#include <stout/check.hpp>
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/hashmap.hpp>
+#include <stout/lambda.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+
+// Resources come in three types: scalar, ranges, and sets. These are
+// represented using protocol buffers. To make manipulation of
+// resources easier within the Mesos core and for scheduler writers,
+// we provide generic overloaded operators (see below) as well as a
+// general Resources class that encapsulates a collection of protocol
+// buffer Resource objects. The Resources class also provides a few
+// static routines to allow parsing resources (e.g., from the command
+// line), as well as determining whether or not a Resource object is
+// valid. Note that many of these operations have not been optimized
+// but instead just written for correct semantics.
+
+namespace mesos {
+namespace v1 {
+
+// NOTE: Resource objects stored in the class are always valid and
+// kept combined if possible. It is the caller's responsibility to
+// validate any Resource object or repeated Resource protobufs before
+// constructing a Resources object. Otherwise, invalid Resource
+// objects will be silently stripped. Invalid Resource objects will
+// also be silently ignored when used in arithmetic operations (e.g.,
+// +=, -=, etc.).
+class Resources
+{
+public:
+  // Parses the text and returns a Resource object with the given name
+  // and role. For example, "Resource r = parse("mem", "1024", "*");".
+  static Try<Resource> parse(
+      const std::string& name,
+      const std::string& value,
+      const std::string& role);
+
+  // Parses Resources from text in the form "name:value(role);
+  // name:value;...". Any name/value pair that doesn't specify a role
+  // is assigned to defaultRole.
+  static Try<Resources> parse(
+      const std::string& text,
+      const std::string& defaultRole = "*");
+
+  // Validates the given Resource object. Returns Error if it is not
+  // valid. A Resource object is valid if it has a name, a valid type,
+  // i.e. scalar, range, or set, has the appropriate value set, and
+  // a valid (role, reservation) pair for dynamic reservation.
+  static Option<Error> validate(const Resource& resource);
+
+  // Validates the given protobufs.
+  // TODO(jieyu): Right now, it's the same as checking each individual
+  // Resource object in the protobufs. In the future, we could add
+  // more checks that are not possible if checking each Resource
+  // object individually. For example, we could check multiple usage
+  // of an item in a set or a ranges, etc.
+  static Option<Error> validate(
+      const google::protobuf::RepeatedPtrField<Resource>& resources);
+
+  // NOTE: The following predicate functions assume that the given
+  // resource is validated.
+  //
+  // Valid states of (role, reservation) pair in the Resource object.
+  //   Unreserved         : ("*", None)
+  //   Static reservation : (R, None)
+  //   Dynamic reservation: (R, { principal: <framework_principal> })
+  //
+  // NOTE: ("*", { principal: <framework_principal> }) is invalid.
+
+  // Tests if the given Resource object is empty.
+  static bool isEmpty(const Resource& resource);
+
+  // Tests if the given Resource object is a persistent volume.
+  static bool isPersistentVolume(const Resource& resource);
+
+  // Tests if the given Resource object is reserved. If the role is
+  // specified, tests that it's reserved for the given role.
+  static bool isReserved(
+      const Resource& resource,
+      const Option<std::string>& role = None());
+
+  // Tests if the given Resource object is unreserved.
+  static bool isUnreserved(const Resource& resource);
+
+  // Tests if the given Resource object is dynamically reserved.
+  static bool isDynamicallyReserved(const Resource& resource);
+
+  // Tests if the given Resource object is revocable.
+  static bool isRevocable(const Resource& resource);
+
+  // Returns the summed up Resources given a hashmap<Key, Resources>.
+  //
+  // NOTE: While scalar resources such as "cpus" sum correctly,
+  // non-scalar resources such as "ports" do not.
+  //   e.g. "cpus:2" + "cpus:1" = "cpus:3"
+  //        "ports:[0-100]" + "ports:[0-100]" = "ports:[0-100]"
+  //
+  // TODO(mpark): Deprecate this function once we introduce the
+  // concept of "cluster-wide" resources which provides correct
+  // semantics for summation over all types of resources. (e.g.
+  // non-scalar)
+  template <typename Key>
+  static Resources sum(const hashmap<Key, Resources>& _resources)
+  {
+    Resources result;
+
+    foreachvalue (const Resources& resources, _resources) {
+      result += resources;
+    }
+
+    return result;
+  }
+
+  Resources() {}
+
+  // TODO(jieyu): Consider using C++11 initializer list.
+  /*implicit*/ Resources(const Resource& resource);
+
+  /*implicit*/
+  Resources(const std::vector<Resource>& _resources);
+
+  /*implicit*/
+  Resources(const google::protobuf::RepeatedPtrField<Resource>& _resources);
+
+  Resources(const Resources& that) : resources(that.resources) {}
+
+  Resources& operator = (const Resources& that)
+  {
+    if (this != &that) {
+      resources = that.resources;
+    }
+    return *this;
+  }
+
+  bool empty() const { return resources.size() == 0; }
+
+  // Checks if this Resources is a superset of the given Resources.
+  bool contains(const Resources& that) const;
+
+  // Checks if this Resources contains the given Resource.
+  bool contains(const Resource& that) const;
+
+  // Filter resources based on the given predicate.
+  Resources filter(
+      const lambda::function<bool(const Resource&)>& predicate) const;
+
+  // Returns the reserved resources, by role.
+  hashmap<std::string, Resources> reserved() const;
+
+  // Returns the reserved resources for the role. Note that the "*"
+  // role represents unreserved resources, and will be ignored.
+  Resources reserved(const std::string& role) const;
+
+  // Returns the unreserved resources.
+  Resources unreserved() const;
+
+  // Returns the persistent volumes.
+  Resources persistentVolumes() const;
+
+  // Returns the revocable resources.
+  Resources revocable() const;
+
+  // Returns a Resources object with the same amount of each resource
+  // type as these Resources, but with all Resource objects marked as
+  // the specified (role, reservation) pair. This is used to cross
+  // reservation boundaries without affecting the actual resources.
+  // If the optional ReservationInfo is given, the resource's
+  // 'reservation' field is set. Otherwise, the resource's
+  // 'reservation' field is cleared.
+  Resources flatten(
+      const std::string& role = "*",
+      const Option<Resource::ReservationInfo>& reservation = None()) const;
+
+  // Finds a Resources object with the same amount of each resource
+  // type as "targets" from these Resources. The roles specified in
+  // "targets" set the preference order. For each resource type,
+  // resources are first taken from the specified role, then from '*',
+  // then from any other role.
+  // TODO(jieyu): 'find' contains some allocation logic for scalars and
+  // fixed set / range elements. However, this is not sufficient for
+  // schedulers that want, say, any N available ports. We should
+  // consider moving this to an internal "allocation" library for our
+  // example frameworks to leverage.
+  Option<Resources> find(const Resources& targets) const;
+
+  // Certain offer operations (e.g., RESERVE, UNRESERVE, CREATE or
+  // DESTROY) alter the offered resources. The following methods
+  // provide a convenient way to get the transformed resources by
+  // applying the given offer operation(s). Returns an Error if the
+  // offer operation(s) cannot be applied.
+  Try<Resources> apply(const Offer::Operation& operation) const;
+
+  template <typename Iterable>
+  Try<Resources> apply(const Iterable& operations) const
+  {
+    Resources result = *this;
+
+    foreach (const Offer::Operation& operation, operations) {
+      Try<Resources> transformed = result.apply(operation);
+      if (transformed.isError()) {
+        return Error(transformed.error());
+      }
+
+      result = transformed.get();
+    }
+
+    return result;
+  }
+
+  // Helpers to get resource values. We consider all roles here.
+  template <typename T>
+  Option<T> get(const std::string& name) const;
+
+  // Get resources of the given name.
+  Resources get(const std::string& name) const;
+
+  // Get all the resources that are scalars.
+  Resources scalars() const;
+
+  // Get the set of unique resource names.
+  std::set<std::string> names() const;
+
+  // Get the types of resources associated with each resource name.
+  // NOTE: Resources of the same name must have the same type, as
+  // enforced by Resources::parse().
+  std::map<std::string, Value_Type> types() const;
+
+  // Helpers to get known resource types.
+  // TODO(vinod): Fix this when we make these types as first class
+  // protobufs.
+  Option<double> cpus() const;
+  Option<Bytes> mem() const;
+  Option<Bytes> disk() const;
+
+  // TODO(vinod): Provide a Ranges abstraction.
+  Option<Value::Ranges> ports() const;
+
+  // TODO(jieyu): Consider returning an EphemeralPorts abstraction
+  // which holds the ephemeral ports allocation logic.
+  Option<Value::Ranges> ephemeral_ports() const;
+
+  typedef google::protobuf::RepeatedPtrField<Resource>::iterator
+  iterator;
+
+  typedef google::protobuf::RepeatedPtrField<Resource>::const_iterator
+  const_iterator;
+
+  iterator begin() { return resources.begin(); }
+  iterator end() { return resources.end(); }
+
+  const_iterator begin() const { return resources.begin(); }
+  const_iterator end() const { return resources.end(); }
+
+  // Using this operator makes it easy to copy a resources object into
+  // a protocol buffer field.
+  operator const google::protobuf::RepeatedPtrField<Resource>& () const;
+
+  bool operator == (const Resources& that) const;
+  bool operator != (const Resources& that) const;
+
+  // NOTE: If any error occurs (e.g., input Resource is not valid or
+  // the first operand is not a superset of the second oprand while
+  // doing subtraction), the semantics is as though the second operand
+  // was actually just an empty resource (as though you didn't do the
+  // operation at all).
+  Resources operator + (const Resource& that) const;
+  Resources operator + (const Resources& that) const;
+  Resources& operator += (const Resource& that);
+  Resources& operator += (const Resources& that);
+
+  Resources operator - (const Resource& that) const;
+  Resources operator - (const Resources& that) const;
+  Resources& operator -= (const Resource& that);
+  Resources& operator -= (const Resources& that);
+
+private:
+  // Similar to 'contains(const Resource&)' but skips the validity
+  // check. This can be used to avoid the performance overhead of
+  // calling 'contains(const Resource&)' when the resource can be
+  // assumed valid (e.g. it's inside a Resources).
+  //
+  // TODO(jieyu): Measure performance overhead of validity check to
+  // ensure this is warranted.
+  bool _contains(const Resource& that) const;
+
+  // Similar to the public 'find', but only for a single Resource
+  // object. The target resource may span multiple roles, so this
+  // returns Resources.
+  Option<Resources> find(const Resource& target) const;
+
+  google::protobuf::RepeatedPtrField<Resource> resources;
+};
+
+
+std::ostream& operator << (std::ostream& stream, const Resource& resource);
+std::ostream& operator << (std::ostream& stream, const Resources& resources);
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const google::protobuf::RepeatedPtrField<Resource>& resources)
+{
+  return stream << Resources(resources);
+}
+
+
+inline Resources operator + (
+    const google::protobuf::RepeatedPtrField<Resource>& left,
+    const Resources& right)
+{
+  return Resources(left) + right;
+}
+
+
+inline Resources operator - (
+    const google::protobuf::RepeatedPtrField<Resource>& left,
+    const Resources& right)
+{
+  return Resources(left) - right;
+}
+
+
+inline bool operator == (
+    const google::protobuf::RepeatedPtrField<Resource>& left,
+    const Resources& right)
+{
+  return Resources(left) == right;
+}
+
+
+template <typename Key>
+hashmap<Key, Resources>& operator += (
+    hashmap<Key, Resources>& left,
+    const hashmap<Key, Resources>& right)
+{
+  foreachpair (const Key& key, const Resources& resources, right) {
+    left[key] += resources;
+  }
+  return left;
+}
+
+
+template <typename Key>
+hashmap<Key, Resources> operator + (
+    const hashmap<Key, Resources>& left,
+    const hashmap<Key, Resources>& right)
+{
+  hashmap<Key, Resources> result = left;
+  result += right;
+  return result;
+}
+
+} // namespace v1 {
+} // namespace mesos {
+
+#endif // __MESOS_V1_RESOURCES_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/v1/scheduler.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/scheduler.hpp b/include/mesos/v1/scheduler.hpp
new file mode 100644
index 0000000..2741e7f
--- /dev/null
+++ b/include/mesos/v1/scheduler.hpp
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MESOS_V1_SCHEDULER_HPP__
+#define __MESOS_V1_SCHEDULER_HPP__
+
+#include <functional>
+#include <queue>
+#include <string>
+
+#include <mesos/v1/mesos.hpp>
+
+#include <mesos/v1/scheduler/scheduler.hpp>
+
+namespace mesos {
+namespace v1 {
+namespace scheduler {
+
+class MesosProcess; // Forward declaration.
+
+// Interface to Mesos for a scheduler. Abstracts master detection
+// (connection and disconnection) and authentication if some
+// credentials are provided.
+//
+// Expects three callbacks, 'connected', 'disconnected', and
+// 'received' which will get invoked _serially_ when it's determined
+// that we've connected, disconnected, or received events from the
+// master. Note that we drop events while disconnected but it's
+// possible to receive a batch of events across a
+// disconnected/connected transition before getting the disconnected
+// and then connected callback.
+//
+// TODO(benh): Don't include events in 'received' that occured after a
+// disconnected/connected transition.
+class Mesos
+{
+public:
+  Mesos(const std::string& master,
+        const std::function<void(void)>& connected,
+        const std::function<void(void)>& disconnected,
+        const std::function<void(const std::queue<Event>&)>& received);
+
+  // Same as the above constructor but takes 'credential' as argument.
+  // The credential will be used for authenticating with the master.
+  Mesos(const std::string& master,
+        const Credential& credential,
+        const std::function<void(void)>& connected,
+        const std::function<void(void)>& disconnected,
+        const std::function<void(const std::queue<Event>&)>& received);
+
+  virtual ~Mesos();
+
+  // Attempts to send a call to the master.
+  //
+  // Some local validation of calls is performed which may generate
+  // events without ever being sent to the master. This includes when
+  // calls are sent but no master is currently detected (i.e., we're
+  // disconnected).
+  virtual void send(const Call& call);
+
+private:
+  MesosProcess* process;
+};
+
+} // namespace scheduler {
+} // namespace v1 {
+} // namespace mesos {
+
+#endif // __MESOS_V1_SCHEDULER_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/b923cb52/include/mesos/v1/scheduler/scheduler.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/scheduler/scheduler.hpp 
b/include/mesos/v1/scheduler/scheduler.hpp
new file mode 100644
index 0000000..692a799
--- /dev/null
+++ b/include/mesos/v1/scheduler/scheduler.hpp
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MESOS_V1_SCHEDULER_PROTO_HPP__
+#define __MESOS_V1_SCHEDULER_PROTO_HPP__
+
+#include <ostream>
+
+// ONLY USEFUL AFTER RUNNING PROTOC.
+#include <mesos/v1/scheduler/scheduler.pb.h>
+
+namespace mesos {
+namespace v1 {
+namespace scheduler {
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const Call::Type& type)
+{
+  return stream << Call::Type_Name(type);
+}
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const Event::Type& type)
+{
+  return stream << Event::Type_Name(type);
+}
+
+} // namespace scheduler {
+} // namespace v1 {
+} // namespace mesos {
+
+#endif // __MESOS_V1_SCHEDULER_PROTO_HPP__

Reply via email to