You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by gi...@apache.org on 2017/12/31 12:17:56 UTC
[1/3] mesos git commit: Added authorization for prune images API call.
Repository: mesos
Updated Branches:
refs/heads/master 0da7b6cc3 -> 5e88bc076
Added authorization for prune images API call.
Review: https://reviews.apache.org/r/64864/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/250a9a53
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/250a9a53
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/250a9a53
Branch: refs/heads/master
Commit: 250a9a53ccd937733ef0a507b555aecbb44af356
Parents: 0da7b6c
Author: Zhitao Li <zh...@gmail.com>
Authored: Sun Dec 31 18:27:44 2017 +0800
Committer: Gilbert Song <so...@gmail.com>
Committed: Sun Dec 31 19:39:57 2017 +0800
----------------------------------------------------------------------
include/mesos/authorizer/acls.proto | 14 ++++++
include/mesos/authorizer/authorizer.proto | 4 ++
src/authorizer/local/authorizer.cpp | 20 +++++++++
src/slave/http.cpp | 60 +++++++++++++++++---------
4 files changed, 78 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/250a9a53/include/mesos/authorizer/acls.proto
----------------------------------------------------------------------
diff --git a/include/mesos/authorizer/acls.proto b/include/mesos/authorizer/acls.proto
index 5c7ed34..152410f 100644
--- a/include/mesos/authorizer/acls.proto
+++ b/include/mesos/authorizer/acls.proto
@@ -495,6 +495,19 @@ message ACL {
// SOME resource provider types and names.
required Entity resource_providers = 2;
}
+
+ // Which principals are authorized to prune unused container images.
+ message PruneImages {
+ // Subjects: HTTP Username.
+ required Entity principals = 1;
+
+ // Objects: Given implicitly.
+ // Use Entity type ANY or NONE to allow or deny access.
+ //
+ // TODO(zhitao): Consider allowing granular permission to act upon
+ // SOME image reference.
+ required Entity images = 2;
+ }
}
@@ -572,4 +585,5 @@ message ACLs {
repeated ACL.RemoveStandaloneContainer remove_standalone_container = 44;
repeated ACL.ViewStandaloneContainer view_standalone_containers = 46;
repeated ACL.ModifyResourceProviderConfig modify_resource_provider_configs = 45;
+ repeated ACL.PruneImages prune_images = 47;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/250a9a53/include/mesos/authorizer/authorizer.proto
----------------------------------------------------------------------
diff --git a/include/mesos/authorizer/authorizer.proto b/include/mesos/authorizer/authorizer.proto
index 90ffdfa..1508c01 100644
--- a/include/mesos/authorizer/authorizer.proto
+++ b/include/mesos/authorizer/authorizer.proto
@@ -250,6 +250,10 @@ enum Action {
// allowed to add, update and remove resource provider config files or is
// unauthorized.
MODIFY_RESOURCE_PROVIDER_CONFIG = 39;
+
+ // This action will not fill in any object fields. A principal is either
+ // allowed to prune unused container images or is unauthorized.
+ PRUNE_IMAGES = 41;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/250a9a53/src/authorizer/local/authorizer.cpp
----------------------------------------------------------------------
diff --git a/src/authorizer/local/authorizer.cpp b/src/authorizer/local/authorizer.cpp
index 0722ac9..b3ec601 100644
--- a/src/authorizer/local/authorizer.cpp
+++ b/src/authorizer/local/authorizer.cpp
@@ -412,6 +412,7 @@ public:
case authorization::STOP_MAINTENANCE:
case authorization::UPDATE_MAINTENANCE_SCHEDULE:
case authorization::MODIFY_RESOURCE_PROVIDER_CONFIG:
+ case authorization::PRUNE_IMAGES:
aclObject.set_type(ACL::Entity::ANY);
break;
@@ -700,6 +701,7 @@ public:
case authorization::LAUNCH_NESTED_CONTAINER_SESSION:
case authorization::LAUNCH_STANDALONE_CONTAINER:
case authorization::MARK_AGENT_GONE:
+ case authorization::PRUNE_IMAGES:
case authorization::REGISTER_AGENT:
case authorization::REMOVE_NESTED_CONTAINER:
case authorization::REMOVE_STANDALONE_CONTAINER:
@@ -917,6 +919,7 @@ public:
case authorization::LAUNCH_NESTED_CONTAINER_SESSION:
case authorization::LAUNCH_STANDALONE_CONTAINER:
case authorization::MARK_AGENT_GONE:
+ case authorization::PRUNE_IMAGES:
case authorization::REGISTER_AGENT:
case authorization::REMOVE_NESTED_CONTAINER:
case authorization::REMOVE_STANDALONE_CONTAINER:
@@ -1130,6 +1133,7 @@ public:
case authorization::KILL_STANDALONE_CONTAINER:
case authorization::LAUNCH_STANDALONE_CONTAINER:
case authorization::MARK_AGENT_GONE:
+ case authorization::PRUNE_IMAGES:
case authorization::REGISTER_AGENT:
case authorization::REMOVE_NESTED_CONTAINER:
case authorization::REMOVE_STANDALONE_CONTAINER:
@@ -1504,6 +1508,16 @@ private:
}
return acls_;
+ case authorization::PRUNE_IMAGES:
+ foreach (const ACL::PruneImages& acl, acls.prune_images()) {
+ GenericACL acl_;
+ acl_.subjects = acl.principals();
+ acl_.objects = acl.images();
+
+ acls_.push_back(acl_);
+ }
+
+ return acls_;
case authorization::REGISTER_FRAMEWORK:
case authorization::CREATE_VOLUME:
case authorization::RESERVE_RESOURCES:
@@ -1684,6 +1698,12 @@ Option<Error> LocalAuthorizer::validate(const ACLs& acls)
}
}
+ foreach (const ACL::PruneImages& acl, acls.prune_images()) {
+ if (acl.images().type() == ACL::Entity::SOME) {
+ return Error("acls.prune_images type must be either NONE or ANY");
+ }
+ }
+
// TODO(alexr): Consider validating not only protobuf, but also the original
// JSON in order to spot misspelled names. A misspelled action may affect
// authorization result and hence lead to a security issue (e.g. when there
http://git-wip-us.apache.org/repos/asf/mesos/blob/250a9a53/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index 446be55..71e0bbb 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -2444,8 +2444,6 @@ Future<Response> Http::pruneImages(
{
CHECK_EQ(agent::Call::PRUNE_IMAGES, call.type());
- // TODO(zhitao): Add AuthN/AuthZ.
-
LOG(INFO) << "Processing PRUNE_IMAGES call";
vector<Image> excludedImages(call.prune_images().excluded_images().begin(),
call.prune_images().excluded_images().end());
@@ -2458,25 +2456,47 @@ Future<Response> Http::pruneImages(
std::back_inserter(excludedImages));
}
- return slave->containerizer->pruneImages(excludedImages)
- .then([acceptType](const Future<Nothing>& result)
- ->Future<Response> {
- if (!result.isReady()) {
- // TODO(zhitao): Because `containerizer::pruneImages` returns
- // a `Nothing` now, we cannot distinguish between actual
- // failure or the case that operator should drain the agent.
- // Consider returning more information.
- LOG(WARNING)
- << "Failed to prune images: "
- << (result.isFailed() ? result.failure() : "discarded");
-
- return result.isFailed()
- ? InternalServerError(result.failure())
- : InternalServerError();
- }
+ Future<Owned<ObjectApprover>> approver;
- return OK();
- });
+ if (slave->authorizer.isSome()) {
+ Option<authorization::Subject> subject = createSubject(principal);
+
+ approver = slave->authorizer.get()->getObjectApprover(
+ subject,
+ authorization::PRUNE_IMAGES);
+ } else {
+ approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
+ }
+
+ return approver
+ .then(defer(slave->self(), [this, excludedImages](
+ const Owned<ObjectApprover>& approver) -> Future<Response> {
+ Try<bool> approved = approver->approved(ObjectApprover::Object());
+ if (approved.isError()) {
+ return InternalServerError("Authorization error: " + approved.error());
+ } else if (!approved.get()) {
+ return Forbidden();
+ }
+
+ return slave->containerizer->pruneImages(excludedImages)
+ .then([](const Future<Nothing>& result) -> Future<Response> {
+ if (!result.isReady()) {
+ // TODO(zhitao): Because `containerizer::pruneImages` returns
+ // a `Nothing` now, we cannot distinguish between actual
+ // failure or the case that operator should drain the agent.
+ // Consider returning more information.
+ LOG(WARNING)
+ << "Failed to prune images: "
+ << (result.isFailed() ? result.failure() : "discarded");
+
+ return result.isFailed()
+ ? InternalServerError(result.failure())
+ : InternalServerError();
+ }
+
+ return OK();
+ });
+ }));
}
[2/3] mesos git commit: Added test for `prune_images` acl validation.
Posted by gi...@apache.org.
Added test for `prune_images` acl validation.
Review: https://reviews.apache.org/r/64865/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/310ba44a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/310ba44a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/310ba44a
Branch: refs/heads/master
Commit: 310ba44a4d48d65e5f28db050fed72e343cde441
Parents: 250a9a5
Author: Zhitao Li <zh...@gmail.com>
Authored: Sun Dec 31 18:27:55 2017 +0800
Committer: Gilbert Song <so...@gmail.com>
Committed: Sun Dec 31 19:40:03 2017 +0800
----------------------------------------------------------------------
src/tests/authorization_tests.cpp | 55 ++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/310ba44a/src/tests/authorization_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/authorization_tests.cpp b/src/tests/authorization_tests.cpp
index 4f3da08..a76ad18 100644
--- a/src/tests/authorization_tests.cpp
+++ b/src/tests/authorization_tests.cpp
@@ -5495,6 +5495,61 @@ TYPED_TEST(AuthorizationTest, ModifyResourceProviderConfig)
}
}
+
+// This tests the authorization of requests to prune images.
+TYPED_TEST(AuthorizationTest, PruneImages)
+{
+ ACLs acls;
+
+ {
+ // "foo" principal can prune any images.
+ mesos::ACL::PruneImages* acl = acls.add_prune_images();
+ acl->mutable_principals()->add_values("foo");
+ acl->mutable_images()->set_type(mesos::ACL::Entity::ANY);
+ }
+
+ {
+ // Nobody else can prune images.
+ mesos::ACL::PruneImages* acl = acls.add_prune_images();
+ acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
+ acl->mutable_images()->set_type(mesos::ACL::Entity::NONE);
+ }
+
+ Try<Authorizer*> create = TypeParam::create(parameterize(acls));
+ ASSERT_SOME(create);
+ Owned<Authorizer> authorizer(create.get());
+
+ {
+ // "foo" is allowed to prune images. This request should succeed.
+ authorization::Request request;
+ request.set_action(authorization::PRUNE_IMAGES);
+ request.mutable_subject()->set_value("foo");
+
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ {
+ // "bar" is not allowed to prune images. The request should fail.
+ authorization::Request request;
+ request.set_action(authorization::PRUNE_IMAGES);
+ request.mutable_subject()->set_value("bar");
+
+ AWAIT_EXPECT_FALSE(authorizer->authorized(request));
+ }
+
+ {
+ // Test that no authorizer is created with invalid ACLs.
+ ACLs invalid;
+
+ mesos::ACL::PruneImages* acl = invalid.add_prune_images();
+ acl->mutable_principals()->add_values("foo");
+ acl->mutable_images()->add_values("yoda");
+
+ Try<Authorizer*> create = TypeParam::create(parameterize(invalid));
+ EXPECT_ERROR(create);
+ }
+}
+
} // namespace tests {
} // namespace internal {
} // namespace mesos {
[3/3] mesos git commit: Documented new image gc support in Mesos
containerizer.
Posted by gi...@apache.org.
Documented new image gc support in Mesos containerizer.
Review: https://reviews.apache.org/r/64813/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5e88bc07
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5e88bc07
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5e88bc07
Branch: refs/heads/master
Commit: 5e88bc076f9c04293057ed1e4b2f941d1238368c
Parents: 310ba44
Author: Zhitao Li <zh...@gmail.com>
Authored: Sun Dec 31 18:28:04 2017 +0800
Committer: Gilbert Song <so...@gmail.com>
Committed: Sun Dec 31 20:08:12 2017 +0800
----------------------------------------------------------------------
docs/container-image.md | 40 ++++++++++++++++++++++++++++++++++++++++
docs/operator-http-api.md | 30 ++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5e88bc07/docs/container-image.md
----------------------------------------------------------------------
diff --git a/docs/container-image.md b/docs/container-image.md
index 99f4f5c..1112bd7 100644
--- a/docs/container-image.md
+++ b/docs/container-image.md
@@ -390,6 +390,46 @@ and mount it under the sandbox directory. The executor can perform
`pivot_root` or `chroot` itself to enter the container root
filesystem.
+## Garbage Collect Unused Container Images
+
+Experimental support of garbage-collecting unused container images was added at
+Mesos 1.5. This can be either configured automatically via a new agent flag
+`--image_gc_config`, or manually invoked through agent's
+[v1 Operator HTTP API](operator-http-api.md#prune_images). This can be used
+to avoid unbounded disk space usage of image stores.
+
+This is implemented with a simple mark-and-sweep logic. When image GC happens,
+we check all layers and images referenced by active running containers and avoid
+removing them from the image store. As a pre-requisite, if there are active
+containers launched before Mesos 1.5.0, we cannot determine what images can be
+safely garbage collected, so agent will refuse to invoke image GC. To garbage
+collect container images, users are expected to drain all containers launched
+before Mesos 1.5.0.
+
+**NOTE**: currently, the image GC is only supported for docker store in Mesos
+Containerizer.
+
+### Automatic Image GC through Agent Flag
+
+To enable automatic image GC, use the new agent flag `--image_gc_config`:
+
+ --image_gc_config=file:///home/vagrant/image-gc-config.json
+
+or as a JSON object,
+
+ --image_gc_config="{ \
+ \"image_disk_headroom\": 0.1, \
+ \"image_disk_watch_interval\": { \
+ \"nano_seconds\": 3600 \
+ }, \
+ \"excluded_images\": \[ \] \
+ }"
+
+
+### Manual Image GC through HTTP API
+See `PRUNE_IMAGES` section in
+[v1 Operator HTTP API](operator-http-api.md#prune_images) for manual image GC
+through the agent HTTP API.
## References
http://git-wip-us.apache.org/repos/asf/mesos/blob/5e88bc07/docs/operator-http-api.md
----------------------------------------------------------------------
diff --git a/docs/operator-http-api.md b/docs/operator-http-api.md
index f81e5bc..af6a3a6 100644
--- a/docs/operator-http-api.md
+++ b/docs/operator-http-api.md
@@ -3848,3 +3848,33 @@ REMOVE_NESTED_CONTAINER HTTP Response (JSON):
HTTP/1.1 200 OK
```
+
+### PRUNE_IMAGES
+
+This call triggers garbage collection for container images. This call can
+only be made when all running containers are launched with Mesos version 1.5
+or newer. An optional list of excluded images from GC can be speficied via
+`prune_images.excluded_images` field.
+
+```
+PRUNE_IMAGES HTTP Request (JSON):
+
+POST /api/v1 HTTP/1.1
+
+Host: agenthost:5051
+Content-Type: application/json
+Accept: application/json
+
+{
+ "type": "PRUNE_IMAGES",
+ "prune_images": {
+ "excluded_images": [
+ {"type":"DOCKER","docker":{"name":"mysql:latest"}}
+ ]
+ }
+}
+
+PRUNE_IMAGES HTTP Response (JSON):
+
+HTTP/1.1 200 OK
+```