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;
 };
 
 

Reply via email to