You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/12/07 00:34:39 UTC
mesos git commit: Added support to destroy running DEBUG containers
on agent recovery.
Repository: mesos
Updated Branches:
refs/heads/master bc906bf4f -> f54babdba
Added support to destroy running DEBUG containers on agent recovery.
Review: https://reviews.apache.org/r/54367/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f54babdb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f54babdb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f54babdb
Branch: refs/heads/master
Commit: f54babdba179a0dfed379c243dc2f5f16c94ed81
Parents: bc906bf
Author: Kevin Klues <kl...@gmail.com>
Authored: Tue Dec 6 16:27:50 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Dec 6 16:27:50 2016 -0800
----------------------------------------------------------------------
src/slave/containerizer/mesos/containerizer.cpp | 26 ++++-
.../nested_mesos_containerizer_tests.cpp | 117 +++++++++++++++++++
2 files changed, 142 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/f54babdb/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index cb23122..6d50755 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -757,9 +757,18 @@ Future<Nothing> MesosContainerizerProcess::recover(
containers_[containerId] = container;
// Add recoverable nested containers to the list of 'ContainerState'.
+ //
+ // TODO(klueska): The final check in the if statement makes sure
+ // that this container was not marked for forcible destruction on
+ // recover. We currently only support 'destroy-on-recovery'
+ // semantics for nested `DEBUG` containers. If we ever support it
+ // on other types of containers, we may need duplicate this logic
+ // elsewhere.
if (containerId.has_parent() &&
alive.contains(getRootContainerId(containerId)) &&
- pid.isSome()) {
+ pid.isSome() &&
+ !containerizer::paths::getContainerForceDestroyOnRecovery(
+ flags.runtime_dir, containerId)) {
CHECK_SOME(directory);
ContainerState state =
protobuf::slave::createContainerState(
@@ -1031,6 +1040,21 @@ Future<bool> MesosContainerizerProcess::launch(
" '" + runtimePath + "': " + mkdir.error());
}
+ // If we are launching a `DEBUG` container,
+ // checkpoint a file to mark it as destroy-on-recovery.
+ if (containerConfig.has_container_class() &&
+ containerConfig.container_class() == ContainerClass::DEBUG) {
+ const string path =
+ containerizer::paths::getContainerForceDestroyOnRecoveryPath(
+ flags.runtime_dir, containerId);
+
+ Try<Nothing> checkpointed = slave::state::checkpoint(path, "");
+ if (checkpointed.isError()) {
+ return Failure("Failed to checkpoint file to mark DEBUG container"
+ " as 'destroy-on-recovery'");
+ }
+ }
+
Owned<Container> container(new Container());
container->state = PROVISIONING;
container->config = containerConfig;
http://git-wip-us.apache.org/repos/asf/mesos/blob/f54babdb/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
index 6c341e1..7744c83 100644
--- a/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
+++ b/src/tests/containerizer/nested_mesos_containerizer_tests.cpp
@@ -468,6 +468,123 @@ TEST_F(NestedMesosContainerizerTest,
}
+TEST_F(NestedMesosContainerizerTest,
+ ROOT_CGROUPS_DestroyDebugContainerOnRecover)
+{
+ slave::Flags flags = CreateSlaveFlags();
+ flags.launcher = "linux";
+ flags.isolation = "cgroups/cpu,filesystem/linux,namespaces/pid";
+
+ Fetcher fetcher;
+
+ Try<MesosContainerizer*> create = MesosContainerizer::create(
+ flags,
+ false,
+ &fetcher);
+
+ ASSERT_SOME(create);
+
+ Owned<MesosContainerizer> containerizer(create.get());
+
+ SlaveState state;
+ state.id = SlaveID();
+
+ AWAIT_READY(containerizer->recover(state));
+
+ ContainerID containerId;
+ containerId.set_value(UUID::random().toString());
+
+ ExecutorInfo executor = createExecutorInfo(
+ "executor",
+ "sleep 1000",
+ "cpus:1");
+
+ Try<string> directory = environment->mkdtemp();
+ ASSERT_SOME(directory);
+
+ Future<bool> launch = containerizer->launch(
+ containerId,
+ None(),
+ executor,
+ directory.get(),
+ None(),
+ SlaveID(),
+ map<string, string>(),
+ true); // TODO(benh): Ever want to test not checkpointing?
+
+ AWAIT_ASSERT_TRUE(launch);
+
+ Future<ContainerStatus> status = containerizer->status(containerId);
+ AWAIT_READY(status);
+ ASSERT_TRUE(status->has_executor_pid());
+
+ pid_t pid = status->executor_pid();
+
+ // Now launch a debug container which should be destroyed on recovery.
+ ContainerID nestedContainerId;
+ nestedContainerId.mutable_parent()->CopyFrom(containerId);
+ nestedContainerId.set_value(UUID::random().toString());
+
+ launch = containerizer->launch(
+ nestedContainerId,
+ createCommandInfo("sleep 1000"),
+ None(),
+ None(),
+ state.id,
+ ContainerClass::DEBUG);
+
+ AWAIT_ASSERT_TRUE(launch);
+
+ status = containerizer->status(nestedContainerId);
+ AWAIT_READY(status);
+
+ // Force a delete on the containerizer before we create the new one.
+ containerizer.reset();
+
+ create = MesosContainerizer::create(
+ flags,
+ false,
+ &fetcher);
+
+ ASSERT_SOME(create);
+
+ containerizer.reset(create.get());
+
+ Try<SlaveState> slaveState = createSlaveState(
+ containerId,
+ pid,
+ executor,
+ state.id,
+ flags.work_dir);
+
+ ASSERT_SOME(slaveState);
+
+ state = slaveState.get();
+ AWAIT_READY(containerizer->recover(state));
+
+ Future<hashset<ContainerID>> containers = containerizer.get()->containers();
+ AWAIT_READY(containers);
+ EXPECT_EQ(2u, containers.get().size());
+
+ Future<Option<ContainerTermination>> wait =
+ containerizer->wait(nestedContainerId);
+
+ AWAIT_READY(wait);
+ ASSERT_SOME(wait.get());
+ ASSERT_TRUE(wait.get()->has_status());
+ EXPECT_WTERMSIG_EQ(SIGKILL, wait.get()->status());
+
+ wait = containerizer->wait(containerId);
+
+ containerizer->destroy(containerId);
+
+ AWAIT_READY(wait);
+ ASSERT_SOME(wait.get());
+ ASSERT_TRUE(wait.get()->has_status());
+ EXPECT_WTERMSIG_EQ(SIGKILL, wait.get()->status());
+}
+
+
TEST_F(NestedMesosContainerizerTest, ROOT_CGROUPS_DestroyNested)
{
slave::Flags flags = CreateSlaveFlags();