Repository: mesos Updated Branches: refs/heads/master 1beef7dab -> 31350f9d3
Fixed composing containerizer to handled nested containers. Made composing containerizer nesting aware so that operators can enable both mesos and docker containerizers on agents. Ofcourse docker containerizer is not nesting aware. Review: https://reviews.apache.org/r/52321 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/31350f9d Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/31350f9d Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/31350f9d Branch: refs/heads/master Commit: 31350f9d3d468f24130c522931189bbf92869b10 Parents: 1beef7d Author: Vinod Kone <vinodk...@gmail.com> Authored: Tue Sep 27 15:10:36 2016 -0700 Committer: Vinod Kone <vinodk...@gmail.com> Committed: Tue Sep 27 17:34:50 2016 -0700 ---------------------------------------------------------------------- src/slave/containerizer/composing.cpp | 99 ++++++++++++++++++++++++++++++ src/slave/containerizer/composing.hpp | 8 +++ src/tests/default_executor_tests.cpp | 24 +++++++- 3 files changed, 128 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/31350f9d/src/slave/containerizer/composing.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/composing.cpp b/src/slave/containerizer/composing.cpp index 179304a..17eb34c 100644 --- a/src/slave/containerizer/composing.cpp +++ b/src/slave/containerizer/composing.cpp @@ -32,6 +32,8 @@ #include "slave/containerizer/containerizer.hpp" #include "slave/containerizer/composing.hpp" +#include "slave/containerizer/mesos/utils.hpp" + using namespace process; using std::list; @@ -70,6 +72,14 @@ public: const map<string, string>& environment, bool checkpoint); + Future<bool> launch( + const ContainerID& containerId, + const CommandInfo& commandInfo, + const Option<ContainerInfo>& containerInfo, + const string& directory, + const Option<string>& user, + const SlaveID& slaveId); + Future<Nothing> update( const ContainerID& containerId, const Resources& resources); @@ -107,6 +117,10 @@ private: vector<Containerizer*>::iterator containerizer, bool launched); + Future<bool> _launch( + const ContainerID& containerId, + bool launched); + vector<Containerizer*> containerizers_; // The states that the composing containerizer cares about for the @@ -184,6 +198,25 @@ Future<bool> ComposingContainerizer::launch( } +Future<bool> ComposingContainerizer::launch( + const ContainerID& containerId, + const CommandInfo& commandInfo, + const Option<ContainerInfo>& containerInfo, + const string& directory, + const Option<string>& user, + const SlaveID& slaveId) +{ + return dispatch(process, + &ComposingContainerizerProcess::launch, + containerId, + commandInfo, + containerInfo, + directory, + user, + slaveId); +} + + Future<Nothing> ComposingContainerizer::update( const ContainerID& containerId, const Resources& resources) @@ -408,6 +441,72 @@ Future<bool> ComposingContainerizerProcess::launch( } +Future<bool> ComposingContainerizerProcess::launch( + const ContainerID& containerId, + const CommandInfo& commandInfo, + const Option<ContainerInfo>& containerInfo, + const std::string& directory, + const Option<std::string>& user, + const SlaveID& slaveId) +{ + ContainerID rootContainerId = getRootContainerId(containerId); + + if (!containers_.contains(rootContainerId)) { + return Failure( + "Root container '" + rootContainerId.value() + "' not found"); + } + + // Use the containerizer that launched the root container to launch + // the nested container. + Containerizer* containerizer = containers_.at(rootContainerId)->containerizer; + + Container* container = new Container(); + container->state = LAUNCHING; + container->containerizer = containerizer; + containers_[containerId] = container; + + return containerizer->launch( + containerId, + commandInfo, + containerInfo, + directory, + user, + slaveId) + .then(defer(self(), + &Self::_launch, + containerId, + lambda::_1)); +} + + +Future<bool> ComposingContainerizerProcess::_launch( + const ContainerID& containerId, + bool launched) +{ + // The container struct will not be cleaned up by destroy + // when the container is in the LAUNCHING state. + CHECK(containers_.contains(containerId)); + Container* container = containers_.at(containerId); + + // A destroy arrived in the interim. + if (container->state == DESTROYING) { + container->destroyed.set(true); + containers_.erase(containerId); + delete container; + return Failure("Container was destroyed while launching"); + } + + if (launched) { + container->state = LAUNCHED; + return true; + } else { + containers_.erase(containerId); + delete container; + return false; + } +} + + Future<Nothing> ComposingContainerizerProcess::update( const ContainerID& containerId, const Resources& resources) http://git-wip-us.apache.org/repos/asf/mesos/blob/31350f9d/src/slave/containerizer/composing.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/composing.hpp b/src/slave/containerizer/composing.hpp index 9be7802..50aa081 100644 --- a/src/slave/containerizer/composing.hpp +++ b/src/slave/containerizer/composing.hpp @@ -62,6 +62,14 @@ public: const std::map<std::string, std::string>& environment, bool checkpoint); + virtual process::Future<bool> launch( + const ContainerID& containerId, + const CommandInfo& commandInfo, + const Option<ContainerInfo>& containerInfo, + const std::string& directory, + const Option<std::string>& user, + const SlaveID& slaveId); + virtual process::Future<Nothing> update( const ContainerID& containerId, const Resources& resources); http://git-wip-us.apache.org/repos/asf/mesos/blob/31350f9d/src/tests/default_executor_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/default_executor_tests.cpp b/src/tests/default_executor_tests.cpp index 3d6cbd9..8b5b1a2 100644 --- a/src/tests/default_executor_tests.cpp +++ b/src/tests/default_executor_tests.cpp @@ -17,6 +17,8 @@ #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <string> + #include <mesos/v1/executor.hpp> #include <mesos/v1/scheduler.hpp> @@ -35,6 +37,10 @@ using mesos::v1::scheduler::Mesos; using process::Future; using process::Owned; +using std::string; + +using testing::WithParamInterface; + namespace mesos { namespace internal { namespace tests { @@ -42,10 +48,20 @@ namespace tests { // Tests that exercise the default executor implementation // should be located in this file. -class DefaultExecutorTest : public MesosTest {}; +class DefaultExecutorTest + : public MesosTest, + public WithParamInterface<string> {}; + + +// These tests are parameterized by the containerizers enabled on the agent. +INSTANTIATE_TEST_CASE_P( + Containterizers, + DefaultExecutorTest, + ::testing::Values("mesos", "docker,mesos")); + // This test verifies that the default executor can launch a task group. -TEST_F(DefaultExecutorTest, TaskRunning) +TEST_P(DefaultExecutorTest, ROOT_TaskRunning) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); @@ -66,6 +82,7 @@ TEST_F(DefaultExecutorTest, TaskRunning) // Disable AuthN on the agent. slave::Flags flags = CreateSlaveFlags(); flags.authenticate_http_readwrite = false; + flags.containerizers = GetParam(); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags); @@ -156,7 +173,7 @@ TEST_F(DefaultExecutorTest, TaskRunning) // This test verifies that if the default executor is asked // to kill a task from a task group, it kills all tasks in // the group and sends TASK_KILLED updates for them. -TEST_F(DefaultExecutorTest, KillTask) +TEST_P(DefaultExecutorTest, ROOT_KillTask) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); @@ -177,6 +194,7 @@ TEST_F(DefaultExecutorTest, KillTask) // Disable AuthN on the agent. slave::Flags flags = CreateSlaveFlags(); flags.authenticate_http_readwrite = false; + flags.containerizers = GetParam(); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags);