Repository: mesos Updated Branches: refs/heads/master ca2e8efca -> 01c9de08f
Added webui_url to FrameworkInfo and web UI. Allows frameworks to register a URL to its web UI. Review: https://reviews.apache.org/r/26125 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/01c9de08 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/01c9de08 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/01c9de08 Branch: refs/heads/master Commit: 01c9de08f4ff196ea9c3acd3518d1c20b2f92bb6 Parents: ca2e8ef Author: Tobi Knaup <[email protected]> Authored: Thu Oct 2 11:41:06 2014 -0700 Committer: Niklas Q. Nielsen <[email protected]> Committed: Thu Oct 2 12:01:26 2014 -0700 ---------------------------------------------------------------------- include/mesos/mesos.proto | 4 +++ src/master/http.cpp | 1 + src/tests/master_tests.cpp | 53 ++++++++++++++++++++++++++++ src/webui/master/static/framework.html | 2 ++ src/webui/master/static/frameworks.html | 5 ++- 5 files changed, 64 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/01c9de08/include/mesos/mesos.proto ---------------------------------------------------------------------- diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto index 735da53..5e14b97 100644 --- a/include/mesos/mesos.proto +++ b/include/mesos/mesos.proto @@ -115,6 +115,9 @@ message ContainerID { * in authentication. This field is used for framework API rate * exporting and limiting and should be set even if authentication is * not enabled if these features are desired. + * The webui_url field allows a framework to advertise its web UI, so + * that the Mesos web UI can link to it. It is expected to be a full + * URL, for example http://my-scheduler.example.com:8080/. */ message FrameworkInfo { required string user = 1; @@ -125,6 +128,7 @@ message FrameworkInfo { optional string role = 6 [default = "*"]; optional string hostname = 7; optional string principal = 8; + optional string webui_url = 9; } http://git-wip-us.apache.org/repos/asf/mesos/blob/01c9de08/src/master/http.cpp ---------------------------------------------------------------------- diff --git a/src/master/http.cpp b/src/master/http.cpp index 41d91c8..16a6a01 100644 --- a/src/master/http.cpp +++ b/src/master/http.cpp @@ -118,6 +118,7 @@ JSON::Object model(const Framework& framework) object.values["active"] = framework.active; object.values["resources"] = model(framework.used()); object.values["hostname"] = framework.info.hostname(); + object.values["webui_url"] = framework.info.webui_url(); // TODO(benh): Consider making reregisteredTime an Option. if (framework.registeredTime != framework.reregisteredTime) { http://git-wip-us.apache.org/repos/asf/mesos/blob/01c9de08/src/tests/master_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp index 1497db2..705e5f2 100644 --- a/src/tests/master_tests.cpp +++ b/src/tests/master_tests.cpp @@ -2356,3 +2356,56 @@ TEST_F(MasterTest, UnacknowledgedTerminalTask) Shutdown(); // Must shutdown before 'containerizer' gets deallocated. } + + +// This test ensures that the web UI of a framework is included in the +// state.json endpoint, if provided by the framework. +TEST_F(MasterTest, FrameworkWebUIUrl) +{ + Try<PID<Master> > master = StartMaster(); + ASSERT_SOME(master); + + FrameworkInfo framework = DEFAULT_FRAMEWORK_INFO; + framework.set_webui_url("http://localhost:8080/"); + + MockScheduler sched; + MesosSchedulerDriver driver( + &sched, framework, master.get(), DEFAULT_CREDENTIAL); + + Future<Nothing> registered; + EXPECT_CALL(sched, registered(&driver, _, _)) + .WillOnce(FutureSatisfy(®istered)); + + driver.start(); + + AWAIT_READY(registered); + + Future<process::http::Response> masterState = + process::http::get(master.get(), "state.json"); + AWAIT_EXPECT_RESPONSE_STATUS_EQ(process::http::OK().status, masterState); + + Try<JSON::Object> masterStateObject = + JSON::parse<JSON::Object>(masterState.get().body); + ASSERT_SOME(masterStateObject); + + // We need a mutable copy of masterStateObject to use []. + JSON::Object masterStateObject_ = masterStateObject.get(); + + EXPECT_EQ(1u, masterStateObject_.values.count("frameworks")); + JSON::Array frameworks = + masterStateObject_.values["frameworks"].as<JSON::Array>(); + + EXPECT_EQ(1u, frameworks.values.size()); + JSON::Object framework_ = frameworks.values.front().as<JSON::Object>(); + + EXPECT_EQ(1u, framework_.values.count("webui_url")); + JSON::String webui_url = + framework_.values["webui_url"].as<JSON::String>(); + + EXPECT_EQ("http://localhost:8080/", webui_url.value); + + driver.stop(); + driver.join(); + + Shutdown(); +} http://git-wip-us.apache.org/repos/asf/mesos/blob/01c9de08/src/webui/master/static/framework.html ---------------------------------------------------------------------- diff --git a/src/webui/master/static/framework.html b/src/webui/master/static/framework.html index f6cce02..8c6e5e4 100644 --- a/src/webui/master/static/framework.html +++ b/src/webui/master/static/framework.html @@ -19,6 +19,8 @@ <dl class="inline clearfix"> <dt>Name:</dt> <dd>{{framework.name}}</dd> + <dt ng-show="framework.webui_url">Web UI:</dt> + <dd ng-show="framework.webui_url"><a href="{{framework.webui_url}}">{{framework.webui_url}}</a></dd> <dt>User:</dt> <dd>{{framework.user}}</dd> <dt>Registered:</dt> http://git-wip-us.apache.org/repos/asf/mesos/blob/01c9de08/src/webui/master/static/frameworks.html ---------------------------------------------------------------------- diff --git a/src/webui/master/static/frameworks.html b/src/webui/master/static/frameworks.html index b11d71a..44ef2e5 100644 --- a/src/webui/master/static/frameworks.html +++ b/src/webui/master/static/frameworks.html @@ -34,7 +34,10 @@ tooltip-trigger="clipboardhover"> </button> </td> - <td>{{framework.hostname}}</td> + <td ng-switch="!!framework.webui_url"> + <a ng-href="{{framework.webui_url}}" ng-switch-when="true">{{framework.hostname}}</a> + <span ng-switch-when="false">{{framework.hostname}}</span> + </td> <td>{{framework.user}}</td> <td>{{framework.name}}</td> <td>{{framework.tasks.length}}</td>
