aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Owen <sowen@cloudera.com>2015-05-01 19:57:37 +0100
committerSean Owen <sowen@cloudera.com>2015-05-01 19:57:37 +0100
commit1262e310cd294c8fd936c55c3281ed855824ea27 (patch)
treec0f510c55b064393feb3ed3496ae05cebf5dd0a2
parent7d427222dca4807ec55e8d9a7de6ffe861cd0d24 (diff)
downloadspark-1262e310cd294c8fd936c55c3281ed855824ea27.tar.gz
spark-1262e310cd294c8fd936c55c3281ed855824ea27.tar.bz2
spark-1262e310cd294c8fd936c55c3281ed855824ea27.zip
[SPARK-6846] [WEBUI] [HOTFIX] return to GET for kill link in UI since YARN AM won't proxy POST
Partial undoing of SPARK-6846; YARN AM proxy won't forward POSTs, so go back to GET for kill links in Spark UI. Standalone UIs are not affected. Author: Sean Owen <sowen@cloudera.com> Closes #5837 from srowen/SPARK-6846.2 and squashes the following commits: c17c386 [Sean Owen] Partial undoing of SPARK-6846; YARN AM proxy won't forward POSTs, so go back to GET for kill links in Spark UI. Standalone UIs are not affected.
-rw-r--r--core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala4
-rw-r--r--core/src/main/scala/org/apache/spark/ui/JettyUtils.scala16
-rw-r--r--core/src/main/scala/org/apache/spark/ui/SparkUI.scala4
-rw-r--r--core/src/main/scala/org/apache/spark/ui/jobs/StageTable.scala7
-rw-r--r--core/src/test/scala/org/apache/spark/ui/UISeleniumSuite.scala5
5 files changed, 23 insertions, 13 deletions
diff --git a/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala b/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala
index aad9c87bdb..dea0a65eee 100644
--- a/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala
@@ -44,9 +44,9 @@ class MasterWebUI(val master: Master, requestedPort: Int)
attachPage(masterPage)
attachHandler(createStaticHandler(MasterWebUI.STATIC_RESOURCE_DIR, "/static"))
attachHandler(createRedirectHandler(
- "/app/kill", "/", masterPage.handleAppKillRequest, httpMethod = "POST"))
+ "/app/kill", "/", masterPage.handleAppKillRequest, httpMethods = Set("POST")))
attachHandler(createRedirectHandler(
- "/driver/kill", "/", masterPage.handleDriverKillRequest, httpMethod = "POST"))
+ "/driver/kill", "/", masterPage.handleDriverKillRequest, httpMethods = Set("POST")))
}
/** Attach a reconstructed UI to this Master UI. Only valid after bind(). */
diff --git a/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala b/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala
index a091ca650c..dfd6fdb5e9 100644
--- a/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala
+++ b/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala
@@ -115,19 +115,21 @@ private[spark] object JettyUtils extends Logging {
destPath: String,
beforeRedirect: HttpServletRequest => Unit = x => (),
basePath: String = "",
- httpMethod: String = "GET"): ServletContextHandler = {
+ httpMethods: Set[String] = Set("GET")): ServletContextHandler = {
val prefixedDestPath = attachPrefix(basePath, destPath)
val servlet = new HttpServlet {
override def doGet(request: HttpServletRequest, response: HttpServletResponse): Unit = {
- httpMethod match {
- case "GET" => doRequest(request, response)
- case _ => response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED)
+ if (httpMethods.contains("GET")) {
+ doRequest(request, response)
+ } else {
+ response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED)
}
}
override def doPost(request: HttpServletRequest, response: HttpServletResponse): Unit = {
- httpMethod match {
- case "POST" => doRequest(request, response)
- case _ => response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED)
+ if (httpMethods.contains("POST")) {
+ doRequest(request, response)
+ } else {
+ response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED)
}
}
private def doRequest(request: HttpServletRequest, response: HttpServletResponse): Unit = {
diff --git a/core/src/main/scala/org/apache/spark/ui/SparkUI.scala b/core/src/main/scala/org/apache/spark/ui/SparkUI.scala
index 580ab8b132..06fce86bd3 100644
--- a/core/src/main/scala/org/apache/spark/ui/SparkUI.scala
+++ b/core/src/main/scala/org/apache/spark/ui/SparkUI.scala
@@ -55,8 +55,10 @@ private[spark] class SparkUI private (
attachTab(new ExecutorsTab(this))
attachHandler(createStaticHandler(SparkUI.STATIC_RESOURCE_DIR, "/static"))
attachHandler(createRedirectHandler("/", "/jobs", basePath = basePath))
+ // This should be POST only, but, the YARN AM proxy won't proxy POSTs
attachHandler(createRedirectHandler(
- "/stages/stage/kill", "/stages", stagesTab.handleKillRequest, httpMethod = "POST"))
+ "/stages/stage/kill", "/stages", stagesTab.handleKillRequest,
+ httpMethods = Set("GET", "POST")))
}
initialize()
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/StageTable.scala b/core/src/main/scala/org/apache/spark/ui/jobs/StageTable.scala
index 6d8c7e1fda..a33243d425 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/StageTable.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/StageTable.scala
@@ -76,15 +76,20 @@ private[ui] class StageTableBase(
val basePathUri = UIUtils.prependBaseUri(basePath)
val killLink = if (killEnabled) {
- val killLinkUri = s"$basePathUri/stages/stage/kill/"
val confirm =
s"if (window.confirm('Are you sure you want to kill stage ${s.stageId} ?')) " +
"{ this.parentNode.submit(); return true; } else { return false; }"
+ // SPARK-6846 this should be POST-only but YARN AM won't proxy POST
+ /*
+ val killLinkUri = s"$basePathUri/stages/stage/kill/"
<form action={killLinkUri} method="POST" style="display:inline">
<input type="hidden" name="id" value={s.stageId.toString}/>
<input type="hidden" name="terminate" value="true"/>
<a href="#" onclick={confirm} class="kill-link">(kill)</a>
</form>
+ */
+ val killLinkUri = s"$basePathUri/stages/stage/kill/?id=${s.stageId}&terminate=true"
+ <a href={killLinkUri} onclick={confirm} class="kill-link">(kill)</a>
}
val nameLinkUri = s"$basePathUri/stages/stage?id=${s.stageId}&attempt=${s.attemptId}"
diff --git a/core/src/test/scala/org/apache/spark/ui/UISeleniumSuite.scala b/core/src/test/scala/org/apache/spark/ui/UISeleniumSuite.scala
index eb9db550fd..d53d7f3ba5 100644
--- a/core/src/test/scala/org/apache/spark/ui/UISeleniumSuite.scala
+++ b/core/src/test/scala/org/apache/spark/ui/UISeleniumSuite.scala
@@ -350,7 +350,7 @@ class UISeleniumSuite extends FunSuite with WebBrowser with Matchers with Before
}
}
- test("kill stage is POST only") {
+ test("kill stage POST/GET response is correct") {
def getResponseCode(url: URL, method: String): Int = {
val connection = url.openConnection().asInstanceOf[HttpURLConnection]
connection.setRequestMethod(method)
@@ -365,7 +365,8 @@ class UISeleniumSuite extends FunSuite with WebBrowser with Matchers with Before
eventually(timeout(5 seconds), interval(50 milliseconds)) {
val url = new URL(
sc.ui.get.appUIAddress.stripSuffix("/") + "/stages/stage/kill/?id=0&terminate=true")
- getResponseCode(url, "GET") should be (405)
+ // SPARK-6846: should be POST only but YARN AM doesn't proxy POST
+ getResponseCode(url, "GET") should be (200)
getResponseCode(url, "POST") should be (200)
}
}