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 2017/04/07 00:16:58 UTC
[1/4] mesos git commit: Added 'shutdownExecutor' methods to the mock
agent.
Repository: mesos
Updated Branches:
refs/heads/master b92a46f06 -> 764fa2cbe
Added 'shutdownExecutor' methods to the mock agent.
This patch adds both mocked and unmocked `shutdownExecutor` methods
to the mock agent to facilitate testing of failure scenarios related
to executor secret generation.
Review: https://reviews.apache.org/r/57924/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e033c1a6
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e033c1a6
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e033c1a6
Branch: refs/heads/master
Commit: e033c1a681f8867f97c70b825cae5b3740f34c9a
Parents: b92a46f
Author: Greg Mann <gr...@mesosphere.io>
Authored: Thu Apr 6 17:15:32 2017 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu Apr 6 17:15:32 2017 -0700
----------------------------------------------------------------------
src/slave/slave.hpp | 3 ++-
src/tests/mock_slave.cpp | 11 +++++++++++
src/tests/mock_slave.hpp | 10 ++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/e033c1a6/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index b26bdf8..77fb93a 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -172,7 +172,8 @@ public:
const process::UPID& from,
const KillTaskMessage& killTaskMessage);
- void shutdownExecutor(
+ // Made 'virtual' for Slave mocking.
+ virtual void shutdownExecutor(
const process::UPID& from,
const FrameworkID& frameworkId,
const ExecutorID& executorId);
http://git-wip-us.apache.org/repos/asf/mesos/blob/e033c1a6/src/tests/mock_slave.cpp
----------------------------------------------------------------------
diff --git a/src/tests/mock_slave.cpp b/src/tests/mock_slave.cpp
index 35cd13d..c435ec7 100644
--- a/src/tests/mock_slave.cpp
+++ b/src/tests/mock_slave.cpp
@@ -143,6 +143,8 @@ MockSlave::MockSlave(
.WillRepeatedly(Invoke(this, &MockSlave::unmocked_usage));
EXPECT_CALL(*this, executorTerminated(_, _, _))
.WillRepeatedly(Invoke(this, &MockSlave::unmocked_executorTerminated));
+ EXPECT_CALL(*this, shutdownExecutor(_, _, _))
+ .WillRepeatedly(Invoke(this, &MockSlave::unmocked_shutdownExecutor));
}
@@ -237,6 +239,15 @@ void MockSlave::unmocked_executorTerminated(
slave::Slave::executorTerminated(frameworkId, executorId, termination);
}
+
+void MockSlave::unmocked_shutdownExecutor(
+ const UPID& from,
+ const FrameworkID& frameworkId,
+ const ExecutorID& executorId)
+{
+ slave::Slave::shutdownExecutor(from, frameworkId, executorId);
+}
+
} // namespace tests {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/e033c1a6/src/tests/mock_slave.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mock_slave.hpp b/src/tests/mock_slave.hpp
index 2b30b87..767ed3d 100644
--- a/src/tests/mock_slave.hpp
+++ b/src/tests/mock_slave.hpp
@@ -201,6 +201,16 @@ public:
const process::Future<Option<
mesos::slave::ContainerTermination>>& termination);
+ MOCK_METHOD3(shutdownExecutor, void(
+ const process::UPID& from,
+ const FrameworkID& frameworkId,
+ const ExecutorID& executorId));
+
+ void unmocked_shutdownExecutor(
+ const process::UPID& from,
+ const FrameworkID& frameworkId,
+ const ExecutorID& executorId);
+
private:
Files files;
MockGarbageCollector gc;
[2/4] mesos git commit: Added further tests for executor secret
generation.
Posted by vi...@apache.org.
Added further tests for executor secret generation.
This patch adds two further tests for executor secret
generation, `SlaveTest.RunTaskGroupReferenceTypeSecret`
and `SlaveTest.RunTaskGroupFailedSecretAfterShutdown`.
Review: https://reviews.apache.org/r/57925/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/98450869
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/98450869
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/98450869
Branch: refs/heads/master
Commit: 9845086949f5ab6442228ca8176f977fa0bcba8d
Parents: e033c1a
Author: Greg Mann <gr...@mesosphere.io>
Authored: Thu Apr 6 17:16:35 2017 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu Apr 6 17:16:35 2017 -0700
----------------------------------------------------------------------
src/tests/slave_tests.cpp | 444 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 444 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/98450869/src/tests/slave_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp
index cd76968..7cb2570 100644
--- a/src/tests/slave_tests.cpp
+++ b/src/tests/slave_tests.cpp
@@ -5523,6 +5523,450 @@ TEST_F(SlaveTest, RunTaskGroupInvalidExecutorSecret)
}
+// This test verifies that TASK_FAILED updates are sent correctly for all the
+// tasks in a task group when the secret generator returns a REFERENCE type
+// secret. Only VALUE type secrets are supported at this time.
+TEST_F(SlaveTest, RunTaskGroupReferenceTypeSecret)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ auto scheduler = std::make_shared<v1::MockHTTPScheduler>();
+ auto executor = std::make_shared<v1::MockHTTPExecutor>();
+
+ v1::Resources resources =
+ v1::Resources::parse("cpus:0.1;mem:32;disk:32").get();
+
+ v1::ExecutorInfo executorInfo = v1::DEFAULT_EXECUTOR_INFO;
+ executorInfo.set_type(v1::ExecutorInfo::CUSTOM);
+
+ executorInfo.mutable_resources()->CopyFrom(resources);
+
+ const v1::ExecutorID& executorId = executorInfo.executor_id();
+ TestContainerizer containerizer(devolve(executorId), executor);
+
+ StandaloneMasterDetector detector(master.get()->pid);
+
+ // This pointer is passed to the agent, which will perform the cleanup.
+ MockSecretGenerator* secretGenerator = new MockSecretGenerator();
+
+ MockSlave slave(
+ CreateSlaveFlags(),
+ &detector,
+ &containerizer,
+ None(),
+ None(),
+ secretGenerator);
+ spawn(slave);
+
+ Future<Nothing> connected;
+ EXPECT_CALL(*scheduler, connected(_))
+ .WillOnce(FutureSatisfy(&connected));
+
+ v1::scheduler::TestMesos mesos(
+ master.get()->pid,
+ ContentType::PROTOBUF,
+ scheduler);
+
+ AWAIT_READY(connected);
+
+ Future<v1::scheduler::Event::Subscribed> subscribed;
+ EXPECT_CALL(*scheduler, subscribed(_, _))
+ .WillOnce(FutureArg<1>(&subscribed));
+
+ Future<v1::scheduler::Event::Offers> offers;
+ EXPECT_CALL(*scheduler, offers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ EXPECT_CALL(*scheduler, heartbeat(_))
+ .WillRepeatedly(Return()); // Ignore heartbeats.
+
+ {
+ Call call;
+ call.set_type(Call::SUBSCRIBE);
+ Call::Subscribe* subscribe = call.mutable_subscribe();
+ subscribe->mutable_framework_info()->CopyFrom(v1::DEFAULT_FRAMEWORK_INFO);
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(subscribed);
+
+ v1::FrameworkID frameworkId(subscribed->framework_id());
+
+ // Update `executorInfo` with the subscribed `frameworkId`.
+ executorInfo.mutable_framework_id()->CopyFrom(frameworkId);
+
+ AWAIT_READY(offers);
+ ASSERT_NE(0, offers->offers().size());
+
+ const v1::Offer& offer = offers->offers(0);
+ const v1::AgentID agentId = offer.agent_id();
+
+ v1::TaskInfo taskInfo1 = v1::createTask(agentId, resources, "");
+
+ v1::TaskInfo taskInfo2 = v1::createTask(agentId, resources, "");
+
+ v1::TaskGroupInfo taskGroup;
+ taskGroup.add_tasks()->CopyFrom(taskInfo1);
+ taskGroup.add_tasks()->CopyFrom(taskInfo2);
+
+ const hashset<v1::TaskID> tasks{taskInfo1.task_id(), taskInfo2.task_id()};
+
+ // The tasks will fail to launch because the executor secret is invalid
+ // (only VALUE type secrets are supported at this time).
+ Secret authenticationToken;
+ authenticationToken.set_type(Secret::REFERENCE);
+ authenticationToken.mutable_reference()->set_name("secret_name");
+ authenticationToken.mutable_reference()->set_key("secret_key");
+
+ EXPECT_CALL(*secretGenerator, generate(_))
+ .WillOnce(Return(authenticationToken));
+
+ EXPECT_CALL(*executor, connected(_))
+ .Times(0);
+
+ EXPECT_CALL(*executor, subscribed(_, _))
+ .Times(0);
+
+ EXPECT_CALL(*executor, shutdown(_))
+ .Times(0);
+
+ EXPECT_CALL(*executor, launchGroup(_, _))
+ .Times(0);
+
+ EXPECT_CALL(*executor, launch(_, _))
+ .Times(0);
+
+ EXPECT_CALL(slave, executorTerminated(_, _, _))
+ .WillOnce(Invoke(&slave, &MockSlave::unmocked_executorTerminated));
+
+ Future<v1::scheduler::Event::Update> update1;
+ Future<v1::scheduler::Event::Update> update2;
+ EXPECT_CALL(*scheduler, update(_, _))
+ .WillOnce(FutureArg<1>(&update1))
+ .WillOnce(FutureArg<1>(&update2));
+
+ Future<Nothing> failure;
+ EXPECT_CALL(*scheduler, failure(_, _))
+ .WillOnce(FutureSatisfy(&failure));
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::ACCEPT);
+
+ Call::Accept* accept = call.mutable_accept();
+ accept->add_offer_ids()->CopyFrom(offer.id());
+
+ v1::Offer::Operation* operation = accept->add_operations();
+ operation->set_type(v1::Offer::Operation::LAUNCH_GROUP);
+
+ v1::Offer::Operation::LaunchGroup* launchGroup =
+ operation->mutable_launch_group();
+
+ launchGroup->mutable_executor()->CopyFrom(executorInfo);
+ launchGroup->mutable_task_group()->CopyFrom(taskGroup);
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(update1);
+ AWAIT_READY(update2);
+
+ AWAIT_READY(failure);
+
+ const hashset<v1::TaskID> failedTasks{
+ update1->status().task_id(), update2->status().task_id()};
+
+ ASSERT_EQ(TASK_FAILED, update1->status().state());
+ ASSERT_EQ(TASK_FAILED, update2->status().state());
+
+ const string failureMessage =
+ "Expecting generated secret to be of VALUE type instead of REFERENCE type";
+
+ EXPECT_TRUE(strings::contains(update1->status().message(), failureMessage));
+ EXPECT_TRUE(strings::contains(update2->status().message(), failureMessage));
+
+ ASSERT_EQ(tasks, failedTasks);
+
+ // Since this is the only task group for this framework, the
+ // framework should be removed after secret generation fails.
+ Future<Nothing> removeFramework;
+ EXPECT_CALL(slave, removeFramework(_))
+ .WillOnce(DoAll(Invoke(&slave, &MockSlave::unmocked_removeFramework),
+ FutureSatisfy(&removeFramework)));
+
+ // Acknowledge the status updates so that the agent will remove the framework.
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::ACKNOWLEDGE);
+
+ Call::Acknowledge* acknowledge = call.mutable_acknowledge();
+ acknowledge->mutable_task_id()->CopyFrom(update1->status().task_id());
+ acknowledge->mutable_agent_id()->CopyFrom(offer.agent_id());
+ acknowledge->set_uuid(update1->status().uuid());
+
+ mesos.send(call);
+ }
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::ACKNOWLEDGE);
+
+ Call::Acknowledge* acknowledge = call.mutable_acknowledge();
+ acknowledge->mutable_task_id()->CopyFrom(update2->status().task_id());
+ acknowledge->mutable_agent_id()->CopyFrom(offer.agent_id());
+ acknowledge->set_uuid(update2->status().uuid());
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(removeFramework);
+
+ terminate(slave);
+ wait(slave);
+}
+
+
+// This test verifies that TASK_FAILED updates and an executor FAILURE message
+// are sent correctly when the secret generator returns the executor secret
+// after the scheduler has shutdown the executor.
+TEST_F(SlaveTest, RunTaskGroupGenerateSecretAfterShutdown)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ auto scheduler = std::make_shared<v1::MockHTTPScheduler>();
+ auto executor = std::make_shared<v1::MockHTTPExecutor>();
+
+ v1::Resources resources =
+ v1::Resources::parse("cpus:0.1;mem:32;disk:32").get();
+
+ v1::ExecutorInfo executorInfo = v1::DEFAULT_EXECUTOR_INFO;
+ executorInfo.set_type(v1::ExecutorInfo::CUSTOM);
+
+ executorInfo.mutable_resources()->CopyFrom(resources);
+
+ const v1::ExecutorID& executorId = executorInfo.executor_id();
+ TestContainerizer containerizer(devolve(executorId), executor);
+
+ StandaloneMasterDetector detector(master.get()->pid);
+
+ // This pointer is passed to the agent, which will perform the cleanup.
+ MockSecretGenerator* secretGenerator = new MockSecretGenerator();
+
+ MockSlave slave(
+ CreateSlaveFlags(),
+ &detector,
+ &containerizer,
+ None(),
+ None(),
+ secretGenerator);
+ spawn(slave);
+
+ Future<Nothing> connected;
+ EXPECT_CALL(*scheduler, connected(_))
+ .WillOnce(FutureSatisfy(&connected));
+
+ v1::scheduler::TestMesos mesos(
+ master.get()->pid,
+ ContentType::PROTOBUF,
+ scheduler);
+
+ AWAIT_READY(connected);
+
+ Future<v1::scheduler::Event::Subscribed> subscribed;
+ EXPECT_CALL(*scheduler, subscribed(_, _))
+ .WillOnce(FutureArg<1>(&subscribed));
+
+ Future<v1::scheduler::Event::Offers> offers;
+ EXPECT_CALL(*scheduler, offers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ EXPECT_CALL(*scheduler, heartbeat(_))
+ .WillRepeatedly(Return()); // Ignore heartbeats.
+
+ {
+ Call call;
+ call.set_type(Call::SUBSCRIBE);
+ Call::Subscribe* subscribe = call.mutable_subscribe();
+ subscribe->mutable_framework_info()->CopyFrom(v1::DEFAULT_FRAMEWORK_INFO);
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(subscribed);
+
+ v1::FrameworkID frameworkId(subscribed->framework_id());
+
+ // Update `executorInfo` with the subscribed `frameworkId`.
+ executorInfo.mutable_framework_id()->CopyFrom(frameworkId);
+
+ AWAIT_READY(offers);
+ ASSERT_NE(0, offers->offers().size());
+
+ const v1::Offer& offer = offers->offers(0);
+ const v1::AgentID agentId = offer.agent_id();
+
+ v1::TaskInfo taskInfo1 = v1::createTask(agentId, resources, "");
+
+ v1::TaskInfo taskInfo2 = v1::createTask(agentId, resources, "");
+
+ v1::TaskGroupInfo taskGroup;
+ taskGroup.add_tasks()->CopyFrom(taskInfo1);
+ taskGroup.add_tasks()->CopyFrom(taskInfo2);
+
+ const hashset<v1::TaskID> tasks{taskInfo1.task_id(), taskInfo2.task_id()};
+
+ // We return this promise's future so that we can delay its fulfillment
+ // until after the scheduler has shutdown the executor.
+ Promise<Secret> secret;
+ Future<Nothing> generate;
+ EXPECT_CALL(*secretGenerator, generate(_))
+ .WillOnce(DoAll(FutureSatisfy(&generate),
+ Return(secret.future())));
+
+ EXPECT_CALL(*executor, connected(_))
+ .Times(0);
+
+ EXPECT_CALL(*executor, subscribed(_, _))
+ .Times(0);
+
+ EXPECT_CALL(*executor, shutdown(_))
+ .Times(0);
+
+ EXPECT_CALL(*executor, launchGroup(_, _))
+ .Times(0);
+
+ EXPECT_CALL(*executor, launch(_, _))
+ .Times(0);
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::ACCEPT);
+
+ Call::Accept* accept = call.mutable_accept();
+ accept->add_offer_ids()->CopyFrom(offer.id());
+
+ v1::Offer::Operation* operation = accept->add_operations();
+ operation->set_type(v1::Offer::Operation::LAUNCH_GROUP);
+
+ v1::Offer::Operation::LaunchGroup* launchGroup =
+ operation->mutable_launch_group();
+
+ launchGroup->mutable_executor()->CopyFrom(executorInfo);
+ launchGroup->mutable_task_group()->CopyFrom(taskGroup);
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(generate);
+
+ Future<Nothing> shutdownExecutor;
+ EXPECT_CALL(slave, shutdownExecutor(_, _, _))
+ .WillOnce(DoAll(Invoke(&slave, &MockSlave::unmocked_shutdownExecutor),
+ FutureSatisfy(&shutdownExecutor)));
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::SHUTDOWN);
+
+ Call::Shutdown* shutdown = call.mutable_shutdown();
+ shutdown->mutable_executor_id()->CopyFrom(executorId);
+ shutdown->mutable_agent_id()->CopyFrom(offer.agent_id());
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(shutdownExecutor);
+
+ Future<v1::scheduler::Event::Update> update1;
+ Future<v1::scheduler::Event::Update> update2;
+ EXPECT_CALL(*scheduler, update(_, _))
+ .WillOnce(FutureArg<1>(&update1))
+ .WillOnce(FutureArg<1>(&update2));
+
+ Future<Nothing> failure;
+ EXPECT_CALL(*scheduler, failure(_, _))
+ .WillOnce(FutureSatisfy(&failure));
+
+ EXPECT_CALL(slave, executorTerminated(_, _, _))
+ .WillOnce(Invoke(&slave, &MockSlave::unmocked_executorTerminated));
+
+ // The tasks will fail to launch because the executor has been shutdown.
+ Secret authenticationToken;
+ authenticationToken.set_type(Secret::VALUE);
+ authenticationToken.mutable_value()->set_data("secret_data");
+ secret.set(authenticationToken);
+
+ AWAIT_READY(update1);
+ AWAIT_READY(update2);
+
+ AWAIT_READY(failure);
+
+ const hashset<v1::TaskID> failedTasks{
+ update1->status().task_id(), update2->status().task_id()};
+
+ ASSERT_EQ(TASK_FAILED, update1->status().state());
+ ASSERT_EQ(TASK_FAILED, update2->status().state());
+
+ const string failureMessage = "Executor terminating";
+
+ EXPECT_TRUE(strings::contains(update1->status().message(), failureMessage));
+ EXPECT_TRUE(strings::contains(update2->status().message(), failureMessage));
+
+ ASSERT_EQ(tasks, failedTasks);
+
+ // Since this is the only task group for this framework, the
+ // framework should be removed after secret generation fails.
+ Future<Nothing> removeFramework;
+ EXPECT_CALL(slave, removeFramework(_))
+ .WillOnce(DoAll(Invoke(&slave, &MockSlave::unmocked_removeFramework),
+ FutureSatisfy(&removeFramework)));
+
+ // Acknowledge the status updates so that the agent will remove the framework.
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::ACKNOWLEDGE);
+
+ Call::Acknowledge* acknowledge = call.mutable_acknowledge();
+ acknowledge->mutable_task_id()->CopyFrom(update1->status().task_id());
+ acknowledge->mutable_agent_id()->CopyFrom(offer.agent_id());
+ acknowledge->set_uuid(update1->status().uuid());
+
+ mesos.send(call);
+ }
+
+ {
+ Call call;
+ call.mutable_framework_id()->CopyFrom(frameworkId);
+ call.set_type(Call::ACKNOWLEDGE);
+
+ Call::Acknowledge* acknowledge = call.mutable_acknowledge();
+ acknowledge->mutable_task_id()->CopyFrom(update2->status().task_id());
+ acknowledge->mutable_agent_id()->CopyFrom(offer.agent_id());
+ acknowledge->set_uuid(update2->status().uuid());
+
+ mesos.send(call);
+ }
+
+ AWAIT_READY(removeFramework);
+
+ terminate(slave);
+ wait(slave);
+}
+
+
// This test ensures that a `killTask()` can happen between `runTask()`
// and `_run()` and then gets "handled properly" for a task group.
// This should result in TASK_KILLED updates for all the tasks in the
[4/4] mesos git commit: Updated documentation for multiple HTTP
authenticators.
Posted by vi...@apache.org.
Updated documentation for multiple HTTP authenticators.
Review: https://reviews.apache.org/r/57663/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/764fa2cb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/764fa2cb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/764fa2cb
Branch: refs/heads/master
Commit: 764fa2cbe5439a509e5eb875aafcace47dc07ccb
Parents: 7dd3b6d
Author: Greg Mann <gr...@mesosphere.io>
Authored: Thu Apr 6 17:16:45 2017 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu Apr 6 17:16:45 2017 -0700
----------------------------------------------------------------------
docs/authentication.md | 13 +++++++++++++
1 file changed, 13 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/764fa2cb/docs/authentication.md
----------------------------------------------------------------------
diff --git a/docs/authentication.md b/docs/authentication.md
index 6961920..a96de6e 100644
--- a/docs/authentication.md
+++ b/docs/authentication.md
@@ -111,6 +111,19 @@ Mesos master and agent processes. For more information, refer to the
format) of accepted credentials. This may be optional depending on the
authenticator being used.
+### Multiple HTTP Authenticators
+
+Multiple HTTP authenticators may be loaded into the Mesos master and agent. In
+order to load multiple authenticators, specify them as a comma-separated list
+using the `--http_authenticators` flag. The authenticators will be called
+serially, and the result of the first successful authentication attempt will be
+returned.
+
+If you wish to specify the default basic HTTP authenticator in addition to
+custom authenticator modules, add the name `basic` to your authenticator list.
+To specify the default JWT HTTP authenticator in addition to custom
+authenticator modules, add the name `jwt` to your authenticator list.
+
### Executor
If HTTP executor authentication is enabled on the agent, then all requests from
[3/4] mesos git commit: Added executor authentication to the docs.
Posted by vi...@apache.org.
Added executor authentication to the docs.
Review: https://reviews.apache.org/r/57667/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/7dd3b6d1
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/7dd3b6d1
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/7dd3b6d1
Branch: refs/heads/master
Commit: 7dd3b6d157250895d09e44d4f06b003542b5e36d
Parents: 9845086
Author: Greg Mann <gr...@mesosphere.io>
Authored: Thu Apr 6 17:16:41 2017 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu Apr 6 17:16:41 2017 -0700
----------------------------------------------------------------------
docs/authentication.md | 48 +++++++++++++++++++++++++++++++++++++++++-
docs/executor-http-api.md | 1 +
2 files changed, 48 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/7dd3b6d1/docs/authentication.md
----------------------------------------------------------------------
diff --git a/docs/authentication.md b/docs/authentication.md
index 279e00a..6961920 100644
--- a/docs/authentication.md
+++ b/docs/authentication.md
@@ -94,7 +94,14 @@ Mesos master and agent processes. For more information, refer to the
to make HTTP requests to the read-write HTTP endpoints that support
authentication. If `false` (the default), these endpoints can be used without
authentication. Read-write endpoints are those which can be used to modify the
- state of the agent.
+ state of the agent. Note that for backward compatibility reasons, the V1
+ executor API is not affected by this flag.
+
+* `--[no-]authenticate_http_executors` - If `true`, authentication is required
+ to make HTTP requests to the V1 executor API. If `false` (the default), that
+ API can be used without authentication. If this flag is `true` and custom
+ HTTP authenticators are not specified, then the default `JWT` authenticator is
+ loaded to handle executor authentication.
* `--http_authenticators` - Specifies which HTTP authenticator module to use.
The default is `basic`, but additional modules can be added using the
@@ -104,6 +111,45 @@ Mesos master and agent processes. For more information, refer to the
format) of accepted credentials. This may be optional depending on the
authenticator being used.
+### Executor
+
+If HTTP executor authentication is enabled on the agent, then all requests from
+HTTP executors must be authenticated. This includes the default executor, HTTP
+command executors, and custom HTTP executors. By default, the agent's JSON web
+token (JWT) HTTP authenticator is loaded to handle executor authentication on
+both the executor and operator API endpoints. Note that command and custom
+executors not using the HTTP API will remain unauthenticated.
+
+When a secret key is loaded via the `--executor_secret_key` flag, the agent will
+generate a default JWT for each executor before it is launched. This token is
+passed into the executor's environment via the
+`MESOS_EXECUTOR_AUTHENTICATION_TOKEN` environment variable. In order to
+authenticate with the agent, the executor should place this token into the
+`Authorization` header of all its requests as follows:
+
+ Authorization: Bearer MESOS_EXECUTOR_AUTHENTICATION_TOKEN
+
+In order to upgrade an existing cluster to require executor authentication, the
+following procedure should be followed:
+
+1. Upgrade all agents, and provide each agent with a cryptographic key via the
+ `--executor_secret_key` flag. This key will be used to sign executor
+ authentication tokens using the HMAC-SHA256 procedure.
+
+2. Before executor authentication can be enabled successfully, all HTTP
+ executors must have executor authentication tokens in their environment and
+ support authentication. To accomplish this, executors which were already
+ running before the upgrade must be restarted. This could either be done all
+ at once, or the cluster may be left in this intermediate state while
+ executors gradually turn over.
+
+3. Once all running default/HTTP command executors have been launched by
+ upgraded agents, and any custom HTTP executors have been upgraded, the agent
+ processes can be restarted with the `--authenticate_http_executors` flag set.
+ This will enable required HTTP executor authentication, and since all
+ executors now have authentication tokens and support authentication, their
+ requests to the agent will authenticate successfully.
+
### Framework
If framework authentication is enabled, each framework must be configured to
http://git-wip-us.apache.org/repos/asf/mesos/blob/7dd3b6d1/docs/executor-http-api.md
----------------------------------------------------------------------
diff --git a/docs/executor-http-api.md b/docs/executor-http-api.md
index c49c234..3e9d04f 100644
--- a/docs/executor-http-api.md
+++ b/docs/executor-http-api.md
@@ -389,6 +389,7 @@ The following environment variables are set by the agent that can be used by the
* `MESOS_AGENT_ENDPOINT`: Agent endpoint (i.e., ip:port to be used by the executor to connect to the agent).
* `MESOS_CHECKPOINT`: If set to true, denotes that framework has checkpointing enabled.
* `MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD`: Amount of time the agent would wait for an executor to shut down (e.g., 60secs, 3mins etc.) after sending a `SHUTDOWN` event.
+* `MESOS_EXECUTOR_AUTHENTICATION_TOKEN`: The token the executor should use to authenticate with the agent. When executor authentication is enabled, the agent generates a JSON web token (JWT) that the executor can use to authenticate with the agent's default JWT authenticator.
If `MESOS_CHECKPOINT` is set (i.e., if framework checkpointing is enabled), the following additional variables are also set that can be used by the executor for retrying upon a disconnection with the agent: