Repository: mesos Updated Branches: refs/heads/master 245ea1886 -> 41e94c5af
Added --modules_dir flag to read module manifests from a directory. This allows the operator to use separate manifest JSON files for each module. Previously, one had to merge all module manifest files into a single JSON file before passing on to the master/agent. Review: https://reviews.apache.org/r/47123/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c7600b76 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c7600b76 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c7600b76 Branch: refs/heads/master Commit: c7600b7632b32101b9ab998d8de7617163fc2773 Parents: 245ea18 Author: Kapil Arya <[email protected]> Authored: Mon May 30 19:25:01 2016 +0200 Committer: Till Toenshoff <[email protected]> Committed: Mon May 30 19:25:01 2016 +0200 ---------------------------------------------------------------------- src/master/flags.cpp | 15 +++++++++++++-- src/master/flags.hpp | 1 + src/master/main.cpp | 12 ++++++++++++ src/module/manager.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/module/manager.hpp | 13 ++++++++++++- src/sched/flags.hpp | 13 ++++++++++++- src/sched/sched.cpp | 18 ++++++++++++++++++ src/slave/flags.cpp | 12 +++++++++++- src/slave/flags.hpp | 1 + src/slave/main.cpp | 12 ++++++++++++ src/tests/flags.hpp | 13 ++++++++++++- src/tests/main.cpp | 15 +++++++++++++++ 12 files changed, 163 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/master/flags.cpp ---------------------------------------------------------------------- diff --git a/src/master/flags.cpp b/src/master/flags.cpp index ceb4bd4..9ec97a3 100644 --- a/src/master/flags.cpp +++ b/src/master/flags.cpp @@ -357,7 +357,7 @@ mesos::internal::master::Flags::Flags() "If not set, offers do not timeout."); // This help message for --modules flag is the same for - // {master,slave,tests}/flags.hpp and should always be kept in + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in // sync. // TODO(karya): Remove the JSON example and add reference to the // doc file explaining the --modules flag. @@ -401,7 +401,18 @@ mesos::internal::master::Flags::Flags() " ]\n" " }\n" " ]\n" - "}"); + "}\n\n" + "Cannot be used in conjunction with --modules_dir.\n"); + + // This help message for --modules_dir flag is the same for + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in + // sync. + add(&Flags::modulesDir, + "modules_dir", + "Directory path of the module manifest files.\n" + "The manifest files are processed in alphabetical order.\n" + "(See --modules for more information on module manifest files)\n" + "Cannot be used in conjunction with --modules.\n"); add(&Flags::authenticators, "authenticators", http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/master/flags.hpp ---------------------------------------------------------------------- diff --git a/src/master/flags.hpp b/src/master/flags.hpp index d085096..735367f 100644 --- a/src/master/flags.hpp +++ b/src/master/flags.hpp @@ -74,6 +74,7 @@ public: Option<RateLimits> rate_limits; Option<Duration> offer_timeout; Option<Modules> modules; + Option<std::string> modulesDir; std::string authenticators; std::string allocator; Option<std::string> hooks; http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/master/main.cpp ---------------------------------------------------------------------- diff --git a/src/master/main.cpp b/src/master/main.cpp index 871cf2d..294b35d 100644 --- a/src/master/main.cpp +++ b/src/master/main.cpp @@ -253,6 +253,18 @@ int main(int argc, char** argv) // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. + if (flags.modules.isSome() && flags.modulesDir.isSome()) { + EXIT(EXIT_FAILURE) << + flags.usage("Only one of --modules or --modules_dir should be specified"); + } + + if (flags.modulesDir.isSome()) { + Try<Nothing> result = ModuleManager::load(flags.modulesDir.get()); + if (result.isError()) { + EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); + } + } + if (flags.modules.isSome()) { Try<Nothing> result = ModuleManager::load(flags.modules.get()); if (result.isError()) { http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/module/manager.cpp ---------------------------------------------------------------------- diff --git a/src/module/manager.cpp b/src/module/manager.cpp index 9f88ec3..725f085 100644 --- a/src/module/manager.cpp +++ b/src/module/manager.cpp @@ -30,6 +30,7 @@ #include <stout/stringify.hpp> #include <stout/version.hpp> +#include "common/parse.hpp" #include "messages/messages.hpp" #include "module/manager.hpp" @@ -263,7 +264,7 @@ Try<Nothing> ModuleManager::verifyIdenticalModule( } -Try<Nothing> ModuleManager::load(const Modules& modules) +Try<Nothing> ModuleManager::loadManifest(const Modules& modules) { synchronized (mutex) { initialize(); @@ -347,3 +348,45 @@ Try<Nothing> ModuleManager::load(const Modules& modules) return Nothing(); } + + +// We load the module manifests sequentially in an alphabetical order. If an +// error is encountered while processing a particular manifest, we do not load +// the remaining manifests and exit with the appropriate error message. +Try<Nothing> ModuleManager::load(const string& modulesDir) +{ + Try<list<string>> moduleManifests = os::ls(modulesDir); + if (moduleManifests.isError()) { + return Error( + "Error loading module manifests from '" + modulesDir + "' directory: " + + moduleManifests.error()); + } + + moduleManifests->sort(); + foreach (const string& filename, moduleManifests.get()) { + const string filepath = path::join(modulesDir, filename); + VLOG(1) << "Processing module manifest from '" << filepath << "'"; + + Try<string> read = os::read(filepath); + if (read.isError()) { + return Error( + "Error reading module manifest file '" + filepath + "': " + + read.error()); + } + + Try<Modules> modules = flags::parse<Modules>(read.get()); + if (modules.isError()) { + return Error( + "Error parsing module manifest file '" + filepath + "': " + + modules.error()); + } + + Try<Nothing> result = loadManifest(modules.get()); + if (result.isError()) { + return Error( + "Error loading modules from '" + filepath + "': " + result.error()); + } + } + + return Nothing(); +} http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/module/manager.hpp ---------------------------------------------------------------------- diff --git a/src/module/manager.hpp b/src/module/manager.hpp index 9944af0..4a9e6a3 100644 --- a/src/module/manager.hpp +++ b/src/module/manager.hpp @@ -34,7 +34,9 @@ #include <stout/check.hpp> #include <stout/dynamiclibrary.hpp> #include <stout/hashmap.hpp> +#include <stout/nothing.hpp> #include <stout/synchronized.hpp> +#include <stout/try.hpp> #include "messages/messages.hpp" @@ -62,7 +64,14 @@ public: // // NOTE: If loading fails at a particular library we don't unload // all of the already loaded libraries. - static Try<Nothing> load(const Modules& modules); + static Try<Nothing> load(const Modules& modules) + { + return loadManifest(modules); + } + + // NOTE: If loading fails at a particular library we don't unload + // all of the already loaded libraries. + static Try<Nothing> load(const std::string& modulesDir); // create() should be called only after load(). template <typename T> @@ -140,6 +149,8 @@ public: private: static void initialize(); + static Try<Nothing> loadManifest(const Modules& modules); + static Try<Nothing> verifyModule( const std::string& moduleName, const ModuleBase* moduleBase); http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/sched/flags.hpp ---------------------------------------------------------------------- diff --git a/src/sched/flags.hpp b/src/sched/flags.hpp index b4ca12b..989cebe 100644 --- a/src/sched/flags.hpp +++ b/src/sched/flags.hpp @@ -47,7 +47,7 @@ public: DEFAULT_REGISTRATION_BACKOFF_FACTOR); // This help message for --modules flag is the same for - // {master,slave,tests,sched}/flags.hpp and should always be kept + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in // in sync. // TODO(karya): Remove the JSON example and add reference to the // doc file explaining the --modules flag. @@ -93,6 +93,16 @@ public: " ]\n" "}"); + // This help message for --modules_dir flag is the same for + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in + // sync. + add(&Flags::modulesDir, + "modules_dir", + "Directory path of the module manifest files.\n" + "The manifest files are processed in alphabetical order.\n" + "(See --modules for more information on module manifest files)\n" + "Cannot be used in conjunction with --modules.\n"); + add(&Flags::authenticatee, "authenticatee", "Authenticatee implementation to use when authenticating against the\n" @@ -103,6 +113,7 @@ public: Duration registration_backoff_factor; Option<Modules> modules; + Option<std::string> modulesDir; std::string authenticatee; }; http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/sched/sched.cpp ---------------------------------------------------------------------- diff --git a/src/sched/sched.cpp b/src/sched/sched.cpp index 8380e48..5eca265 100644 --- a/src/sched/sched.cpp +++ b/src/sched/sched.cpp @@ -1878,6 +1878,24 @@ Status MesosSchedulerDriver::start() // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. + if (flags.modules.isSome() && flags.modulesDir.isSome()) { + status = DRIVER_ABORTED; + scheduler->error( + this, + "Only one of MESOS_MODULES or MESOS_MODULES_DIR should be specified"); + return status; + } + + if (flags.modulesDir.isSome()) { + Try<Nothing> result = + modules::ModuleManager::load(flags.modulesDir.get()); + if (result.isError()) { + status = DRIVER_ABORTED; + scheduler->error(this, "Error loading modules: " + result.error()); + return status; + } + } + if (flags.modules.isSome()) { Try<Nothing> result = modules::ModuleManager::load(flags.modules.get()); if (result.isError()) { http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/slave/flags.cpp ---------------------------------------------------------------------- diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp index d30f39c..f90beaf 100644 --- a/src/slave/flags.cpp +++ b/src/slave/flags.cpp @@ -687,7 +687,7 @@ mesos::internal::slave::Flags::Flags() false); // This help message for --modules flag is the same for - // {master,slave,tests}/flags.hpp and should always be kept in + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in // sync. // TODO(karya): Remove the JSON example and add reference to the // doc file explaining the --modules flag. @@ -733,6 +733,16 @@ mesos::internal::slave::Flags::Flags() " ]\n" "}"); + // This help message for --modules_dir flag is the same for + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in + // sync. + add(&Flags::modulesDir, + "modules_dir", + "Directory path of the module manifest files.\n" + "The manifest files are processed in alphabetical order.\n" + "(See --modules for more information on module manifest files)\n" + "Cannot be used in conjunction with --modules.\n"); + add(&Flags::authenticatee, "authenticatee", "Authenticatee implementation to use when authenticating against the\n" http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/slave/flags.hpp ---------------------------------------------------------------------- diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp index 3363412..17acf56 100644 --- a/src/slave/flags.hpp +++ b/src/slave/flags.hpp @@ -136,6 +136,7 @@ public: Duration container_disk_watch_interval; bool enforce_container_disk_quota; Option<Modules> modules; + Option<std::string> modulesDir; std::string authenticatee; std::string authorizer; std::string http_authenticators; http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/slave/main.cpp ---------------------------------------------------------------------- diff --git a/src/slave/main.cpp b/src/slave/main.cpp index f431e13..fddb05c 100644 --- a/src/slave/main.cpp +++ b/src/slave/main.cpp @@ -232,6 +232,18 @@ int main(int argc, char** argv) // Initialize modules. Note that since other subsystems may depend // upon modules, we should initialize modules before anything else. + if (flags.modules.isSome() && flags.modulesDir.isSome()) { + EXIT(EXIT_FAILURE) << + flags.usage("Only one of --modules or --modules_dir should be specified"); + } + + if (flags.modulesDir.isSome()) { + Try<Nothing> result = ModuleManager::load(flags.modulesDir.get()); + if (result.isError()) { + EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); + } + } + if (flags.modules.isSome()) { Try<Nothing> result = ModuleManager::load(flags.modules.get()); if (result.isError()) { http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/tests/flags.hpp ---------------------------------------------------------------------- diff --git a/src/tests/flags.hpp b/src/tests/flags.hpp index ae232b1..3066399 100644 --- a/src/tests/flags.hpp +++ b/src/tests/flags.hpp @@ -84,7 +84,7 @@ public: "/var/run/docker.sock"); // This help message for --modules flag is the same for - // {master,slave,tests}/flags.hpp and should always be kept in + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in // sync. // TODO(karya): Remove the JSON example and add reference to the // doc file explaining the --modules flag. @@ -130,6 +130,16 @@ public: " ]\n" "}"); + // This help message for --modules_dir flag is the same for + // {master,slave,sched,tests}/flags.[ch]pp and should always be kept in + // sync. + add(&Flags::modulesDir, + "modules_dir", + "Directory path of the module manifest files.\n" + "The manifest files are processed in alphabetical order.\n" + "(See --modules for more information on module manifest files)\n" + "Cannot be used in conjunction with --modules.\n"); + // This help message is duplicated from slave/flags.hpp and // should always be kept in sync with that. add(&Flags::isolation, @@ -158,6 +168,7 @@ public: std::string docker; std::string docker_socket; Option<Modules> modules; + Option<std::string> modulesDir; Option<std::string> isolation; std::string authenticators; }; http://git-wip-us.apache.org/repos/asf/mesos/blob/c7600b76/src/tests/main.cpp ---------------------------------------------------------------------- diff --git a/src/tests/main.cpp b/src/tests/main.cpp index efec922..1425a04 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -29,6 +29,8 @@ #include "messages/messages.hpp" // For GOOGLE_PROTOBUF_VERIFY_VERSION. +#include "module/manager.hpp" + #include "tests/environment.hpp" #include "tests/flags.hpp" #include "tests/mesos.hpp" @@ -65,6 +67,19 @@ int main(int argc, char** argv) } // Initialize Modules. + if (flags.modules.isSome() && flags.modulesDir.isSome()) { + EXIT(EXIT_FAILURE) << + flags.usage("Only one of --modules or --modules_dir should be specified"); + } + + if (flags.modulesDir.isSome()) { + Try<Nothing> result = + mesos::modules::ModuleManager::load(flags.modulesDir.get()); + if (result.isError()) { + EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error(); + } + } + Try<Nothing> result = tests::initModules(flags.modules); if (result.isError()) { cerr << "Error initializing modules: " << result.error() << endl;
