Introduced an agent API for managing nested containers.

This allows the executor to manage nested containers within its
container. This is useful for the implementation of task groups
("pod"-like containers) as well as for executors that would like
to implement isolation between sub-tasks.

This initial patch provides the ability to launch, wait, and
destroy nested containers. This was added as an agent API rather
than an executor API in order to enable operators to inject
subcontainers for future use-cases. For example, an operator
may want to inject a debugging container at run-time.

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


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

Branch: refs/heads/master
Commit: 31fb89f939798a2792ad81c98a5d3cca98bbd40a
Parents: 2a8de62
Author: Benjamin Mahler <bmah...@apache.org>
Authored: Tue Sep 20 12:01:34 2016 -0700
Committer: Benjamin Mahler <bmah...@apache.org>
Committed: Wed Sep 21 23:07:08 2016 -0700

----------------------------------------------------------------------
 include/mesos/agent/agent.proto    | 41 +++++++++++++++++++++++++++++++++
 include/mesos/v1/agent/agent.proto | 41 +++++++++++++++++++++++++++++++++
 src/slave/http.cpp                 | 36 +++++++++++++++++++++++++++++
 src/slave/slave.hpp                | 15 ++++++++++++
 src/slave/validation.cpp           |  9 ++++++++
 5 files changed, 142 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/31fb89f9/include/mesos/agent/agent.proto
----------------------------------------------------------------------
diff --git a/include/mesos/agent/agent.proto b/include/mesos/agent/agent.proto
index 5b91677..3397c41 100644
--- a/include/mesos/agent/agent.proto
+++ b/include/mesos/agent/agent.proto
@@ -53,6 +53,11 @@ message Call {
     GET_FRAMEWORKS = 11;    // Retrieves the information about known 
frameworks.
     GET_EXECUTORS = 12;     // Retrieves the information about known executors.
     GET_TASKS = 13;         // Retrieves the information about known tasks.
+
+    // Calls for managing nested containers underneath an executor's container.
+    LAUNCH_NESTED_CONTAINER = 14;  // See 'LaunchNestedContainer' below.
+    WAIT_NESTED_CONTAINER = 15;    // See 'WaitNestedContainer' below.
+    KILL_NESTED_CONTAINER = 16;    // See 'KillNestedContainer' below.
   }
 
   // Provides a snapshot of the current metrics tracked by the agent.
@@ -93,12 +98,40 @@ message Call {
     optional uint64 length = 3;
   }
 
+ // Launches a nested container within an executor's tree of containers.
+  message LaunchNestedContainer {
+    // The user is responsible for generating a new 'container_id.value'
+    // which must be an RFC-4122 Version 4 UUID (in canonical string form)
+    // and the 'container_id.parent' must be set to determine under which
+    // container to nest the new container.
+    required ContainerID container_id = 1;
+
+    optional CommandInfo command = 2;
+    optional ContainerInfo container = 3;
+
+    // TODO(bmahler): Are there requirements on providing resources?
+    repeated Resource resources = 4;
+  }
+
+  // Waits for the nested container to terminate and receives the exit status.
+  message WaitNestedContainer {
+    required ContainerID container_id = 1;
+  }
+
+  // Kills the nested container. Currently only supports SIGKILL.
+  message KillNestedContainer {
+    required ContainerID container_id = 1;
+  }
+
   optional Type type = 1;
 
   optional GetMetrics get_metrics = 2;
   optional SetLoggingLevel set_logging_level = 3;
   optional ListFiles list_files = 4;
   optional ReadFile read_file = 5;
+  optional LaunchNestedContainer launch_nested_container = 6;
+  optional WaitNestedContainer wait_nested_container = 7;
+  optional KillNestedContainer kill_nested_container = 8;
 }
 
 
@@ -126,6 +159,8 @@ message Response {
     GET_FRAMEWORKS = 10;           // See 'GetFrameworks' below.
     GET_EXECUTORS = 11;            // See 'GetExecutors' below.
     GET_TASKS = 12;                // See 'GetTasks' below.
+
+    WAIT_NESTED_CONTAINER = 13;    // See 'WaitNestedContainer' below.
   }
 
   // `healthy` would be true if the agent is healthy. Delayed responses are 
also
@@ -234,6 +269,11 @@ message Response {
     repeated Task completed_tasks = 5;
   }
 
+  // Returns termination information about the nested container.
+  message WaitNestedContainer {
+    optional int32 exit_status = 1;
+  }
+
   optional Type type = 1;
 
   optional GetHealth get_health = 2;
@@ -248,4 +288,5 @@ message Response {
   optional GetFrameworks get_frameworks = 11;
   optional GetExecutors get_executors = 12;
   optional GetTasks get_tasks = 13;
+  optional WaitNestedContainer wait_nested_container = 14;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mesos/blob/31fb89f9/include/mesos/v1/agent/agent.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/agent/agent.proto 
b/include/mesos/v1/agent/agent.proto
index 8145669..93c817c 100644
--- a/include/mesos/v1/agent/agent.proto
+++ b/include/mesos/v1/agent/agent.proto
@@ -53,6 +53,11 @@ message Call {
     GET_FRAMEWORKS = 11;    // Retrieves the information about known 
frameworks.
     GET_EXECUTORS = 12;     // Retrieves the information about known executors.
     GET_TASKS = 13;         // Retrieves the information about known tasks.
+
+    // Calls for managing nested containers underneath an executor's container.
+    LAUNCH_NESTED_CONTAINER = 14;  // See 'LaunchNestedContainer' below.
+    WAIT_NESTED_CONTAINER = 15;    // See 'WaitNestedContainer' below.
+    KILL_NESTED_CONTAINER = 16;    // See 'KillNestedContainer' below.
   }
 
   // Provides a snapshot of the current metrics tracked by the agent.
@@ -93,12 +98,40 @@ message Call {
     optional uint64 length = 3;
   }
 
+  // Launches a nested container within an executor's tree of containers.
+  message LaunchNestedContainer {
+    // The user is responsible for generating a new 'container_id.value'
+    // which must be an RFC-4122 Version 4 UUID (in canonical string form)
+    // and the 'container_id.parent' must be set to determine under which
+    // container to nest the new container.
+    required ContainerID container_id = 1;
+
+    optional CommandInfo command = 2;
+    optional ContainerInfo container = 3;
+
+    // TODO(bmahler): Are there requirements on providing resources?
+    repeated Resource resources = 4;
+  }
+
+  // Waits for the nested container to terminate and receives the exit status.
+  message WaitNestedContainer {
+    required ContainerID container_id = 1;
+  }
+
+  // Kills the nested container. Currently only supports SIGKILL.
+  message KillNestedContainer {
+    required ContainerID container_id = 1;
+  }
+
   optional Type type = 1;
 
   optional GetMetrics get_metrics = 2;
   optional SetLoggingLevel set_logging_level = 3;
   optional ListFiles list_files = 4;
   optional ReadFile read_file = 5;
+  optional LaunchNestedContainer launch_nested_container = 6;
+  optional WaitNestedContainer wait_nested_container = 7;
+  optional KillNestedContainer kill_nested_container = 8;
 }
 
 
@@ -126,6 +159,8 @@ message Response {
     GET_FRAMEWORKS = 10;           // See 'GetFrameworks' below.
     GET_EXECUTORS = 11;            // See 'GetExecutors' below.
     GET_TASKS = 12;                // See 'GetTasks' below.
+
+    WAIT_NESTED_CONTAINER = 13;    // See 'WaitNestedContainer' below.
   }
 
   // `healthy` would be true if the agent is healthy. Delayed responses are 
also
@@ -234,6 +269,11 @@ message Response {
     repeated Task completed_tasks = 5;
   }
 
+  // Returns termination information about the nested container.
+  message WaitNestedContainer {
+    optional int32 exit_status = 1;
+  }
+
   optional Type type = 1;
 
   optional GetHealth get_health = 2;
@@ -248,4 +288,5 @@ message Response {
   optional GetFrameworks get_frameworks = 11;
   optional GetExecutors get_executors = 12;
   optional GetTasks get_tasks = 13;
+  optional WaitNestedContainer wait_nested_container = 14;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mesos/blob/31fb89f9/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index 0aae145..73135be 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -399,6 +399,15 @@ Future<Response> Slave::Http::api(
 
     case agent::Call::GET_TASKS:
       return getTasks(call, principal, acceptType);
+
+    case agent::Call::LAUNCH_NESTED_CONTAINER:
+      return launchNestedContainer(call, principal, acceptType);
+
+    case agent::Call::WAIT_NESTED_CONTAINER:
+      return waitNestedContainer(call, principal, acceptType);
+
+    case agent::Call::KILL_NESTED_CONTAINER:
+      return killNestedContainer(call, principal, acceptType);
   }
 
   UNREACHABLE();
@@ -1894,6 +1903,33 @@ Future<Response> Slave::Http::readFile(
     });
 }
 
+
+Future<Response> Slave::Http::launchNestedContainer(
+    const mesos::agent::Call& call,
+    const Option<string>& principal,
+    ContentType contentType) const
+{
+  return Failure("Unimplemented");
+}
+
+
+Future<Response> Slave::Http::waitNestedContainer(
+    const mesos::agent::Call& call,
+    const Option<string>& principal,
+    ContentType contentType) const
+{
+  return Failure("Unimplemented");
+}
+
+
+Future<Response> Slave::Http::killNestedContainer(
+    const mesos::agent::Call& call,
+    const Option<string>& principal,
+    ContentType contentType) const
+{
+  return Failure("Unimplemented");
+}
+
 } // namespace slave {
 } // namespace internal {
 } // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/31fb89f9/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index 20ca2fb..265032e 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -609,6 +609,21 @@ private:
         const process::Owned<ObjectApprover>& taskApprover,
         const process::Owned<ObjectApprover>& executorsApprover) const;
 
+    process::Future<process::http::Response> launchNestedContainer(
+        const mesos::agent::Call& call,
+        const Option<std::string>& principal,
+        ContentType contentType) const;
+
+    process::Future<process::http::Response> waitNestedContainer(
+        const mesos::agent::Call& call,
+        const Option<std::string>& principal,
+        ContentType contentType) const;
+
+    process::Future<process::http::Response> killNestedContainer(
+        const mesos::agent::Call& call,
+        const Option<std::string>& principal,
+        ContentType contentType) const;
+
     Slave* slave;
 
     // Used to rate limit the statistics endpoint.

http://git-wip-us.apache.org/repos/asf/mesos/blob/31fb89f9/src/slave/validation.cpp
----------------------------------------------------------------------
diff --git a/src/slave/validation.cpp b/src/slave/validation.cpp
index a9f3182..d9c1aa8 100644
--- a/src/slave/validation.cpp
+++ b/src/slave/validation.cpp
@@ -99,6 +99,15 @@ Option<Error> validate(
 
     case mesos::agent::Call::GET_TASKS:
       return None();
+
+    case mesos::agent::Call::LAUNCH_NESTED_CONTAINER:
+      return Error("Unimplemented");
+
+    case mesos::agent::Call::WAIT_NESTED_CONTAINER:
+      return Error("Unimplemented");
+
+    case mesos::agent::Call::KILL_NESTED_CONTAINER:
+      return Error("Unimplemented");
   }
 
   UNREACHABLE();

Reply via email to