YARN-288. Fair scheduler queue doesn't accept any jobs when ACLs are configured. Contributed by Sandy Ryza.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1428362 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ba90c9c867
commit
19a291a0d6
|
@ -158,6 +158,9 @@ Release 2.0.3-alpha - Unreleased
|
||||||
YARN-192. Node update causes NPE in the fair scheduler.
|
YARN-192. Node update causes NPE in the fair scheduler.
|
||||||
(Sandy Ryza via tomwhite)
|
(Sandy Ryza via tomwhite)
|
||||||
|
|
||||||
|
YARN-288. Fair scheduler queue doesn't accept any jobs when ACLs are
|
||||||
|
configured. (Sandy Ryza via tomwhite)
|
||||||
|
|
||||||
Release 2.0.2-alpha - 2012-09-07
|
Release 2.0.2-alpha - 2012-09-07
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -99,20 +99,6 @@ public class FSParentQueue extends FSQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAccess(QueueACL acl, UserGroupInformation user) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (getQueueAcls().get(acl).isUserAllowed(user)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent != null) {
|
|
||||||
return parent.hasAccess(acl, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized QueueUserACLInfo getUserAclInfo(
|
private synchronized QueueUserACLInfo getUserAclInfo(
|
||||||
UserGroupInformation user) {
|
UserGroupInformation user) {
|
||||||
QueueUserACLInfo userAclInfo =
|
QueueUserACLInfo userAclInfo =
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.authorize.AccessControlList;
|
import org.apache.hadoop.security.authorize.AccessControlList;
|
||||||
import org.apache.hadoop.yarn.api.records.Priority;
|
import org.apache.hadoop.yarn.api.records.Priority;
|
||||||
import org.apache.hadoop.yarn.api.records.QueueACL;
|
import org.apache.hadoop.yarn.api.records.QueueACL;
|
||||||
|
@ -118,6 +119,16 @@ public abstract class FSQueue extends Schedulable implements Queue {
|
||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasAccess(QueueACL acl, UserGroupInformation user) {
|
||||||
|
// Check if the leaf-queue allows access
|
||||||
|
if (queueMgr.getQueueAcls(getName()).get(acl).isUserAllowed(user)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if parent-queue allows access
|
||||||
|
return parent != null && parent.hasAccess(acl, user);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recomputes the fair shares for all queues and applications
|
* Recomputes the fair shares for all queues and applications
|
||||||
* under this queue.
|
* under this queue.
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate;
|
import org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.security.AccessControlException;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.yarn.Clock;
|
import org.apache.hadoop.yarn.Clock;
|
||||||
import org.apache.hadoop.yarn.SystemClock;
|
import org.apache.hadoop.yarn.SystemClock;
|
||||||
|
@ -494,24 +495,15 @@ public class FairScheduler implements ResourceScheduler {
|
||||||
new FSSchedulerApp(applicationAttemptId, user,
|
new FSSchedulerApp(applicationAttemptId, user,
|
||||||
queue, new ActiveUsersManager(getRootQueueMetrics()),
|
queue, new ActiveUsersManager(getRootQueueMetrics()),
|
||||||
rmContext);
|
rmContext);
|
||||||
|
|
||||||
// Enforce ACLs
|
// Enforce ACLs
|
||||||
UserGroupInformation userUgi;
|
UserGroupInformation userUgi = UserGroupInformation.createRemoteUser(user);
|
||||||
try {
|
if (!queue.hasAccess(QueueACL.SUBMIT_APPLICATIONS, userUgi)) {
|
||||||
userUgi = UserGroupInformation.getCurrentUser();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
LOG.info("Failed to get current user information");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always a singleton list
|
|
||||||
List<QueueUserACLInfo> info = queue.getQueueUserAclInfo(userUgi);
|
|
||||||
if (!info.get(0).getUserAcls().contains(QueueACL.SUBMIT_APPLICATIONS)) {
|
|
||||||
LOG.info("User " + userUgi.getUserName() +
|
LOG.info("User " + userUgi.getUserName() +
|
||||||
" cannot submit" + " applications to queue " + queue.getName());
|
" cannot submit applications to queue " + queue.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.addApp(schedulerApp);
|
queue.addApp(schedulerApp);
|
||||||
queue.getMetrics().submitApp(user, applicationAttemptId.getAttemptId());
|
queue.getMetrics().submitApp(user, applicationAttemptId.getAttemptId());
|
||||||
|
|
||||||
|
|
|
@ -387,6 +387,16 @@ public class QueueManager {
|
||||||
queueMaxApps, userMaxApps, queueWeights, userMaxAppsDefault,
|
queueMaxApps, userMaxApps, queueWeights, userMaxAppsDefault,
|
||||||
queueMaxAppsDefault, defaultSchedulingMode, minSharePreemptionTimeouts,
|
queueMaxAppsDefault, defaultSchedulingMode, minSharePreemptionTimeouts,
|
||||||
queueAcls, fairSharePreemptionTimeout, defaultMinSharePreemptionTimeout);
|
queueAcls, fairSharePreemptionTimeout, defaultMinSharePreemptionTimeout);
|
||||||
|
|
||||||
|
// Root queue should have empty ACLs. As a queue's ACL is the union of
|
||||||
|
// its ACL and all its parents' ACLs, setting the roots' to empty will
|
||||||
|
// neither allow nor prohibit more access to its children.
|
||||||
|
Map<QueueACL, AccessControlList> rootAcls =
|
||||||
|
new HashMap<QueueACL, AccessControlList>();
|
||||||
|
rootAcls.put(QueueACL.SUBMIT_APPLICATIONS, new AccessControlList(" "));
|
||||||
|
rootAcls.put(QueueACL.ADMINISTER_QUEUE, new AccessControlList(" "));
|
||||||
|
queueAcls.put(ROOT_QUEUE, rootAcls);
|
||||||
|
|
||||||
for (String name: queueNamesInAllocFile) {
|
for (String name: queueNamesInAllocFile) {
|
||||||
FSLeafQueue queue = getLeafQueue(name);
|
FSLeafQueue queue = getLeafQueue(name);
|
||||||
if (queueModes.containsKey(name)) {
|
if (queueModes.containsKey(name)) {
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair;
|
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1243,4 +1245,34 @@ public class TestFairScheduler {
|
||||||
Assert.assertEquals(2, liveContainer.getContainer().getPriority().getPriority());
|
Assert.assertEquals(2, liveContainer.getContainer().getPriority().getPriority());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAclSubmitApplication() throws Exception {
|
||||||
|
// Set acl's
|
||||||
|
Configuration conf = createConfiguration();
|
||||||
|
conf.set(FairSchedulerConfiguration.ALLOCATION_FILE, ALLOC_FILE);
|
||||||
|
scheduler.reinitialize(conf, resourceManager.getRMContext());
|
||||||
|
|
||||||
|
PrintWriter out = new PrintWriter(new FileWriter(ALLOC_FILE));
|
||||||
|
out.println("<?xml version=\"1.0\"?>");
|
||||||
|
out.println("<allocations>");
|
||||||
|
out.println("<queue name=\"queue1\">");
|
||||||
|
out.println("<aclSubmitApps>norealuserhasthisname</aclSubmitApps>");
|
||||||
|
out.println("</queue>");
|
||||||
|
out.println("</allocations>");
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
QueueManager queueManager = scheduler.getQueueManager();
|
||||||
|
queueManager.initialize();
|
||||||
|
|
||||||
|
ApplicationAttemptId attId1 = createSchedulingRequest(1024, "queue1",
|
||||||
|
"norealuserhasthisname", 1);
|
||||||
|
ApplicationAttemptId attId2 = createSchedulingRequest(1024, "queue1",
|
||||||
|
"norealuserhasthisname2", 1);
|
||||||
|
|
||||||
|
FSSchedulerApp app1 = scheduler.applications.get(attId1);
|
||||||
|
assertNotNull("The application was not allowed", app1);
|
||||||
|
FSSchedulerApp app2 = scheduler.applications.get(attId2);
|
||||||
|
assertNull("The application was allowed", app2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue