@@ -21,14 +21,15 @@ import java.io.{File, FileInputStream, IOException}
21
21
import java .util .Properties
22
22
23
23
import scala .collection .JavaConversions ._
24
- import scala .collection .mutable .{HashMap , ArrayBuffer }
24
+ import scala .collection .mutable .{ArrayBuffer , HashMap }
25
25
26
26
import org .apache .spark .SparkException
27
+ import org .apache .spark .util .Utils
27
28
28
29
/**
29
30
* Parses and encapsulates arguments from the spark-submit script.
30
31
*/
31
- private [spark] class SparkSubmitArguments (args : Array [String ]) {
32
+ private [spark] class SparkSubmitArguments (args : Seq [String ]) {
32
33
var master : String = null
33
34
var deployMode : String = null
34
35
var executorMemory : String = null
@@ -118,8 +119,7 @@ private[spark] class SparkSubmitArguments(args: Array[String]) {
118
119
119
120
if (master.startsWith(" yarn" )) {
120
121
val hasHadoopEnv = sys.env.contains(" HADOOP_CONF_DIR" ) || sys.env.contains(" YARN_CONF_DIR" )
121
- val testing = sys.env.contains(" SPARK_TESTING" )
122
- if (! hasHadoopEnv && ! testing) {
122
+ if (! hasHadoopEnv && ! Utils .isTesting) {
123
123
throw new Exception (s " When running with master ' $master' " +
124
124
" either HADOOP_CONF_DIR or YARN_CONF_DIR must be set in the environment." )
125
125
}
@@ -156,119 +156,121 @@ private[spark] class SparkSubmitArguments(args: Array[String]) {
156
156
""" .stripMargin
157
157
}
158
158
159
- private def parseOpts (opts : List [String ]): Unit = opts match {
160
- case (" --name" ) :: value :: tail =>
161
- name = value
162
- parseOpts(tail)
159
+ /** Fill in values by parsing user options. */
160
+ private def parseOpts (opts : Seq [String ]): Unit = {
161
+ // Delineates parsing of Spark options from parsing of user options.
162
+ var inSparkOpts = true
163
+ parse(opts)
163
164
164
- case (" --master" ) :: value :: tail =>
165
- master = value
166
- parseOpts(tail)
165
+ def parse (opts : Seq [String ]): Unit = opts match {
166
+ case (" --name" ) :: value :: tail =>
167
+ name = value
168
+ parse(tail)
167
169
168
- case (" --class " ) :: value :: tail =>
169
- mainClass = value
170
- parseOpts (tail)
170
+ case (" --master " ) :: value :: tail =>
171
+ master = value
172
+ parse (tail)
171
173
172
- case (" --deploy-mode" ) :: value :: tail =>
173
- if (value != " client" && value != " cluster" ) {
174
- SparkSubmit .printErrorAndExit(" --deploy-mode must be either \" client\" or \" cluster\" " )
175
- }
176
- deployMode = value
177
- parseOpts(tail)
178
-
179
- case (" --num-executors" ) :: value :: tail =>
180
- numExecutors = value
181
- parseOpts(tail)
182
-
183
- case (" --total-executor-cores" ) :: value :: tail =>
184
- totalExecutorCores = value
185
- parseOpts(tail)
186
-
187
- case (" --executor-cores" ) :: value :: tail =>
188
- executorCores = value
189
- parseOpts(tail)
190
-
191
- case (" --executor-memory" ) :: value :: tail =>
192
- executorMemory = value
193
- parseOpts(tail)
194
-
195
- case (" --driver-memory" ) :: value :: tail =>
196
- driverMemory = value
197
- parseOpts(tail)
198
-
199
- case (" --driver-cores" ) :: value :: tail =>
200
- driverCores = value
201
- parseOpts(tail)
202
-
203
- case (" --driver-class-path" ) :: value :: tail =>
204
- driverExtraClassPath = value
205
- parseOpts(tail)
206
-
207
- case (" --driver-java-options" ) :: value :: tail =>
208
- driverExtraJavaOptions = value
209
- parseOpts(tail)
210
-
211
- case (" --driver-library-path" ) :: value :: tail =>
212
- driverExtraLibraryPath = value
213
- parseOpts(tail)
214
-
215
- case (" --properties-file" ) :: value :: tail =>
216
- propertiesFile = value
217
- parseOpts(tail)
218
-
219
- case (" --supervise" ) :: tail =>
220
- supervise = true
221
- parseOpts(tail)
222
-
223
- case (" --queue" ) :: value :: tail =>
224
- queue = value
225
- parseOpts(tail)
226
-
227
- case (" --files" ) :: value :: tail =>
228
- files = value
229
- parseOpts(tail)
230
-
231
- case (" --archives" ) :: value :: tail =>
232
- archives = value
233
- parseOpts(tail)
234
-
235
- case (" --arg" ) :: value :: tail =>
236
- childArgs += value
237
- parseOpts(tail)
238
-
239
- case (" --jars" ) :: value :: tail =>
240
- jars = value
241
- parseOpts(tail)
242
-
243
- case (" --help" | " -h" ) :: tail =>
244
- printUsageAndExit(0 )
245
-
246
- case (" --verbose" | " -v" ) :: tail =>
247
- verbose = true
248
- parseOpts(tail)
249
-
250
- case value :: tail =>
251
- if (value.startsWith(" -" )) {
252
- val errMessage = s " Unrecognized option ' $value'. "
253
- val suggestion : Option [String ] = value match {
254
- case v if v.startsWith(" --" ) && v.contains(" =" ) =>
255
- val parts = v.split(" =" )
256
- Some (s " Perhaps you want ' ${parts(0 )} ${parts(1 )}'? " )
257
- case _ =>
258
- None
174
+ case (" --class" ) :: value :: tail =>
175
+ mainClass = value
176
+ parse(tail)
177
+
178
+ case (" --deploy-mode" ) :: value :: tail =>
179
+ if (value != " client" && value != " cluster" ) {
180
+ SparkSubmit .printErrorAndExit(" --deploy-mode must be either \" client\" or \" cluster\" " )
181
+ }
182
+ deployMode = value
183
+ parse(tail)
184
+
185
+ case (" --num-executors" ) :: value :: tail =>
186
+ numExecutors = value
187
+ parse(tail)
188
+
189
+ case (" --total-executor-cores" ) :: value :: tail =>
190
+ totalExecutorCores = value
191
+ parse(tail)
192
+
193
+ case (" --executor-cores" ) :: value :: tail =>
194
+ executorCores = value
195
+ parse(tail)
196
+
197
+ case (" --executor-memory" ) :: value :: tail =>
198
+ executorMemory = value
199
+ parse(tail)
200
+
201
+ case (" --driver-memory" ) :: value :: tail =>
202
+ driverMemory = value
203
+ parse(tail)
204
+
205
+ case (" --driver-cores" ) :: value :: tail =>
206
+ driverCores = value
207
+ parse(tail)
208
+
209
+ case (" --driver-class-path" ) :: value :: tail =>
210
+ driverExtraClassPath = value
211
+ parse(tail)
212
+
213
+ case (" --driver-java-options" ) :: value :: tail =>
214
+ driverExtraJavaOptions = value
215
+ parse(tail)
216
+
217
+ case (" --driver-library-path" ) :: value :: tail =>
218
+ driverExtraLibraryPath = value
219
+ parse(tail)
220
+
221
+ case (" --properties-file" ) :: value :: tail =>
222
+ propertiesFile = value
223
+ parse(tail)
224
+
225
+ case (" --supervise" ) :: tail =>
226
+ supervise = true
227
+ parse(tail)
228
+
229
+ case (" --queue" ) :: value :: tail =>
230
+ queue = value
231
+ parse(tail)
232
+
233
+ case (" --files" ) :: value :: tail =>
234
+ files = value
235
+ parse(tail)
236
+
237
+ case (" --archives" ) :: value :: tail =>
238
+ archives = value
239
+ parse(tail)
240
+
241
+ case (" --jars" ) :: value :: tail =>
242
+ jars = value
243
+ parse(tail)
244
+
245
+ case (" --help" | " -h" ) :: tail =>
246
+ printUsageAndExit(0 )
247
+
248
+ case (" --verbose" | " -v" ) :: tail =>
249
+ verbose = true
250
+ parse(tail)
251
+
252
+ case value :: tail =>
253
+ if (inSparkOpts) {
254
+ value match {
255
+ // convert --foo=bar to --foo bar
256
+ case v if v.startsWith(" --" ) && v.contains(" =" ) && v.split(" =" ).size == 2 =>
257
+ val parts = v.split(" =" )
258
+ parse(Seq (parts(0 ), parts(1 )) ++ tail)
259
+ case v if v.startsWith(" -" ) =>
260
+ val errMessage = s " Unrecognized option ' $value'. "
261
+ SparkSubmit .printErrorAndExit(errMessage)
262
+ case v =>
263
+ primaryResource = v
264
+ inSparkOpts = false
265
+ parse(tail)
266
+ }
267
+ } else {
268
+ childArgs += value
269
+ parse(tail)
259
270
}
260
- SparkSubmit .printErrorAndExit(errMessage + suggestion.map(" " + _).getOrElse(" " ))
261
- }
262
271
263
- if (primaryResource != null ) {
264
- val error = s " Found two conflicting resources, $value and $primaryResource. " +
265
- " Expecting only one resource."
266
- SparkSubmit .printErrorAndExit(error)
272
+ case Nil =>
267
273
}
268
- primaryResource = value
269
- parseOpts(tail)
270
-
271
- case Nil =>
272
274
}
273
275
274
276
private def printUsageAndExit (exitCode : Int , unknownParam : Any = null ) {
@@ -277,7 +279,7 @@ private[spark] class SparkSubmitArguments(args: Array[String]) {
277
279
outStream.println(" Unknown/unsupported param " + unknownParam)
278
280
}
279
281
outStream.println(
280
- """ Usage: spark-submit <app jar> [options]
282
+ """ Usage: spark-submit [options] <app jar> [app options]
281
283
|Options:
282
284
| --master MASTER_URL spark://host:port, mesos://host:port, yarn, or local.
283
285
| --deploy-mode DEPLOY_MODE Mode to deploy the app in, either 'client' or 'cluster'.
@@ -296,7 +298,9 @@ private[spark] class SparkSubmitArguments(args: Array[String]) {
296
298
| --driver-memory MEM Memory for driver (e.g. 1000M, 2G) (Default: 512M).
297
299
| --driver-java-options Extra Java options to pass to the driver
298
300
| --driver-library-path Extra library path entries to pass to the driver
299
- | --driver-class-path Extra class path entries to pass to the driver
301
+ | --driver-class-path Extra class path entries to pass to the driver. Note that
302
+ | jars added with --jars are automatically included in the
303
+ | classpath.
300
304
|
301
305
| --executor-memory MEM Memory per executor (e.g. 1000M, 2G) (Default: 1G).
302
306
|
0 commit comments