You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2015/05/16 02:14:45 UTC
[2/2] mesos git commit: Added RevocableInfo message to Resource
protobuf.
Added RevocableInfo message to Resource protobuf.
Review: https://reviews.apache.org/r/33865
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c4366d8b
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c4366d8b
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c4366d8b
Branch: refs/heads/master
Commit: c4366d8b997223cb212041daa6678bc1e98271ff
Parents: bbd0582
Author: Vinod Kone <vi...@gmail.com>
Authored: Tue May 5 09:54:57 2015 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri May 15 17:13:33 2015 -0700
----------------------------------------------------------------------
include/mesos/mesos.proto | 10 +++
include/mesos/resources.hpp | 3 +
src/common/resources.cpp | 24 +++++++-
src/master/validation.cpp | 30 +++++++++
src/tests/master_validation_tests.cpp | 20 ++++++
src/tests/resources_tests.cpp | 98 ++++++++++++++++++++++++++++++
6 files changed, 183 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/c4366d8b/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 15f55a3..9cc5782 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -449,6 +449,16 @@ message Resource {
}
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;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/c4366d8b/include/mesos/resources.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp
index f44cb62..1e98c13 100644
--- a/include/mesos/resources.hpp
+++ b/include/mesos/resources.hpp
@@ -117,6 +117,9 @@ public:
// 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,
http://git-wip-us.apache.org/repos/asf/mesos/blob/c4366d8b/src/common/resources.cpp
----------------------------------------------------------------------
diff --git a/src/common/resources.cpp b/src/common/resources.cpp
index 843a06d..92b9e7f 100644
--- a/src/common/resources.cpp
+++ b/src/common/resources.cpp
@@ -112,6 +112,11 @@ bool operator == (const Resource& left, const Resource& right)
return false;
}
+ // Check RevocableInfo.
+ if (left.has_revocable() != right.has_revocable()) {
+ return false;
+ }
+
if (left.type() == Value::SCALAR) {
return left.scalar() == right.scalar();
} else if (left.type() == Value::RANGES) {
@@ -167,6 +172,11 @@ static bool addable(const Resource& left, const Resource& right)
return false;
}
+ // Check RevocableInfo.
+ if (left.has_revocable() != right.has_revocable()) {
+ return false;
+ }
+
return true;
}
@@ -211,6 +221,11 @@ static bool subtractable(const Resource& left, const Resource& right)
return false;
}
+ // Check RevocableInfo.
+ if (left.has_revocable() != right.has_revocable()) {
+ return false;
+ }
+
return true;
}
@@ -219,8 +234,8 @@ static bool subtractable(const Resource& left, const Resource& right)
static bool contains(const Resource& left, const Resource& right)
{
// NOTE: This is a necessary condition for 'contains'.
- // 'subtractable' will verify name, role, type, ReservationInfo
- // and DiskInfo compatibility.
+ // 'subtractable' will verify name, role, type, ReservationInfo,
+ // DiskInfo and RevocableInfo compatibility.
if (!subtractable(left, right)) {
return false;
}
@@ -508,6 +523,11 @@ bool Resources::isDynamicallyReserved(const Resource& resource)
}
+bool Resources::isRevocable(const Resource& resource)
+{
+ return resource.has_revocable();
+}
+
/////////////////////////////////////////////////
// Public member functions.
/////////////////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/mesos/blob/c4366d8b/src/master/validation.cpp
----------------------------------------------------------------------
diff --git a/src/master/validation.cpp b/src/master/validation.cpp
index b53608f..20a6ac8 100644
--- a/src/master/validation.cpp
+++ b/src/master/validation.cpp
@@ -53,6 +53,27 @@ static bool invalid(char c)
namespace resource {
+// Validates the ReservationInfos specified in the given resources (if
+// exist). Returns error if any ReservationInfo is found invalid or
+// unsupported.
+Option<Error> validateDynamicReservationInfo(
+ const RepeatedPtrField<Resource>& resources)
+{
+ foreach (const Resource& resource, resources) {
+ if (!Resources::isDynamicallyReserved(resource)) {
+ continue;
+ }
+
+ if (Resources::isRevocable(resource)) {
+ return Error(
+ "Dynamically reserved resource " + stringify(resource) +
+ " cannot be created from revocable resources");
+ }
+ }
+
+ return None();
+}
+
// Validates the DiskInfos specified in the given resources (if
// exist). Returns error if any DiskInfo is found invalid or
@@ -65,6 +86,10 @@ Option<Error> validateDiskInfo(const RepeatedPtrField<Resource>& resources)
}
if (resource.disk().has_persistence()) {
+ if (Resources::isRevocable(resource)) {
+ return Error(
+ "Persistent volumes cannot be created from revocable resources");
+ }
if (Resources::isUnreserved(resource)) {
return Error(
"Persistent volumes cannot be created from unreserved resources");
@@ -149,6 +174,11 @@ Option<Error> validate(const RepeatedPtrField<Resource>& resources)
return Error("Invalid DiskInfo: " + error.get().message);
}
+ error = validateDynamicReservationInfo(resources);
+ if (error.isSome()) {
+ return Error("Invalid ReservationInfo: " + error.get().message);
+ }
+
return None();
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/c4366d8b/src/tests/master_validation_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_validation_tests.cpp b/src/tests/master_validation_tests.cpp
index 9a6f4fa..dc9e91e 100644
--- a/src/tests/master_validation_tests.cpp
+++ b/src/tests/master_validation_tests.cpp
@@ -93,6 +93,16 @@ TEST_F(ResourceValidationTest, DynamicReservation)
}
+TEST_F(ResourceValidationTest, RevocableDynamicReservation)
+{
+ Resource resource = Resources::parse("cpus", "8", "role").get();
+ resource.mutable_reservation()->CopyFrom(createReservationInfo("principal"));
+ resource.mutable_revocable();
+
+ EXPECT_SOME(resource::validate(CreateResources(resource)));
+}
+
+
TEST_F(ResourceValidationTest, InvalidRoleReservationPair)
{
Resource resource = Resources::parse("cpus", "8", "*").get();
@@ -166,6 +176,16 @@ TEST_F(ResourceValidationTest, NonPersistentVolume)
}
+TEST_F(ResourceValidationTest, RevocablePersistentVolume)
+{
+ Resource volume = Resources::parse("disk", "128", "role1").get();
+ volume.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1"));
+ volume.mutable_revocable();
+
+ EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
class ReserveOperationValidationTest : public MesosTest {};
http://git-wip-us.apache.org/repos/asf/mesos/blob/c4366d8b/src/tests/resources_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resources_tests.cpp b/src/tests/resources_tests.cpp
index a7ec59e..99b2cfc 100644
--- a/src/tests/resources_tests.cpp
+++ b/src/tests/resources_tests.cpp
@@ -1147,6 +1147,104 @@ TEST(ResourcesOperationTest, CreatePersistentVolume)
EXPECT_ERROR(total.apply(create2));
}
+
+// Helper for creating a revocable resource.
+static Resource createRevocableResource(
+ const string& name,
+ const string& value,
+ const string& role,
+ bool revocable)
+{
+ Resource resource = Resources::parse(name, value, role).get();
+
+ if (revocable) {
+ resource.mutable_revocable();
+ }
+
+ return resource;
+}
+
+
+// This test verfies that revocable and non-revocable resources are
+// not considered equal.
+TEST(RevocableResourceTest, Equals)
+{
+ Resources resources1 = createRevocableResource("cpus", "1", "*", true);
+
+ Resources resources2 = resources1;
+ EXPECT_EQ(resources1, resources2);
+
+ Resources resources3 = createRevocableResource("cpus", "1", "*", false);
+ EXPECT_NE(resources1, resources3);
+}
+
+
+// This test verifies that adding revocable resources to revocable
+// resources will merge them but adding to non-revocable resources
+// will not merge.
+TEST(RevocableResourceTest, Addition)
+{
+ Resources r1 = createRevocableResource("cpus", "1", "*", true);
+ Resources r2 = createRevocableResource("cpus", "1", "*", true);
+ Resources r3 = createRevocableResource("cpus", "2", "*", true);
+
+ // Adding revocable resources will merge them.
+ EXPECT_EQ(r3, r1 + r2);
+
+ Resources r4 = createRevocableResource("cpus", "1", "*", true);
+ Resources r5 = createRevocableResource("cpus", "1", "*", false);
+ Resources r6 = createRevocableResource("cpus", "2", "*", false);
+
+ Resources sum = r4 + r5;
+
+ // Adding revocable and non-revocable resources will not merge them.
+ EXPECT_TRUE(sum.contains(r4));
+ EXPECT_TRUE(sum.contains(r5));
+ EXPECT_FALSE(sum.contains(r3));
+ EXPECT_FALSE(sum.contains(r6));
+}
+
+
+// This test verifies that subtracting revocable resources from
+// revocable resources will merge them but subtracting from
+// non-revocable resources will not merge.
+TEST(RevocableResourceTest, Subtraction)
+{
+ Resources r1 = createRevocableResource("cpus", "1", "*", true);
+ Resources r2 = createRevocableResource("cpus", "1", "*", true);
+
+ // Subtracting revocable resources will merge them.
+ EXPECT_TRUE((r1 - r2).empty());
+
+ Resources r3 = createRevocableResource("cpus", "1", "*", true);
+ Resources r4 = createRevocableResource("cpus", "1", "*", false);
+
+ // Subtracting non-revocable resources from revocable resources is
+ // a no-op.
+ EXPECT_EQ(r3, r3 - r4);
+ EXPECT_TRUE((r3 - r3).empty());
+}
+
+
+// This test verifies that adding revocable resources to revocable or
+// non-revocable resources respects the 'contains' logic.
+TEST(RevocableResourceTest, Contains)
+{
+ Resources r1 = createRevocableResource("cpus", "1", "*", true);
+ Resources r2 = createRevocableResource("cpus", "1", "*", true);
+
+ EXPECT_FALSE(r1.contains(r1 + r2));
+ EXPECT_FALSE(r2.contains(r1 + r2));
+ EXPECT_TRUE((r1 + r2).contains(r1));
+ EXPECT_TRUE((r1 + r2).contains(r2));
+ EXPECT_TRUE((r1 + r2).contains(r1 + r2));
+
+ Resources r3 = createRevocableResource("cpus", "1", "*", false);
+
+ EXPECT_TRUE((r1 + r3).contains(r1));
+ EXPECT_TRUE((r1 + r3).contains(r3));
+}
+
} // namespace tests {
} // namespace internal {
} // namespace mesos {