Skip to content

Commit 7c0e2eb

Browse files
dongjoon-hyunilicmarkodb
authored andcommitted
[SPARK-49007][CORE] Improve MasterPage to support custom title
### What changes were proposed in this pull request? This PR aims to improve `MasterPage` to support custom title. ### Why are the changes needed? When there exists multiple Spark clusters, custom title can be more helpful than the spark master address because it can contain semantics like the role of the clusters. In addition, the URL field in the same page already provides the spark master information even when we use a custom title. **BEFORE** ``` sbin/start-master.sh ``` ![Screenshot 2024-07-25 at 14 01 11](https://github.com/user-attachments/assets/7055d700-4bd6-4785-a535-2f8ce6dba47d) **AFTER** ``` SPARK_MASTER_OPTS='-Dspark.master.ui.title="Projext X Staging Cluster"' sbin/start-master.sh ``` ![Screenshot 2024-07-25 at 14 05 38](https://github.com/user-attachments/assets/f7e45fd6-fa2b-4547-ae39-1403b1e910d9) ### Does this PR introduce _any_ user-facing change? ### How was this patch tested? Pass the CIs with newly added test case. ### Was this patch authored or co-authored using generative AI tooling? No. Closes apache#47491 from dongjoon-hyun/SPARK-49007. Authored-by: Dongjoon Hyun <dhyun@apple.com> Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
1 parent 533ef2d commit 7c0e2eb

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ import org.apache.spark.deploy.DeployMessages.{KillDriverResponse, MasterStateRe
2626
import org.apache.spark.deploy.JsonProtocol
2727
import org.apache.spark.deploy.StandaloneResourceUtils._
2828
import org.apache.spark.deploy.master._
29+
import org.apache.spark.internal.config.UI.MASTER_UI_TITLE
2930
import org.apache.spark.ui.{UIUtils, WebUIPage}
3031
import org.apache.spark.util.Utils
3132

3233
private[ui] class MasterPage(parent: MasterWebUI) extends WebUIPage("") {
3334
private val master = parent.masterEndpointRef
35+
private val title = parent.master.conf.get(MASTER_UI_TITLE)
3436
private val jsonFieldPattern = "/json/([a-zA-Z]+).*".r
3537

3638
def getMasterState: MasterStateResponse = {
@@ -266,7 +268,7 @@ private[ui] class MasterPage(parent: MasterWebUI) extends WebUIPage("") {
266268
}
267269
</div>;
268270

269-
UIUtils.basicSparkPage(request, content, "Spark Master at " + state.uri)
271+
UIUtils.basicSparkPage(request, content, title.getOrElse("Spark Master at " + state.uri))
270272
}
271273

272274
private def workerRow(showResourceColumn: Boolean): WorkerInfo => Seq[Node] = worker => {

core/src/main/scala/org/apache/spark/internal/config/UI.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,13 @@ private[spark] object UI {
244244
.checkValues(Set("ALLOW", "LOCAL", "DENY"))
245245
.createWithDefault("LOCAL")
246246

247+
val MASTER_UI_TITLE = ConfigBuilder("spark.master.ui.title")
248+
.version("4.0.0")
249+
.doc("Specifies the title of the Master UI page. If unset, `Spark Master at <MasterURL>` " +
250+
"is used by default.")
251+
.stringConf
252+
.createOptional
253+
247254
val UI_SQL_GROUP_SUB_EXECUTION_ENABLED = ConfigBuilder("spark.ui.groupSQLSubExecutionEnabled")
248255
.doc("Whether to group sub executions together in SQL UI when they belong to the same " +
249256
"root execution")

core/src/test/scala/org/apache/spark/deploy/master/MasterWorkerUISuite.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,22 @@ class MasterWorkerUISuite extends MasterSuiteBase {
140140
System.getProperties().remove("spark.ui.proxyBase")
141141
}
142142
}
143+
144+
test("SPARK-49007: Support custom master web ui title") {
145+
implicit val formats = org.json4s.DefaultFormats
146+
val title = "Spark Custom Title"
147+
val conf = new SparkConf().set(MASTER_UI_TITLE, title)
148+
val localCluster = LocalSparkCluster(2, 2, 512, conf)
149+
localCluster.start()
150+
val masterUrl = s"http://${Utils.localHostNameForURI()}:${localCluster.masterWebUIPort}"
151+
try {
152+
eventually(timeout(50.seconds), interval(100.milliseconds)) {
153+
val html = Utils
154+
.tryWithResource(Source.fromURL(s"$masterUrl/"))(_.getLines().mkString("\n"))
155+
html should include (title)
156+
}
157+
} finally {
158+
localCluster.stop()
159+
}
160+
}
143161
}

0 commit comments

Comments
 (0)