diff --git common/src/java/org/apache/hadoop/hive/common/FileUtils.java common/src/java/org/apache/hadoop/hive/common/FileUtils.java index ee61350..3bad095 100644 --- common/src/java/org/apache/hadoop/hive/common/FileUtils.java +++ common/src/java/org/apache/hadoop/hive/common/FileUtils.java @@ -588,4 +588,37 @@ public static boolean moveToTrash(FileSystem fs, Path f, Configuration conf) thr return result; } + public static boolean renameAndInheritParentPermissions(FileSystem fs, Path sourcePath, + Path destPath, boolean inheritPerms, + Configuration conf) throws IOException { + LOG.info("Copying " + sourcePath + " to " + destPath); + if (!inheritPerms) { + //just rename the directory + return fs.rename(sourcePath, destPath); + } else { + //inherit perms: need to find parent pathOfExistingParent, and apply its permission on entire subtree. + Path pathOfExistingParent = destPath.getParent(); + FsPermission parentPerm = fs.getFileStatus(pathOfExistingParent).getPermission(); + + //rename the directory + if (fs.rename(sourcePath, destPath)) { + + String permString = Integer.toString(parentPerm.toShort(), 8); + FsShell fsShell = new FsShell(); + fsShell.setConf(conf); + LOG.debug("Setting permission " + permString + " of parent directory: " + pathOfExistingParent.toString() + + " on new directory: " + destPath.toString() + " recursively"); + try { + fsShell.run(new String[]{"-chmod", "-R", permString, destPath.toString()}); + } catch (Exception e) { + LOG.warn("Error setting permissions of " + destPath, e); + } + + return true; + } + + return false; + } + } + } diff --git itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/TestFolderPermissions.java itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/TestFolderPermissions.java index 4f566d2..b462117 100644 --- itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/TestFolderPermissions.java +++ itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/TestFolderPermissions.java @@ -147,6 +147,35 @@ public void testStaticPartitionPerms() throws Exception { } @Test + public void testAlterSinglePartitionPerms() throws Exception { + String tableName = "alterSinglepart"; + CommandProcessorResponse ret = driver.run("CREATE TABLE " + tableName + " (key string, value string) partitioned by (part int)"); + Assert.assertEquals(0,ret.getResponseCode()); + + assertExistence(testDir + "/" + tableName); + setPermissions(testDir + "/" + tableName, FsPermission.createImmutable((short) 0777)); + + ret = driver.run("insert into table " + tableName + " partition(part='1') select key,value from mysrc"); + Assert.assertEquals(0,ret.getResponseCode()); + + Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part=1").toString()); + + //change permission of table + setPermissions(testDir + "/" + tableName, FsPermission.createImmutable((short) 0755)); + + //alter partition + ret = driver.run("alter table " + tableName + " partition (part='1') rename to partition (part='2')"); + Assert.assertEquals(0,ret.getResponseCode()); + + Assert.assertEquals("rwxr-xr-x", getPermissions(testDir + "/" + tableName + "/part=2").toString()); + + Assert.assertTrue(listChildrenPerms(testDir + "/" + tableName + "/part=2").size() > 0); + for (FsPermission perm : listChildrenPerms(testDir + "/" + tableName + "/part=2")) { + Assert.assertEquals("rwxr-xr-x", perm.toString()); + } + } + + @Test public void testAlterPartitionPerms() throws Exception { String tableName = "alterpart"; CommandProcessorResponse ret = driver.run("CREATE TABLE " + tableName + " (key string, value string) partitioned by (part1 int, part2 int, part3 int)"); @@ -158,17 +187,24 @@ public void testAlterPartitionPerms() throws Exception { ret = driver.run("insert into table " + tableName + " partition(part1='1',part2='1',part3='1') select key,value from mysrc"); Assert.assertEquals(0,ret.getResponseCode()); + Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part1=1").toString()); + Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part1=1/part2=1").toString()); + Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part1=1/part2=1/part3=1").toString()); + + //change permission of table + setPermissions(testDir + "/" + tableName, FsPermission.createImmutable((short) 0755)); + //alter partition ret = driver.run("alter table " + tableName + " partition (part1='1',part2='1',part3='1') rename to partition (part1='2',part2='2',part3='2')"); Assert.assertEquals(0,ret.getResponseCode()); - Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part1=2").toString()); - Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part1=2/part2=2").toString()); - Assert.assertEquals("rwxrwxrwx", getPermissions(testDir + "/" + tableName + "/part1=2/part2=2/part3=2").toString()); + Assert.assertEquals("rwxr-xr-x", getPermissions(testDir + "/" + tableName + "/part1=2").toString()); + Assert.assertEquals("rwxr-xr-x", getPermissions(testDir + "/" + tableName + "/part1=2/part2=2").toString()); + Assert.assertEquals("rwxr-xr-x", getPermissions(testDir + "/" + tableName + "/part1=2/part2=2/part3=2").toString()); Assert.assertTrue(listChildrenPerms(testDir + "/" + tableName + "/part1=2/part2=2/part3=2").size() > 0); for (FsPermission perm : listChildrenPerms(testDir + "/" + tableName + "/part1=2/part2=2/part3=2")) { - Assert.assertEquals("rwxrwxrwx", perm.toString()); + Assert.assertEquals("rwxr-xr-x", perm.toString()); } } diff --git metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java index 221b010..3126880 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java @@ -398,7 +398,7 @@ public Partition alterPartition(final RawStore msdb, Warehouse wh, final String if (!wh.mkdirs(destParentPath, true)) { throw new IOException("Unable to create path " + destParentPath); } - srcFs.rename(srcPath, destPath); + wh.renameDir(srcPath, destPath, true); LOG.info("rename done!"); } } catch (IOException e) { diff --git metastore/src/java/org/apache/hadoop/hive/metastore/Warehouse.java metastore/src/java/org/apache/hadoop/hive/metastore/Warehouse.java index c1790b4..3497f9c 100755 --- metastore/src/java/org/apache/hadoop/hive/metastore/Warehouse.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/Warehouse.java @@ -198,10 +198,14 @@ public boolean mkdirs(Path f, boolean inheritPermCandidate) throws MetaException } public boolean renameDir(Path sourcePath, Path destPath) throws MetaException { + return renameDir(sourcePath, destPath, false); + } + + public boolean renameDir(Path sourcePath, Path destPath, boolean inheritPerms) throws MetaException { FileSystem fs = null; try { fs = getFs(sourcePath); - fs.rename(sourcePath, destPath); + FileUtils.renameAndInheritParentPermissions(fs, sourcePath, destPath, inheritPerms, conf); return true; } catch (Exception ex) { MetaStoreUtils.logAndThrowMetaException(ex);