You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by al...@apache.org on 2016/08/28 15:04:07 UTC
[07/10] mesos git commit: Added support for HTTP/HTTPS health checks.
Added support for HTTP/HTTPS health checks.
Review: https://reviews.apache.org/r/36816/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2b80207d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2b80207d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2b80207d
Branch: refs/heads/master
Commit: 2b80207d1f05aa9dcb5747d161de84aada41643c
Parents: 7380d13
Author: haosdent huang <ha...@gmail.com>
Authored: Fri Aug 26 16:33:41 2016 +0200
Committer: Alexander Rukletsov <al...@apache.org>
Committed: Sun Aug 28 16:42:57 2016 +0200
----------------------------------------------------------------------
src/health-check/health_checker.cpp | 117 ++++++++++++++++++++++++++++++-
src/health-check/health_checker.hpp | 7 ++
2 files changed, 123 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/2b80207d/src/health-check/health_checker.cpp
----------------------------------------------------------------------
diff --git a/src/health-check/health_checker.cpp b/src/health-check/health_checker.cpp
index 097117a..4dd573b 100644
--- a/src/health-check/health_checker.cpp
+++ b/src/health-check/health_checker.cpp
@@ -31,6 +31,8 @@
#include <process/collect.hpp>
#include <process/delay.hpp>
+#include <process/http.hpp>
+#include <process/io.hpp>
#include <process/subprocess.hpp>
#include <stout/duration.hpp>
@@ -57,12 +59,20 @@ using process::UPID;
using std::map;
using std::string;
+using std::tuple;
using std::vector;
namespace mesos {
namespace internal {
namespace health {
+static const string DEFAULT_HTTP_SCHEME = "http";
+
+// Use '127.0.0.1' instead of 'localhost', because the host
+// file in some container images may not contain 'localhost'.
+static const string DEFAULT_DOMAIN = "127.0.0.1";
+
+
Try<Owned<HealthChecker>> HealthChecker::create(
const HealthCheck& check,
const UPID& executor,
@@ -318,7 +328,112 @@ Future<Nothing> HealthCheckerProcess::_httpHealthCheck()
CHECK_EQ(HealthCheck::HTTP, check.type());
CHECK(check.has_http());
- promise.fail("HTTP health check is not supported");
+ const HealthCheck::HTTPCheckInfo& http = check.http();
+
+ const string scheme = http.has_scheme() ? http.scheme() : DEFAULT_HTTP_SCHEME;
+ const string path = http.has_path() ? http.path() : "";
+ const string url = scheme + "://" + DEFAULT_DOMAIN + ":" +
+ stringify(http.port()) + path;
+
+ VLOG(1) << "Launching HTTP health check '" << url << "'";
+
+ const vector<string> argv = {
+ "curl",
+ "-s", // Don't show progress meter or error messages.
+ "-S", // Makes curl show an error message if it fails.
+ "-L", // Follows HTTP 3xx redirects.
+ "-k", // Ignores SSL validation when scheme is https.
+ "-w", "%{http_code}", // Displays HTTP response code on stdout.
+ "-o", "/dev/null", // Ignores output.
+ url
+ };
+
+ Try<Subprocess> s = subprocess(
+ "curl",
+ argv,
+ Subprocess::PATH("/dev/null"),
+ Subprocess::PIPE(),
+ Subprocess::PIPE());
+
+ if (s.isError()) {
+ return Failure("Failed to create the curl subprocess: " + s.error());
+ }
+
+ pid_t curlPid = s->pid();
+ Duration timeout = Seconds(check.timeout_seconds());
+
+ return await(
+ s->status(),
+ process::io::read(s->out().get()),
+ process::io::read(s->err().get()))
+ .after(timeout,
+ [timeout, curlPid](Future<tuple<Future<Option<int>>,
+ Future<string>,
+ Future<string>>> future) {
+ future.discard();
+
+ if (curlPid != -1) {
+ // Cleanup the curl process.
+ VLOG(1) << "Killing the HTTP health check process " << curlPid;
+
+ os::killtree(curlPid, SIGKILL);
+ }
+
+ return Failure(
+ "curl has not returned after " + stringify(timeout) + "; aborting");
+ })
+ .then(defer(self(), &Self::__httpHealthCheck, lambda::_1));
+}
+
+
+Future<Nothing> HealthCheckerProcess::__httpHealthCheck(
+ const tuple<
+ Future<Option<int>>,
+ Future<string>,
+ Future<string>>& t)
+{
+ Future<Option<int>> status = std::get<0>(t);
+ if (!status.isReady()) {
+ return Failure(
+ "Failed to get the exit status of the curl process: " +
+ (status.isFailed() ? status.failure() : "discarded"));
+ }
+
+ if (status->isNone()) {
+ return Failure("Failed to reap the curl process");
+ }
+
+ int statusCode = status->get();
+ if (statusCode != 0) {
+ Future<string> error = std::get<2>(t);
+ if (!error.isReady()) {
+ return Failure("curl returned " + WSTRINGIFY(statusCode) +
+ "; reading stderr failed: " +
+ (error.isFailed() ? error.failure() : "discarded"));
+ }
+
+ return Failure("curl returned " + WSTRINGIFY(statusCode) + ": " +
+ error.get());
+ }
+
+ Future<string> output = std::get<1>(t);
+ if (!output.isReady()) {
+ return Failure("Failed to read stdout from curl: " +
+ (output.isFailed() ? output.failure() : "discarded"));
+ }
+
+ // Parse the output and get the HTTP response code.
+ Try<int> code = numify<int>(output.get());
+ if (code.isError()) {
+ return Failure("Unexpected output from curl: " + output.get());
+ }
+
+ if (code.get() < process::http::Status::OK ||
+ code.get() >= process::http::Status::BAD_REQUEST) {
+ return Failure(
+ "Unexpected HTTP response code: " +
+ process::http::Status::string(code.get()));
+ }
return Nothing();
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/2b80207d/src/health-check/health_checker.hpp
----------------------------------------------------------------------
diff --git a/src/health-check/health_checker.hpp b/src/health-check/health_checker.hpp
index 83cedfb..83a3384 100644
--- a/src/health-check/health_checker.hpp
+++ b/src/health-check/health_checker.hpp
@@ -18,6 +18,7 @@
#define __HEALTH_CHECKER_HPP__
#include <string>
+#include <tuple>
#include <mesos/mesos.hpp>
@@ -82,6 +83,12 @@ private:
process::Future<Nothing> _httpHealthCheck();
+ process::Future<Nothing> __httpHealthCheck(
+ const std::tuple<
+ process::Future<Option<int>>,
+ process::Future<std::string>,
+ process::Future<std::string>>& t);
+
process::Future<Nothing> _tcpHealthCheck();
void reschedule();