|
27 | 27 | import java.net.MalformedURLException;
|
28 | 28 | import java.net.URL;
|
29 | 29 | import java.net.URLClassLoader;
|
| 30 | +import java.nio.file.FileSystems; |
30 | 31 | import java.nio.file.Files;
|
| 32 | +import java.nio.file.attribute.AclEntry; |
| 33 | +import java.nio.file.attribute.AclEntryPermission; |
31 | 34 | import java.nio.file.attribute.FileAttribute;
|
32 |
| -import java.nio.file.attribute.PosixFilePermission; |
33 | 35 | import java.nio.file.attribute.PosixFilePermissions;
|
| 36 | +import java.nio.file.attribute.UserPrincipal; |
34 | 37 | import java.util.ArrayList;
|
35 | 38 | import java.util.Arrays;
|
| 39 | +import java.util.Collections; |
| 40 | +import java.util.EnumSet; |
36 | 41 | import java.util.Enumeration;
|
37 | 42 | import java.util.List;
|
38 | 43 | import java.util.Set;
|
|
51 | 56 | import org.slf4j.Logger;
|
52 | 57 | import org.slf4j.LoggerFactory;
|
53 | 58 |
|
| 59 | +import static java.nio.file.attribute.AclEntryFlag.DIRECTORY_INHERIT; |
| 60 | +import static java.nio.file.attribute.AclEntryFlag.FILE_INHERIT; |
| 61 | +import static java.nio.file.attribute.AclEntryType.ALLOW; |
| 62 | + |
54 | 63 | /** Run a Hadoop job jar. */
|
55 | 64 | @InterfaceAudience.Private
|
56 | 65 | @InterfaceStability.Unstable
|
@@ -286,25 +295,19 @@ public void run(String[] args) throws Throwable {
|
286 | 295 | }
|
287 | 296 | mainClassName = mainClassName.replaceAll("/", ".");
|
288 | 297 |
|
289 |
| - File tmpDir = new File(System.getProperty("java.io.tmpdir")); |
290 |
| - ensureDirectory(tmpDir); |
291 |
| - |
292 | 298 | final File workDir;
|
293 | 299 | try {
|
294 |
| - FileAttribute<Set<PosixFilePermission>> perms = PosixFilePermissions |
295 |
| - .asFileAttribute(PosixFilePermissions.fromString("rwx------")); |
296 |
| - workDir = Files.createTempDirectory(tmpDir.toPath(), "hadoop-unjar", perms).toFile(); |
| 300 | + workDir = createWorkDirectory(); |
297 | 301 | } catch (IOException | SecurityException e) {
|
298 | 302 | // If user has insufficient perms to write to tmpDir, default
|
299 | 303 | // "Permission denied" message doesn't specify a filename.
|
300 | 304 | System.err.println("Error creating temp dir in java.io.tmpdir "
|
301 |
| - + tmpDir + " due to " + e.getMessage()); |
| 305 | + + System.getProperty("java.io.tmpdir") + " due to " |
| 306 | + + e.getMessage()); |
302 | 307 | System.exit(-1);
|
303 | 308 | return;
|
304 | 309 | }
|
305 | 310 |
|
306 |
| - ensureDirectory(workDir); |
307 |
| - |
308 | 311 | ShutdownHookManager.get().addShutdownHook(
|
309 | 312 | new Runnable() {
|
310 | 313 | @Override
|
@@ -333,6 +336,55 @@ public void run() {
|
333 | 336 | }
|
334 | 337 | }
|
335 | 338 |
|
| 339 | + static File createWorkDirectory() throws IOException { |
| 340 | + File tmpDir = new File(System.getProperty("java.io.tmpdir")); |
| 341 | + ensureDirectory(tmpDir); |
| 342 | + |
| 343 | + File workDir = Files.createTempDirectory(tmpDir.toPath(), "hadoop-unjar", |
| 344 | + directoryPermissions()).toFile(); |
| 345 | + ensureDirectory(workDir); |
| 346 | + return workDir; |
| 347 | + } |
| 348 | + |
| 349 | + private static FileAttribute<?> directoryPermissions() throws IOException { |
| 350 | + Set<String> views = FileSystems.getDefault().supportedFileAttributeViews(); |
| 351 | + if (views.contains("posix")) { |
| 352 | + return PosixFilePermissions |
| 353 | + .asFileAttribute(PosixFilePermissions.fromString("rwx------")); |
| 354 | + } else if (views.contains("acl")) { |
| 355 | + return userOnly(); |
| 356 | + } else { |
| 357 | + throw new IOException("unrecognized FileSystem type " + |
| 358 | + FileSystems.getDefault()); |
| 359 | + } |
| 360 | + } |
| 361 | + |
| 362 | + private static FileAttribute<?> userOnly() throws IOException { |
| 363 | + UserPrincipal user = |
| 364 | + FileSystems.getDefault() |
| 365 | + .getUserPrincipalLookupService() |
| 366 | + .lookupPrincipalByName(System.getProperty("user.name")); |
| 367 | + List<AclEntry> acl = |
| 368 | + Collections.singletonList(AclEntry.newBuilder() |
| 369 | + .setType(ALLOW) |
| 370 | + .setPrincipal(user) |
| 371 | + .setPermissions(EnumSet.allOf(AclEntryPermission.class)) |
| 372 | + .setFlags(DIRECTORY_INHERIT, FILE_INHERIT) |
| 373 | + .build()); |
| 374 | + return |
| 375 | + new FileAttribute<List<AclEntry>>() { |
| 376 | + @Override |
| 377 | + public String name() { |
| 378 | + return "acl:acl"; |
| 379 | + } |
| 380 | + |
| 381 | + @Override |
| 382 | + public List<AclEntry> value() { |
| 383 | + return acl; |
| 384 | + } |
| 385 | + }; |
| 386 | + } |
| 387 | + |
336 | 388 | /**
|
337 | 389 | * Creates a classloader based on the environment that was specified by the
|
338 | 390 | * user. If HADOOP_USE_CLIENT_CLASSLOADER is specified, it creates an
|
|
0 commit comments