Repository: mesos Updated Branches: refs/heads/master ec5ff7540 -> 6cf8b26a7
Include ContainerInfo in command ExecutorInfo Always copy ContainerInfo to ExecutorInfo Remove MesosContainerizer check for TaskInfo->ContainerInfo Review: https://reviews.apache.org/r/39769 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6cf8b26a Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6cf8b26a Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6cf8b26a Branch: refs/heads/master Commit: 6cf8b26a74060bbc12b15122c65c65cb335ceeba Parents: ec5ff75 Author: Spike Curtis <[email protected]> Authored: Fri Nov 6 14:57:58 2015 -0500 Committer: Kapil Arya <[email protected]> Committed: Fri Nov 6 17:48:14 2015 -0500 ---------------------------------------------------------------------- src/slave/slave.cpp | 13 ++++- src/tests/slave_tests.cpp | 128 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/6cf8b26a/src/slave/slave.cpp ---------------------------------------------------------------------- diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp index 4f1e3e3..0f9ed82 100644 --- a/src/slave/slave.cpp +++ b/src/slave/slave.cpp @@ -3252,8 +3252,7 @@ ExecutorInfo Slave::getExecutorInfo( executor.mutable_executor_id()->set_value(task.task_id().value()); executor.mutable_framework_id()->CopyFrom(frameworkInfo.id()); - if (task.has_container() && - task.container().type() != ContainerInfo::MESOS) { + if (task.has_container()) { // Store the container info in the executor info so it will // be checkpointed. This allows the correct containerizer to // recover this task on restart. @@ -3266,6 +3265,16 @@ ExecutorInfo Slave::getExecutorInfo( if (hasRootfs) { ContainerInfo* container = executor.mutable_container(); + + // For command-tasks, we are now copying the entire `task.container` into + // the `executorInfo`. Thus, `executor.container` now has the image if + // `task.container` had one. However, in case of rootfs, we want to run + // the command executor in the host filesystem and prepare/mount the image + // into the container as a volume (command executor will use pivot_root to + // mount the image). For this reason, we need to strip the image in + // `executor.container.mesos`. + container->mutable_mesos()->clear_image(); + container->set_type(ContainerInfo::MESOS); Volume* volume = container->add_volumes(); volume->mutable_image()->CopyFrom(task.container().mesos().image()); http://git-wip-us.apache.org/repos/asf/mesos/blob/6cf8b26a/src/tests/slave_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp index 6b89eaf..ac102f1 100644 --- a/src/tests/slave_tests.cpp +++ b/src/tests/slave_tests.cpp @@ -573,6 +573,134 @@ TEST_F(SlaveTest, GetExecutorInfo) EXPECT_NE(string::npos, executor.command().value().find("mesos-executor")); } +// Ensure getExecutorInfo for mesos-executor gets the ContainerInfo, if +// present. This ensures the MesosContainerizer can get the NetworkInfo even +// when using the command executor. +TEST_F(SlaveTest, GetExecutorInfoForTaskWithContainer) +{ + TestContainerizer containerizer; + StandaloneMasterDetector detector; + + MockSlave slave(CreateSlaveFlags(), &detector, &containerizer); + + // Launch a task with the command executor and ContainerInfo with + // NetworkInfo. + TaskInfo task; + task.set_name("task"); + task.mutable_task_id()->set_value("1"); + task.mutable_slave_id()->set_value( + "20141010-221431-251662764-60288-12345-0001"); + task.mutable_resources()->MergeFrom( + Resources::parse("cpus:0.1;mem:32").get()); + + CommandInfo command; + command.set_shell(false); + command.set_value("/bin/echo"); + command.add_arguments("/bin/echo"); + command.add_arguments("--author"); + + task.mutable_command()->MergeFrom(command); + + ContainerInfo *container = task.mutable_container(); + container->set_type(ContainerInfo::MESOS); + + NetworkInfo *network = container->add_network_infos(); + network->set_ip_address("4.3.2.1"); + network->add_groups("public"); + + FrameworkInfo frameworkInfo; + frameworkInfo.mutable_id()->set_value( + "20141010-221431-251662764-60288-12345-0000"); + const ExecutorInfo& executor = slave.getExecutorInfo(frameworkInfo, task); + + // Now assert that the executor has both the command and ContainerInfo + EXPECT_TRUE(executor.command().shell()); + // CommandInfo.container is not included. In this test the ContainerInfo + // must be included in Executor.container (copied from TaskInfo.container). + EXPECT_FALSE(executor.command().has_container()); + EXPECT_TRUE(executor.has_container()); + + EXPECT_EQ("4.3.2.1", executor.container().network_infos(0).ip_address()); + EXPECT_EQ(1, executor.container().network_infos(0).groups_size()); + EXPECT_EQ("public", executor.container().network_infos(0).groups(0)); +} + +// This tests ensures that MesosContainerizer will launch a command executor +// even if it contains a ContainerInfo in the TaskInfo. Prior to 0.26.0, this +// was only used to launch Docker containers, so MesosContainerizer would fail +// the launch. +TEST_F(SlaveTest, LaunchTaskInfoWithContainerInfo) +{ + Try<PID<Master>> master = StartMaster(); + ASSERT_SOME(master); + + // Need flags for 'executor_registration_timeout'. + slave::Flags flags = CreateSlaveFlags(); + flags.isolation = "posix/cpu,posix/mem"; + + Fetcher fetcher; + + Try<MesosContainerizer*> containerizer = + MesosContainerizer::create(flags, false, &fetcher); + CHECK_SOME(containerizer); + + StandaloneMasterDetector detector; + MockSlave slave(flags, &detector, containerizer.get()); + + // Launch a task with the command executor and ContainerInfo with + // NetworkInfo. + TaskInfo task; + task.set_name("task"); + task.mutable_task_id()->set_value("1"); + task.mutable_slave_id()->set_value( + "20141010-221431-251662764-60288-12345-0001"); + task.mutable_resources()->MergeFrom( + Resources::parse("cpus:0.1;mem:32").get()); + + CommandInfo command; + command.set_shell(false); + command.set_value("/bin/echo"); + command.add_arguments("/bin/echo"); + command.add_arguments("--author"); + + task.mutable_command()->MergeFrom(command); + + ContainerID containerId; + containerId.set_value(UUID::random().toString()); + ContainerInfo *container = task.mutable_container(); + container->set_type(ContainerInfo::MESOS); + + NetworkInfo *network = container->add_network_infos(); + network->set_ip_address("4.3.2.1"); + network->add_groups("public"); + + FrameworkInfo frameworkInfo; + frameworkInfo.mutable_id()->set_value( + "20141010-221431-251662764-60288-12345-0000"); + const ExecutorInfo& executor = slave.getExecutorInfo(frameworkInfo, task); + + Future<bool> result; + SlaveID slaveID; + slaveID.set_value(UUID::random().toString()); + result = containerizer.get()->launch( + containerId, + task, + executor, + "/tmp", + "test", + slaveID, + slave.self(), + false); + AWAIT_READY(result); + + // TODO(spikecurtis): With agent capabilities (MESOS-3362), the + // Containerizer should fail this request since none of the listed + // isolators can handle NetworkInfo, which implies + // IP-per-container. + EXPECT_TRUE(result.get()); + Shutdown(); // Must shutdown before 'containerizer' gets deallocated. +} + // This test runs a command without the command user field set. The // command will verify the assumption that the command is run as the
