This is an automated email from the ASF dual-hosted git repository. bbannier pushed a commit to branch 1.7.x in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 989ccb5c04c25dfde2d9c530cc84218268c403a6 Author: Benjamin Bannier <[email protected]> AuthorDate: Thu Jan 23 14:19:51 2020 +0100 Sync'd whether an executor was generated to and from disk. This patch introduces an `ExecutorState` variable signifying whether an executor was generated by the agent (and is thus unknown to the master). Currently we still detect agent-generated executors with a heuristic, but will adapt that heuristic in a follow-up path making us of the additional state we now persist. Review: https://reviews.apache.org/r/72034/ --- src/slave/paths.cpp | 15 +++++++++++++++ src/slave/paths.hpp | 7 +++++++ src/slave/slave.cpp | 10 ++++++++++ src/slave/state.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/slave/state.hpp | 1 + 5 files changed, 72 insertions(+) diff --git a/src/slave/paths.cpp b/src/slave/paths.cpp index dc1003b..414a5aa 100644 --- a/src/slave/paths.cpp +++ b/src/slave/paths.cpp @@ -297,6 +297,21 @@ string getExecutorRunPath( } +string getExecutorGeneratedForCommandTaskPath( + const string& rootDir, + const SlaveID& slaveId, + const FrameworkID& frameworkId, + const ExecutorID& executorId) +{ + constexpr char EXECUTOR_GENERATED_FOR_COMMAND_TASK_PATH[] = + "executor_generated_for_command_task"; + + return path::join( + getExecutorPath(rootDir, slaveId, frameworkId, executorId), + EXECUTOR_GENERATED_FOR_COMMAND_TASK_PATH); +} + + string getExecutorHttpMarkerPath( const string& rootDir, const SlaveID& slaveId, diff --git a/src/slave/paths.hpp b/src/slave/paths.hpp index 0158964..5e8cc29 100644 --- a/src/slave/paths.hpp +++ b/src/slave/paths.hpp @@ -232,6 +232,13 @@ std::string getExecutorRunPath( const ContainerID& containerId); +std::string getExecutorGeneratedForCommandTaskPath( + const std::string& rootDir, + const SlaveID& slaveId, + const FrameworkID& frameworkId, + const ExecutorID& executorId); + + std::string getExecutorHttpMarkerPath( const std::string& rootDir, const SlaveID& slaveId, diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp index 5f5a0e9..d5e5924 100644 --- a/src/slave/slave.cpp +++ b/src/slave/slave.cpp @@ -9627,6 +9627,7 @@ Executor::Executor( // hacky. We rely on the fact that docker executor launch command is // set in the docker containerizer so that this check is still valid // in the slave. + // TODO(bbannier): Initialize this field with a value passed to constructor. isGeneratedForCommandTask_ = strings::endsWith(info.command().value(), MESOS_EXECUTOR) && strings::startsWith(info.name(), "Command Executor"); @@ -9777,6 +9778,15 @@ void Executor::checkpointExecutor() CHECK_SOME(state::checkpoint(path, info)); + // Sync state of sentinel indicating whether the executor was + // generated by the agent. + CHECK_SOME(state::checkpoint( + paths::getExecutorGeneratedForCommandTaskPath( + slave->metaDir, slave->info.id(), frameworkId, id), + stringify(static_cast<int>(isGeneratedForCommandTask_)), + true)); + + // Create the meta executor directory. // NOTE: This creates the 'latest' symlink in the meta directory. Try<string> mkdir = paths::createExecutorDirectory( diff --git a/src/slave/state.cpp b/src/slave/state.cpp index ae16d6f..10340a0 100644 --- a/src/slave/state.cpp +++ b/src/slave/state.cpp @@ -48,6 +48,7 @@ #include "messages/messages.hpp" +#include "slave/constants.hpp" #include "slave/paths.hpp" #include "slave/state.hpp" @@ -424,6 +425,44 @@ Try<ExecutorState> ExecutorState::recover( state.info = executorInfo.get(); + const string executorGeneratedForCommandTaskPath = + paths::getExecutorGeneratedForCommandTaskPath( + rootDir, slaveId, frameworkId, executorId); + + if (os::exists(executorGeneratedForCommandTaskPath)) { + Try<string> read = os::read(executorGeneratedForCommandTaskPath); + + if (read.isError()) { + return Error( + "Could not read '" + executorGeneratedForCommandTaskPath + "': " + + read.error()); + } + + Try<int> generatedForCommandTask = numify<int>(read.get()); + + if (generatedForCommandTask.isError()) { + return Error( + "Could not parse '" + executorGeneratedForCommandTaskPath + "': " + + generatedForCommandTask.error()); + } + + state.generatedForCommandTask = generatedForCommandTask.get(); + } else { + // If we did not find persisted information on whether this executor was + // generated by the agent, use a heuristic. + // + // TODO(bbannier): Remove this code once we do not need to support + // versions anymore which do not persist this information. + // TODO(jieyu): The way we determine if an executor is generated for + // a command task (either command or docker executor) is really + // hacky. We rely on the fact that docker executor launch command is + // set in the docker containerizer so that this check is still valid + // in the slave. + state.generatedForCommandTask = + strings::endsWith(executorInfo->command().value(), MESOS_EXECUTOR) && + strings::startsWith(executorInfo->name(), "Command Executor"); + } + return state; } diff --git a/src/slave/state.hpp b/src/slave/state.hpp index e2180ae..ce7b95b 100644 --- a/src/slave/state.hpp +++ b/src/slave/state.hpp @@ -315,6 +315,7 @@ struct ExecutorState Option<ContainerID> latest; hashmap<ContainerID, RunState> runs; unsigned int errors; + bool generatedForCommandTask = false; };
