From bac46266a97a6096d6d772e023a3362fd48baac0 Mon Sep 17 00:00:00 2001 From: "Y.CORP.YAHOO.COM\\tgraves" Date: Fri, 30 Aug 2013 15:55:32 -0500 Subject: Link the Spark UI to the Yarn UI --- .../cluster/SparkDeploySchedulerBackend.scala | 2 +- core/src/main/scala/spark/ui/SparkUI.scala | 7 +-- core/src/main/scala/spark/ui/UIUtils.scala | 58 +++++++++++++------- core/src/main/scala/spark/ui/jobs/PoolTable.scala | 3 +- core/src/main/scala/spark/ui/jobs/StageTable.scala | 5 +- .../main/scala/spark/ui/storage/IndexPage.scala | 2 +- docs/running-on-yarn.md | 4 ++ .../spark/deploy/yarn/ApplicationMaster.scala | 63 ++++++++++++++++------ .../spark/deploy/yarn/YarnAllocationHandler.scala | 10 +++- .../scheduler/cluster/YarnClusterScheduler.scala | 2 + 10 files changed, 111 insertions(+), 45 deletions(-) diff --git a/core/src/main/scala/spark/scheduler/cluster/SparkDeploySchedulerBackend.scala b/core/src/main/scala/spark/scheduler/cluster/SparkDeploySchedulerBackend.scala index 42c3b4a6cf..8bdc1469e6 100644 --- a/core/src/main/scala/spark/scheduler/cluster/SparkDeploySchedulerBackend.scala +++ b/core/src/main/scala/spark/scheduler/cluster/SparkDeploySchedulerBackend.scala @@ -49,7 +49,7 @@ private[spark] class SparkDeploySchedulerBackend( val sparkHome = sc.getSparkHome().getOrElse( throw new IllegalArgumentException("must supply spark home for spark standalone")) val appDesc = new ApplicationDescription(appName, maxCores, executorMemory, command, sparkHome, - sc.ui.appUIAddress) + sc.ui.appHttpUIAddress) client = new Client(sc.env.actorSystem, master, appDesc, this) client.start() diff --git a/core/src/main/scala/spark/ui/SparkUI.scala b/core/src/main/scala/spark/ui/SparkUI.scala index 23ded44ba3..e078c4a6b2 100644 --- a/core/src/main/scala/spark/ui/SparkUI.scala +++ b/core/src/main/scala/spark/ui/SparkUI.scala @@ -1,5 +1,4 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more +/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 @@ -78,7 +77,9 @@ private[spark] class SparkUI(sc: SparkContext) extends Logging { server.foreach(_.stop()) } - private[spark] def appUIAddress = "http://" + host + ":" + boundPort.getOrElse("-1") + private[spark] def appHttpUIAddress = "http://" + appUIAddress + private[spark] def appUIAddress = host + ":" + boundPort.getOrElse("-1") + } private[spark] object SparkUI { diff --git a/core/src/main/scala/spark/ui/UIUtils.scala b/core/src/main/scala/spark/ui/UIUtils.scala index fe2afc1129..6b45679f9d 100644 --- a/core/src/main/scala/spark/ui/UIUtils.scala +++ b/core/src/main/scala/spark/ui/UIUtils.scala @@ -25,33 +25,53 @@ import spark.SparkContext private[spark] object UIUtils { import Page._ + // Yarn has to go through a proxy so the base uri is provided and has to be on all links + private[spark] val uiRoot : String = Option(System.getenv("APPLICATION_WEB_PROXY_BASE")). + getOrElse("") + + def addBaseUri(resource: String = ""): String = { + return uiRoot + resource + } + + private[spark] val storageStr = addBaseUri("/storage") + private[spark] val stagesStr = addBaseUri("/stages") + private[spark] val envStr = addBaseUri("/environment") + private[spark] val executorsStr = addBaseUri("/executors") + private[spark] val bootstrapMinCssStr = addBaseUri("/static/bootstrap.min.css") + private[spark] val webuiCssStr = addBaseUri("/static/webui.css") + private[spark] val bootstrapResponsiveCssStr = addBaseUri("/static/bootstrap-responsive.min.css") + private[spark] val sortTableStr = addBaseUri("/static/sorttable.js") + private[spark] val sparkLogoHdStr = addBaseUri("/static/spark-logo-77x50px-hd.png") + private[spark] val sparkLogoStr = addBaseUri("/static/spark_logo.png") + + /** Returns a spark page with correctly formatted headers */ def headerSparkPage(content: => Seq[Node], sc: SparkContext, title: String, page: Page.Value) : Seq[Node] = { - val jobs = page match { - case Jobs =>
  • Jobs
  • - case _ =>
  • Jobs
  • - } val storage = page match { - case Storage =>
  • Storage
  • - case _ =>
  • Storage
  • + case Storage =>
  • Storage
  • + case _ =>
  • Storage
  • + } + val jobs = page match { + case Jobs =>
  • Jobs
  • + case _ =>
  • Jobs
  • } val environment = page match { - case Environment =>
  • Environment
  • - case _ =>
  • Environment
  • + case Environment =>
  • Environment
  • + case _ =>
  • Environment
  • } val executors = page match { - case Executors =>
  • Executors
  • - case _ =>
  • Executors
  • + case Executors =>
  • Executors
  • + case _ =>
  • Executors
  • } - - - - + + + + {sc.appName} - {title}