Add version() to docker abstraction.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/58963abf Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/58963abf Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/58963abf Branch: refs/heads/master Commit: 58963abf01cc33f41164a861d2add6a8b846d971 Parents: 72f62aa Author: Timothy Chen <[email protected]> Authored: Thu Jan 22 16:57:38 2015 -0800 Committer: Timothy Chen <[email protected]> Committed: Sun May 24 22:27:40 2015 -0700 ---------------------------------------------------------------------- src/docker/docker.cpp | 96 ++++++++++++++++++++++++++++------------------ src/docker/docker.hpp | 10 +++++ 2 files changed, 68 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/58963abf/src/docker/docker.cpp ---------------------------------------------------------------------- diff --git a/src/docker/docker.cpp b/src/docker/docker.cpp index d7a33dd..08f2023 100644 --- a/src/docker/docker.cpp +++ b/src/docker/docker.cpp @@ -96,8 +96,9 @@ static Future<Nothing> checkError(const string& cmd, const Subprocess& s) Try<Docker*> Docker::create(const string& path, bool validate) { + Docker* docker = new Docker(path); if (!validate) { - return new Docker(path); + return docker; } #ifdef __linux__ @@ -106,6 +107,7 @@ Try<Docker*> Docker::create(const string& path, bool validate) Result<string> hierarchy = cgroups::hierarchy("cpu"); if (hierarchy.isNone()) { + delete docker; return Error("Failed to find a mounted cgroups hierarchy " "for the 'cpu' subsystem; you probably need " "to mount cgroups manually!"); @@ -113,6 +115,36 @@ Try<Docker*> Docker::create(const string& path, bool validate) #endif // __linux__ // Validate the version (and that we can use Docker at all). + Future<Version> version = docker->version(); + + if(!version.await(Seconds(5))) { + delete docker; + return Error("Timed out getting docker version."); + } + + if (version.isFailed()) { + delete docker; + return Error("Failed to get docker version: " + version.failure()); + } + + if (version.get() < Version(1, 0, 0)) { + delete docker; + return Error("Insufficient version of Docker! Please upgrade to >= 1.0.0"); + } + + return docker; +} + + +void commandDiscarded(const Subprocess& s, const string& cmd) +{ + VLOG(1) << "'" << cmd << "' is being discarded"; + os::killtree(s.pid(), SIGKILL); +} + + +Future<Version> Docker::version() const +{ string cmd = path + " version"; Try<Subprocess> s = subprocess( @@ -122,63 +154,51 @@ Try<Docker*> Docker::create(const string& path, bool validate) Subprocess::PIPE()); if (s.isError()) { - return Error(s.error()); + return Failure(s.error()); } - Future<Option<int> > status = s.get().status(); + return s.get().status() + .then(lambda::bind(&Docker::_version, cmd, s.get())); +} + - if (!status.await(Seconds(5))) { - return Error("Timed out waiting for '" + cmd + "'"); - } else if (status.isFailed()) { - return Error("Failed to execute '" + cmd + "': " + status.failure()); - } else if (!status.get().isSome() || status.get().get() != 0) { +Future<Version> Docker::_version(const string& cmd, const Subprocess& s) +{ + const Option<int>& status = s.status().get(); + if (!status.isSome() || status.get() != 0) { string msg = "Failed to execute '" + cmd + "': "; - if (status.get().isSome()) { - msg += WSTRINGIFY(status.get().get()); + if (status.isSome()) { + msg += WSTRINGIFY(status.get()); } else { msg += "unknown exit status"; } - return Error(msg); + return Failure(msg); } - CHECK_SOME(s.get().out()); + CHECK_SOME(s.out()); - Future<string> output = io::read(s.get().out().get()); + return io::read(s.out().get()) + .then(lambda::bind(&Docker::__version, lambda::_1)); +} - if (!output.await(Seconds(5))) { - return Error("Timed out reading output from '" + cmd + "'"); - } else if (output.isFailed()) { - return Error("Failed to read output from '" + cmd + "': " + - output.failure()); - } +Future<Version> Docker::__version(const Future<string>& output) +{ foreach (string line, strings::split(output.get(), "\n")) { line = strings::trim(line); if (strings::startsWith(line, "Client version: ")) { line = line.substr(strlen("Client version: ")); - vector<string> version = strings::split(line, "."); - if (version.size() < 1) { - return Error("Failed to parse Docker version '" + line + "'"); - } - Try<int> major = numify<int>(version[0]); - if (major.isError()) { - return Error("Failed to parse Docker major version '" + - version[0] + "'"); - } else if (major.get() < 1) { - break; + Try<Version> version = Version::parse(line); + + if (version.isError()) { + return Failure("Failed to parse docker version: " + version.error()); } - return new Docker(path); + + return version; } } - return Error("Insufficient version of Docker! Please upgrade to >= 1.0.0"); -} - - -void commandDiscarded(const Subprocess& s, const string& cmd) -{ - VLOG(1) << "'" << cmd << "' is being discarded"; - os::killtree(s.pid(), SIGKILL); + return Failure("Unable to find docker version in output."); } http://git-wip-us.apache.org/repos/asf/mesos/blob/58963abf/src/docker/docker.hpp ---------------------------------------------------------------------- diff --git a/src/docker/docker.hpp b/src/docker/docker.hpp index 2e2053e..3b6ea64 100644 --- a/src/docker/docker.hpp +++ b/src/docker/docker.hpp @@ -30,6 +30,7 @@ #include <stout/none.hpp> #include <stout/nothing.hpp> #include <stout/option.hpp> +#include <stout/version.hpp> #include "mesos/resources.hpp" @@ -80,6 +81,8 @@ public: : entrypoint(_entrypoint) {} }; + // Returns the current docker version. + virtual process::Future<Version> version() const; // Performs 'docker run IMAGE'. virtual process::Future<Nothing> run( @@ -136,6 +139,13 @@ protected: Docker(const std::string& _path) : path(_path) {}; private: + static process::Future<Version> _version( + const std::string& cmd, + const process::Subprocess& s); + + static process::Future<Version> __version( + const process::Future<std::string>& output); + static process::Future<Nothing> _stop( const Docker& docker, const std::string& container,
