Author: sseth
Date: Wed Jan 9 19:34:58 2013
New Revision: 1431025
URL: http://svn.apache.org/viewvc?rev=1431025&view=rev
Log:
YARN-320. RM should always be able to renew its own tokens. Contributed by
Daryn Sharp
Modified:
hadoop/common/branches/branch-0.23/hadoop-yarn-project/CHANGES.txt
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
Modified: hadoop/common/branches/branch-0.23/hadoop-yarn-project/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-yarn-project/CHANGES.txt?rev=1431025&r1=1431024&r2=1431025&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-yarn-project/CHANGES.txt
(original)
+++ hadoop/common/branches/branch-0.23/hadoop-yarn-project/CHANGES.txt Wed Jan
9 19:34:58 2013
@@ -46,6 +46,9 @@ Release 0.23.6 - UNRELEASED
YARN-50. Implement renewal / cancellation of Delegation Tokens
(Siddharth Seth via tgraves)
+ YARN-320. RM should always be able to renew its own tokens.
+ (Daryn Sharp via sseth)
+
Release 0.23.5 - UNRELEASED
INCOMPATIBLE CHANGES
Modified:
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java?rev=1431025&r1=1431024&r2=1431025&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
(original)
+++
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
Wed Jan 9 19:34:58 2013
@@ -18,6 +18,8 @@
package org.apache.hadoop.yarn.server.resourcemanager;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.AccessControlException;
@@ -505,7 +507,7 @@ public class ClientRMService extends Abs
protoToken.getIdentifier().array(), protoToken.getPassword().array(),
new Text(protoToken.getKind()), new Text(protoToken.getService()));
- String user = UserGroupInformation.getCurrentUser().getShortUserName();
+ String user = getRenewerForToken(token);
long nextExpTime = rmDTSecretManager.renewToken(token, user);
RenewDelegationTokenResponse renewResponse = Records
.newRecord(RenewDelegationTokenResponse.class);
@@ -529,7 +531,7 @@ public class ClientRMService extends Abs
protoToken.getIdentifier().array(), protoToken.getPassword().array(),
new Text(protoToken.getKind()), new Text(protoToken.getService()));
- String user = UserGroupInformation.getCurrentUser().getShortUserName();
+ String user = getRenewerForToken(token);
rmDTSecretManager.cancelToken(token, user);
return Records.newRecord(CancelDelegationTokenResponse.class);
} catch (IOException e) {
@@ -537,6 +539,26 @@ public class ClientRMService extends Abs
}
}
+ private String getRenewerForToken(Token<?> token)
+ throws YarnRemoteException {
+ try {
+ UserGroupInformation user = UserGroupInformation.getCurrentUser();
+ UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
+ String renewer = user.getShortUserName();
+ // we can always renew our own tokens
+ if (loginUser.getUserName().equals(user.getUserName())) {
+ DataInputStream in = new DataInputStream(
+ new ByteArrayInputStream(token.getIdentifier()));
+ RMDelegationTokenIdentifier id = rmDTSecretManager.createIdentifier();
+ id.readFields(in);
+ renewer = id.getRenewer().toString();
+ }
+ return renewer;
+ } catch (IOException e) {
+ throw RPCUtil.getRemoteException(e);
+ }
+ }
+
void refreshServiceAcls(Configuration configuration,
PolicyProvider policyProvider) {
this.server.refreshServiceAcl(configuration, policyProvider);
Modified:
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java?rev=1431025&r1=1431024&r2=1431025&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
(original)
+++
hadoop/common/branches/branch-0.23/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java
Wed Jan 9 19:34:58 2013
@@ -25,6 +25,7 @@ import static org.mockito.Matchers.anySt
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -33,14 +34,21 @@ import junit.framework.Assert;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
+import
org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.AccessControlException;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.yarn.api.ClientRMProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportResponse;
import org.apache.hadoop.yarn.api.protocolrecords.GetClusterNodesRequest;
import org.apache.hadoop.yarn.api.protocolrecords.GetQueueInfoRequest;
import org.apache.hadoop.yarn.api.protocolrecords.GetQueueInfoResponse;
+import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationReport;
+import org.apache.hadoop.yarn.api.records.DelegationToken;
import org.apache.hadoop.yarn.api.records.NodeReport;
import org.apache.hadoop.yarn.api.records.QueueInfo;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
@@ -49,11 +57,16 @@ import org.apache.hadoop.yarn.exceptions
import org.apache.hadoop.yarn.factories.RecordFactory;
import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider;
import org.apache.hadoop.yarn.ipc.YarnRPC;
+import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier;
+import org.apache.hadoop.yarn.server.RMDelegationTokenSecretManager;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppImpl;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler;
+import org.apache.hadoop.yarn.util.BuilderUtils;
import org.apache.hadoop.yarn.util.Records;
import org.junit.Test;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
public class TestClientRMService {
@@ -63,6 +76,21 @@ public class TestClientRMService {
private RecordFactory recordFactory = RecordFactoryProvider
.getRecordFactory(null);
+ private static RMDelegationTokenSecretManager dtsm;
+
+ @BeforeClass
+ public static void setupSecretManager() throws IOException {
+ dtsm = new RMDelegationTokenSecretManager(60000, 60000, 60000, 60000);
+ dtsm.startThreads();
+ }
+
+ @AfterClass
+ public static void teardownSecretManager() {
+ if (dtsm != null) {
+ dtsm.stopThreads();
+ }
+ }
+
@Test
public void testGetClusterNodes() throws Exception {
MockRM rm = new MockRM() {
@@ -141,6 +169,74 @@ public class TestClientRMService {
Assert.assertEquals(2, applications.size());
}
+ private static final UserGroupInformation owner =
+ UserGroupInformation.createRemoteUser("owner");
+ private static final UserGroupInformation other =
+ UserGroupInformation.createRemoteUser("other");
+
+ @Test
+ public void testTokenRenewalByOwner() throws Exception {
+ owner.doAs(new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ checkTokenRenewal(owner, owner);
+ return null;
+ }
+ });
+ }
+
+ @Test
+ public void testTokenRenewalWrongUser() throws Exception {
+ try {
+ owner.doAs(new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ checkTokenRenewal(owner, other);
+ return null;
+ }
+ });
+ } catch (YarnRemoteException e) {
+ Assert.assertEquals(e.getMessage(),
+ "Client " + owner.getUserName() +
+ " tries to renew a token with renewer specified as " +
+ other.getUserName());
+ return;
+ }
+ Assert.fail("renew should have failed");
+ }
+
+ @Test
+ public void testTokenRenewalByLoginUser() throws Exception {
+ UserGroupInformation.getLoginUser().doAs(new
PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ checkTokenRenewal(owner, owner);
+ checkTokenRenewal(owner, other);
+ return null;
+ }
+ });
+ }
+
+ private void checkTokenRenewal(UserGroupInformation owner,
+ UserGroupInformation renewer) throws IOException {
+ RMDelegationTokenIdentifier tokenIdentifier =
+ new RMDelegationTokenIdentifier(
+ new Text(owner.getUserName()), new Text(renewer.getUserName()),
null);
+ Token<?> token =
+ new Token<RMDelegationTokenIdentifier>(tokenIdentifier, dtsm);
+ DelegationToken dToken = BuilderUtils.newDelegationToken(
+ token.getIdentifier(), token.getKind().toString(),
+ token.getPassword(), token.getService().toString());
+ RenewDelegationTokenRequest request =
+ Records.newRecord(RenewDelegationTokenRequest.class);
+ request.setDelegationToken(dToken);
+
+ RMContext rmContext = mock(RMContext.class);
+ ClientRMService rmService = new ClientRMService(
+ rmContext, null, null, null, dtsm);
+ rmService.renewDelegationToken(request);
+ }
+
private void mockRMContext(YarnScheduler yarnScheduler, RMContext rmContext)
throws IOException {
Dispatcher dispatcher = mock(Dispatcher.class);