Supported docker/volume isolator to be nested aware. Review: https://reviews.apache.org/r/52006/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c4cec59f Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c4cec59f Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c4cec59f Branch: refs/heads/master Commit: c4cec59f04643a3038633a944bb0896d7f5a4155 Parents: 6c1ee31 Author: Gilbert Song <songzihao1...@gmail.com> Authored: Wed Nov 29 17:40:18 2017 -0800 Committer: Gilbert Song <songzihao1...@gmail.com> Committed: Wed Nov 29 17:40:18 2017 -0800 ---------------------------------------------------------------------- .../mesos/isolators/docker/volume/isolator.cpp | 68 ++++++++++++++++---- .../mesos/isolators/docker/volume/isolator.hpp | 2 + 2 files changed, 57 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/c4cec59f/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp b/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp index 3e85afb..134ae5d 100644 --- a/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp +++ b/src/slave/containerizer/mesos/isolators/docker/volume/isolator.cpp @@ -63,6 +63,12 @@ DockerVolumeIsolatorProcess::DockerVolumeIsolatorProcess( DockerVolumeIsolatorProcess::~DockerVolumeIsolatorProcess() {} +bool DockerVolumeIsolatorProcess::supportsNesting() +{ + return true; +} + + Try<Isolator*> DockerVolumeIsolatorProcess::create(const Flags& flags) { // Check for root permission. @@ -153,6 +159,20 @@ Future<Nothing> DockerVolumeIsolatorProcess::recover( } } + // Recover any orphan containers that we might have check pointed. + // These orphan containers will be destroyed by the containerizer + // through the regular cleanup path. See MESOS-2367 for details. + foreach (const ContainerID& containerId, orphans) { + Try<Nothing> recover = _recover(containerId); + if (recover.isError()) { + return Failure( + "Failed to recover docker volumes for orphan container " + + stringify(containerId) + ": " + recover.error()); + } + } + + // Walk through all the checkpointed containers to determine if + // there are any 'unknown orphan' containers. Try<list<string>> entries = os::ls(rootDir); if (entries.isError()) { return Failure( @@ -164,11 +184,29 @@ Future<Nothing> DockerVolumeIsolatorProcess::recover( ContainerID containerId; containerId.set_value(Path(entry).basename()); - if (infos.contains(containerId)) { + bool recovered = false; + // Check if this container has already been recovered. + // + // NOTE: We cannot use `infos.contains()` to check the recovery + // status of this container, since the recovered `ContainerID` has + // only the `value` set. We don't checkpoint the `parent` + // associated with the container. Therefore, since we don't know + // if the container is a nested container or not, we have to + // traverse each entry of the `infos` hashmap and compare the + // value fields to identify if the container has already been + // recovered. + foreachkey (const ContainerID& _containerId, infos) { + if (_containerId.value() == containerId.value()) { + recovered = true; + break; + } + } + + if (recovered) { continue; } - // Recover docker volume information for orphan container. + // An unknown orphan container. Recover it and then clean it up. Try<Nothing> recover = _recover(containerId); if (recover.isError()) { return Failure( @@ -176,12 +214,6 @@ Future<Nothing> DockerVolumeIsolatorProcess::recover( stringify(containerId) + ": " + recover.error()); } - // Known orphan containers will be cleaned up by containerizer - // using the normal cleanup path. See MESOS-2367 for details. - if (orphans.contains(containerId)) { - continue; - } - LOG(INFO) << "Cleanup volumes for unknown orphaned " << "container " << containerId; @@ -266,13 +298,11 @@ Future<Option<ContainerLaunchInfo>> DockerVolumeIsolatorProcess::prepare( const ContainerID& containerId, const ContainerConfig& containerConfig) { - const ExecutorInfo& executorInfo = containerConfig.executor_info(); - - if (!executorInfo.has_container()) { + if (!containerConfig.has_container_info()) { return None(); } - if (executorInfo.container().type() != ContainerInfo::MESOS) { + if (containerConfig.container_info().type() != ContainerInfo::MESOS) { return Failure( "Can only prepare docker volume driver for a MESOS container"); } @@ -293,7 +323,7 @@ Future<Option<ContainerLaunchInfo>> DockerVolumeIsolatorProcess::prepare( // The mount points in the container. vector<string> targets; - foreach (const Volume& _volume, executorInfo.container().volumes()) { + foreach (const Volume& _volume, containerConfig.container_info().volumes()) { if (!_volume.has_source()) { continue; } @@ -515,6 +545,18 @@ Future<Nothing> DockerVolumeIsolatorProcess::cleanup( return Nothing(); } + // Make sure the container we are cleaning up doesn't have any + // children (they should have already been cleaned up by a previous + // call if it had any). + foreachkey (const ContainerID& containerId_, infos) { + if (containerId_.has_parent() && containerId_.parent() == containerId) { + return Failure( + "Failed to clean up container " + stringify(containerId) + + ": it has child container " + stringify(containerId_) + + " which is not cleaned up yet"); + } + } + hashmap<DockerVolume, int> references; foreachvalue (const Owned<Info>& info, infos) { foreach (const DockerVolume& volume, info->volumes) { http://git-wip-us.apache.org/repos/asf/mesos/blob/c4cec59f/src/slave/containerizer/mesos/isolators/docker/volume/isolator.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/mesos/isolators/docker/volume/isolator.hpp b/src/slave/containerizer/mesos/isolators/docker/volume/isolator.hpp index 2cc8e76..2e64d05 100644 --- a/src/slave/containerizer/mesos/isolators/docker/volume/isolator.hpp +++ b/src/slave/containerizer/mesos/isolators/docker/volume/isolator.hpp @@ -52,6 +52,8 @@ public: virtual ~DockerVolumeIsolatorProcess(); + virtual bool supportsNesting(); + virtual process::Future<Nothing> recover( const std::list<mesos::slave::ContainerState>& states, const hashset<ContainerID>& orphans);