You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by al...@apache.org on 2018/09/06 14:34:29 UTC

[mesos] branch master updated (52be35f -> 0c5f300)

This is an automated email from the ASF dual-hosted git repository.

alexr pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git.


    from 52be35f  Fixed `LaunchNestedContainerSessionsInParallel` test.
     new dda549b  Restructured /roles code.
     new 0c5f300  Added '/roles' to the set of batched master endpoints.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/master/http.cpp             | 137 ++++------------------------------------
 src/master/master.cpp           |  43 +++++++++++++
 src/master/master.hpp           |  14 ++--
 src/master/readonly_handler.cpp |  85 +++++++++++++++++++++++++
 4 files changed, 149 insertions(+), 130 deletions(-)


[mesos] 01/02: Restructured /roles code.

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit dda549be430921e4e1c4ae670b47f455b215a20c
Author: Benno Evers <be...@mesosphere.com>
AuthorDate: Thu Sep 6 14:07:56 2018 +0200

    Restructured /roles code.
    
    Rework the structure of the role handling in both v0 and
    v1 APIs in preparation for the subsequent commit.
    
    As a nice side bonus on top, this also saves one trip
    through the master queue for every call of this endpoint.
    
    Review: https://reviews.apache.org/r/68567/
---
 src/master/http.cpp   | 83 +++++++++++++++++++++++++--------------------------
 src/master/master.hpp |  5 ++--
 2 files changed, 42 insertions(+), 46 deletions(-)

diff --git a/src/master/http.cpp b/src/master/http.cpp
index 0ac3475..8a37349 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -2631,51 +2631,46 @@ string Master::Http::ROLES_HELP()
 }
 
 
-Future<vector<string>> Master::Http::_roles(
-    const Option<Principal>& principal) const
+vector<string> Master::Http::_filterRoles(
+    const Owned<ObjectApprovers>& approvers) const
 {
-  return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
-    .then(defer(master->self(),
-        [this](const Owned<ObjectApprovers>& approvers)
-          -> vector<string> {
-      JSON::Object object;
+  JSON::Object object;
 
-      // Compute the role names to return results for. When an explicit
-      // role whitelist has been configured, we use that list of names.
-      // When using implicit roles, the right behavior is a bit more
-      // subtle. There are no constraints on possible role names, so we
-      // instead list all the "interesting" roles: all roles with one or
-      // more registered frameworks, and all roles with a non-default
-      // weight or quota.
-      //
-      // NOTE: we use a `std::set` to store the role names to ensure a
-      // deterministic output order.
-      set<string> roleList;
-      if (master->roleWhitelist.isSome()) {
-        const hashset<string>& whitelist = master->roleWhitelist.get();
-        roleList.insert(whitelist.begin(), whitelist.end());
-      } else {
-        hashset<string> roles = master->roles.keys();
-        roleList.insert(roles.begin(), roles.end());
+  // Compute the role names to return results for. When an explicit
+  // role whitelist has been configured, we use that list of names.
+  // When using implicit roles, the right behavior is a bit more
+  // subtle. There are no constraints on possible role names, so we
+  // instead list all the "interesting" roles: all roles with one or
+  // more registered frameworks, and all roles with a non-default
+  // weight or quota.
+  //
+  // NOTE: we use a `std::set` to store the role names to ensure a
+  // deterministic output order.
+  set<string> roleList;
+  if (master->roleWhitelist.isSome()) {
+    const hashset<string>& whitelist = master->roleWhitelist.get();
+    roleList.insert(whitelist.begin(), whitelist.end());
+  } else {
+    hashset<string> roles = master->roles.keys();
+    roleList.insert(roles.begin(), roles.end());
 
-        hashset<string> weights = master->weights.keys();
-        roleList.insert(weights.begin(), weights.end());
+    hashset<string> weights = master->weights.keys();
+    roleList.insert(weights.begin(), weights.end());
 
-        hashset<string> quotas = master->quotas.keys();
-        roleList.insert(quotas.begin(), quotas.end());
-      }
+    hashset<string> quotas = master->quotas.keys();
+    roleList.insert(quotas.begin(), quotas.end());
+  }
 
-      vector<string> filteredRoleList;
-      filteredRoleList.reserve(roleList.size());
+  vector<string> filteredRoleList;
+  filteredRoleList.reserve(roleList.size());
 
-      foreach (const string& role, roleList) {
-        if (approvers->approved<VIEW_ROLE>(role)) {
-          filteredRoleList.push_back(role);
-        }
-      }
+  foreach (const string& role, roleList) {
+    if (approvers->approved<VIEW_ROLE>(role)) {
+      filteredRoleList.push_back(role);
+    }
+  }
 
-      return filteredRoleList;
-    }));
+  return filteredRoleList;
 }
 
 
@@ -2697,11 +2692,12 @@ Future<Response> Master::Http::roles(
     return redirect(request);
   }
 
-  return _roles(principal)
+  return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
     .then(defer(master->self(),
-        [this, request](const vector<string>& filteredRoles)
+        [this, request](const Owned<ObjectApprovers>& approvers)
           -> Response {
       JSON::Object object;
+      const vector<string> filteredRoles = _filterRoles(approvers);
 
       {
         JSON::Array array;
@@ -2791,11 +2787,12 @@ Future<Response> Master::Http::getRoles(
     ContentType contentType) const
 {
   CHECK_EQ(mesos::master::Call::GET_ROLES, call.type());
-
-  return _roles(principal)
+  return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
     .then(defer(master->self(),
-        [this, contentType](const vector<string>& filteredRoles)
+        [this, contentType](const Owned<ObjectApprovers>& approvers)
           -> Response {
+      const vector<string> filteredRoles = _filterRoles(approvers);
+
       mesos::master::Response response;
       response.set_type(mesos::master::Response::GET_ROLES);
 
diff --git a/src/master/master.hpp b/src/master/master.hpp
index eecb66c..5d01de4 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1695,9 +1695,8 @@ private:
         Resources required,
         const Offer::Operation& operation) const;
 
-    process::Future<std::vector<std::string>> _roles(
-        const Option<process::http::authentication::Principal>&
-            principal) const;
+    std::vector<std::string> _filterRoles(
+        const process::Owned<ObjectApprovers>& approvers) const;
 
     // Master API handlers.
 


[mesos] 02/02: Added '/roles' to the set of batched master endpoints.

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 0c5f300aa9cbe6043498d586c1150ba7483b08f1
Author: Benno Evers <be...@mesosphere.com>
AuthorDate: Thu Sep 6 14:08:29 2018 +0200

    Added '/roles' to the set of batched master endpoints.
    
    For improved consistency, the '/roles' endpoint on the
    master is now marked as read-only and uses the batching
    mechanism shared by the other read-only endpoints.
    
    Review: https://reviews.apache.org/r/68568/
---
 src/master/http.cpp             | 126 +++-------------------------------------
 src/master/master.cpp           |  43 ++++++++++++++
 src/master/master.hpp           |  13 ++++-
 src/master/readonly_handler.cpp |  85 +++++++++++++++++++++++++++
 4 files changed, 145 insertions(+), 122 deletions(-)

diff --git a/src/master/http.cpp b/src/master/http.cpp
index 8a37349..deb65af 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -2565,49 +2565,6 @@ Future<Response> Master::Http::stateSummary(
 }
 
 
-// Returns a JSON object modeled after a role.
-JSON::Object model(
-    const string& name,
-    Option<double> weight,
-    Option<Quota> quota,
-    Option<Role*> _role)
-{
-  JSON::Object object;
-  object.values["name"] = name;
-
-  if (weight.isSome()) {
-    object.values["weight"] = weight.get();
-  } else {
-    object.values["weight"] = 1.0; // Default weight.
-  }
-
-  if (quota.isSome()) {
-    object.values["quota"] = model(quota->info);
-  }
-
-  if (_role.isNone()) {
-    object.values["resources"] = model(Resources());
-    object.values["frameworks"] = JSON::Array();
-  } else {
-    Role* role = _role.get();
-
-    object.values["resources"] = model(role->allocatedResources());
-
-    {
-      JSON::Array array;
-
-      foreachkey (const FrameworkID& frameworkId, role->frameworks) {
-        array.values.push_back(frameworkId.value());
-      }
-
-      object.values["frameworks"] = std::move(array);
-    }
-  }
-
-  return object;
-}
-
-
 string Master::Http::ROLES_HELP()
 {
   return HELP(
@@ -2631,49 +2588,6 @@ string Master::Http::ROLES_HELP()
 }
 
 
-vector<string> Master::Http::_filterRoles(
-    const Owned<ObjectApprovers>& approvers) const
-{
-  JSON::Object object;
-
-  // Compute the role names to return results for. When an explicit
-  // role whitelist has been configured, we use that list of names.
-  // When using implicit roles, the right behavior is a bit more
-  // subtle. There are no constraints on possible role names, so we
-  // instead list all the "interesting" roles: all roles with one or
-  // more registered frameworks, and all roles with a non-default
-  // weight or quota.
-  //
-  // NOTE: we use a `std::set` to store the role names to ensure a
-  // deterministic output order.
-  set<string> roleList;
-  if (master->roleWhitelist.isSome()) {
-    const hashset<string>& whitelist = master->roleWhitelist.get();
-    roleList.insert(whitelist.begin(), whitelist.end());
-  } else {
-    hashset<string> roles = master->roles.keys();
-    roleList.insert(roles.begin(), roles.end());
-
-    hashset<string> weights = master->weights.keys();
-    roleList.insert(weights.begin(), weights.end());
-
-    hashset<string> quotas = master->quotas.keys();
-    roleList.insert(quotas.begin(), quotas.end());
-  }
-
-  vector<string> filteredRoleList;
-  filteredRoleList.reserve(roleList.size());
-
-  foreach (const string& role, roleList) {
-    if (approvers->approved<VIEW_ROLE>(role)) {
-      filteredRoleList.push_back(role);
-    }
-  }
-
-  return filteredRoleList;
-}
-
-
 Future<Response> Master::Http::roles(
     const Request& request,
     const Option<Principal>& principal) const
@@ -2694,38 +2608,12 @@ Future<Response> Master::Http::roles(
 
   return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
     .then(defer(master->self(),
-        [this, request](const Owned<ObjectApprovers>& approvers)
-          -> Response {
-      JSON::Object object;
-      const vector<string> filteredRoles = _filterRoles(approvers);
-
-      {
-        JSON::Array array;
-
-        foreach (const string& name, filteredRoles) {
-          Option<double> weight = None();
-          if (master->weights.contains(name)) {
-            weight = master->weights[name];
-          }
-
-          Option<Quota> quota = None();
-          if (master->quotas.contains(name)) {
-            quota = master->quotas.at(name);
-          }
-
-          Option<Role*> role = None();
-          if (master->roles.contains(name)) {
-            role = master->roles.at(name);
-          }
-
-          array.values.push_back(model(name, weight, quota, role));
-        }
-
-        object.values["roles"] = std::move(array);
-      }
-
-      return OK(object, request.url.query.get("jsonp"));
-    }));
+        [this, request](const Owned<ObjectApprovers>& approvers) {
+            return deferBatchedRequest(
+                &Master::ReadOnlyHandler::roles,
+                request,
+                approvers);
+          }));
 }
 
 
@@ -2791,7 +2679,7 @@ Future<Response> Master::Http::getRoles(
     .then(defer(master->self(),
         [this, contentType](const Owned<ObjectApprovers>& approvers)
           -> Response {
-      const vector<string> filteredRoles = _filterRoles(approvers);
+      const vector<string> filteredRoles = master->filterRoles(approvers);
 
       mesos::master::Response response;
       response.set_type(mesos::master::Response::GET_ROLES);
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 3277b57..982bfcc 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -3403,6 +3403,49 @@ void Master::suppress(
 }
 
 
+vector<string> Master::filterRoles(
+    const Owned<ObjectApprovers>& approvers) const
+{
+  JSON::Object object;
+
+  // Compute the role names to return results for. When an explicit
+  // role whitelist has been configured, we use that list of names.
+  // When using implicit roles, the right behavior is a bit more
+  // subtle. There are no constraints on possible role names, so we
+  // instead list all the "interesting" roles: all roles with one or
+  // more registered frameworks, and all roles with a non-default
+  // weight or quota.
+  //
+  // NOTE: we use a `std::set` to store the role names to ensure a
+  // deterministic output order.
+  set<string> roleList;
+  if (roleWhitelist.isSome()) {
+    const hashset<string>& whitelist = roleWhitelist.get();
+    roleList.insert(whitelist.begin(), whitelist.end());
+  } else {
+    hashset<string> roles = this->roles.keys();
+    roleList.insert(roles.begin(), roles.end());
+
+    hashset<string> weights = this->weights.keys();
+    roleList.insert(weights.begin(), weights.end());
+
+    hashset<string> quotas = this->quotas.keys();
+    roleList.insert(quotas.begin(), quotas.end());
+  }
+
+  vector<string> filteredRoleList;
+  filteredRoleList.reserve(roleList.size());
+
+  foreach (const string& role, roleList) {
+    if (approvers->approved<VIEW_ROLE>(role)) {
+      filteredRoleList.push_back(role);
+    }
+  }
+
+  return filteredRoleList;
+}
+
+
 bool Master::isWhitelistedRole(const string& name) const
 {
   if (roleWhitelist.isNone()) {
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 5d01de4..ec2ae01 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1181,6 +1181,9 @@ private:
   process::Future<bool> authorizeLogAccess(
       const Option<process::http::authentication::Principal>& principal);
 
+  std::vector<std::string> filterRoles(
+      const process::Owned<ObjectApprovers>& approvers) const;
+
   /**
    * Returns whether the given role is on the whitelist.
    *
@@ -1401,6 +1404,11 @@ private:
         const process::http::Request& request,
         const process::Owned<ObjectApprovers>& approvers) const;
 
+    // /roles
+    process::http::Response roles(
+        const process::http::Request& request,
+        const process::Owned<ObjectApprovers>& approvers) const;
+
     // /slaves
     process::http::Response slaves(
         const process::http::Request& request,
@@ -1488,6 +1496,8 @@ private:
             principal) const;
 
     // /master/roles
+    //
+    // NOTE: Requests to this endpoint are batched.
     process::Future<process::http::Response> roles(
         const process::http::Request& request,
         const Option<process::http::authentication::Principal>&
@@ -1695,9 +1705,6 @@ private:
         Resources required,
         const Offer::Operation& operation) const;
 
-    std::vector<std::string> _filterRoles(
-        const process::Owned<ObjectApprovers>& approvers) const;
-
     // Master API handlers.
 
     process::Future<process::http::Response> getAgents(
diff --git a/src/master/readonly_handler.cpp b/src/master/readonly_handler.cpp
index 47d7de5..8895374 100644
--- a/src/master/readonly_handler.cpp
+++ b/src/master/readonly_handler.cpp
@@ -53,6 +53,9 @@ namespace mesos {
 namespace internal {
 namespace master {
 
+// Pull in model overrides from common.
+using mesos::internal::model;
+
 // The summary representation of `T` to support the `/state-summary` endpoint.
 // e.g., `Summary<Slave>`.
 template <typename T>
@@ -74,6 +77,9 @@ struct Full : Representation<T>
 // Filtered representation of Full<Framework>.
 // Executors and Tasks are filtered based on whether the
 // user is authorized to view them.
+//
+// TODO(bevers): Consider moving writers and other json-related
+// code into a separate file.
 struct FullFrameworkWriter {
   FullFrameworkWriter(
       const process::Owned<ObjectApprovers>& approvers,
@@ -688,6 +694,85 @@ process::http::Response Master::ReadOnlyHandler::frameworks(
 }
 
 
+// Returns a JSON object modeled after a role.
+JSON::Object model(
+    const string& name,
+    Option<double> weight,
+    Option<Quota> quota,
+    Option<Role*> _role)
+{
+  JSON::Object object;
+  object.values["name"] = name;
+
+  if (weight.isSome()) {
+    object.values["weight"] = weight.get();
+  } else {
+    object.values["weight"] = 1.0; // Default weight.
+  }
+
+  if (quota.isSome()) {
+    object.values["quota"] = model(quota->info);
+  }
+
+  if (_role.isNone()) {
+    object.values["resources"] = model(Resources());
+    object.values["frameworks"] = JSON::Array();
+  } else {
+    Role* role = _role.get();
+
+    object.values["resources"] = model(role->allocatedResources());
+
+    {
+      JSON::Array array;
+
+      foreachkey (const FrameworkID& frameworkId, role->frameworks) {
+        array.values.push_back(frameworkId.value());
+      }
+
+      object.values["frameworks"] = std::move(array);
+    }
+  }
+
+  return object;
+}
+
+
+process::http::Response Master::ReadOnlyHandler::roles(
+    const process::http::Request& request,
+    const process::Owned<ObjectApprovers>& approvers) const
+{
+  JSON::Object object;
+  const vector<string> filteredRoles = master->filterRoles(approvers);
+
+  {
+    JSON::Array array;
+
+    foreach (const string& name, filteredRoles) {
+      Option<double> weight = None();
+      if (master->weights.contains(name)) {
+        weight = master->weights.at(name);
+      }
+
+      Option<Quota> quota = None();
+      if (master->quotas.contains(name)) {
+        quota = master->quotas.at(name);
+      }
+
+      Option<Role*> role = None();
+      if (master->roles.contains(name)) {
+        role = master->roles.at(name);
+      }
+
+      array.values.push_back(model(name, weight, quota, role));
+    }
+
+    object.values["roles"] = std::move(array);
+  }
+
+  return OK(object, request.url.query.get("jsonp"));
+}
+
+
 process::http::Response Master::ReadOnlyHandler::slaves(
     const process::http::Request& request,
     const process::Owned<ObjectApprovers>& approvers) const