Changed containerizer->launch callsites to new interface.

As part of combining the two `containerizer->launch` code paths,
callers now need to construct the `ContainerConfig` (instead of
passing some fields that are then copied into a `ContainerConfig`).

Review: https://reviews.apache.org/r/58902


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/af21bb71
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/af21bb71
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/af21bb71

Branch: refs/heads/master
Commit: af21bb71655053d223eec1595a0384fe9e26f8c7
Parents: a6a7a38
Author: Joseph Wu <josep...@apache.org>
Authored: Mon Apr 10 16:04:55 2017 -0700
Committer: Joseph Wu <josep...@apache.org>
Committed: Thu May 25 18:37:06 2017 -0700

----------------------------------------------------------------------
 src/slave/http.cpp  |  26 +++++++++---
 src/slave/slave.cpp | 101 +++++++++++++++++++++++++++++------------------
 2 files changed, 83 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/af21bb71/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index 4444a38..3160407 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -15,6 +15,7 @@
 // limitations under the License.
 
 #include <list>
+#include <map>
 #include <memory>
 #include <sstream>
 #include <string>
@@ -78,6 +79,7 @@ using mesos::authorization::createSubject;
 using mesos::internal::recordio::Reader;
 
 using mesos::slave::ContainerClass;
+using mesos::slave::ContainerConfig;
 using mesos::slave::ContainerTermination;
 
 using process::AUTHENTICATION;
@@ -116,6 +118,7 @@ using process::metrics::internal::MetricsProcess;
 using ::recordio::Decoder;
 
 using std::list;
+using std::map;
 using std::string;
 using std::tie;
 using std::tuple;
@@ -2327,13 +2330,26 @@ Future<Response> Slave::Http::_launchNestedContainer(
   }
 #endif
 
+  ContainerConfig containerConfig;
+  containerConfig.mutable_command_info()->CopyFrom(commandInfo);
+
+  if (user.isSome()) {
+    containerConfig.set_user(user.get());
+  }
+
+  if (containerInfo.isSome()) {
+    containerConfig.mutable_container_info()->CopyFrom(containerInfo.get());
+  }
+
+  if (containerClass.isSome()) {
+    containerConfig.set_container_class(containerClass.get());
+  }
+
   Future<bool> launched = slave->containerizer->launch(
       containerId,
-      commandInfo,
-      containerInfo,
-      user,
-      slave->info.id(),
-      containerClass);
+      containerConfig,
+      map<string, string>(),
+      None());
 
   // TODO(bmahler): The containerizers currently require that
   // the caller calls destroy if the launch fails. See MESOS-6214.

http://git-wip-us.apache.org/repos/asf/mesos/blob/af21bb71/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 0f21cf8..c578c52 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -117,6 +117,7 @@ using mesos::executor::Call;
 
 using mesos::master::detector::MasterDetector;
 
+using mesos::slave::ContainerConfig;
 using mesos::slave::ContainerTermination;
 using mesos::slave::QoSController;
 using mesos::slave::QoSCorrection;
@@ -2686,6 +2687,8 @@ void Slave::launchExecutor(
   }
 
   // Tell the containerizer to launch the executor.
+  // NOTE: We make a copy of the executor info because we may mutate
+  // it with some default fields and resources.
   ExecutorInfo executorInfo_ = executor->info;
 
   // Populate the command info for default executor. We modify the ExecutorInfo
@@ -2711,6 +2714,41 @@ void Slave::launchExecutor(
 
   executorInfo_.mutable_resources()->CopyFrom(resources);
 
+  // Add the default container info to the executor info.
+  // TODO(jieyu): Rename the flag to be default_mesos_container_info.
+  if (!executorInfo_.has_container() &&
+      flags.default_container_info.isSome()) {
+    executorInfo_.mutable_container()->CopyFrom(
+        flags.default_container_info.get());
+  }
+
+  // Bundle all the container launch fields together.
+  ContainerConfig containerConfig;
+  containerConfig.mutable_executor_info()->CopyFrom(executorInfo_);
+  containerConfig.mutable_command_info()->CopyFrom(executorInfo_.command());
+  containerConfig.mutable_resources()->CopyFrom(executorInfo_.resources());
+  containerConfig.set_directory(executor->directory);
+
+  if (executor->user.isSome()) {
+    containerConfig.set_user(executor->user.get());
+  }
+
+  if (executor->isCommandExecutor()) {
+    if (taskInfo.isSome()) {
+      containerConfig.mutable_task_info()->CopyFrom(taskInfo.get());
+
+      if (taskInfo.get().has_container()) {
+        containerConfig.mutable_container_info()
+          ->CopyFrom(taskInfo.get().container());
+      }
+    }
+  } else {
+    if (executorInfo_.has_container()) {
+      containerConfig.mutable_container_info()
+        ->CopyFrom(executorInfo_.container());
+    }
+  }
+
   // Prepare environment variables for the executor.
   map<string, string> environment = executorEnvironment(
       flags,
@@ -2721,48 +2759,33 @@ void Slave::launchExecutor(
       authenticationToken,
       framework->info.checkpoint());
 
-  // Launch the container.
-  Future<bool> launch;
-  if (!executor->isCommandExecutor()) {
-    // If the executor is _not_ a command executor, this means that
-    // the task will include the executor to run. The actual task to
-    // run will be enqueued and subsequently handled by the executor
-    // when it has registered to the slave.
-    launch = containerizer->launch(
-        executor->containerId,
-        None(),
-        executorInfo_,
-        executor->directory,
-        executor->user,
-        info.id(),
-        environment,
-        framework->info.checkpoint());
-  } else {
-    // An executor has _not_ been provided by the task and will
-    // instead define a command and/or container to run. Right now,
-    // these tasks will require an executor anyway and the slave
-    // creates a command executor. However, it is up to the
-    // containerizer how to execute those tasks and the generated
-    // executor info works as a placeholder.
-    // TODO(nnielsen): Obsolete the requirement for executors to run
-    // one-off tasks.
-    launch = containerizer->launch(
-        executor->containerId,
-        taskInfo,
-        executorInfo_,
-        executor->directory,
-        executor->user,
+  // Prepare the filename of the pidfile, for checkpoint-enabled frameworks.
+  Option<string> pidCheckpointPath = None();
+  if (framework->info.checkpoint()){
+    pidCheckpointPath = slave::paths::getForkedPidPath(
+        slave::paths::getMetaRootDir(flags.work_dir),
         info.id(),
-        environment,
-        framework->info.checkpoint());
+        framework->id(),
+        executor->id,
+        executor->containerId);
   }
 
-  launch.onAny(defer(self(),
-                     &Self::executorLaunched,
-                     frameworkId,
-                     executor->id,
-                     executor->containerId,
-                     lambda::_1));
+  LOG(INFO) << "Launching container " << executor->containerId
+            << " for executor '" << executor->id
+            << "' of framework " << framework->id();
+
+  // Launch the container.
+  containerizer->launch(
+      executor->containerId,
+      containerConfig,
+      environment,
+      pidCheckpointPath)
+    .onAny(defer(self(),
+                 &Self::executorLaunched,
+                 frameworkId,
+                 executor->id,
+                 executor->containerId,
+                 lambda::_1));
 
   // Make sure the executor registers within the given timeout.
   delay(flags.executor_registration_timeout,

Reply via email to