Merge -c 1296835 from trunk to branch-0.23 to fix MAPREDUCE-3929. Fixed output of 'bin/mapred queue -showacl' command to clarify ACLs for users.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1296836 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
526f466d0c
commit
83e260f273
|
@ -167,6 +167,9 @@ Release 0.23.2 - UNRELEASED
|
||||||
MAPREDUCE-3792. Fix "bin/mapred job -list" to display all jobs instead of
|
MAPREDUCE-3792. Fix "bin/mapred job -list" to display all jobs instead of
|
||||||
only the jobs owned by the user. (Jason Lowe via vinodkv)
|
only the jobs owned by the user. (Jason Lowe via vinodkv)
|
||||||
|
|
||||||
|
MAPREDUCE-3929. Fixed output of 'bin/mapred queue -showacl' command to
|
||||||
|
clarify ACLs for users. (John George via acmurthy)
|
||||||
|
|
||||||
Release 0.23.1 - 2012-02-17
|
Release 0.23.1 - 2012-02-17
|
||||||
|
|
||||||
NEW FEATURES
|
NEW FEATURES
|
||||||
|
|
|
@ -317,11 +317,8 @@ public class ParentQueue implements CSQueue {
|
||||||
QueueUserACLInfo userAclInfo =
|
QueueUserACLInfo userAclInfo =
|
||||||
recordFactory.newRecordInstance(QueueUserACLInfo.class);
|
recordFactory.newRecordInstance(QueueUserACLInfo.class);
|
||||||
List<QueueACL> operations = new ArrayList<QueueACL>();
|
List<QueueACL> operations = new ArrayList<QueueACL>();
|
||||||
for (Map.Entry<QueueACL, AccessControlList> e : acls.entrySet()) {
|
for (QueueACL operation : QueueACL.values()) {
|
||||||
QueueACL operation = e.getKey();
|
if (hasAccess(operation, user)) {
|
||||||
AccessControlList acl = e.getValue();
|
|
||||||
|
|
||||||
if (acl.isUserAllowed(user)) {
|
|
||||||
operations.add(operation);
|
operations.add(operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,6 +340,7 @@ public class ParentQueue implements CSQueue {
|
||||||
for (CSQueue child : childQueues) {
|
for (CSQueue child : childQueues) {
|
||||||
userAcls.addAll(child.getQueueUserAclInfo(user));
|
userAcls.addAll(child.getQueueUserAclInfo(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
return userAcls;
|
return userAcls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import static org.mockito.Mockito.*;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
|
@ -32,6 +34,9 @@ import org.apache.hadoop.yarn.server.resourcemanager.resource.Resources;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.NodeType;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.NodeType;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApp;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNode;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNode;
|
||||||
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
|
import org.apache.hadoop.yarn.api.records.QueueACL;
|
||||||
|
import org.apache.hadoop.yarn.api.records.QueueUserACLInfo;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -255,6 +260,11 @@ public class TestParentQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String C = "c";
|
private static final String C = "c";
|
||||||
|
private static final String C1 = "c1";
|
||||||
|
private static final String C11 = "c11";
|
||||||
|
private static final String C111 = "c111";
|
||||||
|
private static final String C1111 = "c1111";
|
||||||
|
|
||||||
private static final String D = "d";
|
private static final String D = "d";
|
||||||
private static final String A1 = "a1";
|
private static final String A1 = "a1";
|
||||||
private static final String A2 = "a2";
|
private static final String A2 = "a2";
|
||||||
|
@ -265,7 +275,7 @@ public class TestParentQueue {
|
||||||
private void setupMultiLevelQueues(CapacitySchedulerConfiguration conf) {
|
private void setupMultiLevelQueues(CapacitySchedulerConfiguration conf) {
|
||||||
|
|
||||||
// Define top-level queues
|
// Define top-level queues
|
||||||
conf.setQueues(CapacitySchedulerConfiguration.ROOT, new String[] {A, B, C, D});
|
csConf.setQueues(CapacitySchedulerConfiguration.ROOT, new String[] {A, B, C, D});
|
||||||
conf.setCapacity(CapacitySchedulerConfiguration.ROOT, 100);
|
conf.setCapacity(CapacitySchedulerConfiguration.ROOT, 100);
|
||||||
|
|
||||||
final String Q_A = CapacitySchedulerConfiguration.ROOT + "." + A;
|
final String Q_A = CapacitySchedulerConfiguration.ROOT + "." + A;
|
||||||
|
@ -289,10 +299,25 @@ public class TestParentQueue {
|
||||||
conf.setCapacity(Q_B + "." + B1, 10);
|
conf.setCapacity(Q_B + "." + B1, 10);
|
||||||
conf.setCapacity(Q_B + "." + B2, 20);
|
conf.setCapacity(Q_B + "." + B2, 20);
|
||||||
conf.setCapacity(Q_B + "." + B3, 70);
|
conf.setCapacity(Q_B + "." + B3, 70);
|
||||||
|
|
||||||
|
conf.setQueues(Q_C, new String[] {C1});
|
||||||
|
|
||||||
|
final String Q_C1= Q_C + "." + C1;
|
||||||
|
conf.setCapacity(Q_C1, 100);
|
||||||
|
conf.setQueues(Q_C1, new String[] {C11});
|
||||||
|
|
||||||
|
final String Q_C11= Q_C1 + "." + C11;
|
||||||
|
conf.setCapacity(Q_C11, 100);
|
||||||
|
conf.setQueues(Q_C11, new String[] {C111});
|
||||||
|
|
||||||
|
final String Q_C111= Q_C11 + "." + C111;
|
||||||
|
conf.setCapacity(Q_C111, 100);
|
||||||
|
//Leaf Queue
|
||||||
|
conf.setQueues(Q_C111, new String[] {C1111});
|
||||||
|
final String Q_C1111= Q_C111 + "." + C1111;
|
||||||
|
conf.setCapacity(Q_C1111, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultiLevelQueues() throws Exception {
|
public void testMultiLevelQueues() throws Exception {
|
||||||
// Setup queue configs
|
// Setup queue configs
|
||||||
|
@ -470,6 +495,79 @@ public class TestParentQueue {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean hasQueueACL(List<QueueUserACLInfo> aclInfos, QueueACL acl, String qName) {
|
||||||
|
for (QueueUserACLInfo aclInfo : aclInfos) {
|
||||||
|
if (aclInfo.getQueueName().equals(qName)) {
|
||||||
|
if (aclInfo.getUserAcls().contains(acl)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueueAcl() throws Exception {
|
||||||
|
|
||||||
|
setupMultiLevelQueues(csConf);
|
||||||
|
csConf.setAcl(CapacitySchedulerConfiguration.ROOT, QueueACL.SUBMIT_APPLICATIONS, " ");
|
||||||
|
csConf.setAcl(CapacitySchedulerConfiguration.ROOT, QueueACL.ADMINISTER_QUEUE, " ");
|
||||||
|
|
||||||
|
final String Q_C = CapacitySchedulerConfiguration.ROOT + "." + C;
|
||||||
|
csConf.setAcl(Q_C, QueueACL.ADMINISTER_QUEUE, "*");
|
||||||
|
final String Q_C11= Q_C + "." + C1 + "." + C11;
|
||||||
|
csConf.setAcl(Q_C11, QueueACL.SUBMIT_APPLICATIONS, "*");
|
||||||
|
|
||||||
|
Map<String, CSQueue> queues = new HashMap<String, CSQueue>();
|
||||||
|
CSQueue root =
|
||||||
|
CapacityScheduler.parseQueue(csContext, csConf, null,
|
||||||
|
CapacitySchedulerConfiguration.ROOT, queues, queues,
|
||||||
|
CapacityScheduler.queueComparator,
|
||||||
|
CapacityScheduler.applicationComparator,
|
||||||
|
TestUtils.spyHook);
|
||||||
|
|
||||||
|
UserGroupInformation user = UserGroupInformation.getCurrentUser();
|
||||||
|
// Setup queue configs
|
||||||
|
ParentQueue c = (ParentQueue)queues.get(C);
|
||||||
|
ParentQueue c1 = (ParentQueue)queues.get(C1);
|
||||||
|
ParentQueue c11 = (ParentQueue)queues.get(C11);
|
||||||
|
ParentQueue c111 = (ParentQueue)queues.get(C111);
|
||||||
|
|
||||||
|
assertFalse(root.hasAccess(QueueACL.ADMINISTER_QUEUE, user));
|
||||||
|
List<QueueUserACLInfo> aclInfos = root.getQueueUserAclInfo(user);
|
||||||
|
assertFalse(hasQueueACL(aclInfos, QueueACL.ADMINISTER_QUEUE, "root"));
|
||||||
|
|
||||||
|
assertFalse(root.hasAccess(QueueACL.SUBMIT_APPLICATIONS, user));
|
||||||
|
assertFalse(hasQueueACL(aclInfos, QueueACL.SUBMIT_APPLICATIONS, "root"));
|
||||||
|
|
||||||
|
// c has no SA, but QA
|
||||||
|
assertTrue(c.hasAccess(QueueACL.ADMINISTER_QUEUE, user));
|
||||||
|
assertTrue(hasQueueACL(aclInfos, QueueACL.ADMINISTER_QUEUE, "c"));
|
||||||
|
assertFalse(c.hasAccess(QueueACL.SUBMIT_APPLICATIONS, user));
|
||||||
|
assertFalse(hasQueueACL(aclInfos, QueueACL.SUBMIT_APPLICATIONS, "c"));
|
||||||
|
|
||||||
|
//Queue c1 has QA, no SA (gotten perm from parent)
|
||||||
|
assertTrue(c1.hasAccess(QueueACL.ADMINISTER_QUEUE, user));
|
||||||
|
assertTrue(hasQueueACL(aclInfos, QueueACL.ADMINISTER_QUEUE, "c1"));
|
||||||
|
assertFalse(c1.hasAccess(QueueACL.SUBMIT_APPLICATIONS, user));
|
||||||
|
assertFalse(hasQueueACL(aclInfos, QueueACL.SUBMIT_APPLICATIONS, "c1"));
|
||||||
|
|
||||||
|
//Queue c11 has permissions from parent queue and SA
|
||||||
|
assertTrue(c11.hasAccess(QueueACL.ADMINISTER_QUEUE, user));
|
||||||
|
assertTrue(hasQueueACL(aclInfos, QueueACL.ADMINISTER_QUEUE, "c11"));
|
||||||
|
assertTrue(c11.hasAccess(QueueACL.SUBMIT_APPLICATIONS, user));
|
||||||
|
assertTrue(hasQueueACL(aclInfos, QueueACL.SUBMIT_APPLICATIONS, "c11"));
|
||||||
|
|
||||||
|
//Queue c111 has SA and AQ, both from parent
|
||||||
|
assertTrue(c111.hasAccess(QueueACL.ADMINISTER_QUEUE, user));
|
||||||
|
assertTrue(hasQueueACL(aclInfos, QueueACL.ADMINISTER_QUEUE, "c111"));
|
||||||
|
assertTrue(c111.hasAccess(QueueACL.SUBMIT_APPLICATIONS, user));
|
||||||
|
assertTrue(hasQueueACL(aclInfos, QueueACL.SUBMIT_APPLICATIONS, "c111"));
|
||||||
|
|
||||||
|
reset(c);
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue