Refactored `Slave::Http::launchNestedContainer()`.

This so that code can be reused for `launchNestedContainerSession()`
that will be added later. No functional change.

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


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

Branch: refs/heads/master
Commit: e9c89abf9ff4d7c8b6b73d687d7248d738b9ac10
Parents: 16765a3
Author: Vinod Kone <vinodk...@gmail.com>
Authored: Sun Nov 20 16:07:31 2016 +0800
Committer: Vinod Kone <vinodk...@gmail.com>
Committed: Thu Dec 1 21:54:28 2016 -0800

----------------------------------------------------------------------
 src/slave/http.cpp  | 176 +++++++++++++++++++++++++----------------------
 src/slave/slave.hpp |   7 ++
 2 files changed, 100 insertions(+), 83 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/e9c89abf/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index 029eead..5c300be 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -2030,100 +2030,110 @@ Future<Response> Slave::Http::launchNestedContainer(
     approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
   }
 
-  return approver.then(defer(slave->self(),
-    [this, call, contentType](const Owned<ObjectApprover>& launchApprover)
-        -> Future<Response> {
-      const ContainerID& containerId =
-        call.launch_nested_container().container_id();
-
-      // We do not yet support launching containers that are nested
-      // two levels beneath the executor's container.
-      if (containerId.parent().has_parent()) {
-        return NotImplemented(
-            "Only a single level of container nesting is supported currently,"
-            " but 'launch_nested_container.container_id.parent.parent' is 
set");
-      }
+  return approver
+    .then(defer(slave->self(), [=](const Owned<ObjectApprover>& approver) {
+      return _launchNestedContainer(
+          call.launch_nested_container().container_id(),
+          call.launch_nested_container().command(),
+          call.launch_nested_container().has_container()
+            ? call.launch_nested_container().container()
+            : Option<ContainerInfo>::none(),
+          acceptType,
+          approver);
+    }));
+}
 
-      // Locate the executor (for now we just loop since we don't
-      // index based on container id and this likely won't have a
-      // significant performance impact due to the low number of
-      // executors per-agent).
-      // TODO(adam-mesos): Support more levels of nesting.
-      Executor* executor = nullptr;
-      Framework* framework = nullptr;
-      foreachvalue (Framework* framework_, slave->frameworks) {
-        foreachvalue (Executor* executor_, framework_->executors) {
-          if (executor_->containerId == containerId.parent()) {
-            framework = framework_;
-            executor = executor_;
-            break;
-          }
-        }
-      }
 
-      // Return a "Bad Request" here rather than "Not Found" since
-      // the executor needs to set parent to its container id.
-      if (executor == nullptr || framework == nullptr) {
-        return BadRequest("Unable to locate executor for parent container"
-                          " " + stringify(containerId.parent()));
-      }
+Future<Response> Slave::Http::_launchNestedContainer(
+    const ContainerID& containerId,
+    const CommandInfo& commandInfo,
+    const Option<ContainerInfo>& containerInfo,
+    ContentType acceptType,
+    const Owned<ObjectApprover>& approver) const
+{
+  // We do not yet support launching containers that are nested
+  // two levels beneath the executor's container.
+  if (containerId.parent().has_parent()) {
+    return NotImplemented(
+        "Only a single level of container nesting is supported currently,"
+        " but 'launch_nested_container.container_id.parent.parent' is set");
+  }
 
-      ObjectApprover::Object object;
-      object.executor_info = &(executor->info);
-      object.framework_info = &(framework->info);
-      if (call.launch_nested_container().has_command()) {
-        object.command_info = &(call.launch_nested_container().command());
+  // Locate the executor (for now we just loop since we don't
+  // index based on container id and this likely won't have a
+  // significant performance impact due to the low number of
+  // executors per-agent).
+  // TODO(adam-mesos): Support more levels of nesting.
+  Executor* executor = nullptr;
+  Framework* framework = nullptr;
+  foreachvalue (Framework* framework_, slave->frameworks) {
+    foreachvalue (Executor* executor_, framework_->executors) {
+      if (executor_->containerId == containerId.parent()) {
+        framework = framework_;
+        executor = executor_;
+        break;
       }
+    }
+  }
 
-      Try<bool> approved = launchApprover.get()->approved(object);
+  // Return a "Bad Request" here rather than "Not Found" since
+  // the executor needs to set parent to its container id.
+  if (executor == nullptr || framework == nullptr) {
+    return BadRequest("Unable to locate executor for parent container"
+                      " " + stringify(containerId.parent()));
+  }
 
-      if (approved.isError()) {
-        return Failure(approved.error());
-      } else if (!approved.get()) {
-        return Forbidden();
-      }
+  ObjectApprover::Object object;
+  object.executor_info = &(executor->info);
+  object.framework_info = &(framework->info);
+  object.command_info = &(commandInfo);
 
-      // By default, we use the executor's user.
-      // The command user overrides it if specified.
-      Option<string> user = executor->user;
+  Try<bool> approved = approver.get()->approved(object);
+
+  if (approved.isError()) {
+    return Failure(approved.error());
+  } else if (!approved.get()) {
+    return Forbidden();
+  }
+
+  // By default, we use the executor's user.
+  // The command user overrides it if specified.
+  Option<string> user = executor->user;
 
 #ifndef __WINDOWS__
-      if (call.launch_nested_container().command().has_user()) {
-        user = call.launch_nested_container().command().user();
-      }
+  if (commandInfo.has_user()) {
+    user = commandInfo.user();
+  }
 #endif
 
-      Future<bool> launched = slave->containerizer->launch(
-          containerId,
-          call.launch_nested_container().command(),
-          call.launch_nested_container().has_container()
-            ? call.launch_nested_container().container()
-            : Option<ContainerInfo>::none(),
-          user,
-          slave->info.id());
-
-      // TODO(bmahler): The containerizers currently require that
-      // the caller calls destroy if the launch fails. See MESOS-6214.
-      launched
-        .onFailed(defer(slave->self(), [=](const string& failure) {
-          LOG(WARNING) << "Failed to launch nested container " << containerId
-                       << ": " << failure;
-
-          slave->containerizer->destroy(containerId)
-            .onFailed([=](const string& failure) {
-              LOG(ERROR) << "Failed to destroy nested container "
-                         << containerId << " after launch failure: " << 
failure;
-            });
-        }));
-
-      return launched
-        .then([](bool launched) -> Response {
-          if (!launched) {
-            return BadRequest("The provided ContainerInfo is not supported");
-          }
-          return OK();
-          });
+  Future<bool> launched = slave->containerizer->launch(
+      containerId,
+      commandInfo,
+      containerInfo,
+      user,
+      slave->info.id());
+
+  // TODO(bmahler): The containerizers currently require that
+  // the caller calls destroy if the launch fails. See MESOS-6214.
+  launched
+    .onFailed(defer(slave->self(), [=](const string& failure) {
+      LOG(WARNING) << "Failed to launch nested container " << containerId
+                   << ": " << failure;
+
+      slave->containerizer->destroy(containerId)
+        .onFailed([=](const string& failure) {
+          LOG(ERROR) << "Failed to destroy nested container "
+                     << containerId << " after launch failure: " << failure;
+        });
     }));
+
+  return launched
+    .then([](bool launched) -> Response {
+      if (!launched) {
+        return BadRequest("The provided ContainerInfo is not supported");
+      }
+      return OK();
+    });
 }
 
 
@@ -2241,7 +2251,7 @@ Future<Response> Slave::Http::killNestedContainer(
   }
 
   return approver.then(defer(slave->self(),
-    [this, call, contentType](const Owned<ObjectApprover>& killApprover)
+    [this, call](const Owned<ObjectApprover>& killApprover)
         -> Future<Response> {
       const ContainerID& containerId =
         call.kill_nested_container().container_id();

http://git-wip-us.apache.org/repos/asf/mesos/blob/e9c89abf/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index 0d0e990..dacdbcf 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -640,6 +640,13 @@ private:
         ContentType acceptType,
         const Option<std::string>& principal) const;
 
+    process::Future<process::http::Response> _launchNestedContainer(
+        const ContainerID& containerId,
+        const CommandInfo& commandInfo,
+        const Option<ContainerInfo>& containerInfo,
+        ContentType acceptType,
+        const Owned<ObjectApprover>& approver) const;
+
     process::Future<process::http::Response> waitNestedContainer(
         const mesos::agent::Call& call,
         ContentType acceptType,

Reply via email to