aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/scala/org/apache/spark/deploy/ClientArguments.scala
blob: db67c6d1bb55c58069a23a7d2d3abb01a4d2a1ea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * 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
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.spark.deploy

import java.net.URL

import scala.collection.mutable.ListBuffer

import org.apache.log4j.Level

/**
 * Command-line parser for the driver client.
 */
private[spark] class ClientArguments(args: Array[String]) {
  val defaultCores = 1
  val defaultMemory = 512

  var cmd: String = "" // 'launch' or 'kill'
  var logLevel = Level.WARN

  // launch parameters
  var master: String = ""
  var jarUrl: String = ""
  var mainClass: String = ""
  var supervise: Boolean = false
  var memory: Int = defaultMemory
  var cores: Int = defaultCores
  private var _driverOptions = ListBuffer[String]()
  def driverOptions = _driverOptions.toSeq

  // kill parameters
  var driverId: String = ""
  
  parse(args.toList)

  def parse(args: List[String]): Unit = args match {
    case ("--cores" | "-c") :: value :: tail =>
      cores = value.toInt
      parse(tail)

    case ("--memory" | "-m") :: value :: tail =>
      memory = value.toInt
      parse(tail)

    case ("--supervise" | "-s") :: tail =>
      supervise = true
      parse(tail)

    case ("--help" | "-h") :: tail =>
      printUsageAndExit(0)

    case ("--verbose" | "-v") :: tail =>
      logLevel = Level.INFO
      parse(tail)

    case "launch" :: _master :: _jarUrl :: _mainClass :: tail =>
      cmd = "launch"

      try {
        new URL(_jarUrl)
      } catch {
        case e: Exception =>
          println(s"Jar url '${_jarUrl}' is not a valid URL.")
          println(s"Jar must be in URL format (e.g. hdfs://XX, file://XX)")
          printUsageAndExit(-1)
      }

      jarUrl = _jarUrl
      master = _master
      mainClass = _mainClass
      _driverOptions ++= tail

    case "kill" :: _master :: _driverId :: tail =>
      cmd = "kill"
      master = _master
      driverId = _driverId

    case _ =>
      printUsageAndExit(1)
  }

  /**
   * Print usage and exit JVM with the given exit code.
   */
  def printUsageAndExit(exitCode: Int) {
    // TODO: It wouldn't be too hard to allow users to submit their app and dependency jars
    //       separately similar to in the YARN client.
    val usage =
      s"""
        |Usage: DriverClient [options] launch <active-master> <jar-url> <main-class> [driver options]
        |Usage: DriverClient kill <active-master> <driver-id>
        |
        |Options:
        |   -c CORES, --cores CORES        Number of cores to request (default: $defaultCores)
        |   -m MEMORY, --memory MEMORY     Megabytes of memory to request (default: $defaultMemory)
        |   -s, --supervise                Whether to restart the driver on failure
        |   -v, --verbose                  Print more debugging output
      """.stripMargin
    System.err.println(usage)
    System.exit(exitCode)
  }
}