You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2016/02/20 17:37:37 UTC
[01/11] mesos git commit: Introduced a TASK_KILLING state.
Repository: mesos
Updated Branches:
refs/heads/master fdeb55a0a -> 1488f16d2
Introduced a TASK_KILLING state.
TASK_KILLING can be used to signify that the kill request has been
received by the executor, but the task is not yet killed. This is
similar to how TASK_STARTING indicates the launch request has been
received by the executor, but the task is not yet launched.
This new state will be guarded by a framework capability in order
to ensure that we do not break older frameworks.
Review: https://reviews.apache.org/r/43487/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/022be0a8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/022be0a8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/022be0a8
Branch: refs/heads/master
Commit: 022be0a833dfb58de958a80eabc89fa9334782e0
Parents: fdeb55a
Author: Abhishek Dasgupta <a1...@linux.vnet.ibm.com>
Authored: Sat Feb 20 12:56:24 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 14:18:30 2016 +0100
----------------------------------------------------------------------
include/mesos/mesos.proto | 5 +++++
include/mesos/v1/mesos.proto | 5 +++++
src/master/http.cpp | 5 +++++
src/master/master.cpp | 19 +++++++++++++++++++
src/master/master.hpp | 1 +
src/master/metrics.cpp | 5 +++++
src/master/metrics.hpp | 1 +
src/slave/metrics.cpp | 5 +++++
src/slave/metrics.hpp | 1 +
src/slave/slave.cpp | 16 ++++++++++++++++
src/slave/slave.hpp | 1 +
src/tests/metrics_tests.cpp | 2 ++
12 files changed, 66 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index a27c505..70e380a 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1218,6 +1218,11 @@ enum TaskState {
TASK_STAGING = 6; // Initial state. Framework status updates should not use.
TASK_STARTING = 0;
TASK_RUNNING = 1;
+
+ // NOTE: This should only be sent when the framework has
+ // the TASK_KILLING_STATE capability.
+ TASK_KILLING = 8; // The task is being killed by the executor.
+
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.
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index e4224af..6271d2a 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1119,6 +1119,11 @@ enum TaskState {
TASK_STAGING = 6; // Initial state. Framework status updates should not use.
TASK_STARTING = 0;
TASK_RUNNING = 1;
+
+ // NOTE: This should only be sent when the framework has
+ // the TASK_KILLING_STATE capability.
+ TASK_KILLING = 8; // The task is being killed by the executor.
+
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.
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 248e3d4..ae6bc78 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -1548,6 +1548,7 @@ struct TaskStateSummary
: staging(0),
starting(0),
running(0),
+ killing(0),
finished(0),
killed(0),
failed(0),
@@ -1561,6 +1562,7 @@ struct TaskStateSummary
case TASK_STAGING: { ++staging; break; }
case TASK_STARTING: { ++starting; break; }
case TASK_RUNNING: { ++running; break; }
+ case TASK_KILLING: { ++killing; break; }
case TASK_FINISHED: { ++finished; break; }
case TASK_KILLED: { ++killed; break; }
case TASK_FAILED: { ++failed; break; }
@@ -1574,6 +1576,7 @@ struct TaskStateSummary
size_t staging;
size_t starting;
size_t running;
+ size_t killing;
size_t finished;
size_t killed;
size_t failed;
@@ -1683,6 +1686,7 @@ Future<Response> Master::Http::stateSummary(const Request& request) const
writer->field("TASK_STAGING", summary.staging);
writer->field("TASK_STARTING", summary.starting);
writer->field("TASK_RUNNING", summary.running);
+ writer->field("TASK_KILLING", summary.killing);
writer->field("TASK_FINISHED", summary.finished);
writer->field("TASK_KILLED", summary.killed);
writer->field("TASK_FAILED", summary.failed);
@@ -1724,6 +1728,7 @@ Future<Response> Master::Http::stateSummary(const Request& request) const
writer->field("TASK_STAGING", summary.staging);
writer->field("TASK_STARTING", summary.starting);
writer->field("TASK_RUNNING", summary.running);
+ writer->field("TASK_KILLING", summary.killing);
writer->field("TASK_FINISHED", summary.finished);
writer->field("TASK_KILLED", summary.killed);
writer->field("TASK_FAILED", summary.failed);
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index e5aaf67..b453bc7 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -6918,6 +6918,25 @@ double Master::_tasks_running()
}
+double Master::_tasks_killing()
+{
+ double count = 0.0;
+
+ foreachvalue (Slave* slave, slaves.registered) {
+ typedef hashmap<TaskID, Task*> TaskMap;
+ foreachvalue (const TaskMap& tasks, slave->tasks) {
+ foreachvalue (const Task* task, tasks) {
+ if (task->state() == TASK_KILLING) {
+ count++;
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+
double Master::_resources_total(const string& name)
{
double total = 0.0;
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 2f2ad2a..13c6ff1 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1462,6 +1462,7 @@ private:
double _tasks_staging();
double _tasks_starting();
double _tasks_running();
+ double _tasks_killing();
double _resources_total(const std::string& name);
double _resources_used(const std::string& name);
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/master/metrics.cpp
----------------------------------------------------------------------
diff --git a/src/master/metrics.cpp b/src/master/metrics.cpp
index 5e4f4d3..30c0911 100644
--- a/src/master/metrics.cpp
+++ b/src/master/metrics.cpp
@@ -80,6 +80,9 @@ Metrics::Metrics(const Master& master)
tasks_running(
"master/tasks_running",
defer(master, &Master::_tasks_running)),
+ tasks_killing(
+ "master/tasks_killing",
+ defer(master, &Master::_tasks_killing)),
tasks_finished(
"master/tasks_finished"),
tasks_failed(
@@ -199,6 +202,7 @@ Metrics::Metrics(const Master& master)
process::metrics::add(tasks_staging);
process::metrics::add(tasks_starting);
process::metrics::add(tasks_running);
+ process::metrics::add(tasks_killing);
process::metrics::add(tasks_finished);
process::metrics::add(tasks_failed);
process::metrics::add(tasks_killed);
@@ -335,6 +339,7 @@ Metrics::~Metrics()
process::metrics::remove(tasks_staging);
process::metrics::remove(tasks_starting);
process::metrics::remove(tasks_running);
+ process::metrics::remove(tasks_killing);
process::metrics::remove(tasks_finished);
process::metrics::remove(tasks_failed);
process::metrics::remove(tasks_killed);
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/master/metrics.hpp
----------------------------------------------------------------------
diff --git a/src/master/metrics.hpp b/src/master/metrics.hpp
index 551e4eb..9d201fc 100644
--- a/src/master/metrics.hpp
+++ b/src/master/metrics.hpp
@@ -60,6 +60,7 @@ struct Metrics
process::metrics::Gauge tasks_staging;
process::metrics::Gauge tasks_starting;
process::metrics::Gauge tasks_running;
+ process::metrics::Gauge tasks_killing;
process::metrics::Counter tasks_finished;
process::metrics::Counter tasks_failed;
process::metrics::Counter tasks_killed;
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/slave/metrics.cpp
----------------------------------------------------------------------
diff --git a/src/slave/metrics.cpp b/src/slave/metrics.cpp
index 0769495..42c66d7 100644
--- a/src/slave/metrics.cpp
+++ b/src/slave/metrics.cpp
@@ -53,6 +53,9 @@ Metrics::Metrics(const Slave& slave)
tasks_running(
"slave/tasks_running",
defer(slave, &Slave::_tasks_running)),
+ tasks_killing(
+ "slave/tasks_killing",
+ defer(slave, &Slave::_tasks_killing)),
tasks_finished(
"slave/tasks_finished"),
tasks_failed(
@@ -99,6 +102,7 @@ Metrics::Metrics(const Slave& slave)
process::metrics::add(tasks_staging);
process::metrics::add(tasks_starting);
process::metrics::add(tasks_running);
+ process::metrics::add(tasks_killing);
process::metrics::add(tasks_finished);
process::metrics::add(tasks_failed);
process::metrics::add(tasks_killed);
@@ -184,6 +188,7 @@ Metrics::~Metrics()
process::metrics::remove(tasks_staging);
process::metrics::remove(tasks_starting);
process::metrics::remove(tasks_running);
+ process::metrics::remove(tasks_killing);
process::metrics::remove(tasks_finished);
process::metrics::remove(tasks_failed);
process::metrics::remove(tasks_killed);
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/slave/metrics.hpp
----------------------------------------------------------------------
diff --git a/src/slave/metrics.hpp b/src/slave/metrics.hpp
index 2c22de5..d443213 100644
--- a/src/slave/metrics.hpp
+++ b/src/slave/metrics.hpp
@@ -45,6 +45,7 @@ struct Metrics
process::metrics::Gauge tasks_staging;
process::metrics::Gauge tasks_starting;
process::metrics::Gauge tasks_running;
+ process::metrics::Gauge tasks_killing;
process::metrics::Counter tasks_finished;
process::metrics::Counter tasks_failed;
process::metrics::Counter tasks_killed;
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index f0be0d5..840534f 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -5046,6 +5046,22 @@ double Slave::_tasks_running()
}
+double Slave::_tasks_killing()
+{
+ double count = 0.0;
+ foreachvalue (Framework* framework, frameworks) {
+ foreachvalue (Executor* executor, framework->executors) {
+ foreach (Task* task, executor->launchedTasks.values()) {
+ if (task->state() == TASK_KILLING) {
+ count++;
+ }
+ }
+ }
+ }
+ return count;
+}
+
+
double Slave::_executors_registering()
{
double count = 0.0;
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index ced835d..7520cc3 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -478,6 +478,7 @@ private:
double _tasks_staging();
double _tasks_starting();
double _tasks_running();
+ double _tasks_killing();
double _executors_registering();
double _executors_running();
http://git-wip-us.apache.org/repos/asf/mesos/blob/022be0a8/src/tests/metrics_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/metrics_tests.cpp b/src/tests/metrics_tests.cpp
index 106bea5..419d275 100644
--- a/src/tests/metrics_tests.cpp
+++ b/src/tests/metrics_tests.cpp
@@ -73,6 +73,7 @@ TEST_F(MetricsTest, Master)
EXPECT_EQ(1u, stats.values.count("master/tasks_staging"));
EXPECT_EQ(1u, stats.values.count("master/tasks_starting"));
EXPECT_EQ(1u, stats.values.count("master/tasks_running"));
+ EXPECT_EQ(1u, stats.values.count("master/tasks_killing"));
EXPECT_EQ(1u, stats.values.count("master/tasks_finished"));
EXPECT_EQ(1u, stats.values.count("master/tasks_failed"));
EXPECT_EQ(1u, stats.values.count("master/tasks_killed"));
@@ -180,6 +181,7 @@ TEST_F(MetricsTest, Slave)
EXPECT_EQ(1u, stats.values.count("slave/tasks_staging"));
EXPECT_EQ(1u, stats.values.count("slave/tasks_starting"));
EXPECT_EQ(1u, stats.values.count("slave/tasks_running"));
+ EXPECT_EQ(1u, stats.values.count("slave/tasks_killing"));
EXPECT_EQ(1u, stats.values.count("slave/tasks_finished"));
EXPECT_EQ(1u, stats.values.count("slave/tasks_failed"));
EXPECT_EQ(1u, stats.values.count("slave/tasks_killed"));
[10/11] mesos git commit: Fixed health check process leak when
shutdown is called without killTask.
Posted by bm...@apache.org.
Fixed health check process leak when shutdown is called without killTask.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/25d303d8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/25d303d8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/25d303d8
Branch: refs/heads/master
Commit: 25d303d8743b524c92627d48f7dfb7ac2a921ede
Parents: a30233b
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 15:31:28 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 17:32:26 2016 +0100
----------------------------------------------------------------------
src/docker/executor.cpp | 14 ++++++++++----
src/launcher/executor.cpp | 14 ++++++++++----
2 files changed, 20 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/25d303d8/src/docker/executor.cpp
----------------------------------------------------------------------
diff --git a/src/docker/executor.cpp b/src/docker/executor.cpp
index cab9d80..1921d4a 100644
--- a/src/docker/executor.cpp
+++ b/src/docker/executor.cpp
@@ -195,10 +195,6 @@ public:
// Since the docker executor manages a single task, we
// shutdown completely when we receive a killTask.
shutdown(driver);
- if (healthPid != -1) {
- // Cleanup health check process.
- os::killtree(healthPid, SIGKILL);
- }
}
void frameworkMessage(ExecutorDriver* driver, const string& data) {}
@@ -230,6 +226,16 @@ public:
stop = docker->stop(containerName, stopTimeout);
killed = true;
}
+
+ // Cleanup health check process.
+ //
+ // TODO(bmahler): Consider doing this after the task has been
+ // reaped, since a framework may be interested in health
+ // information while the task is being killed (consider a
+ // task that takes 30 minutes to be cleanly killed).
+ if (healthPid != -1) {
+ os::killtree(healthPid, SIGKILL);
+ }
}
void error(ExecutorDriver* driver, const string& message) {}
http://git-wip-us.apache.org/repos/asf/mesos/blob/25d303d8/src/launcher/executor.cpp
----------------------------------------------------------------------
diff --git a/src/launcher/executor.cpp b/src/launcher/executor.cpp
index b65f0ab..4149f08 100644
--- a/src/launcher/executor.cpp
+++ b/src/launcher/executor.cpp
@@ -464,10 +464,6 @@ public:
// Since the command executor manages a single task, we
// shutdown completely when we receive a killTask.
shutdown(driver);
- if (healthPid != -1) {
- // Cleanup health check process.
- os::killtree(healthPid, SIGKILL);
- }
}
void frameworkMessage(ExecutorDriver* driver, const string& data) {}
@@ -521,6 +517,16 @@ public:
killed = true;
}
+
+ // Cleanup health check process.
+ //
+ // TODO(bmahler): Consider doing this after the task has been
+ // reaped, since a framework may be interested in health
+ // information while the task is being killed (consider a
+ // task that takes 30 minutes to be cleanly killed).
+ if (healthPid != -1) {
+ os::killtree(healthPid, SIGKILL);
+ }
}
virtual void error(ExecutorDriver* driver, const string& message) {}
[09/11] mesos git commit: Updated the command / docker executors to
send TASK_KILLING.
Posted by bm...@apache.org.
Updated the command / docker executors to send TASK_KILLING.
Review: https://reviews.apache.org/r/43489/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a30233b9
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a30233b9
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a30233b9
Branch: refs/heads/master
Commit: a30233b994dd1a77eb8ef37525b5aa7b6ecdf3bd
Parents: c893c9f
Author: Abhishek Dasgupta <a1...@linux.vnet.ibm.com>
Authored: Sat Feb 20 14:25:15 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 17:32:26 2016 +0100
----------------------------------------------------------------------
src/docker/executor.cpp | 51 ++++++++++++++++++++++++-------------
src/launcher/executor.cpp | 58 +++++++++++++++++++++++++++++++-----------
2 files changed, 77 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a30233b9/src/docker/executor.cpp
----------------------------------------------------------------------
diff --git a/src/docker/executor.cpp b/src/docker/executor.cpp
index 654a41d..cab9d80 100644
--- a/src/docker/executor.cpp
+++ b/src/docker/executor.cpp
@@ -91,11 +91,12 @@ public:
void registered(
ExecutorDriver* _driver,
const ExecutorInfo& executorInfo,
- const FrameworkInfo& frameworkInfo,
+ const FrameworkInfo& _frameworkInfo,
const SlaveInfo& slaveInfo)
{
cout << "Registered docker executor on " << slaveInfo.hostname() << endl;
driver = _driver;
+ frameworkInfo = _frameworkInfo;
}
void reregistered(
@@ -123,9 +124,10 @@ public:
return;
}
- TaskID taskId = task.task_id();
+ // Capture the TaskID.
+ taskId = task.task_id();
- cout << "Starting task " << taskId.value() << endl;
+ cout << "Starting task " << taskId.get() << endl;
CHECK(task.has_container());
CHECK(task.has_command());
@@ -147,13 +149,9 @@ public:
task.resources() + task.executor().resources(),
None(),
Subprocess::FD(STDOUT_FILENO),
- Subprocess::FD(STDERR_FILENO))
- .onAny(defer(
- self(),
- &Self::reaped,
- driver,
- taskId,
- lambda::_1));
+ Subprocess::FD(STDERR_FILENO));
+
+ run->onAny(defer(self(), &Self::reaped, driver, lambda::_1));
// Delay sending TASK_RUNNING status update until we receive
// inspect output.
@@ -161,7 +159,7 @@ public:
.then(defer(self(), [=](const Docker::Container& container) {
if (!killed) {
TaskStatus status;
- status.mutable_task_id()->CopyFrom(taskId);
+ status.mutable_task_id()->CopyFrom(taskId.get());
status.set_state(TASK_RUNNING);
status.set_data(container.output);
if (container.ipAddress.isSome()) {
@@ -192,7 +190,10 @@ public:
void killTask(ExecutorDriver* driver, const TaskID& taskId)
{
- cout << "Killing docker task" << endl;
+ cout << "Received killTask" << endl;
+
+ // Since the docker executor manages a single task, we
+ // shutdown completely when we receive a killTask.
shutdown(driver);
if (healthPid != -1) {
// Cleanup health check process.
@@ -207,12 +208,25 @@ public:
cout << "Shutting down" << endl;
if (run.isSome() && !killed) {
+ // Send TASK_KILLING if the framework can handle it.
+ CHECK_SOME(frameworkInfo);
+ CHECK_SOME(taskId);
+
+ foreach (const FrameworkInfo::Capability& c,
+ frameworkInfo->capabilities()) {
+ if (c.type() == FrameworkInfo::Capability::TASK_KILLING_STATE) {
+ TaskStatus status;
+ status.mutable_task_id()->CopyFrom(taskId.get());
+ status.set_state(TASK_KILLING);
+ driver->sendStatusUpdate(status);
+ break;
+ }
+ }
+
// The docker daemon might still be in progress starting the
// container, therefore we kill both the docker run process
// and also ask the daemon to stop the container.
-
- // Making a mutable copy of the future so we can call discard.
- Future<Nothing>(run.get()).discard();
+ run->discard();
stop = docker->stop(containerName, stopTimeout);
killed = true;
}
@@ -257,7 +271,6 @@ protected:
private:
void reaped(
ExecutorDriver* _driver,
- const TaskID& taskId,
const Future<Nothing>& run)
{
// Wait for docker->stop to finish, and best effort wait for the
@@ -287,8 +300,10 @@ private:
state = TASK_FINISHED;
}
+ CHECK_SOME(taskId);
+
TaskStatus taskStatus;
- taskStatus.mutable_task_id()->CopyFrom(taskId);
+ taskStatus.mutable_task_id()->CopyFrom(taskId.get());
taskStatus.set_state(state);
taskStatus.set_message(message);
if (killed && killedByHealthCheck) {
@@ -415,6 +430,8 @@ private:
Future<Nothing> stop;
Future<Nothing> inspect;
Option<ExecutorDriver*> driver;
+ Option<FrameworkInfo> frameworkInfo;
+ Option<TaskID> taskId;
};
http://git-wip-us.apache.org/repos/asf/mesos/blob/a30233b9/src/launcher/executor.cpp
----------------------------------------------------------------------
diff --git a/src/launcher/executor.cpp b/src/launcher/executor.cpp
index c27e079..b65f0ab 100644
--- a/src/launcher/executor.cpp
+++ b/src/launcher/executor.cpp
@@ -93,6 +93,8 @@ public:
healthPid(-1),
escalationTimeout(slave::EXECUTOR_SIGNAL_ESCALATION_TIMEOUT),
driver(None()),
+ frameworkInfo(None()),
+ taskId(None()),
healthCheckDir(_healthCheckDir),
override(override),
sandboxDirectory(_sandboxDirectory),
@@ -105,13 +107,16 @@ public:
void registered(
ExecutorDriver* _driver,
const ExecutorInfo& _executorInfo,
- const FrameworkInfo& frameworkInfo,
+ const FrameworkInfo& _frameworkInfo,
const SlaveInfo& slaveInfo)
{
CHECK_EQ(REGISTERING, state);
cout << "Registered executor on " << slaveInfo.hostname() << endl;
+
driver = _driver;
+ frameworkInfo = _frameworkInfo;
+
state = REGISTERED;
}
@@ -122,6 +127,7 @@ public:
CHECK(state == REGISTERED || state == REGISTERING) << state;
cout << "Re-registered executor on " << slaveInfo.hostname() << endl;
+
state = REGISTERED;
}
@@ -142,6 +148,9 @@ public:
return;
}
+ // Capture the TaskID.
+ taskId = task.task_id();
+
// Determine the command to launch the task.
CommandInfo command;
@@ -438,12 +447,7 @@ public:
// Monitor this process.
process::reap(pid)
- .onAny(defer(self(),
- &Self::reaped,
- driver,
- task.task_id(),
- pid,
- lambda::_1));
+ .onAny(defer(self(), &Self::reaped, driver, pid, lambda::_1));
TaskStatus status;
status.mutable_task_id()->MergeFrom(task.task_id());
@@ -455,6 +459,10 @@ public:
void killTask(ExecutorDriver* driver, const TaskID& taskId)
{
+ cout << "Received killTask" << endl;
+
+ // Since the command executor manages a single task, we
+ // shutdown completely when we receive a killTask.
shutdown(driver);
if (healthPid != -1) {
// Cleanup health check process.
@@ -468,22 +476,39 @@ public:
{
cout << "Shutting down" << endl;
- if (pid > 0 && !killed) {
- cout << "Sending SIGTERM to process tree at pid "
- << pid << endl;
+ if (launched && !killed) {
+ // Send TASK_KILLING if the framework can handle it.
+ CHECK_SOME(frameworkInfo);
+ CHECK_SOME(taskId);
+
+ foreach (const FrameworkInfo::Capability& c,
+ frameworkInfo->capabilities()) {
+ if (c.type() == FrameworkInfo::Capability::TASK_KILLING_STATE) {
+ TaskStatus status;
+ status.mutable_task_id()->CopyFrom(taskId.get());
+ status.set_state(TASK_KILLING);
+ driver->sendStatusUpdate(status);
+ break;
+ }
+ }
+
+ // Now perform signal escalation to begin killing the task.
+ CHECK_GT(pid, 0);
+
+ cout << "Sending SIGTERM to process tree at pid " << pid << endl;
Try<std::list<os::ProcessTree> > trees =
os::killtree(pid, SIGTERM, true, true);
if (trees.isError()) {
- cerr << "Failed to kill the process tree rooted at pid "
- << pid << ": " << trees.error() << endl;
+ cerr << "Failed to kill the process tree rooted at pid " << pid
+ << ": " << trees.error() << endl;
// Send SIGTERM directly to process 'pid' as it may not have
// received signal before os::killtree() failed.
::kill(pid, SIGTERM);
} else {
- cout << "Killing the following process trees:\n"
+ cout << "Sent SIGTERM to the following process trees:\n"
<< stringify(trees.get()) << endl;
}
@@ -538,7 +563,6 @@ protected:
private:
void reaped(
ExecutorDriver* driver,
- const TaskID& taskId,
pid_t pid,
const Future<Option<int> >& status_)
{
@@ -574,8 +598,10 @@ private:
cout << message << " (pid: " << pid << ")" << endl;
+ CHECK_SOME(taskId);
+
TaskStatus taskStatus;
- taskStatus.mutable_task_id()->MergeFrom(taskId);
+ taskStatus.mutable_task_id()->MergeFrom(taskId.get());
taskStatus.set_state(taskState);
taskStatus.set_message(message);
if (killed && killedByHealthCheck) {
@@ -671,6 +697,8 @@ private:
Duration escalationTimeout;
Timer escalationTimer;
Option<ExecutorDriver*> driver;
+ Option<FrameworkInfo> frameworkInfo;
+ Option<TaskID> taskId;
string healthCheckDir;
Option<char**> override;
Option<string> sandboxDirectory;
[11/11] mesos git commit: Added TASK_KILLING to the API changes in
the CHANGELOG.
Posted by bm...@apache.org.
Added TASK_KILLING to the API changes in the CHANGELOG.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1488f16d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1488f16d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1488f16d
Branch: refs/heads/master
Commit: 1488f16d283f69b7dc96feaee91b04a09012ca4a
Parents: 978ccb5
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 17:35:30 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 17:35:30 2016 +0100
----------------------------------------------------------------------
CHANGELOG | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/1488f16d/CHANGELOG
----------------------------------------------------------------------
diff --git a/CHANGELOG b/CHANGELOG
index 004978f..e6cc39b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@ Release Notes - Mesos - Version 0.28.0 (WIP)
** API Changes:
* [MESOS-4066] - Agent should not return partial state when a request is made to /state endpoint during recovery.
* [MESOS-4479] - Implement reservation labels.
+ * [MESOS-4547] - Introduce TASK_KILLING state.
Release Notes - Mesos - Version 0.27.1
[03/11] mesos git commit: Minor cleanup for TaskState comments.
Posted by bm...@apache.org.
Minor cleanup for TaskState comments.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/de4094da
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/de4094da
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/de4094da
Branch: refs/heads/master
Commit: de4094daa141d24691b81a2c41eef67ceee8d661
Parents: 1bd0663
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 13:06:03 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 14:22:19 2016 +0100
----------------------------------------------------------------------
include/mesos/mesos.proto | 12 ++++++------
include/mesos/v1/mesos.proto | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/de4094da/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 5078da4..debc59d 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1215,7 +1215,7 @@ message TaskInfo {
* another task).
*/
enum TaskState {
- TASK_STAGING = 6; // Initial state. Framework status updates should not use.
+ TASK_STAGING = 6; // Initial state. Framework status updates should not use.
TASK_STARTING = 0; // The task is being launched by the executor.
TASK_RUNNING = 1;
@@ -1223,11 +1223,11 @@ enum TaskState {
// the TASK_KILLING_STATE capability.
TASK_KILLING = 8; // The task is being killed by the executor.
- 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.
+ 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.
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/de4094da/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index a1da4a0..61c3d94 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1116,7 +1116,7 @@ message TaskInfo {
* another task).
*/
enum TaskState {
- TASK_STAGING = 6; // Initial state. Framework status updates should not use.
+ TASK_STAGING = 6; // Initial state. Framework status updates should not use.
TASK_STARTING = 0; // The task is being launched by the executor.
TASK_RUNNING = 1;
@@ -1124,11 +1124,11 @@ enum TaskState {
// the TASK_KILLING_STATE capability.
TASK_KILLING = 8; // The task is being killed by the executor.
- 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.
+ 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.
}
[02/11] mesos git commit: Added a comment to explain TASK_STARTING.
Posted by bm...@apache.org.
Added a comment to explain TASK_STARTING.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1bd06637
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1bd06637
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1bd06637
Branch: refs/heads/master
Commit: 1bd06637cf75068006df72b4e8bc5433b8e6090c
Parents: 022be0a
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 13:04:52 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 14:18:35 2016 +0100
----------------------------------------------------------------------
include/mesos/mesos.proto | 2 +-
include/mesos/v1/mesos.proto | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/1bd06637/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 70e380a..5078da4 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1216,7 +1216,7 @@ message TaskInfo {
*/
enum TaskState {
TASK_STAGING = 6; // Initial state. Framework status updates should not use.
- TASK_STARTING = 0;
+ TASK_STARTING = 0; // The task is being launched by the executor.
TASK_RUNNING = 1;
// NOTE: This should only be sent when the framework has
http://git-wip-us.apache.org/repos/asf/mesos/blob/1bd06637/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index 6271d2a..a1da4a0 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1117,7 +1117,7 @@ message TaskInfo {
*/
enum TaskState {
TASK_STAGING = 6; // Initial state. Framework status updates should not use.
- TASK_STARTING = 0;
+ TASK_STARTING = 0; // The task is being launched by the executor.
TASK_RUNNING = 1;
// NOTE: This should only be sent when the framework has
[06/11] mesos git commit: Added missing assertions to
MasterTest.StateEndpointFrameworkInfo.
Posted by bm...@apache.org.
Added missing assertions to MasterTest.StateEndpointFrameworkInfo.
The MasterTest.StateEndpointFrameworkInfo test can crash when the
assumed JSON types do not hold. Rather, we should assert the type
before using JSON::Value::as, so that the test fails rather than
crashing the program.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c893c9f8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c893c9f8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c893c9f8
Branch: refs/heads/master
Commit: c893c9f8e7fd9fb3f1668e0f065318b8196c0f7e
Parents: a99a205
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 14:00:23 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 17:32:23 2016 +0100
----------------------------------------------------------------------
src/tests/master_tests.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/c893c9f8/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 7cf04a2..0bd8c0e 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -2948,13 +2948,14 @@ TEST_F(MasterTest, StateEndpointFrameworkInfo)
JSON::Array frameworks = object->values["frameworks"].as<JSON::Array>();
EXPECT_EQ(1u, frameworks.values.size());
+ ASSERT_TRUE(frameworks.values.front().is<JSON::Object>());
+
JSON::Object framework = frameworks.values.front().as<JSON::Object>();
EXPECT_EQ(1u, framework.values.count("webui_url"));
- JSON::String webui_url =
- framework.values["webui_url"].as<JSON::String>();
-
- EXPECT_EQ("http://localhost:8080/", webui_url.value);
+ ASSERT_TRUE(framework.values["webui_url"].is<JSON::String>());
+ EXPECT_EQ("http://localhost:8080/",
+ framework.values["webui_url"].as<JSON::String>().value);
EXPECT_EQ(1u, framework.values.count("capabilities"));
ASSERT_TRUE(framework.values["capabilities"].is<JSON::Array>());
[05/11] mesos git commit: Added a framework capability to guard
TASK_KILLING.
Posted by bm...@apache.org.
Added a framework capability to guard TASK_KILLING.
Frameworks must opt-in to receive TASK_KILLING. For now, it will be
entirely the responsibility of the executor to check the capability
before sending a TASK_KILLING update.
Review: https://reviews.apache.org/r/43488/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/cae9162a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/cae9162a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/cae9162a
Branch: refs/heads/master
Commit: cae9162a198a4a298fee920c57dbd128731529e2
Parents: de4094d
Author: Abhishek Dasgupta <a1...@linux.vnet.ibm.com>
Authored: Sat Feb 20 13:09:16 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 14:22:20 2016 +0100
----------------------------------------------------------------------
include/mesos/mesos.proto | 5 +++++
include/mesos/v1/mesos.proto | 5 +++++
src/tests/master_tests.cpp | 33 ++++++++++++++++++++++++++-------
3 files changed, 36 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/cae9162a/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index debc59d..11a71cb 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -262,6 +262,11 @@ message FrameworkInfo {
// message for details.
// TODO(vinod): This is currently a no-op.
REVOCABLE_RESOURCES = 1;
+
+ // Receive the TASK_KILLING TaskState when a task is being
+ // killed by an executor. The executor will examine this
+ // capability to determine whether it can send TASK_KILLING.
+ TASK_KILLING_STATE = 2;
}
required Type type = 1;
http://git-wip-us.apache.org/repos/asf/mesos/blob/cae9162a/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index 61c3d94..84e933e 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -262,6 +262,11 @@ message FrameworkInfo {
// message for details.
// TODO(vinod): This is currently a no-op.
REVOCABLE_RESOURCES = 1;
+
+ // Receive the TASK_KILLING TaskState when a task is being
+ // killed by an executor. The executor will examine this
+ // capability to determine whether it can send TASK_KILLING.
+ TASK_KILLING_STATE = 2;
}
required Type type = 1;
http://git-wip-us.apache.org/repos/asf/mesos/blob/cae9162a/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 393a6f5f..01b82df 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -3016,8 +3016,15 @@ TEST_F(MasterTest, FrameworkWebUIUrlandCapabilities)
FrameworkInfo framework = DEFAULT_FRAMEWORK_INFO;
framework.set_webui_url("http://localhost:8080/");
- auto capabilityType = FrameworkInfo::Capability::REVOCABLE_RESOURCES;
- framework.add_capabilities()->set_type(capabilityType);
+
+ vector<FrameworkInfo::Capability::Type> capabilities = {
+ FrameworkInfo::Capability::REVOCABLE_RESOURCES,
+ FrameworkInfo::Capability::TASK_KILLING_STATE
+ };
+
+ foreach (FrameworkInfo::Capability::Type capability, capabilities) {
+ framework.add_capabilities()->set_type(capability);
+ }
MockScheduler sched;
MesosSchedulerDriver driver(
@@ -3054,12 +3061,24 @@ TEST_F(MasterTest, FrameworkWebUIUrlandCapabilities)
EXPECT_EQ("http://localhost:8080/", webui_url.value);
EXPECT_EQ(1u, framework_.values.count("capabilities"));
- JSON::Array capabilities =
- framework_.values["capabilities"].as<JSON::Array>();
- JSON::String capability = capabilities.values.front().as<JSON::String>();
+ ASSERT_TRUE(framework_.values["capabilities"].is<JSON::Array>());
+
+ vector<FrameworkInfo::Capability::Type> actual;
+
+ foreach (const JSON::Value& capability,
+ framework_.values["capabilities"].as<JSON::Array>().values) {
+ FrameworkInfo::Capability::Type type;
+
+ ASSERT_TRUE(capability.is<JSON::String>());
+ ASSERT_TRUE(
+ FrameworkInfo::Capability::Type_Parse(
+ capability.as<JSON::String>().value,
+ &type));
+
+ actual.push_back(type);
+ }
- EXPECT_EQ(FrameworkInfo::Capability::Type_Name(capabilityType),
- capability.value);
+ EXPECT_EQ(capabilities, actual);
driver.stop();
driver.join();
[04/11] mesos git commit: Generalization and cleanup of
MasterTest.FrameworkWebUIUrlandCapabilities.
Posted by bm...@apache.org.
Generalization and cleanup of MasterTest.FrameworkWebUIUrlandCapabilities.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a99a2059
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a99a2059
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a99a2059
Branch: refs/heads/master
Commit: a99a2059689537f0af3bc4746f1ffda1572910e1
Parents: cae9162
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 13:56:31 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 14:22:20 2016 +0100
----------------------------------------------------------------------
src/tests/master_tests.cpp | 160 ++++++++++++++++++++--------------------
1 file changed, 79 insertions(+), 81 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a99a2059/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 01b82df..7cf04a2 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -2904,6 +2904,85 @@ TEST_F(MasterTest, StateEndpoint)
}
+// This test ensures that the framework's information is included in
+// the master's state endpoint.
+//
+// TODO(bmahler): This only looks at capabilities and the webui URL
+// currently; add more to this test.
+TEST_F(MasterTest, StateEndpointFrameworkInfo)
+{
+ Try<PID<Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+ frameworkInfo.set_webui_url("http://localhost:8080/");
+
+ vector<FrameworkInfo::Capability::Type> capabilities = {
+ FrameworkInfo::Capability::REVOCABLE_RESOURCES,
+ FrameworkInfo::Capability::TASK_KILLING_STATE
+ };
+
+ foreach (FrameworkInfo::Capability::Type capability, capabilities) {
+ frameworkInfo.add_capabilities()->set_type(capability);
+ }
+
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, frameworkInfo, master.get(), DEFAULT_CREDENTIAL);
+
+ Future<Nothing> registered;
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .WillOnce(FutureSatisfy(®istered));
+
+ driver.start();
+
+ AWAIT_READY(registered);
+
+ Future<Response> response = process::http::get(master.get(), "state");
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+
+ Try<JSON::Object> object = JSON::parse<JSON::Object>(response->body);
+ ASSERT_SOME(object);
+
+ EXPECT_EQ(1u, object->values.count("frameworks"));
+ JSON::Array frameworks = object->values["frameworks"].as<JSON::Array>();
+
+ EXPECT_EQ(1u, frameworks.values.size());
+ JSON::Object framework = frameworks.values.front().as<JSON::Object>();
+
+ EXPECT_EQ(1u, framework.values.count("webui_url"));
+ JSON::String webui_url =
+ framework.values["webui_url"].as<JSON::String>();
+
+ EXPECT_EQ("http://localhost:8080/", webui_url.value);
+
+ EXPECT_EQ(1u, framework.values.count("capabilities"));
+ ASSERT_TRUE(framework.values["capabilities"].is<JSON::Array>());
+
+ vector<FrameworkInfo::Capability::Type> actual;
+
+ foreach (const JSON::Value& capability,
+ framework.values["capabilities"].as<JSON::Array>().values) {
+ FrameworkInfo::Capability::Type type;
+
+ ASSERT_TRUE(capability.is<JSON::String>());
+ ASSERT_TRUE(
+ FrameworkInfo::Capability::Type_Parse(
+ capability.as<JSON::String>().value,
+ &type));
+
+ actual.push_back(type);
+ }
+
+ EXPECT_EQ(capabilities, actual);
+
+ driver.stop();
+ driver.join();
+
+ Shutdown();
+}
+
+
TEST_F(MasterTest, StateSummaryEndpoint)
{
master::Flags flags = CreateMasterFlags();
@@ -3006,87 +3085,6 @@ TEST_F(MasterTest, StateSummaryEndpoint)
}
-// This test ensures that the web UI and capabilities of a framework
-// are included in the master's state endpoint, if provided by the
-// framework.
-TEST_F(MasterTest, FrameworkWebUIUrlandCapabilities)
-{
- Try<PID<Master>> master = StartMaster();
- ASSERT_SOME(master);
-
- FrameworkInfo framework = DEFAULT_FRAMEWORK_INFO;
- framework.set_webui_url("http://localhost:8080/");
-
- vector<FrameworkInfo::Capability::Type> capabilities = {
- FrameworkInfo::Capability::REVOCABLE_RESOURCES,
- FrameworkInfo::Capability::TASK_KILLING_STATE
- };
-
- foreach (FrameworkInfo::Capability::Type capability, capabilities) {
- framework.add_capabilities()->set_type(capability);
- }
-
- MockScheduler sched;
- MesosSchedulerDriver driver(
- &sched, framework, master.get(), DEFAULT_CREDENTIAL);
-
- Future<Nothing> registered;
- EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureSatisfy(®istered));
-
- driver.start();
-
- AWAIT_READY(registered);
-
- Future<Response> masterState = process::http::get(master.get(), "state");
- AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, masterState);
-
- Try<JSON::Object> parse = JSON::parse<JSON::Object>(masterState.get().body);
- ASSERT_SOME(parse);
-
- // We need a mutable copy of parse to use [].
- JSON::Object masterStateObject = parse.get();
-
- EXPECT_EQ(1u, masterStateObject.values.count("frameworks"));
- JSON::Array frameworks =
- masterStateObject.values["frameworks"].as<JSON::Array>();
-
- EXPECT_EQ(1u, frameworks.values.size());
- JSON::Object framework_ = frameworks.values.front().as<JSON::Object>();
-
- EXPECT_EQ(1u, framework_.values.count("webui_url"));
- JSON::String webui_url =
- framework_.values["webui_url"].as<JSON::String>();
-
- EXPECT_EQ("http://localhost:8080/", webui_url.value);
-
- EXPECT_EQ(1u, framework_.values.count("capabilities"));
- ASSERT_TRUE(framework_.values["capabilities"].is<JSON::Array>());
-
- vector<FrameworkInfo::Capability::Type> actual;
-
- foreach (const JSON::Value& capability,
- framework_.values["capabilities"].as<JSON::Array>().values) {
- FrameworkInfo::Capability::Type type;
-
- ASSERT_TRUE(capability.is<JSON::String>());
- ASSERT_TRUE(
- FrameworkInfo::Capability::Type_Parse(
- capability.as<JSON::String>().value,
- &type));
-
- actual.push_back(type);
- }
-
- EXPECT_EQ(capabilities, actual);
-
- driver.stop();
- driver.join();
-
- Shutdown();
-}
-
-
// This test verifies that label values are exposed over the master's
// state endpoint.
TEST_F(MasterTest, TaskLabels)
[08/11] mesos git commit: Added docker executor tests for
TASK_KILLING.
Posted by bm...@apache.org.
Added docker executor tests for TASK_KILLING.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/978ccb5d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/978ccb5d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/978ccb5d
Branch: refs/heads/master
Commit: 978ccb5dd637f0e1577ecae1e21973f50429b04c
Parents: ee86b13
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 17:28:58 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 17:32:26 2016 +0100
----------------------------------------------------------------------
.../docker_containerizer_tests.cpp | 128 +++++++++++++++++++
1 file changed, 128 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/978ccb5d/src/tests/containerizer/docker_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/docker_containerizer_tests.cpp b/src/tests/containerizer/docker_containerizer_tests.cpp
index 2b96e41..a299c9e 100644
--- a/src/tests/containerizer/docker_containerizer_tests.cpp
+++ b/src/tests/containerizer/docker_containerizer_tests.cpp
@@ -670,6 +670,134 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Kill)
}
+// Ensures that the framework will receive a TASK_KILLING update
+// before TASK_KILLED, if the capability is supported.
+TEST_F(DockerContainerizerTest, ROOT_DOCKER_TaskKillingCapability)
+{
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ MockDocker* mockDocker =
+ new MockDocker(tests::flags.docker, tests::flags.docker_socket);
+
+ Shared<Docker> docker(mockDocker);
+
+ slave::Flags flags = CreateSlaveFlags();
+
+ Fetcher fetcher;
+
+ Try<ContainerLogger*> logger =
+ ContainerLogger::create(flags.container_logger);
+
+ ASSERT_SOME(logger);
+
+ MockDockerContainerizer dockerContainerizer(
+ flags,
+ &fetcher,
+ Owned<ContainerLogger>(logger.get()),
+ docker);
+
+ Try<PID<Slave> > slave = StartSlave(&dockerContainerizer, flags);
+ ASSERT_SOME(slave);
+
+ // Start the framework with the task killing capability.
+ FrameworkInfo::Capability capability;
+ capability.set_type(FrameworkInfo::Capability::TASK_KILLING_STATE);
+
+ FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+ frameworkInfo.add_capabilities()->CopyFrom(capability);
+
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, frameworkInfo, master.get(), DEFAULT_CREDENTIAL);
+
+ Future<FrameworkID> frameworkId;
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .WillOnce(FutureArg<1>(&frameworkId));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ AWAIT_READY(frameworkId);
+
+ AWAIT_READY(offers);
+ ASSERT_NE(0u, offers.get().size());
+
+ const Offer& offer = offers.get()[0];
+
+ SlaveID slaveId = offer.slave_id();
+
+ TaskInfo task;
+ task.set_name("");
+ task.mutable_task_id()->set_value("1");
+ task.mutable_slave_id()->CopyFrom(offer.slave_id());
+ task.mutable_resources()->CopyFrom(offer.resources());
+
+ CommandInfo command;
+ command.set_value("sleep 1000");
+
+ ContainerInfo containerInfo;
+ containerInfo.set_type(ContainerInfo::DOCKER);
+
+ // TODO(tnachen): Use local image to test if possible.
+ ContainerInfo::DockerInfo dockerInfo;
+ dockerInfo.set_image("alpine");
+ containerInfo.mutable_docker()->CopyFrom(dockerInfo);
+
+ task.mutable_command()->CopyFrom(command);
+ task.mutable_container()->CopyFrom(containerInfo);
+
+ Future<ContainerID> containerId;
+ EXPECT_CALL(dockerContainerizer, launch(_, _, _, _, _, _, _, _))
+ .WillOnce(DoAll(FutureArg<0>(&containerId),
+ Invoke(&dockerContainerizer,
+ &MockDockerContainerizer::_launch)));
+
+ Future<TaskStatus> statusRunning;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&statusRunning));
+
+ driver.launchTasks(offers.get()[0].id(), {task});
+
+ AWAIT_READY_FOR(containerId, Seconds(60));
+ AWAIT_READY_FOR(statusRunning, Seconds(60));
+ EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+ ASSERT_TRUE(
+ exists(docker, slaveId, containerId.get(), ContainerState::RUNNING));
+
+ Future<TaskStatus> statusKilling, statusKilled;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&statusKilling))
+ .WillOnce(FutureArg<1>(&statusKilled));
+
+ Future<containerizer::Termination> termination =
+ dockerContainerizer.wait(containerId.get());
+
+ driver.killTask(task.task_id());
+
+ AWAIT_READY(statusKilling);
+ EXPECT_EQ(TASK_KILLING, statusKilling->state());
+
+ AWAIT_READY(statusKilled);
+ EXPECT_EQ(TASK_KILLED, statusKilled->state());
+
+ AWAIT_READY(termination);
+
+ ASSERT_FALSE(
+ exists(docker, slaveId, containerId.get(), ContainerState::RUNNING));
+
+ driver.stop();
+ driver.join();
+
+ Shutdown();
+}
+
+
// This test tests DockerContainerizer::usage().
TEST_F(DockerContainerizerTest, ROOT_DOCKER_Usage)
{
[07/11] mesos git commit: Added command executor tests for
TASK_KILLING.
Posted by bm...@apache.org.
Added command executor tests for TASK_KILLING.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ee86b136
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ee86b136
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ee86b136
Branch: refs/heads/master
Commit: ee86b13633a9469629dbd79681d0776b6020f76a
Parents: 25d303d
Author: Benjamin Mahler <bm...@apache.org>
Authored: Sat Feb 20 16:18:22 2016 +0100
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Feb 20 17:32:26 2016 +0100
----------------------------------------------------------------------
src/Makefile.am | 1 +
src/tests/command_executor_tests.cpp | 180 ++++++++++++++++++++++++++++++
2 files changed, 181 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/ee86b136/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 27aec37..73e7ff0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1803,6 +1803,7 @@ mesos_tests_SOURCES = \
tests/authentication_tests.cpp \
tests/authorization_tests.cpp \
tests/cluster.cpp \
+ tests/command_executor_tests.cpp \
tests/container_logger_tests.cpp \
tests/containerizer.cpp \
tests/cram_md5_authentication_tests.cpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/ee86b136/src/tests/command_executor_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/command_executor_tests.cpp b/src/tests/command_executor_tests.cpp
new file mode 100644
index 0000000..0d2fcf6
--- /dev/null
+++ b/src/tests/command_executor_tests.cpp
@@ -0,0 +1,180 @@
+// 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.
+
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <mesos/mesos.hpp>
+
+#include <process/future.hpp>
+#include <process/gmock.hpp>
+#include <process/gtest.hpp>
+#include <process/pid.hpp>
+
+#include <stout/gtest.hpp>
+
+#include "master/master.hpp"
+
+#include "slave/slave.hpp"
+
+#include "tests/mesos.hpp"
+
+using mesos::internal::master::Master;
+
+using mesos::internal::slave::Slave;
+
+using process::Future;
+using process::PID;
+
+using std::vector;
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+// Tests that exercise the command executor implementation
+// should be located in this file.
+
+class CommandExecutorTest : public MesosTest {};
+
+
+// This test ensures that the command executor does not send
+// TASK_KILLING to frameworks that do not support the capability.
+TEST_F(CommandExecutorTest, NoTaskKillingCapability)
+{
+ Try<PID<Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave>> slave = StartSlave();
+ ASSERT_SOME(slave);
+
+ // Start the framework without the task killing capability.
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+
+ EXPECT_CALL(sched, registered(&driver, _, _));
+
+ Future<vector<Offer>> offers;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ AWAIT_READY(offers);
+ EXPECT_EQ(1u, offers->size());
+
+ // Launch a task with the command executor.
+ TaskInfo task = createTask(
+ offers->front().slave_id(),
+ offers->front().resources(),
+ "sleep 1000");
+
+ Future<TaskStatus> statusRunning;
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillOnce(FutureArg<1>(&statusRunning));
+
+ driver.launchTasks(offers->front().id(), {task});
+
+ AWAIT_READY(statusRunning);
+ EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+ // There should only be a TASK_KILLED update.
+ Future<TaskStatus> statusKilled;
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillOnce(FutureArg<1>(&statusKilled));
+
+ driver.killTask(task.task_id());
+
+ AWAIT_READY(statusKilled);
+ EXPECT_EQ(TASK_KILLED, statusKilled->state());
+
+ driver.stop();
+ driver.join();
+}
+
+
+// This test ensures that the command executor sends TASK_KILLING
+// to frameworks that support the capability.
+TEST_F(CommandExecutorTest, TaskKillingCapability)
+{
+ Try<PID<Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave>> slave = StartSlave();
+ ASSERT_SOME(slave);
+
+ // Start the framework with the task killing capability.
+ FrameworkInfo::Capability capability;
+ capability.set_type(FrameworkInfo::Capability::TASK_KILLING_STATE);
+
+ FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+ frameworkInfo.add_capabilities()->CopyFrom(capability);
+
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, frameworkInfo, master.get(), DEFAULT_CREDENTIAL);
+
+ EXPECT_CALL(sched, registered(&driver, _, _));
+
+ Future<vector<Offer>> offers;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ AWAIT_READY(offers);
+ EXPECT_EQ(1u, offers->size());
+
+ // Launch a task with the command executor.
+ TaskInfo task = createTask(
+ offers->front().slave_id(),
+ offers->front().resources(),
+ "sleep 1000");
+
+ Future<TaskStatus> statusRunning;
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillOnce(FutureArg<1>(&statusRunning));
+
+ driver.launchTasks(offers->front().id(), {task});
+
+ AWAIT_READY(statusRunning);
+ EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+ Future<TaskStatus> statusKilling, statusKilled;
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillOnce(FutureArg<1>(&statusKilling))
+ .WillOnce(FutureArg<1>(&statusKilled));
+
+ driver.killTask(task.task_id());
+
+ AWAIT_READY(statusKilling);
+ EXPECT_EQ(TASK_KILLING, statusKilling->state());
+
+ AWAIT_READY(statusKilled);
+ EXPECT_EQ(TASK_KILLED, statusKilled->state());
+
+ driver.stop();
+ driver.join();
+}
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {