diff --git a/CHANGES.txt b/CHANGES.txt index 7a2ece8c717..f6817db02c2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -20,6 +20,8 @@ Trunk (unreleased changes) HADOOP-6994. Api to get delegation token in AbstractFileSystem. (jitendra) + HADOOP-7171. Support UGI in FileContext API. (jitendra) + IMPROVEMENTS HADOOP-7042. Updates to test-patch.sh to include failed test names and diff --git a/src/java/org/apache/hadoop/fs/FileContext.java b/src/java/org/apache/hadoop/fs/FileContext.java index e3163ea75e5..38cb98e5d4f 100644 --- a/src/java/org/apache/hadoop/fs/FileContext.java +++ b/src/java/org/apache/hadoop/fs/FileContext.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; @@ -50,6 +51,7 @@ import org.apache.hadoop.ipc.RpcServerException; import org.apache.hadoop.ipc.UnexpectedServerException; import org.apache.hadoop.fs.InvalidPathException; import org.apache.hadoop.security.AccessControlException; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.token.Token; /** @@ -196,12 +198,20 @@ public final class FileContext { private Path workingDir; // Fully qualified private FsPermission umask; private final Configuration conf; + private final UserGroupInformation ugi; private FileContext(final AbstractFileSystem defFs, final FsPermission theUmask, final Configuration aConf) { defaultFS = defFs; umask = FsPermission.getUMask(aConf); conf = aConf; + try { + ugi = UserGroupInformation.getCurrentUser(); + } catch (IOException e) { + LOG.error("Exception in getCurrentUser: ",e); + throw new RuntimeException("Failed to get the current user " + + "while creating a FileContext", e); + } /* * Init the wd. * WorkingDir is implemented at the FileContext layer @@ -276,9 +286,11 @@ public final class FileContext { * * @throws UnsupportedFileSystemException If the file system for * absOrFqPath is not supported. + * @throws IOExcepton If the file system for absOrFqPath could + * not be instantiated. */ private AbstractFileSystem getFSofPath(final Path absOrFqPath) - throws UnsupportedFileSystemException { + throws UnsupportedFileSystemException, IOException { checkNotSchemeWithRelative(absOrFqPath); if (!absOrFqPath.isAbsolute() && absOrFqPath.toUri().getScheme() == null) { throw new HadoopIllegalArgumentException( @@ -290,10 +302,25 @@ public final class FileContext { defaultFS.checkPath(absOrFqPath); return defaultFS; } catch (Exception e) { // it is different FileSystem - return AbstractFileSystem.get(absOrFqPath.toUri(), conf); + return getAbstractFileSystem(ugi, absOrFqPath.toUri(), conf); } } + private static AbstractFileSystem getAbstractFileSystem( + UserGroupInformation user, final URI uri, final Configuration conf) + throws UnsupportedFileSystemException, IOException { + try { + return user.doAs(new PrivilegedExceptionAction() { + public AbstractFileSystem run() throws UnsupportedFileSystemException { + return AbstractFileSystem.get(uri, conf); + } + }); + } catch (InterruptedException ex) { + LOG.error(ex); + throw new IOException("Failed to get the AbstractFileSystem for path: " + + uri, ex); + } + } /** * Protected Static Factory methods for getting a FileContexts @@ -390,10 +417,23 @@ public final class FileContext { * @return new FileContext for specified uri * @throws UnsupportedFileSystemException If the file system with specified is * not supported + * @throws RuntimeException If the file system specified is supported but + * could not be instantiated, or if login fails. */ public static FileContext getFileContext(final URI defaultFsUri, final Configuration aConf) throws UnsupportedFileSystemException { - return getFileContext(AbstractFileSystem.get(defaultFsUri, aConf), aConf); + UserGroupInformation currentUser = null; + AbstractFileSystem defaultAfs = null; + try { + currentUser = UserGroupInformation.getCurrentUser(); + defaultAfs = getAbstractFileSystem(currentUser, defaultFsUri, aConf); + } catch (UnsupportedFileSystemException ex) { + throw ex; + } catch (IOException ex) { + LOG.error(ex); + throw new RuntimeException(ex); + } + return getFileContext(defaultAfs, aConf); } /** @@ -477,6 +517,14 @@ public final class FileContext { return workingDir; } + /** + * Gets the ugi in the file-context + * @return UserGroupInformation + */ + public UserGroupInformation getUgi() { + return ugi; + } + /** * * @return the umask of this FileContext diff --git a/src/test/core/org/apache/hadoop/fs/FileContextPermissionBase.java b/src/test/core/org/apache/hadoop/fs/FileContextPermissionBase.java index 203485eaa03..0e225325812 100644 --- a/src/test/core/org/apache/hadoop/fs/FileContextPermissionBase.java +++ b/src/test/core/org/apache/hadoop/fs/FileContextPermissionBase.java @@ -18,6 +18,7 @@ package org.apache.hadoop.fs; import java.io.IOException; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; @@ -25,6 +26,7 @@ import java.util.StringTokenizer; import junit.framework.Assert; import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.Shell; import org.apache.hadoop.util.StringUtils; import org.junit.After; @@ -32,6 +34,7 @@ import org.junit.Before; import org.junit.Test; import static org.apache.hadoop.fs.FileContextTestHelper.*; +import static org.junit.Assert.assertEquals; /** *

@@ -162,6 +165,22 @@ public abstract class FileContextPermissionBase { } finally {cleanupFile(fc, f);} } + + @Test + public void testUgi() throws IOException, InterruptedException { + + UserGroupInformation otherUser = UserGroupInformation + .createRemoteUser("otherUser"); + FileContext newFc = otherUser.doAs(new PrivilegedExceptionAction() { + + public FileContext run() throws Exception { + FileContext newFc = FileContext.getFileContext(); + return newFc; + } + + }); + assertEquals("otherUser",newFc.getUgi().getUserName()); + } static List getGroups() throws IOException { List a = new ArrayList();