@@ -21,6 +21,7 @@ import java.io.File
2121import java .net .{InetAddress , UnknownHostException , URI , URISyntaxException }
2222import java .nio .ByteBuffer
2323import java .nio .file .Files
24+ import java .util .UUID
2425
2526import scala .collection .JavaConversions ._
2627import scala .collection .mutable .{ArrayBuffer , HashMap , ListBuffer , Map }
@@ -222,8 +223,10 @@ private[spark] class Client(
222223 // and add them as local resources to the application master.
223224 val fs = FileSystem .get(hadoopConf)
224225 val dst = new Path (fs.getHomeDirectory(), appStagingDir)
225- val nns = getNameNodesToAccess(sparkConf) + dst
226- obtainTokensForNamenodes(nns, hadoopConf, credentials)
226+ val nns =
227+ SparkHadoopUtil .get.asInstanceOf [YarnSparkHadoopUtil ].getNameNodesToAccess(sparkConf) + dst
228+ SparkHadoopUtil .get.asInstanceOf [YarnSparkHadoopUtil ].
229+ obtainTokensForNamenodes(nns, hadoopConf, credentials)
227230
228231 val replication = sparkConf.getInt(" spark.yarn.submit.file.replication" ,
229232 fs.getDefaultReplication(dst)).toShort
@@ -240,6 +243,20 @@ private[spark] class Client(
240243 " for alternatives." )
241244 }
242245
246+ // If we passed in a keytab, make sure we copy the keytab to the staging directory on
247+ // HDFS, and setup the relevant environment vars, so the AM can login again.
248+ if (loginFromKeytab) {
249+ val fs = FileSystem .get(hadoopConf)
250+ val stagingDirPath = new Path (fs.getHomeDirectory, appStagingDir)
251+ val localUri = new URI (args.keytab)
252+ val localPath = getQualifiedLocalPath(localUri, hadoopConf)
253+ val destinationPath = new Path (stagingDirPath, keytabFileName)
254+ copyFileToRemote(destinationPath, localPath, replication)
255+ distCacheMgr.addResource(
256+ fs, hadoopConf, destinationPath, localResources, LocalResourceType .FILE , keytabFileName,
257+ statCache, appMasterOnly = true )
258+ }
259+
243260 /**
244261 * Copy the given main resource to the distributed cache if the scheme is not "local".
245262 * Otherwise, set the corresponding key in our SparkConf to handle it downstream.
@@ -320,22 +337,11 @@ private[spark] class Client(
320337 env(" SPARK_YARN_MODE" ) = " true"
321338 env(" SPARK_YARN_STAGING_DIR" ) = stagingDir
322339 env(" SPARK_USER" ) = UserGroupInformation .getCurrentUser().getShortUserName()
323- // If we logged in from keytab, make sure we copy the keytab to the staging directory on
324- // HDFS, and setup the relevant environment vars, so the AM can login again.
325340 if (loginFromKeytab) {
326- val fs = FileSystem .get(hadoopConf)
327- val stagingDirPath = new Path (fs.getHomeDirectory, stagingDir)
328- val localUri = new URI (args.keytab)
329- val localPath = getQualifiedLocalPath(localUri, hadoopConf)
330- val destinationPath = new Path (stagingDirPath, keytabFileName)
331- val replication = sparkConf.getInt(" spark.yarn.submit.file.replication" ,
332- fs.getDefaultReplication(destinationPath)).toShort
333- copyFileToRemote(destinationPath, localPath, replication)
334341 env(" SPARK_PRINCIPAL" ) = args.principal
335342 env(" SPARK_KEYTAB" ) = keytabFileName
336343 }
337344
338-
339345 // Set the environment variables to be passed on to the executors.
340346 distCacheMgr.setDistFilesEnv(env)
341347 distCacheMgr.setDistArchivesEnv(env)
@@ -571,7 +577,7 @@ private[spark] class Client(
571577 val f = new File (args.keytab)
572578 // Generate a file name that can be used for the keytab file, that does not conflict
573579 // with any user file.
574- keytabFileName = f.getName + " -" + System .currentTimeMillis ()
580+ keytabFileName = f.getName + " -" + UUID .randomUUID ()
575581 val ugi = UserGroupInformation .loginUserFromKeytabAndReturnUGI(args.principal, args.keytab)
576582 credentials = ugi.getCredentials
577583 loginFromKeytab = true
@@ -903,28 +909,6 @@ object Client extends Logging {
903909 private def addClasspathEntry (path : String , env : HashMap [String , String ]): Unit =
904910 YarnSparkHadoopUtil .addPathToEnvironment(env, Environment .CLASSPATH .name, path)
905911
906- /**
907- * Get the list of namenodes the user may access.
908- */
909- private [yarn] def getNameNodesToAccess (sparkConf : SparkConf ): Set [Path ] = {
910- SparkHadoopUtil .get.asInstanceOf [YarnSparkHadoopUtil ].getNameNodesToAccess(sparkConf)
911- }
912-
913- private [yarn] def getTokenRenewer (conf : Configuration ): String = {
914- SparkHadoopUtil .get.asInstanceOf [YarnSparkHadoopUtil ].getTokenRenewer(conf)
915- }
916-
917- /**
918- * Obtains tokens for the namenodes passed in and adds them to the credentials.
919- */
920- private def obtainTokensForNamenodes (
921- paths : Set [Path ],
922- conf : Configuration ,
923- creds : Credentials ): Unit = {
924- SparkHadoopUtil .get.asInstanceOf [YarnSparkHadoopUtil ]
925- .obtainTokensForNamenodes(paths, conf, creds)
926- }
927-
928912 /**
929913 * Return whether the two file systems are the same.
930914 */
0 commit comments