This is an automated email from the ASF dual-hosted git repository.

bbannier pushed a commit to branch 1.6.x
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 305f2b5e88ed9256b60a02afbdad06e2333937b7
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 |  9 +++++++++
 src/slave/state.cpp | 39 +++++++++++++++++++++++++++++++++++++++
 src/slave/state.hpp |  1 +
 5 files changed, 71 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 1244c16..f195627 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -9538,6 +9538,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");
@@ -9675,6 +9676,14 @@ 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_))));
+
+
   // 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 37cd2f6..15a78db 100644
--- a/src/slave/state.hpp
+++ b/src/slave/state.hpp
@@ -307,6 +307,7 @@ struct ExecutorState
   Option<ContainerID> latest;
   hashmap<ContainerID, RunState> runs;
   unsigned int errors;
+  bool generatedForCommandTask = false;
 };
 
 

Reply via email to