Repository: mesos Updated Branches: refs/heads/master dcf5e9e49 -> 5c8065e9a
Refactor shared paths in provisioners. Review: https://reviews.apache.org/r/38141 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5c8065e9 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5c8065e9 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5c8065e9 Branch: refs/heads/master Commit: 5c8065e9a0531ccd686d565256d67ccf5f4b018c Parents: dcf5e9e Author: Timothy Chen <[email protected]> Authored: Fri Sep 4 18:19:33 2015 -0700 Committer: Timothy Chen <[email protected]> Committed: Tue Sep 8 17:21:00 2015 -0700 ---------------------------------------------------------------------- src/Makefile.am | 2 + src/slave/containerizer/provisioners/appc.cpp | 10 +- .../containerizer/provisioners/appc/paths.cpp | 153 --------------- .../containerizer/provisioners/appc/paths.hpp | 37 ---- src/slave/containerizer/provisioners/paths.cpp | 191 +++++++++++++++++++ src/slave/containerizer/provisioners/paths.hpp | 78 ++++++++ 6 files changed, 277 insertions(+), 194 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/5c8065e9/src/Makefile.am ---------------------------------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index 5fdca0f..0a8ef6d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -483,6 +483,7 @@ libmesos_no_3rdparty_la_SOURCES = \ slave/containerizer/mesos/launch.cpp \ slave/containerizer/provisioner.cpp \ slave/containerizer/provisioners/appc.cpp \ + slave/containerizer/provisioners/paths.cpp \ slave/containerizer/provisioners/appc/paths.cpp \ slave/containerizer/provisioners/appc/spec.cpp \ slave/containerizer/provisioners/appc/store.cpp \ @@ -762,6 +763,7 @@ libmesos_no_3rdparty_la_SOURCES += \ slave/containerizer/linux_launcher.hpp \ slave/containerizer/provisioner.hpp \ slave/containerizer/provisioners/appc.hpp \ + slave/containerizer/provisioners/paths.hpp \ slave/containerizer/provisioners/appc/paths.hpp \ slave/containerizer/provisioners/appc/spec.hpp \ slave/containerizer/provisioners/appc/store.hpp \ http://git-wip-us.apache.org/repos/asf/mesos/blob/5c8065e9/src/slave/containerizer/provisioners/appc.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/provisioners/appc.cpp b/src/slave/containerizer/provisioners/appc.cpp index fc5ee19..d54b688 100644 --- a/src/slave/containerizer/provisioners/appc.cpp +++ b/src/slave/containerizer/provisioners/appc.cpp @@ -33,6 +33,7 @@ #include "slave/containerizer/provisioners/appc.hpp" #include "slave/containerizer/provisioners/backend.hpp" +#include "slave/containerizer/provisioners/paths.hpp" #include "slave/containerizer/provisioners/appc/paths.hpp" #include "slave/containerizer/provisioners/appc/spec.hpp" @@ -41,6 +42,7 @@ #include "slave/paths.hpp" using namespace process; +using namespace mesos::internal::slave; using std::list; using std::string; @@ -220,7 +222,7 @@ Future<Nothing> AppcProvisionerProcess::recover( // be destroyed by the containerizer using the normal cleanup path. See // MESOS-2367 for details. Try<hashmap<ContainerID, string>> containers = - paths::listContainers(root); + provisioners::paths::listContainers(root); if (containers.isError()) { return Failure("Failed to list the containers managed by Appc " @@ -233,7 +235,7 @@ Future<Nothing> AppcProvisionerProcess::recover( Owned<Info> info = Owned<Info>(new Info()); Try<hashmap<string, hashmap<string, string>>> rootfses = - paths::listContainerRootfses(root, containerId); + provisioners::paths::listContainerRootfses(root, containerId); if (rootfses.isError()) { return Failure("Unable to list rootfses belonged to container '" + @@ -257,7 +259,7 @@ Future<Nothing> AppcProvisionerProcess::recover( // Destroy (unknown) orphan container's rootfses. Try<hashmap<string, hashmap<string, string>>> rootfses = - paths::listContainerRootfses(root, containerId); + provisioners::paths::listContainerRootfses(root, containerId); if (rootfses.isError()) { return Failure("Unable to find rootfses for container '" + @@ -308,7 +310,7 @@ Future<string> AppcProvisionerProcess::provision( } string rootfsId = UUID::random().toString(); - string rootfs = paths::getContainerRootfsDir( + string rootfs = provisioners::paths::getContainerRootfsDir( root, containerId, flags.appc_backend, rootfsId); if (!infos.contains(containerId)) { http://git-wip-us.apache.org/repos/asf/mesos/blob/5c8065e9/src/slave/containerizer/provisioners/appc/paths.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/provisioners/appc/paths.cpp b/src/slave/containerizer/provisioners/appc/paths.cpp index e6be851..e598df0 100644 --- a/src/slave/containerizer/provisioners/appc/paths.cpp +++ b/src/slave/containerizer/provisioners/appc/paths.cpp @@ -20,15 +20,9 @@ #include <glog/logging.h> -#include <mesos/type_utils.hpp> - -#include <stout/os.hpp> #include <stout/path.hpp> -#include <stout/os/stat.hpp> - #include "slave/containerizer/provisioners/appc/paths.hpp" -#include "slave/paths.hpp" using std::list; using std::string; @@ -84,153 +78,6 @@ string getImageManifestPath(const string& imagePath) return path::join(imagePath, "manifest"); } - -// Internal helpers for traversing the directory hierarchy. -static string getContainersDir(const string& provisionerDir) -{ - return path::join(provisionerDir, "containers"); -} - - -static string getContainerDir( - const string& containersDir, - const ContainerID& containerId) -{ - return path::join(containersDir, containerId.value()); -} - - -static string getBackendsDir(const string& containerDir) -{ - return path::join(containerDir, "backends"); -} - - -static string getBackendDir(const string& backendsDir, const string& backend) -{ - return path::join(backendsDir, backend); -} - - -static string getRootfsesDir(const string& backendDir) -{ - return path::join(backendDir, "rootfses"); -} - - -static string getRootfsDir(const string& rootfsesDir, const string& roofsId) -{ - return path::join(rootfsesDir, roofsId); -} - - -string getContainerRootfsDir( - const string& provisionerDir, - const ContainerID& containerId, - const string& backend, - const string& rootfsId) -{ - return getRootfsDir( - getRootfsesDir( - getBackendDir( - getBackendsDir( - getContainerDir( - getContainersDir(provisionerDir), - containerId)), - backend)), - rootfsId); -} - - -Try<hashmap<ContainerID, string>> listContainers( - const string& provisionerDir) -{ - hashmap<ContainerID, string> results; - - string containersDir = getContainersDir(provisionerDir); - if (!os::exists(containersDir)) { - // No container has been created yet. - return results; - } - - Try<list<string>> containerIds = os::ls(containersDir); - if (containerIds.isError()) { - return Error("Unable to list the containers directory: " + - containerIds.error()); - } - - foreach (const string& entry, containerIds.get()) { - string containerPath = path::join(containersDir, entry); - - if (!os::stat::isdir(containerPath)) { - LOG(WARNING) << "Ignoring unexpected container entry at: " - << containerPath; - continue; - } - - ContainerID containerId; - containerId.set_value(entry); - results.put(containerId, containerPath); - } - - return results; -} - - -Try<hashmap<string, hashmap<string, string>>> listContainerRootfses( - const string& provisionerDir, - const ContainerID& containerId) -{ - hashmap<string, hashmap<string, string>> results; - - string backendsDir = getBackendsDir( - getContainerDir( - getContainersDir(provisionerDir), - containerId)); - - Try<list<string>> backends = os::ls(backendsDir); - if (backends.isError()) { - return Error("Unable to list the container directory: " + backends.error()); - } - - foreach (const string& backend, backends.get()) { - string backendDir = getBackendDir(backendsDir, backend); - if (!os::stat::isdir(backendDir)) { - LOG(WARNING) << "Ignoring unexpected backend entry at: " << backendDir; - continue; - } - - Try<list<string>> rootfses = os::ls(getRootfsesDir(backendDir)); - if (rootfses.isError()) { - return Error("Unable to list the backend directory: " + rootfses.error()); - } - - hashmap<string, string> backendResults; - - foreach (const string& rootfsId, rootfses.get()) { - string rootfs = getRootfsDir(getRootfsesDir(backendDir), rootfsId); - - if (!os::stat::isdir(rootfs)) { - LOG(WARNING) << "Ignoring unexpected rootfs entry at: " << backendDir; - continue; - } - - backendResults.put(rootfsId, rootfs); - } - - if (backendResults.empty()) { - LOG(WARNING) << "Ignoring a backend directory with no rootfs in it: " - << backendDir; - continue; - } - - // The rootfs directory has passed validation. - results.put(backend, backendResults); - } - - return results; -} - } // namespace paths { } // namespace appc { } // namespace slave { http://git-wip-us.apache.org/repos/asf/mesos/blob/5c8065e9/src/slave/containerizer/provisioners/appc/paths.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/provisioners/appc/paths.hpp b/src/slave/containerizer/provisioners/appc/paths.hpp index fb3a1a7..37bbf09 100644 --- a/src/slave/containerizer/provisioners/appc/paths.hpp +++ b/src/slave/containerizer/provisioners/appc/paths.hpp @@ -47,24 +47,6 @@ namespace paths { // externally managed) but implemented to illustrate the need for a // separate 'images' directory. Complete the layout diagram when the // staging directory is utilized by the provisioner. -// -// The appc provisioner rootfs directory is as follows: -// <work_dir> ('--work_dir' flag) -// |-- provisioners -// |-- APPC (see definition in src/slave/paths.hpp) -// |-- containers -// |-- <container_id> -// |-- backends -// |-- <backend> (copy, bind, etc.) -// |-- rootfses -// |-- <rootfs_id> (the rootfs) -// -// NOTE: Each container could have multiple image types, therefore there -// can be the same <container_id> directory under other provisioners e.g., -// <work_dir>/provisioners/DOCKER, etc. Under each provisioner + container -// there can be multiple backends due to the change of backend flags. For -// appc, under each backend a rootfs is identified by the 'rootfs_id' which -// is a UUID. std::string getStagingDir(const std::string& storeDir); @@ -92,25 +74,6 @@ std::string getImageManifestPath( std::string getImageManifestPath(const std::string& imagePath); - -std::string getContainerRootfsDir( - const std::string& provisionerDir, - const ContainerID& containerId, - const std::string& backend, - const std::string& rootfsId); - - -// Recursively "ls" the container directory and return a map of -// backend -> rootfsId -> rootfsPath. -Try<hashmap<std::string, hashmap<std::string, std::string>>> -listContainerRootfses( - const std::string& provisionerDir, - const ContainerID& containerId); - -// Return a map of containerId -> containerPath; -Try<hashmap<ContainerID, std::string>> listContainers( - const std::string& provisionerDir); - } // namespace paths { } // namespace appc { } // namespace slave { http://git-wip-us.apache.org/repos/asf/mesos/blob/5c8065e9/src/slave/containerizer/provisioners/paths.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/provisioners/paths.cpp b/src/slave/containerizer/provisioners/paths.cpp new file mode 100644 index 0000000..267912c --- /dev/null +++ b/src/slave/containerizer/provisioners/paths.cpp @@ -0,0 +1,191 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <list> + +#include <glog/logging.h> + +#include <mesos/type_utils.hpp> + +#include <stout/os.hpp> +#include <stout/path.hpp> + +#include <stout/os/stat.hpp> + +#include "slave/containerizer/provisioners/paths.hpp" +#include "slave/paths.hpp" + +using std::list; +using std::string; + +namespace mesos { +namespace internal { +namespace slave { +namespace provisioners { +namespace paths { + +static string getContainersDir(const string& provisionerDir) +{ + return path::join(provisionerDir, "containers"); +} + + +static string getContainerDir( + const string& containersDir, + const ContainerID& containerId) +{ + return path::join(containersDir, containerId.value()); +} + + +static string getBackendsDir(const string& containerDir) +{ + return path::join(containerDir, "backends"); +} + + +static string getBackendDir(const string& backendsDir, const string& backend) +{ + return path::join(backendsDir, backend); +} + + +static string getRootfsesDir(const string& backendDir) +{ + return path::join(backendDir, "rootfses"); +} + + +static string getRootfsDir(const string& rootfsesDir, const string& roofsId) +{ + return path::join(rootfsesDir, roofsId); +} + + +string getContainerRootfsDir( + const string& provisionerDir, + const ContainerID& containerId, + const string& backend, + const string& rootfsId) +{ + return getRootfsDir( + getRootfsesDir( + getBackendDir( + getBackendsDir( + getContainerDir( + getContainersDir(provisionerDir), + containerId)), + backend)), + rootfsId); +} + + +Try<hashmap<ContainerID, string>> listContainers( + const string& provisionerDir) +{ + hashmap<ContainerID, string> results; + + string containersDir = getContainersDir(provisionerDir); + if (!os::exists(containersDir)) { + // No container has been created yet. + return results; + } + + Try<list<string>> containerIds = os::ls(containersDir); + if (containerIds.isError()) { + return Error("Unable to list the containers directory: " + + containerIds.error()); + } + + foreach (const string& entry, containerIds.get()) { + string containerPath = path::join(containersDir, entry); + + if (!os::stat::isdir(containerPath)) { + LOG(WARNING) << "Ignoring unexpected container entry at: " + << containerPath; + continue; + } + + ContainerID containerId; + containerId.set_value(entry); + results.put(containerId, containerPath); + } + + return results; +} + + +Try<hashmap<string, hashmap<string, string>>> listContainerRootfses( + const string& provisionerDir, + const ContainerID& containerId) +{ + hashmap<string, hashmap<string, string>> results; + + string backendsDir = getBackendsDir( + getContainerDir( + getContainersDir(provisionerDir), + containerId)); + + Try<list<string>> backends = os::ls(backendsDir); + if (backends.isError()) { + return Error("Unable to list the container directory: " + backends.error()); + } + + foreach (const string& backend, backends.get()) { + string backendDir = getBackendDir(backendsDir, backend); + if (!os::stat::isdir(backendDir)) { + LOG(WARNING) << "Ignoring unexpected backend entry at: " << backendDir; + continue; + } + + Try<list<string>> rootfses = os::ls(getRootfsesDir(backendDir)); + if (rootfses.isError()) { + return Error("Unable to list the backend directory: " + rootfses.error()); + } + + hashmap<string, string> backendResults; + + foreach (const string& rootfsId, rootfses.get()) { + string rootfs = getRootfsDir(getRootfsesDir(backendDir), rootfsId); + + if (!os::stat::isdir(rootfs)) { + LOG(WARNING) << "Ignoring unexpected rootfs entry at: " << backendDir; + continue; + } + + backendResults.put(rootfsId, rootfs); + } + + if (backendResults.empty()) { + LOG(WARNING) << "Ignoring a backend directory with no rootfs in it: " + << backendDir; + continue; + } + + // The rootfs directory has passed validation. + results.put(backend, backendResults); + } + + return results; +} + +} // namespace paths { +} // namespace provisioners { +} // namespace slave { +} // namespace internal { +} // namespace mesos { http://git-wip-us.apache.org/repos/asf/mesos/blob/5c8065e9/src/slave/containerizer/provisioners/paths.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/provisioners/paths.hpp b/src/slave/containerizer/provisioners/paths.hpp new file mode 100644 index 0000000..a249088 --- /dev/null +++ b/src/slave/containerizer/provisioners/paths.hpp @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MESOS_PROVISIONERS_PATHS_HPP__ +#define __MESOS_PROVISIONERS_PATHS_HPP__ + +#include <string> + +#include <mesos/mesos.hpp> + +#include <stout/hashmap.hpp> +#include <stout/try.hpp> + +namespace mesos { +namespace internal { +namespace slave { +namespace provisioners { +namespace paths { + +// The provisioner rootfs directory is as follows: +// <work_dir> ('--work_dir' flag) +// |-- provisioners +// |-- <provisioner_type> (APPC, DOCKER, etc.) +// |-- containers +// |-- <container_id> +// |-- backends +// |-- <backend> (copy, bind, etc.) +// |-- rootfses +// |-- <rootfs_id> (the rootfs) +// +// NOTE: Each container could have multiple image types, therefore there +// can be the same <container_id> directory under other provisioners e.g., +// <work_dir>/provisioners/DOCKER, <work_dir>/provisioners/APPC, etc. +// Under each provisioner + container there can be multiple backends +// due to the change of backend flags. Under each backend a rootfs is +// identified by the 'rootfs_id' which is a UUID. + +std::string getContainerRootfsDir( + const std::string& provisionerDir, + const ContainerID& containerId, + const std::string& backend, + const std::string& rootfsId); + + +// Recursively "ls" the container directory and return a map of +// backend -> rootfsId -> rootfsPath. +Try<hashmap<std::string, hashmap<std::string, std::string>>> +listContainerRootfses( + const std::string& provisionerDir, + const ContainerID& containerId); + + +// Return a map of containerId -> containerPath; +Try<hashmap<ContainerID, std::string>> listContainers( + const std::string& provisionerDir); + +} // namespace paths { +} // namespace provisioners { +} // namespace slave { +} // namespace internal { +} // namespace mesos { + +#endif // __MESOS_PROVISIONERS_PATHS__
